Browse Source

New features in WPF WatchPad:

- add new watch using Ins key
- ability to edit the name of the variable using also autocomplete.
pull/15/head
Eusebiu Marcu 15 years ago
parent
commit
525c75cad2
  1. 4
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  2. 4
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml.cs
  3. 17
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/Converters.cs
  4. 63
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml
  5. 41
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs
  6. 178
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.cs
  7. 11
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.xaml
  8. 1
      src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
  9. 3
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml.cs
  10. 24
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs

4
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -117,6 +117,9 @@ @@ -117,6 +117,9 @@
<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\ParallelPad\DrawSurface.xaml.cs">
<DependentUpon>DrawSurface.xaml</DependentUpon>
<SubType>Code</SubType>
@ -393,6 +396,7 @@ @@ -393,6 +396,7 @@
<Page Include="Pads\Controls\ConditionCell.xaml" />
<Page Include="Pads\Controls\SimpleListViewControl.xaml" />
<Page Include="Pads\Controls\WatchList.xaml" />
<Page Include="Pads\Controls\WatchListAutoCompleteCell.xaml" />
<Page Include="Pads\ParallelPad\DrawSurface.xaml" />
<Page Include="Pads\ParallelPad\ThreadStack.xaml" />
<Page Include="Pads\WatchInputBox.xaml" />

4
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@

// 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;

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

@ -53,4 +53,21 @@ namespace Debugger.AddIn.Pads.Controls @@ -53,4 +53,21 @@ namespace Debugger.AddIn.Pads.Controls
throw new NotImplementedException();
}
}
public class BoolAndTypeToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
bool val = bool.Parse(parameter.ToString());
return val == ((WatchListType)(values[0]) == WatchListType.Watch &&
bool.Parse(values[1].ToString())) ? Visibility.Visible : Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

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

@ -2,10 +2,15 @@ @@ -2,10 +2,15 @@
<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:localControls="clr-namespace:Debugger.AddIn.Pads.Controls" xmlns:core="http://icsharpcode.net/sharpdevelop/core"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
x:Name="ControlList"
Background="White">
<UserControl.Resources>
<localControls:BoolToVisibilityConverter
x:Key="boolToVisibility" />
<localControls:BoolAndTypeToVisibilityConverter
x:Key="boolTypeToVisibility" />
<localControls:TreeListViewConverter
x:Key="TreeListViewConverter" />
<Style
@ -26,13 +31,11 @@ @@ -26,13 +31,11 @@
</Style>
<Style
TargetType="{x:Type TextBox}"
x:Key="TextBoxStyle">
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="VerticalAlignment" Value="Center" />
<Setter
Property="Visibility">
<Setter.Value>
@ -48,9 +51,27 @@ @@ -48,9 +51,27 @@
</Setter.Value>
</Setter>
</Style>
<Style TargetType="localControls:WatchListAutoCompleteCell"
x:Key="TextBoxNameStyle">
<Setter
Property="Visibility">
<Setter.Value>
<MultiBinding
Converter="{StaticResource boolTypeToVisibility}"
ConverterParameter="True">
<Binding
Path="WatchType"
ElementName="ControlList"/>
<Binding
Path="IsSelected"
RelativeSource="{RelativeSource AncestorType=TreeViewItem}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<Style
TargetType="{x:Type TextBlock}"
x:Key="TextBlockStyle">
x:Key="TextBlockValueStyle">
<Setter
Property="VerticalAlignment"
Value="Center" />
@ -69,6 +90,28 @@ @@ -69,6 +90,28 @@
</Setter.Value>
</Setter>
</Style>
<Style
TargetType="{x:Type TextBlock}"
x:Key="TextBlockNameStyle">
<Setter
Property="VerticalAlignment"
Value="Center" />
<Setter
Property="Visibility">
<Setter.Value>
<MultiBinding
Converter="{StaticResource boolTypeToVisibility}"
ConverterParameter="False">
<Binding
Path="WatchType"
ElementName="ControlList"/>
<Binding
Path="IsSelected"
RelativeSource="{RelativeSource AncestorType=TreeViewItem}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="ExpandToggleStyle"
TargetType="{x:Type ToggleButton}">
@ -256,7 +299,11 @@ @@ -256,7 +299,11 @@
MinWidth="400"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="{Binding Path=Name}" />
Text="{Binding Path=Name}"
Style="{StaticResource TextBlockNameStyle}" />
<localControls:WatchListAutoCompleteCell
CommandText="{Binding Path=Name, Mode=OneWay}"
Style="{StaticResource TextBoxNameStyle}" CommandEntered="WatchListAutoCompleteCell_CommandEntered"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger
@ -278,10 +325,10 @@ @@ -278,10 +325,10 @@
VerticalAlignment="Center"
MinWidth="200"
Text="{Binding Path=Text}"
Style="{StaticResource TextBlockStyle}" />
Style="{StaticResource TextBlockValueStyle}" />
<TextBox
Text="{Binding Path=Text, Mode=OneWay}"
Style="{StaticResource TextBoxStyle}" KeyUp="TextBox_KeyUp" />
Style="{StaticResource TextBoxValueStyle}" KeyUp="OnValueTextBoxKeyUp" />
</StackPanel>
</DataTemplate>
<!-- Type column -->

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

@ -12,9 +12,17 @@ using System.Windows.Media; @@ -12,9 +12,17 @@ using System.Windows.Media;
using Debugger.AddIn.TreeModel;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.Pads;
namespace Debugger.AddIn.Pads.Controls
{
public enum WatchListType
{
LocalVar,
Watch
}
public partial class WatchList : UserControl
{
private ObservableCollection<TreeNode> items = new ObservableCollection<TreeNode>();
@ -24,7 +32,19 @@ namespace Debugger.AddIn.Pads.Controls @@ -24,7 +32,19 @@ namespace Debugger.AddIn.Pads.Controls
InitializeComponent();
}
void TextBox_KeyUp(object sender, KeyEventArgs e)
public WatchListType WatchType { get; set; }
public DebuggerPad ParentPad { get; set; }
public ObservableCollection<TreeNode> WatchItems { get { return items; } }
public TreeNode SelectedNode {
get {
return this.MyList.SelectedItem as TreeNode;
}
}
void OnValueTextBoxKeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter && e.Key != Key.Escape)
{
@ -40,17 +60,24 @@ namespace Debugger.AddIn.Pads.Controls @@ -40,17 +60,24 @@ namespace Debugger.AddIn.Pads.Controls
}
if (e.Key == Key.Enter || e.Key == Key.Escape) {
for (int i = 0; i < MyList.Items.Count; i++) {
TreeViewItem child = (TreeViewItem)MyList.ItemContainerGenerator.ContainerFromIndex(i);
child.IsSelected = false;
TreeViewItem child = (TreeViewItem)MyList.ItemContainerGenerator.ContainerFromIndex(i);
child.IsSelected = false;
}
}
}
public ObservableCollection<TreeNode> WatchItems { get { return items; } }
void WatchListAutoCompleteCell_CommandEntered(object sender, EventArgs e)
{
if (SelectedNode == null) return;
public TreeNode SelectedNode {
get {
return this.MyList.SelectedItem as TreeNode;
SelectedNode.Name = ((WatchListAutoCompleteCell)sender).CommandText;
if (WatchType == WatchListType.Watch) {
ParentPad.RefreshPad();
}
for (int i = 0; i < MyList.Items.Count; i++) {
TreeViewItem child = (TreeViewItem)MyList.ItemContainerGenerator.ContainerFromIndex(i);
child.IsSelected = false;
}
}
}

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

@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
// 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;
debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) {
this.Process = e.Process;
};
this.Process = debugger.DebuggedProcess;
}
private Process Process { get; set; }
/// <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)
{
foreach (char ch in e.Text) {
if (ch == '.') {
ShowDotCompletion(console.CommandText);
}
}
}
private void ShowDotCompletion(string currentText)
{
var seg = Process.SelectedStackFrame.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

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
<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>

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

@ -34,6 +34,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -34,6 +34,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
protected override void InitializeComponents()
{
localVarList = new WatchList();
localVarList.WatchType = WatchListType.LocalVar;
panel.Children.Add(localVarList);
}

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

@ -1,3 +1,6 @@ @@ -1,3 +1,6 @@
// 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;

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

@ -49,15 +49,26 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -49,15 +49,26 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
protected override void InitializeComponents()
{
watchList = new WatchList();
watchList.MouseDoubleClick += watchList_DoubleClick;
watchList.WatchType = WatchListType.Watch;
watchList.ParentPad = this;
watchList.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu");
watchList.AllowDrop = true;
watchList.DragEnter += watchList_DragOver;
watchList.Drop += watchList_Drop;
watchList.MouseDoubleClick += watchList_DoubleClick;
watchList.KeyUp += watchList_KeyUp;
panel.Children.Add(watchList);
panel.KeyUp += new KeyEventHandler(panel_KeyUp);
}
void panel_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Insert) {
AddNewWatch();
e.Handled = true;
}
}
void watchList_KeyUp(object sender, KeyEventArgs e)
@ -79,7 +90,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -79,7 +90,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
// FIXME languages
TextNode text = new TextNode(e.Data.GetData(DataFormats.StringFormat).ToString(),
language == "VB" || language == "VBNet" ? SupportedLanguage.VBNet : SupportedLanguage.CSharp);
language == "VB" || language == "VBNet" ? SupportedLanguage.VBNet : SupportedLanguage.CSharp);
if (!watchList.WatchItems.Contains(text))
watchList.WatchItems.ContainsItem(text);
@ -102,11 +113,16 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -102,11 +113,16 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{
if (watchList.SelectedNode == null)
{
AddWatchCommand command = new AddWatchCommand { Owner = this };
command.Run();
AddNewWatch();
}
}
void AddNewWatch()
{
AddWatchCommand command = new AddWatchCommand { Owner = this };
command.Run();
}
void ResetPad(object sender, EventArgs e)
{
string language = ProjectService.CurrentProject.Language;

Loading…
Cancel
Save