diff options
Diffstat (limited to 'mvc/widgets/gtk/gtkmenus.py')
-rw-r--r-- | mvc/widgets/gtk/gtkmenus.py | 404 |
1 files changed, 0 insertions, 404 deletions
diff --git a/mvc/widgets/gtk/gtkmenus.py b/mvc/widgets/gtk/gtkmenus.py deleted file mode 100644 index 926ba15..0000000 --- a/mvc/widgets/gtk/gtkmenus.py +++ /dev/null @@ -1,404 +0,0 @@ -# @Base: Miro - an RSS based video player application -# Copyright (C) 2011 -# Participatory Culture Foundation -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# In addition, as a special exception, the copyright holders give -# permission to link the code of portions of this program with the OpenSSL -# library. -# -# You must obey the GNU General Public License in all respects for all of -# the code used other than OpenSSL. If you modify file(s) with this -# exception, you may extend this exception to your version of the file(s), -# but you are not obligated to do so. If you do not wish to do so, delete -# this exception statement from your version. If you delete this exception -# statement from all source files in the program, then also delete it here. - -"""gtkmenus.py -- Manage menu layout.""" - -import gtk - -from mvc.widgets import app - -import base -import keymap -import wrappermap - -def _setup_accel(widget, name, shortcut=None): - """Setup accelerators for a menu item. - - This method sets an accel path for the widget and optionally connects a - shortcut to that accel path. - """ - # The GTK docs say that we should set the path using this form: - # <Window-Name>/Menu/Submenu/MenuItem - # ...but this is hard to do because we don't yet know what window/menu - # this menu item is going to be added to. gtk.Action and gtk.ActionGroup - # don't follow the above suggestion, so we don't need to either. - path = "<MiroActions>/MenuBar/%s" % name - widget.set_accel_path(path) - if shortcut is not None: - accel_string = keymap.get_accel_string(shortcut) - key, mods = gtk.accelerator_parse(accel_string) - if gtk.accel_map_lookup_entry(path) is None: - gtk.accel_map_add_entry(path, key, mods) - else: - gtk.accel_map_change_entry(path, key, mods, True) - -# map menu names to GTK stock ids. -_STOCK_IDS = { - "SaveItem": gtk.STOCK_SAVE, - "CopyItemURL": gtk.STOCK_COPY, - "RemoveItems": gtk.STOCK_REMOVE, - "StopItem": gtk.STOCK_MEDIA_STOP, - "NextItem": gtk.STOCK_MEDIA_NEXT, - "PreviousItem": gtk.STOCK_MEDIA_PREVIOUS, - "PlayPauseItem": gtk.STOCK_MEDIA_PLAY, - "Open": gtk.STOCK_OPEN, - "EditPreferences": gtk.STOCK_PREFERENCES, - "Quit": gtk.STOCK_QUIT, - "Help": gtk.STOCK_HELP, - "About": gtk.STOCK_ABOUT, - "Translate": gtk.STOCK_EDIT -} -try: - _STOCK_IDS['Fullscreen'] = gtk.STOCK_FULLSCREEN -except AttributeError: - # fullscreen not available on all GTK versions - pass - -class MenuItemBase(base.Widget): - """Base class for MenuItem and Separator.""" - - def show(self): - """Show this menu item.""" - self._widget.show() - - def hide(self): - """Hide and disable this menu item.""" - self._widget.hide() - - def remove_from_parent(self): - """Remove this menu item from it's parent Menu.""" - parent_menu = self._widget.get_parent() - if parent_menu is None: - return - parent_menu_item = parent_menu.get_attach_widget() - if parent_menu_item is None: - return - parent_menu_item.remove(self._widget) - - def _set_accel_group(self, accel_group): - # menu items don't care about the accel group, their parent Menu - # handles it for them - pass - -class MenuItem(MenuItemBase): - """Single item in the menu that can be clicked - - :param label: The label it has (must be internationalized) - :param name: String identifier for this item - :param shortcut: Shortcut object to use - - Signals: - - activate: menu item was clicked - - Example: - - >>> MenuItem(_("Preferences"), "EditPreferences") - >>> MenuItem(_("Cu_t"), "ClipboardCut", Shortcut("x", MOD)) - >>> MenuItem(_("_Update Podcasts and Library"), "UpdatePodcasts", - ... (Shortcut("r", MOD), Shortcut(F5))) - >>> MenuItem(_("_Play"), "PlayPauseItem", - ... play=_("_Play"), pause=_("_Pause")) - """ - - def __init__(self, label, name, shortcut=None): - MenuItemBase.__init__(self) - self.name = name - self.set_widget(self.make_widget(label)) - self.activate_id = self.wrapped_widget_connect('activate', - self._on_activate) - self._widget.show() - self.create_signal('activate') - _setup_accel(self._widget, self.name, shortcut) - - def _on_activate(self, menu_item): - self.emit('activate') - gtk_menubar = self._find_menubar() - if gtk_menubar is not None: - try: - menubar = wrappermap.wrapper(gtk_menubar) - except KeyError: - logging.exception('menubar activate: ' - 'no wrapper for gtbbk.MenuBar') - else: - menubar.emit('activate', self.name) - - def _find_menubar(self): - """Find the MenuBar that this menu item is attached to.""" - menu_item = self._widget - while True: - parent_menu = menu_item.get_parent() - if isinstance(parent_menu, gtk.MenuBar): - return parent_menu - elif parent_menu is None: - return None - menu_item = parent_menu.get_attach_widget() - if menu_item is None: - return None - - def make_widget(self, label): - """Create the menu item to use for this widget. - - Subclasses will probably want to override this. - """ - if self.name in _STOCK_IDS: - mi = gtk.ImageMenuItem(stock_id=_STOCK_IDS[self.name]) - mi.set_label(label) - return mi - else: - return gtk.MenuItem(label) - - def set_label(self, new_label): - self._widget.set_label(new_label) - - def get_label(self): - self._widget.get_label() - -class CheckMenuItem(MenuItem): - """MenuItem that toggles on/off""" - - def make_widget(self, label): - return gtk.CheckMenuItem(label) - - def set_state(self, active): - # prevent the activate signal from fireing in response to us manually - # changing a value - self._widget.handler_block(self.activate_id) - if active is not None: - self._widget.set_inconsistent(False) - self._widget.set_active(active) - else: - self._widget.set_inconsistent(True) - self._widget.set_active(False) - self._widget.handler_unblock(self.activate_id) - - def get_state(self): - return self._widget.get_active() - -class RadioMenuItem(CheckMenuItem): - """MenuItem that toggles on/off and is grouped with other RadioMenuItems. - """ - - def make_widget(self, label): - widget = gtk.RadioMenuItem() - widget.set_label(label) - return widget - - def set_group(self, group_item): - self._widget.set_group(group_item._widget) - - def remove_from_group(self): - """Remove this RadioMenuItem from its current group.""" - self._widget.set_group(None) - - def _on_activate(self, menu_item): - # GTK sends the activate signal for both the radio button that's - # toggled on and the one that gets turned off. Just emit our signal - # for the active radio button. - if self.get_state(): - MenuItem._on_activate(self, menu_item) - -class Separator(MenuItemBase): - """Separator item for menus""" - - def __init__(self): - MenuItemBase.__init__(self) - self.set_widget(gtk.SeparatorMenuItem()) - self._widget.show() - # Set name to be None just so that it has a similar API to other menu - # items. - self.name = None - -class MenuShell(base.Widget): - """Common code shared between Menu and MenuBar. - - Subclasses must define a _menu attribute that's a gtk.MenuShell subclass. - """ - - def __init__(self): - base.Widget.__init__(self) - self._accel_group = None - self.children = [] - - def append(self, menu_item): - """Add a menu item to the end of this menu.""" - self.children.append(menu_item) - menu_item._set_accel_group(self._accel_group) - self._menu.append(menu_item._widget) - - def insert(self, index, menu_item): - """Insert a menu item in the middle of this menu.""" - self.children.insert(index, menu_item) - menu_item._set_accel_group(self._accel_group) - self._menu.insert(menu_item._widget, index) - - def remove(self, menu_item): - """Remove a child menu item. - - :raises ValueError: menu_item is not a child of this menu - """ - self.children.remove(menu_item) - self._menu.remove(menu_item._widget) - menu_item._set_accel_group(None) - - def index(self, name): - """Get the position of a menu item in this list. - - :param name: name of the menu - :returns: index of the menu item, or -1 if not found. - """ - for i, menu_item in enumerate(self.children): - if menu_item.name == name: - return i - return -1 - - def get_children(self): - """Get the child menu items in order.""" - return list(self.children) - - def find(self, name): - """Search for a menu or menu item - - This method recursively searches the entire menu structure for a Menu - or MenuItem object with a given name. - - :raises KeyError: name not found - """ - found = self._find(name) - if found is None: - raise KeyError(name) - else: - return found - - def _find(self, name): - """Low-level helper-method for find(). - - :returns: found menu item or None. - """ - for menu_item in self.get_children(): - if menu_item.name == name: - return menu_item - if isinstance(menu_item, MenuShell): - submenu_find = menu_item._find(name) - if submenu_find is not None: - return submenu_find - return None - -class Menu(MenuShell): - """A Menu holds a list of MenuItems and Menus. - - Example: - >>> Menu(_("P_layback"), "Playback", [ - ... MenuItem(_("_Foo"), "Foo"), - ... MenuItem(_("_Bar"), "Bar") - ... ]) - >>> Menu("", "toplevel", [ - ... Menu(_("_File"), "File", [ ... ]) - ... ]) - """ - - def __init__(self, label, name, child_items): - MenuShell.__init__(self) - self.set_widget(gtk.MenuItem(label)) - self._widget.show() - self.name = name - # set up _menu for the MenuShell code - self._menu = gtk.Menu() - _setup_accel(self._menu, self.name) - self._widget.set_submenu(self._menu) - for item in child_items: - self.append(item) - - def show(self): - """Show this menu.""" - self._widget.show() - - def hide(self): - """Hide this menu.""" - self._widget.hide() - - def _set_accel_group(self, accel_group): - """Set the accel group for this widget. - - Accel groups get created by the MenuBar. Whenever a menu or menu item - is added to that menu bar, the parent calls _set_accel_group() to give - the accel group to the child. - """ - if accel_group == self._accel_group: - return - self._menu.set_accel_group(accel_group) - self._accel_group = accel_group - for child in self.children: - child._set_accel_group(accel_group) - -class MenuBar(MenuShell): - """Displays a list of Menu items. - - Signals: - - - activate(menu_bar, name): a menu item was activated - """ - - def __init__(self): - """Create a new MenuBar - - :param name: string id to use for our action group - """ - MenuShell.__init__(self) - self.create_signal('activate') - self.set_widget(gtk.MenuBar()) - self._widget.show() - self._accel_group = gtk.AccelGroup() - # set up _menu for the MenuShell code - self._menu = self._widget - - def get_accel_group(self): - return self._accel_group - -class MainWindowMenuBar(MenuBar): - """MenuBar for the main window. - - This gets installed into app.widgetapp.menubar on GTK. - """ - def add_initial_menus(self, menus): - """Add the initial set of menus. - - We modify the menu structure slightly for GTK. - """ - for menu in menus: - self.append(menu) - self._modify_initial_menus() - - def _modify_initial_menus(self): - """Update the portable root menu with GTK-specific stuff.""" - # on linux, we don't have a CheckVersion option because - # we update with the package system. - #this_platform = app.config.get(prefs.APP_PLATFORM) - #if this_platform == 'linux': - # self.find("CheckVersion").remove_from_parent() - #app.video_renderer.setup_subtitle_encoding_menu() |