Browse Source

Decouple some global logic from the MainWindow

pull/3257/head
tom-englert 2 years ago
parent
commit
d38ec53484
  1. 1
      Directory.Packages.props
  2. 61
      ILSpy/Analyzers/AnalyzeCommand.cs
  3. 6
      ILSpy/Analyzers/AnalyzerTreeView.cs
  4. 1
      ILSpy/ILSpy.csproj
  5. 23
      ILSpy/MainWindow.xaml
  6. 9
      ILSpy/MainWindow.xaml.cs
  7. 4
      ILSpy/Search/SearchPane.cs
  8. 5
      ILSpy/Views/DebugSteps.xaml.cs

1
Directory.Packages.props

@ -46,6 +46,7 @@
<PackageVersion Include="System.Resources.Extensions" Version="8.0.0" /> <PackageVersion Include="System.Resources.Extensions" Version="8.0.0" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" /> <PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageVersion Include="TomsToolbox.Wpf.Composition" Version="2.18.1" /> <PackageVersion Include="TomsToolbox.Wpf.Composition" Version="2.18.1" />
<PackageVersion Include="TomsToolbox.Wpf.Composition.Mef" Version="2.18.1" />
<PackageVersion Include="TomsToolbox.Wpf.Styles" Version="2.18.1" /> <PackageVersion Include="TomsToolbox.Wpf.Styles" Version="2.18.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" /> <PackageVersion Include="coverlet.collector" Version="6.0.2" />
</ItemGroup> </ItemGroup>

61
ILSpy/Analyzers/AnalyzeCommand.cs

@ -16,21 +16,30 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.Linq; using System.Linq;
using System.Windows;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using TomsToolbox.Composition;
namespace ICSharpCode.ILSpy.Analyzers namespace ICSharpCode.ILSpy.Analyzers
{ {
[ExportContextMenuEntry(Header = nameof(Resources.Analyze), Icon = "Images/Search", Category = nameof(Resources.Analyze), InputGestureText = "Ctrl+R", Order = 100)] [ExportContextMenuEntry(Header = nameof(Resources.Analyze), Icon = "Images/Search", Category = nameof(Resources.Analyze), InputGestureText = "Ctrl+R", Order = 100)]
[PartCreationPolicy(CreationPolicy.Shared)] [PartCreationPolicy(CreationPolicy.Shared)]
internal sealed class AnalyzeCommand : SimpleCommand, IContextMenuEntry internal sealed class AnalyzeCommand : SimpleCommand, IContextMenuEntry
{ {
private static readonly IExport<AnalyzerTreeView> analyzerTreeViewExport = App.ExportProvider.GetExports<AnalyzerTreeView>().Single();
private static AnalyzerTreeView AnalyzerTreeView {
get {
return Application.Current?.MainWindow?.IsLoaded != true ? null : analyzerTreeViewExport.Value;
}
}
public bool IsVisible(TextViewContext context) public bool IsVisible(TextViewContext context)
{ {
if (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n.Parent.IsRoot)) if (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n.Parent.IsRoot))
@ -43,14 +52,12 @@ namespace ICSharpCode.ILSpy.Analyzers
public bool IsEnabled(TextViewContext context) public bool IsEnabled(TextViewContext context)
{ {
if (context.SelectedTreeNodes == null) if (context.SelectedTreeNodes == null)
return context.Reference != null && context.Reference.Reference is IEntity;
foreach (IMemberTreeNode node in context.SelectedTreeNodes)
{ {
if (!IsValidReference(node.Member)) return context.Reference is { Reference: IEntity };
return false;
} }
return context.SelectedTreeNodes
return true; .OfType<IMemberTreeNode>()
.All(node => IsValidReference(node.Member));
} }
bool IsValidReference(object reference) bool IsValidReference(object reference)
@ -60,52 +67,56 @@ namespace ICSharpCode.ILSpy.Analyzers
public void Execute(TextViewContext context) public void Execute(TextViewContext context)
{ {
AnalyzerTreeView analyzerTreeView = MainWindow.Instance.AnalyzerTreeView; if (AnalyzerTreeView is null)
if (analyzerTreeView == null)
{ {
return; return;
} }
if (context.SelectedTreeNodes != null) if (context.SelectedTreeNodes != null)
{ {
foreach (IMemberTreeNode node in context.SelectedTreeNodes) foreach (var node in context.SelectedTreeNodes.OfType<IMemberTreeNode>().ToArray())
{ {
analyzerTreeView.Analyze(node.Member); AnalyzerTreeView.Analyze(node.Member);
} }
} }
else if (context.Reference != null && context.Reference.Reference is IEntity entity) else if (context.Reference is { Reference: IEntity entity })
{ {
analyzerTreeView.Analyze(entity); AnalyzerTreeView.Analyze(entity);
} }
} }
public override bool CanExecute(object parameter) public override bool CanExecute(object parameter)
{ {
AnalyzerTreeView analyzerTreeView = MainWindow.Instance.AnalyzerTreeView; if (AnalyzerTreeView is null)
if (analyzerTreeView != null && analyzerTreeView.IsKeyboardFocusWithin)
{ {
return analyzerTreeView.SelectedItems.OfType<object>().All(n => n is IMemberTreeNode); return false;
} }
else
if (AnalyzerTreeView is { IsKeyboardFocusWithin: true })
{ {
return MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode); return AnalyzerTreeView.SelectedItems.OfType<object>().All(n => n is IMemberTreeNode);
} }
return MainWindow.Instance.SelectedNodes.All(n => n is IMemberTreeNode);
} }
public override void Execute(object parameter) public override void Execute(object parameter)
{ {
AnalyzerTreeView analyzerTreeView = MainWindow.Instance.AnalyzerTreeView; if (AnalyzerTreeView is null)
if (analyzerTreeView != null && analyzerTreeView.IsKeyboardFocusWithin) {
return;
}
if (AnalyzerTreeView.IsKeyboardFocusWithin)
{ {
foreach (IMemberTreeNode node in MainWindow.Instance.AnalyzerTreeView.SelectedItems.OfType<IMemberTreeNode>().ToArray()) foreach (var node in AnalyzerTreeView.SelectedItems.OfType<IMemberTreeNode>().ToArray())
{ {
MainWindow.Instance.AnalyzerTreeView.Analyze(node.Member); AnalyzerTreeView.Analyze(node.Member);
} }
} }
else else
{ {
foreach (IMemberTreeNode node in MainWindow.Instance.SelectedNodes) foreach (var node in MainWindow.Instance.SelectedNodes.OfType<IMemberTreeNode>())
{ {
MainWindow.Instance.AnalyzerTreeView.Analyze(node.Member); AnalyzerTreeView.Analyze(node.Member);
} }
} }
} }

6
ILSpy/Analyzers/AnalyzerTreeView.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel.Composition;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
@ -30,11 +31,16 @@ using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpy.Controls.TreeView; using ICSharpCode.ILSpy.Controls.TreeView;
using ICSharpCode.ILSpyX.TreeView; using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Wpf.Composition.Mef;
namespace ICSharpCode.ILSpy.Analyzers namespace ICSharpCode.ILSpy.Analyzers
{ {
/// <summary> /// <summary>
/// Analyzer tree view. /// Analyzer tree view.
/// </summary> /// </summary>
[DataTemplate(typeof(AnalyzerPaneModel))]
[PartCreationPolicy(CreationPolicy.Shared)]
[Export]
public class AnalyzerTreeView : SharpTreeView public class AnalyzerTreeView : SharpTreeView
{ {
FilterSettings filterSettings; FilterSettings filterSettings;

1
ILSpy/ILSpy.csproj

@ -51,6 +51,7 @@
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" /> <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" />
<PackageReference Include="NaturalSort.Extension" /> <PackageReference Include="NaturalSort.Extension" />
<PackageReference Include="TomsToolbox.Wpf.Composition" /> <PackageReference Include="TomsToolbox.Wpf.Composition" />
<PackageReference Include="TomsToolbox.Wpf.Composition.Mef" />
<PackageReference Include="TomsToolbox.Wpf.Styles" /> <PackageReference Include="TomsToolbox.Wpf.Styles" />
</ItemGroup> </ItemGroup>

23
ILSpy/MainWindow.xaml

@ -2,8 +2,8 @@
<Window <Window
x:Class="ICSharpCode.ILSpy.MainWindow" x:Class="ICSharpCode.ILSpy.MainWindow"
x:ClassModifier="public" x:ClassModifier="public"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tv="clr-namespace:ICSharpCode.ILSpy.Controls.TreeView" xmlns:tv="clr-namespace:ICSharpCode.ILSpy.Controls.TreeView"
xmlns:local="clr-namespace:ICSharpCode.ILSpy" xmlns:local="clr-namespace:ICSharpCode.ILSpy"
xmlns:search="clr-namespace:ICSharpCode.ILSpy.Search" xmlns:search="clr-namespace:ICSharpCode.ILSpy.Search"
@ -67,29 +67,10 @@
</Style> </Style>
</tv:SharpTreeView.ItemContainerStyle> </tv:SharpTreeView.ItemContainerStyle>
</tv:SharpTreeView> </tv:SharpTreeView>
<DataTemplate DataType="{x:Type viewModels:AssemblyListPaneModel}"> <DataTemplate DataType="{x:Type viewModels:AssemblyListPaneModel}">
<ContentControl Content="{StaticResource AssemblyTreeView}" /> <ContentControl Content="{StaticResource AssemblyTreeView}" />
</DataTemplate> </DataTemplate>
<local:DebugSteps x:Key="DebugSteps" />
<DataTemplate DataType="{x:Type viewModels:DebugStepsPaneModel}">
<ContentControl Content="{StaticResource DebugSteps}" />
</DataTemplate>
<search:SearchPane x:Key="SearchPane" />
<DataTemplate DataType="{x:Type viewModels:SearchPaneModel}">
<ContentControl Content="{StaticResource SearchPane}" />
</DataTemplate>
<analyzers:AnalyzerTreeView x:Key="AnalyzerTreeView" />
<DataTemplate DataType="{x:Type viewModels:AnalyzerPaneModel}">
<ContentControl Content="{StaticResource AnalyzerTreeView}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:TabPageModel}"> <DataTemplate DataType="{x:Type viewModels:TabPageModel}">
<ContentPresenter Content="{Binding Content}" /> <ContentPresenter Content="{Binding Content}" />
</DataTemplate> </DataTemplate>

9
ILSpy/MainWindow.xaml.cs

@ -31,7 +31,6 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Threading; using System.Windows.Threading;
@ -98,15 +97,9 @@ namespace ICSharpCode.ILSpy
} }
} }
public AnalyzerTreeView AnalyzerTreeView {
get {
return !IsLoaded ? null : FindResource("AnalyzerTreeView") as AnalyzerTreeView;
}
}
public SearchPane SearchPane { public SearchPane SearchPane {
get { get {
return FindResource("SearchPane") as SearchPane; return App.ExportProvider.GetExportedValue<SearchPane>();
} }
} }

4
ILSpy/Search/SearchPane.cs

@ -40,11 +40,15 @@ using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Extensions; using ICSharpCode.ILSpyX.Extensions;
using ICSharpCode.ILSpyX.Search; using ICSharpCode.ILSpyX.Search;
using TomsToolbox.Wpf.Composition.Mef;
namespace ICSharpCode.ILSpy.Search namespace ICSharpCode.ILSpy.Search
{ {
/// <summary> /// <summary>
/// Search pane /// Search pane
/// </summary> /// </summary>
[DataTemplate(typeof(SearchPaneModel))]
[PartCreationPolicy(CreationPolicy.Shared)]
public partial class SearchPane : UserControl public partial class SearchPane : UserControl
{ {
const int MAX_RESULTS = 1000; const int MAX_RESULTS = 1000;

5
ILSpy/Views/DebugSteps.xaml.cs

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -9,8 +10,12 @@ using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
using TomsToolbox.Wpf.Composition.Mef;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
{ {
[DataTemplate(typeof(DebugStepsPaneModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class DebugSteps : UserControl public partial class DebugSteps : UserControl
{ {
static readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions { static readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions {

Loading…
Cancel
Save