diff --git a/ICSharpCode.Decompiler/Metadata/MetadataFile.cs b/ICSharpCode.Decompiler/Metadata/MetadataFile.cs index ac0c1da1f..0e00052d6 100644 --- a/ICSharpCode.Decompiler/Metadata/MetadataFile.cs +++ b/ICSharpCode.Decompiler/Metadata/MetadataFile.cs @@ -73,9 +73,12 @@ namespace ICSharpCode.Decompiler.Metadata if (value == null) { var metadata = Metadata; - value = metadata.IsAssembly - ? metadata.GetString(metadata.GetAssemblyDefinition().Name) - : metadata.GetString(metadata.GetModuleDefinition().Name); + if (metadata.IsAssembly) + value = metadata.GetString(metadata.GetAssemblyDefinition().Name); + else if (metadata.DebugMetadataHeader == null) // standalone debug metadata does not contain module table + value = metadata.GetString(metadata.GetModuleDefinition().Name); + else + value = "debug metadata"; value = LazyInit.GetOrSet(ref name, value); } return value; diff --git a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs index 01b505736..a63fc9817 100644 --- a/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs +++ b/ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs @@ -126,6 +126,10 @@ namespace ICSharpCode.ILSpyX.TreeView get { return null; } } + public virtual object? NavigationText { + get { return Text; } + } + public virtual object? Icon { get { return null; } } diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index 7f2829e03..675eeda4d 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -853,15 +853,24 @@ namespace ICSharpCode.ILSpy.AssemblyTree #endregion - public void NavigateHistory(bool forward) + public void NavigateHistory(bool forward, NavigationState? toState = null) { try { TabPageModel tabPage = DockWorkspace.ActiveTabPage; - var state = tabPage.GetState(); - if (state != null) - history.UpdateCurrent(new NavigationState(tabPage, state)); - var newState = forward ? history.GoForward() : history.GoBack(); + var currentState = tabPage.GetState(); + if (currentState != null) + history.UpdateCurrent(new NavigationState(tabPage, currentState)); + + NavigationState newState; + do + { + newState = forward ? history.GoForward() : history.GoBack(); + } while (newState != null && toState != null && toState != newState); + + if (newState == null) + return; + navigatingToState = newState; TabPageModel activeTabPage = newState.TabPage; @@ -884,6 +893,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree } } + public NavigationState[] GetNavigateHistory(bool forward) => forward ? history.ForwardList : history.BackList; + public bool CanNavigateBack => history.CanNavigateBack; public bool CanNavigateForward => history.CanNavigateForward; diff --git a/ILSpy/Commands/BrowseBackCommand.cs b/ILSpy/Commands/BrowseBackCommand.cs index d52f4d734..2db604b65 100644 --- a/ILSpy/Commands/BrowseBackCommand.cs +++ b/ILSpy/Commands/BrowseBackCommand.cs @@ -16,7 +16,9 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Collections; using System.Composition; +using System.Linq; using System.Windows.Input; using ICSharpCode.ILSpy.AssemblyTree; @@ -26,7 +28,7 @@ namespace ICSharpCode.ILSpy { [ExportToolbarCommand(ToolTip = nameof(Resources.Back), ToolbarIcon = "Images/Back", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 0)] [Shared] - sealed class BrowseBackCommand : CommandWrapper + sealed class BrowseBackCommand : CommandWrapper, IProvideParameterList { readonly AssemblyTreeModel assemblyTreeModel; @@ -49,8 +51,15 @@ namespace ICSharpCode.ILSpy if (assemblyTreeModel.CanNavigateBack) { e.Handled = true; - assemblyTreeModel.NavigateHistory(false); + assemblyTreeModel.NavigateHistory(false, e.Parameter as NavigationState); } } + + public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(false).Reverse(); + + public object GetParameterText(object parameter) + { + return (parameter as NavigationState)?.NavigationText; + } } } diff --git a/ILSpy/Commands/BrowseForwardCommand.cs b/ILSpy/Commands/BrowseForwardCommand.cs index 1eb264856..022c74936 100644 --- a/ILSpy/Commands/BrowseForwardCommand.cs +++ b/ILSpy/Commands/BrowseForwardCommand.cs @@ -16,7 +16,9 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Collections; using System.Composition; +using System.Linq; using System.Windows.Input; using ICSharpCode.ILSpy.AssemblyTree; @@ -26,7 +28,7 @@ namespace ICSharpCode.ILSpy { [ExportToolbarCommand(ToolTip = nameof(Resources.Forward), ToolbarIcon = "Images/Forward", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 1)] [Shared] - sealed class BrowseForwardCommand : CommandWrapper + sealed class BrowseForwardCommand : CommandWrapper, IProvideParameterList { private readonly AssemblyTreeModel assemblyTreeModel; @@ -49,9 +51,15 @@ namespace ICSharpCode.ILSpy if (assemblyTreeModel.CanNavigateForward) { e.Handled = true; - assemblyTreeModel.NavigateHistory(true); + assemblyTreeModel.NavigateHistory(true, e.Parameter as NavigationState); } } + public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(true).Reverse(); + + public object GetParameterText(object parameter) + { + return (parameter as NavigationState)?.NavigationText; + } } } diff --git a/ILSpy/Commands/SimpleCommand.cs b/ILSpy/Commands/SimpleCommand.cs index 19c1c7c9e..f57d07571 100644 --- a/ILSpy/Commands/SimpleCommand.cs +++ b/ILSpy/Commands/SimpleCommand.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections; using System.Windows.Data; using System.Windows.Input; @@ -41,4 +42,10 @@ namespace ICSharpCode.ILSpy { Binding ParameterBinding { get; } } + + public interface IProvideParameterList + { + IEnumerable ParameterList { get; } + object GetParameterText(object parameter); + } } diff --git a/ILSpy/Controls/MainToolBar.xaml.cs b/ILSpy/Controls/MainToolBar.xaml.cs index 246d68d6c..e76d19c9c 100644 --- a/ILSpy/Controls/MainToolBar.xaml.cs +++ b/ILSpy/Controls/MainToolBar.xaml.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.ComponentModel; using System.Composition; using System.Linq; using System.Windows; @@ -23,9 +25,11 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; +using System.Windows.Media; using System.Windows.Threading; using ICSharpCode.ILSpy.Themes; +using ICSharpCode.ILSpyX.TreeView; using TomsToolbox.Composition; @@ -85,7 +89,8 @@ namespace ICSharpCode.ILSpy.Controls } } - static Button CreateToolbarItem(IExport commandExport) + + static UIElement CreateToolbarItem(IExport commandExport) { var command = commandExport.Value; @@ -108,9 +113,106 @@ namespace ICSharpCode.ILSpy.Controls parameterBinding.ParameterBinding); } + if (command is IProvideParameterList parameterList) + { + toolbarItem.Margin = new Thickness(2, 0, 0, 0); + + var dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal }; + + var dropDownToggle = new ToggleButton { + Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(), + Content = "▾", + Padding = new Thickness(0), + MinWidth = 0, + Margin = new Thickness(0, 0, 2, 0) + }; + + var contextMenu = new ContextMenu { + PlacementTarget = dropDownPanel, + Tag = command + }; + + ContextMenuService.SetPlacement(toolbarItem, PlacementMode.Bottom); + toolbarItem.ContextMenu = contextMenu; + toolbarItem.ContextMenuOpening += (_, _) => + PrepareParameterList(contextMenu); + dropDownToggle.Checked += (_, _) => { + PrepareParameterList(contextMenu); + contextMenu.Placement = PlacementMode.Bottom; + contextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true); + }; + + BindingOperations.SetBinding(dropDownToggle, ToggleButton.IsCheckedProperty, + new Binding(nameof(contextMenu.IsOpen)) { Source = contextMenu }); + + BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty, + new Binding(nameof(IsEnabled)) { Source = toolbarItem }); + + // When the toggle button is checked, clicking it to uncheck will dismiss the menu first + // which unchecks the toggle button via binding above and the click is used to open it again. + // This is a workaround to ignore the click to uncheck the already unchecked toggle button. + // We have to ensure the dismissing click is on the toggle button, otherwise the flag + // will not get cleared and menu will not open next time. + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(contextMenu, (_, e) => { + var point = e.GetPosition(dropDownToggle); + dropDownToggle.Tag = dropDownToggle.InputHitTest(point); + }); + dropDownToggle.PreviewMouseLeftButtonDown += (_, e) => { + e.Handled = dropDownToggle.Tag != null; + dropDownToggle.Tag = null; + }; + + dropDownPanel.Children.Add(toolbarItem); + dropDownPanel.Children.Add(dropDownToggle); + return dropDownPanel; + } + return toolbarItem; } + static void PrepareParameterList(ContextMenu menu) + { + const int maximumParameterListCount = 20; + + var command = (ICommand)menu.Tag; + var parameterList = (IProvideParameterList)command; + + menu.Items.Clear(); + foreach (var parameter in parameterList.ParameterList) + { + MenuItem parameterItem = new MenuItem(); + parameterItem.Command = CommandWrapper.Unwrap(command); + parameterItem.CommandParameter = parameter; + parameterItem.CommandTarget = menu.PlacementTarget; + parameterItem.InputGestureText = " "; + + var headerPresenter = new ContentPresenter { RecognizesAccessKey = false }; + parameterItem.Header = headerPresenter; + + var header = parameterList.GetParameterText(parameter); + switch (header) + { + case SharpTreeNode node: + headerPresenter.Content = node.NavigationText; + if (node.Icon is ImageSource icon) + parameterItem.Icon = new Image { + Width = 16, + Height = 16, + Source = icon + }; + break; + + default: + headerPresenter.Content = header; + break; + } + + menu.Items.Add(parameterItem); + if (menu.Items.Count >= maximumParameterListCount) + break; + } + } + void MainWindow_KeyDown(object sender, KeyEventArgs e) { if (e.Handled || e.KeyboardDevice.Modifiers != ModifierKeys.Alt || e.Key != Key.System) diff --git a/ILSpy/Metadata/CoffHeaderTreeNode.cs b/ILSpy/Metadata/CoffHeaderTreeNode.cs index 71a4a491a..20b46050f 100644 --- a/ILSpy/Metadata/CoffHeaderTreeNode.cs +++ b/ILSpy/Metadata/CoffHeaderTreeNode.cs @@ -43,6 +43,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "COFF Header"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.Header; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/Metadata/DataDirectoriesTreeNode.cs b/ILSpy/Metadata/DataDirectoriesTreeNode.cs index c54fa9b2c..0b5d4f31c 100644 --- a/ILSpy/Metadata/DataDirectoriesTreeNode.cs +++ b/ILSpy/Metadata/DataDirectoriesTreeNode.cs @@ -35,6 +35,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "Data Directories"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.ListFolder; public override object ExpandedIcon => Images.ListFolderOpen; diff --git a/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs b/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs index da233ca38..6326a8660 100644 --- a/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs +++ b/ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs @@ -40,6 +40,8 @@ namespace ICSharpCode.ILSpy.Metadata override public object Text => entry.Type.ToString(); + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.MetadataTable; public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) diff --git a/ILSpy/Metadata/DebugDirectoryTreeNode.cs b/ILSpy/Metadata/DebugDirectoryTreeNode.cs index ceaa6cf3e..37f6f7e89 100644 --- a/ILSpy/Metadata/DebugDirectoryTreeNode.cs +++ b/ILSpy/Metadata/DebugDirectoryTreeNode.cs @@ -40,6 +40,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "Debug Directory"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.ListFolder; public override object ExpandedIcon => Images.ListFolderOpen; diff --git a/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs b/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs index 5ce76eaa6..8131f0910 100644 --- a/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs +++ b/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs @@ -37,6 +37,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "Tables"; + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.MetadataTableGroup; protected override void LoadChildren() diff --git a/ILSpy/Metadata/DosHeaderTreeNode.cs b/ILSpy/Metadata/DosHeaderTreeNode.cs index 59845ea8d..1deec9717 100644 --- a/ILSpy/Metadata/DosHeaderTreeNode.cs +++ b/ILSpy/Metadata/DosHeaderTreeNode.cs @@ -36,6 +36,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "DOS Header"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.Header; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/Metadata/MetadataHeapTreeNode.cs b/ILSpy/Metadata/MetadataHeapTreeNode.cs index 2c0ee3c79..a74ccd647 100644 --- a/ILSpy/Metadata/MetadataHeapTreeNode.cs +++ b/ILSpy/Metadata/MetadataHeapTreeNode.cs @@ -33,6 +33,8 @@ namespace ICSharpCode.ILSpy.Metadata public HandleKind Kind { get; } + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.Heap; public MetadataHeapTreeNode(HandleKind kind, MetadataFile metadataFile) diff --git a/ILSpy/Metadata/MetadataTableTreeNode.cs b/ILSpy/Metadata/MetadataTableTreeNode.cs index e826bdc46..ccc13c60d 100644 --- a/ILSpy/Metadata/MetadataTableTreeNode.cs +++ b/ILSpy/Metadata/MetadataTableTreeNode.cs @@ -39,6 +39,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => $"{(int)Kind:X2} {Kind} ({metadataFile.Metadata.GetTableRowCount(Kind)})"; + public override object NavigationText => $"{(int)Kind:X2} {Kind} ({metadataFile.Name})"; + public override object Icon => Images.MetadataTable; public MetadataTableTreeNode(TableIndex table, MetadataFile metadataFile) diff --git a/ILSpy/Metadata/MetadataTablesTreeNode.cs b/ILSpy/Metadata/MetadataTablesTreeNode.cs index e7a1ae934..f00894e4b 100644 --- a/ILSpy/Metadata/MetadataTablesTreeNode.cs +++ b/ILSpy/Metadata/MetadataTablesTreeNode.cs @@ -39,6 +39,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "Tables"; + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.MetadataTableGroup; protected override void LoadChildren() diff --git a/ILSpy/Metadata/MetadataTreeNode.cs b/ILSpy/Metadata/MetadataTreeNode.cs index e4fe18b8c..b82a38eb1 100644 --- a/ILSpy/Metadata/MetadataTreeNode.cs +++ b/ILSpy/Metadata/MetadataTreeNode.cs @@ -45,6 +45,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => title; + public override object NavigationText => $"{Text} ({metadataFile.Name})"; + public override object Icon => Images.Metadata; public override bool View(TabPageModel tabPage) diff --git a/ILSpy/Metadata/OptionalHeaderTreeNode.cs b/ILSpy/Metadata/OptionalHeaderTreeNode.cs index aa7cf2e7a..7ad743f35 100644 --- a/ILSpy/Metadata/OptionalHeaderTreeNode.cs +++ b/ILSpy/Metadata/OptionalHeaderTreeNode.cs @@ -42,6 +42,8 @@ namespace ICSharpCode.ILSpy.Metadata public override object Text => "Optional Header"; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.Header; public override bool View(ViewModels.TabPageModel tabPage) diff --git a/ILSpy/NavigationHistory.cs b/ILSpy/NavigationHistory.cs index 30f428a84..6e9f6ed70 100644 --- a/ILSpy/NavigationHistory.cs +++ b/ILSpy/NavigationHistory.cs @@ -34,6 +34,9 @@ namespace ICSharpCode.ILSpy List back = new List(); List forward = new List(); + public T[] BackList => back.ToArray(); + public T[] ForwardList => forward.ToArray(); + public bool CanNavigateBack { get { return back.Count > 0; } } diff --git a/ILSpy/NavigationState.cs b/ILSpy/NavigationState.cs index 287b849cc..7e7151fa0 100644 --- a/ILSpy/NavigationState.cs +++ b/ILSpy/NavigationState.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.ViewModels; @@ -62,5 +63,20 @@ namespace ICSharpCode.ILSpy return this.ViewState.Equals(other.ViewState); } + + public object NavigationText { + get { + if (this.treeNodes.Count == 1) + return this.treeNodes.First(); + + if (this.treeNodes.Count > 0) + return string.Join(", ", treeNodes.Select(tn => tn.NavigationText)); + + if (this.ViewState?.ViewedUri is Uri uri) + return uri; + + return ToString(); + } + } } } diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs index c1b7320bd..6d551814b 100644 --- a/ILSpy/Properties/Resources.Designer.cs +++ b/ILSpy/Properties/Resources.Designer.cs @@ -2401,6 +2401,15 @@ namespace ICSharpCode.ILSpy.Properties { } } + /// + /// Looks up a localized string similar to Referenced Types. + /// + public static string ReferencedTypes { + get { + return ResourceManager.GetString("ReferencedTypes", resourceCulture); + } + } + /// /// Looks up a localized string similar to Reference Name. /// diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx index 2a01be143..992792751 100644 --- a/ILSpy/Properties/Resources.resx +++ b/ILSpy/Properties/Resources.resx @@ -824,6 +824,9 @@ If this does not solve the problem and your system supports long paths, you can Reference Name + + Referenced Types + References diff --git a/ILSpy/Themes/ThemeManager.cs b/ILSpy/Themes/ThemeManager.cs index 667fc83e6..3b5b1f8ec 100644 --- a/ILSpy/Themes/ThemeManager.cs +++ b/ILSpy/Themes/ThemeManager.cs @@ -24,6 +24,7 @@ using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Media; using ICSharpCode.AvalonEdit.Highlighting; @@ -81,6 +82,11 @@ namespace ICSharpCode.ILSpy.Themes return new Style(typeof(Button), (Style)Application.Current.FindResource(ToolBar.ButtonStyleKey)); } + public Style CreateToolBarToggleButtonStyle() + { + return new Style(typeof(ToggleButton), (Style)Application.Current.FindResource(ToolBar.ToggleButtonStyleKey)); + } + public void ApplyHighlightingColors(IHighlightingDefinition highlightingDefinition) { // Make sure all color values are taken from the theme diff --git a/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs index 3f811a0ed..edc441188 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs @@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy.TreeNodes this.LazyLoading = true; } - public override object Text => $"Referenced Types ({r.TypeReferences.Length + r.ExportedTypes.Length})"; + public override object Text => $"{Properties.Resources.ReferencedTypes} ({r.TypeReferences.Length + r.ExportedTypes.Length})"; public override object Icon => Images.MetadataTable; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs index 7eeae132c..b83e885af 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs @@ -53,6 +53,8 @@ namespace ICSharpCode.ILSpy.TreeNodes get { return Language.EscapeName(r.Name) + GetSuffixString(r.Handle); } } + public override object NavigationText => $"{Text} ({Properties.Resources.References})"; + public override object Icon => ImagesProvider.Assembly; public override bool ShowExpander { diff --git a/ILSpy/TreeNodes/BaseTypesEntryNode.cs b/ILSpy/TreeNodes/BaseTypesEntryNode.cs index 0c1f68b33..7d6168aff 100644 --- a/ILSpy/TreeNodes/BaseTypesEntryNode.cs +++ b/ILSpy/TreeNodes/BaseTypesEntryNode.cs @@ -36,6 +36,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => this.Language.TypeToString(type, includeNamespace: true); + public override object NavigationText => $"{Text} ({Properties.Resources.BaseTypes})"; + public override object Icon => type.Kind == TypeKind.Interface ? Images.Interface : Images.Class; public override void ActivateItem(IPlatformRoutedEventArgs e) diff --git a/ILSpy/TreeNodes/BaseTypesTreeNode.cs b/ILSpy/TreeNodes/BaseTypesTreeNode.cs index 150408b7f..d19184ffa 100644 --- a/ILSpy/TreeNodes/BaseTypesTreeNode.cs +++ b/ILSpy/TreeNodes/BaseTypesTreeNode.cs @@ -46,6 +46,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => Properties.Resources.BaseTypes; + public override object NavigationText => $"{Text} ({this.Language.TypeToString(type, includeNamespace: true)})"; + public override object Icon => Images.SuperTypes; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs index ee60a3e9c..3e511b704 100644 --- a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs @@ -47,6 +47,8 @@ namespace ICSharpCode.ILSpy.TreeNodes get { return Language.TypeToString(type, includeNamespace: true) + GetSuffixString(type.MetadataToken); } } + public override object NavigationText => $"{Text} ({Properties.Resources.DerivedTypes})"; + public override object Icon => TypeTreeNode.GetIcon(type); public override FilterResult Filter(LanguageSettings settings) diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 220250ec0..fdf250030 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -46,6 +46,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => Resources.DerivedTypes; + public override object NavigationText => $"{Text} ({this.Language.TypeToString(type, includeNamespace: true)})"; + public override object Icon => Images.SubTypes; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/EventTreeNode.cs b/ILSpy/TreeNodes/EventTreeNode.cs index b03d16d4d..1c10674e9 100644 --- a/ILSpy/TreeNodes/EventTreeNode.cs +++ b/ILSpy/TreeNodes/EventTreeNode.cs @@ -49,6 +49,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => GetText(GetEventDefinition(), this.Language) + GetSuffixString(EventDefinition); + public override object NavigationText => GetText(GetEventDefinition(), Language, includeDeclaringTypeName: true); + private IEvent GetEventDefinition() { return ((MetadataModule)EventDefinition.ParentModule?.MetadataFile @@ -56,9 +58,9 @@ namespace ICSharpCode.ILSpy.TreeNodes ?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition; } - public static object GetText(IEvent ev, Language language) + public static object GetText(IEvent ev, Language language, bool includeDeclaringTypeName = false) { - return language.EventToString(ev, false, false, false); + return language.EventToString(ev, includeDeclaringTypeName, false, false); } public override object Icon => GetIcon(GetEventDefinition()); diff --git a/ILSpy/TreeNodes/FieldTreeNode.cs b/ILSpy/TreeNodes/FieldTreeNode.cs index ffd74e774..5bf508aaf 100644 --- a/ILSpy/TreeNodes/FieldTreeNode.cs +++ b/ILSpy/TreeNodes/FieldTreeNode.cs @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => GetText(GetFieldDefinition(), Language) + GetSuffixString(FieldDefinition); + public override object NavigationText => GetText(GetFieldDefinition(), Language, includeDeclaringTypeName: true); + private IField GetFieldDefinition() { return ((MetadataModule)FieldDefinition.ParentModule?.MetadataFile @@ -48,9 +50,9 @@ namespace ICSharpCode.ILSpy.TreeNodes ?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition; } - public static object GetText(IField field, Language language) + public static object GetText(IField field, Language language, bool includeDeclaringTypeName = false) { - return language.FieldToString(field, includeDeclaringTypeName: false, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false); + return language.FieldToString(field, includeDeclaringTypeName, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false); } public override object Icon => GetIcon(GetFieldDefinition()); diff --git a/ILSpy/TreeNodes/MemberReferenceTreeNode.cs b/ILSpy/TreeNodes/MemberReferenceTreeNode.cs index fedf9b5a0..4d4598a8d 100644 --- a/ILSpy/TreeNodes/MemberReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/MemberReferenceTreeNode.cs @@ -49,6 +49,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => Signature + GetSuffixString(r.Handle); + public override object NavigationText => $"{Text} ({Properties.Resources.ReferencedTypes})"; + public override object Icon => r.MemberReferenceKind switch { MemberReferenceKind.Method => Images.MethodReference, MemberReferenceKind.Field => Images.FieldReference, diff --git a/ILSpy/TreeNodes/MethodTreeNode.cs b/ILSpy/TreeNodes/MethodTreeNode.cs index c8522887e..fc6d44ce6 100644 --- a/ILSpy/TreeNodes/MethodTreeNode.cs +++ b/ILSpy/TreeNodes/MethodTreeNode.cs @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => GetText(GetMethodDefinition(), Language) + GetSuffixString(MethodDefinition); + public override object NavigationText => GetText(GetMethodDefinition(), Language, includeDeclaringTypeName: true); + private IMethod GetMethodDefinition() { return ((MetadataModule)MethodDefinition.ParentModule?.MetadataFile @@ -48,9 +50,9 @@ namespace ICSharpCode.ILSpy.TreeNodes ?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition; } - public static object GetText(IMethod method, Language language) + public static object GetText(IMethod method, Language language, bool includeDeclaringTypeName = false) { - return language.MethodToString(method, false, false, false); + return language.MethodToString(method, includeDeclaringTypeName, false, false); } public override object Icon => GetIcon(GetMethodDefinition()); diff --git a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs index c893007b8..57e91cee8 100644 --- a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs @@ -68,6 +68,8 @@ namespace ICSharpCode.ILSpy.TreeNodes get { return moduleName + GetSuffixString(handle); } } + public override object NavigationText => $"{Text} ({Properties.Resources.References})"; + public override object Icon => Images.Library; public override void ActivateItem(IPlatformRoutedEventArgs e) diff --git a/ILSpy/TreeNodes/PropertyTreeNode.cs b/ILSpy/TreeNodes/PropertyTreeNode.cs index 12d689d18..255299f8c 100644 --- a/ILSpy/TreeNodes/PropertyTreeNode.cs +++ b/ILSpy/TreeNodes/PropertyTreeNode.cs @@ -51,6 +51,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => GetText(GetPropertyDefinition(), Language) + GetSuffixString(PropertyDefinition); + public override object NavigationText => GetText(GetPropertyDefinition(), Language, includeDeclaringTypeName: true); + private IProperty GetPropertyDefinition() { return ((MetadataModule)PropertyDefinition.ParentModule?.MetadataFile @@ -58,9 +60,9 @@ namespace ICSharpCode.ILSpy.TreeNodes ?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition; } - public static object GetText(IProperty property, Language language) + public static object GetText(IProperty property, Language language, bool includeDeclaringTypeName = false) { - return language.PropertyToString(property, false, false, false); + return language.PropertyToString(property, includeDeclaringTypeName, false, false); } public override object Icon => GetIcon(GetPropertyDefinition()); diff --git a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs index 6957ea634..87e72296d 100644 --- a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs +++ b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs @@ -44,6 +44,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => Resources.References; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.ReferenceFolder; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/ResourceListTreeNode.cs b/ILSpy/TreeNodes/ResourceListTreeNode.cs index 9ce35eaf7..174652817 100644 --- a/ILSpy/TreeNodes/ResourceListTreeNode.cs +++ b/ILSpy/TreeNodes/ResourceListTreeNode.cs @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => Resources._Resources; + public override object NavigationText => $"{Text} ({module.Name})"; + public override object Icon => Images.FolderClosed; public override object ExpandedIcon => Images.FolderOpen; diff --git a/ILSpy/TreeNodes/TypeReferenceTreeNode.cs b/ILSpy/TreeNodes/TypeReferenceTreeNode.cs index 431ab57da..6a47c4767 100644 --- a/ILSpy/TreeNodes/TypeReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/TypeReferenceTreeNode.cs @@ -45,6 +45,8 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => Language.TypeToString(resolvedType, includeNamespace: false) + GetSuffixString(r.Handle); + public override object NavigationText => $"{Text} ({Properties.Resources.ReferencedTypes})"; + public override object Icon => Images.TypeReference; protected override void LoadChildren() diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index d2e7bdc31..343f8f3df 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -45,6 +45,9 @@ namespace ICSharpCode.ILSpy.TreeNodes public override object Text => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: false) + GetSuffixString(TypeDefinition.MetadataToken); + public override object NavigationText => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: true) + + GetSuffixString(TypeDefinition.MetadataToken); + private ITypeDefinition GetTypeDefinition() { return ((MetadataModule)ParentAssemblyNode.LoadedAssembly