Browse Source

Get rid of singletons, replace with DI: DockWorkspace

pull/3314/head
tom-englert 9 months ago
parent
commit
61b0714a4b
  1. 2
      ILSpy/App.xaml.cs
  2. 32
      ILSpy/AssemblyTree/AssemblyTreeModel.cs
  3. 11
      ILSpy/Commands/DecompileAllCommand.cs
  4. 15
      ILSpy/Commands/DecompileInNewViewCommand.cs
  5. 7
      ILSpy/Commands/DisassembleAllCommand.cs
  6. 7
      ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs
  7. 13
      ILSpy/Commands/GeneratePdbContextMenuEntry.cs
  8. 15
      ILSpy/Commands/Pdb2XmlCommand.cs
  9. 11
      ILSpy/Commands/SaveCodeContextMenuEntry.cs
  10. 5
      ILSpy/Commands/SaveCommand.cs
  11. 28
      ILSpy/Commands/ShowPane.cs
  12. 17
      ILSpy/Controls/ZoomScrollViewer.cs
  13. 8
      ILSpy/Docking/CloseAllDocumentsCommand.cs
  14. 49
      ILSpy/Docking/DockWorkspace.cs
  15. 3
      ILSpy/Languages/CSharpILMixedLanguage.cs
  16. 34
      ILSpy/Languages/ILAstLanguage.cs
  17. 3
      ILSpy/Languages/ILLanguage.cs
  18. 5
      ILSpy/Languages/LanguageService.cs
  19. 7
      ILSpy/MainWindowViewModel.cs
  20. 7
      ILSpy/Search/SearchPane.xaml.cs
  21. 16
      ILSpy/SolutionWriter.cs
  22. 3
      ILSpy/TaskHelper.cs
  23. 2
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  24. 3
      ILSpy/TreeNodes/ILSpyTreeNode.cs
  25. 2
      ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs
  26. 2
      ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs
  27. 18
      ILSpy/Util/MenuService.cs
  28. 5
      ILSpy/ViewModels/PaneModel.cs
  29. 10
      ILSpy/Views/DebugSteps.xaml.cs

2
ILSpy/App.xaml.cs

@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy @@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy
if (!InitializeDependencyInjection(settingsService))
{
// There is something completely wrong with DI, probably some service registration is missing => nothing we can do to recover, so stop and shut down.
Exit += (_, _) => MessageBox.Show(StartupExceptions.FormatExceptions(), "Sorry we crashed!");
Exit += (_, _) => MessageBox.Show(StartupExceptions.FormatExceptions(), "Sorry we crashed!", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);
Shutdown(1);
return;
}

32
ILSpy/AssemblyTree/AssemblyTreeModel.cs

@ -264,7 +264,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -264,7 +264,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.Write($"Cannot find '{navigateTo}' in command line specified assemblies.");
DockWorkspace.Instance.ShowText(output);
DockWorkspace.ShowText(output);
}
}
else if (relevantAssemblies.Count == 1)
@ -304,7 +304,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -304,7 +304,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
}
else
{
DockWorkspace.Instance.ActiveTabPage.ShowTextView(aboutPage.Display);
DockWorkspace.ActiveTabPage.ShowTextView(aboutPage.Display);
}
}
}
@ -405,8 +405,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -405,8 +405,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
output.Title = "Startup errors";
DockWorkspace.Instance.AddTabPage();
DockWorkspace.Instance.ShowText(output);
DockWorkspace.AddTabPage();
DockWorkspace.ShowText(output);
}
}
@ -524,7 +524,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -524,7 +524,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
if (inNewTabPage)
{
DockWorkspace.Instance.AddTabPage();
DockWorkspace.AddTabPage();
SelectedItem = null;
}
@ -739,7 +739,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -739,7 +739,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
}
else
{
var activeTabPage = DockWorkspace.Instance.ActiveTabPage;
var activeTabPage = DockWorkspace.ActiveTabPage;
if (!isNavigatingHistory)
{
@ -787,7 +787,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -787,7 +787,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
public void DecompileSelectedNodes(DecompilerTextViewState? newState = null)
{
var activeTabPage = DockWorkspace.Instance.ActiveTabPage;
var activeTabPage = DockWorkspace.ActiveTabPage;
activeTabPage.SupportsLanguageSwitching = true;
@ -809,7 +809,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -809,7 +809,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
public void RefreshDecompiledView()
{
DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState);
DecompileSelectedNodes(DockWorkspace.ActiveTabPage.GetState() as DecompilerTextViewState);
}
public Language CurrentLanguage => languageService.Language;
@ -830,7 +830,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -830,7 +830,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
isNavigatingHistory = true;
TabPageModel tabPage = DockWorkspace.Instance.ActiveTabPage;
TabPageModel tabPage = DockWorkspace.ActiveTabPage;
var state = tabPage.GetState();
if (state != null)
history.UpdateCurrent(new NavigationState(tabPage, state));
@ -838,10 +838,10 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -838,10 +838,10 @@ namespace ICSharpCode.ILSpy.AssemblyTree
TabPageModel activeTabPage = newState.TabPage;
if (!DockWorkspace.Instance.TabPages.Contains(activeTabPage))
DockWorkspace.Instance.AddTabPage(activeTabPage);
if (!DockWorkspace.TabPages.Contains(activeTabPage))
DockWorkspace.AddTabPage(activeTabPage);
else
DockWorkspace.Instance.ActiveTabPage = activeTabPage;
DockWorkspace.ActiveTabPage = activeTabPage;
SelectNodes(newState.TreeNodes);
}
@ -861,13 +861,13 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -861,13 +861,13 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
if (inNewTabPage)
{
DockWorkspace.Instance.AddTabPage();
DockWorkspace.AddTabPage();
}
if (e.Uri.Host == "aboutpage")
{
RecordHistory();
DockWorkspace.Instance.ActiveTabPage.ShowTextView(aboutPage.Display);
DockWorkspace.ActiveTabPage.ShowTextView(aboutPage.Display);
e.Handled = true;
return;
}
@ -891,7 +891,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -891,7 +891,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
}
}
RecordHistory();
DockWorkspace.Instance.ShowText(output);
DockWorkspace.ShowText(output);
e.Handled = true;
}
@ -899,7 +899,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -899,7 +899,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
if (isNavigatingHistory)
return;
TabPageModel tabPage = DockWorkspace.Instance.ActiveTabPage;
TabPageModel tabPage = DockWorkspace.ActiveTabPage;
var currentState = tabPage.GetState();
if (currentState != null)
history.UpdateCurrent(new NavigationState(tabPage, currentState));

11
ILSpy/Commands/DecompileAllCommand.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy @@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
[Shared]
sealed class DecompileAllCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
sealed class DecompileAllCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy @@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy
public override void Execute(object parameter)
{
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
Parallel.ForEach(
Partitioner.Create(assemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),
@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy @@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy
{
try
{
var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions();
var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
options.CancellationToken = ct;
options.FullDecompilation = true;
new CSharpLanguage().DecompileAssembly(asm, new PlainTextOutput(writer), options);
@ -85,20 +85,19 @@ namespace ICSharpCode.ILSpy @@ -85,20 +85,19 @@ namespace ICSharpCode.ILSpy
}
});
return output;
}, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions();
}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();
}
}
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile100x), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
[Shared]
sealed class Decompile100TimesCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
sealed class Decompile100TimesCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : SimpleCommand
{
public override void Execute(object parameter)
{
const int numRuns = 100;
var language = languageService.Language;
var nodes = assemblyTreeModel.SelectedNodes.ToArray();
DockWorkspace dockWorkspace = DockWorkspace.Instance;
var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
options.CancellationToken = ct;

15
ILSpy/Commands/DecompileInNewViewCommand.cs

@ -35,15 +35,8 @@ namespace ICSharpCode.ILSpy.Commands @@ -35,15 +35,8 @@ namespace ICSharpCode.ILSpy.Commands
{
[ExportContextMenuEntry(Header = nameof(Resources.DecompileToNewPanel), InputGestureText = "MMB", Icon = "images/Search", Category = nameof(Resources.Analyze), Order = 90)]
[Shared]
internal sealed class DecompileInNewViewCommand : IContextMenuEntry
internal sealed class DecompileInNewViewCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : IContextMenuEntry
{
private readonly AssemblyTreeModel assemblyTreeModel;
public DecompileInNewViewCommand(AssemblyTreeModel assemblyTreeModel)
{
this.assemblyTreeModel = assemblyTreeModel;
}
public bool IsVisible(TextViewContext context)
{
return context.SelectedTreeNodes != null || context.Reference?.Reference is IEntity;
@ -56,11 +49,11 @@ namespace ICSharpCode.ILSpy.Commands @@ -56,11 +49,11 @@ namespace ICSharpCode.ILSpy.Commands
public void Execute(TextViewContext context)
{
var activePane = DockWorkspace.Instance.ActivePane;
var activePane = dockWorkspace.ActivePane;
DecompileNodes(GetNodes(context).ToArray());
DockWorkspace.Instance.ActivePane = activePane;
dockWorkspace.ActivePane = activePane;
}
IEnumerable<ILSpyTreeNode> GetNodes(TextViewContext context)
@ -98,7 +91,7 @@ namespace ICSharpCode.ILSpy.Commands @@ -98,7 +91,7 @@ namespace ICSharpCode.ILSpy.Commands
if (nodes.Length == 0)
return;
DockWorkspace.Instance.AddTabPage();
dockWorkspace.AddTabPage();
if (assemblyTreeModel.SelectedItems.SequenceEqual(nodes))
assemblyTreeModel.DecompileSelectedNodes();

7
ILSpy/Commands/DisassembleAllCommand.cs

@ -25,6 +25,7 @@ using System.Diagnostics; @@ -25,6 +25,7 @@ using System.Diagnostics;
using System.Threading.Tasks;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
@ -33,7 +34,7 @@ namespace ICSharpCode.ILSpy @@ -33,7 +34,7 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDisassemble), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
[Shared]
sealed class DisassembleAllCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
sealed class DisassembleAllCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
@ -42,8 +43,6 @@ namespace ICSharpCode.ILSpy @@ -42,8 +43,6 @@ namespace ICSharpCode.ILSpy
public override void Execute(object parameter)
{
var dockWorkspace = Docking.DockWorkspace.Instance;
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new();
Parallel.ForEach(
@ -61,7 +60,7 @@ namespace ICSharpCode.ILSpy @@ -61,7 +60,7 @@ namespace ICSharpCode.ILSpy
var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
options.CancellationToken = ct;
new ILLanguage().DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), options);
new ILLanguage(dockWorkspace).DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), options);
}
catch (Exception ex)
{

7
ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs

@ -25,6 +25,7 @@ using System.Threading.Tasks; @@ -25,6 +25,7 @@ using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
@ -36,7 +37,7 @@ namespace ICSharpCode.ILSpy @@ -36,7 +37,7 @@ namespace ICSharpCode.ILSpy
{
[ExportContextMenuEntry(Header = nameof(Resources.ExtractPackageEntry), Category = nameof(Resources.Save), Icon = "Images/Save")]
[Shared]
sealed class ExtractPackageEntryContextMenuEntry : IContextMenuEntry
sealed class ExtractPackageEntryContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
@ -61,7 +62,7 @@ namespace ICSharpCode.ILSpy @@ -61,7 +62,7 @@ namespace ICSharpCode.ILSpy
if (selectedNodes.Length > 1)
outputFolderOrFileName = Path.GetDirectoryName(outputFolderOrFileName);
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
Stopwatch stopwatch = Stopwatch.StartNew();
stopwatch.Stop();
@ -83,7 +84,7 @@ namespace ICSharpCode.ILSpy @@ -83,7 +84,7 @@ namespace ICSharpCode.ILSpy
output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
output.WriteLine();
return output;
}, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions();
}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();
}
void SaveEntry(ITextOutput output, PackageEntry entry, string targetFileName)

13
ILSpy/Commands/GeneratePdbContextMenuEntry.cs

@ -43,14 +43,14 @@ namespace ICSharpCode.ILSpy @@ -43,14 +43,14 @@ namespace ICSharpCode.ILSpy
{
[ExportContextMenuEntry(Header = nameof(Resources.GeneratePortable))]
[Shared]
class GeneratePdbContextMenuEntry(LanguageService languageService) : IContextMenuEntry
class GeneratePdbContextMenuEntry(LanguageService languageService, DockWorkspace dockWorkspace) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
var assembly = (context.SelectedTreeNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
if (assembly == null)
return;
GeneratePdbForAssembly(assembly, languageService);
GeneratePdbForAssembly(assembly, languageService, dockWorkspace);
}
public bool IsEnabled(TextViewContext context) => true;
@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpy @@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpy
&& tn.LoadedAssembly.IsLoadedAsValidAssembly;
}
internal static void GeneratePdbForAssembly(LoadedAssembly assembly, LanguageService languageService)
internal static void GeneratePdbForAssembly(LoadedAssembly assembly, LanguageService languageService, DockWorkspace dockWorkspace)
{
var file = assembly.GetMetadataFileOrNull() as PEFile;
if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))
@ -76,7 +76,6 @@ namespace ICSharpCode.ILSpy @@ -76,7 +76,6 @@ namespace ICSharpCode.ILSpy
dlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName);
if (dlg.ShowDialog() != true)
return;
DockWorkspace dockWorkspace = DockWorkspace.Instance;
DecompilationOptions options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
string fileName = dlg.FileName;
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
@ -104,13 +103,13 @@ namespace ICSharpCode.ILSpy @@ -104,13 +103,13 @@ namespace ICSharpCode.ILSpy
output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
output.WriteLine();
return output;
}, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions();
}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();
}
}
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.GeneratePortable), MenuCategory = nameof(Resources.Save))]
[Shared]
class GeneratePdbMainMenuEntry(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
class GeneratePdbMainMenuEntry(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
@ -124,7 +123,7 @@ namespace ICSharpCode.ILSpy @@ -124,7 +123,7 @@ namespace ICSharpCode.ILSpy
var assembly = (assemblyTreeModel.SelectedNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
if (assembly == null)
return;
GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly, languageService);
GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly, languageService, dockWorkspace);
}
}
}

15
ILSpy/Commands/Pdb2XmlCommand.cs

@ -27,6 +27,7 @@ using System.Threading.Tasks; @@ -27,6 +27,7 @@ using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
@ -37,7 +38,7 @@ namespace ICSharpCode.ILSpy @@ -37,7 +38,7 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDumpPDBAsXML), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
[Shared]
sealed class Pdb2XmlCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
sealed class Pdb2XmlCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
@ -48,14 +49,14 @@ namespace ICSharpCode.ILSpy @@ -48,14 +49,14 @@ namespace ICSharpCode.ILSpy
public override void Execute(object parameter)
{
Execute(assemblyTreeModel.SelectedNodes.OfType<AssemblyTreeNode>());
Execute(assemblyTreeModel.SelectedNodes.OfType<AssemblyTreeNode>(), dockWorkspace);
}
internal static void Execute(IEnumerable<AssemblyTreeNode> nodes)
internal static void Execute(IEnumerable<AssemblyTreeNode> nodes, DockWorkspace dockWorkspace)
{
var highlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml");
var options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.IncludeMethodSpans | PdbToXmlOptions.IncludeTokens;
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
var writer = new TextOutputWriter(output);
foreach (var node in nodes)
@ -68,17 +69,17 @@ namespace ICSharpCode.ILSpy @@ -68,17 +69,17 @@ namespace ICSharpCode.ILSpy
PdbToXmlConverter.ToXml(writer, pdbStream, peStream, options);
}
return output;
}, ct)).Then(output => Docking.DockWorkspace.Instance.ShowNodes(output, null, highlighting)).HandleExceptions();
}, ct)).Then(output => dockWorkspace.ShowNodes(output, null, highlighting)).HandleExceptions();
}
}
[ExportContextMenuEntry(Header = nameof(Resources.DEBUGDumpPDBAsXML))]
[Shared]
class Pdb2XmlCommandContextMenuEntry : IContextMenuEntry
class Pdb2XmlCommandContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
Pdb2XmlCommand.Execute(context.SelectedTreeNodes.OfType<AssemblyTreeNode>());
Pdb2XmlCommand.Execute(context.SelectedTreeNodes.OfType<AssemblyTreeNode>(), dockWorkspace);
}
public bool IsEnabled(TextViewContext context) => true;

11
ILSpy/Commands/SaveCodeContextMenuEntry.cs

@ -23,6 +23,7 @@ using System.IO; @@ -23,6 +23,7 @@ using System.IO;
using System.Linq;
using System.Windows;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
@ -35,11 +36,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -35,11 +36,11 @@ namespace ICSharpCode.ILSpy.TextView
{
[ExportContextMenuEntry(Header = nameof(Resources._SaveCode), Category = nameof(Resources.Save), Icon = "Images/Save")]
[Shared]
sealed class SaveCodeContextMenuEntry(LanguageService languageService) : IContextMenuEntry
sealed class SaveCodeContextMenuEntry(LanguageService languageService, DockWorkspace dockWorkspace) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
Execute(context.SelectedTreeNodes, languageService);
Execute(context.SelectedTreeNodes, languageService, dockWorkspace);
}
public bool IsEnabled(TextViewContext context) => true;
@ -57,10 +58,8 @@ namespace ICSharpCode.ILSpy.TextView @@ -57,10 +58,8 @@ namespace ICSharpCode.ILSpy.TextView
|| (selectedNodes.Count > 1 && (selectedNodes.All(n => n is AssemblyTreeNode) || selectedNodes.All(n => n is IMemberTreeNode)));
}
public static void Execute(IReadOnlyList<SharpTreeNode> selectedNodes, LanguageService languageService)
public static void Execute(IReadOnlyList<SharpTreeNode> selectedNodes, LanguageService languageService, DockWorkspace dockWorkspace)
{
var dockWorkspace = Docking.DockWorkspace.Instance;
var currentLanguage = languageService.Language;
var tabPage = dockWorkspace.ActiveTabPage;
tabPage.ShowTextView(textView => {
@ -80,7 +79,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -80,7 +79,7 @@ namespace ICSharpCode.ILSpy.TextView
var assemblies = selectedNodes.OfType<AssemblyTreeNode>()
.Select(n => n.LoadedAssembly)
.Where(a => a.IsLoadedAsValidAssembly).ToArray();
SolutionWriter.CreateSolution(textView, selectedPath, currentLanguage, assemblies);
SolutionWriter.CreateSolution(tabPage, textView, selectedPath, currentLanguage, assemblies);
}
return;
}

5
ILSpy/Commands/SaveCommand.cs

@ -21,6 +21,7 @@ using System.Linq; @@ -21,6 +21,7 @@ using System.Linq;
using System.Windows.Input;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
@ -28,7 +29,7 @@ namespace ICSharpCode.ILSpy @@ -28,7 +29,7 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._SaveCode), MenuIcon = "Images/Save", MenuCategory = nameof(Resources.Save), MenuOrder = 0)]
[Shared]
sealed class SaveCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : CommandWrapper(ApplicationCommands.Save)
sealed class SaveCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : CommandWrapper(ApplicationCommands.Save)
{
protected override void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy
protected override void OnExecute(object sender, ExecutedRoutedEventArgs e)
{
SaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList(), languageService);
SaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList(), languageService, dockWorkspace);
}
}
}

28
ILSpy/Commands/ShowPane.cs

@ -3,39 +3,23 @@ using ICSharpCode.ILSpy.ViewModels; @@ -3,39 +3,23 @@ using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Commands
{
class ToolPaneCommand : SimpleCommand
class ToolPaneCommand(string contentId, DockWorkspace dockWorkspace) : SimpleCommand
{
readonly string contentId;
public ToolPaneCommand(string contentId)
{
this.contentId = contentId;
}
public override void Execute(object parameter)
{
DockWorkspace.Instance.ShowToolPane(contentId);
dockWorkspace.ShowToolPane(contentId);
}
}
class TabPageCommand : SimpleCommand
class TabPageCommand(TabPageModel model, DockWorkspace dockWorkspace) : SimpleCommand
{
readonly TabPageModel model;
public TabPageCommand(TabPageModel model)
{
this.model = model;
}
public override void Execute(object parameter)
{
var workspace = DockWorkspace.Instance;
// ensure the tab control is focused before setting the active tab page, else the tab will not be focused
workspace.ActiveTabPage?.Focus();
dockWorkspace.ActiveTabPage?.Focus();
// reset first, else clicking on the already active tab will not focus the tab and the menu checkmark will not be updated
workspace.ActiveTabPage = null;
workspace.ActiveTabPage = model;
dockWorkspace.ActiveTabPage = null;
dockWorkspace.ActiveTabPage = model;
}
}
}

17
ILSpy/Controls/ZoomScrollViewer.cs

@ -176,21 +176,4 @@ namespace ICSharpCode.ILSpy.Controls @@ -176,21 +176,4 @@ namespace ICSharpCode.ILSpy.Controls
return val;
}
}
sealed class IsNormalZoomConverter : IValueConverter
{
public static readonly IsNormalZoomConverter Instance = new IsNormalZoomConverter();
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (parameter is bool && (bool)parameter)
return true;
return ((double)value) == 1.0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

8
ILSpy/Docking/CloseAllDocumentsCommand.cs

@ -6,21 +6,21 @@ namespace ICSharpCode.ILSpy.Docking @@ -6,21 +6,21 @@ namespace ICSharpCode.ILSpy.Docking
{
[ExportMainMenuCommand(Header = nameof(Resources.Window_CloseAllDocuments), ParentMenuID = nameof(Resources._Window))]
[Shared]
class CloseAllDocumentsCommand : SimpleCommand
class CloseAllDocumentsCommand(DockWorkspace dockWorkspace) : SimpleCommand
{
public override void Execute(object parameter)
{
DockWorkspace.Instance.CloseAllTabs();
dockWorkspace.CloseAllTabs();
}
}
[ExportMainMenuCommand(Header = nameof(Resources.Window_ResetLayout), ParentMenuID = nameof(Resources._Window))]
[Shared]
class ResetLayoutCommand : SimpleCommand
class ResetLayoutCommand(DockWorkspace dockWorkspace) : SimpleCommand
{
public override void Execute(object parameter)
{
DockWorkspace.Instance.ResetLayout();
dockWorkspace.ResetLayout();
}
}
}

49
ILSpy/Docking/DockWorkspace.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Composition;
using System.Linq;
using System.Reflection;
using System.Threading;
@ -43,38 +44,34 @@ using TomsToolbox.Wpf; @@ -43,38 +44,34 @@ using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy.Docking
{
[Export]
[Shared]
public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy
{
private static readonly IExportProvider exportProvider = App.ExportProvider;
private readonly IExportProvider exportProvider;
private SettingsService SettingsService { get; }
private static SettingsService SettingsService => exportProvider.GetExportedValue<SettingsService>();
private LanguageService LanguageService => exportProvider.GetExportedValue<LanguageService>();
private static LanguageService LanguageService => exportProvider.GetExportedValue<LanguageService>();
private static SessionSettings SessionSettings => SettingsService.SessionSettings;
public static readonly DockWorkspace Instance = new();
private SessionSettings SessionSettings { get; }
private readonly ObservableCollection<TabPageModel> tabPages = [];
private DockingManager DockingManager => exportProvider.GetExportedValue<DockingManager>();
AssemblyTreeModel AssemblyTreeModel => exportProvider.GetExportedValue<AssemblyTreeModel>();
private AssemblyTreeModel AssemblyTreeModel => exportProvider.GetExportedValue<AssemblyTreeModel>();
private DockWorkspace()
public DockWorkspace(SettingsService settingsService, IExportProvider exportProvider)
{
this.exportProvider = exportProvider;
SettingsService = settingsService;
SessionSettings = settingsService.SessionSettings;
this.tabPages.CollectionChanged += TabPages_CollectionChanged;
TabPages = new(tabPages);
ToolPanes = exportProvider
.GetExportedValues<ToolPaneModel>("ToolPane")
.OrderBy(item => item.Title)
.ToArray()
.AsReadOnly();
// Make sure there is at least one tab open
AddTabPage();
MessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e);
}
@ -135,7 +132,11 @@ namespace ICSharpCode.ILSpy.Docking @@ -135,7 +132,11 @@ namespace ICSharpCode.ILSpy.Docking
public ReadOnlyObservableCollection<TabPageModel> TabPages { get; }
public ReadOnlyCollection<ToolPaneModel> ToolPanes { get; }
public ReadOnlyCollection<ToolPaneModel> ToolPanes => exportProvider
.GetExportedValues<ToolPaneModel>("ToolPane")
.OrderBy(item => item.Title)
.ToArray()
.AsReadOnly();
public bool ShowToolPane(string contentId)
{
@ -188,15 +189,15 @@ namespace ICSharpCode.ILSpy.Docking @@ -188,15 +189,15 @@ namespace ICSharpCode.ILSpy.Docking
}
public PaneModel ActivePane {
get => DockingManager?.ActiveContent as PaneModel;
set {
if (DockingManager is not null)
DockingManager.ActiveContent = value;
}
get => DockingManager.ActiveContent as PaneModel;
set => DockingManager.ActiveContent = value;
}
public void InitializeLayout()
{
// Make sure there is at least one tab open
AddTabPage();
DockingManager.LayoutUpdateStrategy = this;
XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockingManager);
serializer.LayoutSerializationCallback += LayoutSerializationCallback;

3
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -34,6 +34,7 @@ using ICSharpCode.Decompiler.Disassembler; @@ -34,6 +34,7 @@ using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Extensions;
@ -43,7 +44,7 @@ namespace ICSharpCode.ILSpy @@ -43,7 +44,7 @@ namespace ICSharpCode.ILSpy
[Export(typeof(Language))]
[Shared]
class CSharpILMixedLanguage(SettingsService settingsService) : ILLanguage
class CSharpILMixedLanguage(SettingsService settingsService, DockWorkspace dockWorkspace) : ILLanguage(dockWorkspace)
{
public override string Name => "IL with C#";

34
ILSpy/Languages/ILAstLanguage.cs

@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.IL; @@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
@ -41,13 +42,6 @@ namespace ICSharpCode.ILSpy @@ -41,13 +42,6 @@ namespace ICSharpCode.ILSpy
{
public event EventHandler StepperUpdated;
protected virtual void OnStepperUpdated(EventArgs e = null)
{
StepperUpdated?.Invoke(this, e ?? new EventArgs());
}
public Stepper Stepper { get; set; } = new Stepper();
readonly string name;
protected ILAstLanguage(string name)
@ -55,12 +49,19 @@ namespace ICSharpCode.ILSpy @@ -55,12 +49,19 @@ namespace ICSharpCode.ILSpy
this.name = name;
}
protected virtual void OnStepperUpdated(EventArgs e = null)
{
StepperUpdated?.Invoke(this, e ?? new EventArgs());
}
public Stepper Stepper { get; set; } = new Stepper();
public override string Name { get { return name; } }
internal static IEnumerable<ILAstLanguage> GetDebugLanguages()
internal static IEnumerable<ILAstLanguage> GetDebugLanguages(DockWorkspace dockWorkspace)
{
yield return new TypedIL();
yield return new BlockIL(CSharpDecompiler.GetILTransforms());
yield return new BlockIL(CSharpDecompiler.GetILTransforms(), dockWorkspace);
}
public override string FileExtension {
@ -78,10 +79,8 @@ namespace ICSharpCode.ILSpy @@ -78,10 +79,8 @@ namespace ICSharpCode.ILSpy
output.WriteLine();
}
class TypedIL : ILAstLanguage
class TypedIL() : ILAstLanguage("Typed IL")
{
public TypedIL() : base("Typed IL") { }
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{
base.DecompileMethod(method, output, options);
@ -96,15 +95,8 @@ namespace ICSharpCode.ILSpy @@ -96,15 +95,8 @@ namespace ICSharpCode.ILSpy
}
}
class BlockIL : ILAstLanguage
class BlockIL(IReadOnlyList<IILTransform> transforms, DockWorkspace dockWorkspace) : ILAstLanguage("ILAst")
{
readonly IReadOnlyList<IILTransform> transforms;
public BlockIL(IReadOnlyList<IILTransform> transforms) : base("ILAst")
{
this.transforms = transforms;
}
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{
base.DecompileMethod(method, output, options);
@ -146,7 +138,7 @@ namespace ICSharpCode.ILSpy @@ -146,7 +138,7 @@ namespace ICSharpCode.ILSpy
}
}
(output as ISmartTextOutput)?.AddButton(Images.ViewCode, "Show Steps", delegate {
Docking.DockWorkspace.Instance.ShowToolPane(DebugStepsPaneModel.PaneContentId);
dockWorkspace.ShowToolPane(DebugStepsPaneModel.PaneContentId);
});
output.WriteLine();
il.WriteTo(output, DebugSteps.Options);

3
ILSpy/Languages/ILLanguage.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy
/// </remarks>
[Export(typeof(Language))]
[Shared]
public class ILLanguage : Language
public class ILLanguage(DockWorkspace dockWorkspace) : Language
{
protected bool detectControlStructure = true;
@ -199,7 +199,6 @@ namespace ICSharpCode.ILSpy @@ -199,7 +199,6 @@ namespace ICSharpCode.ILSpy
public override RichText GetRichTextTooltip(IEntity entity)
{
var output = new AvalonEditTextOutput() { IgnoreNewLineAndIndent = true };
var dockWorkspace = DockWorkspace.Instance;
var disasm = CreateDisassembler(output, dockWorkspace.ActiveTabPage.CreateDecompilationOptions());
MetadataFile module = entity.ParentModule?.MetadataFile;

5
ILSpy/Languages/LanguageService.cs

@ -24,6 +24,7 @@ using System.Collections.ObjectModel; @@ -24,6 +24,7 @@ using System.Collections.ObjectModel;
using System.Composition;
using System.Linq;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpyX;
using TomsToolbox.Wpf;
@ -36,7 +37,7 @@ namespace ICSharpCode.ILSpy @@ -36,7 +37,7 @@ namespace ICSharpCode.ILSpy
{
private readonly LanguageSettings languageSettings;
public LanguageService(IEnumerable<Language> languages, SettingsService settingsService)
public LanguageService(IEnumerable<Language> languages, SettingsService settingsService, DockWorkspace dockWorkspace)
{
languageSettings = settingsService.SessionSettings.LanguageSettings;
@ -44,7 +45,7 @@ namespace ICSharpCode.ILSpy @@ -44,7 +45,7 @@ namespace ICSharpCode.ILSpy
sortedLanguages.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));
#if DEBUG
sortedLanguages.AddRange(ILAstLanguage.GetDebugLanguages());
sortedLanguages.AddRange(ILAstLanguage.GetDebugLanguages(dockWorkspace));
sortedLanguages.AddRange(CSharpLanguage.GetDebugLanguages());
#endif
AllLanguages = sortedLanguages.AsReadOnly();

7
ILSpy/MainWindowViewModel.cs

@ -29,11 +29,14 @@ namespace ICSharpCode.ILSpy @@ -29,11 +29,14 @@ namespace ICSharpCode.ILSpy
{
[Export]
[Shared]
public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel, SettingsService settingsService, LanguageService languageService) : ObservableObject
public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel, SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace) : ObservableObject
{
public DockWorkspace Workspace => DockWorkspace.Instance;
public DockWorkspace Workspace { get; } = dockWorkspace;
public SessionSettings SessionSettings => settingsService.SessionSettings;
public LanguageService LanguageService => languageService;
public AssemblyListManager AssemblyListManager => settingsService.AssemblyListManager;
public AnalyzeCommand AnalyzeCommand { get; } = new(assemblyTreeModel, analyzerTreeViewModel);

7
ILSpy/Search/SearchPane.xaml.cs

@ -554,9 +554,12 @@ namespace ICSharpCode.ILSpy.Search @@ -554,9 +554,12 @@ namespace ICSharpCode.ILSpy.Search
[Shared]
sealed class ShowSearchCommand : CommandWrapper
{
public ShowSearchCommand()
private readonly DockWorkspace dockWorkspace;
public ShowSearchCommand(DockWorkspace dockWorkspace)
: base(NavigationCommands.Search)
{
this.dockWorkspace = dockWorkspace;
var gestures = NavigationCommands.Search.InputGestures;
gestures.Clear();
@ -566,7 +569,7 @@ namespace ICSharpCode.ILSpy.Search @@ -566,7 +569,7 @@ namespace ICSharpCode.ILSpy.Search
protected override void OnExecute(object sender, ExecutedRoutedEventArgs e)
{
DockWorkspace.Instance.ShowToolPane(SearchPaneModel.PaneContentId);
dockWorkspace.ShowToolPane(SearchPaneModel.PaneContentId);
}
}
}

16
ILSpy/SolutionWriter.cs

@ -47,15 +47,17 @@ namespace ICSharpCode.ILSpy @@ -47,15 +47,17 @@ namespace ICSharpCode.ILSpy
/// to the <paramref name="solutionFilePath"/>. The directory of this file must either
/// be empty or not exist.
/// </summary>
/// <param name="tabPage"></param>
/// <param name="textView">A reference to the <see cref="DecompilerTextView"/> instance.</param>
/// <param name="solutionFilePath">The target file path of the solution file.</param>
/// <param name="language"></param>
/// <param name="assemblies">The assembly nodes to decompile.</param>
///
/// <exception cref="ArgumentException">Thrown when <paramref name="solutionFilePath"/> is null,
/// an empty or a whitespace string.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="textView"/>> or
/// <paramref name="assemblies"/> is null.</exception>
public static void CreateSolution(DecompilerTextView textView, string solutionFilePath, Language language, IEnumerable<LoadedAssembly> assemblies)
public static void CreateSolution(TabPageModel tabPage, DecompilerTextView textView, string solutionFilePath,
Language language, IEnumerable<LoadedAssembly> assemblies)
{
if (textView == null)
{
@ -75,7 +77,7 @@ namespace ICSharpCode.ILSpy @@ -75,7 +77,7 @@ namespace ICSharpCode.ILSpy
var writer = new SolutionWriter(solutionFilePath);
textView
.RunWithCancellation(ct => writer.CreateSolution(assemblies, language, ct))
.RunWithCancellation(ct => writer.CreateSolution(tabPage, assemblies, language, ct))
.Then(output => textView.ShowText(output))
.HandleExceptions();
}
@ -93,7 +95,7 @@ namespace ICSharpCode.ILSpy @@ -93,7 +95,7 @@ namespace ICSharpCode.ILSpy
projects = new ConcurrentBag<ProjectItem>();
}
async Task<AvalonEditTextOutput> CreateSolution(IEnumerable<LoadedAssembly> assemblies, Language language, CancellationToken ct)
async Task<AvalonEditTextOutput> CreateSolution(TabPageModel tabPage, IEnumerable<LoadedAssembly> assemblies, Language language, CancellationToken ct)
{
var result = new AvalonEditTextOutput();
@ -113,7 +115,7 @@ namespace ICSharpCode.ILSpy @@ -113,7 +115,7 @@ namespace ICSharpCode.ILSpy
// long to decompile.
await Task.Run(() => Parallel.ForEach(Partitioner.Create(assemblies),
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },
n => WriteProject(n, language, solutionDirectory, ct)))
item => WriteProject(tabPage, item, language, solutionDirectory, ct)))
.ConfigureAwait(false);
if (projects.Count == 0)
@ -175,7 +177,7 @@ namespace ICSharpCode.ILSpy @@ -175,7 +177,7 @@ namespace ICSharpCode.ILSpy
return result;
}
void WriteProject(LoadedAssembly loadedAssembly, Language language, string targetDirectory, CancellationToken ct)
void WriteProject(TabPageModel tabPage, LoadedAssembly loadedAssembly, Language language, string targetDirectory, CancellationToken ct)
{
targetDirectory = Path.Combine(targetDirectory, loadedAssembly.ShortName);
@ -214,7 +216,7 @@ namespace ICSharpCode.ILSpy @@ -214,7 +216,7 @@ namespace ICSharpCode.ILSpy
using (var projectFileWriter = new StreamWriter(projectFileName))
{
var projectFileOutput = new PlainTextOutput(projectFileWriter);
var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions();
var options = tabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
options.CancellationToken = ct;
options.SaveAsProjectDirectory = targetDirectory;

3
ILSpy/TaskHelper.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.TextView;
namespace ICSharpCode.ILSpy
@ -200,7 +201,7 @@ namespace ICSharpCode.ILSpy @@ -200,7 +201,7 @@ namespace ICSharpCode.ILSpy
task.Catch<Exception>(exception => App.Current.Dispatcher.BeginInvoke(new Action(delegate {
AvalonEditTextOutput output = new();
output.Write(exception.ToString());
Docking.DockWorkspace.Instance.ShowText(output);
App.ExportProvider.GetExportedValue<DockWorkspace>().ShowText(output);
}))).IgnoreExceptions();
}
}

2
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -547,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -547,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
dlg.Filter = language.Name + " project|*" + language.ProjectFileExtension + "|" + language.Name + " single file|*" + language.FileExtension + "|All files|*.*";
if (dlg.ShowDialog() == true)
{
var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions();
var options = DockWorkspace.ActiveTabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
if (dlg.FilterIndex == 1)
{

3
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -27,6 +27,7 @@ using System.Windows.Threading; @@ -27,6 +27,7 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpyX.Abstractions;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
using ICSharpCode.ILSpyX.TreeView;
@ -57,6 +58,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -57,6 +58,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static LanguageService LanguageService { get; } = App.ExportProvider.GetExportedValue<LanguageService>();
public static DockWorkspace DockWorkspace { get; } = App.ExportProvider.GetExportedValue<DockWorkspace>();
public virtual FilterResult Filter(LanguageSettings settings)
{
if (string.IsNullOrEmpty(settings.SearchTerm))

2
ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs

@ -74,7 +74,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -74,7 +74,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
ISmartTextOutput smartOutput = output as ISmartTextOutput;
if (smartOutput != null)
{
smartOutput.AddButton(Images.Save, Resources.Save, delegate { Save(Docking.DockWorkspace.Instance.ActiveTabPage); });
smartOutput.AddButton(Images.Save, Resources.Save, delegate { Save(DockWorkspace.ActiveTabPage); });
output.WriteLine();
}
}

2
ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs

@ -176,7 +176,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -176,7 +176,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
EnsureLazyChildren();
base.Decompile(language, output, options);
var textView = (DecompilerTextView)Docking.DockWorkspace.Instance.ActiveTabPage.Content;
var textView = (DecompilerTextView)DockWorkspace.ActiveTabPage.Content;
if (stringTableEntries.Count != 0)
{
ISmartTextOutput smartOutput = output as ISmartTextOutput;

18
ILSpy/Util/MenuService.cs

@ -38,10 +38,8 @@ namespace ICSharpCode.ILSpy.Util @@ -38,10 +38,8 @@ namespace ICSharpCode.ILSpy.Util
{
[Export]
[Shared]
public class MenuService(IExportProvider exportProvider)
public class MenuService(IExportProvider exportProvider, DockWorkspace dockWorkspace)
{
private readonly DockWorkspace dockWorkspace = DockWorkspace.Instance;
public void Init(Menu mainMenu, ToolBar toolBar, InputBindingCollection inputBindings)
{
InitMainMenu(mainMenu);
@ -144,7 +142,7 @@ namespace ICSharpCode.ILSpy.Util @@ -144,7 +142,7 @@ namespace ICSharpCode.ILSpy.Util
windowMenuItem.Items.Clear();
var toolItems = dockWorkspace.ToolPanes.Select(toolPane => CreateMenuItem(toolPane, inputBindings)).ToArray();
var tabItems = dockWorkspace.TabPages.ObservableSelect(tabPage => CreateMenuItem(tabPage, dockWorkspace));
var tabItems = dockWorkspace.TabPages.ObservableSelect(tabPage => CreateMenuItem(tabPage));
var allItems = new ObservableCompositeCollection<Control>(defaultItems, [new Separator()], toolItems, [new Separator()], tabItems);
@ -188,7 +186,7 @@ namespace ICSharpCode.ILSpy.Util @@ -188,7 +186,7 @@ namespace ICSharpCode.ILSpy.Util
}
static Control CreateMenuItem(TabPageModel pane, DockWorkspace dock)
Control CreateMenuItem(TabPageModel pane)
{
var header = new TextBlock {
MaxWidth = 200,
@ -200,13 +198,13 @@ namespace ICSharpCode.ILSpy.Util @@ -200,13 +198,13 @@ namespace ICSharpCode.ILSpy.Util
});
MenuItem menuItem = new() {
Command = new TabPageCommand(pane),
Command = new TabPageCommand(pane, dockWorkspace),
Header = header,
IsCheckable = true
};
menuItem.SetBinding(MenuItem.IsCheckedProperty, new Binding(nameof(dock.ActiveTabPage)) {
Source = dock,
menuItem.SetBinding(MenuItem.IsCheckedProperty, new Binding(nameof(dockWorkspace.ActiveTabPage)) {
Source = dockWorkspace,
ConverterParameter = pane,
Converter = BinaryOperationConverter.Equality,
Mode = BindingMode.OneWay
@ -215,10 +213,10 @@ namespace ICSharpCode.ILSpy.Util @@ -215,10 +213,10 @@ namespace ICSharpCode.ILSpy.Util
return menuItem;
}
static Control CreateMenuItem(ToolPaneModel pane, InputBindingCollection inputBindings)
Control CreateMenuItem(ToolPaneModel pane, InputBindingCollection inputBindings)
{
MenuItem menuItem = new() {
Command = pane.AssociatedCommand ?? new ToolPaneCommand(pane.ContentId),
Command = pane.AssociatedCommand ?? new ToolPaneCommand(pane.ContentId, dockWorkspace),
Header = pane.Title
};
var shortcutKey = pane.ShortcutKey;

5
ILSpy/ViewModels/PaneModel.cs

@ -22,6 +22,7 @@ using System.Windows; @@ -22,6 +22,7 @@ using System.Windows;
using System.Windows.Input;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.ILSpy.Docking;
using TomsToolbox.Wpf;
@ -31,6 +32,8 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -31,6 +32,8 @@ namespace ICSharpCode.ILSpy.ViewModels
{
private Throttle titleChangeThrottle;
public static DockWorkspace DockWorkspace => App.ExportProvider.GetExportedValue<DockWorkspace>();
protected PaneModel()
{
titleChangeThrottle = new Throttle(() => OnPropertyChanged(nameof(Title)));
@ -63,7 +66,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -63,7 +66,7 @@ namespace ICSharpCode.ILSpy.ViewModels
public void Execute(object parameter)
{
Docking.DockWorkspace.Instance.Remove(model);
DockWorkspace.Remove(model);
}
}

10
ILSpy/Views/DebugSteps.xaml.cs

@ -22,6 +22,7 @@ namespace ICSharpCode.ILSpy @@ -22,6 +22,7 @@ namespace ICSharpCode.ILSpy
private readonly AssemblyTreeModel assemblyTreeModel;
private readonly SettingsService settingsService;
private readonly LanguageService languageService;
private readonly DockWorkspace dockWorkspace;
static readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions {
UseFieldSugar = true,
@ -33,12 +34,13 @@ namespace ICSharpCode.ILSpy @@ -33,12 +34,13 @@ namespace ICSharpCode.ILSpy
#if DEBUG
ILAstLanguage language;
#endif
public DebugSteps(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService)
public DebugSteps(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace)
{
this.assemblyTreeModel = assemblyTreeModel;
this.settingsService = settingsService;
this.languageService = languageService;
this.dockWorkspace = dockWorkspace;
InitializeComponent();
#if DEBUG
@ -132,8 +134,8 @@ namespace ICSharpCode.ILSpy @@ -132,8 +134,8 @@ namespace ICSharpCode.ILSpy
void DecompileAsync(int step, bool isDebug = false)
{
lastSelectedStep = step;
var state = DockWorkspace.Instance.ActiveTabPage.GetState();
DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes,
var state = dockWorkspace.ActiveTabPage.GetState();
dockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes,
new DecompilationOptions(assemblyTreeModel.CurrentLanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) {
StepLimit = step,
IsDebug = isDebug,

Loading…
Cancel
Save