diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin index fc4362a7ab..2b88c401e2 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin +++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin @@ -75,6 +75,16 @@ label = "${res:MainWindow.Windows.Debug.DebugExecutable}" class = "Debugger.AddIn.DebugExecutableMenuCommand"/> </Condition> + <MenuItem id="AddExpressionBreakpoint" + insertafter="Toggle Breakpoint" + label = "${res:XML.MainMenu.DebugMenu.AddExpressionBreakpoint}" + shortcut="Shift|F7" + class = "Debugger.AddIn.AddExpressionBreakpointCommand"/> + <MenuItem id="AddWatchExpression" + insertafter="AddExpressionBreakpoint" + label = "${res:XML.MainMenu.DebugMenu.AddWatchExpression}" + shortcut="Ctrl|F7" + class = "Debugger.AddIn.AddWatchExpressionCommand"/> </Path> <Path name = "/SharpDevelop/Workbench/Pads"> @@ -128,12 +138,6 @@ defaultPosition = "Bottom, Hidden" /> </Path> - <Path name ="/SharpDevelop/Pads/WatchPad/ContextMenu"> - <MenuItem id="AddWatch" label="${res:MainWindow.Windows.Debug.Watch.AddWatch}" class="Debugger.AddIn.AddWatchCommand" /> - <MenuItem id="RemoveWatch" label="${res:MainWindow.Windows.Debug.Watch.RemoveWatch}" class="Debugger.AddIn.RemoveWatchCommand" /> - <MenuItem id="ClearWatches" label="${res:MainWindow.Windows.Debug.Watch.RemoveAll}" class="Debugger.AddIn.ClearWatchesCommand" /> - </Path> - <Path name = "/SharpDevelop/Dialogs/OptionsDialog"> <OptionPanel id = "Debugging" label = "${res:Dialog.Options.IDEOptions.Debugging}" diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs index 10d5684ab2..a37b779a72 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs @@ -56,7 +56,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads tree.ShowRoot = false; tree.View = (GridView)res["variableGridView"]; tree.SetValue(GridViewColumnAutoSize.AutoWidthProperty, "50%;25%;25%"); - //tree.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu"); tree.MouseDoubleClick += delegate(object sender, MouseButtonEventArgs e) { if (this.tree.SelectedItem == null) { AddWatch(focus: true); @@ -124,6 +123,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads process.EnqueueForEach( Dispatcher.CurrentDispatcher, expressions, + expr => this.Items.Add(MakeNode(expr)), expr => this.Items.Add(MakeNode(expr)) ); } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadCommands.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadCommands.cs index 4eb40d5cea..d346bdee48 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadCommands.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadCommands.cs @@ -3,6 +3,9 @@ using System; using System.Linq; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Gui; using Debugger.AddIn.Pads; using Debugger.AddIn.Pads.Controls; using Debugger.AddIn.TreeModel; @@ -47,4 +50,17 @@ namespace Debugger.AddIn } } } + + public class AddWatchExpressionCommand : AbstractMenuCommand + { + public override void Run() + { + var editor = SD.GetActiveViewContentService<ITextEditor>(); + if (editor == null) return; + var pad = SD.Workbench.GetPad(typeof(WatchPad)); + if (pad == null) return; + pad.BringPadToFront(); + ((WatchPad)pad.PadContent).AddWatch(editor.SelectedText); + } + } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs index e93fb5910a..52ab6492cf 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Windows.Forms; using System.Windows.Threading; +using ICSharpCode.SharpDevelop; using Debugger.AddIn.Pads.Controls; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Gui; @@ -41,46 +42,39 @@ namespace Debugger.AddIn.TreeModel ); } - public static void EnqueueForEach<T>(this Process process, Dispatcher dispatcher, IList<T> items, Action<T> work) + public static void EnqueueForEach<T>(this Process process, Dispatcher dispatcher, IList<T> items, Action<T> work, Action<T> failAction = null) { long debuggeeStateWhenEnqueued = process.DebuggeeState; - dispatcher.BeginInvoke( - DispatcherPriority.Normal, - (Action)delegate { ProcessItems(process, dispatcher, 0, items, work, debuggeeStateWhenEnqueued); } - ); + foreach (T item in items) { + var workItem = item; + dispatcher.BeginInvoke( + DispatcherPriority.Normal, + (Action)delegate { + if (!ProcessItem(process, workItem, work, debuggeeStateWhenEnqueued) && failAction != null) + failAction(workItem); + } + ); + } } - static void ProcessItems<T>(Process process, Dispatcher dispatcher, int startIndex, IList<T> items, Action<T> work, long debuggeeStateWhenEnqueued) + static bool ProcessItem<T>(Process process, T item, Action<T> work, long debuggeeStateWhenEnqueued) { - var watch = new System.Diagnostics.Stopwatch(); - watch.Start(); - - for (int i = startIndex; i < items.Count; i++) { - int index = i; - if (process.IsPaused && debuggeeStateWhenEnqueued == process.DebuggeeState) { - try { - // Do the work, this may recursively enqueue more work - work(items[index]); - } catch (System.Exception ex) { - if (process == null || process.HasExited) { - // Process unexpectedly exited - silently ignore - } else { - MessageService.ShowException(ex); - } - break; + if (process.IsPaused && debuggeeStateWhenEnqueued == process.DebuggeeState) { + try { + // Do the work, this may recursively enqueue more work + work(item); + return true; + } catch (System.Exception ex) { + if (process == null || process.HasExited) { + // Process unexpectedly exited - silently ignore + } else { + MessageService.ShowException(ex); } - } - - // if we are too slow move to background - if (watch.ElapsedMilliseconds > 100) { - dispatcher.BeginInvoke( - DispatcherPriority.Background, - (Action)delegate { ProcessItems(process, dispatcher, index + 1, items, work, debuggeeStateWhenEnqueued); } - ); - break; + SD.Log.Error("ProcessItem cancelled", ex); } } + return false; } }