Browse Source

Refactor SearchPane so only the view model is exposed.

pull/3266/head
tom-englert 9 months ago committed by Siegfried Pammer
parent
commit
dde581adc8
  1. 4
      ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs
  2. 13
      ILSpy/Commands/ScopeSearchToAssembly.cs
  3. 14
      ILSpy/Commands/ScopeSearchToNamespace.cs
  4. 8
      ILSpy/Controls/CultureSelectionConverter.cs
  5. 46
      ILSpy/Controls/TreeView/Converters.cs
  6. 5
      ILSpy/Controls/TreeView/SharpTreeView.xaml
  7. 6
      ILSpy/DecompilationOptions.cs
  8. 11
      ILSpy/Docking/DockWorkspace.cs
  9. 126
      ILSpy/MainWindow.xaml
  10. 30
      ILSpy/MainWindow.xaml.cs
  11. 6
      ILSpy/Options/DisplaySettings.cs
  12. 2
      ILSpy/Options/DisplaySettingsPanel.xaml
  13. 8
      ILSpy/Options/DisplaySettingsPanel.xaml.cs
  14. 24
      ILSpy/Search/SearchPane.xaml
  15. 193
      ILSpy/Search/SearchPane.xaml.cs
  16. 41
      ILSpy/Search/SearchPaneModel.cs
  17. 4
      ILSpy/TextView/DecompilerTextView.cs
  18. 2
      ILSpy/Themes/WindowStyleManagerBehavior.cs
  19. 2
      ILSpy/Util/SettingsService.cs
  20. 103
      ILSpy/ViewModels/PaneModel.cs

4
ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpyX.Search
public AssemblySearchKind AssemblySearchKind;
public MemberSearchKind MemberSearchKind;
public string[] Keywords;
public Regex RegEx;
public Regex? RegEx;
public bool FullNameSearch;
public bool OmitGenerics;
public string InNamespace;
@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpyX.Search
public abstract class AbstractSearchStrategy
{
protected readonly string[] searchTerm;
protected readonly Regex regex;
protected readonly Regex? regex;
protected readonly bool fullNameSearch;
protected readonly bool omitGenerics;
protected readonly SearchRequest searchRequest;

13
ILSpy/Commands/ScopeSearchToAssembly.cs

@ -23,6 +23,7 @@ using System.ComponentModel.Composition; @@ -23,6 +23,7 @@ using System.ComponentModel.Composition;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy
@ -31,11 +32,19 @@ namespace ICSharpCode.ILSpy @@ -31,11 +32,19 @@ namespace ICSharpCode.ILSpy
[PartCreationPolicy(CreationPolicy.Shared)]
public class ScopeSearchToAssembly : IContextMenuEntry
{
private readonly SearchPaneModel searchPane;
[ImportingConstructor]
public ScopeSearchToAssembly(SearchPaneModel searchPane)
{
this.searchPane = searchPane;
}
public void Execute(TextViewContext context)
{
// asmName cannot be null here, because Execute is only called if IsEnabled/IsVisible return true.
string asmName = GetAssembly(context)!;
string searchTerm = MainWindow.Instance.SearchPane.SearchTerm;
string searchTerm = searchPane.SearchTerm;
string[] args = CommandLineTools.CommandLineToArgumentArray(searchTerm);
bool replaced = false;
for (int i = 0; i < args.Length; i++)
@ -55,7 +64,7 @@ namespace ICSharpCode.ILSpy @@ -55,7 +64,7 @@ namespace ICSharpCode.ILSpy
{
searchTerm = CommandLineTools.ArgumentArrayToCommandLine(args);
}
MainWindow.Instance.SearchPane.SearchTerm = searchTerm;
searchPane.SearchTerm = searchTerm;
}
public bool IsEnabled(TextViewContext context)

14
ILSpy/Commands/ScopeSearchToNamespace.cs

@ -21,6 +21,7 @@ using System.ComponentModel.Composition; @@ -21,6 +21,7 @@ using System.ComponentModel.Composition;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy
@ -29,10 +30,18 @@ namespace ICSharpCode.ILSpy @@ -29,10 +30,18 @@ namespace ICSharpCode.ILSpy
[PartCreationPolicy(CreationPolicy.Shared)]
public class ScopeSearchToNamespace : IContextMenuEntry
{
private readonly SearchPaneModel searchPane;
[ImportingConstructor]
public ScopeSearchToNamespace(SearchPaneModel searchPane)
{
this.searchPane = searchPane;
}
public void Execute(TextViewContext context)
{
string ns = GetNamespace(context);
string searchTerm = MainWindow.Instance.SearchPane.SearchTerm;
string searchTerm = searchPane.SearchTerm;
string[] args = CommandLineTools.CommandLineToArgumentArray(searchTerm);
bool replaced = false;
for (int i = 0; i < args.Length; i++)
@ -52,7 +61,8 @@ namespace ICSharpCode.ILSpy @@ -52,7 +61,8 @@ namespace ICSharpCode.ILSpy
{
searchTerm = CommandLineTools.ArgumentArrayToCommandLine(args);
}
MainWindow.Instance.SearchPane.SearchTerm = searchTerm;
searchPane.SearchTerm = searchTerm;
}
public bool IsEnabled(TextViewContext context)

8
ILSpy/Controls/CultureSelectionConverter.cs

@ -19,10 +19,11 @@ @@ -19,10 +19,11 @@
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace ICSharpCode.ILSpy.Controls
{
public class CultureSelectionConverter : IValueConverter
public class CultureSelectionConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
@ -37,5 +38,10 @@ namespace ICSharpCode.ILSpy.Controls @@ -37,5 +38,10 @@ namespace ICSharpCode.ILSpy.Controls
return parameter;
return Binding.DoNothing;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}

46
ILSpy/Controls/TreeView/Converters.cs

@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace ICSharpCode.ILSpy.Controls.TreeView
{
public class CollapsedWhenFalse : MarkupExtension, IValueConverter
{
public static CollapsedWhenFalse Instance = new CollapsedWhenFalse();
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Instance;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

5
ILSpy/Controls/TreeView/SharpTreeView.xaml

@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Default="clr-namespace:ICSharpCode.ILSpy.Controls.TreeView"
xmlns:styles="urn:TomsToolbox.Wpf.Styles">
xmlns:styles="urn:TomsToolbox.Wpf.Styles"
xmlns:toms="urn:TomsToolbox">
<Style x:Key="ExpandCollapseToggleStyle"
TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource {x:Type ToggleButton}}">
@ -227,7 +228,7 @@ @@ -227,7 +228,7 @@
<Grid>
<Default:LinesRenderer x:Name="linesRenderer"
ClipToBounds="True"
Visibility="{Binding ShowLines, RelativeSource={RelativeSource AncestorType={x:Type Default:SharpTreeView}}, Converter={Default:CollapsedWhenFalse}}" />
Visibility="{Binding ShowLines, RelativeSource={RelativeSource AncestorType={x:Type Default:SharpTreeView}}, Converter={toms:BooleanToVisibilityConverter}}" />
<StackPanel Orientation="Horizontal">
<FrameworkElement Name="spacer" />
<ToggleButton Name="expander"

6
ILSpy/DecompilationOptions.cs

@ -67,7 +67,7 @@ namespace ICSharpCode.ILSpy @@ -67,7 +67,7 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// Gets the settings for the decompiler.
/// </summary>
public Decompiler.DecompilerSettings DecompilerSettings { get; private set; }
public DecompilerSettings DecompilerSettings { get; private set; }
/// <summary>
/// Gets/sets an optional state of a decompiler text view.
@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy @@ -83,7 +83,7 @@ namespace ICSharpCode.ILSpy
internal int StepLimit = int.MaxValue;
internal bool IsDebug = false;
public DecompilationOptions(LanguageVersion version, Decompiler.DecompilerSettings settings, DisplaySettingsViewModel displaySettings)
public DecompilationOptions(LanguageVersion version, DecompilerSettings settings, DisplaySettings displaySettings)
{
if (!Enum.TryParse(version?.Version, out Decompiler.CSharp.LanguageVersion languageVersion))
languageVersion = Decompiler.CSharp.LanguageVersion.Latest;
@ -96,7 +96,7 @@ namespace ICSharpCode.ILSpy @@ -96,7 +96,7 @@ namespace ICSharpCode.ILSpy
newSettings.CSharpFormattingOptions.IndentationString = GetIndentationString(displaySettings);
}
private string GetIndentationString(DisplaySettingsViewModel displaySettings)
private string GetIndentationString(DisplaySettings displaySettings)
{
if (displaySettings.IndentationUseTabs)
{

11
ILSpy/Docking/DockWorkspace.cs

@ -17,17 +17,12 @@ @@ -17,17 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Navigation;
using System.Windows.Threading;
using AvalonDock;
@ -36,6 +31,7 @@ using AvalonDock.Layout.Serialization; @@ -36,6 +31,7 @@ using AvalonDock.Layout.Serialization;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
@ -219,7 +215,7 @@ namespace ICSharpCode.ILSpy.Docking @@ -219,7 +215,7 @@ namespace ICSharpCode.ILSpy.Docking
}
CloseAllTabs();
SessionSettings.DockLayout.Reset();
InitializeLayout(MainWindow.Instance.DockManager);
InitializeLayout(MainWindow.Instance.dockManager);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView);
}
@ -268,5 +264,8 @@ namespace ICSharpCode.ILSpy.Docking @@ -268,5 +264,8 @@ namespace ICSharpCode.ILSpy.Docking
public void AfterInsertDocument(LayoutRoot layout, LayoutDocument anchorableShown)
{
}
// Dummy property to make the XAML designer happy, the model is provided by the AvalonDock PaneStyleSelectors, not by the DockWorkspace, but the designer assumes the data context in the PaneStyleSelectors is the DockWorkspace.
public PaneModel Model { get; } = null;
}
}

126
ILSpy/MainWindow.xaml

@ -1,12 +1,11 @@ @@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="ICSharpCode.ILSpy.MainWindow"
x:ClassModifier="public"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tv="clr-namespace:ICSharpCode.ILSpy.Controls.TreeView"
xmlns:local="clr-namespace:ICSharpCode.ILSpy"
xmlns:search="clr-namespace:ICSharpCode.ILSpy.Search"
xmlns:avalondock="https://github.com/Dirkster99/AvalonDock"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls"
xmlns:docking="clr-namespace:ICSharpCode.ILSpy.Docking"
@ -22,21 +21,22 @@ @@ -22,21 +21,22 @@
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes"
xmlns:toms="urn:TomsToolbox"
xmlns:viewModels="clr-namespace:ICSharpCode.ILSpy.ViewModels"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}"
>
xmlns:treeNodes="clr-namespace:ICSharpCode.ILSpy.TreeNodes"
xmlns:util="clr-namespace:ICSharpCode.ILSpy.Util"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
<Window.Resources>
<tv:SharpTreeView x:Key="AssemblyTreeView"
AutomationProperties.Name="Assemblies and Classes"
SelectionChanged="TreeView_SelectionChanged"
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0" Visibility="Visible">
AutomationProperties.Name="Assemblies and Classes"
SelectionChanged="TreeView_SelectionChanged"
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0" Visibility="Visible">
<tv:SharpTreeView.ItemContainerStyle>
<Style TargetType="tv:SharpTreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type tv:SharpTreeViewItem}">
<ControlTemplate TargetType="{x:Type tv:SharpTreeViewItem}" d:DataContext="{d:DesignInstance treeNodes:ILSpyTreeNode}">
<Border Background="Transparent">
<Border Background="{TemplateBinding Background}">
<tv:SharpTreeNodeView x:Name="nodeView" HorizontalAlignment="Left" />
@ -76,9 +76,7 @@ @@ -76,9 +76,7 @@
<ContentPresenter Content="{Binding Content}" />
</DataTemplate>
<controls:CultureSelectionConverter x:Key="cultureSelectionConverter" />
<toms:BindingRelay x:Key="WindowBinding" DataContext="{Binding}"/>
<toms:BindingRelay x:Key="WindowBinding" DataContext="{Binding}" />
</Window.Resources>
@ -127,13 +125,14 @@ @@ -127,13 +125,14 @@
<MenuItem Header="{x:Static properties:Resources.Show_publiconlyTypesMembers}" IsCheckable="True" IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisPublicOnly}" />
<MenuItem Header="{x:Static properties:Resources.Show_internalTypesMembers}" IsCheckable="True" IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisPublicAndInternal}" />
<MenuItem Header="{x:Static properties:Resources.Show_allTypesAndMembers}" IsCheckable="True" IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisAll}" />
<Separator/>
<Separator />
<MenuItem Header="{x:Static properties:Resources.Theme}" ItemsSource="{x:Static themes:ThemeManager.AllThemes}">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Setter Property="Command" Value="{x:Static local:ILSpyCommands.SetTheme}" />
<Setter Property="CommandParameter" Value="{Binding}" />
<Setter Property="IsCheckable" Value="True" /><!-- Required by AvalonDock's MenuItem style to show the checkmark -->
<Setter Property="IsCheckable" Value="True" />
<!-- Required by AvalonDock's MenuItem style to show the checkmark -->
<Setter Property="IsChecked">
<Setter.Value>
<MultiBinding Converter="{x:Static toms:BinaryOperationConverter.Equality}" Mode="OneWay">
@ -146,9 +145,9 @@ @@ -146,9 +145,9 @@
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="{x:Static properties:Resources.UILanguage}">
<MenuItem Header="{x:Static properties:Resources.UILanguage_System}" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={StaticResource cultureSelectionConverter}, ConverterParameter={x:Null}}" />
<MenuItem Header="English" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={StaticResource cultureSelectionConverter}, ConverterParameter=en-US}" />
<MenuItem Header="中文" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={StaticResource cultureSelectionConverter}, ConverterParameter=zh-Hans}" />
<MenuItem Header="{x:Static properties:Resources.UILanguage_System}" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={controls:CultureSelectionConverter}, ConverterParameter={x:Null}}" />
<MenuItem Header="English" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={controls:CultureSelectionConverter}, ConverterParameter=en-US}" />
<MenuItem Header="中文" IsCheckable="True" IsChecked="{Binding SessionSettings.CurrentCulture, Converter={controls:CultureSelectionConverter}, ConverterParameter=zh-Hans}" />
</MenuItem>
</MenuItem>
<MenuItem Header="{x:Static properties:Resources._Window}" Tag="_Window" />
@ -184,39 +183,52 @@ @@ -184,39 +183,52 @@
<!-- 'Open' toolbar category is inserted here -->
<Separator />
<ComboBox Name="assemblyListComboBox" Width="100" MaxDropDownHeight="Auto"
ItemsSource="{Binding AssemblyListManager.AssemblyLists}" ToolTip="{x:Static properties:Resources.SelectAssemblyListDropdownTooltip}"
SelectedItem="{Binding SessionSettings.ActiveAssemblyList}"/>
<Button Command="{x:Static local:ILSpyCommands.ManageAssemblyListsCommand}" ToolTip="{x:Static properties:Resources.ManageAssemblyLists}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}" Style="{StaticResource DarkModeAwareImageStyle}"/>
ItemsSource="{Binding AssemblyListManager.AssemblyLists}"
ToolTip="{x:Static properties:Resources.SelectAssemblyListDropdownTooltip}"
SelectedItem="{Binding SessionSettings.ActiveAssemblyList}" />
<Button Command="{x:Static local:ILSpyCommands.ManageAssemblyListsCommand}"
ToolTip="{x:Static properties:Resources.ManageAssemblyLists}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}"
Style="{StaticResource DarkModeAwareImageStyle}" />
</Button>
<Separator />
<CheckBox IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisPublicOnly}" ToolTip="{x:Static properties:Resources.ShowPublicOnlyTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPublicOnly}" Style="{StaticResource DarkModeAwareImageStyle}"/>
<CheckBox IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisPublicOnly}"
ToolTip="{x:Static properties:Resources.ShowPublicOnlyTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPublicOnly}"
Style="{StaticResource DarkModeAwareImageStyle}" />
</CheckBox>
<CheckBox IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisPublicAndInternal}" ToolTip="{x:Static properties:Resources.ShowInternalTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPrivateInternal}" Style="{StaticResource DarkModeAwareImageStyle}"/>
<CheckBox IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisPublicAndInternal}"
ToolTip="{x:Static properties:Resources.ShowInternalTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPrivateInternal}"
Style="{StaticResource DarkModeAwareImageStyle}" />
</CheckBox>
<CheckBox IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisAll}" ToolTip="{x:Static properties:Resources.ShowAllTypesAndMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowAll}" Style="{StaticResource DarkModeAwareImageStyle}"/>
<CheckBox IsChecked="{Binding SessionSettings.LanguageSettings.ApiVisAll}"
ToolTip="{x:Static properties:Resources.ShowAllTypesAndMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowAll}"
Style="{StaticResource DarkModeAwareImageStyle}" />
</CheckBox>
<Separator />
<ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100" MaxDropDownHeight="Auto"
IsEnabled="{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}"
ItemsSource="{x:Static local:Languages.AllLanguages}" ToolTip="{x:Static properties:Resources.SelectLanguageDropdownTooltip}"
SelectedItem="{Binding SessionSettings.LanguageSettings.Language}"/>
<ComboBox Name="languageVersionComboBox" DisplayMemberPath="DisplayName" Width="120" MaxDropDownHeight="Auto" ToolTip="{x:Static properties:Resources.SelectVersionDropdownTooltip}"
IsEnabled="{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}"
ItemsSource="{x:Static local:Languages.AllLanguages}"
ToolTip="{x:Static properties:Resources.SelectLanguageDropdownTooltip}"
SelectedItem="{Binding SessionSettings.LanguageSettings.Language}" />
<ComboBox Name="languageVersionComboBox" DisplayMemberPath="DisplayName" Width="120" MaxDropDownHeight="Auto"
ToolTip="{x:Static properties:Resources.SelectVersionDropdownTooltip}"
Visibility="{Binding SelectedItem.HasLanguageVersions, ElementName=languageComboBox, Converter={toms:BooleanToVisibilityConverter}}"
IsEnabled="{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}"
IsEnabled="{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}"
ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SessionSettings.LanguageSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/>
SelectedItem="{Binding SessionSettings.LanguageSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}" />
</ToolBar>
<!-- Update panel -->
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1" Name="updatePanel" Visibility="Collapsed">
<DockPanel KeyboardNavigation.TabNavigation="Contained">
<Button DockPanel.Dock="Right" Click="updatePanelCloseButtonClick" MinWidth="0">X</Button>
<StackPanel Orientation="Horizontal">
<TextBlock Name="updatePanelMessage" Margin="4,0" VerticalAlignment="Center" Text="{x:Static properties:Resources.ILSpyVersionAvailable}" />
<Button Name="downloadOrCheckUpdateButton" Click="downloadOrCheckUpdateButtonClick" Content="{x:Static properties:Resources.Download}"/>
<TextBlock Name="updatePanelMessage" Margin="4,0" VerticalAlignment="Center"
Text="{x:Static properties:Resources.ILSpyVersionAvailable}" />
<Button Name="downloadOrCheckUpdateButton" Click="downloadOrCheckUpdateButtonClick"
Content="{x:Static properties:Resources.Download}" />
</StackPanel>
</DockPanel>
</Border>
@ -225,21 +237,21 @@ @@ -225,21 +237,21 @@
<StatusBarItem DockPanel.Dock="Right">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Right"
x:Name="StatusLabel"
x:Name="statusLabel"
ToolTip="{x:Static properties:Resources.Status}"
Text="{x:Static properties:Resources.StandBy}"/>
Text="{x:Static properties:Resources.StandBy}" />
</StatusBarItem>
</StatusBar>
<avalondock:DockingManager x:Name="DockManager"
DataContext="{Binding Workspace}"
AnchorablesSource="{Binding ToolPanes}"
DocumentsSource="{Binding TabPages}"
ActiveContent="{Binding ActiveTabPage, Mode=TwoWay, Converter={docking:TabPageGuardConverter}}"
AllowMixedOrientation="True">
<avalondock:DockingManager x:Name="dockManager"
DataContext="{Binding Workspace}"
AnchorablesSource="{Binding ToolPanes}"
DocumentsSource="{Binding TabPages}"
ActiveContent="{Binding ActiveTabPage, Mode=TwoWay, Converter={docking:TabPageGuardConverter}}"
AllowMixedOrientation="True">
<avalondock:DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<DataTemplate DataType="{x:Type viewModels:PaneModel}">
<TextBlock x:Name="headerText" Text="{Binding Title}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="True">
@ -253,11 +265,11 @@ @@ -253,11 +265,11 @@
<docking:PaneStyleSelector>
<docking:PaneStyleSelector.ToolPaneStyle>
<Style TargetType="{x:Type avalondock:LayoutAnchorableItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={toms:BooleanToVisibilityConverter VisibilityWhenBooleanIsFalse=Hidden}}"/>
<Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/>
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
<Setter Property="Title" Value="{Binding Model.Title}" />
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={toms:BooleanToVisibilityConverter VisibilityWhenBooleanIsFalse=Hidden}}" />
<Setter Property="ContentId" Value="{Binding Model.ContentId}" />
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}" />
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}" />
<Setter Property="CanHide" Value="{Binding Model.IsCloseable}" />
<Setter Property="HideCommand" Value="{Binding Model.CloseCommand}" />
<Setter Property="CanClose" Value="{Binding Model.IsCloseable}" />
@ -266,11 +278,11 @@ @@ -266,11 +278,11 @@
</docking:PaneStyleSelector.ToolPaneStyle>
<docking:PaneStyleSelector.TabPageStyle>
<Style TargetType="{x:Type avalondock:LayoutItem}">
<Setter Property="Title" Value="{Binding Model.Title}"/>
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={toms:BooleanToVisibilityConverter VisibilityWhenBooleanIsFalse=Hidden}}"/>
<Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/>
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
<Setter Property="Title" Value="{Binding Model.Title}" />
<Setter Property="Visibility" Value="{Binding Model.IsVisible, Mode=TwoWay, Converter={toms:BooleanToVisibilityConverter VisibilityWhenBooleanIsFalse=Hidden}}" />
<Setter Property="ContentId" Value="{Binding Model.ContentId}" />
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}" />
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}" />
<Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
<Setter Property="CanClose" Value="{Binding Model.IsCloseable, Mode=TwoWay}" />
</Style>
@ -279,4 +291,4 @@ @@ -279,4 +291,4 @@
</avalondock:DockingManager.LayoutItemContainerStyleSelector>
</avalondock:DockingManager>
</DockPanel>
</Window>
</Window>

30
ILSpy/MainWindow.xaml.cs

@ -89,12 +89,6 @@ namespace ICSharpCode.ILSpy @@ -89,12 +89,6 @@ namespace ICSharpCode.ILSpy
}
}
public SearchPane SearchPane {
get {
return App.ExportProvider.GetExportedValue<SearchPane>();
}
}
public DecompilationOptions CreateDecompilationOptions()
{
var decompilerView = DockWorkspace.Instance.ActiveTabPage.Content as IProgress<DecompilationProgress>;
@ -123,10 +117,10 @@ namespace ICSharpCode.ILSpy @@ -123,10 +117,10 @@ namespace ICSharpCode.ILSpy
}
InitializeComponent();
InitToolPanes();
DockWorkspace.Instance.InitializeLayout(DockManager);
DockWorkspace.Instance.InitializeLayout(dockManager);
MessageBus<SessionSettingsChangedEventArgs>.Subscribers += (sender, e) => SessionSettings_PropertyChanged(sender, e);
MessageBus<LanguageSettingsChangedEventArgs>.Subscribers += (sender, e) => filterSettings_PropertyChanged(sender, e);
MessageBus<LanguageSettingsChangedEventArgs>.Subscribers += (sender, e) => LanguageSettings_PropertyChanged(sender, e);
MessageBus<DockWorkspaceActiveTabPageChangedEventArgs>.Subscribers += DockWorkspace_ActiveTabPageChanged;
InitMainMenu();
@ -647,8 +641,10 @@ namespace ICSharpCode.ILSpy @@ -647,8 +641,10 @@ namespace ICSharpCode.ILSpy
NavigateOnLaunch(args.NavigateTo, sessionSettings.ActiveTreeViewPath, spySettings, relevantAssemblies);
if (args.Search != null)
{
SearchPane.SearchTerm = args.Search;
SearchPane.Show();
var searchPane = App.ExportProvider.GetExportedValue<SearchPaneModel>();
searchPane.SearchTerm = args.Search;
searchPane.Show();
}
}
@ -1004,20 +1000,14 @@ namespace ICSharpCode.ILSpy @@ -1004,20 +1000,14 @@ namespace ICSharpCode.ILSpy
assemblyList.OpenAssembly(asm.Location);
}
void filterSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
void LanguageSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
RefreshTreeViewFilter();
if (e.PropertyName == "Language" || e.PropertyName == "LanguageVersion")
{
DecompileSelectedNodes(recordHistory: false);
}
}
public void RefreshTreeViewFilter()
{
SearchPane.UpdateFilter();
}
internal AssemblyListTreeNode AssemblyListTreeNode {
get { return assemblyListTreeNode; }
}
@ -1592,7 +1582,7 @@ namespace ICSharpCode.ILSpy @@ -1592,7 +1582,7 @@ namespace ICSharpCode.ILSpy
sessionSettings.ActiveTreeViewPath = GetPathForNode(AssemblyTreeView.SelectedItem as SharpTreeNode);
sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(AssemblyTreeView.SelectedItem as SharpTreeNode);
sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(DockManager));
sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(dockManager));
sessionSettings.Save();
}
@ -1622,8 +1612,8 @@ namespace ICSharpCode.ILSpy @@ -1622,8 +1612,8 @@ namespace ICSharpCode.ILSpy
{
if (this.statusBar.Visibility == Visibility.Collapsed)
this.statusBar.Visibility = Visibility.Visible;
this.StatusLabel.Foreground = foreground;
this.StatusLabel.Text = status;
this.statusLabel.Foreground = foreground;
this.statusLabel.Text = status;
}
public ItemCollection GetMainMenuItems()

6
ILSpy/Options/DisplaySettingsViewModel.cs → ILSpy/Options/DisplaySettings.cs

@ -27,9 +27,9 @@ namespace ICSharpCode.ILSpy.Options @@ -27,9 +27,9 @@ namespace ICSharpCode.ILSpy.Options
/// <summary>
/// Description of DisplaySettings.
/// </summary>
public class DisplaySettingsViewModel : INotifyPropertyChanged
public class DisplaySettings : INotifyPropertyChanged
{
public DisplaySettingsViewModel()
public DisplaySettings()
{
this.theme = ThemeManager.Current.DefaultTheme;
this.selectedFont = new FontFamily("Consolas");
@ -328,7 +328,7 @@ namespace ICSharpCode.ILSpy.Options @@ -328,7 +328,7 @@ namespace ICSharpCode.ILSpy.Options
}
}
public void CopyValues(DisplaySettingsViewModel s)
public void CopyValues(DisplaySettings s)
{
this.Theme = s.Theme;
this.SelectedFont = s.selectedFont;

2
ILSpy/Options/DisplaySettingsPanel.xaml

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes"
d:DataContext="{d:DesignInstance local:DisplaySettingsViewModel}">
d:DataContext="{d:DesignInstance local:DisplaySettings}">
<UserControl.Resources>
<local:FontSizeConverter x:Key="fontSizeConv" />
</UserControl.Resources>

8
ILSpy/Options/DisplaySettingsPanel.xaml.cs

@ -99,10 +99,10 @@ namespace ICSharpCode.ILSpy.Options @@ -99,10 +99,10 @@ namespace ICSharpCode.ILSpy.Options
select ff).ToArray();
}
public static DisplaySettingsViewModel LoadDisplaySettings(ILSpySettings settings, SessionSettings sessionSettings = null)
public static DisplaySettings LoadDisplaySettings(ILSpySettings settings, SessionSettings sessionSettings = null)
{
XElement e = settings["DisplaySettings"];
var s = new DisplaySettingsViewModel();
var s = new DisplaySettings();
s.SelectedFont = new FontFamily((string)e.Attribute("Font") ?? "Consolas");
s.SelectedFontSize = (double?)e.Attribute("FontSize") ?? 10.0 * 4 / 3;
s.ShowLineNumbers = (bool?)e.Attribute("ShowLineNumbers") ?? false;
@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Options @@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Options
public void Save(XElement root)
{
var s = (DisplaySettingsViewModel)this.DataContext;
var s = (DisplaySettings)this.DataContext;
var section = new XElement("DisplaySettings");
section.SetAttributeValue("Font", s.SelectedFont.Source);
@ -190,7 +190,7 @@ namespace ICSharpCode.ILSpy.Options @@ -190,7 +190,7 @@ namespace ICSharpCode.ILSpy.Options
public void LoadDefaults()
{
SettingsService.Instance.DisplaySettings.CopyValues(new DisplaySettingsViewModel());
SettingsService.Instance.DisplaySettings.CopyValues(new DisplaySettings());
this.DataContext = SettingsService.Instance.DisplaySettings;
}
}

24
ILSpy/Search/SearchPane.xaml

@ -2,10 +2,14 @@ @@ -2,10 +2,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties"
xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="self" mc:Ignorable="d"
xmlns:toms="urn:TomsToolbox"
d:DesignHeight="300" d:DesignWidth="300">
xmlns:search="clr-namespace:ICSharpCode.ILSpy.Search"
xmlns:spyX="clr-namespace:ICSharpCode.ILSpyX.Search;assembly=ICSharpCode.ILSpyX"
xmlns:viewModels="clr-namespace:ICSharpCode.ILSpy.ViewModels"
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance search:SearchPaneModel}"
viewModels:Pane.IsActive="{Binding IsActive}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
@ -20,15 +24,19 @@ @@ -20,15 +24,19 @@
</Grid.ColumnDefinitions>
<controls:SearchBox x:Name="searchBox" DockPanel.Dock="Top" Grid.Column="0" Grid.Row="0" Margin="1"
PreviewKeyDown="SearchBox_PreviewKeyDown"
Text="{Binding SearchTerm, ElementName=self}" ToolTip="{x:Static properties:Resources.SearchPane_Search}" UpdateDelay="0:0:0.1"
Text="{Binding SearchTerm, UpdateSourceTrigger=PropertyChanged}" ToolTip="{x:Static properties:Resources.SearchPane_Search}" UpdateDelay="0:0:0.1"
TextChanged="SearchBox_TextChanged"
WatermarkColor="Gray" WatermarkText="{x:Static properties:Resources.WatermarkText}" />
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal">
<Label Margin="0,-1" Target="searchModeComboBox" Content="{x:Static properties:Resources._SearchFor}"/>
<ComboBox Width="100" Name="searchModeComboBox" Margin="1"
TextSearch.TextPath="Name"
ItemsSource="{Binding SearchModes}"
SelectedValuePath="Mode"
SelectedValue="{Binding SessionSettings.SelectedSearchMode, Mode=TwoWay}"
SelectionChanged="SearchModeComboBox_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<DataTemplate DataType="{x:Type search:SearchModeModel}">
<StackPanel Orientation="Horizontal">
<Image Height="16" Margin="0,0,4,0" Width="16" Source="{Binding Image}" />
<TextBlock Text="{Binding Name}" />
@ -41,7 +49,7 @@ @@ -41,7 +49,7 @@
</Border>
<ProgressBar x:Name="searchProgressBar" Grid.Row="1" BorderThickness="0" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<ListView Grid.Row="2" BorderThickness="0,1,0,0" HorizontalContentAlignment="Stretch" KeyDown="ListBox_KeyDown"
MouseDoubleClick="ListBox_MouseDoubleClick" Name="listBox" SelectionMode="Single" controls:SortableGridViewColumn.SortMode="Automatic"
MouseDoubleClick="ListBox_MouseDoubleClick" Name="listBox" SelectionMode="Single" controls:SortableGridViewColumn.SortMode="Automatic"
controls:GridViewColumnAutoSize.AutoWidth="40%;40%;20%" BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
ItemsSource="{Binding Results, ElementName=self}"
toms:AdvancedScrollWheelBehavior.Attach="WithoutAnimation">
@ -49,7 +57,7 @@ @@ -49,7 +57,7 @@
<GridView AllowsColumnReorder="False">
<controls:SortableGridViewColumn Header="{x:Static properties:Resources.Name}" SortBy="Name">
<controls:SortableGridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate DataType="{x:Type spyX:SearchResult}">
<StackPanel Orientation="Horizontal">
<Image Height="16" Margin="0,0,4,0" Width="16" Source="{Binding Image}" />
<TextBlock Text="{Binding Name}" ToolTip="{Binding ToolTip}" TextTrimming="CharacterEllipsis" />
@ -59,7 +67,7 @@ @@ -59,7 +67,7 @@
</controls:SortableGridViewColumn>
<controls:SortableGridViewColumn Header="{x:Static properties:Resources.Location}" SortBy="Location">
<controls:SortableGridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate DataType="{x:Type spyX:SearchResult}">
<StackPanel Orientation="Horizontal">
<Image Height="16" Margin="4,0,4,0" Width="16" Source="{Binding LocationImage}" />
<TextBlock Text="{Binding Location}" ToolTip="{Binding Location}" TextTrimming="CharacterEllipsis" />
@ -69,7 +77,7 @@ @@ -69,7 +77,7 @@
</controls:SortableGridViewColumn>
<controls:SortableGridViewColumn Header="{x:Static properties:Resources.Assembly}" SortBy="Assembly">
<controls:SortableGridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate DataType="{x:Type spyX:SearchResult}">
<StackPanel Orientation="Horizontal">
<Image Height="16" Margin="4,0,4,0" Width="16" Source="{Binding AssemblyImage}" />
<TextBlock Text="{Binding Assembly}" ToolTip="{Binding Assembly}" TextTrimming="CharacterEllipsis" />

193
ILSpy/Search/SearchPane.cs → ILSpy/Search/SearchPane.xaml.cs

@ -20,10 +20,8 @@ using System; @@ -20,10 +20,8 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
@ -34,13 +32,14 @@ using System.Windows.Media; @@ -34,13 +32,14 @@ using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Extensions;
using ICSharpCode.ILSpyX.Search;
using TomsToolbox.Essentials;
using TomsToolbox.Wpf;
using TomsToolbox.Wpf.Composition.Mef;
namespace ICSharpCode.ILSpy.Search
@ -49,48 +48,31 @@ namespace ICSharpCode.ILSpy.Search @@ -49,48 +48,31 @@ namespace ICSharpCode.ILSpy.Search
/// Search pane
/// </summary>
[DataTemplate(typeof(SearchPaneModel))]
[PartCreationPolicy(CreationPolicy.Shared)]
[Export]
public partial class SearchPane : UserControl
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class SearchPane
{
const int MAX_RESULTS = 1000;
const int MAX_REFRESH_TIME_MS = 10; // More means quicker forward of data, less means better responsibility
const int MAX_REFRESH_TIME_MS = 10; // More means quicker forward of data, fewer means better responsibility
RunningSearch currentSearch;
bool runSearchOnNextShow;
IComparer<SearchResult> resultsComparer;
public static readonly DependencyProperty ResultsProperty =
DependencyProperty.Register("Results", typeof(ObservableCollection<SearchResult>), typeof(SearchPane),
new PropertyMetadata(new ObservableCollection<SearchResult>()));
public ObservableCollection<SearchResult> Results {
get { return (ObservableCollection<SearchResult>)GetValue(ResultsProperty); }
}
public ObservableCollection<SearchResult> Results { get; } = [];
string SearchTerm => searchBox.Text;
public SearchPane()
{
InitializeComponent();
searchModeComboBox.Items.Add(new { Image = Images.Library, Name = "Types and Members" });
searchModeComboBox.Items.Add(new { Image = Images.Class, Name = "Type" });
searchModeComboBox.Items.Add(new { Image = Images.Property, Name = "Member" });
searchModeComboBox.Items.Add(new { Image = Images.Method, Name = "Method" });
searchModeComboBox.Items.Add(new { Image = Images.Field, Name = "Field" });
searchModeComboBox.Items.Add(new { Image = Images.Property, Name = "Property" });
searchModeComboBox.Items.Add(new { Image = Images.Event, Name = "Event" });
searchModeComboBox.Items.Add(new { Image = Images.Literal, Name = "Constant" });
searchModeComboBox.Items.Add(new { Image = Images.Library, Name = "Metadata Token" });
searchModeComboBox.Items.Add(new { Image = Images.Resource, Name = "Resource" });
searchModeComboBox.Items.Add(new { Image = Images.Assembly, Name = "Assembly" });
searchModeComboBox.Items.Add(new { Image = Images.Namespace, Name = "Namespace" });
ContextMenuProvider.Add(listBox);
MessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => MainWindow_Instance_CurrentAssemblyListChanged(sender, e);
CompositionTarget.Rendering += UpdateResults;
MessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => CurrentAssemblyList_Changed();
MessageBus<LanguageSettingsChangedEventArgs>.Subscribers += (sender, e) => LanguageSettings_PropertyChanged();
// This starts empty search right away, so do at the end (we're still in ctor)
searchModeComboBox.SelectedIndex = (int)SettingsService.Instance.SessionSettings.SelectedSearchMode;
CompositionTarget.Rendering += UpdateResults;
}
void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e)
void CurrentAssemblyList_Changed()
{
if (IsVisible)
{
@ -103,7 +85,12 @@ namespace ICSharpCode.ILSpy.Search @@ -103,7 +85,12 @@ namespace ICSharpCode.ILSpy.Search
}
}
internal void UpdateFilter()
void LanguageSettings_PropertyChanged()
{
UpdateFilter();
}
void UpdateFilter()
{
if (IsVisible)
{
@ -116,43 +103,48 @@ namespace ICSharpCode.ILSpy.Search @@ -116,43 +103,48 @@ namespace ICSharpCode.ILSpy.Search
}
}
public void Show()
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (!IsVisible)
base.OnPropertyChanged(e);
if (e.Property == IsVisibleProperty)
{
DockWorkspace.Instance.ToolPanes.Single(p => p.ContentId == SearchPaneModel.PaneContentId).IsVisible = true;
if (runSearchOnNextShow)
{
runSearchOnNextShow = false;
StartSearch(this.SearchTerm);
}
if (e.NewValue as bool? != true)
return;
if (!runSearchOnNextShow)
return;
runSearchOnNextShow = false;
StartSearch(this.SearchTerm);
}
Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(
delegate {
searchBox.Focus();
searchBox.SelectAll();
}));
}
else if (e.Property == Pane.IsActiveProperty)
{
if (e.NewValue as bool? != true)
return;
public static readonly DependencyProperty SearchTermProperty =
DependencyProperty.Register("SearchTerm", typeof(string), typeof(SearchPane),
new FrameworkPropertyMetadata(string.Empty, OnSearchTermChanged));
if (IsMouseOver && Mouse.LeftButton == MouseButtonState.Pressed && !SearchTerm.IsNullOrEmpty())
return;
public string SearchTerm {
get { return (string)GetValue(SearchTermProperty); }
set { SetValue(SearchTermProperty, value); }
FocusSearchBox();
}
}
static void OnSearchTermChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
void FocusSearchBox()
{
((SearchPane)o).StartSearch((string)e.NewValue);
this.BeginInvoke(DispatcherPriority.Background, () => {
searchBox.Focus();
searchBox.SelectAll();
});
}
void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
{
StartSearch(searchBox.Text);
}
void SearchModeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SettingsService.Instance.SessionSettings.SelectedSearchMode = (SearchMode)searchModeComboBox.SelectedIndex;
StartSearch(this.SearchTerm);
}
@ -180,31 +172,35 @@ namespace ICSharpCode.ILSpy.Search @@ -180,31 +172,35 @@ namespace ICSharpCode.ILSpy.Search
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.T && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
{
searchModeComboBox.SelectedIndex = (int)SearchMode.Type;
e.Handled = true;
}
else if (e.Key == Key.M && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
{
searchModeComboBox.SelectedIndex = (int)SearchMode.Member;
e.Handled = true;
}
else if (e.Key == Key.S && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
if (e.KeyboardDevice.Modifiers != ModifierKeys.Control)
return;
switch (e.Key)
{
searchModeComboBox.SelectedIndex = (int)SearchMode.Literal;
e.Handled = true;
case Key.T:
searchModeComboBox.SelectedValue = SearchMode.Type;
e.Handled = true;
break;
case Key.M:
searchModeComboBox.SelectedValue = SearchMode.Member;
e.Handled = true;
break;
case Key.S:
searchModeComboBox.SelectedValue = SearchMode.Literal;
e.Handled = true;
break;
}
}
void SearchBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down && listBox.HasItems)
{
e.Handled = true;
listBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
listBox.SelectedIndex = 0;
}
if (e.Key != Key.Down || !listBox.HasItems)
return;
e.Handled = true;
listBox.MoveFocus(new(FocusNavigationDirection.First));
listBox.SelectedIndex = 0;
}
void UpdateResults(object sender, EventArgs e)
@ -220,18 +216,19 @@ namespace ICSharpCode.ILSpy.Search @@ -220,18 +216,19 @@ namespace ICSharpCode.ILSpy.Search
++resultsAdded;
}
if (resultsAdded > 0 && Results.Count == MAX_RESULTS)
{
Results.Add(new SearchResult {
Name = Properties.Resources.SearchAbortedMoreThan1000ResultsFound,
Location = null!,
Assembly = null!,
Image = null!,
LocationImage = null!,
AssemblyImage = null!,
});
currentSearch.Cancel();
}
if (resultsAdded <= 0 || Results.Count != MAX_RESULTS)
return;
Results.Add(new() {
Name = Properties.Resources.SearchAbortedMoreThan1000ResultsFound,
Location = null!,
Assembly = null!,
Image = null!,
LocationImage = null!,
AssemblyImage = null!,
});
currentSearch.Cancel();
}
async void StartSearch(string searchTerm)
@ -253,7 +250,7 @@ namespace ICSharpCode.ILSpy.Search @@ -253,7 +250,7 @@ namespace ICSharpCode.ILSpy.Search
{
searchProgressBar.IsIndeterminate = true;
startedSearch = new RunningSearch(await mainWindow.CurrentAssemblyList.GetAllAssemblies(), searchTerm,
startedSearch = new(await mainWindow.CurrentAssemblyList.GetAllAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage,
SettingsService.Instance.SessionSettings.LanguageSettings.ShowApiLevel);
currentSearch = startedSearch;
@ -262,7 +259,8 @@ namespace ICSharpCode.ILSpy.Search @@ -262,7 +259,8 @@ namespace ICSharpCode.ILSpy.Search
}
if (currentSearch == startedSearch)
{ //are we still running the same search
{
//are we still running the same search
searchProgressBar.IsIndeterminate = false;
}
}
@ -277,7 +275,7 @@ namespace ICSharpCode.ILSpy.Search @@ -277,7 +275,7 @@ namespace ICSharpCode.ILSpy.Search
sealed class RunningSearch
{
readonly CancellationTokenSource cts = new CancellationTokenSource();
readonly CancellationTokenSource cts = new();
readonly IList<LoadedAssembly> assemblies;
readonly SearchRequest searchRequest;
readonly SearchMode searchMode;
@ -299,8 +297,8 @@ namespace ICSharpCode.ILSpy.Search @@ -299,8 +297,8 @@ namespace ICSharpCode.ILSpy.Search
{
string[] parts = CommandLineTools.CommandLineToArgumentArray(input);
SearchRequest request = new SearchRequest();
List<string> keywords = new List<string>();
SearchRequest request = new();
List<string> keywords = new();
Regex regex = null;
request.Mode = searchMode;
@ -350,7 +348,6 @@ namespace ICSharpCode.ILSpy.Search @@ -350,7 +348,6 @@ namespace ICSharpCode.ILSpy.Search
// then we do not interpret it as prefix, but as searchTerm.
searchTerm = part;
prefix = null;
prefixLength = -1;
}
if (prefix == null || prefix.Length <= 2)
@ -442,7 +439,7 @@ namespace ICSharpCode.ILSpy.Search @@ -442,7 +439,7 @@ namespace ICSharpCode.ILSpy.Search
{
try
{
return new Regex(s, RegexOptions.Compiled);
return new(s, RegexOptions.Compiled);
}
catch (ArgumentException)
{
@ -540,9 +537,11 @@ namespace ICSharpCode.ILSpy.Search @@ -540,9 +537,11 @@ namespace ICSharpCode.ILSpy.Search
public ShowSearchCommand()
: base(NavigationCommands.Search)
{
NavigationCommands.Search.InputGestures.Clear();
NavigationCommands.Search.InputGestures.Add(new KeyGesture(Key.F, ModifierKeys.Control | ModifierKeys.Shift));
NavigationCommands.Search.InputGestures.Add(new KeyGesture(Key.E, ModifierKeys.Control));
var gestures = NavigationCommands.Search.InputGestures;
gestures.Clear();
gestures.Add(new KeyGesture(Key.F, ModifierKeys.Control | ModifierKeys.Shift));
gestures.Add(new KeyGesture(Key.E, ModifierKeys.Control));
}
}
}

41
ILSpy/ViewModels/SearchPaneModel.cs → ILSpy/Search/SearchPaneModel.cs

@ -17,15 +17,28 @@ @@ -17,15 +17,28 @@
// DEALINGS IN THE SOFTWARE.
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace ICSharpCode.ILSpy.ViewModels
using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX.Search;
namespace ICSharpCode.ILSpy.Search
{
public class SearchModeModel
{
public SearchMode Mode { get; init; }
public string Name { get; init; }
public ImageSource Image { get; init; }
}
[ExportToolPane]
[PartCreationPolicy(CreationPolicy.Shared)]
[Export]
public class SearchPaneModel : ToolPaneModel
{
private string searchTerm;
public const string PaneContentId = "searchPane";
public SearchPaneModel()
@ -37,10 +50,26 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -37,10 +50,26 @@ namespace ICSharpCode.ILSpy.ViewModels
IsCloseable = true;
}
public override void Show()
{
base.Show();
MainWindow.Instance.SearchPane.Show();
public SearchModeModel[] SearchModes { get; } = [
new() { Mode = SearchMode.TypeAndMember, Image = Images.Library, Name = "Types and Members" },
new() { Mode = SearchMode.Type, Image = Images.Class, Name = "Type" },
new() { Mode = SearchMode.Member, Image = Images.Property, Name = "Member" },
new() { Mode = SearchMode.Method, Image = Images.Method, Name = "Method" },
new() { Mode = SearchMode.Field, Image = Images.Field, Name = "Field" },
new() { Mode = SearchMode.Property, Image = Images.Property, Name = "Property" },
new() { Mode = SearchMode.Event, Image = Images.Event, Name = "Event" },
new() { Mode = SearchMode.Literal, Image = Images.Literal, Name = "Constant" },
new() { Mode = SearchMode.Token, Image = Images.Library, Name = "Metadata Token" },
new() { Mode = SearchMode.Resource, Image = Images.Resource, Name = "Resource" },
new() { Mode = SearchMode.Assembly, Image = Images.Assembly, Name = "Assembly" },
new() { Mode = SearchMode.Namespace, Image = Images.Namespace, Name = "Namespace" }
];
public SessionSettings SessionSettings => SettingsService.Instance.SessionSettings;
public string SearchTerm {
get => searchTerm;
set => SetProperty(ref searchTerm, value);
}
}
}

4
ILSpy/TextView/DecompilerTextView.cs

@ -181,11 +181,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -181,11 +181,11 @@ namespace ICSharpCode.ILSpy.TextView
void CurrentDisplaySettings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(DisplaySettingsViewModel.ShowLineNumbers))
if (e.PropertyName == nameof(DisplaySettings.ShowLineNumbers))
{
ShowLineMargin();
}
else if (e.PropertyName == nameof(DisplaySettingsViewModel.HighlightCurrentLine))
else if (e.PropertyName == nameof(DisplaySettings.HighlightCurrentLine))
{
SetHighlightCurrentLine();
}

2
ILSpy/Themes/WindowStyleManagerBehavior.cs

@ -85,7 +85,7 @@ namespace ICSharpCode.ILSpy.Themes @@ -85,7 +85,7 @@ namespace ICSharpCode.ILSpy.Themes
private void DisplaySettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(DisplaySettingsViewModel.StyleWindowTitleBar))
if (e.PropertyName == nameof(DisplaySettings.StyleWindowTitleBar))
{
if (!SettingsService.Instance.DisplaySettings.StyleWindowTitleBar)
{

2
ILSpy/Util/SettingsService.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.Util @@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.Util
public DecompilerSettings DecompilerSettings { get; set; }
public DisplaySettingsViewModel DisplaySettings { get; }
public DisplaySettings DisplaySettings { get; }
public AssemblyListManager AssemblyListManager { get; }
}

103
ILSpy/ViewModels/PaneModel.cs

@ -18,8 +18,11 @@ @@ -18,8 +18,11 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.ILSpy.Docking;
using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy.ViewModels
@ -57,93 +60,81 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -57,93 +60,81 @@ namespace ICSharpCode.ILSpy.ViewModels
}
}
public PaneModel()
{
this.closeCommand = new CloseCommandImpl(this);
}
private bool isSelected;
private bool isSelected = false;
public bool IsSelected {
get => isSelected;
set {
if (isSelected != value)
{
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
set => SetProperty(ref isSelected, value);
}
private bool isActive = false;
private bool isActive;
public bool IsActive {
get => isActive;
set {
if (isActive != value)
{
isActive = value;
OnPropertyChanged(nameof(IsActive));
}
}
set => SetProperty(ref isActive, value);
}
private bool isVisible;
public bool IsVisible {
get { return isVisible; }
set {
if (isVisible != value)
if (SetProperty(ref isVisible, value) && !value)
{
isVisible = value;
OnPropertyChanged(nameof(IsVisible));
// When the pane is hidden, it should no longer be marked as active, else it won't raise an event when it is activated again.
IsActive = false;
}
}
}
private bool isCloseable = true;
public bool IsCloseable {
get { return isCloseable; }
set {
if (isCloseable != value)
{
isCloseable = value;
OnPropertyChanged(nameof(IsCloseable));
}
}
get => isCloseable;
set => SetProperty(ref isCloseable, value);
}
private ICommand closeCommand;
public ICommand CloseCommand {
get { return closeCommand; }
set {
if (closeCommand != value)
{
closeCommand = value;
OnPropertyChanged(nameof(CloseCommand));
}
}
}
public ICommand CloseCommand => new CloseCommandImpl(this);
private string contentId;
public string ContentId {
get => contentId;
set {
if (contentId != value)
{
contentId = value;
OnPropertyChanged(nameof(ContentId));
}
}
set => SetProperty(ref contentId, value);
}
private string title;
public string Title {
get => title;
set {
if (title != value)
{
title = value;
OnPropertyChanged(nameof(Title));
}
}
set => SetProperty(ref title, value);
}
}
public static class Pane
{
// Helper properties to enable binding state properties from the model to the view.
public static readonly DependencyProperty IsActiveProperty = DependencyProperty.RegisterAttached(
"IsActive", typeof(bool), typeof(Pane), new FrameworkPropertyMetadata(default(bool)));
public static void SetIsActive(DependencyObject element, bool value)
{
element.SetValue(IsActiveProperty, value);
}
public static bool GetIsActive(DependencyObject element)
{
return (bool)element.GetValue(IsActiveProperty);
}
public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.RegisterAttached(
"IsVisible", typeof(bool), typeof(Pane), new FrameworkPropertyMetadata(default(bool)));
public static void SetIsVisible(DependencyObject element, bool value)
{
element.SetValue(IsVisibleProperty, value);
}
public static bool GetIsVisible(DependencyObject element)
{
return (bool)element.GetValue(IsVisibleProperty);
}
}
}

Loading…
Cancel
Save