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

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.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:
26
26
//
27
27
 
28
28
using System;
 
29
using System.Text;
29
30
using System.Collections.Generic;
30
 
using System.Text;
 
31
using System.Threading.Tasks;
 
32
 
31
33
using Gtk;
32
34
using Mono.Debugging.Client;
33
35
using MonoDevelop.Components;
50
52
                List<ObjectValue> values = new List<ObjectValue> ();
51
53
                Dictionary<ObjectValue,TreeRowReference> nodes = new Dictionary<ObjectValue, TreeRowReference> ();
52
54
                Dictionary<string,ObjectValue> cachedValues = new Dictionary<string,ObjectValue> ();
 
55
                Dictionary<ObjectValue, Task> expandTasks = new Dictionary<ObjectValue, Task> ();
53
56
                TreeStore store;
54
57
                TreeViewState state;
55
58
                string createMsg;
56
59
                bool allowAdding;
57
60
                bool allowEditing;
58
61
                bool allowExpanding = true;
 
62
                bool restoringState = false;
59
63
                bool compact;
60
64
                StackFrame frame;
61
65
                bool disposed;
131
135
                        store = new TreeStore (typeof(string), typeof(string), typeof(string), typeof(ObjectValue), typeof(bool), typeof(bool), typeof(bool), typeof(string), typeof(string), typeof(string), typeof(bool), typeof(string), typeof(Gdk.Pixbuf), typeof(bool));
132
136
                        Model = store;
133
137
                        RulesHint = true;
 
138
                        EnableSearch = false;
134
139
                        Selection.Mode = Gtk.SelectionMode.Multiple;
135
140
                        ResetColumnSizes ();
136
141
                        
233
238
                        crtValue.EditingStarted -= OnValueEditing;
234
239
                        crtValue.Edited -= OnValueEdited;
235
240
                        crtValue.EditingCanceled -= OnEditingCancelled;
236
 
                        
 
241
 
 
242
                        if (expandTasks.Count > 0) {
 
243
                                var tasks = new Task[expandTasks.Count];
 
244
                                expandTasks.Values.CopyTo (tasks, 0);
 
245
                                Task.WaitAll (tasks);
 
246
                        }
 
247
 
237
248
                        base.OnDestroyed ();
238
249
                        disposed = true;
239
250
                }
249
260
                        base.OnShown ();
250
261
                        AdjustColumnSizes ();
251
262
                }
252
 
                
253
 
                
 
263
 
 
264
                protected override void OnRealized ()
 
265
                {
 
266
                        base.OnRealized ();
 
267
                        AdjustColumnSizes ();
 
268
                }
 
269
 
254
270
                void OnColumnWidthChanged (object o, GLib.NotifyArgs args)
255
271
                {
256
272
                        if (!columnSizesUpdating && allowStoreColumnSizes) {
257
273
                                StoreColumnSizes ();
258
274
                        }
259
275
                }
260
 
                
261
 
                
 
276
 
262
277
                void AdjustColumnSizes ()
263
278
                {
264
 
                        if (!IsRealized || !Visible || Allocation.Width == 0 || columnSizesUpdating || compact)
 
279
                        if (!Visible || Allocation.Width <= 0 || columnSizesUpdating || compact)
265
280
                                return;
266
281
                        
267
282
                        columnSizesUpdating = true;
268
283
                        
269
284
                        double width = (double) Allocation.Width;
270
285
                        
271
 
                        int texp = (int) (width * expColWidth);
 
286
                        int texp = Math.Max ((int) (width * expColWidth), 1);
272
287
                        if (texp != expCol.FixedWidth) {
273
288
                                expCol.FixedWidth = texp;
274
289
                        }
275
290
                        
276
 
                        int ttype = 0;
277
291
                        if (typeCol.Visible) {
278
 
                                ttype = (int) (width * typeColWidth);
 
292
                                int ttype = Math.Max ((int) (width * typeColWidth), 1);
279
293
                                if (ttype != typeCol.FixedWidth) {
280
294
                                        typeCol.FixedWidth = ttype;
281
295
                                }
282
296
                        }
283
297
                        
284
 
                        int tval = (int) (width * valueColWidth);
 
298
                        int tval = Math.Max ((int) (width * valueColWidth), 1);
285
299
 
286
300
                        if (tval != valueCol.FixedWidth) {
287
301
                                valueCol.FixedWidth = tval;
328
342
                
329
343
                public void LoadState ()
330
344
                {
 
345
                        restoringState = true;
331
346
                        state.Load ();
 
347
                        restoringState = false;
332
348
                }
333
349
                
334
350
                public bool AllowAdding {
437
453
                        values.Remove (value);
438
454
                        Refresh ();
439
455
                }
 
456
 
 
457
                public void ReplaceValue (ObjectValue old, ObjectValue @new)
 
458
                {
 
459
                        int idx = values.IndexOf (old);
 
460
                        if (idx == -1)
 
461
                                return;
 
462
 
 
463
                        values [idx] = @new;
 
464
                        Refresh ();
 
465
                }
440
466
                
441
467
                public void ClearValues ()
442
468
                {
465
491
                        foreach (ObjectValue val in new List<ObjectValue> (nodes.Keys))
466
492
                                UnregisterValue (val);
467
493
                        nodes.Clear ();
468
 
                        
469
 
                        state.Save ();
470
 
                        
 
494
 
 
495
                        if (IsRealized)
 
496
                                ScrollToPoint (0, 0);
 
497
 
 
498
                        SaveState ();
 
499
 
471
500
                        CleanPinIcon ();
472
501
                        store.Clear ();
473
502
                        
487
516
                                                showExpanders = true;
488
517
                                }
489
518
                        }
490
 
                        
491
 
                        ShowExpanders = showExpanders;
 
519
 
 
520
                        if (showExpanders)
 
521
                                ShowExpanders = true;
492
522
                        
493
523
                        if (AllowAdding)
494
524
                                store.AppendValues (createMsg, "", "", null, true, true, null, disabledColor, disabledColor);
495
 
                        
496
 
                        state.Load ();
 
525
 
 
526
                        LoadState ();
497
527
                }
498
528
                
499
529
                void RefreshRow (TreeIter it)
505
535
                        TreeIter parent;
506
536
                        if (!store.IterParent (out parent, it))
507
537
                                parent = TreeIter.Zero;
508
 
                        
509
 
                        EvaluationOptions ops = frame.DebuggerSession.Options.EvaluationOptions.Clone ();
510
 
                        ops.AllowMethodEvaluation = true;
511
 
                        ops.AllowToStringCalls = true;
512
 
                        ops.AllowTargetInvoke = true;
513
 
                        ops.EllipsizeStrings = false;
514
 
                        
515
 
                        string oldName = val.Name;
516
 
                        val.Refresh (ops);
517
 
                        
518
 
                        // Don't update the name for the values entered by the user
519
 
                        if (store.IterDepth (it) == 0)
520
 
                                val.Name = oldName;
521
 
                        
 
538
 
 
539
                        if (frame != null && frame.DebuggerSession.IsConnected) {
 
540
                                EvaluationOptions ops = frame.DebuggerSession.Options.EvaluationOptions.Clone ();
 
541
                                ops.AllowMethodEvaluation = true;
 
542
                                ops.AllowToStringCalls = true;
 
543
                                ops.AllowTargetInvoke = true;
 
544
                                ops.EllipsizeStrings = false;
 
545
 
 
546
                                string oldName = val.Name;
 
547
                                val.Refresh (ops);
 
548
 
 
549
                                // Don't update the name for the values entered by the user
 
550
                                if (store.IterDepth (it) == 0)
 
551
                                        val.Name = oldName;
 
552
                        }
 
553
 
522
554
                        SetValues (parent, it, val.Name, val);
523
555
                        RegisterValue (val, it);
524
556
                }
591
623
                {
592
624
                        TreeRowReference row;
593
625
                        
594
 
                        if (!nodes.TryGetValue (val, out row)) {
 
626
                        if (!nodes.TryGetValue (val, out row) || !row.Valid ()) {
595
627
                                it = TreeIter.Zero;
596
628
                                return false;
597
629
                        }
661
693
                        oldValues.TryGetValue (valPath, out oldValue);
662
694
                        
663
695
                        if (val.IsUnknown) {
664
 
                                strval = GettextCatalog.GetString ("The name '{0}' does not exist in the current context.", val.Name);
665
 
                                nameColor = disabledColor;
666
 
                                canEdit = false;
 
696
                                if (frame != null) {
 
697
                                        strval = GettextCatalog.GetString ("The name '{0}' does not exist in the current context.", val.Name);
 
698
                                        nameColor = disabledColor;
 
699
                                        canEdit = false;
 
700
                                } else {
 
701
                                        canEdit = !val.IsReadOnly;
 
702
                                        strval = string.Empty;
 
703
                                }
667
704
                        }
668
705
                        else if (val.IsError) {
669
706
                                strval = val.Value;
690
727
                                canEdit = false;
691
728
                        }
692
729
                        else {
693
 
                                canEdit = val.IsPrimitive && !val.IsReadOnly && allowEditing;
 
730
                                canEdit = val.IsPrimitive && !val.IsReadOnly;
694
731
                                strval = val.DisplayValue ?? "(null)";
695
732
                                if (oldValue != null && strval != oldValue)
696
733
                                        nameColor = valueColor = modifiedColor;
699
736
                        strval = strval.Replace (Environment.NewLine, " ");
700
737
                        
701
738
                        bool showViewerButton = DebuggingService.HasValueVisualizers (val);
702
 
                        
 
739
 
 
740
                        bool hasChildren = val.HasChildren;
703
741
                        string icon = GetIcon (val.Flags);
704
742
 
705
743
                        store.SetValue (it, NameCol, name);
706
744
                        store.SetValue (it, ValueCol, strval);
707
745
                        store.SetValue (it, TypeCol, val.TypeName);
708
746
                        store.SetValue (it, ObjectCol, val);
709
 
                        store.SetValue (it, ExpandedCol, !val.HasChildren);
 
747
                        store.SetValue (it, ExpandedCol, !hasChildren);
710
748
                        store.SetValue (it, NameEditableCol, !hasParent && allowAdding);
711
 
                        store.SetValue (it, ValueEditableCol, canEdit);
 
749
                        store.SetValue (it, ValueEditableCol, canEdit && allowEditing);
712
750
                        store.SetValue (it, IconCol, icon);
713
751
                        store.SetValue (it, NameColorCol, nameColor);
714
752
                        store.SetValue (it, ValueColorCol, valueColor);
725
763
                        if (RootPinAlwaysVisible && (!hasParent && PinnedWatch ==null && AllowPinning))
726
764
                                store.SetValue (it, PinIconCol, "md-pin-up");
727
765
                        
728
 
                        if (val.HasChildren) {
 
766
                        if (hasChildren) {
729
767
                                // Add dummy node
730
 
                                it = store.AppendValues (it, "", "", "", null, true);
 
768
                                store.AppendValues (it, GettextCatalog.GetString ("Loading..."), "", "", null, true);
731
769
                                if (!ShowExpanders)
732
770
                                        ShowExpanders = true;
733
771
                        }
742
780
                        string stic = (flags & ObjectValueFlags.Global) != 0 ? "static-" : string.Empty;
743
781
                        
744
782
                        switch (flags & ObjectValueFlags.OriginMask) {
745
 
                                case ObjectValueFlags.Property: source = "property"; break;
746
 
                                case ObjectValueFlags.Type: source = "class"; stic = string.Empty; break;
747
 
                                case ObjectValueFlags.Literal: return "md-literal";
748
 
                                case ObjectValueFlags.Namespace: return "md-name-space";
749
 
                                case ObjectValueFlags.Group: return "md-open-resource-folder";
750
 
                                default: source = "field"; break;
 
783
                        case ObjectValueFlags.Property: source = "property"; break;
 
784
                        case ObjectValueFlags.Type: source = "class"; stic = string.Empty; break;
 
785
                        case ObjectValueFlags.Literal: return "md-literal";
 
786
                        case ObjectValueFlags.Namespace: return "md-name-space";
 
787
                        case ObjectValueFlags.Group: return "md-open-resource-folder";
 
788
                        case ObjectValueFlags.Field: source = "field"; break;
 
789
                        default: return "md-empty";
751
790
                        }
 
791
 
752
792
                        string access;
753
793
                        switch (flags & ObjectValueFlags.AccessMask) {
754
 
                                case ObjectValueFlags.Private: access = "private-"; break;
755
 
                                case ObjectValueFlags.Internal: access = "internal-"; break;
756
 
                                case ObjectValueFlags.InternalProtected:
757
 
                                case ObjectValueFlags.Protected: access = "protected-"; break;
758
 
                                default: access = string.Empty; break;
 
794
                        case ObjectValueFlags.Private: access = "private-"; break;
 
795
                        case ObjectValueFlags.Internal: access = "internal-"; break;
 
796
                        case ObjectValueFlags.InternalProtected:
 
797
                        case ObjectValueFlags.Protected: access = "protected-"; break;
 
798
                        default: access = string.Empty; break;
759
799
                        }
760
800
                        
761
801
                        return "md-" + access + stic + source;
763
803
                
764
804
                protected override bool OnTestExpandRow (TreeIter iter, TreePath path)
765
805
                {
766
 
                        if (!allowExpanding)
767
 
                                return true;
768
 
                        
769
 
                        if (GetRowExpanded (path))
770
 
                                return true;
771
 
                        
772
 
                        TreeIter parent;
773
 
                        if (store.IterParent (out parent, iter)) {
774
 
                                if (!GetRowExpanded (store.GetPath (parent)))
775
 
                                        return true;
 
806
                        if (!restoringState) {
 
807
                                if (!allowExpanding)
 
808
                                        return true;
 
809
 
 
810
                                if (GetRowExpanded (path))
 
811
                                        return true;
 
812
 
 
813
                                TreeIter parent;
 
814
                                if (store.IterParent (out parent, iter)) {
 
815
                                        if (!GetRowExpanded (store.GetPath (parent)))
 
816
                                                return true;
 
817
                                }
776
818
                        }
777
819
                        
778
820
                        return base.OnTestExpandRow (iter, path);
785
827
                        if (compact)
786
828
                                ColumnsAutosize ();
787
829
                }
 
830
 
 
831
                static Task<ObjectValue[]> GetChildrenAsync (ObjectValue value)
 
832
                {
 
833
                        return Task.Factory.StartNew<ObjectValue[]> (delegate (object arg) {
 
834
                                try {
 
835
                                        return ((ObjectValue) arg).GetAllChildren ();
 
836
                                } catch (Exception ex) {
 
837
                                        // Note: this should only happen if someone breaks ObjectValue.GetAllChildren()
 
838
                                        LoggingService.LogError ("Failed to get ObjectValue children.", ex);
 
839
                                        return new ObjectValue[0];
 
840
                                }
 
841
                        }, value);
 
842
                }
 
843
 
 
844
                void AddChildrenAsync (ObjectValue value, TreePathReference row)
 
845
                {
 
846
                        Task task;
 
847
 
 
848
                        if (expandTasks.TryGetValue (value, out task))
 
849
                                return;
 
850
 
 
851
                        task = GetChildrenAsync (value).ContinueWith (t => {
 
852
                                TreeIter iter, it;
 
853
 
 
854
                                if (row.IsValid && store.GetIter (out iter, row.Path) && store.IterChildren (out it, iter)) {
 
855
                                        foreach (var child in t.Result) {
 
856
                                                SetValues (iter, it, null, child);
 
857
                                                RegisterValue (child, it);
 
858
                                                it = store.InsertNodeAfter (it);
 
859
                                        }
 
860
 
 
861
                                        store.Remove (ref it);
 
862
 
 
863
                                        if (compact)
 
864
                                                ColumnsAutosize ();
 
865
                                }
 
866
 
 
867
                                expandTasks.Remove (value);
 
868
                                row.Dispose ();
 
869
                        }, Xwt.Application.UITaskScheduler);
 
870
                        expandTasks.Add (value, task);
 
871
                }
788
872
                
789
873
                protected override void OnRowExpanded (TreeIter iter, TreePath path)
790
874
                {
792
876
                        TreeIter it;
793
877
                        
794
878
                        if (store.IterChildren (out it, iter)) {
795
 
                                ObjectValue val = (ObjectValue) store.GetValue (it, ObjectCol);
796
 
                                if (val == null) {
797
 
                                        val = (ObjectValue) store.GetValue (iter, ObjectCol);
798
 
                                        bool first = true;
799
 
                                        
800
 
                                        foreach (ObjectValue cval in val.GetAllChildren ()) {
801
 
                                                SetValues (iter, it, null, cval);
802
 
                                                RegisterValue (cval, it);
803
 
                                                it = store.InsertNodeAfter (it);
804
 
                                        }
805
 
                                        
806
 
                                        store.Remove (ref it);
 
879
                                ObjectValue value = (ObjectValue) store.GetValue (it, ObjectCol);
 
880
                                if (value == null) {
 
881
                                        value = (ObjectValue) store.GetValue (iter, ObjectCol);
 
882
                                        AddChildrenAsync (value, new TreePathReference (store, store.GetPath (iter)));
807
883
                                }
808
884
                        }
809
885
                        
810
886
                        base.OnRowExpanded (iter, path);
811
 
                        
812
 
                        if (compact)
813
 
                                ColumnsAutosize ();
814
887
                }
815
888
                
816
889
                string GetIterPath (TreeIter iter)
853
926
                                        return;
854
927
                                
855
928
                                int i = valueNames.IndexOf (exp);
 
929
                                if (i == -1)
 
930
                                        return;
 
931
 
856
932
                                if (args.NewText.Length != 0)
857
933
                                        valueNames [i] = args.NewText;
858
934
                                else
928
1004
                        editing = true;
929
1005
                        editEntry = (Gtk.Entry) args.Editable;
930
1006
                        editEntry.KeyPressEvent += OnEditKeyPress;
 
1007
                        editEntry.KeyReleaseEvent += HandleChanged;
931
1008
                        if (StartEditing != null)
932
1009
                                StartEditing (this, EventArgs.Empty);
933
1010
                }
934
 
                
 
1011
 
 
1012
                void HandleChanged (object sender, EventArgs e)
 
1013
                {
 
1014
                        if (!wasHandled) {
 
1015
                                string text = ctx == null ? editEntry.Text : editEntry.Text.Substring (Math.Max (0, Math.Min (ctx.TriggerOffset, editEntry.Text.Length)));
 
1016
                                CompletionWindowManager.UpdateWordSelection (text);
 
1017
                                CompletionWindowManager.PostProcessKeyEvent (key, keyChar, modifierState);
 
1018
                                PopupCompletion ((Entry) sender);
 
1019
                        }
 
1020
                }
 
1021
 
935
1022
                void OnEndEditing ()
936
1023
                {
937
1024
                        editing = false;
938
1025
                        editEntry.KeyPressEvent -= OnEditKeyPress;
 
1026
                        editEntry.KeyReleaseEvent -= HandleChanged;
 
1027
 
939
1028
                        CompletionWindowManager.HideWindow ();
940
1029
                        currentCompletionData = null;
941
1030
                        if (EndEditing != null)
942
1031
                                EndEditing (this, EventArgs.Empty);
943
1032
                }
944
 
                
 
1033
                bool wasHandled = false;
 
1034
                CodeCompletionContext ctx;
 
1035
                Gdk.Key key;
 
1036
                char keyChar;
 
1037
                Gdk.ModifierType modifierState;
 
1038
                uint keyValue;
 
1039
 
945
1040
                [GLib.ConnectBeforeAttribute]
946
1041
                void OnEditKeyPress (object s, Gtk.KeyPressEventArgs args)
947
1042
                {
948
 
                        Gtk.Entry entry = (Gtk.Entry)s;
949
 
                        
 
1043
                        wasHandled = false;
 
1044
                        key = args.Event.Key;
 
1045
                        keyChar =  (char)args.Event.Key;
 
1046
                        modifierState = args.Event.State;
 
1047
                        keyValue = args.Event.KeyValue;
950
1048
                        if (currentCompletionData != null) {
951
 
                                bool ret = CompletionWindowManager.PreProcessKeyEvent (args.Event.Key, (char)args.Event.Key, args.Event.State);
952
 
                                CompletionWindowManager.PostProcessKeyEvent (args.Event.Key, (char)args.Event.Key, args.Event.State);
953
 
                                args.RetVal = ret;
 
1049
                                wasHandled  = CompletionWindowManager.PreProcessKeyEvent (key, keyChar, modifierState);
 
1050
                                args.RetVal = wasHandled ;
954
1051
                        }
955
 
                        
 
1052
                }
 
1053
 
 
1054
                void PopupCompletion (Entry entry)
 
1055
                {
956
1056
                        Gtk.Application.Invoke (delegate {
957
 
                                char c = (char)Gdk.Keyval.ToUnicode (args.Event.KeyValue);
 
1057
                                char c = (char)Gdk.Keyval.ToUnicode (keyValue);
958
1058
                                if (currentCompletionData == null && IsCompletionChar (c)) {
959
1059
                                        string exp = entry.Text.Substring (0, entry.CursorPosition);
960
1060
                                        currentCompletionData = GetCompletionData (exp);
961
1061
                                        if (currentCompletionData != null) {
962
1062
                                                DebugCompletionDataList dataList = new DebugCompletionDataList (currentCompletionData);
963
 
                                                CodeCompletionContext ctx = ((ICompletionWidget)this).CreateCodeCompletionContext (entry.CursorPosition - currentCompletionData.ExpressionLenght);
 
1063
                                                ctx = ((ICompletionWidget)this).CreateCodeCompletionContext (entry.CursorPosition - currentCompletionData.ExpressionLength);
964
1064
                                                CompletionWindowManager.ShowWindow (null, c, dataList, this, ctx);
965
 
                                        } else
 
1065
                                        }
 
1066
                                        else
966
1067
                                                currentCompletionData = null;
967
1068
                                }
968
1069
                        });
1002
1103
                                CleanPinIcon ();
1003
1104
                        return base.OnLeaveNotifyEvent (evnt);
1004
1105
                }
1005
 
 
 
1106
                
 
1107
                protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
 
1108
                {
 
1109
                        // Ignore if editing a cell, or if not editable
 
1110
                        if (!AllowEditing || !AllowAdding || editing)
 
1111
                                return base.OnKeyPressEvent (evnt);
 
1112
                        
 
1113
                        // Delete the current item with any delete key
 
1114
                        switch (evnt.Key) {
 
1115
                        case Gdk.Key.Delete:
 
1116
                        case Gdk.Key.KP_Delete:
 
1117
                        case Gdk.Key.BackSpace:
 
1118
                                if (Selection.CountSelectedRows () > 0) {
 
1119
                                        bool deleted = false;
 
1120
                                        string expression;
 
1121
                                        ObjectValue val;
 
1122
                                        TreeIter iter;
 
1123
 
 
1124
                                        // get a list of the selected rows (in reverse order so that we delete children before parents)
 
1125
                                        var selected = Selection.GetSelectedRows ();
 
1126
                                        Array.Sort (selected, new TreePathComparer (true));
 
1127
 
 
1128
                                        foreach (var path in selected) {
 
1129
                                                if (!Model.GetIter (out iter, path))
 
1130
                                                        continue;
 
1131
 
 
1132
                                                val = (ObjectValue)store.GetValue (iter, ObjectCol);
 
1133
                                                expression = GetFullExpression (iter);
 
1134
 
 
1135
                                                // Lookup and remove
 
1136
                                                if (val != null && values.Contains (val)) {
 
1137
                                                        RemoveValue (val);
 
1138
                                                        deleted = true;
 
1139
                                                } else if (!string.IsNullOrEmpty (expression) && valueNames.Contains (expression)) {
 
1140
                                                        RemoveExpression (expression);
 
1141
                                                        deleted = true;
 
1142
                                                }
 
1143
                                        }
 
1144
 
 
1145
                                        if (deleted)
 
1146
                                                return true;
 
1147
                                }
 
1148
                                break;
 
1149
                        }
 
1150
                        return base.OnKeyPressEvent (evnt);
 
1151
                }
1006
1152
 
1007
1153
                protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
1008
1154
                {
1080
1226
                        TreePath[] selected = Selection.GetSelectedRows ();
1081
1227
                        TreeIter iter;
1082
1228
                        
1083
 
                        if (selected == null || selected.Length != 1)
1084
 
                                return;
1085
 
                        
1086
 
                        if (!store.GetIter (out iter, selected[0]))
1087
 
                                return;
1088
 
 
1089
 
                        object focus = IdeApp.Workbench.RootWindow.Focus;
1090
 
 
1091
 
                        if (focus is Gtk.Editable) {
1092
 
                                ((Gtk.Editable) focus).CopyClipboard ();
1093
 
                                return;
1094
 
                        }
1095
 
                        
1096
 
                        string value = (string) store.GetValue (iter, ValueCol);
1097
 
                        Clipboard.Get (Gdk.Selection.Clipboard).Text = value;
 
1229
                        if (selected == null || selected.Length == 0)
 
1230
                                return;
 
1231
 
 
1232
                        if (selected.Length == 1) {
 
1233
                                object focus = IdeApp.Workbench.RootWindow.Focus;
 
1234
 
 
1235
                                if (focus is Gtk.Editable) {
 
1236
                                        ((Gtk.Editable) focus).CopyClipboard ();
 
1237
                                        return;
 
1238
                                }
 
1239
                        }
 
1240
 
 
1241
                        var values = new List<string> ();
 
1242
                        var names = new List<string> ();
 
1243
                        var types = new List<string> ();
 
1244
                        int maxValue = 0;
 
1245
                        int maxName = 0;
 
1246
 
 
1247
                        for (int i = 0; i < selected.Length; i++) {
 
1248
                                if (!store.GetIter (out iter, selected[i]))
 
1249
                                        continue;
 
1250
 
 
1251
                                string value = (string) store.GetValue (iter, ValueCol);
 
1252
                                string name = (string) store.GetValue (iter, NameCol);
 
1253
                                string type = (string) store.GetValue (iter, TypeCol);
 
1254
 
 
1255
                                maxValue = Math.Max (maxValue, value.Length);
 
1256
                                maxName = Math.Max (maxName, name.Length);
 
1257
 
 
1258
                                values.Add (value);
 
1259
                                names.Add (name);
 
1260
                                types.Add (type);
 
1261
                        }
 
1262
 
 
1263
                        var str = new StringBuilder ();
 
1264
                        for (int i = 0; i < values.Count; i++) {
 
1265
                                if (i > 0)
 
1266
                                        str.AppendLine ();
 
1267
 
 
1268
                                str.Append (names[i]);
 
1269
                                if (names[i].Length < maxName)
 
1270
                                        str.Append (new string (' ', maxName - names[i].Length));
 
1271
                                str.Append ('\t');
 
1272
                                str.Append (values[i]);
 
1273
                                if (values[i].Length < maxValue)
 
1274
                                        str.Append (new string (' ', maxValue - values[i].Length));
 
1275
                                str.Append ('\t');
 
1276
                                str.Append (types[i]);
 
1277
                        }
 
1278
 
 
1279
                        Clipboard.Get (Gdk.Selection.Clipboard).Text = str.ToString ();
1098
1280
                }
1099
1281
                
1100
1282
                [CommandHandler (EditCommands.Delete)]
1208
1390
                
1209
1391
                string GetFullExpression (TreeIter it)
1210
1392
                {
 
1393
                        TreePath path = store.GetPath (it);
1211
1394
                        string exp = "";
1212
 
                        while (store.GetPath (it).Depth != 1) {
1213
 
                                ObjectValue val = (ObjectValue) store.GetValue (it, ObjectCol);
 
1395
                        
 
1396
                        while (path.Depth != 1) {
 
1397
                                ObjectValue val = (ObjectValue)store.GetValue (it, ObjectCol);
1214
1398
                                exp = val.ChildSelector + exp;
1215
 
                                store.IterParent (out it, it);
 
1399
                                if (!store.IterParent (out it, it))
 
1400
                                        break;
 
1401
                                path = store.GetPath (it);
1216
1402
                        }
 
1403
 
1217
1404
                        string name = (string) store.GetValue (it, NameCol);
 
1405
 
1218
1406
                        return name + exp;
1219
1407
                }
1220
1408
 
1263
1451
                        }
1264
1452
                }
1265
1453
                
1266
 
                EventHandler completionContextChanged;
1267
 
                
1268
 
                event EventHandler ICompletionWidget.CompletionContextChanged {
1269
 
                        add { completionContextChanged += value; }
1270
 
                        remove { completionContextChanged -= value; }
 
1454
                public event EventHandler CompletionContextChanged;
 
1455
 
 
1456
                protected virtual void OnCompletionContextChanged (EventArgs e)
 
1457
                {
 
1458
                        EventHandler handler = this.CompletionContextChanged;
 
1459
                        if (handler != null)
 
1460
                                handler (this, e);
1271
1461
                }
1272
1462
                
1273
1463
                string ICompletionWidget.GetText (int startOffset, int endOffset)
1274
1464
                {
1275
 
                        if (startOffset < 0) startOffset = 0;
1276
 
                        if (endOffset > editEntry.Text.Length) endOffset = editEntry.Text.Length;
1277
 
                        return editEntry.Text.Substring (startOffset, endOffset - startOffset);
 
1465
                        string text = editEntry.Text;
 
1466
 
 
1467
                        if (startOffset < 0 || endOffset < 0 || startOffset > endOffset || startOffset >= text.Length)
 
1468
                                return "";
 
1469
 
 
1470
                        int length = Math.Min (endOffset - startOffset, text.Length - startOffset);
 
1471
 
 
1472
                        return text.Substring (startOffset, length);
1278
1473
                }
1279
1474
                
1280
1475
                void ICompletionWidget.Replace (int offset, int count, string text)
1307
1502
                        c.TriggerOffset = triggerOffset;
1308
1503
                        c.TriggerLineOffset = c.TriggerOffset;
1309
1504
                        c.TriggerTextHeight = editEntry.SizeRequest ().Height;
1310
 
                        c.TriggerWordLength = currentCompletionData.ExpressionLenght;
 
1505
                        c.TriggerWordLength = currentCompletionData.ExpressionLength;
1311
1506
                        
1312
1507
                        int x, y;
1313
1508
                        int tx, ty;
1398
1593
                
1399
1594
                Mono.Debugging.Client.CompletionData GetCompletionData (string exp)
1400
1595
                {
1401
 
                        if (frame != null)
 
1596
                        if (frame != null && frame.DebuggerSession.IsConnected)
1402
1597
                                return frame.GetExpressionCompletionData (exp);
1403
 
                        else
1404
 
                                return null;
 
1598
 
 
1599
                        return null;
1405
1600
                }
1406
1601
                
1407
1602
                internal void SetCustomFont (Pango.FontDescription font)
1418
1613
                        IsSorted = false;
1419
1614
                        foreach (CompletionItem it in data.Items)
1420
1615
                                Add (new DebugCompletionData (it));
 
1616
                        AutoSelect =true;
1421
1617
                }
1422
1618
                public bool AutoSelect { get; set; }
1423
1619
                public string DefaultCompletionString {
1433
1629
                public bool AutoCompleteEmptyMatch {
1434
1630
                        get { return false; }
1435
1631
                }
1436
 
                
 
1632
                public bool AutoCompleteEmptyMatchOnCurlyBrace {
 
1633
                        get { return false; }
 
1634
                }
1437
1635
                public bool CloseOnSquareBrackets {
1438
1636
                        get {
1439
1637
                                return false;