From dea5046becdbdd88006f712c6099f849be61b4ff Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 20 May 2009 13:02:15 +0000 Subject: [PATCH] Refactoring menu for AvalonEdit git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4092 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../AvalonEdit.AddIn/Src/CodeEditor.cs | 9 +++- .../Src/Gui/Pads/ClassBrowser/ClassBrowser.cs | 7 +++- .../ClassBrowserIconService.cs | 2 + .../RefactoringMenuBuilder.cs | 10 ++--- .../Commands/ClassBookmarkMenuBuilder.cs | 10 ++++- .../Commands/ClassMemberMenuBuilder.cs | 10 ++++- .../Src/TextEditor/Gui/Dialogs/GotoDialog.cs | 2 +- .../Base/Project/Src/Util/ExtensionMethods.cs | 41 ++++++++++++++++++- .../Menu/MenuCommand.cs | 6 +-- .../Menu/MenuService.cs | 8 ++-- 10 files changed, 85 insertions(+), 20 deletions(-) diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index d9da35ef1d..3ea22bcd88 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -163,12 +163,19 @@ namespace ICSharpCode.AvalonEdit.AddIn var iconBarMargin = new IconBarMargin(iconBarManager) { TextView = textView }; textEditor.TextArea.LeftMargins.Insert(0, iconBarMargin); - textEditor.TextArea.TextView.ContextMenu = MenuService.CreateContextMenu(adapter, contextMenuPath); textEditor.TextArea.TextView.MouseRightButtonDown += textEditor_TextArea_TextView_MouseRightButtonDown; + textEditor.TextArea.TextView.ContextMenuOpening += textEditor_TextArea_TextView_ContextMenuOpening; return textEditor; } + void textEditor_TextArea_TextView_ContextMenuOpening(object sender, ContextMenuEventArgs e) + { + ITextEditorComponent component = (ITextEditorComponent)sender; + ITextEditor adapter = (ITextEditor)component.GetService(typeof(ITextEditor)); + MenuService.CreateContextMenu(adapter, contextMenuPath).IsOpen = true; + } + void textEditor_TextArea_TextView_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { ITextEditorComponent component = (ITextEditorComponent)sender; diff --git a/src/Main/Base/Project/Src/Gui/Pads/ClassBrowser/ClassBrowser.cs b/src/Main/Base/Project/Src/Gui/Pads/ClassBrowser/ClassBrowser.cs index 89b4a005b6..5580109adb 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ClassBrowser/ClassBrowser.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ClassBrowser/ClassBrowser.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Windows.Forms; using ICSharpCode.Core; @@ -77,7 +78,11 @@ namespace ICSharpCode.SharpDevelop.Gui.ClassBrowser { instance = this; classBrowserTreeView.Dock = DockStyle.Fill; - classBrowserTreeView.ImageList = ClassBrowserIconService.ImageList; + // we need to create a copy of the image list because adding image to + // ClassBrowserIconService.ImageList is not allowed, but the ExtTreeView sometimes + // does add images to its image list. + classBrowserTreeView.ImageList = new ImageList(); + classBrowserTreeView.ImageList.Images.AddRange(ClassBrowserIconService.ImageList.Images.Cast().ToArray()); classBrowserTreeView.AfterSelect += new TreeViewEventHandler(ClassBrowserTreeViewAfterSelect); contentPanel.Controls.Add(classBrowserTreeView); diff --git a/src/Main/Base/Project/Src/Services/ClassBrowserIcons/ClassBrowserIconService.cs b/src/Main/Base/Project/Src/Services/ClassBrowserIcons/ClassBrowserIconService.cs index 6a9dc1cdd4..09fe3bcae6 100644 --- a/src/Main/Base/Project/Src/Services/ClassBrowserIcons/ClassBrowserIconService.cs +++ b/src/Main/Base/Project/Src/Services/ClassBrowserIcons/ClassBrowserIconService.cs @@ -68,6 +68,8 @@ namespace ICSharpCode.SharpDevelop static void AddNewImagesToList() { lock (lockObj) { + if (imglist.Images.Count > imglistEntries.Count) + throw new InvalidOperationException("Too many images in list (list was modified externally?)"); while (imglist.Images.Count < imglistEntries.Count) { imglist.Images.Add(imglistEntries[imglist.Images.Count].Bitmap); } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs index daa06873f1..26b55688e1 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs @@ -67,7 +67,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring definitions.Add(cmb.Member.DotNetName); item = new MenuItem { Header = MemberNode.GetText(cmb.Member), - Icon = cmb.Image.ImageSource, + Icon = cmb.Image.CreateImage(), ItemsSource = MenuService.CreateMenuItems(null, mark, ClassMemberBookmark.ContextMenuPath) }; resultItems.Add(item); @@ -79,7 +79,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring definitions.Add(type.DotNetName); item = new MenuItem { Header = ClassNode.GetText(type), - Icon = ClassBrowserIconService.GetIcon(type).ImageSource, + Icon = ClassBrowserIconService.GetIcon(type).CreateImage(), ItemsSource = MenuService.CreateMenuItems(null, cb ?? new ClassBookmark(type), ClassBookmark.ContextMenuPath) @@ -272,7 +272,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring { MenuItem item = new MenuItem(); item.Header = title; - item.Icon = image.ImageSource; + item.Icon = image.CreateImage(); //ToolStripMenuItem titleItem = new ToolStripMenuItem(title); //titleItem.Enabled = false; @@ -281,8 +281,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring if (cu != null && cu.FileName != null && !region.IsEmpty) { MenuItem gotoDefinitionItem = new MenuItem(); - gotoDefinitionItem.Header = StringParser.Parse("${res:ICSharpCode.NAntAddIn.GotoDefinitionMenuLabel}"); - gotoDefinitionItem.Icon = ClassBrowserIconService.GotoArrow.ImageSource; + gotoDefinitionItem.Header = MenuService.ConvertLabel(StringParser.Parse("${res:ICSharpCode.NAntAddIn.GotoDefinitionMenuLabel}")); + gotoDefinitionItem.Icon = ClassBrowserIconService.GotoArrow.CreatePixelSnappedImage(); gotoDefinitionItem.InputGestureText = new KeyGesture(Key.Enter, ModifierKeys.Control).GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture); gotoDefinitionItem.Click += delegate { FileService.JumpToFilePosition(cu.FileName, region.BeginLine, region.BeginColumn); diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/ClassBookmarkMenuBuilder.cs b/src/Main/Base/Project/Src/TextEditor/Commands/ClassBookmarkMenuBuilder.cs index b85df2638f..aa77374a8f 100644 --- a/src/Main/Base/Project/Src/TextEditor/Commands/ClassBookmarkMenuBuilder.cs +++ b/src/Main/Base/Project/Src/TextEditor/Commands/ClassBookmarkMenuBuilder.cs @@ -5,13 +5,14 @@ // $Revision$ // -using ICSharpCode.NRefactory; +using ICSharpCode.Core.Presentation; using System; using System.Collections.Generic; using System.IO; using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.Core.WinForms; +using ICSharpCode.NRefactory; using ICSharpCode.SharpDevelop.Bookmarks; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom.Refactoring; @@ -27,8 +28,13 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands /// /// Build context menu for class members in the text editor. /// - public class ClassBookmarkMenuBuilder : ISubmenuBuilder + public class ClassBookmarkMenuBuilder : ISubmenuBuilder, IMenuItemBuilder { + public System.Collections.ICollection BuildItems(Codon codon, object owner) + { + return BuildSubmenu(codon, owner).TranslateToWpf(); + } + /// /// Gets a specific part of the compound class. /// diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs b/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs index b119efd6f0..a2ff366b12 100644 --- a/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs +++ b/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs @@ -5,12 +5,13 @@ // $Revision$ // -using ICSharpCode.NRefactory; +using ICSharpCode.Core.Presentation; using System; using System.Collections.Generic; using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.Core.WinForms; +using ICSharpCode.NRefactory; using ICSharpCode.SharpDevelop.Bookmarks; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom.Refactoring; @@ -25,8 +26,13 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands /// /// Build context menu for class members in the text editor. /// - public class ClassMemberMenuBuilder : ISubmenuBuilder + public class ClassMemberMenuBuilder : ISubmenuBuilder, IMenuItemBuilder { + public System.Collections.ICollection BuildItems(Codon codon, object owner) + { + return BuildSubmenu(codon, owner).TranslateToWpf(); + } + public ToolStripItem[] BuildSubmenu(Codon codon, object owner) { MenuCommand cmd; diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs index 1aa41959b5..1b3b8e431a 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs @@ -63,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.Gui this.Content = new StackPanel { Orientation = Orientation.Horizontal, Children = { - new PixelSnapper(new Image { Source = image.ImageSource }), + image.CreatePixelSnappedImage(), new TextBlock { Text = text, Margin = new Thickness(4, 0, 0, 0) diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs index e3453d09d5..6d0c71e7a4 100644 --- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs +++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs @@ -5,17 +5,18 @@ // $Revision$ // -using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.Core.Presentation; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; -using System.Text; using System.Windows.Forms; +using ICSharpCode.SharpDevelop.Gui; using WinForms = System.Windows.Forms; namespace ICSharpCode.SharpDevelop @@ -267,5 +268,41 @@ namespace ICSharpCode.SharpDevelop result.Append(original, currentPos, original.Length - currentPos); return result.ToString(); } + + /// + /// Creates a new image for the image source. + /// + public static Image CreateImage(this IImage image) + { + if (image == null) + throw new ArgumentNullException("image"); + return new Image { Source = image.ImageSource }; + } + + /// + /// Creates a new image for the image source. + /// + public static UIElement CreatePixelSnappedImage(this IImage image) + { + return new PixelSnapper(CreateImage(image)); + } + + /// + /// Translates a WinForms menu to WPF. + /// + public static ICollection TranslateToWpf(this ToolStripItem[] items) + { + return items.OfType().Select(item => TranslateMenuItemToWpf(item)).ToList(); + } + + static System.Windows.Controls.MenuItem TranslateMenuItemToWpf(ToolStripMenuItem item) + { + var r = new System.Windows.Controls.MenuItem(); + r.Header = MenuService.ConvertLabel(item.Text); + if (item.ImageIndex >= 0) + r.Icon = ClassBrowserIconService.GetImageByIndex(item.ImageIndex).CreatePixelSnappedImage(); + r.Click += delegate { item.PerformClick(); }; + return r; + } } } diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs index ccb8d92bdf..c9514275b0 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs @@ -121,9 +121,9 @@ namespace ICSharpCode.Core.Presentation this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) { KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]); - inputBindingOwner.InputBindings.Add( - new InputBinding(this.Command, kg) - ); + if (inputBindingOwner != null) { + inputBindingOwner.InputBindings.Add(new InputBinding(this.Command, kg)); + } this.InputGestureText = kg.GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture); } } diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs index 1314abb979..b4bfe9d78f 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs @@ -94,8 +94,6 @@ namespace ICSharpCode.Core.Presentation public static IList CreateMenuItems(UIElement inputBindingOwner, object owner, string addInTreePath) { - if (inputBindingOwner == null) - throw new ArgumentNullException("inputBindingOwner"); return CreateMenuItems(inputBindingOwner, AddInTree.BuildItems(addInTreePath, owner, false)); } @@ -126,7 +124,7 @@ namespace ICSharpCode.Core.Presentation result.Add(CreateMenuItemFromDescriptor(inputBindingOwner, descriptor)); } } - return result; + return ExpandMenuBuilders(result); } static IList ExpandMenuBuilders(ICollection input) @@ -185,6 +183,10 @@ namespace ICSharpCode.Core.Presentation } } + /// + /// Converts from the Windows-Forms style label format (accessor key marked with '&') + /// to a WPF label format (accessor key marked with '_'). + /// public static string ConvertLabel(string label) { return label.Replace("_", "__").Replace("&", "_");