Browse Source

Grid visualizer can be opened from Debugger tooltips.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4753 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Martin Koníček 16 years ago
parent
commit
e8090246eb
  1. 6
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
  2. 9
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Commands/GridVisualizerCommand.cs
  3. 6
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Commands/ObjectGraphVisualizerCommand.cs
  4. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Commands/ObjectGraphVisualizerMenuCommand.cs
  5. 16
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraphControl.xaml.cs
  6. 9
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraphWindow.xaml
  7. 104
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraphWindow.xaml.cs
  8. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/GridVisualizerWindow.xaml
  9. 105
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs
  10. 26
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ObjectValue.cs

6
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj

@ -253,8 +253,8 @@ @@ -253,8 +253,8 @@
<Compile Include="Src\Visualizers\Utils\DictionaryExtensions.cs" />
<Compile Include="Src\Visualizers\Utils\Lookup.cs" />
<Compile Include="Src\Visualizers\Utils\LookupValueCollection.cs" />
<Compile Include="Src\Visualizers\Graph\VisualizerWPFWindow.xaml.cs">
<DependentUpon>VisualizerWPFWindow.xaml</DependentUpon>
<Compile Include="Src\Visualizers\Graph\ObjectGraphWindow.xaml.cs">
<DependentUpon>ObjectGraphWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Src\Visualizers\ICorDebug.cs" />
<Compile Include="Src\Visualizers\IList.cs" />
@ -381,7 +381,7 @@ @@ -381,7 +381,7 @@
<Folder Include="Src\Visualizers\Utils" />
<Folder Include="Src\Visualizers\GridVisualizer" />
<Folder Include="Src\Visualizers\PresentationBindings" />
<Page Include="Src\Visualizers\Graph\VisualizerWPFWindow.xaml" />
<Page Include="Src\Visualizers\Graph\ObjectGraphWindow.xaml" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">

9
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Commands/GridVisualizerCommand.cs

@ -4,10 +4,11 @@ @@ -4,10 +4,11 @@
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
// <version>$Revision$</version>
// </file>
using Debugger.AddIn.TreeModel;
using System;
using System.Collections.Generic;
using System.Linq;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.GridVisualizer;
namespace Debugger.AddIn.Visualizers
{
@ -32,7 +33,11 @@ namespace Debugger.AddIn.Visualizers @@ -32,7 +33,11 @@ namespace Debugger.AddIn.Visualizers
public override void Execute()
{
if (this.Node != null && this.Node.Expression != null)
{
var gridVisualizerWindow = GridVisualizerWindow.EnsureShown();
gridVisualizerWindow.ShownExpression = this.Node.Expression;
}
}
}
}

6
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Commands/ObjectGraphVisualizerCommand.cs

@ -35,10 +35,8 @@ namespace Debugger.AddIn.Visualizers @@ -35,10 +35,8 @@ namespace Debugger.AddIn.Visualizers
{
if (this.Node != null && this.Node.Expression != null)
{
var objectGraphWindow = VisualizerWPFWindow.EnsureShown();
// is this ok with different languages than C#?
// - Prettyprint an expression and then call WindowsDebugger.GetValueFromName, which is C# only
objectGraphWindow.ShownExpression = this.Node.Expression.PrettyPrint();
var objectGraphWindow = ObjectGraphWindow.EnsureShown();
objectGraphWindow.ShownExpression = this.Node.Expression;
}
}
}

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Commands/ObjectGraphVisualizerMenuCommand.cs

@ -20,7 +20,7 @@ namespace Debugger.AddIn.Visualizers @@ -20,7 +20,7 @@ namespace Debugger.AddIn.Visualizers
{
public override void Run()
{
VisualizerWPFWindow.EnsureShown();
ObjectGraphWindow.EnsureShown();
}
}
}

16
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraphControl.xaml.cs

@ -66,14 +66,22 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -66,14 +66,22 @@ namespace Debugger.AddIn.Visualizers.Graph
refreshGraph();
}
public string ShownExpression
private ICSharpCode.NRefactory.Ast.Expression shownExpression;
public ICSharpCode.NRefactory.Ast.Expression ShownExpression
{
get {
return this.txtExpression.Text;
return shownExpression;
}
set {
if (value != this.txtExpression.Text) {
this.txtExpression.Text = value;
if (value == null) {
shownExpression = null;
txtExpression.Text = null;
Refresh();
return;
}
if (shownExpression == null || value.PrettyPrint() != shownExpression.PrettyPrint()) {
txtExpression.Text = value.PrettyPrint();
Refresh();
}
}
}

9
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraphWindow.xaml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
<Window x:Class="Debugger.AddIn.Visualizers.Graph.ObjectGraphWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dv="clr-namespace:Debugger.AddIn.Visualizers.Graph"
xmlns:controls="clr-namespace:Debugger.AddIn.Visualizers.Controls"
Title="Object graph visualizer" Height="400" Width="600">
<dv:ObjectGraphControl x:Name="objectGraphControl"></dv:ObjectGraphControl>
</Window>

104
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraphWindow.xaml.cs

@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Martin Koníček" email="martin.konicek@gmail.com"/>
// <version>$Revision: 4708 $</version>
// </file>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Debugger.AddIn.Visualizers.Graph.Layout;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Visualizers.Graph
{
/// <summary>
/// Interaction logic for VisualizerWPFWindow.xaml
/// </summary>
public partial class ObjectGraphWindow : Window
{
private WindowsDebugger debuggerService;
public ObjectGraphWindow()
{
InitializeComponent();
debuggerService = DebuggerService.CurrentDebugger as WindowsDebugger;
if (debuggerService == null)
throw new ApplicationException("Only windows debugger is currently supported");
registerEvents();
instance = this;
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
unregisterEvents();
this.objectGraphControl.ClearUIControlCache();
instance = null;
}
public ICSharpCode.NRefactory.Ast.Expression ShownExpression
{
get {
return this.objectGraphControl.ShownExpression;
}
set {
this.objectGraphControl.ShownExpression = value;
}
}
static ObjectGraphWindow instance;
/// <summary> When Window is visible, returns reference to the Window. Otherwise returns null. </summary>
public static ObjectGraphWindow Instance
{
get { return instance; }
}
public static ObjectGraphWindow EnsureShown()
{
var window = ObjectGraphWindow.Instance ?? new ObjectGraphWindow();
window.Topmost = true;
window.Show();
return window;
}
private void registerEvents()
{
debuggerService.IsProcessRunningChanged += new EventHandler(debuggerService_IsProcessRunningChanged);
debuggerService.DebugStopped += new EventHandler(debuggerService_DebugStopped);
}
private void unregisterEvents()
{
debuggerService.IsProcessRunningChanged -= new EventHandler(debuggerService_IsProcessRunningChanged);
debuggerService.DebugStopped -= new EventHandler(debuggerService_DebugStopped);
}
public void debuggerService_IsProcessRunningChanged(object sender, EventArgs e)
{
// on step or breakpoint hit
if (!debuggerService.IsProcessRunning)
{
this.objectGraphControl.Refresh();
}
}
public void debuggerService_DebugStopped(object sender, EventArgs e)
{
this.Close();
}
}
}

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/GridVisualizerWindow.xaml

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dv="clr-namespace:Debugger.AddIn.Visualizers.Graph"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Title="Grid visualizer" Height="350" Width="600">
Title="Collection visualizer" Height="350" Width="600">
<Window.Resources>
<Style x:Key="ComboBoxFocusVisual">
<Setter Property="Control.Template">

105
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs

@ -40,58 +40,108 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -40,58 +40,108 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
this.debuggerService = DebuggerService.CurrentDebugger as WindowsDebugger;
if (debuggerService == null)
throw new ApplicationException("Only windows debugger is currently supported");
instance = this;
this.Deactivated += GridVisualizerWindow_Deactivated;
}
void GridVisualizerWindow_Deactivated(object sender, EventArgs e)
{
this.Close();
}
private ICSharpCode.NRefactory.Ast.Expression shownExpression;
public ICSharpCode.NRefactory.Ast.Expression ShownExpression
{
get {
return shownExpression;
}
set {
if (value == null) {
shownExpression = null;
txtExpression.Text = null;
Refresh();
return;
}
if (shownExpression == null || value.PrettyPrint() != shownExpression.PrettyPrint()) {
txtExpression.Text = value.PrettyPrint();
Refresh();
}
}
}
static GridVisualizerWindow instance;
/// <summary> When Window is visible, returns reference to the Window. Otherwise returns null. </summary>
public static GridVisualizerWindow Instance
{
get { return instance; }
}
public static GridVisualizerWindow EnsureShown()
{
var window = GridVisualizerWindow.Instance ?? new GridVisualizerWindow();
window.Topmost = true;
window.Show();
return window;
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
this.Deactivated -= GridVisualizerWindow_Deactivated;
base.OnClosing(e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
instance = null;
}
private void btnInspect_Click(object sender, RoutedEventArgs e)
{
Refresh();
}
public void Refresh()
{
// clear ListView
listView.ItemsSource = null;
ScrollViewer listViewScroller = listView.GetScrollViewer();
if (listViewScroller != null)
if (listViewScroller != null) {
listViewScroller.ScrollToVerticalOffset(0);
}
Value val = null;
try
{
try {
val = debuggerService.GetValueFromName(txtExpression.Text);
}
catch(GetValueException)
{
} catch(GetValueException) {
// display ex.Message
}
if (val != null && !val.IsNull)
{
if (val != null && !val.IsNull) {
GridValuesProvider gridValuesProvider;
// Value is IList?
DebugType iListType, listItemType;
if (val.Type.ResolveIListImplementation(out iListType, out listItemType))
{
if (val.Type.ResolveIListImplementation(out iListType, out listItemType)) {
var listValuesProvider = new ListValuesProvider(val.ExpressionTree, iListType, listItemType);
var virtCollection = new VirtualizingCollection<ObjectValue>(listValuesProvider);
this.listView.ItemsSource = virtCollection;
gridValuesProvider = listValuesProvider;
}
else
{
} else {
// Value is IEnumerable?
DebugType iEnumerableType, itemType;
if (val.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType))
{
if (val.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) {
var lazyListViewWrapper = new LazyItemsControl<ObjectValue>(this.listView, 24);
var enumerableValuesProvider = new EnumerableValuesProvider(val.ExpressionTree, iEnumerableType, itemType);
lazyListViewWrapper.ItemsSource = new VirtualizingIEnumerable<ObjectValue>(enumerableValuesProvider.ItemsSource);
gridValuesProvider = enumerableValuesProvider;
}
else
{
} else {
// Value cannot be displayed in GridVisualizer
return;
}
}
IList<MemberInfo> itemTypeMembers = gridValuesProvider.GetItemTypeMembers();
// create ListView columns
createGridViewColumns((GridView)this.listView.View, itemTypeMembers);
this.columnHider = new GridViewColumnHider((GridView)this.listView.View);
// fill column-choosing ComboBox
@ -103,11 +153,10 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -103,11 +153,10 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
private void createGridViewColumns(GridView gridView, IList<MemberInfo> itemTypeMembers)
{
gridView.Columns.Clear();
foreach (var member in itemTypeMembers)
{
foreach (var member in itemTypeMembers) {
GridViewColumn column = new GridViewColumn();
column.Header = member.Name;
// "{Binding Path=[Name]}"
// "{Binding Path=[Name].Value}"
column.DisplayMemberBinding = new Binding("[" + member.Name + "].Value");
gridView.Columns.Add(column);
}
@ -116,8 +165,7 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -116,8 +165,7 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
private SelectedProperties initializeSelectedPropertiesWithEvents(IList<MemberInfo> itemTypeMembers)
{
var selectedProperties = new SelectedProperties(itemTypeMembers.Select(member => member.Name));
foreach (var selectedProperty in selectedProperties)
{
foreach (var selectedProperty in selectedProperties) {
selectedProperty.SelectedChanged += new EventHandler(selectedProperty_SelectedChanged);
}
return selectedProperties;
@ -127,12 +175,9 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -127,12 +175,9 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
{
var propertySeleted = ((SelectedProperty)sender);
var columnName = propertySeleted.Name;
if (propertySeleted.IsSelected)
{
if (propertySeleted.IsSelected) {
this.columnHider.ShowColumn(columnName);
}
else
{
} else {
this.columnHider.HideColumn(columnName);
}
}

26
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ObjectValue.cs

@ -14,44 +14,44 @@ using ICSharpCode.NRefactory.Ast; @@ -14,44 +14,44 @@ using ICSharpCode.NRefactory.Ast;
namespace Debugger.AddIn.Visualizers.GridVisualizer
{
/// <summary>
/// Object in the debugee, with its properties loaded.
/// Object in the debugee, with lazy evaluated properties.
/// </summary>
public class ObjectValue
{
// Used to be able to expand items of IEnumerable
// Now we rely on PermanentReference to be able to get member values on demand. With IList, PermanentReference can be replaced by Expression
// Now we rely on PermanentReference to be able to get member values on demand. With IList, PermanentReference could be replaced by Expression
public Value PermanentReference { get; private set; }
private Dictionary<string, ObjectProperty> properties = new Dictionary<string, ObjectProperty>();
/// <summary> Used to quickly find MemberInfo by member name - DebugType.GetMember(name) uses a loop to search members </summary>
private Dictionary<string, MemberInfo> memberFromNameMap;
private Dictionary<string, MemberInfo> memberForNameMap;
internal ObjectValue(Dictionary<string, MemberInfo> memberFromNameMap)
{
this.memberFromNameMap = memberFromNameMap;
this.memberForNameMap = memberFromNameMap;
}
/// <summary>
/// Returns property with given name.
/// </summary>
public ObjectProperty this[string key]
public ObjectProperty this[string propertyName]
{
get
{
ObjectProperty property;
// has property with name 'propertyName' already been evaluated?
if(!this.properties.TryGetValue(key, out property))
if(!this.properties.TryGetValue(propertyName, out property))
{
if (this.PermanentReference == null) {
throw new DebuggerVisualizerException("Cannot get member of this ObjectValue - ObjectValue.PermanentReference is null");
}
MemberInfo memberInfo = this.memberFromNameMap.GetValue(key);
MemberInfo memberInfo = this.memberForNameMap.GetValue(propertyName);
if (memberInfo == null) {
throw new DebuggerVisualizerException("Cannot get member value - no member found with name " + key);
throw new DebuggerVisualizerException("Cannot get member value - no member found with name " + propertyName);
}
property = createPropertyFromValue(key, this.PermanentReference.GetMemberValue(memberInfo));
this.properties.Add(key, property);
property = createPropertyFromValue(propertyName, this.PermanentReference.GetMemberValue(memberInfo));
this.properties.Add(propertyName, property);
}
return property;
}
@ -66,12 +66,6 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -66,12 +66,6 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
Value permanentReference = value.GetPermanentReference();
result.PermanentReference = permanentReference;
// cannot use GetMemberValues because memberValue does not have CodeTail anymore - but we need the name of the member
/*foreach(MemberInfo memberInfo in permanentReference.Type.GetMembers(bindingFlags))
{
Value memberValue = permanentReference.GetMemberValue(memberInfo);
result.properties.Add(createPropertyFromValue(memberInfo.Name, memberValue));
}*/
return result;
}

Loading…
Cancel
Save