Skip to content

Commit 751f109

Browse files
Merge pull request #3642 from lextudio/wpf-isolation
Refactor for cross platform port (#3641)
2 parents 6db9a02 + c735e20 commit 751f109

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1489
-715
lines changed

ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,26 @@ public bool LazyLoading {
323323
}
324324
RaisePropertyChanged(nameof(LazyLoading));
325325
RaisePropertyChanged(nameof(ShowExpander));
326+
RaisePropertyChanged(nameof(ViewChildren));
326327
}
327328
}
328329

330+
/// <summary>
331+
/// Workaround for cross platform treeview bindings.
332+
/// </summary>
333+
public System.Collections.IEnumerable ViewChildren {
334+
get {
335+
if (LazyLoading && Children.Count == 0)
336+
return new[] { new LoadingTreeNode() };
337+
return Children;
338+
}
339+
}
340+
341+
class LoadingTreeNode : SharpTreeNode
342+
{
343+
public override object Text => "Loading...";
344+
}
345+
329346
bool canExpandRecursively = true;
330347

331348
/// <summary>

ICSharpCode.ILSpyX/TreeView/SharpTreeNodeCollection.cs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// DEALINGS IN THE SOFTWARE.
1818

1919
using System;
20+
using System.Collections;
2021
using System.Collections.Generic;
2122
using System.Collections.Specialized;
2223
using System.Diagnostics;
@@ -29,7 +30,7 @@ namespace ICSharpCode.ILSpyX.TreeView
2930
/// <summary>
3031
/// Collection that validates that inserted nodes do not have another parent.
3132
/// </summary>
32-
public sealed class SharpTreeNodeCollection : IList<SharpTreeNode>, INotifyCollectionChanged
33+
public sealed class SharpTreeNodeCollection : IList<SharpTreeNode>, IList, INotifyCollectionChanged
3334
{
3435
readonly SharpTreeNode parent;
3536
List<SharpTreeNode> list = new List<SharpTreeNode>();
@@ -94,6 +95,20 @@ bool ICollection<SharpTreeNode>.IsReadOnly {
9495
get { return false; }
9596
}
9697

98+
#region IList Members
99+
100+
public bool IsFixedSize => ((IList)list).IsFixedSize;
101+
102+
public bool IsReadOnly => ((IList)list).IsReadOnly;
103+
104+
public bool IsSynchronized => ((ICollection)list).IsSynchronized;
105+
106+
public object SyncRoot => ((ICollection)list).SyncRoot;
107+
108+
object IList.this[int index] { get => this[index]; set => this[index] = (SharpTreeNode)value; }
109+
110+
#endregion
111+
97112
public int IndexOf(SharpTreeNode node)
98113
{
99114
if (node == null || node.modelParent != parent)
@@ -236,5 +251,52 @@ public void RemoveAll(Predicate<SharpTreeNode> match)
236251
RemoveRange(firstToRemove, list.Count - firstToRemove);
237252
}
238253
}
254+
255+
public int Add(object value)
256+
{
257+
if (value == null)
258+
throw new ArgumentNullException(nameof(value));
259+
if (!(value is SharpTreeNode node))
260+
throw new ArgumentException("Value must be a SharpTreeNode", nameof(value));
261+
Add(node);
262+
return list.IndexOf(node);
263+
}
264+
265+
public bool Contains(object value)
266+
{
267+
return value is SharpTreeNode node && Contains(node);
268+
}
269+
270+
public int IndexOf(object value)
271+
{
272+
return value is SharpTreeNode node ? IndexOf(node) : -1;
273+
}
274+
275+
public void Insert(int index, object value)
276+
{
277+
if (value == null)
278+
throw new ArgumentNullException(nameof(value));
279+
if (!(value is SharpTreeNode node))
280+
throw new ArgumentException("Value must be a SharpTreeNode", nameof(value));
281+
Insert(index, node);
282+
}
283+
284+
public void Remove(object value)
285+
{
286+
if (value is SharpTreeNode node)
287+
Remove(node);
288+
}
289+
290+
public void CopyTo(Array array, int index)
291+
{
292+
if (array is SharpTreeNode[] nodes)
293+
{
294+
CopyTo(nodes, index);
295+
}
296+
else
297+
{
298+
((ICollection)list).CopyTo(array, index);
299+
}
300+
}
239301
}
240302
}

ILSpy/AboutPage.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,11 @@ static void ShowAvailableVersion(AvailableVersionInfo availableVersion, StackPan
192192
stackPanel.Children.Add(
193193
new Image {
194194
Width = 16, Height = 16,
195+
#if CROSS_PLATFORM
196+
Source = Images.LoadImage(Images.OK),
197+
#else
195198
Source = Images.OK,
199+
#endif
196200
Margin = new Thickness(4, 0, 4, 0)
197201
});
198202
stackPanel.Children.Add(

ILSpy/AssemblyTree/AssemblyTreeModel.cs

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
using System.Reflection.Metadata.Ecma335;
3030
using System.Threading.Tasks;
3131
using System.Windows;
32-
using System.Windows.Documents;
3332
using System.Windows.Input;
3433
using System.Windows.Navigation;
3534
using System.Windows.Threading;
@@ -57,7 +56,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
5756
{
5857
[ExportToolPane]
5958
[Shared]
60-
public class AssemblyTreeModel : ToolPaneModel
59+
public partial class AssemblyTreeModel : ToolPaneModel
6160
{
6261
public const string PaneContentId = "assemblyListPane";
6362

@@ -74,36 +73,6 @@ public class AssemblyTreeModel : ToolPaneModel
7473

7574
private static Dispatcher UIThreadDispatcher => Application.Current.Dispatcher;
7675

77-
public AssemblyTreeModel(SettingsService settingsService, LanguageService languageService, IExportProvider exportProvider)
78-
{
79-
this.settingsService = settingsService;
80-
this.languageService = languageService;
81-
this.exportProvider = exportProvider;
82-
83-
Title = Resources.Assemblies;
84-
ContentId = PaneContentId;
85-
IsCloseable = false;
86-
ShortcutKey = new KeyGesture(Key.F6);
87-
88-
MessageBus<NavigateToReferenceEventArgs>.Subscribers += JumpToReference;
89-
MessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);
90-
MessageBus<ApplySessionSettingsEventArgs>.Subscribers += ApplySessionSettings;
91-
MessageBus<ActiveTabPageChangedEventArgs>.Subscribers += ActiveTabPageChanged;
92-
MessageBus<TabPagesCollectionChangedEventArgs>.Subscribers += (_, e) => history.RemoveAll(s => !DockWorkspace.TabPages.Contains(s.TabPage));
93-
MessageBus<ResetLayoutEventArgs>.Subscribers += ResetLayout;
94-
MessageBus<NavigateToEventArgs>.Subscribers += (_, e) => NavigateTo(e.Request, e.InNewTabPage);
95-
MessageBus<MainWindowLoadedEventArgs>.Subscribers += (_, _) => {
96-
Initialize();
97-
Show();
98-
};
99-
100-
EventManager.RegisterClassHandler(typeof(Window), Hyperlink.RequestNavigateEvent, new RequestNavigateEventHandler((_, e) => NavigateTo(e)));
101-
102-
refreshThrottle = new(DispatcherPriority.Background, RefreshInternal);
103-
104-
AssemblyList = settingsService.CreateEmptyAssemblyList();
105-
}
106-
10776
private void Settings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
10877
{
10978
if (sender is SessionSettings sessionSettings)
@@ -161,6 +130,9 @@ public SharpTreeNode[] SelectedItems {
161130
var oldSelection = selectedItems;
162131
selectedItems = value;
163132
OnPropertyChanged();
133+
#if CROSS_PLATFORM
134+
OnPropertyChanged(nameof(SelectedItem));
135+
#endif
164136
TreeView_SelectionChanged(oldSelection, selectedItems);
165137
}
166138
}
@@ -494,24 +466,6 @@ private void assemblyList_CollectionChanged(object? sender, NotifyCollectionChan
494466
MessageBus.Send(this, new CurrentAssemblyListChangedEventArgs(e));
495467
}
496468

497-
private static void LoadInitialAssemblies(AssemblyList assemblyList)
498-
{
499-
// Called when loading an empty assembly list; so that
500-
// the user can see something initially.
501-
System.Reflection.Assembly[] initialAssemblies = {
502-
typeof(object).Assembly,
503-
typeof(Uri).Assembly,
504-
typeof(System.Linq.Enumerable).Assembly,
505-
typeof(System.Xml.XmlDocument).Assembly,
506-
typeof(System.Windows.Markup.MarkupExtension).Assembly,
507-
typeof(System.Windows.Rect).Assembly,
508-
typeof(System.Windows.UIElement).Assembly,
509-
typeof(System.Windows.FrameworkElement).Assembly
510-
};
511-
foreach (System.Reflection.Assembly asm in initialAssemblies)
512-
assemblyList.OpenAssembly(asm.Location);
513-
}
514-
515469
public AssemblyTreeNode? FindAssemblyNode(LoadedAssembly asm)
516470
{
517471
return assemblyListTreeNode?.FindAssemblyNode(asm);
@@ -542,10 +496,16 @@ public void SelectNode(SharpTreeNode? node, bool inNewTabPage = false)
542496
}
543497
else
544498
{
499+
#if CROSS_PLATFORM
500+
ExpandAncestors(node);
501+
#endif
545502
activeView?.ScrollIntoView(node);
546503
SelectedItem = node;
547504

548505
UIThreadDispatcher.BeginInvoke(DispatcherPriority.Background, () => {
506+
#if CROSS_PLATFORM
507+
SelectedItem = node;
508+
#endif
549509
activeView?.ScrollIntoView(node);
550510
});
551511
}
@@ -1011,6 +971,15 @@ private IEnumerable<SharpTreeNode> GetTopLevelSelection()
1011971
return selection.Where(item => item.Ancestors().All(a => !selectionHash.Contains(a)));
1012972
}
1013973

974+
void ExpandAncestors(SharpTreeNode node)
975+
{
976+
foreach (var ancestor in node.Ancestors().Reverse())
977+
{
978+
ancestor.EnsureLazyChildren();
979+
ancestor.IsExpanded = true;
980+
}
981+
}
982+
1014983
public void SetActiveView(AssemblyListPane activeView)
1015984
{
1016985
this.activeView = activeView;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4+
// software and associated documentation files (the "Software"), to deal in the Software
5+
// without restriction, including without limitation the rights to use, copy, modify, merge,
6+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7+
// to whom the Software is furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in all copies or
10+
// substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17+
// DEALINGS IN THE SOFTWARE.
18+
19+
using System;
20+
using System.Windows;
21+
using System.Windows.Documents;
22+
using System.Windows.Input;
23+
using System.Windows.Navigation;
24+
using System.Windows.Threading;
25+
26+
using ICSharpCode.ILSpy.Properties;
27+
using ICSharpCode.ILSpyX;
28+
29+
using TomsToolbox.Composition;
30+
31+
namespace ICSharpCode.ILSpy.AssemblyTree
32+
{
33+
public partial class AssemblyTreeModel
34+
{
35+
public AssemblyTreeModel(SettingsService settingsService, LanguageService languageService, IExportProvider exportProvider)
36+
{
37+
this.settingsService = settingsService;
38+
this.languageService = languageService;
39+
this.exportProvider = exportProvider;
40+
41+
Title = Resources.Assemblies;
42+
ContentId = PaneContentId;
43+
IsCloseable = false;
44+
ShortcutKey = new KeyGesture(Key.F6);
45+
46+
MessageBus<NavigateToReferenceEventArgs>.Subscribers += JumpToReference;
47+
MessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);
48+
MessageBus<ApplySessionSettingsEventArgs>.Subscribers += ApplySessionSettings;
49+
MessageBus<ActiveTabPageChangedEventArgs>.Subscribers += ActiveTabPageChanged;
50+
MessageBus<TabPagesCollectionChangedEventArgs>.Subscribers += (_, e) => history.RemoveAll(s => !DockWorkspace.TabPages.Contains(s.TabPage));
51+
MessageBus<ResetLayoutEventArgs>.Subscribers += ResetLayout;
52+
MessageBus<NavigateToEventArgs>.Subscribers += (_, e) => NavigateTo(e.Request, e.InNewTabPage);
53+
MessageBus<MainWindowLoadedEventArgs>.Subscribers += (_, _) => {
54+
Initialize();
55+
Show();
56+
};
57+
58+
EventManager.RegisterClassHandler(typeof(Window), Hyperlink.RequestNavigateEvent, new RequestNavigateEventHandler((_, e) => NavigateTo(e)));
59+
60+
refreshThrottle = new(DispatcherPriority.Background, RefreshInternal);
61+
62+
AssemblyList = settingsService.CreateEmptyAssemblyList();
63+
}
64+
65+
private static void LoadInitialAssemblies(AssemblyList assemblyList)
66+
{
67+
// Called when loading an empty assembly list; so that
68+
// the user can see something initially.
69+
System.Reflection.Assembly[] initialAssemblies = {
70+
typeof(object).Assembly,
71+
typeof(Uri).Assembly,
72+
typeof(System.Linq.Enumerable).Assembly,
73+
typeof(System.Xml.XmlDocument).Assembly,
74+
typeof(System.Windows.Markup.MarkupExtension).Assembly,
75+
typeof(System.Windows.Rect).Assembly,
76+
typeof(System.Windows.UIElement).Assembly,
77+
typeof(System.Windows.FrameworkElement).Assembly
78+
};
79+
foreach (System.Reflection.Assembly asm in initialAssemblies)
80+
assemblyList.OpenAssembly(asm.Location);
81+
}
82+
}
83+
}

ILSpy/Commands/Pdb2XmlCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1717
// DEALINGS IN THE SOFTWARE.
1818

19-
#if DEBUG
19+
#if DEBUG && WINDOWS
2020

2121
using System.Collections.Generic;
2222
using System.Composition;

0 commit comments

Comments
 (0)