/// <summary> /// Sets the file content given the text string. /// </summary> /// <param name="args">.</param> /// <remarks> /// If this method is used then <see cref="Functions"/> should contain the <see cref="ExplorerFunctions.SetText"/> flag. /// </remarks> public virtual void SetText(SetTextEventArgs args) { if (args != null) { args.Result = JobResult.Default; } }
/// <summary> /// Calls <see cref="FarNet.Explorer.SetText"/> and <see cref="OnThisFileChanged"/>. /// </summary> /// <param name="args">.</param> public virtual void UISetText(SetTextEventArgs args) { if (args == null) { return; } Explorer.SetText(args); if (args.Result != JobResult.Ignore) { OnThisFileChanged(args); } }
/// <summary> /// Opens the file in the editor. /// </summary> /// <param name="file">The file to edit.</param> /// <remarks> /// The default method calls <see cref="FarNet.Explorer.GetContent"/> to get a temporary file to edit /// and <see cref="FarNet.Explorer.SetFile"/> to save changes when the editor closes. /// The explorer should have at least export implemented. /// </remarks> public virtual void UIEditFile(FarFile file) { if (file == null) { return; } // target var temp = Far.Api.TempName(); // export var xExportArgs = WorksExportExplorerFile(Explorer, this, ExplorerModes.Edit, file, temp); if (xExportArgs == null) { return; } // case: actual file exists var asExportFileEventArgs = xExportArgs as GetContentEventArgs; if (asExportFileEventArgs != null && !string.IsNullOrEmpty(asExportFileEventArgs.UseFileName)) { var editorActual = Far.Api.CreateEditor(); editorActual.FileName = asExportFileEventArgs.UseFileName; editorActual.Title = file.Name; if (!asExportFileEventArgs.CanSet) { editorActual.IsLocked = true; } editorActual.Open(); return; } // rename if (!string.IsNullOrEmpty(xExportArgs.UseFileExtension)) { string temp2 = temp + xExportArgs.UseFileExtension; File.Move(temp, temp2); temp = temp2; } // editor var editorTemp = Far.Api.CreateEditor(); editorTemp.DeleteSource = DeleteSource.File; editorTemp.DisableHistory = true; editorTemp.FileName = temp; editorTemp.Title = file.Name; if (asExportFileEventArgs.CodePage != 0) { editorTemp.CodePage = asExportFileEventArgs.CodePage; } // future if (xExportArgs.CanSet) { if (Explorer.CanSetText) { editorTemp.Saving += delegate { var xImportTextArgs = new SetTextEventArgs(ExplorerModes.Edit, file, editorTemp.GetText()); Log.Source.TraceInformation("ImportText"); UISetText(xImportTextArgs); }; } else { editorTemp.Closed += delegate //???? to use Saved (Far 3), update docs. { if (editorTemp.TimeOfSave == DateTime.MinValue) { return; } var xImportFileArgs = new SetFileEventArgs(ExplorerModes.Edit, file, temp); Log.Source.TraceInformation("ImportFile"); UISetFile(xImportFileArgs); }; } } else { // to lock editorTemp.IsLocked = true; } // go editorTemp.Open(); }
/// <summary> /// Opens the file in the editor. /// </summary> /// <param name="file">The file to edit.</param> /// <remarks> /// The default method calls <see cref="FarNet.Explorer.GetContent"/> to get a temporary file to edit /// and <see cref="FarNet.Explorer.SetFile"/> to save changes when the editor closes. /// The explorer should have at least export implemented. /// </remarks> public virtual void UIEditFile(FarFile file) { if (file == null) { return; } // target file path // _201223_vc Avoid Far.Api.TempName(). I think it reuses names if files do not exist. But file history may exist unexpectedly. var temp = Kit.TempFileName(null); // export var xExportArgs = WorksExportExplorerFile(Explorer, this, ExplorerModes.Edit, file, temp); if (xExportArgs == null) { return; } // case: actual file exists if (!string.IsNullOrEmpty(xExportArgs.UseFileName)) { var editorActual = Far.Api.CreateEditor(); editorActual.FileName = xExportArgs.UseFileName; editorActual.Title = file.Name; if (!xExportArgs.CanSet) { editorActual.IsLocked = true; } if (xExportArgs.EditorOpened != null) { editorActual.Opened += xExportArgs.EditorOpened; } editorActual.Open(); return; } // rename if (!string.IsNullOrEmpty(xExportArgs.UseFileExtension)) { var temp2 = Path.ChangeExtension(temp, xExportArgs.UseFileExtension); File.Move(temp, temp2); temp = temp2; } // editor var editorTemp = Far.Api.CreateEditor(); editorTemp.DisableHistory = true; editorTemp.FileName = temp; editorTemp.Title = file.Name; if (xExportArgs.CodePage != 0) { editorTemp.CodePage = xExportArgs.CodePage; } if (xExportArgs.EditorOpened != null) { editorTemp.Opened += xExportArgs.EditorOpened; } // future //! Not sure why but with used DisableHistory the file reopens with the last caret restored. //! If this is some Far feature and it changes then save and set the last caret manually. var timeError = DateTime.MinValue; if (xExportArgs.CanSet) { if (Explorer.CanSetText) { editorTemp.Saving += delegate { var xImportTextArgs = new SetTextEventArgs(ExplorerModes.Edit, file, editorTemp.GetText()); Log.Source.TraceInformation("ImportText"); try { timeError = DateTime.MinValue; UISetText(xImportTextArgs); } catch (Exception exn) { //! show first, then save error time Far.Api.ShowError("Cannot set text", exn); timeError = DateTime.UtcNow; } }; editorTemp.Closed += delegate { //! if error was on saving without closing then on closing "much later" without new saving ignore error if (timeError != DateTime.MinValue && (DateTime.UtcNow - timeError).TotalSeconds > 1) { timeError = DateTime.MinValue; } }; } else { editorTemp.Closed += delegate { if (editorTemp.TimeOfSave == DateTime.MinValue) { return; } var xImportFileArgs = new SetFileEventArgs(ExplorerModes.Edit, file, temp); Log.Source.TraceInformation("ImportFile"); try { UISetFile(xImportFileArgs); } catch (Exception exn) { Far.Api.ShowError("Cannot set file", exn); timeError = DateTime.UtcNow; } }; } } else { // lock, do nothing else editorTemp.IsLocked = true; } // loop while errors on saving async void Loop() { try { for (; ;) { timeError = DateTime.MinValue; await Tasks.Editor(editorTemp); if (timeError == DateTime.MinValue) { break; } } } finally { File.Delete(temp); } } Loop(); }