diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs index b2a0e3bc53..65566eeb81 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs @@ -164,13 +164,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads } } - string GetFullName(StackFrame frame) + internal static 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(frame.MethodInfo.DeclaringType.FullName); name.Append('.'); name.Append(frame.MethodInfo.Name); if (showArgumentNames || showArgumentValues) { diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml index 843236079d..d6d7dc7bdc 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml @@ -43,7 +43,7 @@ @@ -127,6 +127,10 @@ diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml.cs index 6d58b1ccf2..7942fba9cb 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/DrawSurface.xaml.cs @@ -32,7 +32,6 @@ namespace Debugger.AddIn.Pads.ParallelPad public void SetGraph(ParallelStacksGraph graph) { this.ParallelStacksLayout.Graph = graph; - this.ParallelStacksLayout.Relayout(); } #region Pan @@ -50,10 +49,10 @@ namespace Debugger.AddIn.Pads.ParallelPad void DrawSurface_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { + drawingSurface.ReleaseMouseCapture(); if (e.OriginalSource is Slider || e.OriginalSource is Button) return; - drawingSurface.ReleaseMouseCapture(); this.PreviewMouseMove -= DrawSurface_PreviewMouseMove; Cursor = Cursors.Arrow; } @@ -67,10 +66,11 @@ namespace Debugger.AddIn.Pads.ParallelPad if (e.OriginalSource is Slider || e.OriginalSource is Button) return; - Cursor = Cursors.ScrollAll; - Vector v = dragStartedPoint - e.GetPosition(drawingSurface); - translate.X = v.X / 5; - translate.Y = v.Y / 5; + Cursor = Cursors.SizeAll; + var point = e.GetPosition(drawingSurface); + Vector v = dragStartedPoint - point; + translate.X += v.X / 200; + translate.Y += v.Y / 200; e.Handled = true; } } @@ -98,6 +98,9 @@ namespace Debugger.AddIn.Pads.ParallelPad void Reset_Click(object sender, RoutedEventArgs e) { this.SliderControl.Value = 5; + + translate.X = 0; + translate.Y = 0; } #endregion diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs index 1c4983eb2c..7630cc34c4 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs @@ -12,6 +12,7 @@ using System.Windows.Media; using Debugger.AddIn.TreeModel; using ICSharpCode.Core; +using ICSharpCode.Core.Presentation; using ICSharpCode.SharpDevelop.Debugging; using ICSharpCode.SharpDevelop.Gui.Pads; using ICSharpCode.SharpDevelop.Services; @@ -68,7 +69,7 @@ namespace Debugger.AddIn.Pads.ParallelPad return; } - using(new PrintTimes("Threads refresh")) { + using(new PrintTimes("Parallel stack refresh")) { try { OnReset(null, EventArgs.Empty); // create all simple ThreadStacks @@ -90,11 +91,13 @@ namespace Debugger.AddIn.Pads.ParallelPad 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 && @@ -105,13 +108,14 @@ namespace Debugger.AddIn.Pads.ParallelPad // add the children AddChildren(stack); - } + } surface.SetGraph(graph); } } ParallelStacksGraph graph; + void AddChildren(ThreadStack parent) { if(parent.ThreadStackChildren == null || parent.ThreadStackChildren.Length == 0) @@ -245,6 +249,7 @@ namespace Debugger.AddIn.Pads.ParallelPad commonParent.ThreadIds = threadIds; commonParent.ItemCollection = parentItems.ToObservable(); commonParent.Process = debuggedProcess; + commonParent.FrameSelected += threadStack_FrameSelected; commonParent.IsSelected = commonParent.ThreadIds.Contains(debuggedProcess.SelectedThread.ID); // add new children foreach (var stack in listOfCurrentStacks) { @@ -283,6 +288,7 @@ namespace Debugger.AddIn.Pads.ParallelPad return; ThreadStack threadStack = new ThreadStack(); + threadStack.FrameSelected += threadStack_FrameSelected; threadStack.ThreadIds = new List(); threadStack.ThreadIds.Add(thread.ID); threadStack.Process = debuggedProcess; @@ -292,6 +298,14 @@ namespace Debugger.AddIn.Pads.ParallelPad if (debuggedProcess.SelectedThread != null) threadStack.IsSelected = threadStack.ThreadIds.Contains(debuggedProcess.SelectedThread.ID); } + + void threadStack_FrameSelected(object sender, EventArgs e) + { + foreach (var ts in this.currentThreadStacks) { + ts.IsSelected = false; + ts.ClearImages(); + } + } private ObservableCollection CreateItems(Thread thread) { @@ -315,7 +329,14 @@ namespace Debugger.AddIn.Pads.ParallelPad lastItemIsExternalMethod = true; } - obj.Image = null; + 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); @@ -331,6 +352,9 @@ namespace Debugger.AddIn.Pads.ParallelPad { internal static string GetMethodName(this StackFrame frame) { + if (frame == null) + return null; + StringBuilder name = new StringBuilder(); name.Append(frame.MethodInfo.DeclaringType.FullName); name.Append('.'); diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml index 8a21fbebe2..5d717dce79 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml @@ -78,16 +78,26 @@ + + + - - + diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs index 89ea9c79a4..8c056a4fc9 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs @@ -10,6 +10,11 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using ICSharpCode.Core.Presentation; +using ICSharpCode.SharpDevelop.Debugging; +using ICSharpCode.SharpDevelop.Gui.Pads; +using ICSharpCode.SharpDevelop.Services; + namespace Debugger.AddIn.Pads.ParallelPad { public partial class ThreadStack : UserControl @@ -20,15 +25,20 @@ namespace Debugger.AddIn.Pads.ParallelPad DependencyProperty.Register("IsSelected", typeof(bool), typeof(ThreadStack), new FrameworkPropertyMetadata()); + + public event EventHandler FrameSelected; + private ObservableCollection itemCollection = new ObservableCollection(); + private ToolTip toolTip = new ToolTip(); + public ThreadStack() { InitializeComponent(); + ToolTip = toolTip; + ToolTipOpening += new ToolTipEventHandler(OnToolTipOpening); } - internal bool IsAdded { get; set; } - public Process Process { get; set; } public bool IsSelected { @@ -71,7 +81,14 @@ namespace Debugger.AddIn.Pads.ParallelPad } } - private void SelectParent(bool isSelected) + public void ClearImages() + { + foreach(dynamic item in itemCollection) { + item.Image = null; + } + } + + void SelectParent(bool isSelected) { var ts = this.ThreadStackParent; while(ts != null) { @@ -99,9 +116,18 @@ namespace Debugger.AddIn.Pads.ParallelPad void SelectFrame(uint threadId, ExpandoObject selectedItem) { + if (selectedItem == null) + return; + var thread = Process.Threads.Find(t => t.ID == threadId); if (thread == null) return; + + if (FrameSelected != null) + FrameSelected(this, EventArgs.Empty); + + this.IsSelected = true; + dynamic obj = selectedItem; Process.SelectedThread = thread; foreach(var frame in thread.Callstack) @@ -109,11 +135,11 @@ namespace Debugger.AddIn.Pads.ParallelPad if (frame.GetMethodName() == obj.MethodName) { Process.SelectedThread.SelectedStackFrame = frame; + obj.Image = PresentationResourceService.GetImage("Bookmarks.CurrentLine").Source; + ((WindowsDebugger)DebuggerService.CurrentDebugger).JumpToCurrentLine(); break; } } - - Process.OnPaused(); } void Datagrid_MouseRightButtonUp(object sender, MouseButtonEventArgs e) @@ -138,7 +164,7 @@ namespace Debugger.AddIn.Pads.ParallelPad MenuItem m = new MenuItem(); m.IsCheckable = true; m.IsChecked = id == Process.SelectedThread.ID; - m.Checked += delegate(object sender, RoutedEventArgs e) { + m.Click += delegate(object sender, RoutedEventArgs e) { var menuItem = e.OriginalSource as MenuItem; SelectFrame((uint)menuItem.Tag, item); }; @@ -150,5 +176,36 @@ namespace Debugger.AddIn.Pads.ParallelPad return menu; } + + void OnToolTipOpening(object sender, ToolTipEventArgs e) + { + StackPanel panel = new StackPanel(); + + dynamic selectedItem = datagrid.SelectedItem; + if (selectedItem == null) { + panel.Children.Add(new TextBlock { Text = "No item selected" }); + this.toolTip.Content = panel; + return; + } + + foreach(var thread in Process.Threads) + { + if (ThreadIds.Contains(thread.ID)) + { + foreach (var frame in thread.Callstack) + { + if (selectedItem.MethodName == frame.GetMethodName()) + { + // TODO : get method parameter values + TextBlock tb = new TextBlock(); + tb.Text = thread.ID + ": " + CallStackPadContent.GetFullName(frame); + panel.Children.Add(tb); + } + } + } + } + + this.toolTip.Content = panel; + } } } \ No newline at end of file