~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
// THE SOFTWARE.
26
26
 
27
27
using System;
28
 
using System.Text;
29
 
using System.Threading;
30
 
 
31
 
using Gtk;
32
28
using Mono.Debugging.Client;
33
29
using MonoDevelop.Core;
 
30
using Gtk;
 
31
using System.Threading;
 
32
using MonoDevelop.Components;
 
33
using MonoDevelop.Ide.TextEditing;
 
34
using MonoDevelop.Ide;
 
35
using MonoDevelop.Ide.Gui.Content;
34
36
 
35
37
namespace MonoDevelop.Debugger
36
38
{
37
 
        public partial class ExceptionCaughtDialog : Gtk.Dialog
 
39
        public partial class ExceptionCaughtWidget : Gtk.Bin
38
40
        {
 
41
                Gtk.TreeStore stackStore;
39
42
                ExceptionInfo exception;
40
43
                bool destroyed;
41
44
                
42
 
                public ExceptionCaughtDialog (ExceptionInfo exception)
 
45
                public ExceptionCaughtWidget (ExceptionInfo exception)
43
46
                {
44
47
                        this.Build ();
45
 
                        
46
 
                        HasSeparator = false;
 
48
 
 
49
                        stackStore = new TreeStore (typeof(string), typeof(string), typeof(int), typeof(int));
 
50
                        treeStack.Model = stackStore;
 
51
                        var crt = new CellRendererText ();
 
52
                        crt.WrapWidth = 200;
 
53
                        crt.WrapMode = Pango.WrapMode.WordChar;
 
54
                        treeStack.AppendColumn ("", crt, "markup", 0);
 
55
                        treeStack.ShowExpanders = false;
47
56
                        
48
57
                        valueView.AllowExpanding = true;
49
58
                        valueView.Frame = DebuggingService.CurrentFrame;
50
59
                        this.exception = exception;
51
60
                        
52
61
                        exception.Changed += HandleExceptionChanged;
 
62
                        treeStack.SizeAllocated += delegate(object o, SizeAllocatedArgs args) {
 
63
                                if (crt.WrapWidth != args.Allocation.Width)
 
64
                                        crt.WrapWidth = args.Allocation.Width;
 
65
                        };
53
66
                        
54
67
                        Fill ();
 
68
                        treeStack.RowActivated += HandleRowActivated;
 
69
                }
 
70
 
 
71
                void HandleRowActivated (object o, RowActivatedArgs args)
 
72
                {
 
73
                        Gtk.TreeIter it;
 
74
                        if (!stackStore.GetIter (out it, args.Path))
 
75
                                return;
 
76
                        string file = (string) stackStore.GetValue (it, 1);
 
77
                        int line = (int) stackStore.GetValue (it, 2);
 
78
                        if (!string.IsNullOrEmpty (file))
 
79
                                IdeApp.Workbench.OpenDocument (file, line, 0);
55
80
                }
56
81
 
57
82
                void HandleExceptionChanged (object sender, EventArgs e)
66
91
                        if (destroyed)
67
92
                                return;
68
93
                        
 
94
                        stackStore.Clear ();
69
95
                        valueView.ClearValues ();
70
96
 
71
97
                        labelType.Markup = GettextCatalog.GetString ("<b>{0}</b> has been thrown", exception.Type);
72
 
                        labelMessage.Text = string.IsNullOrEmpty (exception.Message)?
73
 
                                            string.Empty: 
 
98
                        labelMessage.Text = string.IsNullOrEmpty (exception.Message) ?
 
99
                                            string.Empty : 
74
100
                                            exception.Message;
75
101
                        
76
 
                        if (!exception.IsEvaluating) {
77
 
                                StringBuilder stack = new StringBuilder ();
78
 
                                ShowStackTrace (stack, exception);
79
 
                                stackTextView.Buffer.Text = stack.ToString ();
80
 
                                
81
 
                                if (exception.Instance != null) {
82
 
                                        valueView.AddValue (exception.Instance);
83
 
                                        valueView.ExpandRow (new TreePath ("0"), false);
 
102
                        ShowStackTrace (exception, false);
 
103
                        
 
104
                        if (!exception.IsEvaluating && exception.Instance != null) {
 
105
                                valueView.AddValue (exception.Instance);
 
106
                                valueView.ExpandRow (new TreePath ("0"), false);
 
107
                        }
 
108
                        if (exception.StackIsEvaluating) {
 
109
                                stackStore.AppendValues (GettextCatalog.GetString ("Loading..."), "", 0, 0);
 
110
                        }
 
111
                }
 
112
                
 
113
                void ShowStackTrace (ExceptionInfo exc, bool showExceptionNode)
 
114
                {
 
115
                        TreeIter it = TreeIter.Zero;
 
116
                        if (showExceptionNode) {
 
117
                                treeStack.ShowExpanders = true;
 
118
                                string tn = exc.Type + ": " + exc.Message;
 
119
                                it = stackStore.AppendValues (tn, null, 0, 0);
 
120
                        }
 
121
 
 
122
                        foreach (ExceptionStackFrame frame in exc.StackTrace) {
 
123
                                string text = GLib.Markup.EscapeText (frame.DisplayText);
 
124
                                if (!string.IsNullOrEmpty (frame.File)) {
 
125
                                        text += "\n<small>" + GLib.Markup.EscapeText (frame.File);
 
126
                                        if (frame.Line > 0) {
 
127
                                                text += ":" + frame.Line;
 
128
                                                if (frame.Column > 0)
 
129
                                                        text += "," + frame.Column;
 
130
                                        }
 
131
                                        text += "</small>";
84
132
                                }
85
 
                        }
86
 
                }
87
 
                
88
 
                void ShowStackTrace (StringBuilder stack, ExceptionInfo ex)
89
 
                {
90
 
                        ExceptionInfo inner = ex.InnerException;
91
 
                        
92
 
                        if (inner != null) {
93
 
                                stack.AppendFormat ("{0}: {1} ---> ", ex.Type, ex.Message);
94
 
                                ShowStackTrace (stack, inner);
95
 
                                stack.AppendLine ("  --- End of inner exception stack trace ---");
96
 
                        } else {
97
 
                                stack.AppendFormat ("{0}: {1}\n", ex.Type, ex.Message);
98
 
                        }
99
 
                        
100
 
                        foreach (ExceptionStackFrame frame in ex.StackTrace) {
101
 
                                stack.Append ("  ");
102
 
                                stack.AppendLine (frame.DisplayText);
103
 
                        }
104
 
                }
105
 
                
106
 
                protected override bool OnDeleteEvent (Gdk.Event evnt)
107
 
                {
108
 
                        Destroy ();
109
 
                        return false;
110
 
                }
111
 
                
112
 
                protected virtual void OnButtonOkClicked (object sender, System.EventArgs e)
113
 
                {
114
 
                        Destroy ();
 
133
                                if (!it.Equals (TreeIter.Zero))
 
134
                                        stackStore.AppendValues (it, text, frame.File, frame.Line, frame.Column);
 
135
                                else
 
136
                                        stackStore.AppendValues (text, frame.File, frame.Line, frame.Column);
 
137
                        }
 
138
                        
 
139
                        ExceptionInfo inner = exc.InnerException;
 
140
                        if (inner != null)
 
141
                                ShowStackTrace (inner, true);
115
142
                }
116
143
                
117
144
                protected override void OnDestroyed ()
120
147
                        exception.Changed -= HandleExceptionChanged;
121
148
                        base.OnDestroyed ();
122
149
                }
123
 
                
 
150
        }
 
151
 
 
152
        class ExceptionCaughtDialog: Gtk.Dialog
 
153
        {
 
154
                ExceptionCaughtWidget widget;
 
155
                ExceptionInfo ex;
 
156
                ExceptionCaughtMessage msg;
 
157
 
 
158
                public ExceptionCaughtDialog (ExceptionInfo val, ExceptionCaughtMessage msg)
 
159
                {
 
160
                        Title = GettextCatalog.GetString ("Exception Caught");
 
161
                        ex = val;
 
162
                        widget = new ExceptionCaughtWidget (val);
 
163
                        this.msg = msg;
 
164
 
 
165
                        VBox box = new VBox ();
 
166
                        box.Spacing = 6;
 
167
                        box.PackStart (widget, true, true, 0);
 
168
                        HButtonBox buttonBox = new HButtonBox ();
 
169
                        buttonBox.BorderWidth = 6;
 
170
 
 
171
                        var copy = new Gtk.Button (GettextCatalog.GetString ("Copy to Clipboard"));
 
172
                        buttonBox.PackStart (copy, false, false, 0);
 
173
                        copy.Clicked += HandleCopyClicked;
 
174
 
 
175
                        var close = new Gtk.Button (GettextCatalog.GetString ("Close"));
 
176
                        buttonBox.PackStart (close, false, false, 0);
 
177
                        close.Clicked += (sender, e) => msg.Close ();
 
178
                        close.Activated += (sender, e) => msg.Close ();
 
179
 
 
180
                        box.PackStart (buttonBox, false, false, 0);
 
181
                        VBox.Add (box);
 
182
 
 
183
                        DefaultWidth = 500;
 
184
                        DefaultHeight = 350;
 
185
 
 
186
                        box.ShowAll ();
 
187
                        ActionArea.Hide ();
 
188
                }
 
189
 
 
190
                protected override bool OnDeleteEvent (Gdk.Event evnt)
 
191
                {
 
192
                        msg.Close ();
 
193
                        return true;
 
194
                }
 
195
 
 
196
                void HandleCopyClicked (object sender, EventArgs e)
 
197
                {
 
198
                        var text = ex.ToString ();
 
199
                        var clipboard = Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
 
200
                        clipboard.Text = text;
 
201
                        clipboard = Clipboard.Get (Gdk.Atom.Intern ("PRIMARY", false));
 
202
                        clipboard.Text = text;
 
203
                }
 
204
        }
 
205
 
 
206
        class ExceptionCaughtMessage
 
207
        {
 
208
                ExceptionInfo ex;
 
209
                ExceptionCaughtDialog dialog;
 
210
                ExceptionCaughtButton button;
 
211
                ExceptionCaughtMiniButton miniButton;
 
212
 
 
213
                public ExceptionCaughtMessage (ExceptionInfo val, FilePath file, int line, int col)
 
214
                {
 
215
                        File = file;
 
216
                        Line = line;
 
217
                        ex = val;
 
218
                }
 
219
 
 
220
                public FilePath File {
 
221
                        get; private set;
 
222
                }
 
223
 
 
224
                public int Line {
 
225
                        get; private set;
 
226
                }
 
227
 
 
228
                public bool IsMinimized {
 
229
                        get { return miniButton != null; }
 
230
                }
 
231
 
 
232
                public void ShowDialog ()
 
233
                {
 
234
                        if (dialog == null) {
 
235
                                dialog = new ExceptionCaughtDialog (ex, this);
 
236
                                MessageService.ShowCustomDialog (dialog, IdeApp.Workbench.RootWindow);
 
237
                                dialog = null;
 
238
                        }
 
239
                }
 
240
 
 
241
                public void ShowButton ()
 
242
                {
 
243
                        if (dialog != null) {
 
244
                                dialog.Destroy ();
 
245
                                dialog = null;
 
246
                        }
 
247
                        if (button == null) {
 
248
                                button = new ExceptionCaughtButton (ex, this, File, Line);
 
249
                                TextEditorService.RegisterExtension (button);
 
250
                        }
 
251
                        if (miniButton != null) {
 
252
                                miniButton.Dispose ();
 
253
                                miniButton = null;
 
254
                        }
 
255
                }
 
256
 
 
257
                public void ShowMiniButton ()
 
258
                {
 
259
                        if (dialog != null) {
 
260
                                dialog.Destroy ();
 
261
                                dialog = null;
 
262
                        }
 
263
                        if (button != null) {
 
264
                                button.Dispose ();
 
265
                                button = null;
 
266
                        }
 
267
                        if (miniButton == null) {
 
268
                                miniButton = new ExceptionCaughtMiniButton (this, File, Line);
 
269
                                TextEditorService.RegisterExtension (miniButton);
 
270
                        }
 
271
                }
 
272
 
 
273
                public void Dispose ()
 
274
                {
 
275
                        if (dialog != null) {
 
276
                                dialog.Destroy ();
 
277
                                dialog = null;
 
278
                        }
 
279
                        if (button != null) {
 
280
                                button.Dispose ();
 
281
                                button = null;
 
282
                        }
 
283
                        if (miniButton != null) {
 
284
                                miniButton.Dispose ();
 
285
                                miniButton = null;
 
286
                        }
 
287
                        if (Closed != null)
 
288
                                Closed (this, EventArgs.Empty);
 
289
                }
 
290
 
 
291
                public void Close ()
 
292
                {
 
293
                        ShowButton ();
 
294
                }
 
295
 
 
296
                public event EventHandler Closed;
 
297
        }
 
298
 
 
299
        class ExceptionCaughtButton: TopLevelWidgetExtension
 
300
        {
 
301
                ExceptionCaughtMessage dlg;
 
302
                ExceptionInfo exception;
 
303
                Gtk.Label messageLabel;
 
304
                Gdk.Pixbuf closeSelImage;
 
305
                Gdk.Pixbuf closeSelOverImage;
 
306
 
 
307
                public ExceptionCaughtButton (ExceptionInfo val, ExceptionCaughtMessage dlg, FilePath file, int line)
 
308
                {
 
309
                        this.exception = val;
 
310
                        this.dlg = dlg;
 
311
                        OffsetX = 6;
 
312
                        File = file;
 
313
                        Line = line;
 
314
                        closeSelImage = Gdk.Pixbuf.LoadFromResource ("MonoDevelop.Close.Selected.png");
 
315
                        closeSelOverImage = Gdk.Pixbuf.LoadFromResource ("MonoDevelop.Close.Selected.Over.png");
 
316
                }
 
317
 
 
318
                protected override void OnLineDeleted ()
 
319
                {
 
320
                        dlg.Dispose ();
 
321
                }
 
322
 
 
323
                public override Widget CreateWidget ()
 
324
                {
 
325
                        var icon = Gdk.Pixbuf.LoadFromResource ("lightning.png");
 
326
                        var image = new Gtk.Image (icon);
 
327
 
 
328
                        HBox box = new HBox (false, 6);
 
329
                        VBox vb = new VBox ();
 
330
                        vb.PackStart (image, false, false, 0);
 
331
                        box.PackStart (vb, false, false, 0);
 
332
                        vb = new VBox (false, 6);
 
333
                        vb.PackStart (new Gtk.Label () {
 
334
                                Markup = GettextCatalog.GetString ("<b>{0}</b> has been thrown", exception.Type),
 
335
                                Xalign = 0
 
336
                        });
 
337
                        messageLabel = new Gtk.Label () {
 
338
                                Xalign = 0,
 
339
                                NoShowAll = true
 
340
                        };
 
341
                        vb.PackStart (messageLabel);
 
342
 
 
343
                        var detailsBtn = new Xwt.LinkLabel (GettextCatalog.GetString ("Show Details"));
 
344
                        HBox hh = new HBox ();
 
345
                        detailsBtn.NavigateToUrl += (o,e) => dlg.ShowDialog ();
 
346
                        hh.PackStart (detailsBtn.ToGtkWidget (), false, false, 0);
 
347
                        vb.PackStart (hh, false, false, 0);
 
348
 
 
349
                        box.PackStart (vb, true, true, 0);
 
350
 
 
351
                        vb = new VBox ();
 
352
                        var closeButton = new ImageButton () {
 
353
                                InactiveImage = closeSelImage,
 
354
                                Image = closeSelOverImage
 
355
                        };
 
356
                        closeButton.Clicked += delegate {
 
357
                                dlg.ShowMiniButton ();
 
358
                        };
 
359
                        vb.PackStart (closeButton, false, false, 0);
 
360
                        box.PackStart (vb, false, false, 0);
 
361
 
 
362
                        exception.Changed += delegate {
 
363
                                Application.Invoke (delegate {
 
364
                                        LoadData ();
 
365
                                });
 
366
                        };
 
367
                        LoadData ();
 
368
 
 
369
                        PopoverWidget eb = new PopoverWidget ();
 
370
                        eb.ShowArrow = true;
 
371
                        eb.EnableAnimation = true;
 
372
                        eb.PopupPosition = PopupPosition.Left;
 
373
                        eb.ContentBox.Add (box);
 
374
                        eb.ShowAll ();
 
375
                        return eb;
 
376
                }
 
377
 
 
378
                void LoadData ()
 
379
                {
 
380
                        if (!string.IsNullOrEmpty (exception.Message)) {
 
381
                                messageLabel.Show ();
 
382
                                messageLabel.Text = exception.Message;
 
383
                                if (messageLabel.SizeRequest ().Width > 400) {
 
384
                                        messageLabel.WidthRequest = 400;
 
385
                                        messageLabel.Wrap = true;
 
386
                                }
 
387
                        } else {
 
388
                                messageLabel.Hide ();
 
389
                        }
 
390
                }
 
391
        }
 
392
 
 
393
        class ExceptionCaughtMiniButton: TopLevelWidgetExtension
 
394
        {
 
395
                ExceptionCaughtMessage dlg;
 
396
 
 
397
                public ExceptionCaughtMiniButton (ExceptionCaughtMessage dlg, FilePath file, int line)
 
398
                {
 
399
                        this.dlg = dlg;
 
400
                        OffsetX = 6;
 
401
                        File = file;
 
402
                        Line = line;
 
403
                }
 
404
 
 
405
                protected override void OnLineDeleted ()
 
406
                {
 
407
                        dlg.Dispose ();
 
408
                }
 
409
 
 
410
                public override Widget CreateWidget ()
 
411
                {
 
412
                        Gtk.EventBox box = new EventBox ();
 
413
                        box.VisibleWindow = false;
 
414
                        var icon = Gdk.Pixbuf.LoadFromResource ("lightning.png");
 
415
                        box.Add (new Gtk.Image (icon));
 
416
                        box.ButtonPressEvent += (o,e) => dlg.ShowButton ();
 
417
                        PopoverWidget eb = new PopoverWidget ();
 
418
                        eb.Theme.Padding = 2;
 
419
                        eb.ShowArrow = true;
 
420
                        eb.EnableAnimation = true;
 
421
                        eb.PopupPosition = PopupPosition.Left;
 
422
                        eb.ContentBox.Add (box);
 
423
                        eb.ShowAll ();
 
424
                        return eb;
 
425
                }
 
426
        }
 
427
 
 
428
        class ExceptionCaughtTextEditorExtension: TextEditorExtension
 
429
        {
 
430
                public override bool KeyPress (Gdk.Key key, char keyChar, Gdk.ModifierType modifier)
 
431
                {
 
432
                        if (key == Gdk.Key.Escape && DebuggingService.ExceptionCaughtMessage != null && 
 
433
                            !DebuggingService.ExceptionCaughtMessage.IsMinimized && 
 
434
                            DebuggingService.ExceptionCaughtMessage.File.CanonicalPath == Document.FileName.CanonicalPath) {
 
435
 
 
436
                                DebuggingService.ExceptionCaughtMessage.ShowMiniButton ();
 
437
                                return true;
 
438
                        }
 
439
 
 
440
                        return base.KeyPress (key, keyChar, modifier);
 
441
                }
124
442
        }
125
443
}
126
444