Browse Source

Refactored Local Variables Pad and Watch Pad

newNRvisualizers
David Srbecký 13 years ago
parent
commit
f6cdd42cf5
  1. 2
      SharpDevelop.Tests.sln
  2. 24
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  3. 62
      src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs
  4. 120
      src/AddIns/Debugger/Debugger.AddIn/Pads/Common/AutoCompleteTextBox.cs
  5. 37
      src/AddIns/Debugger/Debugger.AddIn/Pads/Common/CommonResources.xaml
  6. 0
      src/AddIns/Debugger/Debugger.AddIn/Pads/Common/ConditionCell.xaml
  7. 0
      src/AddIns/Debugger/Debugger.AddIn/Pads/Common/ConditionCell.xaml.cs
  8. 28
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/Converters.cs
  9. 82
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml
  10. 91
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs
  11. 169
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.cs
  12. 11
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.xaml
  13. 37
      src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
  14. 35
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml
  15. 123
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml.cs
  16. 213
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
  17. 23
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs
  18. 6
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/TreeNode.cs
  19. 4
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs

2
SharpDevelop.Tests.sln

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
# SharpDevelop 4.2.0.8564-beta # SharpDevelop 4.2.0.8717-Beta 2
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject ProjectSection(SolutionItems) = postProject
EndProjectSection EndProjectSection

24
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -111,17 +111,10 @@
<Compile Include="Pads\Commands\ParallelStacksViewCommands.cs" /> <Compile Include="Pads\Commands\ParallelStacksViewCommands.cs" />
<Compile Include="Pads\Commands\SelectLanguageCommand.cs" /> <Compile Include="Pads\Commands\SelectLanguageCommand.cs" />
<Compile Include="Pads\Commands\WatchPadCommands.cs" /> <Compile Include="Pads\Commands\WatchPadCommands.cs" />
<Compile Include="Pads\Controls\TreeNodeWrapper.cs" /> <Compile Include="Pads\Common\AutoCompleteTextBox.cs" />
<Compile Include="Pads\Controls\ConditionCell.xaml.cs"> <Compile Include="Pads\Common\ConditionCell.xaml.cs">
<DependentUpon>ConditionCell.xaml</DependentUpon> <DependentUpon>ConditionCell.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Pads\Controls\Converters.cs" />
<Compile Include="Pads\Controls\WatchList.xaml.cs">
<DependentUpon>WatchList.xaml</DependentUpon>
</Compile>
<Compile Include="Pads\Controls\WatchListAutoCompleteCell.cs">
<DependentUpon>WatchListAutoCompleteCell.xaml</DependentUpon>
</Compile>
<Compile Include="Pads\MemoryPad.cs" /> <Compile Include="Pads\MemoryPad.cs" />
<Compile Include="Pads\ParallelPad\DrawSurface.xaml.cs"> <Compile Include="Pads\ParallelPad\DrawSurface.xaml.cs">
<DependentUpon>DrawSurface.xaml</DependentUpon> <DependentUpon>DrawSurface.xaml</DependentUpon>
@ -135,10 +128,6 @@
<DependentUpon>ThreadStack.xaml</DependentUpon> <DependentUpon>ThreadStack.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Pads\WatchInputBox.xaml.cs">
<DependentUpon>WatchInputBox.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="BreakpointChangeMenuBuilder.cs" /> <Compile Include="BreakpointChangeMenuBuilder.cs" />
<Compile Include="DisableBreakpointMenuCommand.cs" /> <Compile Include="DisableBreakpointMenuCommand.cs" />
@ -182,6 +171,7 @@
<Compile Include="Tooltips\VisualizerPicker.cs"> <Compile Include="Tooltips\VisualizerPicker.cs">
<DependentUpon>VisualizerPicker.xaml</DependentUpon> <DependentUpon>VisualizerPicker.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="TreeModel\SharpTreeNodeAdapter.cs" />
<Compile Include="TreeModel\TreeNode.cs" /> <Compile Include="TreeModel\TreeNode.cs" />
<Compile Include="Visualizers\Commands\ExpressionVisualizerCommand.cs" /> <Compile Include="Visualizers\Commands\ExpressionVisualizerCommand.cs" />
<Compile Include="Visualizers\Commands\GridVisualizerCommand.cs" /> <Compile Include="Visualizers\Commands\GridVisualizerCommand.cs" />
@ -352,12 +342,10 @@
<ItemGroup> <ItemGroup>
<Page Include="Options\DebuggingOptionsPanel.xaml" /> <Page Include="Options\DebuggingOptionsPanel.xaml" />
<Page Include="Pads\CallStackPad.xaml" /> <Page Include="Pads\CallStackPad.xaml" />
<Page Include="Pads\Controls\ConditionCell.xaml" /> <Page Include="Pads\Common\CommonResources.xaml" />
<Page Include="Pads\Controls\WatchList.xaml" /> <Page Include="Pads\Common\ConditionCell.xaml" />
<Page Include="Pads\Controls\WatchListAutoCompleteCell.xaml" />
<Page Include="Pads\ParallelPad\DrawSurface.xaml" /> <Page Include="Pads\ParallelPad\DrawSurface.xaml" />
<Page Include="Pads\ParallelPad\ThreadStack.xaml" /> <Page Include="Pads\ParallelPad\ThreadStack.xaml" />
<Page Include="Pads\WatchInputBox.xaml" />
<Page Include="Service\EditBreakpointScriptWindow.xaml" /> <Page Include="Service\EditBreakpointScriptWindow.xaml" />
<Page Include="Tooltips\DebuggerTooltipControl.xaml" /> <Page Include="Tooltips\DebuggerTooltipControl.xaml" />
<Page Include="Tooltips\VisualizerPicker.xaml" /> <Page Include="Tooltips\VisualizerPicker.xaml" />
@ -379,7 +367,7 @@
</ProjectReference> </ProjectReference>
<Folder Include="NRefactory" /> <Folder Include="NRefactory" />
<Folder Include="Pads\Commands" /> <Folder Include="Pads\Commands" />
<Folder Include="Pads\Controls" /> <Folder Include="Pads\Common" />
<Folder Include="Pads\ParallelPad" /> <Folder Include="Pads\ParallelPad" />
<Folder Include="Tooltips" /> <Folder Include="Tooltips" />
<Folder Include="Visualizers\Graph" /> <Folder Include="Visualizers\Graph" />

62
src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs

@ -20,30 +20,9 @@ namespace Debugger.AddIn
{ {
if (this.Owner is WatchPad) { if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner; WatchPad pad = (WatchPad)this.Owner;
var node = new TreeNode(string.Empty, null).ToSharpTreeNode();
var inputWindow = new WatchInputBox(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.AddWatch}"), pad.Items.Add(node);
StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.EnterExpression}")); pad.Tree.FocusNode(node);
inputWindow.Owner = ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainWindow;
var result = inputWindow.ShowDialog();
if (!result.HasValue || !result.Value)
return;
string input = inputWindow.CommandText;
if (!string.IsNullOrEmpty(input)) {
// get language
if (ProjectService.CurrentProject == null) return;
string language = ProjectService.CurrentProject.Language;
var text = new TreeNode(input, null).ToSharpTreeNode();
var list = pad.WatchList;
if(!list.WatchItems.Any(n => text.Node.Name == ((TreeNodeWrapper)n).Node.Name))
list.WatchItems.Add(text);
}
WindowsDebugger.RefreshPads();
} }
} }
} }
@ -54,50 +33,19 @@ namespace Debugger.AddIn
{ {
if (this.Owner is WatchPad) { if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner; WatchPad pad = (WatchPad)this.Owner;
var list = pad.WatchList; pad.Items.Remove(pad.Tree.SelectedItem as SharpTreeNodeAdapter);
var node = list.SelectedNode;
if (node == null)
return;
list.WatchItems.Remove(node);
WindowsDebugger.RefreshPads(); WindowsDebugger.RefreshPads();
} }
} }
} }
public class RefreshWatchesCommand : AbstractMenuCommand
{
public override void Run()
{
WindowsDebugger.RefreshPads();
}
}
public class ClearWatchesCommand : AbstractMenuCommand public class ClearWatchesCommand : AbstractMenuCommand
{ {
public override void Run() public override void Run()
{ {
if (this.Owner is WatchPad) { if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner; WatchPad pad = (WatchPad)this.Owner;
var list = pad.WatchList; pad.Items.Clear();
list.WatchItems.Clear();
}
}
}
public class CopyToClipboardCommand : AbstractMenuCommand
{
public override void Run()
{
if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner;
var node = pad.WatchList.SelectedNode;
if (node != null && node.Node is ValueNode) {
string text = ((ValueNode)node.Node).FullText;
ClipboardWrapper.SetText(text);
}
} }
} }
} }

120
src/AddIns/Debugger/Debugger.AddIn/Pads/Common/AutoCompleteTextBox.cs

@ -0,0 +1,120 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Pads.Controls
{
public class AutoCompleteTextBox : UserControl
{
TextEditor editor;
ITextEditor editorAdapter;
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteTextBox),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, TextChanged));
public static readonly DependencyProperty IsEditableProperty =
DependencyProperty.Register("IsEditable", typeof(bool), typeof(AutoCompleteTextBox),
new FrameworkPropertyMetadata(true, IsEditableChanged));
public string Text {
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public bool IsEditable {
get { return (bool)GetValue(IsEditableProperty); }
set { SetValue(IsEditableProperty, value); }
}
static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AutoCompleteTextBox)d).editor.Text = (string)e.NewValue;
}
static void IsEditableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AutoCompleteTextBox)d).editor.IsReadOnly = !(bool)e.NewValue;
}
public AutoCompleteTextBox()
{
object tmp;
this.editorAdapter = EditorControlService.CreateEditor(out tmp);
this.editor = (TextEditor)tmp;
this.editor.Background = Brushes.Transparent;
this.editor.ShowLineNumbers = false;
this.editor.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
this.editor.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
this.editor.TextArea.GotKeyboardFocus += delegate {
this.Background = Brushes.White;
};
this.editor.TextArea.LostKeyboardFocus += delegate {
this.Background = Brushes.Transparent;
this.Text = this.editor.Text;
this.editor.Select(0, 0);
};
this.editor.TextArea.PreviewKeyDown += editor_TextArea_PreviewKeyDown;
this.editor.TextArea.TextEntered += editor_TextArea_TextEntered;
this.Content = this.editor;
}
void editor_TextArea_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return || e.Key == Key.Escape) {
if (e.Key == Key.Return)
this.Text = this.editor.Text;
e.Handled = true;
}
}
void editor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
StackFrame frame = WindowsDebugger.CurrentStackFrame;
if (e.Text == "." && frame != null)
ShowDotCompletion(frame, this.editor.Text);
}
private void ShowDotCompletion(StackFrame frame, string currentText)
{
string language = ProjectService.CurrentProject == null ? "C#" : ProjectService.CurrentProject.Language;
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
var seg = frame.NextStatement;
var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
var info = ParserService.GetParseInformation(seg.Filename);
string text = ParserService.GetParseableFileContent(seg.Filename).Text;
int currentOffset = this.editor.CaretOffset;
var expr = expressionFinder.FindExpression(currentText, currentOffset);
expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
var rr = resolver.Resolve(expr, info, text);
if (rr != null) {
editorAdapter.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
}
}
}
}

37
src/AddIns/Debugger/Debugger.AddIn/Pads/Common/CommonResources.xaml

@ -0,0 +1,37 @@
<ResourceDictionary
x:Class="CommonResources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Debugger.AddIn.Pads.Controls"
xmlns:core="http://icsharpcode.net/sharpdevelop/core"
xmlns:tv="http://icsharpcode.net/sharpdevelop/treeview"
>
<tv:SharpGridView x:Key="variableGridView">
<GridView.Columns>
<GridViewColumn Header="{core:Localize MainWindow.Windows.Debug.LocalVariables.NameColumn}" Width="400">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<tv:SharpTreeNodeView/>
<local:AutoCompleteTextBox Margin="-6 0 0 0" Text="{Binding Node.Name}" IsEditable="{Binding Node.CanSetName}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{core:Localize MainWindow.Windows.Debug.LocalVariables.ValueColumn}" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<local:AutoCompleteTextBox Text="{Binding Node.Value}" IsEditable="{Binding Node.CanSetValue}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{core:Localize MainWindow.Windows.Debug.LocalVariables.TypeColumn}" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<local:AutoCompleteTextBox Text="{Binding Node.Type}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</tv:SharpGridView>
</ResourceDictionary>

0
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml → src/AddIns/Debugger/Debugger.AddIn/Pads/Common/ConditionCell.xaml

0
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml.cs → src/AddIns/Debugger/Debugger.AddIn/Pads/Common/ConditionCell.xaml.cs

28
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/Converters.cs

@ -1,28 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace Debugger.AddIn.Pads.Controls
{
public class BoolToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
bool val = bool.Parse(parameter.ToString());
return val == (bool.Parse(values[0].ToString()) && bool.Parse(values[1].ToString())) ? Visibility.Visible : Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

82
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl x:Class="Debugger.AddIn.Pads.Controls.WatchList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Debugger.AddIn.Pads.Controls"
xmlns:core="http://icsharpcode.net/sharpdevelop/core"
xmlns:tv="http://icsharpcode.net/sharpdevelop/treeview">
<UserControl.Resources>
<local:BoolToVisibilityConverter x:Key="boolToVisibility" />
<Style x:Key="BorderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="LightGray" />
<Setter Property="BorderThickness" Value="1,0,1,1"></Setter>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
<Style TargetType="{x:Type TextBox}" x:Key="TextBoxValueStyle">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Background" Value="White"/>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource boolToVisibility}" ConverterParameter="True">
<Binding Path="Node.CanSetValue" />
<Binding Path="IsSelected" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="TextBlockValueStyle">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource boolToVisibility}" ConverterParameter="False">
<Binding Path="Node.CanSetValue" />
<Binding Path="IsSelected" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<!-- Value column -->
<DataTemplate x:Key="CellTemplate_Value">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" MinWidth="200" Text="{Binding Node.Value}" Style="{StaticResource TextBlockValueStyle}" />
<TextBox Text="{Binding Node.Value, Mode=OneWay}" Style="{StaticResource TextBoxValueStyle}" KeyUp="OnValueTextBoxKeyUp" />
</StackPanel>
</DataTemplate>
<!-- Type column -->
<DataTemplate x:Key="CellTemplate_Type">
<TextBlock VerticalAlignment="Center" MinWidth="200" Text="{Binding Node.Type}" />
</DataTemplate>
</UserControl.Resources>
<DockPanel>
<tv:SharpTreeView x:Name="myList" ShowRoot="False" PreviewMouseDoubleClick="MyListPreviewMouseDoubleClick" AllowDrop="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AllowDrop}">
<tv:SharpTreeView.View>
<tv:SharpGridView>
<GridView.Columns>
<GridViewColumn Header="{core:Localize Global.Name}" Width="400">
<GridViewColumn.CellTemplate>
<DataTemplate>
<tv:SharpTreeNodeView>
<tv:SharpTreeNodeView.CellEditor>
<local:WatchListAutoCompleteCell
CommandText="{Binding Node.Name, Mode=OneWay}"
CommandEntered="WatchListAutoCompleteCellCommandEntered"/>
</tv:SharpTreeNodeView.CellEditor>
</tv:SharpTreeNodeView>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{core:Localize Dialog.HighlightingEditor.Properties.Value}"
CellTemplate="{StaticResource CellTemplate_Value}"
Width="200" />
<GridViewColumn Header="{core:Localize ResourceEditor.ResourceEdit.TypeColumn}"
CellTemplate="{StaticResource CellTemplate_Type}"
Width="200" />
</GridView.Columns>
</tv:SharpGridView>
</tv:SharpTreeView.View>
</tv:SharpTreeView>
</DockPanel>
</UserControl>

91
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs

@ -1,91 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using Debugger.AddIn.TreeModel;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Services;
using ICSharpCode.TreeView;
namespace Debugger.AddIn.Pads.Controls
{
public enum WatchListType
{
LocalVar,
Watch
}
public partial class WatchList : UserControl
{
public WatchList(WatchListType type)
{
InitializeComponent();
WatchType = type;
if (type == WatchListType.Watch)
myList.Root = new WatchRootNode();
else
myList.Root = new SharpTreeNode();
}
public WatchListType WatchType { get; private set; }
public SharpTreeNodeCollection WatchItems {
get { return myList.Root.Children; }
}
public TreeNodeWrapper SelectedNode {
get { return myList.SelectedItem as TreeNodeWrapper; }
}
void OnValueTextBoxKeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter && e.Key != Key.Escape) {
e.Handled = true;
return;
}
if (e.Key == Key.Enter) {
if(SelectedNode.Node is ValueNode) {
var node = (ValueNode)SelectedNode.Node;
node.Value = ((TextBox)sender).Text;
}
}
if (e.Key == Key.Enter || e.Key == Key.Escape) {
myList.UnselectAll();
WindowsDebugger.RefreshPads();
}
}
void WatchListAutoCompleteCellCommandEntered(object sender, EventArgs e)
{
if (SelectedNode == null) return;
if (WatchType != WatchListType.Watch) return;
var cell = ((WatchListAutoCompleteCell)sender);
SelectedNode.Node.Name = cell.CommandText;
myList.UnselectAll();
if (WatchType == WatchListType.Watch && WatchPad.Instance != null) {
WindowsDebugger.RefreshPads();
}
SelectedNode.IsEditing = false;
}
void MyListPreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (SelectedNode == null) return;
if (WatchType != WatchListType.Watch)
return;
SelectedNode.IsEditing = true;
}
}
}

169
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.cs

@ -1,169 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using ICSharpCode.AvalonEdit;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Pads.Controls
{
public partial class WatchListAutoCompleteCell : UserControl
{
private string language;
protected ConsoleControl console;
public static readonly DependencyProperty CommandTextProperty =
DependencyProperty.Register("CommandText", typeof(string), typeof(WatchListAutoCompleteCell),
new UIPropertyMetadata(null, new PropertyChangedCallback(OnCommandTextChanged)));
private NRefactoryResolver resolver;
public event EventHandler CommandEntered;
public WatchListAutoCompleteCell()
{
InitializeComponent();
console = new ConsoleControl();
console.TextAreaTextEntered += new TextCompositionEventHandler(consoleControl_TextAreaTextEntered);
console.TextAreaPreviewKeyDown += new KeyEventHandler(console_TextAreaPreviewKeyDown);
console.LostFocus += new RoutedEventHandler(console_LostFocus);
console.HideScrollBar();
ConsolePanel.Content = console;
// get language
if (ProjectService.CurrentProject == null)
language = "C#";
else
language = ProjectService.CurrentProject.Language;
resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
// FIXME set language
if (language == "VB" || language == "VBNet") {
console.SetHighlighting("VBNET");
}
else {
console.SetHighlighting("C#");
}
// get process
WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
}
/// <summary>
/// Gets/sets the command text displayed at the command prompt.
/// </summary>
public string CommandText {
get { return console.CommandText.Trim(); }
set { console.CommandText = value; }
}
private ITextEditor TextEditor {
get {
return console.TextEditor;
}
}
private void console_TextAreaPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return || e.Key == Key.Escape) {
if (e.Key == Key.Escape)
CommandText = string.Empty;
else {
if(!CheckSyntax())
return;
}
if (CommandEntered != null)
CommandEntered(this, EventArgs.Empty);
e.Handled = true;
}
}
private void console_LostFocus(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(CommandText) || !this.CheckSyntax())
return;
if (CommandEntered != null)
CommandEntered(this, EventArgs.Empty);
}
private bool CheckSyntax()
{
string command = CommandText;
// FIXME workaround the NRefactory issue that needs a ; at the end
if (language == "C#" || language == "CSharp") {
if(!command.EndsWith(";"))
command += ";";
// FIXME only one string should be available; highlighting expects C#, supproted language, CSharp
language = "CSharp";
}
SupportedLanguage supportedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), language.ToString(), true);
using (var parser = ParserFactory.CreateParser(supportedLanguage, new StringReader(command))) {
parser.ParseExpression();
if (parser.Errors.Count > 0) {
MessageService.ShowError(parser.Errors.ErrorOutput);
return false;
}
}
return true;
}
private void consoleControl_TextAreaTextEntered(object sender, TextCompositionEventArgs e)
{
StackFrame frame = WindowsDebugger.CurrentStackFrame;
if (e.Text == "." && frame != null)
ShowDotCompletion(frame, console.CommandText);
}
private void ShowDotCompletion(StackFrame frame, string currentText)
{
var seg = frame.NextStatement;
var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
var info = ParserService.GetParseInformation(seg.Filename);
string text = ParserService.GetParseableFileContent(seg.Filename).Text;
int currentOffset = TextEditor.Caret.Offset - console.CommandOffset - 1;
var expr = expressionFinder.FindExpression(currentText, currentOffset);
expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
var rr = resolver.Resolve(expr, info, text);
if (rr != null) {
TextEditor.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
}
}
private static void OnCommandTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var cell = d as WatchListAutoCompleteCell;
cell.CommandText = e.NewValue.ToString();
}
}
}

11
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.xaml

@ -1,11 +0,0 @@
<UserControl x:Class="Debugger.AddIn.Pads.Controls.WatchListAutoCompleteCell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="200"/>
</Grid.ColumnDefinitions>
<ContentPresenter
Name="ConsolePanel" />
</Grid>
</UserControl>

37
src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs

@ -1,59 +1,54 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt) // This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Threading; using System.Windows.Threading;
using Debugger; using Debugger;
using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.TreeModel; using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Services; using ICSharpCode.SharpDevelop.Services;
using Exception = System.Exception; using ICSharpCode.TreeView;
using TreeNode = Debugger.AddIn.TreeModel.TreeNode;
namespace ICSharpCode.SharpDevelop.Gui.Pads namespace ICSharpCode.SharpDevelop.Gui.Pads
{ {
public class LocalVarPad : AbstractPadContent public class LocalVarPad : AbstractPadContent
{ {
DockPanel panel; SharpTreeView tree;
WatchList localVarList;
static LocalVarPad instance;
public override object Control { public override object Control {
get { return panel; } get { return tree; }
}
SharpTreeNodeCollection Items {
get { return tree.Root.Children; }
} }
public LocalVarPad() public LocalVarPad()
{ {
this.panel = new DockPanel(); var res = new CommonResources();
instance = this; res.InitializeComponent();
localVarList = new WatchList(WatchListType.LocalVar); this.tree = new SharpTreeView();
panel.Children.Add(localVarList); this.tree.Root = new SharpTreeNode();
this.tree.ShowRoot = false;
this.tree.View = (GridView)res["variableGridView"];
WindowsDebugger.RefreshingPads += RefreshPad; WindowsDebugger.RefreshingPads += RefreshPad;
RefreshPad(); RefreshPad();
} }
/// <remarks>Always check if Instance is null, might be null if pad is not opened!</remarks>
public static LocalVarPad Instance {
get { return instance; }
}
void RefreshPad() void RefreshPad()
{ {
StackFrame frame = WindowsDebugger.CurrentStackFrame; StackFrame frame = WindowsDebugger.CurrentStackFrame;
if (frame == null) { if (frame == null) {
localVarList.WatchItems.Clear(); this.Items.Clear();
} else { } else {
localVarList.WatchItems.Clear(); this.Items.Clear();
frame.Process.EnqueueForEach( frame.Process.EnqueueForEach(
Dispatcher.CurrentDispatcher, Dispatcher.CurrentDispatcher,
ValueNode.GetLocalVariables().ToList(), ValueNode.GetLocalVariables().ToList(),
n => localVarList.WatchItems.Add(n.ToSharpTreeNode()) n => this.Items.Add(n.ToSharpTreeNode())
); );
} }
} }

35
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<src:BaseWatchBox
x:Class="Debugger.AddIn.Pads.WatchInputBox" xmlns:src="clr-namespace:ICSharpCode.SharpDevelop.Gui.Pads;assembly=ICSharpCode.SharpDevelop" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:core="http://icsharpcode.net/sharpdevelop/core" xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets"
Style="{x:Static core:GlobalStyles.DialogWindowStyle}"
WindowStartupLocation="CenterScreen"
WindowState="Normal"
WindowStyle="ToolWindow"
Width="300"
SizeToContent="Height"
ResizeMode="NoResize">
<DockPanel Margin="4">
<widgets:UniformGridWithSpacing
Columns="2"
DockPanel.Dock="Bottom"
Margin="0,8"
Grid.Row="1"
HorizontalAlignment="Center">
<Button
Name="AcceptButton"
Style="{x:Static core:GlobalStyles.ButtonStyle}"
Content="{core:Localize Global.OKButtonText}"
Click="AcceptButton_Click"
IsDefault="True" />
<Button
Name="CancelButton"
Style="{x:Static core:GlobalStyles.ButtonStyle}"
Content="{core:Localize Global.CancelButtonText}"
Click="CancelButton_Click"
IsCancel="True" />
</widgets:UniformGridWithSpacing>
<ContentPresenter
MaxHeight="75"
Name="ConsolePanel" />
</DockPanel>
</src:BaseWatchBox>

123
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml.cs

@ -1,123 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.AvalonEdit;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Pads
{
/// <summary>
/// Interaction logic for WatchBox.xaml
/// </summary>
public partial class WatchInputBox : BaseWatchBox
{
private NRefactoryResolver resolver;
private string language;
public WatchInputBox(string text, string caption) : base()
{
InitializeComponent();
// UI
text = StringParser.Parse(text);
this.Title = StringParser.Parse(caption);
this.ConsolePanel.Content = console;
if (ProjectService.CurrentProject == null) return;
// get language
language = ProjectService.CurrentProject.Language;
resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
// FIXME set language
if (language == "VB" || language == "VBNet") {
console.SetHighlighting("VBNET");
} else {
language = "C#";
console.SetHighlighting("C#");
}
}
protected override void AbstractConsolePadTextEntered(object sender, TextCompositionEventArgs e)
{
StackFrame frame = WindowsDebugger.CurrentStackFrame;
if (e.Text == "." && frame != null)
ShowDotCompletion(frame, console.CommandText);
}
private void ShowDotCompletion(StackFrame frame, string currentText)
{
var seg = frame.NextStatement;
var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
var info = ParserService.GetParseInformation(seg.Filename);
string text = ParserService.GetParseableFileContent(seg.Filename).Text;
int currentOffset = TextEditor.Caret.Offset - console.CommandOffset - 1;
var expr = expressionFinder.FindExpression(currentText, currentOffset);
expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
var rr = resolver.Resolve(expr, info, text);
if (rr != null) {
TextEditor.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
}
}
private bool CheckSyntax()
{
string command = console.CommandText.Trim();
// FIXME workaround the NRefactory issue that needs a ; at the end
if (language == "C#") {
if(!command.EndsWith(";"))
command += ";";
// FIXME only one string should be available; highlighting expects C#, supproted language, CSharp
language = "CSharp";
}
SupportedLanguage supportedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), language, true);
using (var parser = ParserFactory.CreateParser(supportedLanguage, new StringReader(command))) {
parser.ParseExpression();
if (parser.Errors.Count > 0) {
MessageService.ShowError(parser.Errors.ErrorOutput);
return false;
}
}
return true;
}
private void AcceptButton_Click(object sender, RoutedEventArgs e)
{
if (!this.CheckSyntax())
return;
this.DialogResult = true;
this.Close();
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
this.Close();
}
}
}

213
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs

@ -2,15 +2,10 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt) // This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading; using System.Windows.Threading;
using System.Xml.Serialization;
using Debugger; using Debugger;
using Debugger.AddIn; using Debugger.AddIn;
using Debugger.AddIn.Pads.Controls; using Debugger.AddIn.Pads.Controls;
@ -18,191 +13,111 @@ using Debugger.AddIn.TreeModel;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.Core.Presentation; using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors; using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Services; using ICSharpCode.SharpDevelop.Services;
using Exception = System.Exception; using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Gui.Pads namespace ICSharpCode.SharpDevelop.Gui.Pads
{ {
public class WatchPad : AbstractPadContent public class WatchPad : AbstractPadContent
{ {
DockPanel panel; SharpTreeView tree;
WatchList watchList;
static WatchPad instance;
public override object Control { public override object Control {
get { return panel; } get { return tree; }
} }
/// <remarks>Always check if Instance is null, might be null if pad is not opened!</remarks> public SharpTreeView Tree {
public static WatchPad Instance { get { return tree; }
get { return instance; }
} }
public WatchList WatchList { public SharpTreeNodeCollection Items {
get { get { return tree.Root.Children; }
return watchList;
}
} }
public WatchPad() public WatchPad()
{ {
this.panel = new DockPanel(); var res = new CommonResources();
res.InitializeComponent();
instance = this;
this.tree = new SharpTreeView();
watchList = new WatchList(WatchListType.Watch); this.tree.Root = new SharpTreeNode();
watchList.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu"); this.tree.ShowRoot = false;
this.tree.View = (GridView)res["variableGridView"];
watchList.MouseDoubleClick += watchList_DoubleClick; this.tree.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu");
watchList.KeyUp += watchList_KeyUp; this.tree.KeyUp += delegate(object sender, KeyEventArgs e) {
watchList.WatchItems.CollectionChanged += OnWatchItemsCollectionChanged; if (e.Key == Key.Delete) {
RemoveWatchCommand cmd = new RemoveWatchCommand { Owner = this };
panel.Children.Add(watchList); cmd.Run();
panel.KeyUp += new KeyEventHandler(panel_KeyUp);
// wire events that influence the items
LoadSavedNodes();
ProjectService.SolutionClosed += delegate { watchList.WatchItems.Clear(); };
ProjectService.ProjectAdded += delegate { LoadSavedNodes(); };
ProjectService.SolutionLoaded += delegate { LoadSavedNodes(); };
WindowsDebugger.RefreshingPads += RefreshPad;
RefreshPad();
}
#region Saved nodes
void LoadSavedNodes()
{
var props = GetSavedVariablesProperties();
if (props == null)
return;
foreach (var element in props.Elements) {
watchList.WatchItems.Add(new TreeNode(element, null).ToSharpTreeNode());
}
}
void OnWatchItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var props = GetSavedVariablesProperties();
if (props == null) return;
if (e.Action == NotifyCollectionChangedAction.Add) {
// add to saved data
foreach(var data in e.NewItems.OfType<TreeNode>()) {
props.Set(data.Name, (object)null);
} }
} };
this.tree.MouseDoubleClick += delegate(object sender, MouseButtonEventArgs e) {
if (e.Action == NotifyCollectionChangedAction.Remove) { if (this.tree.SelectedItem == null) {
// remove from saved data AddWatchCommand cmd = new AddWatchCommand { Owner = this };
foreach(var data in e.OldItems.OfType<TreeNode>()) { cmd.Run();
props.Remove(data.Name);
} }
} };
}
Properties GetSavedVariablesProperties()
{
if (ProjectService.CurrentProject == null)
return null;
if (ProjectService.CurrentProject.ProjectSpecificProperties == null)
return null;
var props = ProjectService.CurrentProject.ProjectSpecificProperties.Get("watchVars") as Properties; ProjectService.SolutionLoaded += delegate { LoadNodes(); };
if (props == null) { ProjectService.SolutionClosing += delegate { SaveNodes(); };
ProjectService.CurrentProject.ProjectSpecificProperties.Set("watchVars", new Properties()); LoadNodes();
}
return ProjectService.CurrentProject.ProjectSpecificProperties.Get("watchVars") as Properties; WindowsDebugger.RefreshingPads += RefreshPad;
RefreshPad();
} }
#endregion void LoadNodes()
void panel_KeyUp(object sender, KeyEventArgs e)
{ {
if (e.Key == Key.Insert) { if (ProjectService.OpenSolution != null &&
AddNewWatch(); ProjectService.OpenSolution.Preferences != null &&
e.Handled = true; ProjectService.OpenSolution.Preferences.Properties != null)
{
var props = ProjectService.OpenSolution.Preferences.Properties.Get("Watches", new Properties());
foreach(var element in props.Elements) {
this.Items.Add(new TreeNode(element, null).ToSharpTreeNode());
}
} }
} }
void watchList_KeyUp(object sender, KeyEventArgs e) void SaveNodes()
{ {
if (e.Key == Key.Delete) { if (ProjectService.OpenSolution != null &&
RemoveWatchCommand cmd = new RemoveWatchCommand { Owner = this }; ProjectService.OpenSolution.Preferences != null &&
cmd.Run(); ProjectService.OpenSolution.Preferences.Properties != null)
}
}
void watchList_DoubleClick(object sender, MouseEventArgs e)
{
if (watchList.SelectedNode == null)
{ {
AddNewWatch(); var props = new Properties();
ProjectService.OpenSolution.Preferences.Properties.Set("Watches", props);
foreach(var node in this.Items.OfType<TreeNode>()) {
props.Set(node.Name, (object)null);
}
} }
} }
void AddNewWatch() SharpTreeNodeAdapter MakeNode(string name)
{
AddWatchCommand command = new AddWatchCommand { Owner = this };
command.Run();
}
void ResetPad(object sender, EventArgs e)
{
string language = "CSharp";
if (ProjectService.CurrentProject != null)
language = ProjectService.CurrentProject.Language;
// rebuild list
var nodes = new List<TreeNodeWrapper>();
foreach (var nod in watchList.WatchItems.OfType<TreeNodeWrapper>())
nodes.Add(new TreeNode(nod.Node.Name, null).ToSharpTreeNode());
watchList.WatchItems.Clear();
foreach (var nod in nodes)
watchList.WatchItems.Add(nod);
}
TreeNodeWrapper UpdateNode(TreeNodeWrapper node, Process process)
{ {
LoggingService.Info("Evaluating watch: " + name);
TreeNode node;
try { try {
LoggingService.Info("Evaluating: " + (string.IsNullOrEmpty(node.Node.Name) ? "is null or empty!" : node.Node.Name)); node = new ValueNode(null, name, () => ExpressionEvaluator.Evaluate(name, SupportedLanguage.CSharp, WindowsDebugger.CurrentStackFrame));
} catch (GetValueException e) {
ValueNode valNode = new ValueNode(null, node.Node.Name, () => ExpressionEvaluator.Evaluate(node.Node.Name, SupportedLanguage.CSharp, WindowsDebugger.CurrentStackFrame)); node = new TreeNode("Icons.16x16.Error", name, e.Message, string.Empty, null);
return valNode.ToSharpTreeNode();
} catch (GetValueException) {
string error = String.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.InvalidExpression}"), node.Node.Name);
TreeNode infoNode = new TreeNode("Icons.16x16.Error", node.Node.Name, error, string.Empty, null);
return infoNode.ToSharpTreeNode();
} }
node.CanSetName = true;
node.PropertyChanged += (s, e) => { if (e.PropertyName == "Name") WindowsDebugger.RefreshPads(); };
return node.ToSharpTreeNode();
} }
protected void RefreshPad() protected void RefreshPad()
{ {
Process debuggedProcess = WindowsDebugger.CurrentProcess; Process process = WindowsDebugger.CurrentProcess;
if (process != null) {
ResetPad(null, null); var names = this.Items.OfType<SharpTreeNodeAdapter>().Select(n => n.Node.Name).ToList();
this.Items.Clear();
if (debuggedProcess == null || debuggedProcess.IsRunning) process.EnqueueForEach(
return;
using(new PrintTimes("Watch Pad refresh")) {
var nodes = watchList.WatchItems.OfType<TreeNodeWrapper>().ToArray();
watchList.WatchItems.Clear();
debuggedProcess.EnqueueForEach(
Dispatcher.CurrentDispatcher, Dispatcher.CurrentDispatcher,
nodes, names,
n => watchList.WatchItems.Add(UpdateNode(n, debuggedProcess)) name => this.Items.Add(MakeNode(name))
); );
} }
} }

23
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs → src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs

@ -15,24 +15,20 @@ using ICSharpCode.TreeView;
namespace Debugger.AddIn.Pads.Controls namespace Debugger.AddIn.Pads.Controls
{ {
public class TreeNodeWrapper : SharpTreeNode public class SharpTreeNodeAdapter : SharpTreeNode
{ {
public TreeNodeWrapper(TreeNode node) public SharpTreeNodeAdapter(TreeNode node)
{ {
if (node == null) if (node == null)
throw new ArgumentNullException("node"); throw new ArgumentNullException("node");
Node = node; this.Node = node;
LazyLoading = true; this.LazyLoading = true;
} }
public TreeNode Node { get; private set; } public TreeNode Node { get; private set; }
public override object Text {
get { return this.Node.Name; }
}
public override object Icon { public override object Icon {
get { return this.Node.Image.ImageSource; } get { return this.Node.Image != null ? this.Node.Image.ImageSource : null; }
} }
public override bool ShowExpander { public override bool ShowExpander {
@ -46,10 +42,8 @@ namespace Debugger.AddIn.Pads.Controls
process.EnqueueWork(Dispatcher.CurrentDispatcher, () => Children.AddRange(this.Node.GetChildren().Select(node => node.ToSharpTreeNode()))); process.EnqueueWork(Dispatcher.CurrentDispatcher, () => Children.AddRange(this.Node.GetChildren().Select(node => node.ToSharpTreeNode())));
} }
} }
}
/*
public class WatchRootNode : SharpTreeNode
{
public override bool CanDrop(System.Windows.DragEventArgs e, int index) public override bool CanDrop(System.Windows.DragEventArgs e, int index)
{ {
e.Effects = DragDropEffects.None; e.Effects = DragDropEffects.None;
@ -72,10 +66,11 @@ namespace Debugger.AddIn.Pads.Controls
var text = new TreeNode(e.Data.GetData(DataFormats.StringFormat).ToString(), null); var text = new TreeNode(e.Data.GetData(DataFormats.StringFormat).ToString(), null);
var node = text.ToSharpTreeNode(); var node = text.ToSharpTreeNode();
if (!WatchPad.Instance.WatchList.WatchItems.Any(n => text.Name == ((TreeNodeWrapper)n).Node.Name)) if (!WatchPad.Instance.WatchList.WatchItems.Any(n => text.Name == ((SharpTreeNodeAdapter)n).Node.Name))
WatchPad.Instance.WatchList.WatchItems.Add(node); WatchPad.Instance.WatchList.WatchItems.Add(node);
WindowsDebugger.RefreshPads(); WindowsDebugger.RefreshPads();
} }
*/
} }
} }

6
src/AddIns/Debugger/Debugger.AddIn/TreeModel/TreeNode.cs

@ -19,7 +19,7 @@ namespace Debugger.AddIn.TreeModel
public class TreeNode : INotifyPropertyChanged public class TreeNode : INotifyPropertyChanged
{ {
public event EventHandler<PropertyEventArgs> PropertyRead; public event EventHandler<PropertyEventArgs> PropertyRead;
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
IImage image; IImage image;
string name; string name;
@ -52,7 +52,7 @@ namespace Debugger.AddIn.TreeModel
} }
} }
public bool CanSetName { get; protected set; } public bool CanSetName { get; set; }
public string Value { public string Value {
get { get {
@ -67,7 +67,7 @@ namespace Debugger.AddIn.TreeModel
} }
} }
public bool CanSetValue { get; protected set; } public bool CanSetValue { get; set; }
public string Type { public string Type {
get { get {

4
src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs

@ -122,9 +122,9 @@ namespace Debugger.AddIn.TreeModel
public static class ExtensionMethods public static class ExtensionMethods
{ {
public static TreeNodeWrapper ToSharpTreeNode(this TreeNode node) public static SharpTreeNodeAdapter ToSharpTreeNode(this TreeNode node)
{ {
return new TreeNodeWrapper(node); return new SharpTreeNodeAdapter(node);
} }
} }
} }

Loading…
Cancel
Save