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> ();
54
57
TreeViewState state;
58
61
bool allowExpanding = true;
62
bool restoringState = false;
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));
133
137
RulesHint = true;
138
EnableSearch = false;
134
139
Selection.Mode = Gtk.SelectionMode.Multiple;
135
140
ResetColumnSizes ();
250
261
AdjustColumnSizes ();
264
protected override void OnRealized ()
267
AdjustColumnSizes ();
254
270
void OnColumnWidthChanged (object o, GLib.NotifyArgs args)
256
272
if (!columnSizesUpdating && allowStoreColumnSizes) {
257
273
StoreColumnSizes ();
262
277
void AdjustColumnSizes ()
264
if (!IsRealized || !Visible || Allocation.Width == 0 || columnSizesUpdating || compact)
279
if (!Visible || Allocation.Width <= 0 || columnSizesUpdating || compact)
267
282
columnSizesUpdating = true;
269
284
double width = (double) Allocation.Width;
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;
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;
284
int tval = (int) (width * valueColWidth);
298
int tval = Math.Max ((int) (width * valueColWidth), 1);
286
300
if (tval != valueCol.FixedWidth) {
287
301
valueCol.FixedWidth = tval;
506
536
if (!store.IterParent (out parent, it))
507
537
parent = TreeIter.Zero;
509
EvaluationOptions ops = frame.DebuggerSession.Options.EvaluationOptions.Clone ();
510
ops.AllowMethodEvaluation = true;
511
ops.AllowToStringCalls = true;
512
ops.AllowTargetInvoke = true;
513
ops.EllipsizeStrings = false;
515
string oldName = val.Name;
518
// Don't update the name for the values entered by the user
519
if (store.IterDepth (it) == 0)
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;
546
string oldName = val.Name;
549
// Don't update the name for the values entered by the user
550
if (store.IterDepth (it) == 0)
522
554
SetValues (parent, it, val.Name, val);
523
555
RegisterValue (val, it);
661
693
oldValues.TryGetValue (valPath, out oldValue);
663
695
if (val.IsUnknown) {
664
strval = GettextCatalog.GetString ("The name '{0}' does not exist in the current context.", val.Name);
665
nameColor = disabledColor;
697
strval = GettextCatalog.GetString ("The name '{0}' does not exist in the current context.", val.Name);
698
nameColor = disabledColor;
701
canEdit = !val.IsReadOnly;
702
strval = string.Empty;
668
705
else if (val.IsError) {
669
706
strval = val.Value;
699
736
strval = strval.Replace (Environment.NewLine, " ");
701
738
bool showViewerButton = DebuggingService.HasValueVisualizers (val);
740
bool hasChildren = val.HasChildren;
703
741
string icon = GetIcon (val.Flags);
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");
728
if (val.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;
742
780
string stic = (flags & ObjectValueFlags.Global) != 0 ? "static-" : string.Empty;
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";
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;
761
801
return "md-" + access + stic + source;
764
804
protected override bool OnTestExpandRow (TreeIter iter, TreePath path)
769
if (GetRowExpanded (path))
773
if (store.IterParent (out parent, iter)) {
774
if (!GetRowExpanded (store.GetPath (parent)))
806
if (!restoringState) {
810
if (GetRowExpanded (path))
814
if (store.IterParent (out parent, iter)) {
815
if (!GetRowExpanded (store.GetPath (parent)))
778
820
return base.OnTestExpandRow (iter, path);
786
828
ColumnsAutosize ();
831
static Task<ObjectValue[]> GetChildrenAsync (ObjectValue value)
833
return Task.Factory.StartNew<ObjectValue[]> (delegate (object arg) {
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];
844
void AddChildrenAsync (ObjectValue value, TreePathReference row)
848
if (expandTasks.TryGetValue (value, out task))
851
task = GetChildrenAsync (value).ContinueWith (t => {
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);
861
store.Remove (ref it);
867
expandTasks.Remove (value);
869
}, Xwt.Application.UITaskScheduler);
870
expandTasks.Add (value, task);
789
873
protected override void OnRowExpanded (TreeIter iter, TreePath path)
794
878
if (store.IterChildren (out it, iter)) {
795
ObjectValue val = (ObjectValue) store.GetValue (it, ObjectCol);
797
val = (ObjectValue) store.GetValue (iter, ObjectCol);
800
foreach (ObjectValue cval in val.GetAllChildren ()) {
801
SetValues (iter, it, null, cval);
802
RegisterValue (cval, it);
803
it = store.InsertNodeAfter (it);
806
store.Remove (ref it);
879
ObjectValue value = (ObjectValue) store.GetValue (it, ObjectCol);
881
value = (ObjectValue) store.GetValue (iter, ObjectCol);
882
AddChildrenAsync (value, new TreePathReference (store, store.GetPath (iter)));
810
886
base.OnRowExpanded (iter, path);
816
889
string GetIterPath (TreeIter iter)
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);
1012
void HandleChanged (object sender, EventArgs e)
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);
935
1022
void OnEndEditing ()
937
1024
editing = false;
938
1025
editEntry.KeyPressEvent -= OnEditKeyPress;
1026
editEntry.KeyReleaseEvent -= HandleChanged;
939
1028
CompletionWindowManager.HideWindow ();
940
1029
currentCompletionData = null;
941
1030
if (EndEditing != null)
942
1031
EndEditing (this, EventArgs.Empty);
1033
bool wasHandled = false;
1034
CodeCompletionContext ctx;
1037
Gdk.ModifierType modifierState;
945
1040
[GLib.ConnectBeforeAttribute]
946
1041
void OnEditKeyPress (object s, Gtk.KeyPressEventArgs args)
948
Gtk.Entry entry = (Gtk.Entry)s;
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);
1049
wasHandled = CompletionWindowManager.PreProcessKeyEvent (key, keyChar, modifierState);
1050
args.RetVal = wasHandled ;
1054
void PopupCompletion (Entry entry)
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);
966
1067
currentCompletionData = null;
1002
1103
CleanPinIcon ();
1003
1104
return base.OnLeaveNotifyEvent (evnt);
1107
protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
1109
// Ignore if editing a cell, or if not editable
1110
if (!AllowEditing || !AllowAdding || editing)
1111
return base.OnKeyPressEvent (evnt);
1113
// Delete the current item with any delete 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;
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));
1128
foreach (var path in selected) {
1129
if (!Model.GetIter (out iter, path))
1132
val = (ObjectValue)store.GetValue (iter, ObjectCol);
1133
expression = GetFullExpression (iter);
1135
// Lookup and remove
1136
if (val != null && values.Contains (val)) {
1139
} else if (!string.IsNullOrEmpty (expression) && valueNames.Contains (expression)) {
1140
RemoveExpression (expression);
1150
return base.OnKeyPressEvent (evnt);
1007
1153
protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
1080
1226
TreePath[] selected = Selection.GetSelectedRows ();
1083
if (selected == null || selected.Length != 1)
1086
if (!store.GetIter (out iter, selected[0]))
1089
object focus = IdeApp.Workbench.RootWindow.Focus;
1091
if (focus is Gtk.Editable) {
1092
((Gtk.Editable) focus).CopyClipboard ();
1096
string value = (string) store.GetValue (iter, ValueCol);
1097
Clipboard.Get (Gdk.Selection.Clipboard).Text = value;
1229
if (selected == null || selected.Length == 0)
1232
if (selected.Length == 1) {
1233
object focus = IdeApp.Workbench.RootWindow.Focus;
1235
if (focus is Gtk.Editable) {
1236
((Gtk.Editable) focus).CopyClipboard ();
1241
var values = new List<string> ();
1242
var names = new List<string> ();
1243
var types = new List<string> ();
1247
for (int i = 0; i < selected.Length; i++) {
1248
if (!store.GetIter (out iter, selected[i]))
1251
string value = (string) store.GetValue (iter, ValueCol);
1252
string name = (string) store.GetValue (iter, NameCol);
1253
string type = (string) store.GetValue (iter, TypeCol);
1255
maxValue = Math.Max (maxValue, value.Length);
1256
maxName = Math.Max (maxName, name.Length);
1263
var str = new StringBuilder ();
1264
for (int i = 0; i < values.Count; i++) {
1268
str.Append (names[i]);
1269
if (names[i].Length < maxName)
1270
str.Append (new string (' ', maxName - names[i].Length));
1272
str.Append (values[i]);
1273
if (values[i].Length < maxValue)
1274
str.Append (new string (' ', maxValue - values[i].Length));
1276
str.Append (types[i]);
1279
Clipboard.Get (Gdk.Selection.Clipboard).Text = str.ToString ();
1100
1282
[CommandHandler (EditCommands.Delete)]
1209
1391
string GetFullExpression (TreeIter it)
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);
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))
1401
path = store.GetPath (it);
1217
1404
string name = (string) store.GetValue (it, NameCol);
1218
1406
return name + exp;
1266
EventHandler completionContextChanged;
1268
event EventHandler ICompletionWidget.CompletionContextChanged {
1269
add { completionContextChanged += value; }
1270
remove { completionContextChanged -= value; }
1454
public event EventHandler CompletionContextChanged;
1456
protected virtual void OnCompletionContextChanged (EventArgs e)
1458
EventHandler handler = this.CompletionContextChanged;
1459
if (handler != null)
1273
1463
string ICompletionWidget.GetText (int startOffset, int endOffset)
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;
1467
if (startOffset < 0 || endOffset < 0 || startOffset > endOffset || startOffset >= text.Length)
1470
int length = Math.Min (endOffset - startOffset, text.Length - startOffset);
1472
return text.Substring (startOffset, length);
1280
1475
void ICompletionWidget.Replace (int offset, int count, string text)