dabo Commit
Revision 1493
Date: 2005-10-31 12:17:36 -0800 (Mon, 31 Oct 2005)
Author: paul

Changed:
U   trunk/dabo/lib/datanav/Form.py
U   trunk/dabo/ui/uiwx/dMenu.py
U   trunk/dabo/ui/uiwx/dMenuItem.py

Log:
Added DynamicEnabled property to dMenuItem. This property takes a 
function that should return True/False to determine if the item 
should be enabled/disabled when the parent menu is opened.

Added an example of this in the Actions menu item "Quick Report", 
which will be disabled before a query has been run, and enabled
afterward.

In working on the above, I needed to fix a big problem with dabo
menu items: when they are added to a dMenu using wx functions, the
actual menu item reverts back to a pure wx object with no remnants
of our dPemMixin anymore. I worked around this by maintaining a 
dictionary which maps the wx object to the dabo object.

TODO still: Make a dMenuSeparator object, because as it stands
any separators will be listed in dMenu.Children, but as pure wx
objects and not Dabo objects.

Also, we should get DynamicEnabled implemented in dToolBar, but
a quick look leads me to believe that toolbar items aren't 
objectified like dMenuItems are.



Diff:
Modified: trunk/dabo/lib/datanav/Form.py
===================================================================
--- trunk/dabo/lib/datanav/Form.py      2005-10-31 00:52:35 UTC (rev 1492)
+++ trunk/dabo/lib/datanav/Form.py      2005-10-31 20:17:36 UTC (rev 1493)
@@ -218,11 +218,23 @@
 
                if self.FormType != "Edit":
                        menu.append(_("Show SQL"), bindfunc=self.onShowSQL, 
bmp="zoomNormal")
-                       menu.append(_("Quick Report"), 
bindfunc=self.onQuickReport, bmp="print")
+                       menu.append(_("Quick Report"), 
bindfunc=self.onQuickReport, bmp="print",
+                                       DynamicEnabled=self.enableQuickReport)
 
                return menu
 
 
+       def enableQuickReport(self):
+               ## Can't enable quick report unless the dataset has been 
requeried once and
+               ## the browse grid exists (because it gets the layout from the 
browse grid).
+               ret = True
+               try:
+                       self.PageFrame.Pages[1].BrowseGrid
+               except AttributeError:
+                       ret = False
+               return ret
+
+
        def setupMenu(self):
                """ Set up the action menu for this frame.
 

Modified: trunk/dabo/ui/uiwx/dMenu.py
===================================================================
--- trunk/dabo/ui/uiwx/dMenu.py 2005-10-31 00:52:35 UTC (rev 1492)
+++ trunk/dabo/ui/uiwx/dMenu.py 2005-10-31 20:17:36 UTC (rev 1493)
@@ -20,14 +20,39 @@
                self._baseClass = dMenu
                preClass = wx.Menu
                self.Parent = parent
+               ## pkm: When a dMenuItem is added to a dMenu, the wx functions 
only
+               ##      add the C++ portion, not the mixed-in dabo dMenuItem 
object.
+               ##      To work around this, we maintain an internal dictionary 
that
+               ##      maps the id of the wxMenuItem to the dMenuItem object.
+               self._daboChildren = {}
                pm.dPemMixin.__init__(self, preClass, parent, properties, 
*args, **kwargs)
 
 
        def _initEvents(self):
-               ## see self._setId(), which is where this needs to take place
-               pass
+               ## see self._setId(), which is where the binding of wxEvents 
needs to take 
+               ## place.
+               self.bindEvent(dEvents.MenuHighlight, self._onMenuHighlight)
 
 
+       def _onMenuHighlight(self, evt):
+               ## Note that this code is here in a dabo binding instead of in 
the wx binding
+               ## because of the way we've worked around wx limitations: dMenu 
as a top-level
+               ## menu in a menu bar doesn't send wx events.
+               self._setDynamicEnabled()
+
+
+       def _setDynamicEnabled(self):
+               """For each dMenuItem, set Enabled per the item's 
DynamicEnabled prop."""
+               for item in self.Children:
+                       # separators haven't been abstracted yet, so there are 
still pure wx items.
+                       try:
+                               de = item.DynamicEnabled
+                       except:
+                               de = None
+                       if de is not None:
+                               item.Enabled = de()
+
+
        def __onWxMenuHighlight(self, evt):
                self.raiseEvent(dEvents.MenuHighlight)
                evt.Skip()
@@ -35,20 +60,23 @@
 
        def appendItem(self, item):
                """Insert a dMenuItem at the bottom of the menu."""
-               self.AppendItem(item)
+               wxItem = self.AppendItem(item)
                item.Parent = self
+               self._daboChildren[wxItem.GetId()] = item
                
 
        def insertItem(self, pos, item):
                """Insert a dMenuItem before the specified position in the 
menu."""
                self.InsertItem(pos, item)
                item.Parent = self
+               self._daboChildren[wxItem.GetId()] = item
                
 
        def prependItem(self, item):
                """Insert a dMenuItem at the top of the menu."""
                self.PrependItem(item)
                item.Parent = self
+               self._daboChildren[wxItem.GetId()] = item
 
 
        def appendMenu(self, menu):
@@ -56,6 +84,7 @@
                wxMenuItem = self.AppendMenu(-1, menu.Caption, menu, 
help=menu.HelpText)
                menu._setId(wxMenuItem.GetId())
                menu.Parent = self
+               self._daboChildren[wxMenuItem.GetId()] = menu
                
 
        def insertMenu(self, pos, menu):
@@ -63,6 +92,7 @@
                wxMenuItem = self.InsertMenu(-1, pos, menu.Caption, menu, 
help=menu.HelpText)
                menu._setId(wxMenuItem.GetId())
                menu.Parent = self
+               self._daboChildren[wxMenuItem.GetId()] = menu
                
                
        def prependMenu(self, menu):
@@ -70,6 +100,7 @@
                wxMenuItem = self.PrependMenu(-1, menu.Caption, menu, 
help=menu.HelpText)
                menu._setId(wxMenuItem.GetId())
                menu.Parent = self
+               self._daboChildren[wxMenuItem.GetId()] = menu
 
 
        def appendSeparator(self):
@@ -141,6 +172,9 @@
                is responsible for deleting it.
                """
                item = self.Children[index]
+               id_ = item.GetId()
+               if self._daboChildren.has_key(id_):
+                       del self._daboChildren[id_]
                self.RemoveItem(item)
                if release:
                        item.Destroy()
@@ -180,13 +214,12 @@
                ## MenuOpen and MenuClose don't appear to be working on Linux. 
Need
                ## to test on Mac and Win.
                if self.Application is not None:
-                       # Set up a mechanism to catch menu events
-                       # and re-raise Dabo events. If Application
-                       # is None, however, this won't work because of wx 
limitations.
+                       # Set up a mechanism to catch menu events and re-raise 
Dabo events. 
+                       # If Application is None, however, this won't work 
because of wx 
+                       # limitations.
                        self.Application.uiApp.Bind(wx.EVT_MENU_HIGHLIGHT,
                                        self.__onWxMenuHighlight, id=id_)
                
-               
        def _isPopupMenu(self):
                ## TODO: Make dMenu work as a submenu, a child of dMenuBar, or 
as a popup.
                return False
@@ -210,7 +243,9 @@
                """
                idx = self.getItemIndex(caption)
                if idx is not None:
-                       return self.FindItemByPosition(idx)
+                       wxItem = self.FindItemByPosition(idx)
+                       if wxItem:
+                               return self._daboChildren.get(wxItem.GetId(), 
wxItem)
                return None
 
 
@@ -219,11 +254,9 @@
                # calls it in _getChildren(). The Dabo developer wants the 
submenus and
                # items in this menu, but is using the consistent Children 
property to 
                # do it.
-               ## pkm: GetMenuItems() only returns the C++ part of the menu 
item, not
-               ##      the dabo mixed-in portion. I'll have to look into this, 
but until
-               ##      I have a fix, dMenu.Children will always return an 
empty list.
                children = self.GetMenuItems()
-               return children
+               daboChildren = [self._daboChildren.get(c.GetId(), c) for c in 
children]
+               return daboChildren
 
 
        def _getCaption(self):

Modified: trunk/dabo/ui/uiwx/dMenuItem.py
===================================================================
--- trunk/dabo/ui/uiwx/dMenuItem.py     2005-10-31 00:52:35 UTC (rev 1492)
+++ trunk/dabo/ui/uiwx/dMenuItem.py     2005-10-31 20:17:36 UTC (rev 1493)
@@ -1,4 +1,5 @@
 """ dMenuItem.py """
+import types
 import wx
 import dPemMixin as pm
 import dIcons
@@ -15,6 +16,7 @@
                self.Parent = parent
                pm.dPemMixin.__init__(self, preClass, parent, properties, 
*args, **kwargs)
 
+
        def _initEvents(self):
                ## wx.MenuItems don't have a Bind() of their own, so this 
serves to 
                ## override the base behavior in dPemMixin._initEvents() which 
has
@@ -51,6 +53,18 @@
                        self._properties["Caption"] = val
 
 
+       def _getDynamicEnabled(self):
+               try:
+                       val = self._dynamicEnabled
+               except AttributeError:
+                       val = self._dynamicEnabled = None
+               return val
+
+       def _setDynamicEnabled(self, val):
+               assert isinstance(val, (types.FunctionType, types.MethodType))
+               self._dynamicEnabled = val
+
+
        def _getEnabled(self):
                return self.IsEnabled()
 
@@ -110,22 +124,29 @@
 
 
        Caption = property(_getCaption, _setCaption, None,
-               _("Specifies the text of the menu item."))
+                       _("Specifies the text of the menu item."))
 
+       DynamicEnabled = property(_getDynamicEnabled, _setDynamicEnabled, None,
+                       _("""Specifies a function to run to determine whether 
the item is enabled.
+
+                       The function will run when the parent menu is 
activated, and will set the
+                       menu item's Enabled property to the return value of the 
function.
+                       """))
+
        Enabled = property(_getEnabled, _setEnabled, None,
-               _("Specifies whether the menu item can be interacted with."))
+                       _("Specifies whether the menu item can be interacted 
with."))
 
        Icon = property(_getIcon, _setIcon, None,
-               _("Specifies the icon for the menu item."))
+                       _("Specifies the icon for the menu item."))
 
        Form = property(_getForm, None, None,
-               _("Specifies the containing form."))
+                       _("Specifies the containing form."))
 
        HelpText = property(_getHelpText, _setHelpText, None,
-               _("Specifies the help text associated with this menu. (str)"))
+                       _("Specifies the help text associated with this menu. 
(str)"))
 
        Parent = property(_getParent, _setParent, None, 
-               _("Specifies the parent menu."))
+                       _("Specifies the parent menu."))
 
 
 class dCheckMenuItem(dMenuItem):




_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev

Reply via email to