]> git.saurik.com Git - wxWidgets.git/blob - wxPython/tests/pytree.py
Allow for multiple CHM controllers in app (don't leak dynamic libs)
[wxWidgets.git] / wxPython / tests / pytree.py
1 """
2 Hello, and welcome to this test of the wxTreeItemData class.
3
4 The wxTreeItemData class can be used to associate a python object with
5 a wxTreeCtrl item. In this sample, its use is demonstrated via a tree
6 control that shows the contents of a python namespace according to the
7 standard dir() command. Every item in the tree has its label taken
8 from the dir() output, and 'behind it' a reference to the python
9 object is stored in a wxTreeItemData object.
10
11 As you may have guessed by now, this sample automatically displays
12 '__doc__' strings if the selected python object happens to have
13 one. Please expand the pyTree object to learn more about the
14 implementation.
15
16 Version 1.0, April 4 1999.
17 Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)
18
19 P.S. Check out the string module. It's imported in this sample not
20 because it's used, but because it's so beautifully documented...
21 """
22
23 from wxPython import wx
24 import string # Don't use it, but it's fun expanding :-)
25
26 #----------------------------------------------------------------------
27
28 def _getindent(line):
29 """Returns the indentation level of the given line."""
30 indent = 0
31 for c in line:
32 if c == ' ': indent = indent + 1
33 elif c == '\t': indent = indent + 8
34 else: break
35 return indent
36
37 def _sourcefinder(func):
38 """Given a func_code object, this function tries to find and return
39 the python source code of the function."""
40 try:
41 f = open(func.co_filename,"r")
42 except:
43 return "(could not open file %s)" % (func.co_filename,)
44
45 for i in range(func.co_firstlineno):
46 line = f.readline()
47 ind = _getindent(line)
48 msg = ""
49 while line:
50 msg = msg + line
51 line = f.readline()
52 # the following should be <= ind, but then we get
53 # confused by multiline docstrings. Using == works most of
54 # the time... but not always!
55 if _getindent(line) == ind: break
56 return msg
57
58 #----------------------------------------------------------------------
59
60 class pyTree(wx.wxTreeCtrl):
61 """
62 This wxTreeCtrl derivative displays a tree view of a Python namespace.
63 Anything from which the dir() command returns a non-empty list is a branch
64 in this tree.
65 """
66
67 def __init__(self, parent, id, root):
68 """
69 Initialize function; because we insert branches into the tree
70 as needed, we use the ITEM_EXPANDING event handler. The
71 ITEM_COLLAPSED handler removes the stuff afterwards. The
72 SEL_CHANGED handler attempts to display interesting
73 information about the selected object.
74 """
75 wx.wxTreeCtrl.__init__(self, parent, id)
76 self.root = self.AddRoot(str(root), -1, -1, wx.wxTreeItemData(root))
77 if dir(root):
78 self.SetItemHasChildren(self.root, wx.TRUE)
79 wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
80 wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
81 wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
82 self.output = None
83
84
85 def SetOutput(self, output):
86 """
87 Set output function (accepts single string). Used to display string
88 representation of the selected object by OnSelChanged.
89 """
90 self.output = output
91
92
93 def OnItemExpanding(self,event):
94 """
95 The real workhorse of this class. First we retrieve the object
96 (parent) belonging to the branch that is to be expanded. This
97 is done by calling GetPyData(parent), which is a short-cut for
98 GetPyItemData(parent).Get().
99
100 Then we get the dir() list of that object. For each item in
101 this list, a tree item is created with associated
102 wxTreeItemData referencing the child object. We get this
103 object using child = getattr(parent, item).
104
105 Finally, we check wether the child returns a non-empty dir()
106 list. If so, it is labeled as 'having children', so that it
107 may be expanded. When it actually is expanded, this function
108 will again figure out what the offspring is.
109 """
110 item = event.GetItem()
111 obj = self.GetPyData( item )
112 lst = dir(obj)
113 for key in lst:
114 new_obj = getattr(obj,key)
115 new_item = self.AppendItem( item, key, -1, -1,
116 wx.wxTreeItemData(new_obj) )
117 if dir(new_obj):
118 self.SetItemHasChildren(new_item, wx.TRUE)
119
120 def OnItemCollapsed(self, event):
121 """
122 We need to remove all children here, otherwise we'll see all
123 that old rubbish again after the next expansion.
124 """
125 item = event.GetItem()
126 self.DeleteChildren(item)
127
128 def OnSelChanged(self, event):
129 """
130 If an output function is defined, we try to print some
131 informative, interesting and thought-provoking stuff to it.
132 If it has a __doc__ string, we print it. If it's a function or
133 unbound class method, we attempt to find the python source.
134 """
135 if not self.output:
136 return
137 obj = self.GetPyData( event.GetItem() )
138 msg = str(obj)
139 if hasattr(obj, '__doc__'):
140 msg = msg+"\n\nDocumentation string:\n\n%s" % ( getattr(obj, '__doc__'),)
141 # Is it a function?
142 func = None
143 if hasattr(obj, "func_code"): # normal function
144 func = getattr(obj, "func_code")
145 elif hasattr(obj, "im_func"): # unbound class method
146 func = getattr(getattr(obj, "im_func"), "func_code")
147 if func: # if we found one, let's try to print the source
148 msg = msg+"\n\nFunction source:\n\n" + _sourcefinder(func)
149
150 apply(self.output, (msg,))
151
152 #----------------------------------------------------------------------
153
154 overview = __doc__
155
156 def runTest(frame, nb, log):
157 split = wx.wxSplitterWindow(nb, -1)
158 tree = pyTree(split, -1, __main__)
159 text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
160 wx.wxDefaultSize, wx.wxTE_MULTILINE)
161 split.SplitVertically(tree, text, 200)
162 tree.SetOutput(text.SetValue)
163 tree.SelectItem(tree.root)
164 text.SetBackgroundColour(wxNamedColour("LIGHT BLUE"))
165 tree.SetBackgroundColour(wxNamedColour("LIGHT BLUE"))
166
167 return split
168
169
170
171 #----------------------------------------------------------------------
172 if __name__ == '__main__':
173
174 class MyFrame(wx.wxFrame):
175 """Very standard Frame class. Nothing special here!"""
176
177 def __init__(self):
178 """Make a splitter window; left a tree, right a textctrl. Wow."""
179 import __main__
180 wx.wxFrame.__init__(self, wx.NULL, -1, "PyTreeItemData Test",
181 wx.wxDefaultPosition, wx.wxSize(800,500))
182 split = wx.wxSplitterWindow(self, -1)
183 tree = pyTree(split, -1, __main__)
184 text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
185 wx.wxDefaultSize, wx.wxTE_MULTILINE)
186 split.SplitVertically(tree, text, 200)
187 tree.SetOutput(text.SetValue)
188 tree.SelectItem(tree.root)
189
190 class MyApp(wx.wxApp):
191 """This class is even less interesting than MyFrame."""
192
193 def OnInit(self):
194 """OnInit. Boring, boring, boring!"""
195 frame = MyFrame()
196 frame.Show(wx.TRUE)
197 self.SetTopWindow(frame)
198 return wx.TRUE
199
200 app = MyApp(0)
201 app.MainLoop()
202
203