main logo
Subject: [dabo-dev] dabo Commit 1493
Author: Paul McNett

Posted: 2005/10/31 15:17:35
 
View Entire Thread
New Search


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):





 
©2005 Paul McNett
<-- Prior Message New Search Next Message -->