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