On Saturday, February 12, 2011 09:18:41 am Ed Leafe wrote: > dabo Commit > Revision 6430 > Date: 2011-02-12 09:18:39 -0800 (Sat, 12 Feb 2011) > Author: Ed > Trac: http://trac.dabodev.com/changeset/6430 > > Changed: > U trunk/dabo/dApp.py > A trunk/dabo/icons/collapse_tree.png > A trunk/dabo/icons/event_watcher.png > A trunk/dabo/icons/expand_tree.png > A trunk/dabo/icons/find_object.png > A trunk/dabo/icons/highlight_item.png > A trunk/dabo/icons/refresh_tree.png > A trunk/dabo/icons/show_sizers.png > U trunk/dabo/ui/uiwx/dBaseMenuBar.py > U trunk/dabo/ui/uiwx/dFormMixin.py > A trunk/dabo/ui/uiwx/object_inspector.py > U trunk/dabo/ui/uiwx/uiApp.py > > Log: > First pass at creating an Object Inspector, which is largely modeled on the > wxPython Widget Inspection Tool > (http://wiki.wxpython.org/Widget%20Inspection%20Tool). It largely works as > expected, but I'm sure there will be cases that need cleaning up. > > To invoke it, I've added a menu item to dBaseMenuBar that can be triggered > by Ctrl-Shift-I. > > Right now the form sections are arranged using splitters, because the form > is cdxml-based. This allowed me to rapidly prototype it, but I would > prefer to use dDockForm instead, which unfortunately is not yet supported > in the Class Designer. > > Feedback welcome!! > > > Diff: > Modified: trunk/dabo/dApp.py > =================================================================== > --- trunk/dabo/dApp.py 2011-02-12 16:51:17 UTC (rev 6429) > +++ trunk/dabo/dApp.py 2011-02-12 17:18:39 UTC (rev 6430) > @@ -1181,6 +1181,8 @@ > self.uiApp.onCmdWin(evt) > def onDebugWin(self, evt): > self.uiApp.onDebugWin(evt) > + def onObjectInspectorWin(self, evt): > + self.uiApp.onObjectInspectorWin(evt) > def onWinClose(self, evt): > self.uiApp.onWinClose(evt) > def onFileExit(self, evt): > @@ -1709,7 +1711,7 @@ > FormsToOpen = property(_getFormsToOpen, _setFormsToOpen, None, > _("""List of forms to open after App instantiation. > (list of form > class references)""")) formsToOpen = FormsToOpen ## > backwards-compatibility > - > + > HomeDirectory = property(_getHomeDirectory, _setHomeDirectory, None, > _("""Specifies the application's home directory. > (string) > > > Added: trunk/dabo/icons/collapse_tree.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/collapse_tree.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Added: trunk/dabo/icons/event_watcher.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/event_watcher.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Added: trunk/dabo/icons/expand_tree.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/expand_tree.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Added: trunk/dabo/icons/find_object.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/find_object.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Added: trunk/dabo/icons/highlight_item.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/highlight_item.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Added: trunk/dabo/icons/refresh_tree.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/refresh_tree.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Added: trunk/dabo/icons/show_sizers.png > =================================================================== > (Binary files differ) > > > Property changes on: trunk/dabo/icons/show_sizers.png > ___________________________________________________________________ > Name: svn:mime-type > + application/octet-stream > > Modified: trunk/dabo/ui/uiwx/dBaseMenuBar.py > =================================================================== > --- trunk/dabo/ui/uiwx/dBaseMenuBar.py 2011-02-12 16:51:17 UTC (rev > 6429) > +++ trunk/dabo/ui/uiwx/dBaseMenuBar.py 2011-02-12 17:18:39 UTC (rev > 6430) > @@ -43,7 +43,12 @@ > OnHit=app.onDebugWin, > ItemID="file_debugwin", > help=_("Open up a debug output window")) > self.Parent.debugMenuItem.Checked = True > - > + > + self.Parent.inspectorMenuItem = self.append(_("Object &Inspector"), > HotKey="Ctrl+Shift+I", + OnHit=app.onObjectInspectorWin, > bmp="%s/apps/system-search.png" % iconPath, > + ItemID="file_inspectorwin", > menutype="check", > + help=_("Open up the object inspector")) > + > prmpt = _("Close Windo&w") > self.Parent.closeWindowMenuItem = self.append(prmpt, HotKey="Ctrl+W", > OnHit=app.onWinClose, ItemID="file_close", > @@ -177,16 +182,6 @@ > self.helpMenu = self.appendMenu(HelpMenu(self, > MenuID="base_help")) > > > -# Trying to expose menu atts as menubar atts. Not sure if this is a good > idea yet... -# def __getattr__(self, att): > -# ret = None > -# for menu in self.Children: > -# ret = getattr(menu, att) > -# if ret: > -# break > -# if not ret: > -# raise AttributeError > -# return ret > > if __name__ == "__main__": > app = dabo.dApp() > > Modified: trunk/dabo/ui/uiwx/dFormMixin.py > =================================================================== > --- trunk/dabo/ui/uiwx/dFormMixin.py 2011-02-12 16:51:17 UTC (rev 6429) > +++ trunk/dabo/ui/uiwx/dFormMixin.py 2011-02-12 17:18:39 UTC (rev 6430) > @@ -231,9 +231,11 @@ > > def __onIdle(self, evt): > if self.__needOutlineRedraw or self._alwaysDrawSizerOutlines: > + self.refresh() > for sz in self.SizersToOutline: > + win = sz.getContainingWindow() > try: > - sz.drawOutline(self, recurse=self._recurseOutlinedSizers, > + sz.drawOutline(win, recurse=self._recurseOutlinedSizers, > > drawChildren=self._drawSizerChildren) > except AttributeError: > # Will happen if sz is None > @@ -265,6 +267,10 @@ > app.uiForms.remove(self) > > > + def forceSizerOutline(self): > + self.__needOutlineRedraw = True > + > + > def activeControlValid(self): > """ Force the control-with-focus to fire its KillFocus code. > > > Added: trunk/dabo/ui/uiwx/object_inspector.py > =================================================================== > --- trunk/dabo/ui/uiwx/object_inspector.py (rev 0) > +++ trunk/dabo/ui/uiwx/object_inspector.py 2011-02-12 17:18:39 UTC (rev > 6430) @@ -0,0 +1,447 @@ > +#!/usr/bin/env python > +# -*- coding: utf-8 -*- > +import dabo > +dabo.ui.loadUI("wx") > + > + > +# 'InspectorFormClass' is defined at the bottom > + > +inspector_source = '''<?xml version="1.0" encoding="mac-roman" > standalone="no"?> +<dForm Name="dForm" Caption="Dabo Object Inspector" > SaveRestorePosition="False" Height="750" Width="850" > designerClass="DesForm"> + <code> > + <addkids><![CDATA[ > +def addkids(self, obj, node): > + if self._showSizers: > + try: > + kid = obj.Sizer > + except AttributeError: > + kid = None > + if kid: > + snode = node.appendChild(self.sizer_repr(kid)) > + snode.Object = kid > + snode.ForeColor = "blue" > + self.addkids(kid, snode) > + return > + try: > + kids = obj.Children > + except AttributeError: > + # Not a dabo obj > + return > + for kid in kids: > + if self.exclude(kid): > + continue > + nodeColor = None > + if isinstance(kid, wx._controls.ScrollBar): > + continue > + if isinstance(obj, dabo.ui.dSizerMixin): > + kid = obj.getItem(kid) > + if isinstance(kid, dabo.ui.dSizerMixin): > + txt = self.sizer_repr(kid) > + nodeColor = "blue" > + else: > + try: > + txt = kid.Name > + except AttributeError: > + if isinstance(kid, wx.Size): > + txt = "Spacer %s" % kid > + nodeColor = "darkred" > + else: > + txt = "%s" % kid > + txt = "%s (%s)" % (txt, self.cls_repr(kid.__class__)) > + knode = node.appendChild(txt) > + if nodeColor is not None: > + knode.ForeColor = nodeColor > + knode.Object = kid > + self.addkids(kid, knode) > +]]> > + </addkids> > + <clearHighlight><![CDATA[ > +def clearHighlight(self): > + if not self: > + return > + current = time.time() > + for expiration in self._highlights.keys(): > + if expiration > current: > + continue > + toClear = self._highlights.pop(expiration) > + frm = toClear["targetForm"] > + if toClear["type"] == "drawing": > + try: > + frm.removeDrawnObject(toClear["drawingToClear"]) > + except ValueError: > + pass > + frm.forceSizerOutline() > + else: > + sz = toClear["outlinedSizer"] > + frm.removeFromOutlinedSizers(sz) > + frm._alwaysDrawSizerOutlines = toClear["drawSetting"] > + sz.outlineStyle = toClear["outlineStyle"] > + sz.outlineWidth = toClear["outlineWidth"] > + frm.clear() > +]]> > + </clearHighlight> > + <onCollapseTree><![CDATA[ > +def onCollapseTree(self, evt): > + self.objectTree.collapseCurrentNode() > +]]> > + </onCollapseTree> > + <afterInit><![CDATA[ > +def afterInit(self): > + self.BasePrefKey = "object_inspector" > + self.PreferenceManager = dabo.dPref(key=self.BasePrefKey) > + self._highlights = {} > +]]> > + </afterInit> > + <_setShowSizers><![CDATA[ > +def _setShowSizers(self, val): > + self._showSizers = val > +]]> > + </_setShowSizers> > + <importStatements><![CDATA[ > +import time > +import wx > +from dabo.dLocalize import _ > +]]> > + </importStatements> > + <formatName><![CDATA[ > +def formatName(self, obj): > + if not obj: > + return "< -dead object- >" > + try: > + cap = obj.Caption > + except AttributeError: > + cap = "" > + try: > + cls = obj.BaseClass > + except AttributeError: > + cls = obj.__class__ > + classString = "%s" % cls > + shortClass = classString.replace("'", "").replace(">", > "").split(".")[-1] > + if cap: > + ret = "%s (\\"%s\\")" % (shortClass, cap) > + else: > + try: > + ret = "%s (%s)" % (obj.Name, shortClass) > + except AttributeError: > + ret = "%s (%s)" % (obj, cls) > + return ret > +]]> > + </formatName> > + <onToggleSizers><![CDATA[ > +def onToggleSizers(self, evt): > + self._showSizers = not self._showSizers > + self.createObjectTree() > +]]> > + </onToggleSizers> > + <showPropVals><![CDATA[ > +def showPropVals(self, obj): > + rows = [] > + props = [] > + try: > + props = obj.getPropertyList(onlyDabo=True) > + except AttributeError: > + for c in obj.__class__.__mro__: > + if c is > dabo.lib.propertyHelperMixin.PropertyHelperMixin: > + # Don't list properties lower down (e.g., from > wxPython): > + break > + for item in dir(c): > + if item[0].isupper(): > + if item in c.__dict__: > + if type(c.__dict__[item]) == > property: > + if props.count(item) == > 0: > + > props.append(item) > + for prop in props: > + if prop == "ShowColumnLabels": > + # Avoid the deprecation warning > + continue > + try: > + val = getattr(obj, prop) > + except (AttributeError, TypeError, dabo.ui.assertionException): > + # write-only or otherwise unavailable > + continue > + if prop.startswith("Dynamic") and val is None: > + continue > + if val is None: > + val = self.Application.NoneDisplay > + elif isinstance(val, basestring): > + val = "'%s'" % val > + elif isinstance(val, dabo.dObject.dObject): > + try: > + val = "'%s'" % self.formatName(val) > + except StandardError, e: > + pass > + rows.append({"prop": prop, "val": val}) > + ds = dabo.db.dDataSet(rows) > + self.infoGrid.DataSet = ds > +]]> > + </showPropVals> > + <sizer_repr><![CDATA[ > +def sizer_repr(self, sz): > + """Returns an informative representation for a sizer""" > + if isinstance(sz, dabo.ui.dGridSizer): > + ret = "dGridSizer (%s x %s)" % (sz.HighRow, sz.HighCol) > + elif isinstance(sz, dabo.ui.dBorderSizer): > + ret = "dBorderSizer (%s, '%s')" % (sz.Orientation, sz.Caption) > + else: > + ret = "dSizer (%s)" % sz.Orientation > + return ret > +]]> > + </sizer_repr> > + <_getShowSizers><![CDATA[ > +def _getShowSizers(self): > + try: > + return self._showSizers > + except AttributeError: > + return None > +]]> > + </_getShowSizers> > + <exclude><![CDATA[ > +def exclude(self, obj): > + isFloat = (isinstance(obj, dabo.ui.dDialog) and > + hasattr(obj, "Above") and hasattr(obj, "Owner")) > + return isFloat or (obj is self) > +]]> > + </exclude> > + <onHighlightItem><![CDATA[ > +def onHighlightItem(self, evt): > + obj = self.objectTree.Selection.Object > + try: > + frm = obj.Form > + except AttributeError: > + return > + # Remove the highlight after 3 seconds > + expires = time.time() + 3 > + entry = self._highlights[expires] = {} > + entry["targetForm"] = frm > + > + if isinstance(obj, dabo.ui.dSizerMixin): > + entry["type"] = "sizer" > + frm.addToOutlinedSizers(obj) > + frm.refresh() > + entry["outlinedSizer"] = obj > + entry["drawSetting"] = frm._alwaysDrawSizerOutlines > + entry["outlineStyle"] = obj.outlineStyle > + obj.outlineStyle = "dot" > + entry["outlineWidth"] = obj.outlineWidth > + obj.outlineWidth = 4 > + frm._alwaysDrawSizerOutlines = True > + else: > + entry["type"] = "drawing" > + x, y = obj.formCoordinates() > + entry["drawingToClear"] = frm.drawRectangle(x-3, y-3, > obj.Width+6, > obj.Height+6, + penWidth=3, penColor="magenta") > +]]> > + </onHighlightItem> > + <onFindObject><![CDATA[ > +def onFindObject(self, evt): > + self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) > + self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLost) > + self.CaptureMouse() > + self.finding = wx.BusyInfo("Click on any widget in the app...") > +]]> > + </onFindObject> > + <OnCaptureLost><![CDATA[ > +def OnCaptureLost(self, evt): > + self.Unbind(wx.EVT_LEFT_DOWN) > + self.Unbind(wx.EVT_MOUSE_CAPTURE_LOST) > + del self.finding > +]]> > + </OnCaptureLost> > + <afterInitAll><![CDATA[ > +def afterInitAll(self): > + objnote = "NOTE: The 'obj' variable refers to the object selected in the > tree." + intro = "%s\\n%s" % (dabo.ui.getSystemInfo(), objnote) > + self.shell = dabo.ui.dShell._Shell(self.shellPanel, > showInterpIntro=False, + introText=intro) > + self.shell.interp.locals['self'] = self > + sz = self.shellPanel.Sizer = dabo.ui.dBorderSizer(self.shellPanel, > Caption="Interactive Interpreter") + sz.append1x(self.shell) > + dabo.ui.callEvery(250, self.clearHighlight) > + > + tb = self.ToolBar = dabo.ui.dToolBar(self, ShowCaptions=True) > + self.refreshButton = self.appendToolBarButton(name="Refresh", > pic="refresh_tree.png", + toggle=False, tip=_("Re-create > the object > tree"), > + OnHit=self.onRefreshTree) > + self.findButton = self.appendToolBarButton(name="Find", > pic="find_object.png", + toggle=False, tip=_("Find an > object in your app > in the tree"), + OnHit=self.onFindObject) > + self.showSizersButton = self.appendToolBarButton(name="Show Sizers", > pic="show_sizers.png", + toggle=True, tip=_("Show/Hide > sizers in the > object hierarchy"), + OnHit=self.onToggleSizers) > + self.expandButton = self.appendToolBarButton(name="Expand", > pic="expand_tree.png", + toggle=False, tip=_("Expand > this node and all > nodes under it."), + OnHit=self.onExpandTree) > + self.collapseButton = self.appendToolBarButton(name="Collapse", > pic="collapse_tree.png", + toggle=False, tip=_("Collapse > this node and > all nodes under it."), + OnHit=self.onCollapseTree) > + self.highlightButton = self.appendToolBarButton(name="Highlight", > pic="highlight_item.png", + toggle=False, tip=_("Highlight > the selected > node in your app."), + OnHit=self.onHighlightItem) > + self.layout() > +]]> > + </afterInitAll> > + <onRefreshTree><![CDATA[ > +def onRefreshTree(self, evt): > + self.createObjectTree() > +]]> > + </onRefreshTree> > + <onExpandTree><![CDATA[ > +def onExpandTree(self, evt): > + self.objectTree.expandCurrentNode() > +]]> > + </onExpandTree> > + <cls_repr><![CDATA[ > +def cls_repr(self, cls): > + """Returns a readable representation for a class""" > + txt = "%s" % cls > + prfx, clsname, suff = txt.split("'") > + return clsname > +]]> > + </cls_repr> > + <OnLeftDown><![CDATA[ > +def OnLeftDown(self, evt): > + self.ReleaseMouse() > + wnd = wx.FindWindowAtPointer() > + if wnd is not None: > + self.objectTree.showObject(wnd) > + else: > + dabo.ui.beep() > + self.OnCaptureLost(evt) > +]]> > + </OnLeftDown> > + <object_selected><![CDATA[ > +def object_selected(self, obj): > + self.shell.interp.locals['obj'] = obj > + self.shellPanel.Sizer.Caption = "'obj' is %s" % self.formatName(obj) > + self.showPropVals(obj) > +]]> > + </object_selected> > + <createObjectTree><![CDATA[ > +def createObjectTree(self): > + tree = self.objectTree > + try: > + currObj = tree.Selection.Object > + currForm = currObj.Form > + except AttributeError: > + # Nothing selected yet > + currObj = currForm = None > + tree.clear() > + root = tree.setRootNode("Top Level Windows") > + for win in self.Application.uiForms: > + if self.exclude(win): > + continue > + winNode = root.appendChild(self.formatName(win)) > + winNode.Object = win > + self.addkids(win, winNode) > + root.expand() > + if currObj: > + nd = tree.nodeForObject(currObj) > + if not nd: > + nd = tree.nodeForObject(currForm) > + nd.Selected = True > +]]> > + </createObjectTree> > + </code> > + > + <properties> > + <ShowSizers> > + <comment>Determines if sizers are displayed in the > object > hierarchy</comment> + <defaultValue>False</defaultValue> > + <deller>None</deller> > + <getter>_getShowSizers</getter> > + <propName>ShowSizers</propName> > + <defaultType>boolean</defaultType> > + <setter>_setShowSizers</setter> > + </ShowSizers> > + </properties> > + > + <dSizer SlotCount="1" designerClass="LayoutSizer" > Orientation="Vertical"> > + <dSplitter SashPosition="380" sizerInfo="{'VAlign': 'Middle'}" > designerClass="controlMix" Split="True" Orientation="Horizontal"> > + <dPanel designerClass="MixedSplitterPanel" > Name="dPanel2"> > + <dSizer SlotCount="1" > designerClass="LayoutSizer" > Orientation="Vertical"> + <dSplitter SashPosition="322" > sizerInfo="{'VAlign': 'Middle'}" designerClass="controlMix" Split="True" > Orientation="Vertical"> + <dPanel designerClass="MixedSplitterPanel" > Name="dPanel2"> > + <dSizer SlotCount="1" designerClass="LayoutSizer" > Orientation="Vertical"> + > <dTreeView RegID="objectTree" > sizerInfo="{'VAlign': 'Middle'}" designerClass="controlMix"> > + <code> > + > <showObject><![CDATA[ > +def showObject(self, obj): > + nd = self.nodeForObject(obj) > + if nd: > + nd.Selected = True > + self.showNode(nd) > + else: > + dabo.ui.stop("Couldn't find object: %s" % obj) > +]]> > + > </showObject> > + > <onTreeSelection><![CDATA[ > +def onTreeSelection(self, evt): > + self.Form.object_selected(self.Selection.Object) > +]]> > + > </onTreeSelection> > + > <expandCurrentNode><![CDATA[ > +def expandCurrentNode(self): > + self.expandBranch(self.Selection) > +]]> > + > </expandCurrentNode> > + > <collapseCurrentNode><! [CDATA[ > +def collapseCurrentNode(self): > + self.collapseBranch(self.Selection) > +]]> > + > </collapseCurrentNode> > + </code> > + > + <dNode > Caption="This is the root" designerClass="controlMix"> > + > <dNode Caption="First Child" designerClass="controlMix"></dNode> > + > <dNode Caption="Second Child" designerClass="controlMix"> > + > <dNode Caption="Grandkid #1" > designerClass="controlMix"></dNode> + > <dNode Caption="Grandkid > #2" designerClass="controlMix"> + > <dNode > Caption="Great-Grandkid #1" designerClass="controlMix"></dNode> > + > </dNode> > + > <dNode Caption="Grandkid #3" > designerClass="controlMix"></dNode> + > </dNode> > + > <dNode Caption="Third Child" designerClass="controlMix"></dNode> > + </dNode> > + </dTreeView> > + </dSizer> > + </dPanel> > + <dPanel > designerClass="MixedSplitterPanel" Name="dPanel1"> > + <dSizer SlotCount="1" designerClass="LayoutSizer" > Orientation="Vertical"> + > <dGrid ColumnCount="2" RegID="infoGrid" > SelectionMode="Row" designerClass="controlMix" sizerInfo="{}"> > + <code> > + > <onGridMouseLeftClick><! [CDATA[ > +def onGridMouseLeftClick(self, evt): > + def later(): > + ds = self.DataSet > + row = ds[self.CurrentRow] > + prop = row["prop"] > + self.Form.PreferenceManager.excluded_props.setValue(prop, True) > + lds = list(ds) > + lds.remove(row) > + self.DataSet = dabo.db.dDataSet(lds) > + > + if evt.altDown: > + dabo.ui.callAfterInterval(250, later) > +]]> > + > </onGridMouseLeftClick> > + </code> > + > + > <dColumn Width="169" Caption="Property" > HorizontalAlignment="Right" DataField="prop" designerClass="controlMix" > Order="0"></dColumn> + > <dColumn Caption="Value" DataField="val" > designerClass="controlMix" Order="10" Width="399"></dColumn> > + </dGrid> > + </dSizer> > + </dPanel> > + </dSplitter> > + </dSizer> > + </dPanel> > + <dPanel designerClass="MixedSplitterPanel" > Name="dPanel1"> > + <dSizer SlotCount="1" > designerClass="LayoutSizer" > Orientation="Vertical"> + <dPanel > RegID="shellPanel" > sizerInfo="{'VAlign': 'Middle'}" AlwaysResetSizer="True" > designerClass="controlMix"></dPanel> + > </dSizer> > + </dPanel> > + </dSplitter> > + </dSizer> > +</dForm> > +''' > + > +InspectorFormClass = dabo.ui.createClass(inspector_source) > > > Property changes on: trunk/dabo/ui/uiwx/object_inspector.py > ___________________________________________________________________ > Name: svn:eol-style > + native > > Modified: trunk/dabo/ui/uiwx/uiApp.py > =================================================================== > --- trunk/dabo/ui/uiwx/uiApp.py 2011-02-12 16:51:17 UTC (rev 6429) > +++ trunk/dabo/ui/uiwx/uiApp.py 2011-02-12 17:18:39 UTC (rev 6430) > @@ -157,6 +157,8 @@ > wx.InitAllImageHandlers() > # Set up the debug logging > self.debugWindow = None > + # Set up the object inspector > + self.inspectorWindow = None > log = logging.getLogger("Debug") > class DebugLogHandler(logging.Handler): > def emit(self, record): > @@ -507,6 +509,10 @@ > self.toggleDebugWindow(self.ActiveForm) > > > + def onObjectInspectorWin(self, evt): > + self.toggleInspectorWindow(self.ActiveForm) > + > + > def showCommandWindow(self, context=None): > """Display a command window for debugging.""" > if context is None: > @@ -558,9 +564,30 @@ > except AttributeError: > #Either no such item, or not a valid reference > pass > - > > > + def toggleInspectorWindow(self, context=None): > + """Display the object inspector window.""" > + if context is None: > + context = self.ActiveForm > + if not self.inspectorWindow: > +# loc = os.path.dirname(dabo.ui.uiwx.__file__) > +# pth = os.path.join(loc, "inspector.cdxml") > +# self.inspectorWindow = dabo.ui.createForm(pth, > parent=context, > show=False) + from object_inspector import InspectorFormClass > + self.inspectorWindow = > InspectorFormClass(parent=context) > + insp = self.inspectorWindow > + insp.createObjectTree() > + insp.Visible = not insp.Visible > + try: > + mb = context.MenuBar > + mb.inspectorMenuItem.Checked = insp.Visible > + mb.Refresh() > + except AttributeError: > + # Either no such item, or not a valid reference > + pass > + > + > def onWinClose(self, evt): > """Close the topmost window, if any.""" > if self.ActiveForm:
Wow - that's cool!!!!!!!!!!!!!!!!!! Still playing but it works on Linux Johnf _______________________________________________ Post Messages to: [email protected] Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev Searchable Archives: http://leafe.com/archives/search/dabo-dev This message: http://leafe.com/archives/byMID/[email protected]
