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]

Reply via email to