]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxPython/lib/PyCrust/filling.py
83bc34a79b2344a1eb22aa66a49e011b2363552e
[wxWidgets.git] / wxPython / wxPython / lib / PyCrust / filling.py
1 """PyCrust Filling is the gui tree control through which a user can navigate
2 the local namespace or any object."""
3
4 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
5 __cvsid__ = "$Id$"
6 __date__ = "August 21, 2001"
7 __version__ = "$Revision$"[11:-2]
8
9 from wxPython.wx import *
10 from wxPython.stc import *
11 from version import VERSION
12 import inspect
13 import introspect
14 import keyword
15 import sys
16 import types
17
18
19 class FillingTree(wxTreeCtrl):
20 """PyCrust FillingTree based on wxTreeCtrl."""
21
22 name = 'PyCrust Filling Tree'
23 revision = __version__
24
25 def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
26 size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \
27 rootObject=None, rootLabel=None, rootIsNamespace=0):
28 """Create a PyCrust FillingTree instance."""
29 wxTreeCtrl.__init__(self, parent, id, pos, size)
30 self.rootIsNamespace = rootIsNamespace
31 if not rootObject:
32 import __main__
33 rootObject = __main__
34 self.rootIsNamespace = 1
35 if not rootLabel: rootLabel = 'Ingredients'
36 rootData = wxTreeItemData(rootObject)
37 self.root = self.AddRoot(rootLabel, -1, -1, rootData)
38 self.SetItemHasChildren(self.root, self.hasChildren(self.root))
39 EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
40 EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
41 EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
42
43 def hasChildren(self, object):
44 """Return true if object has children."""
45 if self.getChildren(object):
46 return true
47 else:
48 return false
49
50 def getChildren(self, object):
51 """Return a dictionary with the attributes or contents of object."""
52 dict = {}
53 objtype = type(object)
54 if objtype is types.DictType:
55 dict = object
56 elif objtype in (types.InstanceType, types.ModuleType):
57 for key in introspect.getAttributeNames(object):
58 # Believe it or not, some attributes can disappear, such as
59 # the exc_traceback attribute of the sys module. So this is
60 # nested in a try block.
61 try:
62 dict[key] = getattr(object, key)
63 except:
64 pass
65 return dict
66
67 def OnItemExpanding(self, event):
68 selection = event.GetItem()
69 if self.IsExpanded(selection):
70 return
71 object = self.GetPyData(selection)
72 children = self.getChildren(object)
73 if not children:
74 return
75 list = children.keys()
76 list.sort()
77 for item in list:
78 itemtext = str(item)
79 # Show string dictionary items with single quotes, except for
80 # the first level of items, if they represent a namespace.
81 if type(object) is types.DictType \
82 and type(item) is types.StringType \
83 and (selection != self.root \
84 or (selection == self.root and not self.rootIsNamespace)):
85 itemtext = repr(item)
86 child = self.AppendItem(selection, itemtext, -1, -1, \
87 wxTreeItemData(children[item]))
88 self.SetItemHasChildren(child, self.hasChildren(children[item]))
89
90 def OnItemCollapsed(self, event):
91 """Remove all children from the item."""
92 item = event.GetItem()
93 self.DeleteChildren(item)
94
95 def OnSelChanged(self, event):
96 item = event.GetItem()
97 if item == self.root:
98 self.setText('')
99 return
100 object = self.GetPyData(item)
101 text = ''
102 text += self.getFullName(item)
103 text += '\n\nType: ' + str(type(object))[7:-2]
104 value = str(object)
105 if type(object) is types.StringType:
106 value = repr(value)
107 text += '\n\nValue: ' + value
108 if type(object) is types.InstanceType:
109 try:
110 text += '\n\nClass Definition:\n\n' + \
111 inspect.getsource(object.__class__)
112 except:
113 try:
114 text += '\n\n"""' + inspect.getdoc(object).strip() + '"""'
115 except:
116 pass
117 else:
118 try:
119 text += '\n\nSource Code:\n\n' + \
120 inspect.getsource(object)
121 except:
122 try:
123 text += '\n\n"""' + inspect.getdoc(object).strip() + '"""'
124 except:
125 pass
126 self.setText(text)
127
128 def getFullName(self, item, partial=''):
129 """Return a syntactically proper name for item."""
130 parent = self.GetItemParent(item)
131 parentobject = self.GetPyData(parent)
132 name = self.GetItemText(item)
133 # Apply dictionary syntax to dictionary items, except the root
134 # and first level children of a namepace.
135 if type(parentobject) is types.DictType \
136 and ((item != self.root and parent != self.root) \
137 or (parent == self.root and not self.rootIsNamespace)):
138 name = '[' + name + ']'
139 # Apply dot syntax to multipart names.
140 if partial:
141 if partial[0] == '[':
142 name += partial
143 else:
144 name += '.' + partial
145 # Repeat for everything but the root item
146 # and first level children of a namespace.
147 if (item != self.root and parent != self.root) \
148 or (parent == self.root and not self.rootIsNamespace):
149 name = self.getFullName(parent, partial=name)
150 return name
151
152 def setText(self, text):
153 """Display information about the current selection."""
154
155 # This method will most likely be replaced by the enclosing app
156 # to do something more interesting, like write to a text control.
157 print text
158
159 def setStatusText(self, text):
160 """Display status information."""
161
162 # This method will most likely be replaced by the enclosing app
163 # to do something more interesting, like write to a status bar.
164 print text
165
166
167 if wxPlatform == '__WXMSW__':
168 faces = { 'times' : 'Times New Roman',
169 'mono' : 'Courier New',
170 'helv' : 'Lucida Console',
171 'lucida' : 'Lucida Console',
172 'other' : 'Comic Sans MS',
173 'size' : 8,
174 'lnsize' : 7,
175 'backcol': '#FFFFFF',
176 }
177 else: # GTK
178 faces = { 'times' : 'Times',
179 'mono' : 'Courier',
180 'helv' : 'Helvetica',
181 'other' : 'new century schoolbook',
182 'size' : 12,
183 'lnsize' : 10,
184 'backcol': '#FFFFFF',
185 }
186
187
188 class FillingText(wxStyledTextCtrl):
189 """PyCrust FillingText based on wxStyledTextCtrl."""
190
191 name = 'PyCrust Filling Text'
192 revision = __version__
193
194 def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
195 size=wxDefaultSize, style=wxCLIP_CHILDREN):
196 """Create a PyCrust FillingText instance."""
197 wxStyledTextCtrl.__init__(self, parent, id, pos, size, style)
198 # Configure various defaults and user preferences.
199 self.config()
200
201 def config(self):
202 """Configure shell based on user preferences."""
203 self.SetMarginWidth(1, 0)
204
205 self.SetLexer(wxSTC_LEX_PYTHON)
206 self.SetKeyWords(0, ' '.join(keyword.kwlist))
207
208 self.setStyles(faces)
209 self.SetViewWhiteSpace(0)
210 self.SetTabWidth(4)
211 self.SetUseTabs(0)
212
213 def setStyles(self, faces):
214 """Configure font size, typeface and color for lexer."""
215
216 # Default style
217 self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
218
219 self.StyleClearAll()
220
221 # Built in styles
222 self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
223 self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces)
224 self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88")
225 self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88")
226
227 # Python styles
228 self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces)
229 self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces)
230 self.StyleSetSpec(wxSTC_P_NUMBER, "")
231 self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces)
232 self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces)
233 self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold")
234 self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000")
235 self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8")
236 self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold")
237 self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold")
238 self.StyleSetSpec(wxSTC_P_OPERATOR, "")
239 self.StyleSetSpec(wxSTC_P_IDENTIFIER, "")
240 self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F")
241 self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
242
243
244 class Filling(wxSplitterWindow):
245 """PyCrust Filling based on wxSplitterWindow."""
246
247 name = 'PyCrust Filling'
248 revision = __version__
249
250 def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
251 size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \
252 rootObject=None, rootLabel=None, rootIsNamespace=0):
253 """Create a PyCrust Filling instance."""
254 wxSplitterWindow.__init__(self, parent, id, pos, size, style, name)
255 self.fillingTree = FillingTree(parent=self, rootObject=rootObject, \
256 rootLabel=rootLabel, \
257 rootIsNamespace=rootIsNamespace)
258 self.fillingText = FillingText(parent=self)
259 self.SplitVertically(self.fillingTree, self.fillingText, 200)
260 self.SetMinimumPaneSize(1)
261 # Override the filling so that descriptions go to fillingText.
262 self.fillingTree.setText = self.fillingText.SetText
263 # Select the root item.
264 self.fillingTree.SelectItem(self.fillingTree.root)
265
266
267 class FillingFrame(wxFrame):
268 """Frame containing the PyCrust filling, or namespace tree component."""
269
270 name = 'PyCrust Filling Frame'
271 revision = __version__
272
273 def __init__(self, parent=None, id=-1, title='PyFilling', \
274 pos=wxDefaultPosition, size=wxDefaultSize, \
275 style=wxDEFAULT_FRAME_STYLE, rootObject=None, \
276 rootLabel=None, rootIsNamespace=0):
277 """Create a PyCrust FillingFrame instance."""
278 wxFrame.__init__(self, parent, id, title, pos, size, style)
279 intro = 'Welcome To PyFilling - The Tastiest Namespace Inspector'
280 self.CreateStatusBar()
281 self.SetStatusText(intro)
282 if wxPlatform == '__WXMSW__':
283 icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO)
284 self.SetIcon(icon)
285 self.filling = Filling(parent=self, rootObject=rootObject, \
286 rootLabel=rootLabel, \
287 rootIsNamespace=rootIsNamespace)
288 # Override the filling so that status messages go to the status bar.
289 self.filling.fillingTree.setStatusText = self.SetStatusText
290
291
292 class App(wxApp):
293 """PyFilling standalone application."""
294
295 def OnInit(self):
296 self.fillingFrame = FillingFrame()
297 self.fillingFrame.Show(true)
298 self.SetTopWindow(self.fillingFrame)
299 return true
300
301