diff --git a/CHANGELOG b/CHANGELOG index df534dadfd..7f6aea59aa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Move Plugins into toolbar Actions * Add url to list view * Add dynamic icon for url * Add completion on Many2One, Many2Many and One2Many diff --git a/doc/usage.rst b/doc/usage.rst index a4c79baeac..111d0f2b59 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -84,7 +84,7 @@ Figure: Tryton client application:: Client Window ________________________________________________________________ | Tryton _ o x| |----------------------------------------------------------------| - Menu bar | File User Options Plugins Shortcuts Help | + Menu bar | File User Options Shortcuts Help | |________________________________________________________________| | | ______ | Tabs | Menu | [Tab1] |[Tab2]| [Tab3]... | @@ -612,24 +612,6 @@ Save Options: Saves all the options. -Plug-ins -^^^^^^^^ -Plug-ins are client side add-ons for Tryton. There are some included plug-ins -with the standard client. - -Execute a Plug-in -+++++++++++++++++ -Translate View: - Creates a translation table of the current view. - -Print Workflow: - Creates a graph which shows the work flow of the current view. - -Print Workflow (complex): - Like 'Print Workflow', with additional sub work flows inherited by the - current view. - - Shortcuts ^^^^^^^^^ A collection of user defined shortcuts for specific resources. diff --git a/tryton/gui/main.py b/tryton/gui/main.py index 91831ef50d..7014485f74 100644 --- a/tryton/gui/main.py +++ b/tryton/gui/main.py @@ -138,7 +138,6 @@ class Main(object): self.status_hbox = None self.menubar = None self.menuitem_user = None - self.menuitem_plugins = None self.menuitem_shortcut = None if self.macapp is not None: @@ -189,6 +188,9 @@ class Main(object): self.sig_statusbar_show() + # Register plugins + tryton.plugins.register() + # Adding a timer the check to requests gobject.timeout_add(5 * 60 * 1000, self.request_set) _MAIN.append(self) @@ -231,20 +233,6 @@ class Main(object): menu_options.set_accel_group(self.accel_group) menu_options.set_accel_path('/Options') - menuitem_plugins = gtk.MenuItem(_('_Plugins')) - if self.menuitem_plugins: - menuitem_plugins.set_sensitive( - self.menuitem_plugins.get_property('sensitive')) - else: - menuitem_plugins.set_sensitive(False) - self.menuitem_plugins = menuitem_plugins - menubar.add(menuitem_plugins) - - menu_plugins = self._set_menu_plugins() - menuitem_plugins.set_submenu(menu_plugins) - menu_plugins.set_accel_group(self.accel_group) - menu_plugins.set_accel_path('/Plugins') - menuitem_shortcut = gtk.MenuItem(_('_Shortcuts')) if self.menuitem_shortcut: menuitem_shortcut.set_sensitive( @@ -276,7 +264,6 @@ class Main(object): menuitem_file.show_all() menuitem_user.show_all() menuitem_options.show_all() - menuitem_plugins.show_all() menuitem_shortcut.show_all() menuitem_help.show_all() else: @@ -652,21 +639,6 @@ class Main(object): menu_options.add(imagemenuitem_opt_save) return menu_options - def _set_menu_plugins(self): - menu_plugins = gtk.Menu() - - imagemenuitem_plugin_execute = gtk.ImageMenuItem( - _('_Execute a Plugin')) - image = gtk.Image() - image.set_from_stock('tryton-executable', gtk.ICON_SIZE_MENU) - imagemenuitem_plugin_execute.set_image(image) - imagemenuitem_plugin_execute.connect('activate', - self.sig_plugin_execute) - imagemenuitem_plugin_execute.set_accel_path( - '/Plugins/Execute a Plugin') - menu_plugins.add(imagemenuitem_plugin_execute) - return menu_plugins - def _set_menu_help(self): menu_help = gtk.Menu() @@ -961,7 +933,6 @@ class Main(object): self.shortcut_unset() self.menuitem_shortcut.set_sensitive(True) self.menuitem_user.set_sensitive(True) - self.menuitem_plugins.set_sensitive(True) if CONFIG.arguments: url = CONFIG.arguments.pop() self.open_url(url) @@ -1003,7 +974,6 @@ class Main(object): self.shortcut_unset() self.menuitem_shortcut.set_sensitive(False) self.menuitem_user.set_sensitive(False) - self.menuitem_plugins.set_sensitive(False) if disconnect: rpc.logout() self.refresh_ssl() @@ -1079,17 +1049,6 @@ class Main(object): screen.display(set_cursor=True) self.menu_screen = screen - def sig_plugin_execute(self, widget): - page = self.notebook.get_current_page() - if page == -1: - return - datas = { - 'model': self.pages[page].model, - 'ids': self.pages[page].ids_get(), - 'id': self.pages[page].id_get(), - } - tryton.plugins.execute(datas) - @classmethod def sig_quit(cls, widget=None): rpc.logout() diff --git a/tryton/gui/window/form.py b/tryton/gui/window/form.py index 421a68bf04..f6c4bddc9c 100644 --- a/tryton/gui/window/form.py +++ b/tryton/gui/window/form.py @@ -18,6 +18,7 @@ from tryton.common import (TRYTON_ICON, message, sur, sur_3b, COLOR_SCHEMES, import tryton.common as common from tryton.translate import date_format from tryton.common import RPCExecute, RPCException +from tryton import plugins from tabcontent import TabContent @@ -555,7 +556,7 @@ class Form(SignalEvent, TabContent): tbutton.connect('toggled', self.action_popup) self.tooltips.set_tip(tbutton, tooltip) self.buttons[special_action] = tbutton - tbutton._can_be_sensitive = bool(toolbars.get(action_type)) + tbutton._can_be_sensitive = bool(tbutton._menu.get_children()) else: tbutton = gtk.SeparatorToolItem() gtktoolbar.insert(tbutton, -1) @@ -580,7 +581,18 @@ class Form(SignalEvent, TabContent): menuitem.connect('activate', self._popup_menu_selected, widget, new_action, keyword) menu.add(menuitem) - + if keyword == 'action': + menu.add(gtk.SeparatorMenuItem()) + for plugin in plugins.MODULES: + for name, func in plugin.get_plugins(self.model): + menuitem = gtk.MenuItem('_' + name) + menuitem.set_use_underline(True) + menuitem.connect('activate', lambda *a: func({ + 'model': self.model, + 'ids': self.id_get(), + 'id': self.id_get(), + })) + menu.add(menuitem) return menu def _popup_menu_selected(self, menuitem, togglebutton, action, keyword): diff --git a/tryton/plugins/__init__.py b/tryton/plugins/__init__.py index 492786bb6b..d66d689b03 100644 --- a/tryton/plugins/__init__.py +++ b/tryton/plugins/__init__.py @@ -1,6 +1,5 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. -from tryton import common import os import sys import imp @@ -15,29 +14,17 @@ if not os.path.isdir(PLUGINS_PATH): os.path.dirname(sys.argv[0]))), 'plugins') MODULES = [] -if os.path.isdir(PLUGINS_PATH): - for plugin in os.listdir(PLUGINS_PATH): - if not os.path.isdir(os.path.join(PLUGINS_PATH, plugin)): - continue - module = os.path.splitext(plugin)[0] - try: - module = imp.load_module(module, *imp.find_module(module, - [PLUGINS_PATH])) - MODULES.append(module) - except ImportError, exception: - continue - -def execute(datas): - result = {} - - for module in MODULES: - for name, func in module.get_plugins(datas['model']): - result[name] = func - if not result: - common.message(_('No available plugin for this resource!')) - return False - res = common.selection(_('Choose a Plugin'), result, alwaysask=True) - if res: - res[1](datas) - return True +def register(): + global MODULES + if os.path.isdir(PLUGINS_PATH): + for plugin in os.listdir(PLUGINS_PATH): + if not os.path.isdir(os.path.join(PLUGINS_PATH, plugin)): + continue + module = os.path.splitext(plugin)[0] + try: + module = imp.load_module(module, *imp.find_module(module, + [PLUGINS_PATH])) + MODULES.append(module) + except ImportError: + continue