/* ЗАМЕТКА РАЗРАБОТЧИКУ * * В данном файле размещаются функции для работы с файлами и каталогами. * Данные функции запускаются в отдельных от UI потоках из кода * файла MainWindow-Actions.cs . Всякая функция должна иметь * префикс Do, означающий её чисто утилитарную принадлежность. * * Вызовы пользовательского интерфейса (XWT) должны производиться через * вызывалку Xwt.Application.Invoke(new Action(delegate { КОД ПОТОКА ИНТЕРФЕЙСА })); * в противном случае возможны глюки (вылеты WPF, зависания и лаги GTK). */ /// <summary> /// Background file copier /// </summary> /// <param name='SourceFS'>Source FS.</param> /// <param name='DestinationFS'>Destination FS.</param> /// <param name='SourceURL'>Source file URL.</param> /// <param name='DestinationURL'>Destination URL.</param> /// <param name="Feedback">If at the destination URL a file exists, a ReplaceQuestionDialog will be shown. This argument is the place, where the user's last choose should be saved.</param> /// <param name="AC">The instance of AsyncCopy class that should be used to copy the file.</param> private void DoCp(IFSPlugin SourceFS, IFSPlugin DestinationFS, string SourceURL, string DestinationURL, ref ReplaceQuestionDialog.ClickedButton Feedback, AsyncCopy AC) { if (SourceURL == DestinationURL){ string itself = Localizator.GetString("CantCopySelf"); string toshow = string.Format(Localizator.GetString("CantCopy"), SourceFS.GetMetadata(SourceURL).Name, itself); Xwt.Application.Invoke(delegate { Xwt.MessageDialog.ShowWarning(toshow); }); //calling the msgbox in non-main threads causes some UI bugs, so push this call into main thread return; } if(DestinationFS.FileExists (DestinationURL)){ ReplaceQuestionDialog rpd = null; bool ready = false; Xwt.Application.Invoke( delegate { rpd = new ReplaceQuestionDialog(DestinationFS.GetMetadata(DestinationURL).Name); ready = true; } ); do { } while (!ready); ready = false; var ClickedButton = ReplaceQuestionDialog.ClickedButton.Skip; Xwt.Application.Invoke( delegate { ClickedButton = rpd.Run(); ready = true; } ); do {} while (!ready); switch(ClickedButton){ case ReplaceQuestionDialog.ClickedButton.Replace: //continue execution Feedback = rpd.ChoosedButton; break; case ReplaceQuestionDialog.ClickedButton.ReplaceAll: //continue execution Feedback = rpd.ChoosedButton; break; case ReplaceQuestionDialog.ClickedButton.ReplaceOld: Feedback = rpd.ChoosedButton; if(SourceFS.GetMetadata(SourceURL).LastWriteTimeUTC < DestinationFS.GetMetadata(DestinationURL).LastWriteTimeUTC) {/*continue execution*/} else {return;} break; case ReplaceQuestionDialog.ClickedButton.Skip: Feedback = rpd.ChoosedButton; return; case ReplaceQuestionDialog.ClickedButton.SkipAll: Feedback = rpd.ChoosedButton; return; } } try { pluginner.FSEntryMetadata md = SourceFS.GetMetadata(SourceURL); md.FullURL = DestinationURL; System.IO.Stream SrcStream = SourceFS.GetFileStream(SourceURL); DestinationFS.Touch(md); System.IO.Stream DestStream = DestinationFS.GetFileStream(DestinationURL,true); if(AC == null) AC = new AsyncCopy(); bool CpComplete = false; AC.OnComplete += result => CpComplete = true; //warning: due to some GTK# bugs, buffer sizes lesser than 128KB may cause //an StackOverflowException at UI update code AC.CopyFile(SrcStream, DestStream, 131072); //buffer is 1/8 megabyte or 128KB do{ } while(!CpComplete); //don't stop this thread until the copy is finished } catch (Exception ex) { if (ex.GetType() != typeof(System.Threading.ThreadAbortException)) { Utilities.ShowMessage(string.Format(Localizator.GetString("CantCopy"),SourceURL,ex.Message)); Console.WriteLine("Cannot copy because of {0}({1}) at \n{2}.", ex.GetType(), ex.Message, ex.StackTrace); } } }
/// <summary>Load the file in the VE (with plugin autodetection)</summary> /// <param name="URL">The file's URL</param> /// <param name="FS">The file's filesystem</param> /// <param name="AllowEdit">Mode of VE: true=editor, false=viewer</param> public void LoadFile(string URL, IFSPlugin FS, bool AllowEdit) { try { byte[] ContentBytes = FS.GetFileContent(URL); string content = (ContentBytes != null && ContentBytes.Length > 0) ? Encoding.UTF8.GetString(ContentBytes) : ""; pluginfinder pf = new pluginfinder(); string GottenHeaders; if (content.Length >= 20) GottenHeaders = content.Substring(0, 20); else GottenHeaders = content; LoadFile(URL, FS, pf.GetFCVEplugin("NAME=" + URL + "HEADERS=" + GottenHeaders), AllowEdit); } catch (pluginfinder.PluginNotFoundException ex) { // ReSharper disable LocalizableElement Console.WriteLine("ERROR: VE plugin is not loaded: " + ex.Message + "\n" + ex.StackTrace); MessageDialog.ShowError(Localizator.GetString("FCVE_PluginNotFound")); LoadFile(URL, FS, new PlainText(), AllowEdit); } catch (Exception ex) { MessageDialog.ShowError(string.Format(Localizator.GetString("FCVE_LoadError"),ex.Message)); Console.WriteLine("ERROR: VE can't load file: " + ex.Message + "\n" + ex.StackTrace); // ReSharper restore LocalizableElement } }
/// <summary>Load the file in the VE</summary> /// <param name="URL">The URL of the file</param> /// <param name="FS">The filesystem of the file</param> /// <param name="plugin">The VE plugin, which will be used to load this file</param> /// <param name="AllowEdit">Allow editing the file</param> public void LoadFile(string URL, IFSPlugin FS, IVEPlugin plugin, bool AllowEdit) { //check for external editor try{ if (Settings.Default.UseExternalEditor && AllowEdit || Settings.Default.UseExternalViewer && !AllowEdit && URL.StartsWith("file:")){ CanBeShowed = false; if (AllowEdit){ ExecuteProgram(Settings.Default.ExternalEditor.Replace("$", "\"" + URL)); } else{ ExecuteProgram(Settings.Default.ExternalViewer.Replace("$", "\"" + URL)); } return; } } catch (Exception ex) { MessageDialog.ShowError(Localizator.GetString("CantRunEXE"), ex.Message); CanBeShowed = false; return; } FileNameForTitle = URL.Substring(URL.LastIndexOf(FS.DirSeparator, StringComparison.Ordinal) + 1); IsEditor = AllowEdit; if(AllowEdit) Title = string.Format(Localizator.GetString("FCETitle"), FileNameForTitle); else Title = string.Format(Localizator.GetString("FCVTitle"), FileNameForTitle); FileProcessDialog ProgressDialog = new FileProcessDialog(); string ProgressInitialText = String.Format(Localizator.GetString("FCVELoadingMsg"),URL); ProgressDialog.lblStatus.Text = ProgressInitialText; FS.ProgressChanged += d => { ProgressDialog.pbrProgress.Fraction = (d >= 0 && d <= 1) ? d : ProgressDialog.pbrProgress.Fraction; Xwt.Application.MainLoop.DispatchPendingEvents(); }; FS.StatusChanged += d => { ProgressDialog.lblStatus.Text = ProgressInitialText + "\n" + d; Xwt.Application.MainLoop.DispatchPendingEvents(); }; ProgressDialog.cmdCancel.Clicked += (o, ea) => { CanBeShowed = false; ProgressDialog.Close(); }; ProgressDialog.Show(); Xwt.Application.MainLoop.DispatchPendingEvents(); if (!CanBeShowed) return; try { Plugin = plugin; Plugin.ReadOnly = !AllowEdit; Plugin.OpenFile(URL, FS); Plugin.ShowToolbar = Settings.Default.VE_ShowToolbar; Plugin.Stylist = s; mnuFormat.SubMenu = Plugin.FormatMenu; bool Mode = AllowEdit; if (!Plugin.CanEdit && AllowEdit) { MessageDialog.ShowWarning(String.Format(Localizator.GetString("FCVEpluginro1"), Plugin.Name + " " + Plugin.Version), Localizator.GetString("FCVEpluginro2")); Mode = false; } FSPlugin = FS; PluginBody = Plugin.Body; SetVEMode(Mode); } catch (Exception ex) { MessageDialog.ShowWarning(ex.Message); if(PluginBody.GetType() == typeof(Spinner)) { ProgressDialog.Close(); CanBeShowed = false; return;} } BuildLayout(); ProgressDialog.Close(); }
public void OpenFile(string url, IFSPlugin fsplugin) { doc.LoadXml( Encoding.Default.GetString(fsplugin.GetFileContent(url))); if (doc.ChildNodes.Count > 0) { int deep = 0; foreach (XmlNode n in doc.ChildNodes) { if (n.NodeType != XmlNodeType.XmlDeclaration) //skip "<?xml version=... codepage=..." { XmlDisplay child_xd = new XmlDisplay(n, ht) { Tag = n, MarginLeft = ((deep > 0) ? 12 : 0) }; layout.PackStart(child_xd); //обеспечивается рекурсивность } } sw = new ScrollView(layout); } else { XmlDisplay xd = new XmlDisplay(doc.ChildNodes[0], ht); sw = new ScrollView(xd); } }