Skip to content

Commit

Permalink
Fix #3293: Right panel shows old info in case all is deleted in the l…
Browse files Browse the repository at this point in the history
…eft-hand tree
  • Loading branch information
tom-englert committed Oct 3, 2024
1 parent f5c27c3 commit 2c6f06e
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 75 deletions.
14 changes: 6 additions & 8 deletions ICSharpCode.ILSpyX/AssemblyListManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,16 @@ public bool RenameList(string selectedAssemblyList, string newListName)
public void SaveList(AssemblyList list)
{
this.settingsProvider.Update(
delegate (XElement root) {
root => {
XElement? doc = root.Element("AssemblyLists");
if (doc == null)
{
doc = new XElement("AssemblyLists");
root.Add(doc);
}
XElement? listElement = doc.Elements("List").FirstOrDefault(e => (string?)e.Attribute("name") == list.ListName);

XElement? listElement = doc.Elements("List")
.FirstOrDefault(e => (string?)e.Attribute("name") == list.ListName);
if (listElement != null)
listElement.ReplaceWith(list.SaveAsXml());
else
Expand Down Expand Up @@ -163,13 +165,9 @@ public void ClearAll()
{
AssemblyLists.Clear();
this.settingsProvider.Update(
delegate (XElement root) {
root => {
XElement? doc = root.Element("AssemblyLists");
if (doc == null)
{
return;
}
doc.Remove();
doc?.Remove();
});
}

Expand Down
3 changes: 0 additions & 3 deletions ILSpy/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ protected override void OnStartup(StartupEventArgs e)
}

MainWindow = new MainWindow();
MainWindow.Loaded += (sender, args) => {
ExportProvider.GetExportedValue<AssemblyTreeModel>().Initialize();
};
MainWindow.Show();
}

Expand Down
36 changes: 11 additions & 25 deletions ILSpy/AssemblyTree/AssemblyTreeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ public AssemblyTreeModel()
SelectedItems.CollectionChanged += (_, _) => selectionChangeThrottle.Tick();

refreshThrottle = new DispatcherThrottle(DispatcherPriority.Background, RefreshInternal);

AssemblyList = SettingsService.Instance.CreateEmptyAssemblyList();
}

private void Settings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
Expand Down Expand Up @@ -121,7 +123,7 @@ private void Settings_PropertyChanged(object? sender, PropertyChangedEventArgs e
}
}

public AssemblyList? AssemblyList { get; private set; }
public AssemblyList AssemblyList { get; private set; }

private SharpTreeNode? root;
public SharpTreeNode? Root {
Expand Down Expand Up @@ -205,7 +207,7 @@ private async void NavigateOnLaunch(string? navigateTo, string[]? activeTreeView
{
// FindNamespaceNode() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead.
await asm.GetMetadataFileAsync().Catch<Exception>(ex => { });
await asm.GetMetadataFileAsync().Catch<Exception>(_ => { });
NamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName);
if (nsNode != null)
{
Expand Down Expand Up @@ -260,15 +262,15 @@ private async void NavigateOnLaunch(string? navigateTo, string[]? activeTreeView
else if (spySettings != null)
{
SharpTreeNode? node = null;
if (activeTreeViewPath?.Length > 0 && AssemblyList != null)
if (activeTreeViewPath?.Length > 0)
{
foreach (var asm in AssemblyList.GetAssemblies())
{
if (asm.FileName == activeTreeViewPath[0])
{
// FindNodeByPath() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead.
await asm.GetMetadataFileAsync().Catch<Exception>(ex => { });
await asm.GetMetadataFileAsync().Catch<Exception>(_ => { });
}
}
node = FindNodeByPath(activeTreeViewPath, true);
Expand Down Expand Up @@ -401,7 +403,7 @@ private void ShowAssemblyList(string name)
{
AssemblyList list = SettingsService.Instance.AssemblyListManager.LoadList(name);
//Only load a new list when it is a different one
if (list.ListName != AssemblyList?.ListName)
if (list.ListName != AssemblyList.ListName)
{
ShowAssemblyList(list);
SelectNode(Root);
Expand All @@ -411,12 +413,9 @@ private void ShowAssemblyList(string name)
private void ShowAssemblyList(AssemblyList assemblyList)
{
history.Clear();
if (this.AssemblyList != null)
{
this.AssemblyList.CollectionChanged -= assemblyList_CollectionChanged;
}

this.AssemblyList = assemblyList;
AssemblyList.CollectionChanged -= assemblyList_CollectionChanged;
AssemblyList = assemblyList;

assemblyList.CollectionChanged += assemblyList_CollectionChanged;

Expand Down Expand Up @@ -527,11 +526,6 @@ public void SelectNodes(IEnumerable<SharpTreeNode> nodes)
return;
}

if (SelectedItems.SequenceEqual(nodesList))
{
return;
}

if (this.isNavigatingHistory)
{
SelectedItems.Clear();
Expand Down Expand Up @@ -649,8 +643,6 @@ private Task JumpToReferenceAsync(object? reference, bool inNewTabPage = false)
MainWindow.OpenLink(opCode.Link);
break;
case EntityReference unresolvedEntity:
if (AssemblyList is null)
break;
string protocol = unresolvedEntity.Protocol;
var file = unresolvedEntity.ResolveAssembly(AssemblyList);
if (file == null)
Expand Down Expand Up @@ -696,8 +688,6 @@ private void LoadAssemblies(IEnumerable<string> fileNames, List<LoadedAssembly>?
AssemblyTreeNode? lastNode = null;

var assemblyList = AssemblyList;
if (assemblyList is null)
return;

foreach (string file in fileNames)
{
Expand Down Expand Up @@ -907,11 +897,7 @@ private void RefreshInternal()
{
var path = GetPathForNode(SelectedItem);

if (AssemblyList != null)
{
ShowAssemblyList(SettingsService.Instance.AssemblyListManager.LoadList(AssemblyList.ListName));
}

ShowAssemblyList(SettingsService.Instance.AssemblyListManager.LoadList(AssemblyList.ListName));
SelectNode(FindNodeByPath(path, true), inNewTabPage: false);

RefreshDecompiledView();
Expand Down Expand Up @@ -940,7 +926,7 @@ public void SortAssemblyList()
{
using (activeView?.LockUpdates())
{
AssemblyList?.Sort(AssemblyComparer.Instance);
AssemblyList.Sort(AssemblyComparer.Instance);
}
}

Expand Down
29 changes: 23 additions & 6 deletions ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.ComponentModel.Composition;
using System.Linq;

using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;

namespace ICSharpCode.ILSpy
Expand All @@ -27,18 +28,26 @@ namespace ICSharpCode.ILSpy
[PartCreationPolicy(CreationPolicy.Shared)]
class RemoveAssembliesWithLoadErrors : SimpleCommand
{
private readonly AssemblyTreeModel assemblyTreeModel;

[ImportingConstructor]
public RemoveAssembliesWithLoadErrors(AssemblyTreeModel assemblyTreeModel)
{
this.assemblyTreeModel = assemblyTreeModel;
}

public override bool CanExecute(object parameter)
{
return MainWindow.Instance.AssemblyTreeModel.AssemblyList?.GetAssemblies().Any(l => l.HasLoadError) == true;
return assemblyTreeModel.AssemblyList.GetAssemblies().Any(l => l.HasLoadError);
}

public override void Execute(object parameter)
{
foreach (var asm in MainWindow.Instance.AssemblyTreeModel.AssemblyList.GetAssemblies())
foreach (var assembly in assemblyTreeModel.AssemblyList.GetAssemblies())
{
if (!asm.HasLoadError)
if (!assembly.HasLoadError)
continue;
var node = MainWindow.Instance.AssemblyTreeModel.FindAssemblyNode(asm);
var node = MainWindow.Instance.AssemblyTreeModel.FindAssemblyNode(assembly);
if (node != null && node.CanDelete())
node.Delete();
}
Expand All @@ -49,14 +58,22 @@ public override void Execute(object parameter)
[PartCreationPolicy(CreationPolicy.Shared)]
class ClearAssemblyList : SimpleCommand
{
private readonly AssemblyTreeModel assemblyTreeModel;

[ImportingConstructor]
public ClearAssemblyList(AssemblyTreeModel assemblyTreeModel)
{
this.assemblyTreeModel = assemblyTreeModel;
}

public override bool CanExecute(object parameter)
{
return MainWindow.Instance.AssemblyTreeModel.AssemblyList?.Count > 0;
return assemblyTreeModel.AssemblyList.Count > 0;
}

public override void Execute(object parameter)
{
MainWindow.Instance.AssemblyTreeModel.AssemblyList?.Clear();
assemblyTreeModel.AssemblyList.Clear();
}
}
}
7 changes: 1 addition & 6 deletions ILSpy/Docking/CloseAllDocumentsCommand.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;

using ICSharpCode.ILSpy.Properties;

Expand Down
55 changes: 32 additions & 23 deletions ILSpy/Docking/DockWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
Expand Down Expand Up @@ -51,13 +52,17 @@ public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy
public static readonly DockWorkspace Instance = new();

private readonly ObservableCollection<TabPageModel> tabPages = [];
private readonly ObservableCollection<ToolPaneModel> toolPanes = [];

private DockWorkspace()
{
this.tabPages.CollectionChanged += TabPages_CollectionChanged;
TabPages = new(tabPages);
ToolPanes = new(toolPanes);

ToolPanes = exportProvider
.GetExportedValues<ToolPaneModel>("ToolPane")
.OrderBy(item => item.Title)
.ToArray()
.AsReadOnly();

// Make sure there is at least one tab open
AddTabPage();
Expand All @@ -83,11 +88,16 @@ private void CurrentAssemblyList_Changed(object sender, NotifyCollectionChangedE
.ExceptNullItems()
.Any(assemblyNode => !e.OldItems.Contains(assemblyNode.LoadedAssembly));

if (!found && tabPages.Count > 1)
if (!found)
{
tabPages.Remove(tab);
}
}

if (tabPages.Count == 0)
{
AddTabPage();
}
}

private void TabPages_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
Expand Down Expand Up @@ -117,11 +127,11 @@ public void AddTabPage(TabPageModel tabPage = null)

public ReadOnlyObservableCollection<TabPageModel> TabPages { get; }

public ReadOnlyObservableCollection<ToolPaneModel> ToolPanes { get; }
public ReadOnlyCollection<ToolPaneModel> ToolPanes { get; }

public bool ShowToolPane(string contentId)
{
var pane = toolPanes.FirstOrDefault(p => p.ContentId == contentId);
var pane = ToolPanes.FirstOrDefault(p => p.ContentId == contentId);
if (pane != null)
{
pane.Show();
Expand All @@ -132,10 +142,15 @@ public bool ShowToolPane(string contentId)

public void Remove(PaneModel model)
{
if (model is TabPageModel document)
tabPages.Remove(document);
if (model is ToolPaneModel tool)
tool.IsVisible = false;
switch (model)
{
case TabPageModel document:
tabPages.Remove(document);
break;
case ToolPaneModel tool:
tool.IsVisible = false;
break;
}
}

private TabPageModel activeTabPage = null;
Expand Down Expand Up @@ -166,10 +181,6 @@ public TabPageModel ActiveTabPage {

public void InitializeLayout(DockingManager manager)
{
var panes = exportProvider.GetExportedValues<ToolPaneModel>("ToolPane").OrderBy(item => item.Title);

this.toolPanes.AddRange(panes);

manager.LayoutUpdateStrategy = this;
XmlLayoutSerializer serializer = new XmlLayoutSerializer(manager);
serializer.LayoutSerializationCallback += LayoutSerializationCallback;
Expand All @@ -188,13 +199,13 @@ void LayoutSerializationCallback(object sender, LayoutSerializationCallbackEvent
switch (e.Model)
{
case LayoutAnchorable la:
e.Content = this.toolPanes.FirstOrDefault(p => p.ContentId == la.ContentId);
e.Content = this.ToolPanes.FirstOrDefault(p => p.ContentId == la.ContentId);
e.Cancel = e.Content == null;
la.CanDockAsTabbedDocument = false;
if (!e.Cancel)
if (e.Content is ToolPaneModel toolPaneModel)
{
e.Cancel = ((ToolPaneModel)e.Content).IsVisible;
((ToolPaneModel)e.Content).IsVisible = true;
e.Cancel = toolPaneModel.IsVisible;
toolPaneModel.IsVisible = true;
}
break;
default:
Expand All @@ -220,16 +231,14 @@ internal void ShowNodes(AvalonEditTextOutput output, TreeNodes.ILSpyTreeNode[] n

internal void CloseAllTabs()
{
foreach (var doc in tabPages.ToArray())
{
if (doc.IsCloseable)
tabPages.Remove(doc);
}
var activePage = ActiveTabPage;

tabPages.RemoveWhere(page => page != activePage);
}

internal void ResetLayout()
{
foreach (var pane in toolPanes)
foreach (var pane in ToolPanes)
{
pane.IsVisible = false;
}
Expand Down
10 changes: 7 additions & 3 deletions ILSpy/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

using AvalonDock.Layout.Serialization;

Expand Down Expand Up @@ -70,11 +71,14 @@ public MainWindow()

InitializeComponent();

mainWindowViewModel.Workspace.InitializeLayout(dockManager);
InitFileLoaders();

MenuService.Instance.Init(mainMenu, toolBar, InputBindings);
Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {
mainWindowViewModel.Workspace.InitializeLayout(dockManager);
MenuService.Instance.Init(mainMenu, toolBar, InputBindings);

InitFileLoaders();
Dispatcher.BeginInvoke(DispatcherPriority.Background, AssemblyTreeModel.Initialize);
});
}

void SetWindowBounds(Rect bounds)
Expand Down
Loading

0 comments on commit 2c6f06e

Please sign in to comment.