core: dynamics menus refactoring:

- menu now use generic callback system, with extra data
    - asyncMenuCall is removed in favor of launchAction
    - menu_id (== callback_id) is used to identify menu instead of category/name/type tuple
    - i18n is managed throught deferred translation, and returned with _i18n suffix
        e.g.: menu (D_('File'), D_('Open')): (u'File', u'Open') is menu_path, (u'Fichier', u'Ouvrir') is french menu_path_i18n.
    - type actually can have the following values:
        - NORMAL: classical menu
        - JID_CONTEXT: contextual menu, used with any jid
        - ROSTER_JID_CONTEXT: like JID_CONTEXT, but restricted to jids in roster.
        - ROSTER_GROUP_CONTEXT: contextual menu, use with groups
    - security_limit is used, in the same way as for parameters
    - when using importMenu, callback can be an actual callback, or one already registered with registerCallback
This commit is contained in:
Goffi 2013-12-29 17:10:14 +01:00
commit b7bf434cd2
8 changed files with 129 additions and 132 deletions

View file

@ -98,9 +98,6 @@ class DBusBridgeFrontend(BridgeFrontend):
def addContact(self, entity_jid, profile_key="@DEFAULT@"):
return self.db_core_iface.addContact(entity_jid, profile_key)
def asyncCallMenu(self, category, name, menu_type, profile_key, callback=None, errback=None):
return unicode(self.db_core_iface.asyncCallMenu(category, name, menu_type, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
def asyncConnect(self, profile_key="@DEFAULT@", callback=None, errback=None):
return self.db_core_iface.asyncConnect(profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))
@ -146,11 +143,11 @@ class DBusBridgeFrontend(BridgeFrontend):
def getLastResource(self, contact_jid, profile_key="@DEFAULT@"):
return unicode(self.db_core_iface.getLastResource(contact_jid, profile_key))
def getMenuHelp(self, category, name, menu_type):
return unicode(self.db_core_iface.getMenuHelp(category, name, menu_type))
def getMenuHelp(self, menu_id, language):
return unicode(self.db_core_iface.getMenuHelp(menu_id, language))
def getMenus(self, ):
return self.db_core_iface.getMenus()
def getMenus(self, language, security_limit):
return self.db_core_iface.getMenus(language, security_limit)
def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@"):
return unicode(self.db_core_iface.getParamA(name, category, attribute, profile_key))

View file

@ -58,3 +58,5 @@ class Const(object):
# from plugin_misc_text_syntaxes
_SYNTAX_XHTML = "XHTML"
_SYNTAX_CURRENT = "@CURRENT@"
NO_SECURITY_LIMIT = -1

View file

@ -282,13 +282,6 @@ class PrimitivusApp(QuickApp, InputHistory):
except AttributeError:
return input
def _dynamicMenuCb(self, xmlui):
ui = XMLUI(self, xml_data = xmlui)
ui.show('popup')
def _dynamicMenuEb(self, failure):
self.showDialog(_(u"Error while calling menu"), type="error")
def _buildMenuRoller(self):
menu = sat_widgets.Menu(self.loop)
general = _("General")
@ -306,14 +299,14 @@ class PrimitivusApp(QuickApp, InputHistory):
menu.addMenu(communication, _("Search directory"), self.onSearchDirectory)
#additionals menus
#FIXME: do this in a more generic way (in quickapp)
add_menus = self.bridge.getMenus()
def add_menu_cb(menu):
category, name = menu
self.bridge.asyncCallMenu(category, name, Const.MENU_NORMAL, self.profile, callback=self._dynamicMenuCb, errback=self._dynamicMenuEb)
for new_menu in add_menus:
type_, category, name = new_menu
add_menus = self.bridge.getMenus('', Const.NO_SECURITY_LIMIT)
def add_menu_cb(callback_id):
self.launchAction(callback_id, None, profile_key = self.profile)
for id_, type_, path, path_i18n in add_menus:
assert(type_=="NORMAL") #TODO: manage other types
menu.addMenu(unicode(category), unicode(name), add_menu_cb)
if len(path) != 2:
raise NotImplementedError("Menu with a path != 2 are not implemented yet")
menu.addMenu(path_i18n[0], path_i18n[1], lambda menu: add_menu_cb(id_))
menu_roller = sat_widgets.MenuRoller([(_('Main menu'),menu)])
return menu_roller

View file

@ -116,17 +116,6 @@ class MainWindow(wx.Frame, QuickApp):
self.menuBar.EnableTop(i, True)
super(MainWindow, self).plug_profile(profile_key)
def _dynamicMenuCb(self, xmlui):
XMLUI(self, xml_data = xmlui)
def _dynamicMenuEb(self, failure):
dlg = wx.MessageDialog(self, _(u"Error while calling menu"),
_('Error'),
wx.OK | wx.ICON_ERROR
)
dlg.ShowModal()
dlg.Destroy()
def createMenus(self):
info(_("Creating menus"))
connectMenu = wx.Menu()
@ -152,10 +141,13 @@ class MainWindow(wx.Frame, QuickApp):
#additionals menus
#FIXME: do this in a more generic way (in quickapp)
add_menus = self.bridge.getMenus()
for menu in add_menus:
type_,category,name = menu
add_menus = self.bridge.getMenus('', Const.NO_SECURITY_LIMIT)
for id_, type_, path, path_i18n in add_menus:
assert(type_=="NORMAL") #TODO: manage other types
if len(path) != 2:
raise NotImplementedError("Menu with a path != 2 are not implemented yet")
category = path_i18n[0] # TODO: manage path with more than 2 levels
name = path_i18n[1]
menu_idx = self.menuBar.FindMenu(category)
current_menu = None
if menu_idx == wx.NOT_FOUND:
@ -166,11 +158,12 @@ class MainWindow(wx.Frame, QuickApp):
current_menu = self.menuBar.GetMenu(menu_idx)
assert(current_menu != None)
item_id = wx.NewId()
help_string = self.bridge.getMenuHelp(category, name, type_)
current_menu.Append(item_id, name, help = help_string)
help_string = self.bridge.getMenuHelp(id_, '')
current_menu.Append(item_id, name, help=help_string)
#now we register the event
def event_answer(e):
self.bridge.asyncCallMenu(category, name, Const.MENU_NORMAL, self.profile, callback=self._dynamicMenuCb, errback=self._dynamicMenuEb)
self.launchAction(id_, None, profile_key = self.profile)
wx.EVT_MENU(self, item_id, event_answer)