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 12import re 13 14from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas 15 16from repr import Repr 17 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): 64 return True 65 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): 73 return True 74 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 102 item = make_objecttreeitem("%r:" % (key,), value, setfunction) 103 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) 131 if t in dispatch: 132 c = dispatch[t] 133 else: 134 c = ObjectTreeItem 135 return c(labeltext, object, setfunction) 136 137 138def _object_browser(parent): 139 import sys 140 from Tkinter import Tk 141 root = Tk() 142 root.title("Test ObjectBrowser") 143 width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) 144 root.geometry("+%d+%d"%(x, y + 150)) 145 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) 151 node.update() 152 root.mainloop() 153 154if __name__ == '__main__': 155 from idlelib.idle_test.htest import run 156 run(_object_browser) 157