blob: e69365c144f3f02117aa03393a242acbadc635be [file] [log] [blame]
David Scherer7aced172000-08-15 01:13:23 +00001# XXX TO DO:
2# - popup menu
3# - support partial or total redisplay
4# - more doc strings
5# - tooltips
6
7# object browser
8
9# XXX TO DO:
10# - for classes/modules, add "open source" to object browser
11
Terry Jan Reedy62012fc2014-05-24 18:48:03 -040012import re
13
Florent Xiclunad630c042010-04-02 07:24:52 +000014from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas
David Scherer7aced172000-08-15 01:13:23 +000015
Brett Cannon2ee0e8e2008-05-23 05:03:59 +000016from repr import Repr
David Scherer7aced172000-08-15 01:13:23 +000017
18myrepr = Repr()
19myrepr.maxstring = 100
20myrepr.maxother = 100
21
22class ObjectTreeItem(TreeItem):
23 def __init__(self, labeltext, object, setfunction=None):
24 self.labeltext = labeltext
25 self.object = object
26 self.setfunction = setfunction
27 def GetLabelText(self):
28 return self.labeltext
29 def GetText(self):
30 return myrepr.repr(self.object)
31 def GetIconName(self):
32 if not self.IsExpandable():
33 return "python"
34 def IsEditable(self):
35 return self.setfunction is not None
36 def SetText(self, text):
37 try:
38 value = eval(text)
39 self.setfunction(value)
40 except:
41 pass
42 else:
43 self.object = value
44 def IsExpandable(self):
45 return not not dir(self.object)
46 def GetSubList(self):
47 keys = dir(self.object)
48 sublist = []
49 for key in keys:
50 try:
51 value = getattr(self.object, key)
52 except AttributeError:
53 continue
54 item = make_objecttreeitem(
55 str(key) + " =",
56 value,
57 lambda value, key=key, object=self.object:
58 setattr(object, key, value))
59 sublist.append(item)
60 return sublist
61
62class InstanceTreeItem(ObjectTreeItem):
63 def IsExpandable(self):
Kurt B. Kaiser33931ef2002-09-16 22:16:05 +000064 return True
David Scherer7aced172000-08-15 01:13:23 +000065 def GetSubList(self):
66 sublist = ObjectTreeItem.GetSubList(self)
67 sublist.insert(0,
68 make_objecttreeitem("__class__ =", self.object.__class__))
69 return sublist
70
71class ClassTreeItem(ObjectTreeItem):
72 def IsExpandable(self):
Kurt B. Kaiser33931ef2002-09-16 22:16:05 +000073 return True
David Scherer7aced172000-08-15 01:13:23 +000074 def GetSubList(self):
75 sublist = ObjectTreeItem.GetSubList(self)
76 if len(self.object.__bases__) == 1:
77 item = make_objecttreeitem("__bases__[0] =",
78 self.object.__bases__[0])
79 else:
80 item = make_objecttreeitem("__bases__ =", self.object.__bases__)
81 sublist.insert(0, item)
82 return sublist
83
84class AtomicObjectTreeItem(ObjectTreeItem):
85 def IsExpandable(self):
86 return 0
87
88class SequenceTreeItem(ObjectTreeItem):
89 def IsExpandable(self):
90 return len(self.object) > 0
91 def keys(self):
92 return range(len(self.object))
93 def GetSubList(self):
94 sublist = []
95 for key in self.keys():
96 try:
97 value = self.object[key]
98 except KeyError:
99 continue
100 def setfunction(value, key=key, object=self.object):
101 object[key] = value
Walter Dörwald70a6b492004-02-12 17:35:32 +0000102 item = make_objecttreeitem("%r:" % (key,), value, setfunction)
David Scherer7aced172000-08-15 01:13:23 +0000103 sublist.append(item)
104 return sublist
105
106class DictTreeItem(SequenceTreeItem):
107 def keys(self):
108 keys = self.object.keys()
109 try:
110 keys.sort()
111 except:
112 pass
113 return keys
114
115from types import *
116
117dispatch = {
118 IntType: AtomicObjectTreeItem,
119 LongType: AtomicObjectTreeItem,
120 FloatType: AtomicObjectTreeItem,
121 StringType: AtomicObjectTreeItem,
122 TupleType: SequenceTreeItem,
123 ListType: SequenceTreeItem,
124 DictType: DictTreeItem,
125 InstanceType: InstanceTreeItem,
126 ClassType: ClassTreeItem,
127}
128
129def make_objecttreeitem(labeltext, object, setfunction=None):
130 t = type(object)
Benjamin Peterson6e3dbbd2009-10-09 22:15:50 +0000131 if t in dispatch:
David Scherer7aced172000-08-15 01:13:23 +0000132 c = dispatch[t]
133 else:
134 c = ObjectTreeItem
135 return c(labeltext, object, setfunction)
136
David Scherer7aced172000-08-15 01:13:23 +0000137
Terry Jan Reedy62012fc2014-05-24 18:48:03 -0400138def _object_browser(parent):
David Scherer7aced172000-08-15 01:13:23 +0000139 import sys
Georg Brandl6634bf22008-05-20 07:13:37 +0000140 from Tkinter import Tk
Kurt B. Kaiser6a945a52001-07-13 17:57:37 +0000141 root = Tk()
Terry Jan Reedy76916e82014-05-29 01:46:16 -0400142 root.title("Test ObjectBrowser")
Terry Jan Reedy62012fc2014-05-24 18:48:03 -0400143 width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
Terry Jan Reedy76916e82014-05-29 01:46:16 -0400144 root.geometry("+%d+%d"%(x, y + 150))
David Scherer7aced172000-08-15 01:13:23 +0000145 root.configure(bd=0, bg="yellow")
146 root.focus_set()
147 sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
148 sc.frame.pack(expand=1, fill="both")
149 item = make_objecttreeitem("sys", sys)
150 node = TreeNode(sc.canvas, None, item)
Kurt B. Kaiser6a945a52001-07-13 17:57:37 +0000151 node.update()
152 root.mainloop()
David Scherer7aced172000-08-15 01:13:23 +0000153
154if __name__ == '__main__':
Terry Jan Reedy62012fc2014-05-24 18:48:03 -0400155 from idlelib.idle_test.htest import run
156 run(_object_browser)