Browse Source

Fix navigation and history in AboutPage

pull/1891/head
Siegfried Pammer 6 years ago
parent
commit
89e8ea072d
  1. 9
      ILSpy/AboutPage.cs
  2. 18
      ILSpy/App.xaml.cs
  3. 51
      ILSpy/MainWindow.xaml.cs
  4. 4
      ILSpy/Metadata/Helpers.cs
  5. 16
      ILSpy/NavigationState.cs
  6. 6
      ILSpy/TextView/AvalonEditTextOutput.cs
  7. 29
      ILSpy/TextView/DecompilerTextView.cs

9
ILSpy/AboutPage.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Net;
@ -28,14 +27,14 @@ using System.Windows; @@ -28,14 +27,14 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using OSVersionHelper;
namespace ICSharpCode.ILSpy
@ -45,8 +44,7 @@ namespace ICSharpCode.ILSpy @@ -45,8 +44,7 @@ namespace ICSharpCode.ILSpy
{
public override void Execute(object parameter)
{
MainWindow.Instance.UnselectAll();
DockWorkspace.Instance.ActiveTabPage.ShowTextView(Display);
MainWindow.Instance.NavigateTo(new RequestNavigateEventArgs(new Uri("resource://aboutpage"), null));
}
static readonly Uri UpdateUrl = new Uri("https://ilspy.net/updates.xml");
@ -89,6 +87,7 @@ namespace ICSharpCode.ILSpy @@ -89,6 +87,7 @@ namespace ICSharpCode.ILSpy
foreach (var plugin in App.ExportProvider.GetExportedValues<IAboutPageAddition>())
plugin.Write(output);
output.WriteLine();
output.Address = new Uri("resource://AboutPage");
using (Stream s = typeof(AboutPage).Assembly.GetManifestResourceStream(typeof(AboutPage), "ILSpyAboutPage.txt")) {
using (StreamReader r = new StreamReader(s)) {
string line;

18
ILSpy/App.xaml.cs

@ -22,17 +22,16 @@ using System.Diagnostics; @@ -22,17 +22,16 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Navigation;
using System.Windows.Threading;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Options;
using Microsoft.VisualStudio.Composition;
using System.Text;
namespace ICSharpCode.ILSpy
{
@ -233,20 +232,7 @@ namespace ICSharpCode.ILSpy @@ -233,20 +232,7 @@ namespace ICSharpCode.ILSpy
void Window_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
if (e.Uri.Scheme == "resource") {
AvalonEditTextOutput output = new AvalonEditTextOutput();
using (Stream s = typeof(App).Assembly.GetManifestResourceStream(typeof(App), e.Uri.AbsolutePath)) {
using (StreamReader r = new StreamReader(s)) {
string line;
while ((line = r.ReadLine()) != null) {
output.Write(line);
output.WriteLine();
}
}
}
Docking.DockWorkspace.Instance.ShowText(output);
e.Handled = true;
}
ILSpy.MainWindow.Instance.NavigateTo(e);
}
}
}

51
ILSpy/MainWindow.xaml.cs

@ -25,7 +25,6 @@ using System.IO; @@ -25,7 +25,6 @@ using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
@ -34,6 +33,7 @@ using System.Windows.Input; @@ -34,6 +33,7 @@ using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Documentation;
@ -41,7 +41,6 @@ using ICSharpCode.Decompiler.Metadata; @@ -41,7 +41,6 @@ using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.Controls;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
@ -49,7 +48,6 @@ using ICSharpCode.ILSpy.ViewModels; @@ -49,7 +48,6 @@ using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.TreeView;
using Microsoft.Win32;
using OSVersionHelper;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;
namespace ICSharpCode.ILSpy
@ -996,6 +994,10 @@ namespace ICSharpCode.ILSpy @@ -996,6 +994,10 @@ namespace ICSharpCode.ILSpy
if (node != null && node.View(DockWorkspace.Instance.ActiveTabPage))
return;
}
if (newState?.ViewedUri != null) {
NavigateTo(new RequestNavigateEventArgs(newState.ViewedUri, null), recordHistory: false);
return;
}
decompilationTask = DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, new DecompilationOptions() { TextViewState = newState }));
}
@ -1078,9 +1080,50 @@ namespace ICSharpCode.ILSpy @@ -1078,9 +1080,50 @@ namespace ICSharpCode.ILSpy
ignoreDecompilationRequests = false;
DecompileSelectedNodes(newState.ViewState as DecompilerTextViewState, false);
}
#endregion
internal void NavigateTo(RequestNavigateEventArgs e, bool recordHistory = true)
{
if (e.Uri.Scheme == "resource") {
if (e.Uri.Host == "aboutpage") {
RecordHistory();
DockWorkspace.Instance.ActiveTabPage.ShowTextView(AboutPage.Display);
e.Handled = true;
return;
}
AvalonEditTextOutput output = new AvalonEditTextOutput {
Address = e.Uri,
Title = e.Uri.AbsolutePath,
EnableHyperlinks = true
};
using (Stream s = typeof(App).Assembly.GetManifestResourceStream(typeof(App), e.Uri.AbsolutePath)) {
using (StreamReader r = new StreamReader(s)) {
string line;
while ((line = r.ReadLine()) != null) {
output.Write(line);
output.WriteLine();
}
}
}
RecordHistory();
DockWorkspace.Instance.ShowText(output);
e.Handled = true;
}
void RecordHistory()
{
if (!recordHistory)
return;
var currentState = DockWorkspace.Instance.ActiveTabPage.GetState();
if (currentState != null)
history.UpdateCurrent(new NavigationState(currentState));
ignoreDecompilationRequests = true;
UnselectAll();
ignoreDecompilationRequests = false;
history.Record(new NavigationState(new ViewState { ViewedUri = e.Uri }));
}
}
protected override void OnStateChanged(EventArgs e)
{
base.OnStateChanged(e);

4
ILSpy/Metadata/Helpers.cs

@ -91,7 +91,9 @@ namespace ICSharpCode.ILSpy.Metadata @@ -91,7 +91,9 @@ namespace ICSharpCode.ILSpy.Metadata
public ViewState GetState()
{
return new ViewState { DecompiledNodes = SelectedTreeNode == null ? null : new[] { SelectedTreeNode } };
return new ViewState {
DecompiledNodes = SelectedTreeNode == null ? null : new HashSet<ILSpyTreeNode>(new[] { SelectedTreeNode })
};
}
}

16
ILSpy/NavigationState.cs

@ -18,11 +18,13 @@ @@ -18,11 +18,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy
{
[DebuggerDisplay("Nodes = {treeNodes.Count}, State = [{ViewState}]")]
public class NavigationState : IEquatable<NavigationState>
{
private readonly HashSet<SharpTreeNode> treeNodes;
@ -32,7 +34,7 @@ namespace ICSharpCode.ILSpy @@ -32,7 +34,7 @@ namespace ICSharpCode.ILSpy
public NavigationState(ViewState viewState)
{
this.treeNodes = new HashSet<SharpTreeNode>(viewState.DecompiledNodes);
this.treeNodes = new HashSet<SharpTreeNode>((IEnumerable<SharpTreeNode>)viewState.DecompiledNodes ?? Array.Empty<SharpTreeNode>());
ViewState = viewState;
}
@ -44,8 +46,16 @@ namespace ICSharpCode.ILSpy @@ -44,8 +46,16 @@ namespace ICSharpCode.ILSpy
public bool Equals(NavigationState other)
{
// TODO: should this care about the view state as well?
return this.treeNodes.SetEquals(other.treeNodes);
if (!this.treeNodes.SetEquals(other.treeNodes))
return false;
if (object.ReferenceEquals(this.ViewState, other.ViewState))
return true;
if (this.ViewState == null)
return false;
return this.ViewState.Equals(other.ViewState);
}
}
}

6
ILSpy/TextView/AvalonEditTextOutput.cs

@ -83,6 +83,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -83,6 +83,12 @@ namespace ICSharpCode.ILSpy.TextView
public string IndentationString { get; set; } = "\t";
public string Title { get; set; }
/// <summary>
/// Gets/sets the <see cref="Uri"/> that is displayed by this view.
/// Used to identify the AboutPage and other views built into ILSpy in the navigation history.
/// </summary>
public Uri Address { get; set; }
internal readonly List<VisualLineElementGenerator> elementGenerators = new List<VisualLineElementGenerator>();

29
ILSpy/TextView/DecompilerTextView.cs

@ -71,6 +71,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -71,6 +71,7 @@ namespace ICSharpCode.ILSpy.TextView
BracketHighlightRenderer bracketHighlightRenderer;
FoldingManager foldingManager;
ILSpyTreeNode[] decompiledNodes;
Uri currentAddress;
DefinitionLookup definitionLookup;
TextSegmentCollection<ReferenceSegment> references;
@ -647,6 +648,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -647,6 +648,7 @@ namespace ICSharpCode.ILSpy.TextView
if (this.DataContext is PaneModel model) {
model.Title = textOutput.Title;
}
currentAddress = textOutput.Address;
}
#endregion
@ -1010,7 +1012,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -1010,7 +1012,7 @@ namespace ICSharpCode.ILSpy.TextView
public DecompilerTextViewState GetState()
{
if (decompiledNodes == null)
if (decompiledNodes == null && currentAddress == null)
return null;
var state = new DecompilerTextViewState();
@ -1018,7 +1020,8 @@ namespace ICSharpCode.ILSpy.TextView @@ -1018,7 +1020,8 @@ namespace ICSharpCode.ILSpy.TextView
state.SaveFoldingsState(foldingManager.AllFoldings);
state.VerticalOffset = textEditor.VerticalOffset;
state.HorizontalOffset = textEditor.HorizontalOffset;
state.DecompiledNodes = decompiledNodes;
state.DecompiledNodes = decompiledNodes == null ? null : new HashSet<ILSpyTreeNode>(decompiledNodes);
state.ViewedUri = currentAddress;
return state;
}
@ -1059,9 +1062,16 @@ namespace ICSharpCode.ILSpy.TextView @@ -1059,9 +1062,16 @@ namespace ICSharpCode.ILSpy.TextView
#endregion
}
public class ViewState
[DebuggerDisplay("Nodes = {DecompiledNodes}, ViewedUri = {ViewedUri}")]
public class ViewState : IEquatable<ViewState>
{
public ILSpyTreeNode[] DecompiledNodes;
public HashSet<ILSpyTreeNode> DecompiledNodes;
public Uri ViewedUri;
public virtual bool Equals(ViewState other)
{
return ViewedUri == other.ViewedUri && (DecompiledNodes == other.DecompiledNodes || DecompiledNodes?.SetEquals(other.DecompiledNodes) == true);
}
}
public class DecompilerTextViewState : ViewState
@ -1084,5 +1094,16 @@ namespace ICSharpCode.ILSpy.TextView @@ -1084,5 +1094,16 @@ namespace ICSharpCode.ILSpy.TextView
foreach (var folding in list)
folding.DefaultClosed = !ExpandedFoldings.Any(f => f.Item1 == folding.StartOffset && f.Item2 == folding.EndOffset);
}
public override bool Equals(ViewState other)
{
if (other is DecompilerTextViewState vs) {
return base.Equals(vs)
&& FoldingsChecksum == vs.FoldingsChecksum
&& VerticalOffset == vs.VerticalOffset
&& HorizontalOffset == vs.HorizontalOffset;
}
return false;
}
}
}

Loading…
Cancel
Save