1# 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
12from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas
13
14from repr import Repr
15
16myrepr = Repr()
17myrepr.maxstring = 100
18myrepr.maxother = 100
19
20class ObjectTreeItem(TreeItem):
21    def __init__(self, labeltext, object, setfunction=None):
22        self.labeltext = labeltext
23        self.object = object
24        self.setfunction = setfunction
25    def GetLabelText(self):
26        return self.labeltext
27    def GetText(self):
28        return myrepr.repr(self.object)
29    def GetIconName(self):
30        if not self.IsExpandable():
31            return "python"
32    def IsEditable(self):
33        return self.setfunction is not None
34    def SetText(self, text):
35        try:
36            value = eval(text)
37            self.setfunction(value)
38        except:
39            pass
40        else:
41            self.object = value
42    def IsExpandable(self):
43        return not not dir(self.object)
44    def GetSubList(self):
45        keys = dir(self.object)
46        sublist = []
47        for key in keys:
48            try:
49                value = getattr(self.object, key)
50            except AttributeError:
51                continue
52            item = make_objecttreeitem(
53                str(key) + " =",
54                value,
55                lambda value, key=key, object=self.object:
56                    setattr(object, key, value))
57            sublist.append(item)
58        return sublist
59
60class InstanceTreeItem(ObjectTreeItem):
61    def IsExpandable(self):
62        return True
63    def GetSubList(self):
64        sublist = ObjectTreeItem.GetSubList(self)
65        sublist.insert(0,
66            make_objecttreeitem("__class__ =", self.object.__class__))
67        return sublist
68
69class ClassTreeItem(ObjectTreeItem):
70    def IsExpandable(self):
71        return True
72    def GetSubList(self):
73        sublist = ObjectTreeItem.GetSubList(self)
74        if len(self.object.__bases__) == 1:
75            item = make_objecttreeitem("__bases__[0] =",
76                self.object.__bases__[0])
77        else:
78            item = make_objecttreeitem("__bases__ =", self.object.__bases__)
79        sublist.insert(0, item)
80        return sublist
81
82class AtomicObjectTreeItem(ObjectTreeItem):
83    def IsExpandable(self):
84        return 0
85
86class SequenceTreeItem(ObjectTreeItem):
87    def IsExpandable(self):
88        return len(self.object) > 0
89    def keys(self):
90        return range(len(self.object))
91    def GetSubList(self):
92        sublist = []
93        for key in self.keys():
94            try:
95                value = self.object[key]
96            except KeyError:
97                continue
98            def setfunction(value, key=key, object=self.object):
99                object[key] = value
100            item = make_objecttreeitem("%r:" % (key,), value, setfunction)
101            sublist.append(item)
102        return sublist
103
104class DictTreeItem(SequenceTreeItem):
105    def keys(self):
106        keys = self.object.keys()
107        try:
108            keys.sort()
109        except:
110            pass
111        return keys
112
113from types import *
114
115dispatch = {
116    IntType: AtomicObjectTreeItem,
117    LongType: AtomicObjectTreeItem,
118    FloatType: AtomicObjectTreeItem,
119    StringType: AtomicObjectTreeItem,
120    TupleType: SequenceTreeItem,
121    ListType: SequenceTreeItem,
122    DictType: DictTreeItem,
123    InstanceType: InstanceTreeItem,
124    ClassType: ClassTreeItem,
125}
126
127def make_objecttreeitem(labeltext, object, setfunction=None):
128    t = type(object)
129    if t in dispatch:
130        c = dispatch[t]
131    else:
132        c = ObjectTreeItem
133    return c(labeltext, object, setfunction)
134
135# Test script
136
137def _test():
138    import sys
139    from Tkinter import Tk
140    root = Tk()
141    root.configure(bd=0, bg="yellow")
142    root.focus_set()
143    sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
144    sc.frame.pack(expand=1, fill="both")
145    item = make_objecttreeitem("sys", sys)
146    node = TreeNode(sc.canvas, None, item)
147    node.update()
148    root.mainloop()
149
150if __name__ == '__main__':
151    _test()
152