Browse Source

Add method view

add toolbar to parallel stacks
pull/15/head
Eusebiu Marcu 15 years ago
parent
commit
3318da248a
  1. 8
      data/resources/StringResources.resx
  2. BIN
      data/resources/image/BitmapResources/BitmapResources-data/Icons.48x48.CurrentFrame.png
  3. 5
      data/resources/image/BitmapResources/BitmapResources.res
  4. BIN
      data/resources/image/BitmapResources/PadIcons/MethodView.png
  5. BIN
      data/resources/image/BitmapResources/PadIcons/ZoomControl.png
  6. 20
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
  7. 6
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  8. 92
      src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/ParallelStacksViewCommands.cs
  9. 94
      src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/SelectLanguageCommand.cs
  10. 0
      src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs
  11. 107
      src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerPad.cs
  12. 7
      src/AddIns/Debugger/Debugger.AddIn/Pads/LoadedModulesPad.cs
  13. 10
      src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
  14. 148
      src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs
  15. 4
      src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml
  16. 17
      src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml.cs
  17. 377
      src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs
  18. 53
      src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs
  19. 7
      src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs
  20. 11
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
  21. BIN
      src/Main/StartUp/Project/Resources/BitmapResources.resources

8
data/resources/StringResources.resx

@ -5935,7 +5935,13 @@ Shows the full callstack of the error.</comment> @@ -5935,7 +5935,13 @@ Shows the full callstack of the error.</comment>
<value>Object Graph</value>
</data>
<data name="MainWindow.Windows.Debug.ParallelStack" xml:space="preserve">
<value>Parallel Stack</value>
<value>Parallel Stacks</value>
</data>
<data name="MainWindow.Windows.Debug.ToggleMethodView" xml:space="preserve">
<value>Toggle Method View</value>
</data>
<data name="MainWindow.Windows.Debug.HideZoomControl" xml:space="preserve">
<value>Show/Hide Zoom Control</value>
</data>
<data name="MainWindow.Windows.Debug.RunToCursor" xml:space="preserve">
<value>Run to cursor</value>

BIN
data/resources/image/BitmapResources/BitmapResources-data/Icons.48x48.CurrentFrame.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

5
data/resources/image/BitmapResources/BitmapResources.res

@ -37,6 +37,10 @@ ProjectBrowser.WebReferenceFolder.Closed = ProjectBrowserIcons\WebReferenceFolde @@ -37,6 +37,10 @@ ProjectBrowser.WebReferenceFolder.Closed = ProjectBrowserIcons\WebReferenceFolde
ProjectBrowser.WebReferenceFolder.Open = ProjectBrowserIcons\WebReferenceFolder.Open.png
ProjectBrowser.WebReference = ProjectBrowserIcons\WebReference.png
#Parallel Stacks pad
ParallelStacks.MethodView = PadIcons\MethodView.png
ParallelStacks.ZoomControl = PadIcons\ZoomControl.png
#Output pad
OutputPad.Toolbar.ClearOutputWindow = OutputPadIcons\ClearOutputWindow.png
@ -226,6 +230,7 @@ Icons.16x16.OpenFileIcon = BitmapResources-data\Icons.1 @@ -226,6 +230,7 @@ Icons.16x16.OpenFileIcon = BitmapResources-data\Icons.1
Icons.16x16.HtmlElements.FieldSetElement = BitmapResources-data\Icons.16x16.HtmlElements.FieldSetElement.png
Icons.16x16.SplitWindow = BitmapResources-data\Icons.16x16.SplitWindow.png
Icons.16x16.DeleteHistory = BitmapResources-data\Icons.16x16.DeleteHistory.png
Icons.48x48.CurrentFrame = BitmapResources-data\Icons.48x48.CurrentFrame.png
#pad icons
PadIcons.ErrorList = PadIcons\ErrorList.png

BIN
data/resources/image/BitmapResources/PadIcons/MethodView.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
data/resources/image/BitmapResources/PadIcons/ZoomControl.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

20
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin

@ -128,7 +128,7 @@ @@ -128,7 +128,7 @@
category = "Debugger"
title = "${res:MainWindow.Windows.Debug.ParallelStack}"
icon = "PadIcons.Parallel"
class = "Debugger.AddIn.Pads.ParallelPad.ParallelStackPad"
class = "ICSharpCode.SharpDevelop.Gui.Pads.ParallelStackPad"
defaultPosition = "Bottom, Hidden" />
</Path>
@ -166,6 +166,24 @@ @@ -166,6 +166,24 @@
type="ComboBox" id="SelectLanguageCommand" />
</Path>
<Path name="/SharpDevelop/Pads/ParallelStacksPad/ToolBar">
<ToolbarItem id="View" type="ComboBox" class="ICSharpCode.SharpDevelop.Gui.Pads.ParallelStacksViewCommand"/>
<ToolbarItem id="Separator" type="Separator"/>
<ToolbarItem
id="MethodView"
type="CheckBox"
tooltip="${res:MainWindow.Windows.Debug.ToggleMethodView}"
icon="ParallelStacks.MethodView"
class="ICSharpCode.SharpDevelop.Gui.Pads.ToggleMethodViewCommand"/>
<ToolbarItem
id="ZoomControl"
type="CheckBox"
tooltip="${res:MainWindow.Windows.Debug.HideZoomControl}"
icon="ParallelStacks.ZoomControl"
class="ICSharpCode.SharpDevelop.Gui.Pads.ShowZoomControlCommand"/>
/>
</Path>
<Path name="/SharpDevelop/Services/DebuggerService/Visualizers">
<Class class="Debugger.AddIn.Visualizers.TextVisualizerDescriptor" />
<Class class="Debugger.AddIn.Visualizers.XmlVisualizerDescriptor" />

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

@ -104,6 +104,9 @@ @@ -104,6 +104,9 @@
<DependentUpon>CallStackPad.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Pads\Commands\ParallelStacksViewCommands.cs" />
<Compile Include="Pads\Commands\SelectLanguageCommand.cs" />
<Compile Include="Pads\Commands\WatchPadCommands.cs" />
<Compile Include="Pads\Controls\ConditionCell.xaml.cs">
<DependentUpon>ConditionCell.xaml</DependentUpon>
</Compile>
@ -150,8 +153,6 @@ @@ -150,8 +153,6 @@
<DependentUpon>DebuggingSymbolsPanel.cs</DependentUpon>
</Compile>
<Compile Include="Pads\ObjectGraphPad.cs" />
<Compile Include="Pads\SelectLanguageCommand.cs" />
<Compile Include="Pads\WatchPadCommands.cs" />
<Compile Include="Pads\BreakPointsPad.cs" />
<Compile Include="Pads\ConsolePad.cs">
<SubType>UserControl</SubType>
@ -398,6 +399,7 @@ @@ -398,6 +399,7 @@
<Name>ICSharpCode.Core.WinForms</Name>
<Private>False</Private>
</ProjectReference>
<Folder Include="Pads\Commands" />
<Folder Include="Pads\Controls" />
<Folder Include="Pads\ParallelPad" />
<Folder Include="Visualizers\Graph" />

92
src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/ParallelStacksViewCommands.cs

@ -0,0 +1,92 @@ @@ -0,0 +1,92 @@
// 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.Controls;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public sealed class ShowZoomControlCommand : AbstractCheckableMenuCommand
{
ParallelStackPad pad;
public override object Owner {
get { return base.Owner; }
set {
if (!(value is ParallelStackPad))
throw new Exception("Owner has to be a AbstractConsolePad");
pad = value as ParallelStackPad;
base.Owner = value;
}
}
public override bool IsChecked {
get { return pad.IsZoomControlVisible; }
set { pad.IsZoomControlVisible = value; }
}
public override void Run()
{
IsChecked = !IsChecked;
}
}
public sealed class ToggleMethodViewCommand : AbstractCheckableMenuCommand
{
ParallelStackPad pad;
public override object Owner {
get { return base.Owner; }
set {
if (!(value is ParallelStackPad))
throw new Exception("Owner has to be a AbstractConsolePad");
pad = value as ParallelStackPad;
base.Owner = value;
}
}
public override bool IsChecked {
get { return pad.IsMethodView; }
set { pad.IsMethodView = value; }
}
public override void Run()
{
IsChecked = !IsChecked;
}
}
public sealed class ParallelStacksViewCommand : AbstractComboBoxCommand
{
ParallelStackPad pad;
ComboBox box;
protected override void OnOwnerChanged(EventArgs e)
{
this.pad = this.Owner as ParallelStackPad;
if (this.pad == null)
return;
box = this.ComboBox as ComboBox;
if (this.box == null)
return;
foreach (var name in Enum.GetNames(typeof(ParallelStacksView)))
box.Items.Add(name);
box.SelectedIndex = 0;
base.OnOwnerChanged(e);
}
public override void Run()
{
if (this.pad != null && this.box != null) {
pad.ParallelStacksView = (ParallelStacksView)Enum.Parse(typeof(ParallelStacksView), box.SelectedValue.ToString());
}
base.Run();
}
}
}

94
src/AddIns/Debugger/Debugger.AddIn/Pads/SelectLanguageCommand.cs → src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/SelectLanguageCommand.cs

@ -1,47 +1,47 @@ @@ -1,47 +1,47 @@
// 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)
using System;
using Debugger;
using Debugger.AddIn;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
using System.Windows.Controls;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
class SelectLanguageCommand : AbstractComboBoxCommand
{
ConsolePad pad;
ComboBox box;
protected override void OnOwnerChanged(EventArgs e)
{
this.pad = this.Owner as ConsolePad;
if (this.pad == null)
return;
box = this.ComboBox as ComboBox;
if (this.box == null)
return;
foreach (var name in Enum.GetNames(typeof(SupportedLanguage)))
box.Items.Add(name);
box.SelectedIndex = 0;
base.OnOwnerChanged(e);
}
public override void Run()
{
if (this.pad != null && this.box != null) {
pad.SelectedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), box.SelectedValue.ToString());
}
base.Run();
}
}
}
// 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)
using System;
using Debugger;
using Debugger.AddIn;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
using System.Windows.Controls;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
class SelectLanguageCommand : AbstractComboBoxCommand
{
ConsolePad pad;
ComboBox box;
protected override void OnOwnerChanged(EventArgs e)
{
this.pad = this.Owner as ConsolePad;
if (this.pad == null)
return;
box = this.ComboBox as ComboBox;
if (this.box == null)
return;
foreach (var name in Enum.GetNames(typeof(SupportedLanguage)))
box.Items.Add(name);
box.SelectedIndex = 0;
base.OnOwnerChanged(e);
}
public override void Run()
{
if (this.pad != null && this.box != null) {
pad.SelectedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), box.SelectedValue.ToString());
}
base.Run();
}
}
}

0
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadCommands.cs → src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs

107
src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerPad.cs

@ -1,41 +1,66 @@ @@ -1,41 +1,66 @@
// 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)
using Debugger;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public abstract class DebuggerPad: AbstractPadContent
{
protected WindowsDebugger debugger;
public DebuggerPad()
{
debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
InitializeComponents();
debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) {
SelectProcess(e.Process);
};
SelectProcess(debugger.DebuggedProcess);
}
protected virtual void InitializeComponents()
{
}
protected virtual void SelectProcess(Process process)
{
}
public virtual void RefreshPad()
{
}
}
}
// 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)
using System.Windows.Controls;
using Debugger;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public abstract class DebuggerPad : AbstractPadContent
{
protected DockPanel panel;
ToolBar toolbar;
protected WindowsDebugger debugger;
public override object Control {
get {
return panel;
}
}
public DebuggerPad()
{
// UI
this.panel = new DockPanel();
this.toolbar = BuildToolBar();
if (this.toolbar != null) {
this.toolbar.SetValue(DockPanel.DockProperty, Dock.Top);
this.panel.Children.Add(toolbar);
}
// logic
debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
InitializeComponents();
debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) {
SelectProcess(e.Process);
};
SelectProcess(debugger.DebuggedProcess);
}
protected virtual void InitializeComponents()
{
}
protected virtual void SelectProcess(Process process)
{
}
public virtual void RefreshPad()
{
}
protected virtual ToolBar BuildToolBar()
{
return null;
}
}
}

7
src/AddIns/Debugger/Debugger.AddIn/Pads/LoadedModulesPad.cs

@ -17,15 +17,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -17,15 +17,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
SimpleListViewControl loadedModulesList;
Process debuggedProcess;
public override object Control {
get {
return loadedModulesList;
}
}
protected override void InitializeComponents()
{
loadedModulesList = new SimpleListViewControl();
panel.Children.Add(loadedModulesList);
RedrawContent();
ResourceService.LanguageChanged += delegate { RedrawContent(); };
}

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

@ -26,15 +26,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -26,15 +26,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
get { return instance; }
}
/// <remarks>
/// This is not used anywhere, but it is neccessary to be overridden in children of AbstractPadContent.
/// </remarks>
public override object Control {
get {
return localVarList;
}
}
public Process Process {
get { return debuggedProcess; }
}
@ -42,6 +33,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -42,6 +33,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
protected override void InitializeComponents()
{
localVarList = new WatchList();
panel.Children.Add(localVarList);
}
protected override void SelectProcess(Process process)

148
src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs

@ -1,76 +1,72 @@ @@ -1,76 +1,72 @@
// 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)
using ICSharpCode.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Debugger;
using Debugger.AddIn.Visualizers.Graph;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
/// <summary>
/// Description of ObjectGraphPad.
/// </summary>
public class ObjectGraphPad : DebuggerPad
{
Process debuggedProcess;
ObjectGraphControl objectGraphControl;
static ObjectGraphPad instance;
public ObjectGraphPad()
{
instance = this;
}
/// <remarks>Always check if Instance is null, might be null if pad is not opened!</remarks>
public static ObjectGraphPad Instance {
get { return instance; }
}
protected override void InitializeComponents()
{
objectGraphControl = new ObjectGraphControl();
}
public override object Control {
get {
return objectGraphControl;
}
}
public override void RefreshPad()
{
// BUG: if pad window is undocked and floats standalone, IsVisible == false (so pad won't refresh)
// REQUEST: need to refresh when pad becomes visible -> VisibleChanged event?
if (!objectGraphControl.IsVisible)
{
return;
}
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) {
this.objectGraphControl.Clear();
return;
}
this.objectGraphControl.Refresh();
}
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();
}
}
}
// 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)
using ICSharpCode.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Debugger;
using Debugger.AddIn.Visualizers.Graph;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
/// <summary>
/// Description of ObjectGraphPad.
/// </summary>
public class ObjectGraphPad : DebuggerPad
{
Process debuggedProcess;
ObjectGraphControl objectGraphControl;
static ObjectGraphPad instance;
public ObjectGraphPad()
{
instance = this;
}
/// <remarks>Always check if Instance is null, might be null if pad is not opened!</remarks>
public static ObjectGraphPad Instance {
get { return instance; }
}
protected override void InitializeComponents()
{
objectGraphControl = new ObjectGraphControl();
panel.Children.Add(objectGraphControl);
}
public override void RefreshPad()
{
// BUG: if pad window is undocked and floats standalone, IsVisible == false (so pad won't refresh)
// REQUEST: need to refresh when pad becomes visible -> VisibleChanged event?
if (!objectGraphControl.IsVisible)
{
return;
}
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) {
this.objectGraphControl.Clear();
return;
}
this.objectGraphControl.Refresh();
}
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();
}
}
}

4
src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml

@ -79,11 +79,11 @@ @@ -79,11 +79,11 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="40" />
Width="Auto" />
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<Canvas
<Canvas x:Name="ZoomControl" Width="40" Visibility="Hidden"
Margin="3,3">
<TextBlock
Foreground="LightGray"

17
src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml.cs

@ -32,6 +32,21 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -32,6 +32,21 @@ namespace Debugger.AddIn.Pads.ParallelPad
public void SetGraph(ParallelStacksGraph graph)
{
this.ParallelStacksLayout.Graph = graph;
if (graph == null)
this.ParallelStacksLayout.CancelLayout();
else
this.ParallelStacksLayout.Relayout();
}
public bool IsZoomControlVisible {
get { return ZoomControl.Visibility == Visibility.Visible; }
set {
if (value)
ZoomControl.Visibility = Visibility.Visible;
else
ZoomControl.Visibility = Visibility.Hidden;
}
}
#region Pan
@ -68,7 +83,7 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -68,7 +83,7 @@ namespace Debugger.AddIn.Pads.ParallelPad
Cursor = Cursors.SizeAll;
var point = e.GetPosition(drawingSurface);
Vector v = dragStartedPoint - point;
Vector v = point - dragStartedPoint;
translate.X += v.X / 200;
translate.Y += v.Y / 200;
e.Handled = true;

377
src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs

@ -10,33 +10,39 @@ using System.Windows; @@ -10,33 +10,39 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Debugger;
using Debugger.AddIn.Pads.ParallelPad;
using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Pads.ParallelPad
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public enum ParallelStacksView
{
Threads,
Tasks
}
public class ParallelStackPad : DebuggerPad
{
private DrawSurface surface;
private Process debuggedProcess;
private ParallelStacksGraph graph;
private List<ThreadStack> currentThreadStacks = new List<ThreadStack>();
private ParallelStacksView parallelStacksView;
private StackFrame selectedFrame;
private bool isMethodView;
#region Overrides
protected override void InitializeComponents()
{
surface = new DrawSurface();
}
public override object Control {
get {
return surface;
}
panel.Children.Add(surface);
}
protected override void SelectProcess(Process process)
@ -60,54 +66,125 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -60,54 +66,125 @@ namespace Debugger.AddIn.Pads.ParallelPad
if (debuggedProcess == null || debuggedProcess.IsRunning) {
return;
}
OnReset(null, EventArgs.Empty);
using(new PrintTimes("Parallel stack refresh")) {
try {
OnReset(null, EventArgs.Empty);
// create all simple ThreadStacks
foreach (Thread thread in debuggedProcess.Threads) {
if (debuggedProcess.IsPaused) {
Utils.DoEvents(debuggedProcess);
if (ParallelStacksView == ParallelStacksView.Threads)
{
if (isMethodView)
{
// build method view for threads
using(new PrintTimes("Parallel stack - method view + threads refresh")) {
try {
// create all simple ThreadStacks
foreach (Thread thread in debuggedProcess.Threads) {
if (debuggedProcess.IsPaused) {
Utils.DoEvents(debuggedProcess);
}
CreateThreadStack(thread);
}
CreateMethodViewStacks();
}
catch(AbortedBecauseDebuggeeResumedException) { }
catch(System.Exception) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
throw;
}
}
CreateThreadStack(thread);
}
CreateCommonStacks();
}
catch(AbortedBecauseDebuggeeResumedException) { }
catch(System.Exception) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
throw;
else
{
// normal view
using(new PrintTimes("Parallel stack - threads refresh")) {
try {
// create all simple ThreadStacks
foreach (Thread thread in debuggedProcess.Threads) {
if (debuggedProcess.IsPaused) {
Utils.DoEvents(debuggedProcess);
}
CreateThreadStack(thread);
}
CreateCommonStacks();
}
catch(AbortedBecauseDebuggeeResumedException) { }
catch(System.Exception) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
throw;
}
}
}
}
}
using(new PrintTimes("Graph refresh")) {
// paint the ThreadStaks
graph = new ParallelStacksGraph();
foreach (var stack in this.currentThreadStacks)
{
if (stack == null)
continue;
if (stack.ThreadStackParent != null &&
(stack.ThreadStackChildren == null || stack.ThreadStackChildren.Count == 0))
continue;
graph.AddVertex(stack);
using(new PrintTimes("Graph refresh")) {
// paint the ThreadStaks
graph = new ParallelStacksGraph();
foreach (var stack in this.currentThreadStacks.FindAll(ts => ts.ThreadStackParent == null))
{
graph.AddVertex(stack);
// add the children
AddChildren(stack);
}
// add the children
AddChildren(stack);
surface.SetGraph(graph);
}
}
else
{
MessageBox.Show(
"Not yet supported", "Tasks view", MessageBoxButton.OK, MessageBoxImage.Information);
surface.SetGraph(graph);
// TODO : hadle tasks here
if (isMethodView)
{
// build method view for tasks
}
else
{
// normal
}
surface.SetGraph(new ParallelStacksGraph());
}
}
protected override ToolBar BuildToolBar()
{
return ToolBarService.CreateToolBar(this, "/SharpDevelop/Pads/ParallelStacksPad/ToolBar");
}
#endregion
#region Public Properties
public ParallelStacksView ParallelStacksView {
get { return parallelStacksView; }
set {
parallelStacksView = value;
RefreshPad();
}
}
public bool IsMethodView {
get { return isMethodView; }
set {
isMethodView = value;
RefreshPad();
}
}
public bool IsZoomControlVisible {
get { return surface.IsZoomControlVisible; }
set { surface.IsZoomControlVisible = value; }
}
#endregion
#region Private Methods
private void OnReset(object sender, EventArgs e)
@ -260,7 +337,8 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -260,7 +337,8 @@ namespace Debugger.AddIn.Pads.ParallelPad
commonParent.UpdateThreadIds(threadIds.ToArray());
commonParent.ItemCollection = parentItems.ToObservable();
commonParent.Process = debuggedProcess;
commonParent.FrameSelected += threadStack_FrameSelected;
commonParent.StackSelected += OnThreadStackSelected;
commonParent.FrameSelected += OnFrameSelected;
commonParent.IsSelected = commonParent.ThreadIds.Contains(debuggedProcess.SelectedThread.ID);
// add new children
foreach (var stack in listOfCurrentStacks) {
@ -283,17 +361,7 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -283,17 +361,7 @@ namespace Debugger.AddIn.Pads.ParallelPad
// update thread ids
var parent = commonParent.ThreadStackParent;
if (parent != null) {
if (parent.ThreadIds != null)
{
var list = new List<uint>();
foreach (uint id in commonParent.ThreadIds) {
if (!parent.ThreadIds.Contains(id)) {
list.Add(id);
}
}
parent.UpdateThreadIds(list.ToArray());
}
parent.UpdateThreadIds(commonParent.ThreadIds.ToArray());
}
stack.ThreadStackParent = commonParent;
@ -324,6 +392,73 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -324,6 +392,73 @@ namespace Debugger.AddIn.Pads.ParallelPad
break;
}
}
private void CreateMethodViewStacks()
{
var list =
new List<Tuple<ObservableCollection<ExpandoObject>, ObservableCollection<ExpandoObject>, List<uint>>>();
// find all threadstacks that contains the selected frame
for (int i = currentThreadStacks.Count - 1; i >= 0; --i) {
var tuple = currentThreadStacks[i].ItemCollection.SplitStack(selectedFrame, currentThreadStacks[i].ThreadIds);
if (tuple != null)
list.Add(tuple);
}
currentThreadStacks.Clear();
// common
ThreadStack common = new ThreadStack();
var observ = new ObservableCollection<ExpandoObject>();
bool dummy = false;
dynamic obj = CreateItem(selectedFrame, selectedFrame.Thread, ref dummy);
obj.Image = PresentationResourceService.GetImage("Icons.48x48.CurrentFrame").Source;
observ.Add(obj);
common.ItemCollection = observ;
common.StackSelected += OnThreadStackSelected;
common.FrameSelected += OnFrameSelected;
common.UpdateThreadIds(selectedFrame.Thread.ID);
common.Process = debuggedProcess;
common.ThreadStackChildren = new List<ThreadStack>();
// for all thread stacks, split them in 2 :
// one that invokes the method frame, second that get's invoked by current method frame
foreach (var tuple in list) {
// add top
if (tuple.Item1.Count > 0)
{
ThreadStack topStack = new ThreadStack();
topStack.ItemCollection = tuple.Item1;
topStack.StackSelected += OnThreadStackSelected;
topStack.FrameSelected += OnFrameSelected;
topStack.UpdateThreadIds(tuple.Item3.ToArray());
common.UpdateThreadIds(tuple.Item3.ToArray());
topStack.Process = debuggedProcess;
topStack.ThreadStackParent = common;
currentThreadStacks.Add(topStack);
common.ThreadStackChildren.Add(topStack);
}
// add bottom
if(tuple.Item2.Count > 0)
{
ThreadStack bottomStack = new ThreadStack();
bottomStack.ItemCollection = tuple.Item2;
bottomStack.StackSelected += OnThreadStackSelected;
bottomStack.FrameSelected += OnFrameSelected;
bottomStack.UpdateThreadIds(tuple.Item3.ToArray());
bottomStack.Process = debuggedProcess;
bottomStack.ThreadStackChildren = new List<ThreadStack>();
bottomStack.ThreadStackChildren.Add(common);
currentThreadStacks.Add(bottomStack);
}
}
currentThreadStacks.Add(common);
common.IsSelected = true;
}
private void CreateThreadStack(Thread thread)
{
@ -332,22 +467,19 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -332,22 +467,19 @@ namespace Debugger.AddIn.Pads.ParallelPad
return;
ThreadStack threadStack = new ThreadStack();
threadStack.FrameSelected += threadStack_FrameSelected;
threadStack.StackSelected += OnThreadStackSelected;
threadStack.FrameSelected += OnFrameSelected;
threadStack.UpdateThreadIds(thread.ID);
threadStack.Process = debuggedProcess;
currentThreadStacks.Add(threadStack);
threadStack.ItemCollection = items;
if (debuggedProcess.SelectedThread != null)
if (debuggedProcess.SelectedThread != null) {
threadStack.IsSelected = threadStack.ThreadIds.Contains(debuggedProcess.SelectedThread.ID);
}
private void threadStack_FrameSelected(object sender, EventArgs e)
{
foreach (var ts in this.currentThreadStacks) {
ts.IsSelected = false;
ts.ClearImages();
if (selectedFrame == null)
selectedFrame = debuggedProcess.SelectedStackFrame;
}
currentThreadStacks.Add(threadStack);
}
private ObservableCollection<ExpandoObject> CreateItems(Thread thread)
@ -355,34 +487,9 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -355,34 +487,9 @@ namespace Debugger.AddIn.Pads.ParallelPad
bool lastItemIsExternalMethod = false;
var result = new ObservableCollection<ExpandoObject>();
foreach (StackFrame frame in thread.GetCallstack(100)) {
dynamic obj = new ExpandoObject();
string fullName;
if (frame.HasSymbols) {
// Show the method in the list
fullName = frame.GetMethodName();
lastItemIsExternalMethod = false;
obj.FontWeight = FontWeights.Normal;
obj.Foreground = Brushes.Black;
} else {
// Show [External methods] in the list
if (lastItemIsExternalMethod) continue;
fullName = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods").Trim();
obj.FontWeight = FontWeights.Normal;
obj.Foreground = Brushes.Gray;
lastItemIsExternalMethod = true;
}
if (thread.SelectedStackFrame != null &&
thread.ID == debuggedProcess.SelectedThread.ID &&
thread.SelectedStackFrame.IP == frame.IP &&
thread.SelectedStackFrame.GetMethodName() == frame.GetMethodName())
obj.Image = PresentationResourceService.GetImage("Bookmarks.CurrentLine").Source;
else
obj.Image = null;
obj.MethodName = fullName;
result.Add(obj);
dynamic obj = CreateItem(frame, thread, ref lastItemIsExternalMethod);
if (obj != null)
result.Add(obj);
}
Utils.DoEvents(debuggedProcess);
@ -390,6 +497,61 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -390,6 +497,61 @@ namespace Debugger.AddIn.Pads.ParallelPad
return result;
}
private ExpandoObject CreateItem(StackFrame frame, Thread thread, ref bool lastItemIsExternalMethod)
{
dynamic obj = new ExpandoObject();
string fullName;
if (frame.HasSymbols) {
// Show the method in the list
fullName = frame.GetMethodName();
lastItemIsExternalMethod = false;
obj.FontWeight = FontWeights.Normal;
obj.Foreground = Brushes.Black;
} else {
// Show [External methods] in the list
if (lastItemIsExternalMethod) return null;
fullName = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods").Trim();
obj.FontWeight = FontWeights.Normal;
obj.Foreground = Brushes.Gray;
lastItemIsExternalMethod = true;
}
if (thread.SelectedStackFrame != null &&
thread.ID == debuggedProcess.SelectedThread.ID &&
thread.SelectedStackFrame.IP == frame.IP &&
thread.SelectedStackFrame.GetMethodName() == frame.GetMethodName()) {
obj.Image = PresentationResourceService.GetImage("Bookmarks.CurrentLine").Source;
obj.IsRunningStackFrame = true;
}
else {
if (selectedFrame != null && frame.GetMethodName() == selectedFrame.GetMethodName())
obj.Image = PresentationResourceService.GetImage("Icons.48x48.CurrentFrame").Source;
else
obj.Image = null;
obj.IsRunningStackFrame = false;
}
obj.MethodName = fullName;
return obj;
}
private void OnThreadStackSelected(object sender, EventArgs e)
{
foreach (var ts in this.currentThreadStacks) {
ts.IsSelected = false;
ts.ClearImages();
}
}
private void OnFrameSelected(object sender, FrameSelectedEventArgs e)
{
selectedFrame = e.Item;
if (isMethodView)
RefreshPad();
}
#endregion
}
@ -434,5 +596,34 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -434,5 +596,34 @@ namespace Debugger.AddIn.Pads.ParallelPad
return result;
}
internal static Tuple<ObservableCollection<T>, ObservableCollection<T>, List<uint>>
SplitStack<T>(this ObservableCollection<T> source, StackFrame frame, List<uint> threadIds)
{
var bottom = new ObservableCollection<T>();
var top = new ObservableCollection<T>();
int found = 0;
foreach (dynamic item in source)
{
if (item.MethodName == frame.GetMethodName())
found = 1;
if (found >= 1) {
if(found > 1)
bottom.Add(item);
found++;
}
else
top.Add(item);
}
var result =
new Tuple<ObservableCollection<T>, ObservableCollection<T>, List<uint>>(top, bottom, threadIds);
return found > 1 ? result : null;
}
}
}

53
src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs

@ -4,7 +4,6 @@ @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Dynamic;
using System.Windows;
using System.Windows.Controls;
@ -12,12 +11,24 @@ using System.Windows.Input; @@ -12,12 +11,24 @@ using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Pads.ParallelPad
{
public class FrameSelectedEventArgs : EventArgs
{
public StackFrame Item {
get;
private set;
}
public FrameSelectedEventArgs(StackFrame item)
{
Item = item;
}
}
public partial class ThreadStack : UserControl
{
public static SolidColorBrush SelectedBrush = new SolidColorBrush(Color.FromRgb(84, 169, 255));
@ -26,7 +37,9 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -26,7 +37,9 @@ namespace Debugger.AddIn.Pads.ParallelPad
DependencyProperty.Register("IsSelected", typeof(bool), typeof(ThreadStack),
new FrameworkPropertyMetadata());
public event EventHandler FrameSelected;
public event EventHandler StackSelected;
public event EventHandler<FrameSelectedEventArgs> FrameSelected;
private ObservableCollection<ExpandoObject> itemCollection = new ObservableCollection<ExpandoObject>();
@ -93,7 +106,13 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -93,7 +106,13 @@ namespace Debugger.AddIn.Pads.ParallelPad
public void UpdateThreadIds(params uint[] threadIds)
{
this.threadIds.AddRange(threadIds);
var list = new List<uint>();
foreach (uint id in threadIds) {
if (!this.threadIds.Contains(id)) {
list.Add(id);
}
}
this.threadIds.AddRange(list);
if (this.threadIds.Count > 1)
this.HeaderText.Text = this.threadIds.Count.ToString() + " Threads";
@ -104,7 +123,8 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -104,7 +123,8 @@ namespace Debugger.AddIn.Pads.ParallelPad
public void ClearImages()
{
foreach(dynamic item in itemCollection) {
item.Image = null;
if (!item.IsRunningStackFrame)
item.Image = null;
}
}
@ -164,20 +184,29 @@ namespace Debugger.AddIn.Pads.ParallelPad @@ -164,20 +184,29 @@ namespace Debugger.AddIn.Pads.ParallelPad
if (thread == null)
return;
if (FrameSelected != null)
FrameSelected(this, EventArgs.Empty);
if (StackSelected != null)
StackSelected(this, EventArgs.Empty);
this.IsSelected = true;
dynamic obj = selectedItem;
Process.SelectedThread = thread;
foreach(var frame in thread.Callstack)
{
if (frame.GetMethodName() == obj.MethodName)
{
Process.SelectedThread.SelectedStackFrame = frame;
obj.Image = PresentationResourceService.GetImage("Bookmarks.CurrentLine").Source;
((WindowsDebugger)DebuggerService.CurrentDebugger).JumpToCurrentLine();
if (!obj.IsRunningStackFrame)
obj.Image = PresentationResourceService.GetImage("Icons.48x48.CurrentFrame").Source;
SourcecodeSegment nextStatement = frame.NextStatement;
if (nextStatement != null) {
FileService.JumpToFilePosition(
nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn);
}
if (FrameSelected != null)
FrameSelected(this, new FrameSelectedEventArgs(frame));
break;
}
}

7
src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs

@ -20,17 +20,12 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -20,17 +20,12 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
SimpleListViewControl runningThreadsList;
Process debuggedProcess;
public override object Control {
get {
return runningThreadsList;
}
}
protected override void InitializeComponents()
{
runningThreadsList = new SimpleListViewControl();
runningThreadsList.ContextMenu = CreateContextMenuStrip();
runningThreadsList.ItemActivated += RunningThreadsListItemActivate;
panel.Children.Add(runningThreadsList);
RedrawContent();
ResourceService.LanguageChanged += delegate { RedrawContent(); };

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

@ -35,15 +35,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -35,15 +35,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
instance = this;
}
/// <remarks>
/// This is not used anywhere, but it is neccessary to be overridden in children of AbstractPadContent.
/// </remarks>
public override object Control {
get {
return watchList;
}
}
public Process Process {
get { return debuggedProcess; }
}
@ -58,6 +49,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -58,6 +49,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
watchList.DragEnter += watchList_DragOver;
watchList.Drop += watchList_Drop;
watchList.KeyUp += watchList_KeyUp;
panel.Children.Add(watchList);
}
void watchList_KeyUp(object sender, KeyEventArgs e)

BIN
src/Main/StartUp/Project/Resources/BitmapResources.resources

Binary file not shown.
Loading…
Cancel
Save