From a661a68967206d74673309b26aeaae9da8f8ae3c Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 15 Jun 2013 22:40:46 +0200 Subject: [PATCH 01/19] fix context menu commands implemented as ICommand in Windows Forms Designer --- .../ICSharpCode.Core.WinForms.csproj | 9 +++++++++ .../Menu/MenuCommand.cs | 6 +++--- .../Menu/MenuService.cs | 2 ++ src/Main/SharpDevelop/Workbench/WpfWorkbench.cs | 16 ++++++++++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj b/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj index d7ffcfcbe6..d6aabfe10f 100644 --- a/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj +++ b/src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj @@ -44,10 +44,19 @@ + + 3.0 + + + 3.0 + + + 3.0 + diff --git a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs index c323dbbb38..77752791fa 100644 --- a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs @@ -66,9 +66,9 @@ namespace ICSharpCode.Core.WinForms protected override void OnClick(System.EventArgs e) { base.OnClick(e); - if (command != null && command.CanExecute(caller)) { - ServiceSingleton.GetRequiredService().TrackFeature(command.GetType().FullName, "Menu"); - command.Execute(caller); + command = CommandWrapper.Unwrap(command); + if (command != null) { + MenuService.ExecuteCommand(command, caller); } } diff --git a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs index 09e442d6ed..f09238da03 100644 --- a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs +++ b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs @@ -12,6 +12,8 @@ namespace ICSharpCode.Core.WinForms { public static class MenuService { + public static Action ExecuteCommand; + public static void AddItemsToMenu(ToolStripItemCollection collection, object owner, string addInTreePath) { AddItemsToMenu(collection, AddInTree.BuildItems(addInTreePath, owner, false)); diff --git a/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs b/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs index 12ffdcefa3..7b04b7b828 100644 --- a/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs +++ b/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs @@ -121,6 +121,7 @@ namespace ICSharpCode.SharpDevelop.Workbench DockPanel.SetDock(statusBar, Dock.Bottom); dockPanel.Children.Insert(dockPanel.Children.Count - 2, statusBar); + Core.WinForms.MenuService.ExecuteCommand = ExecuteCommand; UpdateMenu(); AddHandler(Hyperlink.RequestNavigateEvent, new RequestNavigateEventHandler(OnRequestNavigate)); @@ -140,6 +141,21 @@ namespace ICSharpCode.SharpDevelop.Workbench SD.StatusBar.SetMessage("${res:MainWindow.StatusBar.ReadyMessage}"); } + void ExecuteCommand(ICommand command, object caller) + { + ServiceSingleton.GetRequiredService() + .TrackFeature(command.GetType().FullName, "Menu"); + var routedCommand = command as System.Windows.Input.RoutedCommand; + if (routedCommand != null) { + var target = System.Windows.Input.FocusManager.GetFocusedElement(this); + if (routedCommand.CanExecute(caller, target)) + routedCommand.Execute(caller, target); + } else { + if (command.CanExecute(caller)) + command.Execute(caller); + } + } + // keep a reference to the event handler to prevent it from being garbage collected // (CommandManager.RequerySuggested only keeps weak references to the event handlers) EventHandler requerySuggestedEventHandler; From 172436e4c2d77c4566ac9fd211cf840eea44fadd Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 16 Jun 2013 07:54:59 +0200 Subject: [PATCH 02/19] fix order of file creation from template: 1. create the file 2. if it's not unnamed write it to disk 3. add it to the project 4. open view content --- .../Templates/File/FileTemplateImpl.cs | 70 ++++++++++++------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs b/src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs index a328c36d0d..b3431b9f06 100644 --- a/src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs +++ b/src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs @@ -12,6 +12,7 @@ using System.Xml; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Templates { @@ -432,20 +433,18 @@ namespace ICSharpCode.SharpDevelop.Templates return null; } } - var createdFiles = new List>(); ScriptRunner scriptRunner = new ScriptRunner(); foreach (FileDescriptionTemplate newFile in FileDescriptionTemplates) { FileOperationResult opresult = FileUtility.ObservedSave( () => { string resultFile; if (!String.IsNullOrEmpty(newFile.BinaryFileName)) { - resultFile = SaveFile(newFile, null, newFile.BinaryFileName); + resultFile = SaveFile(newFile, null, newFile.BinaryFileName, options); } else { - resultFile = SaveFile(newFile, scriptRunner.CompileScript(this, newFile), null); + resultFile = SaveFile(newFile, scriptRunner.CompileScript(this, newFile), null, options); } if (resultFile != null) { result.NewFiles.Add(FileName.Create(resultFile)); - createdFiles.Add(new KeyValuePair(resultFile, newFile)); } }, FileName.Create(StringParser.Parse(newFile.Name)) ); @@ -454,14 +453,6 @@ namespace ICSharpCode.SharpDevelop.Templates } if (project != null) { - foreach (KeyValuePair createdFile in createdFiles) { - FileName fileName = FileName.Create(createdFile.Key); - ItemType type = project.GetDefaultItemType(fileName); - FileProjectItem newItem = new FileProjectItem(project, type); - newItem.FileName = fileName; - createdFile.Value.SetProjectItemProperties(newItem); - project.Items.Add(newItem); - } project.Save(); } @@ -480,9 +471,9 @@ namespace ICSharpCode.SharpDevelop.Templates return true; } - string SaveFile(FileDescriptionTemplate newfile, string content, string binaryFileName) + string SaveFile(FileDescriptionTemplate newFile, string content, string binaryFileName, FileTemplateOptions options) { - string unresolvedFileName = StringParser.Parse(newfile.Name); + string unresolvedFileName = StringParser.Parse(newFile.Name); // Parse twice so that tags used in included standard header are parsed string parsedContent = StringParser.Parse(StringParser.Parse(content)); @@ -502,28 +493,55 @@ namespace ICSharpCode.SharpDevelop.Templates unresolvedFileName = unresolvedFileName.Substring(1); } - if (newfile.IsDependentFile && Path.IsPathRooted(unresolvedFileName)) { - Directory.CreateDirectory(Path.GetDirectoryName(unresolvedFileName)); + var project = options.Project; + var fileName = FileName.Create(unresolvedFileName); + + if (newFile.IsDependentFile && Path.IsPathRooted(fileName)) { + Directory.CreateDirectory(Path.GetDirectoryName(fileName)); if (!String.IsNullOrEmpty(binaryFileName)) - File.Copy(binaryFileName, unresolvedFileName); + File.Copy(binaryFileName, fileName); else - File.WriteAllText(unresolvedFileName, parsedContent, SD.FileService.DefaultFileEncoding); + File.WriteAllText(fileName, parsedContent, SD.FileService.DefaultFileEncoding); + if (project != null) + AddTemplateFileToProject(project, newFile, fileName); } else { if (!String.IsNullOrEmpty(binaryFileName)) { LoggingService.Warn("binary file was skipped"); return null; } - IViewContent viewContent = FileService.NewFile(Path.GetFileName(unresolvedFileName), parsedContent); - if (viewContent == null) { - return null; - } - if (Path.IsPathRooted(unresolvedFileName)) { - Directory.CreateDirectory(Path.GetDirectoryName(unresolvedFileName)); - viewContent.PrimaryFile.SaveToDisk(FileName.Create(unresolvedFileName)); + var data = SD.FileService.DefaultFileEncoding.GetBytesWithPreamble(parsedContent); + OpenedFile file = null; + try { + if (Path.IsPathRooted(fileName)) { + file = SD.FileService.GetOrCreateOpenedFile(fileName); + file.SetData(data); + + Directory.CreateDirectory(Path.GetDirectoryName(fileName)); + file.SaveToDisk(); + + if (project != null) + AddTemplateFileToProject(project, newFile, fileName); + } else { + file = SD.FileService.CreateUntitledOpenedFile(Path.GetFileName(fileName), data); + } + + SD.FileService.OpenFile(file.FileName); + } finally { + if (file != null) + file.CloseIfAllViewsClosed(); } } - return unresolvedFileName; + + return fileName; } + static void AddTemplateFileToProject(IProject project, FileDescriptionTemplate newFile, FileName fileName) + { + ItemType type = project.GetDefaultItemType(fileName); + FileProjectItem newItem = new FileProjectItem(project, type); + newItem.FileName = fileName; + newFile.SetProjectItemProperties(newItem); + project.Items.Add(newItem); + } } } From 77562789342440232332b1667ff201c909bb5d57 Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Sat, 15 Jun 2013 20:19:16 +0200 Subject: [PATCH 03/19] Added first version of symbol rename dialog. --- .../Project/ICSharpCode.SharpDevelop.csproj | 6 ++ .../Editor/Commands/FindReferencesCommand.cs | 51 +++++----- .../Commands/SymbolUnderCaretMenuCommand.cs | 25 ++++- .../Editor/Dialogs/RenameSymbolDialog.xaml | 83 ++++++++++++++++ .../Editor/Dialogs/RenameSymbolDialog.xaml.cs | 94 +++++++++++++++++++ 5 files changed, 232 insertions(+), 27 deletions(-) create mode 100644 src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml create mode 100644 src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml.cs diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 8c746ab3de..8bdfb532a7 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -202,6 +202,10 @@ + + RenameSymbolDialog.xaml + Code + @@ -806,11 +810,13 @@ + + diff --git a/src/Main/Base/Project/Src/Editor/Commands/FindReferencesCommand.cs b/src/Main/Base/Project/Src/Editor/Commands/FindReferencesCommand.cs index 81c0df9fc0..28d838bc6f 100644 --- a/src/Main/Base/Project/Src/Editor/Commands/FindReferencesCommand.cs +++ b/src/Main/Base/Project/Src/Editor/Commands/FindReferencesCommand.cs @@ -4,6 +4,7 @@ using System; using ICSharpCode.Core; using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.SharpDevelop.Editor.Dialogs; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Refactoring; @@ -35,38 +36,44 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands public override void Run(ResolveResult symbol) { var entity = GetEntity(symbol); - - string title = "${res:SharpDevelop.Refactoring.Rename}"; - string text = title; // TODO add proper text - if (entity != null) { - switch (entity.SymbolKind) { - case ICSharpCode.NRefactory.TypeSystem.SymbolKind.TypeDefinition: - text = "${res:SharpDevelop.Refactoring.RenameClassText}"; - break; - default: - text = "${res:SharpDevelop.Refactoring.RenameMemberText}"; - break; - } - - string newName = SD.MessageService.ShowInputBox(title, text, entity.Name); - if (newName != entity.Name) { - if (!CheckName(newName)) { - SD.MessageService.ShowError("The symbol cannot be renamed because its new name is invalid!"); - return; - } + if (entity != null) { + RenameSymbolDialog renameDialog = new RenameSymbolDialog(CheckName) + { + Owner = SD.Workbench.MainWindow, + OldSymbolName = entity.Name, + NewSymbolName = entity.Name + }; + if ((bool) renameDialog.ShowDialog()) { using (IProgressMonitor progressMonitor = AsynchronousWaitDialog.ShowWaitDialog("${res:SharpDevelop.Refactoring.Rename}")) - FindReferenceService.RenameSymbol(entity, newName, progressMonitor) + FindReferenceService.RenameSymbol(entity, renameDialog.NewSymbolName, progressMonitor) .ObserveOnUIThread() .Subscribe(error => SD.MessageService.ShowError(error.Message), ex => SD.MessageService.ShowException(ex), () => {}); } } - } bool CheckName(string name) { // TODO implement for current language! - return !string.IsNullOrWhiteSpace(name); + if (string.IsNullOrEmpty(name)) + return false; + + for (int i = 0; i < name.Length; i++) { + char thisChar = name[i]; + if (!Char.IsLetter(thisChar) + && !Char.IsDigit(thisChar) + && (thisChar != '_')) + return false; + } + + return true; + } + + public override bool CanExecute(ResolveResult symbol) + { + if (symbol == null) + return false; + return !symbol.GetDefinitionRegion().IsEmpty; } } } diff --git a/src/Main/Base/Project/Src/Editor/Commands/SymbolUnderCaretMenuCommand.cs b/src/Main/Base/Project/Src/Editor/Commands/SymbolUnderCaretMenuCommand.cs index 9a8517d1dd..a1761cacf9 100644 --- a/src/Main/Base/Project/Src/Editor/Commands/SymbolUnderCaretMenuCommand.cs +++ b/src/Main/Base/Project/Src/Editor/Commands/SymbolUnderCaretMenuCommand.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Windows.Input; using ICSharpCode.Core; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Semantics; @@ -21,17 +22,31 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands /// /// If the owner isn't one of the types above, the command operates on the caret position in the current editor. /// - public abstract class ResolveResultMenuCommand : AbstractMenuCommand + public abstract class ResolveResultMenuCommand : ICommand { - public abstract void Run(ResolveResult symbol); - - public override void Run() + public virtual event EventHandler CanExecuteChanged { add {} remove {} } + + public bool CanExecute(object parameter) + { + ITextEditor editor = SD.GetActiveViewContentService(); + ResolveResult resolveResult = GetResolveResult(editor, parameter); + return CanExecute(resolveResult); + } + + public void Execute(object parameter) { ITextEditor editor = SD.GetActiveViewContentService(); - ResolveResult resolveResult = GetResolveResult(editor, Owner); + ResolveResult resolveResult = GetResolveResult(editor, parameter); Run(resolveResult); } + public abstract void Run(ResolveResult symbol); + + public virtual bool CanExecute(ResolveResult symbol) + { + return true; + } + public static ResolveResult GetResolveResult(object owner) { return GetResolveResult(null, owner); diff --git a/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml b/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml new file mode 100644 index 0000000000..df581d434d --- /dev/null +++ b/src/Main/Base/Project/Src/Editor/Dialogs/RenameSymbolDialog.xaml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +