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