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 12 from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas 13 14 from repr import Repr 15 16 myrepr = Repr() 17 myrepr.maxstring = 100 18 myrepr.maxother = 100 19 20 class 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 60 class 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 69 class 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 82 class AtomicObjectTreeItem(ObjectTreeItem): 83 def IsExpandable(self): 84 return 0 85 86 class 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 104 class DictTreeItem(SequenceTreeItem): 105 def keys(self): 106 keys = self.object.keys() 107 try: 108 keys.sort() 109 except: 110 pass 111 return keys 112 113 from types import * 114 115 dispatch = { 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 127 def 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 137 def _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 150 if __name__ == '__main__': 151 _test() 152