From 1c61553dd7066bc9f809a3312c1ea321a7aa096f Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 29 Mar 2012 14:53:02 +0200 Subject: [PATCH] Move remainder of the FileService into interface. --- .../Src/AvalonEditDisplayBinding.cs | 2 +- .../Src/ChooseEncodingDialog.xaml.cs | 6 +- .../AvalonEdit.AddIn/Src/CodeEditor.cs | 2 +- .../XmlEditor/Project/Src/XmlView.cs | 2 +- .../Project/Src/RecentProjectsControl.xaml.cs | 2 +- .../VersionControl/GitAddIn/Src/Commands.cs | 2 +- .../Src/Commands/ProjectBrowserCommands.cs | 2 +- .../Project/ICSharpCode.SharpDevelop.csproj | 6 - .../Base/Project/Src/Commands/FileCommands.cs | 8 +- .../Project/Src/Commands/MenuItemBuilders.cs | 20 +- .../Src/Gui/Dialogs/NewProjectDialog.cs | 8 +- .../ProjectAndSolutionOptions.xaml.cs | 12 +- .../ProjectBrowser/TreeNodes/DirectoryNode.cs | 2 +- .../Project/Src/Services/File/FileService.cs | 541 ++-------------- .../Project/Src/Services/File/IFileService.cs | 195 ++++++ .../Project/Src/Services/File/OpenedFile.cs | 147 +---- .../Project/Src/Services/File/RecentOpen.cs | 132 ---- .../ParseableFileContentFinder.cs | 2 +- .../Services/ProjectService/ProjectService.cs | 1 + .../FindReferencesAndRenameHelper.cs | 2 +- .../Project/Src/Util/FakeXmlViewContent.cs | 2 +- .../OptionPanels}/LoadSaveOptions.xaml | 14 +- .../OptionPanels}/LoadSaveOptions.xaml.cs | 2 +- src/Main/SharpDevelop/SharpDevelop.csproj | 8 + .../SharpDevelop/Workbench/FileService.cs | 588 +++++++++++++++++- .../Workbench/FileServiceOpenedFile.cs | 161 +++++ src/Main/SharpDevelop/Workbench/RecentOpen.cs | 114 ++++ .../Workbench/WorkbenchStartup.cs | 4 +- .../SharpDevelop/Workbench/WpfWorkbench.cs | 10 +- 29 files changed, 1173 insertions(+), 824 deletions(-) delete mode 100644 src/Main/Base/Project/Src/Services/File/RecentOpen.cs rename src/Main/{Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions => SharpDevelop/OptionPanels}/LoadSaveOptions.xaml (81%) rename src/Main/{Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions => SharpDevelop/OptionPanels}/LoadSaveOptions.xaml.cs (91%) create mode 100644 src/Main/SharpDevelop/Workbench/FileServiceOpenedFile.cs create mode 100644 src/Main/SharpDevelop/Workbench/RecentOpen.cs diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditDisplayBinding.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditDisplayBinding.cs index 983eb2c9c3..f866e2eff8 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditDisplayBinding.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditDisplayBinding.cs @@ -65,7 +65,7 @@ namespace ICSharpCode.AvalonEdit.AddIn ChooseEncodingDialog dlg = new ChooseEncodingDialog(); dlg.Owner = WorkbenchSingleton.MainWindow; using (Stream stream = file.OpenRead()) { - using (StreamReader reader = FileReader.OpenStream(stream, FileService.DefaultFileEncoding.GetEncoding())) { + using (StreamReader reader = FileReader.OpenStream(stream, SD.FileService.DefaultFileEncoding)) { reader.Peek(); // force reader to auto-detect encoding dlg.Encoding = reader.CurrentEncoding; } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChooseEncodingDialog.xaml.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChooseEncodingDialog.xaml.cs index 561504e8e7..0e3a7da3d6 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChooseEncodingDialog.xaml.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChooseEncodingDialog.xaml.cs @@ -18,13 +18,13 @@ namespace ICSharpCode.AvalonEdit.AddIn public ChooseEncodingDialog() { InitializeComponent(); - encodingComboBox.ItemsSource = FileService.AllEncodings; - encodingComboBox.SelectedItem = FileService.DefaultFileEncoding; + encodingComboBox.ItemsSource = SD.FileService.AllEncodings; + encodingComboBox.SelectedItem = SD.FileService.DefaultFileEncodingInfo; } public Encoding Encoding { get { return ((EncodingInfo)encodingComboBox.SelectedItem).GetEncoding(); } - set { encodingComboBox.SelectedItem = FileService.AllEncodings.Single(e => e.CodePage == value.CodePage); } + set { encodingComboBox.SelectedItem = SD.FileService.AllEncodings.Single(e => e.CodePage == value.CodePage); } } void okButton_Click(object sender, RoutedEventArgs e) diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index b5b32df266..6189d7d093 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -293,7 +293,7 @@ namespace ICSharpCode.AvalonEdit.AddIn } } else { // do encoding auto-detection - using (StreamReader reader = FileReader.OpenStream(stream, this.Encoding ?? FileService.DefaultFileEncoding.GetEncoding())) { + using (StreamReader reader = FileReader.OpenStream(stream, this.Encoding ?? SD.FileService.DefaultFileEncoding)) { ReloadDocument(primaryTextEditor.Document, reader.ReadToEnd()); this.Encoding = reader.CurrentEncoding; } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs index f13111c3cd..40f9bd9d50 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs @@ -56,7 +56,7 @@ namespace ICSharpCode.XmlEditor public static XmlView ForFileName(string fileName) { - return ForFile(FileService.GetOpenedFile(fileName)); + return ForFile(SD.FileService.GetOpenedFile(fileName)); } public OpenedFile File { get; set; } diff --git a/src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml.cs b/src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml.cs index f3c596d16b..bca9c50964 100644 --- a/src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml.cs +++ b/src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.StartPage // When building the project list we access the .sln files (to see if they still exist). // Because those might be stored on a slow network drive, we do this on a background thread so that // SharpDevelop startup doesn't have to wait. - ThreadPool.QueueUserWorkItem(AsyncBuildRecentProjectList, FileService.RecentOpen.RecentProject.ToArray()); + ThreadPool.QueueUserWorkItem(AsyncBuildRecentProjectList, SD.FileService.RecentOpen.RecentProjects.ToArray()); } void AsyncBuildRecentProjectList(object state) diff --git a/src/AddIns/VersionControl/GitAddIn/Src/Commands.cs b/src/AddIns/VersionControl/GitAddIn/Src/Commands.cs index 232b58368e..4cc964668d 100644 --- a/src/AddIns/VersionControl/GitAddIn/Src/Commands.cs +++ b/src/AddIns/VersionControl/GitAddIn/Src/Commands.cs @@ -32,7 +32,7 @@ namespace ICSharpCode.GitAddIn } if (nodeFileName != null) { List unsavedFiles = new List(); - foreach (OpenedFile file in FileService.OpenedFiles) { + foreach (OpenedFile file in SD.FileService.OpenedFiles) { if (file.IsDirty && !file.IsUntitled) { if (string.IsNullOrEmpty(file.FileName)) continue; if (FileUtility.IsUrl(file.FileName)) continue; diff --git a/src/AddIns/VersionControl/SubversionAddIn/Src/Commands/ProjectBrowserCommands.cs b/src/AddIns/VersionControl/SubversionAddIn/Src/Commands/ProjectBrowserCommands.cs index 4d51b035a5..aff4da70d4 100644 --- a/src/AddIns/VersionControl/SubversionAddIn/Src/Commands/ProjectBrowserCommands.cs +++ b/src/AddIns/VersionControl/SubversionAddIn/Src/Commands/ProjectBrowserCommands.cs @@ -29,7 +29,7 @@ namespace ICSharpCode.Svn.Commands } if (nodeFileName != null) { List unsavedFiles = new List(); - foreach (OpenedFile file in FileService.OpenedFiles) { + foreach (OpenedFile file in SD.FileService.OpenedFiles) { if (file.IsDirty && !file.IsUntitled) { if (string.IsNullOrEmpty(file.FileName)) continue; if (FileUtility.IsUrl(file.FileName)) continue; diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 858780bc67..8aa16490c8 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -211,10 +211,6 @@ OpenWithDialog.cs - - LoadSaveOptions.xaml - Code - ProjectAndSolutionOptions.xaml Code @@ -362,7 +358,6 @@ - @@ -857,7 +852,6 @@ GotoDialog.cs - diff --git a/src/Main/Base/Project/Src/Commands/FileCommands.cs b/src/Main/Base/Project/Src/Commands/FileCommands.cs index bb26141ea6..9316ef8f43 100644 --- a/src/Main/Base/Project/Src/Commands/FileCommands.cs +++ b/src/Main/Base/Project/Src/Commands/FileCommands.cs @@ -181,7 +181,7 @@ namespace ICSharpCode.SharpDevelop.Commands return; } if (FileUtility.ObservedSave(new NamedFileOperationDelegate(file.SaveToDisk), fileName) == FileOperationResult.OK) { - FileService.RecentOpen.AddLastFile(fileName); + SD.FileService.RecentOpen.AddRecentFile(fileName); MessageService.ShowMessage(fileName, "${res:ICSharpCode.SharpDevelop.Commands.SaveFile.FileSaved}"); } } @@ -198,7 +198,7 @@ namespace ICSharpCode.SharpDevelop.Commands ((ICustomizedCommands)content).SaveCommand(); } } - foreach (OpenedFile file in FileService.OpenedFiles) { + foreach (OpenedFile file in SD.FileService.OpenedFiles) { if (file.IsDirty) { SaveFile.Save(file); } @@ -308,7 +308,7 @@ namespace ICSharpCode.SharpDevelop.Commands { public override void Run() { - FileService.RecentOpen.ClearRecentFiles(); + SD.FileService.RecentOpen.ClearRecentFiles(); } } @@ -316,7 +316,7 @@ namespace ICSharpCode.SharpDevelop.Commands { public override void Run() { - FileService.RecentOpen.ClearRecentProjects(); + SD.FileService.RecentOpen.ClearRecentProjects(); } } } diff --git a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs index eedfb96dad..b5e5e8f51f 100644 --- a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs +++ b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs @@ -136,14 +136,14 @@ namespace ICSharpCode.SharpDevelop.Commands { public ICollection BuildItems(Codon codon, object owner) { - RecentOpen recentOpen = FileService.RecentOpen; + IRecentOpen recentOpen = SD.FileService.RecentOpen; - if (recentOpen.RecentFile.Count > 0) { - var items = new System.Windows.Controls.MenuItem[recentOpen.RecentFile.Count]; + if (recentOpen.RecentFiles.Count > 0) { + var items = new System.Windows.Controls.MenuItem[recentOpen.RecentFiles.Count]; - for (int i = 0; i < recentOpen.RecentFile.Count; ++i) { + for (int i = 0; i < recentOpen.RecentFiles.Count; ++i) { // variable inside loop, so that anonymous method refers to correct recent file - string recentFile = recentOpen.RecentFile[i]; + string recentFile = recentOpen.RecentFiles[i]; string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10) + " " : ""; items[i] = new System.Windows.Controls.MenuItem() { Header = accelaratorKeyPrefix + recentFile @@ -166,14 +166,14 @@ namespace ICSharpCode.SharpDevelop.Commands { public ICollection BuildItems(Codon codon, object owner) { - RecentOpen recentOpen = FileService.RecentOpen; + IRecentOpen recentOpen = SD.FileService.RecentOpen; - if (recentOpen.RecentProject.Count > 0) { - var items = new System.Windows.Controls.MenuItem[recentOpen.RecentProject.Count]; + if (recentOpen.RecentProjects.Count > 0) { + var items = new System.Windows.Controls.MenuItem[recentOpen.RecentProjects.Count]; - for (int i = 0; i < recentOpen.RecentProject.Count; ++i) { + for (int i = 0; i < recentOpen.RecentProjects.Count; ++i) { // variable inside loop, so that anonymous method refers to correct recent file - string recentProject = recentOpen.RecentProject[i]; + string recentProject = recentOpen.RecentProjects[i]; string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10) + " " : ""; items[i] = new System.Windows.Controls.MenuItem() { Header = accelaratorKeyPrefix + recentProject diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/NewProjectDialog.cs b/src/Main/Base/Project/Src/Gui/Dialogs/NewProjectDialog.cs index 7daf51f2d9..862322923e 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/NewProjectDialog.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/NewProjectDialog.cs @@ -362,11 +362,9 @@ namespace ICSharpCode.SharpDevelop.Project.Dialogs void BrowseDirectories(object sender, EventArgs e) { - using (FolderBrowserDialog fd = FileService.CreateFolderBrowserDialog("${res:Dialog.NewProject.SelectDirectoryForProject}", locationTextBox.Text)) { - if (fd.ShowDialog() == DialogResult.OK) { - locationTextBox.Text = fd.SelectedPath; - } - } + string path = SD.FileService.BrowseForFolder("${res:Dialog.NewProject.SelectDirectoryForProject}", locationTextBox.Text); + if (path != null) + locationTextBox.Text = path; } // list view event handlers diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptions.xaml.cs b/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptions.xaml.cs index 1999700edd..0ecffa1ca2 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptions.xaml.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptions.xaml.cs @@ -20,7 +20,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels FillComboBoxWithEnumValues(typeof(Project.BuildOnExecuteSetting), onExecuteComboBox); FillComboBoxWithEnumValues(typeof(Project.BuildOutputVerbosity), verbosityComboBox); } - + void FillComboBoxWithEnumValues(Type type, ComboBox comboBox) { foreach (Project.BuildOnExecuteSetting element in Enum.GetValues(type)) { @@ -37,11 +37,11 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels void defaultProjectLocationButtonClick(object sender, RoutedEventArgs e) { - using (var fdiag = FileService.CreateFolderBrowserDialog("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.SelectDefaultProjectLocationDialog.Title}", defaultProjectLocationTextBox.Text)) { - if (fdiag.ShowDialog() == System.Windows.Forms.DialogResult.OK) { - defaultProjectLocationTextBox.Text = fdiag.SelectedPath; - } - } + string path = SD.FileService.BrowseForFolder( + "${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.SelectDefaultProjectLocationDialog.Title}", + defaultProjectLocationTextBox.Text); + if (path != null) + defaultProjectLocationTextBox.Text = path; } public override void LoadOptions() diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/DirectoryNode.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/DirectoryNode.cs index a968c2bd96..522f4557f1 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/DirectoryNode.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/DirectoryNode.cs @@ -674,7 +674,7 @@ namespace ICSharpCode.SharpDevelop.Project RecreateSubNodes(); } if (performMove) { - foreach (OpenedFile file in FileService.OpenedFiles) { + foreach (OpenedFile file in SD.FileService.OpenedFiles) { if (file.FileName != null && FileUtility.IsEqualFileName(file.FileName, fileName)) { diff --git a/src/Main/Base/Project/Src/Services/File/FileService.cs b/src/Main/Base/Project/Src/Services/File/FileService.cs index 2c6e0090e4..f77e0399ba 100644 --- a/src/Main/Base/Project/Src/Services/File/FileService.cs +++ b/src/Main/Base/Project/Src/Services/File/FileService.cs @@ -20,30 +20,8 @@ namespace ICSharpCode.SharpDevelop { static bool serviceInitialized; - #region RecentOpen - static RecentOpen recentOpen = null; - - public static RecentOpen RecentOpen { - get { - if (recentOpen == null) { - recentOpen = RecentOpen.FromXmlElement(PropertyService.NestedProperties("RecentOpen")); - } - return recentOpen; - } - } - - static void ProjectServiceSolutionLoaded(object sender, SolutionEventArgs e) - { - RecentOpen.AddLastProject(e.Solution.FileName); - } - #endregion - internal static void Unload() { - if (recentOpen != null) { - PropertyService.SetNestedProperties("RecentOpen", recentOpen.ToProperties()); - } - ProjectService.SolutionLoaded -= ProjectServiceSolutionLoaded; SD.ParserService.LoadSolutionProjectsThreadEnded -= ParserServiceLoadSolutionProjectsThreadEnded; serviceInitialized = false; } @@ -51,134 +29,18 @@ namespace ICSharpCode.SharpDevelop internal static void InitializeService() { if (!serviceInitialized) { - ProjectService.SolutionLoaded += ProjectServiceSolutionLoaded; SD.ParserService.LoadSolutionProjectsThreadEnded += ParserServiceLoadSolutionProjectsThreadEnded; serviceInitialized = true; } } - #region OpenedFile - static Dictionary openedFileDict = new Dictionary(); - - /// - /// Gets a collection containing all currently opened files. - /// The returned collection is a read-only copy of the currently opened files - - /// it will not reflect future changes of the list of opened files. - /// - public static ICollection OpenedFiles { - get { - return openedFileDict.Values.ToArray(); - } - } - - /// - /// Gets an opened file, or returns null if the file is not opened. - /// - public static OpenedFile GetOpenedFile(string fileName) - { - return GetOpenedFile(FileName.Create(fileName)); - } - - /// - /// Gets an opened file, or returns null if the file is not opened. - /// - public static OpenedFile GetOpenedFile(FileName fileName) - { - if (fileName == null) - throw new ArgumentNullException("fileName"); - - WorkbenchSingleton.AssertMainThread(); - - OpenedFile file; - openedFileDict.TryGetValue(fileName, out file); - return file; - } - - /// - /// Gets or creates an opened file. - /// Warning: the opened file will be a file without any views attached. - /// Make sure to attach a view to it, or call CloseIfAllViewsClosed on the OpenedFile to - /// unload the OpenedFile instance if no views were attached to it. - /// - public static OpenedFile GetOrCreateOpenedFile(string fileName) - { - return GetOrCreateOpenedFile(FileName.Create(fileName)); - } - - /// - /// Gets or creates an opened file. - /// Warning: the opened file will be a file without any views attached. - /// Make sure to attach a view to it, or call CloseIfAllViewsClosed on the OpenedFile to - /// unload the OpenedFile instance if no views were attached to it. - /// - public static OpenedFile GetOrCreateOpenedFile(FileName fileName) - { - if (fileName == null) - throw new ArgumentNullException("fileName"); - - OpenedFile file; - if (!openedFileDict.TryGetValue(fileName, out file)) { - openedFileDict[fileName] = file = new FileServiceOpenedFile(fileName); - } - return file; - } - - /// - /// Creates a new untitled OpenedFile. - /// - public static OpenedFile CreateUntitledOpenedFile(string defaultName, byte[] content) - { - if (defaultName == null) - throw new ArgumentNullException("defaultName"); - - OpenedFile file = new FileServiceOpenedFile(content); - file.FileName = new FileName(file.GetHashCode() + "/" + defaultName); - openedFileDict[file.FileName] = file; - return file; - } - - /// Called by OpenedFile.set_FileName to update the dictionary. - internal static void OpenedFileFileNameChange(OpenedFile file, FileName oldName, FileName newName) - { - if (oldName == null) return; // File just created with NewFile where name is being initialized. - - LoggingService.Debug("OpenedFileFileNameChange: " + oldName + " => " + newName); - - if (openedFileDict[oldName] != file) - throw new ArgumentException("file must be registered as oldName"); - if (openedFileDict.ContainsKey(newName)) { - OpenedFile oldFile = openedFileDict[newName]; - if (oldFile.CurrentView != null) { - oldFile.CurrentView.WorkbenchWindow.CloseWindow(true); - } else { - throw new ArgumentException("there already is a file with the newName"); - } - } - openedFileDict.Remove(oldName); - openedFileDict[newName] = file; - } - - /// Called by OpenedFile.UnregisterView to update the dictionary. - internal static void OpenedFileClosed(OpenedFile file) - { - if (openedFileDict[file.FileName] != file) - throw new ArgumentException("file must be registered"); - - openedFileDict.Remove(file.FileName); - LoggingService.Debug("OpenedFileClosed: " + file.FileName); - } - #endregion - /// /// Checks if the path is valid and shows a MessageBox if it is not valid. /// Do not use in non-UI methods. /// public static bool CheckFileName(string path) { - if (FileUtility.IsValidPath(path)) - return true; - MessageService.ShowMessage(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.SaveFile.InvalidFileNameError}", new StringTagPair("FileName", path))); - return false; + return SD.FileService.CheckFileName(path); } /// @@ -188,10 +50,7 @@ namespace ICSharpCode.SharpDevelop /// A single file name not the full path public static bool CheckDirectoryEntryName(string name) { - if (FileUtility.IsValidDirectoryEntryName(name)) - return true; - MessageService.ShowMessage(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.SaveFile.InvalidFileNameError}", new StringTagPair("FileName", name))); - return false; + return SD.FileService.CheckDirectoryEntryName(name); } internal sealed class LoadFileWrapper @@ -207,7 +66,7 @@ namespace ICSharpCode.SharpDevelop public void Invoke(string fileName) { - OpenedFile file = FileService.GetOrCreateOpenedFile(FileName.Create(fileName)); + OpenedFile file = SD.FileService.GetOrCreateOpenedFile(FileName.Create(fileName)); IViewContent newContent = binding.CreateContentForFile(file); if (newContent != null) { DisplayBindingService.AttachSubWindows(newContent, false); @@ -226,7 +85,7 @@ namespace ICSharpCode.SharpDevelop public static bool IsOpen(string fileName) { - return GetOpenFile(fileName) != null; + return SD.FileService.IsOpen(FileName.Create(fileName)); } /// @@ -237,7 +96,7 @@ namespace ICSharpCode.SharpDevelop /// The existing or opened for the specified file. public static IViewContent OpenFile(string fileName) { - return OpenFile(fileName, true); + return SD.FileService.OpenFile(FileName.Create(fileName)); } /// @@ -249,26 +108,7 @@ namespace ICSharpCode.SharpDevelop /// The existing or opened for the specified file. public static IViewContent OpenFile(string fileName, bool switchToOpenedView) { - fileName = FileUtility.NormalizePath(fileName); - LoggingService.Info("Open file " + fileName); - - IViewContent viewContent = GetOpenFile(fileName); - if (viewContent != null) { - if (switchToOpenedView) { - viewContent.WorkbenchWindow.SelectWindow(); - } - return viewContent; - } - - IDisplayBinding binding = DisplayBindingService.GetBindingPerFileName(fileName); - - if (binding == null) { - binding = new ErrorFallbackBinding("Could not find any display binding for " + Path.GetFileName(fileName)); - } - if (FileUtility.ObservedLoad(new NamedFileOperationDelegate(new LoadFileWrapper(binding, switchToOpenedView).Invoke), fileName) == FileOperationResult.OK) { - FileService.RecentOpen.AddLastFile(fileName); - } - return GetOpenFile(fileName); + return SD.FileService.OpenFile(FileName.Create(fileName), switchToOpenedView); } /// @@ -278,7 +118,7 @@ namespace ICSharpCode.SharpDevelop /// Content of the file to create public static IViewContent NewFile(string defaultName, string content) { - return NewFile(defaultName, SD.FileService.DefaultFileEncoding.GetBytesWithPreamble(content)); + return SD.FileService.NewFile(defaultName, content); } /// @@ -288,29 +128,7 @@ namespace ICSharpCode.SharpDevelop /// Content of the file to create public static IViewContent NewFile(string defaultName, byte[] content) { - if (defaultName == null) - throw new ArgumentNullException("defaultName"); - if (content == null) - throw new ArgumentNullException("content"); - - IDisplayBinding binding = DisplayBindingService.GetBindingPerFileName(defaultName); - - if (binding == null) { - binding = new ErrorFallbackBinding("Can't create display binding for file " + defaultName); - } - OpenedFile file = CreateUntitledOpenedFile(defaultName, content); - - IViewContent newContent = binding.CreateContentForFile(file); - if (newContent == null) { - LoggingService.Warn("Created view content was null - DefaultName:" + defaultName); - file.CloseIfAllViewsClosed(); - return null; - } - - DisplayBindingService.AttachSubWindows(newContent, false); - - WorkbenchSingleton.Workbench.ShowView(newContent); - return newContent; + return SD.FileService.NewFile(defaultName, content); } /// @@ -319,13 +137,7 @@ namespace ICSharpCode.SharpDevelop /// public static IList GetOpenFiles() { - List fileNames = new List(); - foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) { - FileName contentName = content.PrimaryFileName; - if (contentName != null && !fileNames.Contains(contentName)) - fileNames.Add(contentName); - } - return fileNames; + return SD.FileService.OpenPrimaryFiles.ToArray(); } /// @@ -333,55 +145,7 @@ namespace ICSharpCode.SharpDevelop /// public static IViewContent GetOpenFile(string fileName) { - if (fileName != null && fileName.Length > 0) { - foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) { - string contentName = content.PrimaryFileName; - if (contentName != null) { - if (FileUtility.IsEqualFileName(fileName, contentName)) - return content; - } - } - } - return null; - } - - public static bool DeleteToRecycleBin { - get { - return PropertyService.Get("SharpDevelop.DeleteToRecycleBin", true); - } - set { - PropertyService.Set("SharpDevelop.DeleteToRecycleBin", value); - } - } - - public static bool SaveUsingTemporaryFile { - get { - return PropertyService.Get("SharpDevelop.SaveUsingTemporaryFile", true); - } - set { - PropertyService.Set("SharpDevelop.SaveUsingTemporaryFile", value); - } - } - - public static int DefaultFileEncodingCodePage { - get { return PropertyService.Get("SharpDevelop.DefaultFileEncoding", 65001); } - set { PropertyService.Set("SharpDevelop.DefaultFileEncoding", value); } - } - - static readonly ReadOnlyCollection allEncodings = Encoding.GetEncodings().OrderBy(e => e.DisplayName).ToArray().AsReadOnly(); - - public static ReadOnlyCollection AllEncodings { - get { return allEncodings; } - } - - public static EncodingInfo DefaultFileEncoding { - get { - int cp = FileService.DefaultFileEncodingCodePage; - return allEncodings.Single(e => e.CodePage == cp); - } - set { - FileService.DefaultFileEncodingCodePage = value.CodePage; - } + return SD.FileService.GetOpenFile(FileName.Create(fileName)); } /// @@ -389,36 +153,7 @@ namespace ICSharpCode.SharpDevelop /// public static void RemoveFile(string fileName, bool isDirectory) { - FileCancelEventArgs eargs = new FileCancelEventArgs(fileName, isDirectory); - OnFileRemoving(eargs); - if (eargs.Cancel) - return; - if (!eargs.OperationAlreadyDone) { - if (isDirectory) { - try { - if (Directory.Exists(fileName)) { - if (DeleteToRecycleBin) - NativeMethods.DeleteToRecycleBin(fileName); - else - Directory.Delete(fileName, true); - } - } catch (Exception e) { - MessageService.ShowHandledException(e, "Can't remove directory " + fileName); - } - } else { - try { - if (File.Exists(fileName)) { - if (DeleteToRecycleBin) - NativeMethods.DeleteToRecycleBin(fileName); - else - File.Delete(fileName); - } - } catch (Exception e) { - MessageService.ShowHandledException(e, "Can't remove file " + fileName); - } - } - } - OnFileRemoved(new FileEventArgs(fileName, isDirectory)); + SD.FileService.RemoveFile(fileName, isDirectory); } /// @@ -426,45 +161,7 @@ namespace ICSharpCode.SharpDevelop /// public static bool RenameFile(string oldName, string newName, bool isDirectory) { - if (FileUtility.IsEqualFileName(oldName, newName)) - return false; - FileChangeWatcher.DisableAllChangeWatchers(); - try { - FileRenamingEventArgs eargs = new FileRenamingEventArgs(oldName, newName, isDirectory); - OnFileRenaming(eargs); - if (eargs.Cancel) - return false; - if (!eargs.OperationAlreadyDone) { - try { - if (isDirectory && Directory.Exists(oldName)) { - - if (Directory.Exists(newName)) { - MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}")); - return false; - } - Directory.Move(oldName, newName); - - } else if (File.Exists(oldName)) { - if (File.Exists(newName)) { - MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}")); - return false; - } - File.Move(oldName, newName); - } - } catch (Exception e) { - if (isDirectory) { - MessageService.ShowHandledException(e, "Can't rename directory " + oldName); - } else { - MessageService.ShowHandledException(e, "Can't rename file " + oldName); - } - return false; - } - } - OnFileRenamed(new FileRenameEventArgs(oldName, newName, isDirectory)); - return true; - } finally { - FileChangeWatcher.EnableAllChangeWatchers(); - } + return SD.FileService.RenameFile(oldName, newName, isDirectory); } /// @@ -472,40 +169,7 @@ namespace ICSharpCode.SharpDevelop /// public static bool CopyFile(string oldName, string newName, bool isDirectory, bool overwrite) { - if (FileUtility.IsEqualFileName(oldName, newName)) - return false; - FileRenamingEventArgs eargs = new FileRenamingEventArgs(oldName, newName, isDirectory); - OnFileCopying(eargs); - if (eargs.Cancel) - return false; - if (!eargs.OperationAlreadyDone) { - try { - if (isDirectory && Directory.Exists(oldName)) { - - if (!overwrite && Directory.Exists(newName)) { - MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}")); - return false; - } - FileUtility.DeepCopy(oldName, newName, overwrite); - - } else if (File.Exists(oldName)) { - if (!overwrite && File.Exists(newName)) { - MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}")); - return false; - } - File.Copy(oldName, newName, overwrite); - } - } catch (Exception e) { - if (isDirectory) { - MessageService.ShowHandledException(e, "Can't copy directory " + oldName); - } else { - MessageService.ShowHandledException(e, "Can't copy file " + oldName); - } - return false; - } - } - OnFileCopied(new FileRenameEventArgs(oldName, newName, isDirectory)); - return true; + return SD.FileService.CopyFile(oldName, newName, isDirectory, overwrite); } /// @@ -514,38 +178,7 @@ namespace ICSharpCode.SharpDevelop /// public static IViewContent JumpToFilePosition(string fileName, int line, int column) { - LoggingService.InfoFormatted("FileService\n\tJumping to File Position: [{0} : {1}x{2}]", fileName, line, column); - - if (fileName == null || fileName.Length == 0) { - return null; - } - - NavigationService.SuspendLogging(); - bool loggingResumed = false; - - try { - IViewContent content = OpenFile(fileName); - if (content is IPositionable) { - // TODO: enable jumping to a particular view - content.WorkbenchWindow.ActiveViewContent = content; - NavigationService.ResumeLogging(); - loggingResumed = true; - ((IPositionable)content).JumpTo(Math.Max(1, line), Math.Max(1, column)); - } else { - NavigationService.ResumeLogging(); - loggingResumed = true; - NavigationService.Log(content); - } - - return content; - - } finally { - LoggingService.InfoFormatted("FileService\n\tJumped to File Position: [{0} : {1}x{2}]", fileName, line, column); - - if (!loggingResumed) { - NavigationService.ResumeLogging(); - } - } + return SD.FileService.JumpToFilePosition(FileName.Create(fileName), line, column); } /// @@ -554,7 +187,8 @@ namespace ICSharpCode.SharpDevelop /// behaviour of the FolderBrowserDialog is used where it selects the /// desktop folder. /// - public static FolderBrowserDialog CreateFolderBrowserDialog(string description, string selectedPath) + [Obsolete("Use SD.FileService.BrowseForFolder instead.")] + public static FolderBrowserDialog CreateFolderBrowserDialog(string description, string selectedPath = null) { FolderBrowserDialog dialog = new FolderBrowserDialog(); dialog.Description = StringParser.Parse(description); @@ -565,59 +199,6 @@ namespace ICSharpCode.SharpDevelop return dialog; } - /// - /// Creates a FolderBrowserDialog that will initially select the - /// desktop folder. - /// - public static FolderBrowserDialog CreateFolderBrowserDialog(string description) - { - return CreateFolderBrowserDialog(description, null); - } - - #region Event Handlers - - static void OnFileRemoved(FileEventArgs e) - { - if (FileRemoved != null) { - FileRemoved(null, e); - } - } - - static void OnFileRemoving(FileCancelEventArgs e) - { - if (FileRemoving != null) { - FileRemoving(null, e); - } - } - - static void OnFileRenamed(FileRenameEventArgs e) - { - if (FileRenamed != null) { - FileRenamed(null, e); - } - } - - static void OnFileRenaming(FileRenamingEventArgs e) { - if (FileRenaming != null) { - FileRenaming(null, e); - } - } - - static void OnFileCopied(FileRenameEventArgs e) - { - if (FileCopied != null) { - FileCopied(null, e); - } - } - - static void OnFileCopying(FileRenamingEventArgs e) { - if (FileCopying != null) { - FileCopying(null, e); - } - } - - #endregion Event Handlers - #region Static event firing methods /// @@ -627,11 +208,7 @@ namespace ICSharpCode.SharpDevelop /// Set to true if this is a directory public static bool FireFileReplacing(string fileName, bool isDirectory) { - FileCancelEventArgs e = new FileCancelEventArgs(fileName, isDirectory); - if (FileReplacing != null) { - FileReplacing(null, e); - } - return !e.Cancel; + return SD.FileService.FireFileReplacing(fileName, isDirectory); } /// @@ -641,9 +218,7 @@ namespace ICSharpCode.SharpDevelop /// Set to true if this is a directory public static void FireFileReplaced(string fileName, bool isDirectory) { - if (FileReplaced != null) { - FileReplaced(null, new FileEventArgs(fileName, isDirectory)); - } + SD.FileService.FireFileReplaced(fileName, isDirectory); } /// @@ -653,59 +228,53 @@ namespace ICSharpCode.SharpDevelop /// Set to true if this is a directory public static void FireFileCreated(string fileName, bool isDirectory) { - if (FileCreated != null) { - FileCreated(null, new FileEventArgs(fileName, isDirectory)); - } + SD.FileService.FireFileCreated(fileName, isDirectory); } #endregion Static event firing methods #region Events - public static event EventHandler FileCreated; - - public static event EventHandler FileRenaming; - public static event EventHandler FileRenamed; + public static event EventHandler FileRenaming { + add { SD.FileService.FileRenaming += value; } + remove { SD.FileService.FileRenaming -= value; } + } + public static event EventHandler FileRenamed { + add { SD.FileService.FileRenamed += value; } + remove { SD.FileService.FileRenamed -= value; } + } - public static event EventHandler FileCopying; - public static event EventHandler FileCopied; + public static event EventHandler FileCopying { + add { SD.FileService.FileCopying += value; } + remove { SD.FileService.FileCopying -= value; } + } + public static event EventHandler FileCopied { + add { SD.FileService.FileCopied += value; } + remove { SD.FileService.FileCopied -= value; } + } - public static event EventHandler FileRemoving; - public static event EventHandler FileRemoved; + public static event EventHandler FileRemoving { + add { SD.FileService.FileRemoving += value; } + remove { SD.FileService.FileRemoving -= value; } + } + public static event EventHandler FileRemoved { + add { SD.FileService.FileRemoved += value; } + remove { SD.FileService.FileRemoved -= value; } + } - public static event EventHandler FileReplacing; - public static event EventHandler FileReplaced; + public static event EventHandler FileCreated { + add { SD.FileService.FileCreated += value; } + remove { SD.FileService.FileCreated -= value; } + } + public static event EventHandler FileReplacing { + add { SD.FileService.FileReplacing += value; } + remove { SD.FileService.FileReplacing -= value; } + } + public static event EventHandler FileReplaced { + add { SD.FileService.FileReplaced += value; } + remove { SD.FileService.FileReplaced -= value; } + } #endregion Events - - sealed class ErrorFallbackBinding : IDisplayBinding - { - string errorMessage; - - public ErrorFallbackBinding(string errorMessage) - { - this.errorMessage = errorMessage; - } - - public bool CanCreateContentForFile(string fileName) - { - return true; - } - - public IViewContent CreateContentForFile(OpenedFile file) - { - return new SimpleViewContent(errorMessage) { TitleName = Path.GetFileName(file.FileName) }; - } - - public bool IsPreferredBindingForFile(string fileName) - { - return false; - } - - public double AutoDetectFileContent(string fileName, Stream fileContent, string detectedMimeType) - { - return double.NegativeInfinity; - } - } } } diff --git a/src/Main/Base/Project/Src/Services/File/IFileService.cs b/src/Main/Base/Project/Src/Services/File/IFileService.cs index 4ac87d0e99..2d894e2be6 100644 --- a/src/Main/Base/Project/Src/Services/File/IFileService.cs +++ b/src/Main/Base/Project/Src/Services/File/IFileService.cs @@ -2,10 +2,13 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Collections.Generic; using System.Text; using System.Threading; + using ICSharpCode.Core; using ICSharpCode.NRefactory.Editor; +using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.SharpDevelop { @@ -14,12 +17,24 @@ namespace ICSharpCode.SharpDevelop /// public interface IFileService { + #region Options + IRecentOpen RecentOpen { get; } + + bool DeleteToRecycleBin { get; set; } + bool SaveUsingTemporaryFile { get; set; } + /// /// Gets the default file encoding. /// This property is thread-safe. /// Encoding DefaultFileEncoding { get; } + EncodingInfo DefaultFileEncodingInfo { get; set; } + + IReadOnlyList AllEncodings { get; } + #endregion + + #region GetFileContent /// /// Gets the content of the specified file. /// If the file is currently open in SharpDevelop, retrieves a snapshot @@ -51,5 +66,185 @@ namespace ICSharpCode.SharpDevelop /// This method is thread-safe. /// ITextSource GetFileContentFromDisk(FileName fileName, CancellationToken cancellationToken = default(CancellationToken)); + #endregion + + #region BrowseForFolder + /// + /// Shows a 'browse for folder' dialog. + /// + /// Description shown in the dialog. + /// Optional: Initially selected folder. + /// The selected folder; or null if the user cancelled the dialog. + string BrowseForFolder(string description, string selectedPath = null); + #endregion + + #region OpenedFiles + /// + /// Gets a collection containing all currently opened files. + /// The returned collection is a read-only copy of the currently opened files - + /// it will not reflect future changes of the list of opened files. + /// + IReadOnlyList OpenedFiles { get; } + + /// + /// Gets an opened file, or returns null if the file is not opened. + /// + OpenedFile GetOpenedFile(string fileName); + + /// + /// Gets an opened file, or returns null if the file is not opened. + /// + OpenedFile GetOpenedFile(FileName fileName); + + /// + /// Gets or creates an opened file. + /// Warning: the opened file will be a file without any views attached. + /// Make sure to attach a view to it, or call CloseIfAllViewsClosed on the OpenedFile to + /// unload the OpenedFile instance if no views were attached to it. + /// + OpenedFile GetOrCreateOpenedFile(string fileName); + + /// + /// Gets or creates an opened file. + /// Warning: the opened file will be a file without any views attached. + /// Make sure to attach a view to it, or call CloseIfAllViewsClosed on the OpenedFile to + /// unload the OpenedFile instance if no views were attached to it. + /// + OpenedFile GetOrCreateOpenedFile(FileName fileName); + + /// + /// Creates a new untitled OpenedFile. + /// + OpenedFile CreateUntitledOpenedFile(string defaultName, byte[] content); + #endregion + + #region CheckFileName + /// + /// Checks if the path is valid and shows a MessageBox if it is not valid. + /// Do not use in non-UI methods. + /// + /// + bool CheckFileName(string path); + + /// + /// Checks that a single directory entry (file or subdirectory) name is valid + /// and shows a MessageBox if it is not valid. + /// + /// A single file name not the full path + /// + bool CheckDirectoryEntryName(string name); + #endregion + + #region OpenFile (ViewContent) + /// + /// Gets whether the file is open in a view content. + /// + bool IsOpen(FileName fileName); + + /// + /// Opens a view content for the specified file + /// or returns the existing view content for the file if it is already open. + /// + /// The name of the file to open. + /// Specifies whether to switch to the view for the specified file. + /// The existing or opened for the specified file. + IViewContent OpenFile(FileName fileName, bool switchToOpenedView = true); + + /// + /// Opens a new unsaved file. + /// + /// The (unsaved) name of the to open + /// Content of the file to create + IViewContent NewFile(string defaultName, string content); + + /// + /// Opens a new unsaved file. + /// + /// The (unsaved) name of the to open + /// Content of the file to create + IViewContent NewFile(string defaultName, byte[] content); + + /// + /// Gets a list of the names of the files that are open as primary files + /// in view contents. + /// + IReadOnlyList OpenPrimaryFiles { get; } + + /// + /// Gets the IViewContent for a fileName. Returns null if the file is not opened currently. + /// + IViewContent GetOpenFile(FileName fileName); + + /// + /// Opens the specified file and jumps to the specified file position. + /// Line and column start counting at 1. + /// + IViewContent JumpToFilePosition(FileName fileName, int line, int column); + #endregion + + #region Remove/Rename/Copy + /// + /// Removes a file, raising the appropriate events. This method may show message boxes. + /// + void RemoveFile(string fileName, bool isDirectory); + + /// + /// Renames or moves a file, raising the appropriate events. This method may show message boxes. + /// + bool RenameFile(string oldName, string newName, bool isDirectory); + + /// + /// Copies a file, raising the appropriate events. This method may show message boxes. + /// + bool CopyFile(string oldName, string newName, bool isDirectory, bool overwrite); + + event EventHandler FileRenaming; + event EventHandler FileRenamed; + + event EventHandler FileCopying; + event EventHandler FileCopied; + + event EventHandler FileRemoving; + event EventHandler FileRemoved; + #endregion + + #region FileCreated/Replaced + /// + /// Fires the event handlers for a file being created. + /// + /// The name of the file being created. This should be a fully qualified path. + /// Set to true if this is a directory + /// True if the operation can proceed, false if an event handler cancelled the operation. + bool FireFileReplacing(string fileName, bool isDirectory); + + /// + /// Fires the event handlers for a file being replaced. + /// + /// The name of the file being created. This should be a fully qualified path. + /// Set to true if this is a directory + void FireFileReplaced(string fileName, bool isDirectory); + + /// + /// Fires the event handlers for a file being created. + /// + /// The name of the file being created. This should be a fully qualified path. + /// Set to true if this is a directory + void FireFileCreated(string fileName, bool isDirectory); + + event EventHandler FileCreated; + event EventHandler FileReplacing; + event EventHandler FileReplaced; + #endregion + } + + public interface IRecentOpen + { + IReadOnlyList RecentFiles { get; } + IReadOnlyList RecentProjects { get; } + + void ClearRecentFiles(); + void ClearRecentProjects(); + void AddRecentFile(string fileName); + void AddRecentProject(string fileName); } } diff --git a/src/Main/Base/Project/Src/Services/File/OpenedFile.cs b/src/Main/Base/Project/Src/Services/File/OpenedFile.cs index c6f3d1f8a8..feb2a0f0f9 100644 --- a/src/Main/Base/Project/Src/Services/File/OpenedFile.cs +++ b/src/Main/Base/Project/Src/Services/File/OpenedFile.cs @@ -201,7 +201,7 @@ namespace ICSharpCode.SharpDevelop throw new InvalidOperationException("Cannot save an untitled file to disk!"); LoggingService.Debug("Save " + FileName); - bool safeSaving = FileService.SaveUsingTemporaryFile && File.Exists(FileName); + bool safeSaving = SD.FileService.SaveUsingTemporaryFile && File.Exists(FileName); string saveAs = safeSaving ? FileName + ".bak" : FileName; using (FileStream fs = new FileStream(saveAs, FileMode.Create, FileAccess.Write)) { if (currentView != null) { @@ -354,149 +354,4 @@ namespace ICSharpCode.SharpDevelop } } } - - sealed class FileServiceOpenedFile : OpenedFile - { - List registeredViews = new List(); - FileChangeWatcher fileChangeWatcher; - - protected override void ChangeFileName(FileName newValue) - { - FileService.OpenedFileFileNameChange(this, this.FileName, newValue); - base.ChangeFileName(newValue); - } - - internal FileServiceOpenedFile(FileName fileName) - { - this.FileName = fileName; - IsUntitled = false; - fileChangeWatcher = new FileChangeWatcher(this); - } - - internal FileServiceOpenedFile(byte[] fileData) - { - this.FileName = null; - SetData(fileData); - IsUntitled = true; - MakeDirty(); - fileChangeWatcher = new FileChangeWatcher(this); - } - - /// - /// Gets the list of view contents registered with this opened file. - /// - public override IList RegisteredViewContents { - get { return registeredViews.AsReadOnly(); } - } - - public override void ForceInitializeView(IViewContent view) - { - if (view == null) - throw new ArgumentNullException("view"); - if (!registeredViews.Contains(view)) - throw new ArgumentException("registeredViews must contain view"); - - base.ForceInitializeView(view); - } - - public override void RegisterView(IViewContent view) - { - if (view == null) - throw new ArgumentNullException("view"); - if (registeredViews.Contains(view)) - throw new ArgumentException("registeredViews already contains view"); - - registeredViews.Add(view); - - if (WorkbenchSingleton.Workbench != null) { - WorkbenchSingleton.Workbench.ActiveViewContentChanged += WorkbenchActiveViewContentChanged; - if (WorkbenchSingleton.Workbench.ActiveViewContent == view) { - SwitchedToView(view); - } - } - #if DEBUG - view.Disposed += ViewDisposed; - #endif - } - - public override void UnregisterView(IViewContent view) - { - if (view == null) - throw new ArgumentNullException("view"); - Debug.Assert(registeredViews.Contains(view)); - - if (WorkbenchSingleton.Workbench != null) { - WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchActiveViewContentChanged; - } - #if DEBUG - view.Disposed -= ViewDisposed; - #endif - - registeredViews.Remove(view); - if (registeredViews.Count > 0) { - if (currentView == view) { - SaveCurrentView(); - currentView = null; - } - } else { - // all views to the file were closed - CloseIfAllViewsClosed(); - } - } - - public override void CloseIfAllViewsClosed() - { - if (registeredViews.Count == 0) { - bool wasDirty = this.IsDirty; - FileService.OpenedFileClosed(this); - - FileClosed.RaiseEvent(this, EventArgs.Empty); - - if (fileChangeWatcher != null) { - fileChangeWatcher.Dispose(); - fileChangeWatcher = null; - } - - if (wasDirty) { - // We discarded some information when closing the file, - // so we need to re-parse it. - if (File.Exists(this.FileName)) - SD.ParserService.ParseAsync(this.FileName).FireAndForget(); - else - SD.ParserService.ClearParseInformation(this.FileName); - } - } - } - - #if DEBUG - void ViewDisposed(object sender, EventArgs e) - { - Debug.Fail("View was disposed while still registered with OpenedFile!"); - } - #endif - - void WorkbenchActiveViewContentChanged(object sender, EventArgs e) - { - IViewContent newView = WorkbenchSingleton.Workbench.ActiveViewContent; - - if (!registeredViews.Contains(newView)) - return; - - SwitchedToView(newView); - } - - public override void SaveToDisk() - { - try { - if (fileChangeWatcher != null) - fileChangeWatcher.Enabled = false; - base.SaveToDisk(); - } finally { - if (fileChangeWatcher != null) - fileChangeWatcher.Enabled = true; - } - } - - public override event EventHandler FileClosed; - } } diff --git a/src/Main/Base/Project/Src/Services/File/RecentOpen.cs b/src/Main/Base/Project/Src/Services/File/RecentOpen.cs deleted file mode 100644 index d6b15b3c12..0000000000 --- a/src/Main/Base/Project/Src/Services/File/RecentOpen.cs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Windows.Shell; -using ICSharpCode.Core; - -namespace ICSharpCode.SharpDevelop -{ - /// - /// This class handles the recent open files and the recent open project files of SharpDevelop - /// it checks, if the files exists at every creation, and if not it doesn't list them in the - /// recent files, and they'll not be saved during the next option save. - /// - public sealed class RecentOpen - { - /// - /// This variable is the maximal length of lastfile/lastopen entries - /// must be > 0 - /// - int MAX_LENGTH = 10; - - readonly ObservableCollection lastfile = new ObservableCollection(); - readonly ObservableCollection lastproject = new ObservableCollection(); - - public IList RecentFile { - get { - return lastfile; - } - } - - public IList RecentProject { - get { - return lastproject; - } - } - - public RecentOpen() - { - } - - public RecentOpen(Properties p) - { - // don't check whether files exist because that might be slow (e.g. if file is on network - // drive that's unavailable) - - lastfile.AddRange(p.GetList("Files")); - lastproject.AddRange(p.GetList("Projects")); - } - - public void AddLastFile(string name) - { - for (int i = 0; i < lastfile.Count; ++i) { - if (lastfile[i].Equals(name, StringComparison.OrdinalIgnoreCase)) { - lastfile.RemoveAt(i); - } - } - - while (lastfile.Count >= MAX_LENGTH) { - lastfile.RemoveAt(lastfile.Count - 1); - } - - lastfile.Insert(0, name); - } - - public void ClearRecentFiles() - { - lastfile.Clear(); - } - - public void ClearRecentProjects() - { - lastproject.Clear(); - } - - public void AddLastProject(string name) - { - for (int i = 0; i < lastproject.Count; ++i) { - if (lastproject[i].ToString().Equals(name, StringComparison.OrdinalIgnoreCase)) { - lastproject.RemoveAt(i); - } - } - - while (lastproject.Count >= MAX_LENGTH) { - lastproject.RemoveAt(lastproject.Count - 1); - } - - lastproject.Insert(0, name); - JumpList.AddToRecentCategory(name); - } - - public static RecentOpen FromXmlElement(Properties properties) - { - return new RecentOpen(properties); - } - - public Properties ToProperties() - { - Properties p = new Properties(); - p.SetList("Files", lastfile); - p.SetList("Projects", lastproject); - return p; - } - - internal void FileRemoved(object sender, FileEventArgs e) - { - for (int i = 0; i < lastfile.Count; ++i) { - string file = lastfile[i].ToString(); - if (e.FileName == file) { - lastfile.RemoveAt(i); - break; - } - } - } - - internal void FileRenamed(object sender, FileRenameEventArgs e) - { - for (int i = 0; i < lastfile.Count; ++i) { - string file = lastfile[i].ToString(); - if (e.SourceFile == file) { - lastfile.RemoveAt(i); - lastfile.Insert(i, e.TargetFile); - break; - } - } - } - } -} diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentFinder.cs b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentFinder.cs index 7e93d6a11c..42bc638f07 100644 --- a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentFinder.cs +++ b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentFinder.cs @@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Project /// public class ParseableFileContentFinder { - FileName[] viewContentFileNamesCollection = SD.MainThread.InvokeIfRequired(() => FileService.OpenedFiles.Select(f => f.FileName).ToArray()); + FileName[] viewContentFileNamesCollection = SD.MainThread.InvokeIfRequired(() => SD.FileService.OpenedFiles.Select(f => f.FileName).ToArray()); /// /// Retrieves the file contents for the specified project items. diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs index 665cc85ea1..0cd67e3b5e 100644 --- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs +++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs @@ -301,6 +301,7 @@ namespace ICSharpCode.SharpDevelop.Project MessageService.ShowException(ex); } SD.ParserService.InvalidateCurrentSolutionSnapshot(); + SD.FileService.RecentOpen.AddRecentProject(openSolution.FileName); Project.Converter.UpgradeViewContent.ShowIfRequired(openSolution); diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs b/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs index 656de6edc0..1ec5c7ae60 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs @@ -237,7 +237,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring [Obsolete] public static ProvidedDocumentInformation GetDocumentInformation(string fileName) { - OpenedFile file = FileService.GetOpenedFile(fileName); + OpenedFile file = SD.FileService.GetOpenedFile(fileName); if (file != null) { IFileDocumentProvider documentProvider = file.CurrentView as IFileDocumentProvider; if (documentProvider != null) { diff --git a/src/Main/Base/Project/Src/Util/FakeXmlViewContent.cs b/src/Main/Base/Project/Src/Util/FakeXmlViewContent.cs index fa3d7f3250..b750baba45 100644 --- a/src/Main/Base/Project/Src/Util/FakeXmlViewContent.cs +++ b/src/Main/Base/Project/Src/Util/FakeXmlViewContent.cs @@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Util { public FakeXmlViewContent(string fileName) { - this.PrimaryFile = FileService.GetOrCreateOpenedFile(fileName); + this.PrimaryFile = SD.FileService.GetOrCreateOpenedFile(fileName); this.oldView = this.PrimaryFile.CurrentView; this.PrimaryFile.RegisterView(this); this.PrimaryFile.SwitchedToView(this); diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/LoadSaveOptions.xaml b/src/Main/SharpDevelop/OptionPanels/LoadSaveOptions.xaml similarity index 81% rename from src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/LoadSaveOptions.xaml rename to src/Main/SharpDevelop/OptionPanels/LoadSaveOptions.xaml index dcbcb06346..3f8c7f67cb 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/LoadSaveOptions.xaml +++ b/src/Main/SharpDevelop/OptionPanels/LoadSaveOptions.xaml @@ -1,8 +1,10 @@  @@ -10,7 +12,7 @@ + IsChecked="{core:OptionBinding wb:WpfWorkbench.LoadDocumentProperties}" /> @@ -23,15 +25,15 @@ + IsChecked="{core:OptionBinding wb:FileService.SaveUsingTemporaryFile}" />