Browse Source

moved CallStackPad to WPF; this should fix the repaint problems/errors

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6385 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 15 years ago
parent
commit
0d977e0a84
  1. 7
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  2. 97
      src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.Menu.cs
  3. 250
      src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.cs
  4. 27
      src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml
  5. 242
      src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs

7
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -79,6 +79,10 @@ @@ -79,6 +79,10 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Pads\CallStackPad.xaml.cs">
<DependentUpon>CallStackPad.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="BreakpointChangeMenuBuilder.cs" />
<Compile Include="DisableBreakpointMenuCommand.cs" />
@ -102,7 +106,6 @@ @@ -102,7 +106,6 @@
<Compile Include="Pads\SelectLanguageCommand.cs" />
<Compile Include="Pads\WatchPadCommands.cs" />
<Compile Include="Pads\BreakPointsPad.cs" />
<Compile Include="Pads\CallStackPad.cs" />
<Compile Include="Pads\ConsolePad.cs">
<SubType>UserControl</SubType>
</Compile>
@ -223,7 +226,6 @@ @@ -223,7 +226,6 @@
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Pads\DebuggerPad.cs" />
<Compile Include="Pads\CallStackPad.Menu.cs" />
<Compile Include="Pads\RunningThreadsPad.Menu.cs" />
<Compile Include="TreeModel\TreeNode.cs" />
<Compile Include="TreeModel\Adapters\TreeViewVarNode.cs">
@ -321,6 +323,7 @@ @@ -321,6 +323,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Page Include="Pads\CallStackPad.xaml" />
<Page Include="Service\EditBreakpointScriptWindow.xaml" />
<Page Include="Visualizers\Graph\Drawing\NodeControlResources.xaml" />
<Page Include="Visualizers\Graph\Drawing\PositionedGraphNodeControl.xaml" />

97
src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.Menu.cs

@ -1,97 +0,0 @@ @@ -1,97 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
#region License
//
// Copyright (c) 2007, ic#code
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the ic#code nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#endregion
using System.ComponentModel;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public partial class CallStackPad
{
ContextMenuStrip CreateContextMenuStrip()
{
ContextMenuStrip menu = new ContextMenuStrip();
menu.Opening += FillContextMenuStrip;
return menu;
}
void FillContextMenuStrip(object sender, CancelEventArgs e)
{
ContextMenuStrip menu = sender as ContextMenuStrip;
menu.Items.Clear();
ToolStripMenuItem argNamesItem;
argNamesItem = new ToolStripMenuItem();
argNamesItem.Text = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentNames");
argNamesItem.Checked = DebuggingOptions.Instance.ShowArgumentNames;
argNamesItem.Click += delegate {
DebuggingOptions.Instance.ShowArgumentNames = !DebuggingOptions.Instance.ShowArgumentNames;
RefreshPad();
};
ToolStripMenuItem argValuesItem;
argValuesItem = new ToolStripMenuItem();
argValuesItem.Text = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentValues");
argValuesItem.Checked = DebuggingOptions.Instance.ShowArgumentValues;
argValuesItem.Click += delegate {
DebuggingOptions.Instance.ShowArgumentValues = !DebuggingOptions.Instance.ShowArgumentValues;
RefreshPad();
};
ToolStripMenuItem extMethodsItem;
extMethodsItem = new ToolStripMenuItem();
extMethodsItem.Text = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowExternalMethods");
extMethodsItem.Checked = DebuggingOptions.Instance.ShowExternalMethods;
extMethodsItem.Click += delegate {
DebuggingOptions.Instance.ShowExternalMethods = !DebuggingOptions.Instance.ShowExternalMethods;
RefreshPad();
};
menu.Items.AddRange(new ToolStripItem[] {
argNamesItem,
argValuesItem,
extMethodsItem
});
e.Cancel = false;
}
}
}

250
src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.cs

@ -1,250 +0,0 @@ @@ -1,250 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
#region License
//
// Copyright (c) 2007, ic#code
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the ic#code nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Debugger;
using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Services;
using Exception=System.Exception;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public partial class CallStackPad : DebuggerPad
{
ListView callStackList;
Process debuggedProcess;
ColumnHeader name = new ColumnHeader();
ColumnHeader language = new ColumnHeader();
public override object Control {
get {
return callStackList;
}
}
protected override void InitializeComponents()
{
callStackList = new ListView();
callStackList.FullRowSelect = true;
callStackList.AutoArrange = true;
callStackList.Alignment = ListViewAlignment.Left;
callStackList.View = View.Details;
callStackList.Dock = DockStyle.Fill;
callStackList.GridLines = false;
callStackList.Activation = ItemActivation.OneClick;
callStackList.Columns.AddRange(new ColumnHeader[] {name, language} );
callStackList.ContextMenuStrip = CreateContextMenuStrip();
callStackList.ItemActivate += new EventHandler(CallStackListItemActivate);
name.Width = 500;
language.Width = 50;
RedrawContent();
ResourceService.LanguageChanged += delegate { RedrawContent(); };
}
public void RedrawContent()
{
name.Text = ResourceService.GetString("Global.Name");
language.Text = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.Language");
}
protected override void SelectProcess(Process process)
{
if (debuggedProcess != null) {
debuggedProcess.Paused -= debuggedProcess_Paused;
}
debuggedProcess = process;
if (debuggedProcess != null) {
debuggedProcess.Paused += debuggedProcess_Paused;
}
RefreshPad();
}
void debuggedProcess_Paused(object sender, ProcessEventArgs e)
{
RefreshPad();
}
void CallStackListItemActivate(object sender, EventArgs e)
{
if (debuggedProcess.IsPaused) {
StackFrame frame = (StackFrame)(callStackList.SelectedItems[0].Tag);
if (frame.HasSymbols) {
if (debuggedProcess.SelectedThread != null) {
debuggedProcess.SelectedThread.SelectedStackFrame = frame;
debuggedProcess.OnPaused(); // Force refresh of pads
}
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWithoutSymbols}", "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
}
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
}
}
public override void RefreshPad()
{
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedThread == null) {
callStackList.Items.Clear();
return;
}
using(new PrintTimes("Callstack refresh")) {
try {
Utils.DoEvents(debuggedProcess);
List<ListViewItem> items = CreateItems();
UpdateItems(items);
} catch(AbortedBecauseDebuggeeResumedException) {
} catch(Exception) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
throw;
}
}
}
}
public List<ListViewItem> CreateItems()
{
bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods;
bool lastItemIsExternalMethod = false;
List<ListViewItem> items = new List<ListViewItem>();
foreach (StackFrame frame in debuggedProcess.SelectedThread.GetCallstack(100)) {
ListViewItem item;
if (frame.HasSymbols || showExternalMethods) {
// Show the method in the list
item = new ListViewItem(new string[] { GetFullName(frame), "" });
lastItemIsExternalMethod = false;
} else {
// Show [External methods] in the list
if (lastItemIsExternalMethod) continue;
item = new ListViewItem(new string[] { ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods"), "" });
lastItemIsExternalMethod = true;
}
item.Tag = frame;
item.ForeColor = frame.HasSymbols ? Color.Black : Color.Gray;
items.Add(item);
Utils.DoEvents(debuggedProcess);
}
return items;
}
public void UpdateItems(List<ListViewItem> items)
{
callStackList.BeginUpdate();
// Adjust count
while (callStackList.Items.Count < items.Count) {
callStackList.Items.Insert(0, new ListViewItem(new string[2]));
}
while (callStackList.Items.Count > items.Count) {
callStackList.Items.RemoveAt(0);
}
// Overwrite
for(int i = 0; i < items.Count; i++) {
callStackList.Items[i].SubItems[0] = items[i].SubItems[0];
callStackList.Items[i].SubItems[1] = items[i].SubItems[1];
callStackList.Items[i].Tag = items[i].Tag;
callStackList.Items[i].ForeColor = items[i].ForeColor;
Utils.DoEvents(debuggedProcess);
}
callStackList.EndUpdate();
}
public string GetFullName(StackFrame frame)
{
bool showArgumentNames = DebuggingOptions.Instance.ShowArgumentNames;
bool showArgumentValues = DebuggingOptions.Instance.ShowArgumentValues;
StringBuilder name = new StringBuilder();
name.Append(frame.MethodInfo.DeclaringType.Name);
name.Append('.');
name.Append(frame.MethodInfo.Name);
if (showArgumentNames || showArgumentValues) {
name.Append("(");
for (int i = 0; i < frame.ArgumentCount; i++) {
string parameterName = null;
string argValue = null;
if (showArgumentNames) {
try {
parameterName = frame.MethodInfo.GetParameters()[i].Name;
} catch { }
if (parameterName == "") parameterName = null;
}
if (showArgumentValues) {
try {
argValue = frame.GetArgumentValue(i).AsString;
} catch { }
}
if (parameterName != null && argValue != null) {
name.Append(parameterName);
name.Append("=");
name.Append(argValue);
}
if (parameterName != null && argValue == null) {
name.Append(parameterName);
}
if (parameterName == null && argValue != null) {
name.Append(argValue);
}
if (parameterName == null && argValue == null) {
name.Append(ResourceService.GetString("Global.NA"));
}
if (i < frame.ArgumentCount - 1) {
name.Append(", ");
}
}
name.Append(")");
}
return name.ToString();
}
}
}

27
src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
<UserControl x:Class="ICSharpCode.SharpDevelop.Gui.Pads.CallStackPadContent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sd="http://icsharpcode.net/sharpdevelop/core"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel>
<ListView Name="view" SelectionChanged="ViewSelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="{sd:Localize Global.Name}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Foreground="{Binding FontColor}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{sd:Localize MainWindow.Windows.Debug.CallStack.Language}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Language}" Foreground="{Binding FontColor}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</UserControl>

242
src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs

@ -0,0 +1,242 @@ @@ -0,0 +1,242 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com" />
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
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 Debugger;
using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
/// <summary>
/// Interaction logic for CallStackPadContent.xaml
/// </summary>
public partial class CallStackPadContent : UserControl
{
Process debuggedProcess;
public CallStackPadContent()
{
InitializeComponent();
view.ContextMenu = CreateMenu();
}
ContextMenu CreateMenu()
{
MenuItem argNamesItem = new MenuItem();
argNamesItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentNames");
argNamesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentNames;
argNamesItem.Click += delegate {
argNamesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentNames = !DebuggingOptions.Instance.ShowArgumentNames;
RefreshPad();
};
MenuItem argValuesItem = new MenuItem();
argValuesItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentValues");
argValuesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentValues;
argValuesItem.Click += delegate {
argValuesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentValues = !DebuggingOptions.Instance.ShowArgumentValues;
RefreshPad();
};
MenuItem extMethodsItem = new MenuItem();
extMethodsItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowExternalMethods");
extMethodsItem.IsChecked = DebuggingOptions.Instance.ShowExternalMethods;
extMethodsItem.Click += delegate {
extMethodsItem.IsChecked = DebuggingOptions.Instance.ShowExternalMethods = !DebuggingOptions.Instance.ShowExternalMethods;
RefreshPad();
};
return new ContextMenu() {
Items = {
argNamesItem,
argValuesItem,
extMethodsItem
}
};
}
public void SelectProcess(Process process)
{
if (debuggedProcess != null) {
debuggedProcess.Paused -= debuggedProcess_Paused;
}
debuggedProcess = process;
if (debuggedProcess != null) {
debuggedProcess.Paused += debuggedProcess_Paused;
}
RefreshPad();
}
void debuggedProcess_Paused(object sender, ProcessEventArgs e)
{
RefreshPad();
}
void ViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (debuggedProcess.IsPaused) {
CallStackItem item = view.SelectedItem as CallStackItem;
if (item == null)
return;
if (item.Frame.HasSymbols) {
if (debuggedProcess.SelectedThread != null) {
debuggedProcess.SelectedThread.SelectedStackFrame = item.Frame;
debuggedProcess.OnPaused(); // Force refresh of pads
}
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWithoutSymbols}", "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
}
} else {
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
}
}
public void RefreshPad()
{
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedThread == null) {
view.ItemsSource = null;
return;
}
using(new PrintTimes("Callstack refresh")) {
try {
Utils.DoEvents(debuggedProcess);
view.ItemsSource = CreateItems();
} catch(AbortedBecauseDebuggeeResumedException) {
} catch(System.Exception) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
throw;
}
}
}
}
IEnumerable<CallStackItem> CreateItems()
{
bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods;
bool lastItemIsExternalMethod = false;
foreach (StackFrame frame in debuggedProcess.SelectedThread.GetCallstack(100)) {
CallStackItem item;
if (frame.HasSymbols || showExternalMethods) {
// Show the method in the list
item = new CallStackItem() { Name = GetFullName(frame), Language = "" };
lastItemIsExternalMethod = false;
} else {
// Show [External methods] in the list
if (lastItemIsExternalMethod) continue;
item = new CallStackItem() { Name = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods"), Language = "" };
lastItemIsExternalMethod = true;
}
item.Frame = frame;
yield return item;
Utils.DoEvents(debuggedProcess);
}
}
string GetFullName(StackFrame frame)
{
bool showArgumentNames = DebuggingOptions.Instance.ShowArgumentNames;
bool showArgumentValues = DebuggingOptions.Instance.ShowArgumentValues;
StringBuilder name = new StringBuilder();
name.Append(frame.MethodInfo.DeclaringType.Name);
name.Append('.');
name.Append(frame.MethodInfo.Name);
if (showArgumentNames || showArgumentValues) {
name.Append("(");
for (int i = 0; i < frame.ArgumentCount; i++) {
string parameterName = null;
string argValue = null;
if (showArgumentNames) {
try {
parameterName = frame.MethodInfo.GetParameters()[i].Name;
} catch { }
if (parameterName == "") parameterName = null;
}
if (showArgumentValues) {
try {
argValue = frame.GetArgumentValue(i).AsString;
} catch { }
}
if (parameterName != null && argValue != null) {
name.Append(parameterName);
name.Append("=");
name.Append(argValue);
}
if (parameterName != null && argValue == null) {
name.Append(parameterName);
}
if (parameterName == null && argValue != null) {
name.Append(argValue);
}
if (parameterName == null && argValue == null) {
name.Append(ResourceService.GetString("Global.NA"));
}
if (i < frame.ArgumentCount - 1) {
name.Append(", ");
}
}
name.Append(")");
}
return name.ToString();
}
}
public class CallStackItem
{
public string Name { get; set; }
public string Language { get; set; }
public StackFrame Frame { get; set; }
public Brush FontColor {
get { return Frame == null || Frame.HasSymbols ? Brushes.Black : Brushes.Gray; }
}
}
public class CallStackPad : DebuggerPad
{
CallStackPadContent callStackList;
public override object Control {
get {
return callStackList;
}
}
protected override void InitializeComponents()
{
callStackList = new CallStackPadContent();
}
protected override void SelectProcess(Process process)
{
callStackList.SelectProcess(process);
}
public override void RefreshPad()
{
callStackList.RefreshPad();
}
}
}
Loading…
Cancel
Save