Exemplo n.º 1
0
    def register(self, name, bindings, callback, args=[], kwargs={}):
        """ Registers an action for a predefined keybinding name.
        @param name: Action name, defined in L{BINDING_INFO}.
        @param bindings: List of keybinding strings, as understood
                         by L{gtk.accelerator_parse}. Only used if no
                         bindings were loaded for this action.
        @param callback: Function callback
        @param args: List of arguments to pass to the callback
        @param kwargs: List of keyword arguments to pass to the callback.
        """
        global BINDING_INFO
        assert name in BINDING_INFO, "'%s' isn't a valid keyboard action." % name

        # Load stored keybindings, or fall back to passed arguments
        keycodes = self._action_to_bindings[name]
        if keycodes == []:
            keycodes = [gtk.accelerator_parse(binding) for binding in bindings ]

        for keycode in keycodes:
            if keycode in self._binding_to_action.keys():
                if self._binding_to_action[keycode] != name:
                    log.warning(_('Keybinding for "%(action)s" overrides hotkey for another action.'),
                            {"action": name})
                    log.warning('Binding %s overrides %r' % (keycode, self._binding_to_action[keycode]))
            else:
                self._binding_to_action[keycode] = name
                self._action_to_bindings[name].append(keycode)

        # Add gtk accelerator for labels in menu
        if len(self._action_to_bindings[name]) > 0:
            key, mod = self._action_to_bindings[name][0]
            gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % name, key, mod, True)

        self._action_to_callback[name] = (callback, args, kwargs)
Exemplo n.º 2
0
    def register(self, name, bindings, callback, args=[], kwargs={}):
        """ Registers an action for a predefined keybinding name.
        @param name: Action name, defined in L{BINDING_INFO}.
        @param bindings: List of keybinding strings, as understood
                         by L{gtk.accelerator_parse}. Only used if no
                         bindings were loaded for this action.
        @param callback: Function callback
        @param args: List of arguments to pass to the callback
        @param kwargs: List of keyword arguments to pass to the callback.
        """
        global BINDING_INFO
        assert name in BINDING_INFO, "'%s' isn't a valid keyboard action." % name

        # Load stored keybindings, or fall back to passed arguments
        keycodes = self._action_to_bindings[name]
        if keycodes == []:
            keycodes = [gtk.accelerator_parse(binding) for binding in bindings ]

        for keycode in keycodes:
            if keycode in self._binding_to_action.keys():
                if self._binding_to_action[keycode] != name:
                    log.warning(_('Keybinding for "%(action)s" overrides hotkey for another action.'),
                            {"action": name})
                    log.warning('Binding %s overrides %r' % (keycode, self._binding_to_action[keycode]))
            else:
                self._binding_to_action[keycode] = name
                self._action_to_bindings[name].append(keycode)

        # Add gtk accelerator for labels in menu
        if len(self._action_to_bindings[name]) > 0:
            key, mod = self._action_to_bindings[name][0]
            gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % name, key, mod, True)

        self._action_to_callback[name] = (callback, args, kwargs)
Exemplo n.º 3
0
        def on_accel_edited(renderer, path, accel_key, accel_mods,
                            hardware_keycode):
            iter = self.treestore.get_iter(path)
            col = column + 3  # accel cells start from 3 position
            old_accel = self.treestore.get(iter, col)[0]
            new_accel = gtk.accelerator_name(accel_key, accel_mods)
            self.treestore.set_value(iter, col, new_accel)
            action_name = self.treestore.get_value(iter, 1)
            affected_action = self.keymanager.edit_accel(
                action_name, new_accel, old_accel)

            # Find affected row and cell
            if affected_action == action_name:
                for idx in range(0, self.accel_column_num):
                    if idx != column and self.treestore.get(
                            iter, idx + 3)[0] == new_accel:
                        self.treestore.set_value(iter, idx + 3, "")
            elif affected_action is not None:
                titer = self.action_treeiter_map[affected_action]
                for idx in range(0, self.accel_column_num):
                    if self.treestore.get(titer, idx + 3)[0] == new_accel:
                        self.treestore.set_value(titer, idx + 3, "")

            # updating gtk accelerator for label in menu
            if self.keymanager.get_bindings_for_action(action_name)[0] == (
                    accel_key, accel_mods):
                gtk.accel_map_change_entry(
                    '<Actions>/mcomix-main/%s' % action_name, accel_key,
                    accel_mods, True)
 def _response(dlg, response):
     d.hide()
     if response == gtk.RESPONSE_ACCEPT:
         newaccel = e.get_text()
         action.set_accel(newaccel)
         actwrap.reset_markup()
         key, mod = gtk.accelerator_parse(newaccel)
         gtk.accel_map_change_entry(action.accel_path, key, mod, True)
     d.destroy()
Exemplo n.º 5
0
 def _response(dlg, response):
     d.hide()
     if response == gtk.RESPONSE_ACCEPT:
         newaccel = e.get_text()
         action.set_accel(newaccel)
         actwrap.reset_markup()
         key, mod = gtk.accelerator_parse(newaccel)
         gtk.accel_map_change_entry(action.accel_path, key, mod, True)
     d.destroy()
Exemplo n.º 6
0
    def on_accel_cleared(self, renderer, path, *args):
        iter = self.actions.get_iter(path)
        name = self.actions.get_value(iter, 0)
        path = shortcuts.get_path_by_name(name)

        accel_map_change_entry(path, 0, 0, True)
        shortcuts.names_by_key.clear()

        self.actions.set_value(iter, 1, None)
        self.actions.set_value(iter, 4, WEIGHT_BOLD)
Exemplo n.º 7
0
    def on_accel_edited(self, renderer, path, accel_key, accel_mods, hardware_keycode):
        iter = self.actions.get_iter(path)
        accel = accelerator_name(accel_key, accel_mods)
        name = self.actions.get_value(iter, 0)
        path = shortcuts.get_path_by_name(name)

        accel_map_change_entry(path, accel_key, accel_mods, True)
        shortcuts.names_by_key.clear()

        self.actions.set_value(iter, 1, accel)
        self.actions.set_value(iter, 4, self.get_weight(path, accel_key, accel_mods))
Exemplo n.º 8
0
    def on_ok_click(self, event):
        self._get_dialog_widgets_values()
        self._set_options_from_widgets_values()

        # Reconfigure accel keys on menu
        for index, action in enumerate(self.action_list):
            accel_value = gtk.accelerator_parse(self.options[index])
            accel_path = self.action_path + action
            gtk.accel_map_change_entry(accel_path, accel_value[0], accel_value[1], False)

        self._set_config_file()
        self.dialog.destroy()
Exemplo n.º 9
0
    def apply_changes_to_accel(self, iter):
        """ Recursively saves accelerators from tree to gtk.AccelMap. """
        if not iter: return

        if self.__model[iter][2]:
            path = self.__model[iter][2]
            (key, mods) = self.__my_accel_map[path]
            gtk.accel_map_change_entry(path, key, mods, False)

        if self.__model.iter_has_child(iter):
            self.apply_changes_to_accel(self.__model.iter_children(iter))

        self.apply_changes_to_accel(self.__model.iter_next(iter))
Exemplo n.º 10
0
 def on_accel_edited(self, renderer, path, accel_key, accel_mods,
                     hardware_keycode):
     model = self.shortcuts_model
     iter_ = model.get_iter(path)
     action = model.get_value(iter_, 5)
     if not action:
         return
     if accel_key == gtk.keysyms.Delete and not accel_mods:
         accel_key = accel_mods = 0
     model.set_value(iter_, 1, accel_key)
     model.set_value(iter_, 2, accel_mods)
     gtk.accel_map_change_entry(action.get_accel_path(),
                                accel_key, accel_mods, True)
Exemplo n.º 11
0
    def apply_changes_to_accel(self, iter):
        """ Recursively saves accelerators from tree to gtk.AccelMap. """
        if not iter: return

        if self.__model[iter][2]:
            path        = self.__model[iter][2]
            (key, mods) = self.__my_accel_map[path]
            gtk.accel_map_change_entry(path, key, mods, False)                    

        if self.__model.iter_has_child(iter):
            self.apply_changes_to_accel(self.__model.iter_children(iter))

        self.apply_changes_to_accel(self.__model.iter_next(iter))
Exemplo n.º 12
0
 def _is_valid_accel(self, keyval, mod):
     accel_path = self.action_path + self.action_list[self.accel_index]
     old_accel = gtk.accel_map_lookup_entry(accel_path)
     if not gtk.accel_map_change_entry(accel_path, keyval, mod, False):
         msgdlg = gtk.MessageDialog(self.dialog,
                                    gtk.DIALOG_MODAL,
                                    gtk.MESSAGE_ERROR,
                                    gtk.BUTTONS_OK,
                                    _('Shortcut %s is already in use') % gtk.accelerator_name(keyval, mod))
         msgdlg.run()
         msgdlg.destroy()
         return False
     else:
         gtk.accel_map_change_entry(accel_path, old_accel[0], old_accel[1], True)
         return True
Exemplo n.º 13
0
 def register_gtk_accelerator(self, groupname, action, accel_string,
                              accel_name):
     # menu item and shortcut
     try:
         import gtk
     except ImportError:
         return
     actiongroup = gtk.ActionGroup(groupname)
     accel_path = "<pycam>/%s" % accel_name
     action.set_accel_path(accel_path)
     # it is a bit pointless, but we allow an empty accel_string anyway ...
     if accel_string:
         key, mod = gtk.accelerator_parse(accel_string)
         gtk.accel_map_change_entry(accel_path, key, mod, True)
     actiongroup.add_action(action)
     self.core.get("gtk-uimanager").insert_action_group(actiongroup, pos=-1)
 def add_action_with_accel(self, action, accel):
     # print "add_action_with_accel"
     _keyval = None
     _mods = None
     _name = action.get_name()
     _path = "/".join(['<Actions>', self.name, _name])
     if accel is None:
         # print "accel is None"
         _sid = action.get_property('stock-id')
         if _sid != '':
             # print "sid = '%s'" % _sid
             _data = gtk.stock_lookup(_sid)
             if _data is not None and _data[3] != 0:
                 # print "data: " + str(_data)
                 _mods = _data[2]
                 _keyval = _data[3]
     else:
         _k, _m = gtk.accelerator_parse(accel)
         if gtk.accelerator_valid(_k, _m):
             _keyval = _k
             _mods = _m
     if _keyval is not None:
         # print "calling gtk.accel_map_change_entry()"
         # print "Path: " + _path
         # print "Key: " + str(_keyval)
         # print "Mods: " + str(_mods)
         if not gtk.accel_map_change_entry(_path, _keyval, _mods, True):
             print "Failed to change accel_map for '%s'" % _path
     action.set_accel_path(_path)
     self.add_action(action)
Exemplo n.º 15
0
 def register_gtk_accelerator(self, groupname, action, accel_string,
         accel_name):
     # menu item and shortcut
     try:
         import gtk
     except ImportError:
         return
     actiongroup = gtk.ActionGroup(groupname)
     accel_path = "<pycam>/%s" % accel_name
     action.set_accel_path(accel_path)
     # it is a bit pointless, but we allow an empty accel_string anyway ...
     if accel_string:
         key, mod = gtk.accelerator_parse(accel_string)
         gtk.accel_map_change_entry(accel_path, key, mod, True)
     actiongroup.add_action(action)
     self.core.get("gtk-uimanager").insert_action_group(actiongroup, pos=-1)
Exemplo n.º 16
0
        def on_accel_cleared(renderer, path, *args):
            iter = self.treestore.get_iter(path)
            col = column + 3
            accel = self.treestore.get(iter, col)[0]
            action_name = self.treestore.get_value(iter, 1)
            if accel != "":
                self.keymanager.clear_accel(action_name, accel)

                # updating gtk accelerator for label in menu
                if len(self.keymanager.get_bindings_for_action(action_name)) == 0:
                    gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % action_name, 0, 0, True)
                else:
                    key, mods  = self.keymanager.get_bindings_for_action(action_name)[0]
                    gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % action_name, key, mods, True)

            self.treestore.set_value(iter, col, "")
Exemplo n.º 17
0
    def add_ui_actions(self,
                       ui_string,
                       actions,
                       name='Actions',
                       action_type='normal',
                       filename=None,
                       instance=None):
        if instance is None:
            instance = self
        ag = self._get_action_group(name)

        to_add = [entry[0] for entry in actions]
        for action in ag.list_actions():
            if action.get_name() in to_add:
                ag.remove_action(action)

        if action_type == 'normal':
            ag.add_actions(actions)
        elif action_type == 'toggle':
            ag.add_toggle_actions(actions)
        elif action_type == 'radio':
            ag.add_radio_actions(actions)
        else:
            raise ValueError(action_type)
        if filename is not None:
            ui_string = environ.get_resource_string('stoq', 'uixml', filename)
        ui_id = self.uimanager.add_ui_from_string(ui_string)

        self.action_permissions.update(self.common_action_permissions)
        pm = PermissionManager.get_permission_manager()
        for action in ag.list_actions():
            action_name = action.get_name()
            setattr(instance, action_name, action)

            # Check permissions
            key, required = instance.action_permissions.get(
                action_name, (None, pm.PERM_ALL))
            if not pm.get(key) & required:
                action.set_visible(False)
                # Disable keyboard shortcut
                path = action.get_accel_path()
                gtk.accel_map_change_entry(path, 0, 0, True)

        return ui_id
Exemplo n.º 18
0
    def add_ui_actions(self, ui_string,
                       actions,
                       name='Actions',
                       action_type='normal',
                       filename=None,
                       instance=None):
        if instance is None:
            instance = self
        ag = self._get_action_group(name)

        to_add = [entry[0] for entry in actions]
        for action in ag.list_actions():
            if action.get_name() in to_add:
                ag.remove_action(action)

        if action_type == 'normal':
            ag.add_actions(actions)
        elif action_type == 'toggle':
            ag.add_toggle_actions(actions)
        elif action_type == 'radio':
            ag.add_radio_actions(actions)
        else:
            raise ValueError(action_type)
        if filename is not None:
            ui_string = environ.get_resource_string('stoq', 'uixml', filename)
        ui_id = self.uimanager.add_ui_from_string(ui_string)

        self.action_permissions.update(self.common_action_permissions)
        pm = PermissionManager.get_permission_manager()
        for action in ag.list_actions():
            action_name = action.get_name()
            setattr(instance, action_name, action)

            # Check permissions
            key, required = instance.action_permissions.get(action_name,
                                                            (None, pm.PERM_ALL))
            if not pm.get(key) & required:
                action.set_visible(False)
                # Disable keyboard shortcut
                path = action.get_accel_path()
                gtk.accel_map_change_entry(path, 0, 0, True)

        return ui_id
Exemplo n.º 19
0
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)
Exemplo n.º 20
0
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)
Exemplo n.º 21
0
        def on_accel_cleared(renderer, path, *args):
            iter = self.treestore.get_iter(path)
            col = column + 3
            accel = self.treestore.get(iter, col)[0]
            action_name = self.treestore.get_value(iter, 1)
            if accel != "":
                self.keymanager.clear_accel(action_name, accel)

                # updating gtk accelerator for label in menu
                if len(self.keymanager.get_bindings_for_action(
                        action_name)) == 0:
                    gtk.accel_map_change_entry(
                        '<Actions>/mcomix-main/%s' % action_name, 0, 0, True)
                else:
                    key, mods = self.keymanager.get_bindings_for_action(
                        action_name)[0]
                    gtk.accel_map_change_entry(
                        '<Actions>/mcomix-main/%s' % action_name, key, mods,
                        True)

            self.treestore.set_value(iter, col, "")
Exemplo n.º 22
0
    def _insert_directory(self, directory, path):
        manager = self._window.get_ui_manager()

        for item in directory.subdirs:
            action_name = 'ExternalToolDirectory%X' % id(item)
            action = gtk.Action(action_name, item.name.replace('_', '__'),
                                None, None)
            self._action_group.add_action(action)

            manager.add_ui(self._merge_id, path, action_name, action_name,
                           gtk.UI_MANAGER_MENU, False)

            self._insert_directory(item, path + '/' + action_name)

        for item in directory.tools:
            action_name = 'ExternalToolTool%X' % id(item)
            action = gtk.Action(action_name, item.name.replace('_', '__'),
                                item.comment, None)
            handler = action.connect("activate", capture_menu_action,
                                     self._window, item)

            action.set_data(self.ACTION_ITEM_DATA_KEY, item)
            action.set_data(self.ACTION_HANDLER_DATA_KEY, handler)

            # Make sure to replace accel
            accelpath = '<Actions>/ExternalToolsPluginToolActions/%s' % (
                action_name, )

            if item.shortcut:
                key, mod = gtk.accelerator_parse(item.shortcut)
                gtk.accel_map_change_entry(accelpath, key, mod, True)

                self._signals.append(gtk.accel_map_get().connect(
                    'changed::%s' % (accelpath, ), self.on_accelmap_changed,
                    item))

            self._action_group.add_action_with_accel(action, item.shortcut)

            manager.add_ui(self._merge_id, path, action_name, action_name,
                           gtk.UI_MANAGER_MENUITEM, False)
Exemplo n.º 23
0
        def on_accel_edited(renderer, path, accel_key, accel_mods, hardware_keycode):
            iter = self.treestore.get_iter(path)
            col = column + 3  # accel cells start from 3 position
            old_accel = self.treestore.get(iter, col)[0]
            new_accel = gtk.accelerator_name(accel_key, accel_mods)
            self.treestore.set_value(iter, col, new_accel)
            action_name = self.treestore.get_value(iter, 1)
            affected_action = self.keymanager.edit_accel(action_name, new_accel, old_accel)

            # Find affected row and cell
            if affected_action == action_name:
                for idx in range(0, self.accel_column_num):
                    if idx != column and self.treestore.get(iter, idx + 3)[0] == new_accel:
                        self.treestore.set_value(iter, idx + 3, "")
            elif affected_action is not None:
                titer = self.action_treeiter_map[affected_action]
                for idx in range(0, self.accel_column_num):
                    if self.treestore.get(titer, idx + 3)[0] == new_accel:
                        self.treestore.set_value(titer, idx + 3, "")

            # updating gtk accelerator for label in menu
            if self.keymanager.get_bindings_for_action(action_name)[0] == (accel_key, accel_mods):
                gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % action_name,
                        accel_key, accel_mods, True)
Exemplo n.º 24
0
    def _insert_directory(self, directory, path):
        manager = self._window.get_ui_manager()

        for item in directory.subdirs:
            action_name = 'RunExternalToolDirectory%X' % id(item)
            action = gtk.Action(action_name, item.name.replace('_', '__'), None, None)
            self._action_group.add_action(action)

            manager.add_ui(self._merge_id, path,
                           action_name, action_name,
                           gtk.UI_MANAGER_MENU, False)
                           
            self._insert_directory(item, path + '/' + action_name)

        for item in directory.tools:
            action_name = 'RunExternalToolTool%X' % id(item)
            action = gtk.Action(action_name, item.name.replace('_', '__'), item.comment, None)
            handler = action.connect("activate", capture_menu_action, self._window, item)

            action.set_data(self.ACTION_ITEM_DATA_KEY, item)
            action.set_data(self.ACTION_HANDLER_DATA_KEY, handler)
            
            # Make sure to replace accel
            accelpath = '<Actions>/RunExternalToolsPluginToolActions/%s' % (action_name, )
            
            if item.shortcut:
                key, mod = gtk.accelerator_parse(item.shortcut)
                gtk.accel_map_change_entry(accelpath, key, mod, True)
                
                self._signals.append(gtk.accel_map_get().connect('changed::%s' % (accelpath,), self.on_accelmap_changed, item))
                
            self._action_group.add_action_with_accel(action, item.shortcut)

            manager.add_ui(self._merge_id, path,
                           action_name, action_name,
                           gtk.UI_MANAGER_MENUITEM, False)
Exemplo n.º 25
0
    def __init__(self, window):
        gtk.UIManager.__init__(self)

        self._window = window
        self._tooltipstatus = status.TooltipStatusHelper(
            self, window.statusbar)

        # ----------------------------------------------------------------
        # Create actions for the menus.
        # ----------------------------------------------------------------
        self._actiongroup = gtk.ActionGroup('mcomix-main')
        self._actiongroup.add_actions([
            ('copy_page', gtk.STOCK_COPY, _('_Copy'), None,
             _('Copies the current page to clipboard.'),
             window.clipboard.copy_page),
            ('delete', gtk.STOCK_DELETE, _('_Delete'), None,
             _('Deletes the current file or archive from disk.'),
             window.delete),
            ('next_page', gtk.STOCK_GO_FORWARD, _('_Next page'), None,
             _('Next page'), window.next_page),
            ('previous_page', gtk.STOCK_GO_BACK, _('_Previous page'), None,
             _('Previous page'), window.previous_page),
            ('first_page', gtk.STOCK_GOTO_FIRST, _('_First page'), None,
             _('First page'), window.first_page),
            ('last_page', gtk.STOCK_GOTO_LAST, _('_Last page'), None,
             _('Last page'), window.last_page),
            ('go_to', gtk.STOCK_JUMP_TO, _('_Go to page...'), None,
             _('Go to page...'), window.page_select),
            ('refresh_archive', gtk.STOCK_REFRESH, _('Re_fresh'), None,
             _('Reloads the currently opened files or archive.'),
             window.filehandler.refresh_file),
            ('next_archive', gtk.STOCK_MEDIA_NEXT, _('Next _archive'), None,
             _('Next archive'), window.filehandler._open_next_archive),
            ('previous_archive', gtk.STOCK_MEDIA_PREVIOUS,
             _('Previous a_rchive'), None, _('Previous archive'),
             window.filehandler._open_previous_archive),
            ('next_directory', gtk.STOCK_REDO, _('Next directory'), None,
             _('Next directory'), window.filehandler.open_next_directory),
            ('previous_directory', gtk.STOCK_UNDO, _('Previous directory'),
             None, _('Previous directory'),
             window.filehandler.open_previous_directory),
            ('zoom_in', gtk.STOCK_ZOOM_IN, _('Zoom _In'), None, None,
             window.manual_zoom_in),
            ('zoom_out', gtk.STOCK_ZOOM_OUT, _('Zoom _Out'), None, None,
             window.manual_zoom_out),
            ('zoom_original', gtk.STOCK_ZOOM_100, _('_Normal Size'), None,
             None, window.manual_zoom_original),
            ('minimize', gtk.STOCK_LEAVE_FULLSCREEN, _('Mi_nimize'), None,
             None, window.minimize),
            ('close', gtk.STOCK_CLOSE, _('_Close'), None,
             _('Closes all opened files.'), window.filehandler.close_file),
            ('quit', gtk.STOCK_QUIT, _('_Quit'), None, None,
             window.close_program),
            ('save_and_quit', gtk.STOCK_QUIT, _('_Save and quit'), None,
             _('Quits and restores the currently opened file next time the program starts.'
               ), window.save_and_terminate_program),
            ('rotate_90', 'mcomix-rotate-90', _('_Rotate 90 degrees CW'), None,
             None, window.rotate_90),
            ('rotate_180', 'mcomix-rotate-180', _('Rotate 180 de_grees'), None,
             None, window.rotate_180),
            ('rotate_270', 'mcomix-rotate-270', _('Rotat_e 90 degrees CCW'),
             None, None, window.rotate_270),
            ('flip_horiz', 'mcomix-flip-horizontal', _('Fli_p horizontally'),
             None, None, window.flip_horizontally),
            ('flip_vert', 'mcomix-flip-vertical', _('Flip _vertically'), None,
             None, window.flip_vertically),
            ('extract_page', gtk.STOCK_SAVE_AS, _('Save _As'), None, None,
             window.extract_page), ('menu_zoom', 'mcomix-zoom', _('_Zoom')),
            ('menu_recent', gtk.STOCK_DND_MULTIPLE, _('_Recent')),
            ('menu_bookmarks_popup', 'comix-add-bookmark', _('_Bookmarks')),
            ('menu_bookmarks', None, _('_Bookmarks')),
            ('menu_toolbars', None, _('T_oolbars')),
            ('menu_edit', None, _('_Edit')),
            ('menu_open_with', gtk.STOCK_OPEN, _('Open _with'), ''),
            ('menu_open_with_popup', gtk.STOCK_OPEN, _('Open _with'), ''),
            ('menu_file', None, _('_File')), ('menu_view', None, _('_View')),
            ('menu_view_popup', 'comix-image', _('_View')),
            ('menu_go', None, _('_Go')),
            ('menu_go_popup', gtk.STOCK_GO_FORWARD, _('_Go')),
            ('menu_tools', None, _('_Tools')), ('menu_help', None, _('_Help')),
            ('menu_transform', 'mcomix-transform', _('_Transform image')),
            ('menu_autorotate', None, _('_Auto-rotate image')),
            ('menu_autorotate_width', None, _('...when width exceeds height')),
            ('menu_autorotate_height', None,
             _('...when height exceeds width')),
            ('expander', None, None, None, None, None)
        ])

        self._actiongroup.add_toggle_actions([
            ('fullscreen', gtk.STOCK_FULLSCREEN, _('_Fullscreen'), None,
             _('Fullscreen mode'), window.change_fullscreen),
            ('double_page', 'mcomix-double-page', _('_Double page mode'), None,
             _('Double page mode'), window.change_double_page),
            ('toolbar', None, _('_Toolbar'), None, None,
             window.change_toolbar_visibility),
            ('menubar', None, _('_Menubar'), None, None,
             window.change_menubar_visibility),
            ('statusbar', None, _('St_atusbar'), None, None,
             window.change_statusbar_visibility),
            ('scrollbar', None, _('S_crollbars'), None, None,
             window.change_scrollbar_visibility),
            ('thumbnails', None, _('Th_umbnails'), None, None,
             window.change_thumbnails_visibility),
            ('hide_all', None, _('H_ide all'), None, None,
             window.change_hide_all),
            ('manga_mode', 'mcomix-manga', _('_Manga mode'), None,
             _('Manga mode'), window.change_manga_mode),
            ('invert_scroll', gtk.STOCK_UNDO, _('Invert smart scroll'), None,
             _('Invert smart scrolling direction.'),
             window.change_invert_scroll),
            ('keep_transformation', None, _('_Keep transformation'), None,
             _('Keeps the currently selected transformation for the next pages.'
               ), window.change_keep_transformation),
            ('slideshow', gtk.STOCK_MEDIA_PLAY, _('Start _slideshow'), None,
             _('Start slideshow'), window.slideshow.toggle),
            ('lens', 'mcomix-lens', _('Magnifying _lens'), None,
             _('Magnifying lens'), window.lens.toggle),
            ('stretch', None, _('Stretch small images'), None,
             _('Stretch images to fit to the screen, depending on zoom mode.'),
             window.change_stretch)
        ])

        # Note: Don't change the default value for the radio buttons unless
        # also fixing the code for setting the correct one on start-up in main.py.
        self._actiongroup.add_radio_actions(
            [('best_fit_mode', 'mcomix-fitbest', _('_Best fit mode'), None,
              _('Best fit mode'), constants.ZOOM_MODE_BEST),
             ('fit_width_mode', 'mcomix-fitwidth', _('Fit _width mode'), None,
              _('Fit width mode'), constants.ZOOM_MODE_WIDTH),
             ('fit_height_mode', 'mcomix-fitheight', _('Fit _height mode'),
              None, _('Fit height mode'), constants.ZOOM_MODE_HEIGHT),
             ('fit_size_mode', 'mcomix-fitsize', _('Fit _size mode'), None,
              _('Fit to size mode'), constants.ZOOM_MODE_SIZE),
             ('fit_manual_mode', 'mcomix-fitmanual', _('M_anual zoom mode'),
              None, _('Manual zoom mode'), constants.ZOOM_MODE_MANUAL)], 3,
            window.change_zoom_mode)

        # Automatically rotate image if width>height or height>width
        self._actiongroup.add_radio_actions([
            ('no_autorotation', None, _('Never'), None, None,
             constants.AUTOROTATE_NEVER),
            ('rotate_90_width', 'mcomix-rotate-90', _('_Rotate 90 degrees CW'),
             None, None, constants.AUTOROTATE_WIDTH_90),
            ('rotate_270_width', 'mcomix-rotate-270',
             _('Rotat_e 90 degrees CCW'), None, None,
             constants.AUTOROTATE_WIDTH_270),
            ('rotate_90_height', 'mcomix-rotate-90',
             _('_Rotate 90 degrees CW'), None, None,
             constants.AUTOROTATE_HEIGHT_90),
            ('rotate_270_height', 'mcomix-rotate-270',
             _('Rotat_e 90 degrees CCW'), None, None,
             constants.AUTOROTATE_HEIGHT_270)
        ], prefs['auto rotate depending on size'], window.change_autorotation)

        self._actiongroup.add_actions(
            [('about', gtk.STOCK_ABOUT, _('_About'), None, None,
              dialog_handler.open_dialog)], (window, 'about-dialog'))

        self._actiongroup.add_actions(
            [('comments', 'mcomix-comments', _('Co_mments...'), None, None,
              dialog_handler.open_dialog)], (window, 'comments-dialog'))

        self._actiongroup.add_actions(
            [('properties', gtk.STOCK_PROPERTIES, _('Proper_ties'), None, None,
              dialog_handler.open_dialog)], (window, 'properties-dialog'))

        self._actiongroup.add_actions(
            [('preferences', gtk.STOCK_PREFERENCES, _('Pr_eferences'), None,
              None, preferences_dialog.open_dialog)], (window))

        # Some actions added separately since they need extra arguments.
        self._actiongroup.add_actions(
            [('edit_archive', gtk.STOCK_EDIT, _('_Edit archive...'), None,
              _('Opens the archive editor.'), edit_dialog.open_dialog),
             ('open', gtk.STOCK_OPEN, _('_Open...'), None, None,
              file_chooser_main_dialog.open_main_filechooser_dialog),
             ('enhance_image', 'mcomix-enhance-image', _('En_hance image...'),
              None, None, enhance_dialog.open_dialog)], window)

        self._actiongroup.add_actions(
            [('library', 'mcomix-library', _('_Library...'), None, None,
              library_main_dialog.open_dialog)], window)

        # fix some gtk magic: removing unreqired accelerators
        gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % 'close', 0, 0,
                                   True)

        ui_description = """
        <ui>
            <toolbar name="Tool">
                <toolitem action="previous_archive" />
                <toolitem action="first_page" />
                <toolitem action="previous_page" />
                <toolitem action="go_to" />
                <toolitem action="next_page" />
                <toolitem action="last_page" />
                <toolitem action="next_archive" />
                <separator />
                <toolitem action="slideshow" />
                <toolitem action="expander" />
                <toolitem action="best_fit_mode" />
                <toolitem action="fit_width_mode" />
                <toolitem action="fit_height_mode" />
                <toolitem action="fit_size_mode" />
                <toolitem action="fit_manual_mode" />
                <separator />
                <toolitem action="double_page" />
                <toolitem action="manga_mode" />
                <separator />
                <toolitem action="lens" />
            </toolbar>

            <menubar name="Menu">
                <menu action="menu_file">
                    <menuitem action="open" />
                    <menu action="menu_recent" />
                    <menuitem action="library" />
                    <separator />
                    <menuitem action="extract_page" />
                    <menuitem action="refresh_archive" />
                    <menuitem action="properties" />
                    <separator />
                    <menu action="menu_open_with"></menu>
                    <separator />
                    <menuitem action="delete" />
                    <separator />
                    <menuitem action="minimize" />
                    <menuitem action="close" />
                    <menuitem action="save_and_quit" />
                    <menuitem action="quit" />
                </menu>
                <menu action="menu_edit">
                    <menuitem action="copy_page" />
                    <separator />
                    <menuitem action="edit_archive" />
                    <menuitem action="comments" />
                    <separator />
                    <menuitem action="preferences" />
                </menu>
                <menu action="menu_view">
                    <menuitem action="fullscreen" />
                    <menuitem action="double_page" />
                    <menuitem action="manga_mode" />
                    <separator />
                    <menuitem action="best_fit_mode" />
                    <menuitem action="fit_width_mode" />
                    <menuitem action="fit_height_mode" />
                    <menuitem action="fit_size_mode" />
                    <menuitem action="fit_manual_mode" />
                    <separator />
                    <menuitem action="slideshow" />
                    <separator />
                    <menuitem action="stretch" />
                    <menuitem action="invert_scroll" />
                    <menuitem action="lens" />
                    <menu action="menu_zoom">
                        <menuitem action="zoom_in" />
                        <menuitem action="zoom_out" />
                        <menuitem action="zoom_original" />
                    </menu>
                    <separator />
                    <menu action="menu_toolbars">
                        <menuitem action="menubar" />
                        <menuitem action="toolbar" />
                        <menuitem action="statusbar" />
                        <menuitem action="scrollbar" />
                        <menuitem action="thumbnails" />
                        <separator />
                        <menuitem action="hide_all" />
                    </menu>
                </menu>
                <menu action="menu_go">
                    <menuitem action="next_page" />
                    <menuitem action="previous_page" />
                    <menuitem action="go_to" />
                    <menuitem action="first_page" />
                    <menuitem action="last_page" />
                    <separator />
                    <menuitem action="next_archive" />
                    <menuitem action="previous_archive" />
                    <separator />
                    <menuitem action="next_directory" />
                    <menuitem action="previous_directory" />
                </menu>
                <menu action="menu_bookmarks">
                </menu>
                <menu action="menu_tools">
                    <menuitem action="enhance_image" />
                    <menu action="menu_transform">
                        <menuitem action="rotate_90" />
                        <menuitem action="rotate_270" />
                        <menuitem action="rotate_180" />
                        <separator />
                        <menu action="menu_autorotate">
                            <menuitem action="no_autorotation" />
                            <separator />
                            <menuitem action="menu_autorotate_height" />
                            <separator />
                            <menuitem action="rotate_90_height" />
                            <menuitem action="rotate_270_height" />
                            <separator />
                            <menuitem action="menu_autorotate_width" />
                            <separator />
                            <menuitem action="rotate_90_width" />
                            <menuitem action="rotate_270_width" />
                        </menu>
                        <separator />
                        <menuitem action="flip_horiz" />
                        <menuitem action="flip_vert" />
                        <separator />
                        <menuitem action="keep_transformation" />
                    </menu>
                </menu>
                <menu action="menu_help">
                    <menuitem action="about" />
                </menu>
            </menubar>

            <popup name="Popup">
                <menu action="menu_go_popup">
                    <menuitem action="next_page" />
                    <menuitem action="previous_page" />
                    <menuitem action="go_to" />
                    <menuitem action="first_page" />
                    <menuitem action="last_page" />
                    <separator />
                    <menuitem action="next_archive" />
                    <menuitem action="previous_archive" />
                    <separator />
                    <menuitem action="next_directory" />
                    <menuitem action="previous_directory" />
                </menu>
                <menu action="menu_view_popup">
                    <menuitem action="fullscreen" />
                    <menuitem action="double_page" />
                    <menuitem action="manga_mode" />
                    <separator />
                    <menuitem action="best_fit_mode" />
                    <menuitem action="fit_width_mode" />
                    <menuitem action="fit_height_mode" />
                    <menuitem action="fit_size_mode" />
                    <menuitem action="fit_manual_mode" />
                    <separator />
                    <menuitem action="slideshow" />
                    <separator />
                    <menuitem action="enhance_image" />
                    <separator />
                    <menuitem action="stretch" />
                    <menuitem action="invert_scroll" />
                    <menuitem action="lens" />
                    <menu action="menu_zoom">
                        <menuitem action="zoom_in" />
                        <menuitem action="zoom_out" />
                        <menuitem action="zoom_original" />
                    </menu>
                    <separator />
                    <menu action="menu_toolbars">
                        <menuitem action="menubar" />
                        <menuitem action="toolbar" />
                        <menuitem action="statusbar" />
                        <menuitem action="scrollbar" />
                        <menuitem action="thumbnails" />
                        <separator />
                        <menuitem action="hide_all" />
                    </menu>
                </menu>
                <menu action="menu_bookmarks_popup">
                </menu>
                <separator />
                <menuitem action="open" />
                <menu action="menu_recent" />
                <menuitem action="library" />
                <separator />
                <menu action="menu_open_with_popup"></menu>
                <separator />
                <menuitem action="preferences" />
                <separator />
                <menuitem action="close" />
                <menuitem action="quit" />
            </popup>
        </ui>
        """

        self.add_ui_from_string(ui_description)
        self.insert_action_group(self._actiongroup, 0)

        self.bookmarks = bookmark_menu.BookmarksMenu(self, window)
        self.get_widget('/Menu/menu_bookmarks').set_submenu(self.bookmarks)
        self.get_widget('/Menu/menu_bookmarks').show()

        self.bookmarks_popup = bookmark_menu.BookmarksMenu(self, window)
        self.get_widget('/Popup/menu_bookmarks_popup').set_submenu(
            self.bookmarks_popup)
        self.get_widget('/Popup/menu_bookmarks_popup').show()

        self.recent = recent.RecentFilesMenu(self, window)
        self.get_widget('/Menu/menu_file/menu_recent').set_submenu(self.recent)
        self.get_widget('/Menu/menu_file/menu_recent').show()

        self.recentPopup = recent.RecentFilesMenu(self, window)
        self.get_widget('/Popup/menu_recent').set_submenu(self.recentPopup)
        self.get_widget('/Popup/menu_recent').show()

        openwith = openwith_menu.OpenWithMenu(self, window)
        self.get_widget('/Menu/menu_file/menu_open_with').set_submenu(openwith)
        self.get_widget('/Menu/menu_file/menu_open_with').show()
        openwith = openwith_menu.OpenWithMenu(self, window)
        self.get_widget('/Popup/menu_open_with_popup').set_submenu(openwith)
        self.get_widget('/Popup/menu_open_with_popup').show()

        window.add_accel_group(self.get_accel_group())

        # Is there no built-in way to do this?
        self.get_widget('/Tool/expander').set_expand(True)
        self.get_widget('/Tool/expander').set_sensitive(False)
Exemplo n.º 26
0
 def _set_action_keypress(self, name, accel_string):
     keyval, modmask = gtk.accelerator_parse(accel_string)
     gtk.accel_map_change_entry(self._create_accel_path(name), keyval,
                                modmask, True)
Exemplo n.º 27
0
 def set_accel_keymap(self):
     if self.__keyval:
         gtk.accel_map_change_entry(self.accel_path, self.__keyval,
                                    self.__modmask, True)
Exemplo n.º 28
0
    def __init__(self, window):
        super(MainUI, self).__init__()

        self._window = window
        self._tooltipstatus = status.TooltipStatusHelper(self, window.statusbar)

        def _action_lambda(fn, *args):
            return lambda *_: fn(*args)

        # ----------------------------------------------------------------
        # Create actions for the menus.
        # ----------------------------------------------------------------
        self._actiongroup = gtk.ActionGroup('mcomix-main')
        self._actiongroup.add_actions([
            ('copy_page', gtk.STOCK_COPY, _('_Copy'),
                None, _('Copies the current page to clipboard.'),
                window.clipboard.copy_page),
            ('delete', gtk.STOCK_DELETE, _('_Delete'),
                None, _('Deletes the current file or archive from disk.'),
                window.delete),
            ('next_page', gtk.STOCK_GO_FORWARD, _('_Next page'),
             None, _('Next page'), _action_lambda(window.flip_page, +1)),
            ('previous_page', gtk.STOCK_GO_BACK, _('_Previous page'),
             None, _('Previous page'), _action_lambda(window.flip_page, -1)),
            ('first_page', gtk.STOCK_GOTO_FIRST, _('_First page'),
             None, _('First page'), _action_lambda(window.first_page)),
            ('last_page', gtk.STOCK_GOTO_LAST, _('_Last page'),
             None, _('Last page'), _action_lambda(window.last_page)),
            ('go_to', gtk.STOCK_JUMP_TO, _('_Go to page...'),
                None, _('Go to page...'), window.page_select),
            ('refresh_archive', gtk.STOCK_REFRESH, _('Re_fresh'),
                None, _('Reloads the currently opened files or archive.'),
                window.filehandler.refresh_file),
            ('next_archive', gtk.STOCK_MEDIA_NEXT, _('Next _archive'),
                None, _('Next archive'), window.filehandler._open_next_archive),
            ('previous_archive', gtk.STOCK_MEDIA_PREVIOUS, _('Previous a_rchive'),
                None, _('Previous archive'), window.filehandler._open_previous_archive),
            ('next_directory', gtk.STOCK_REDO, _('Next directory'),
                None, _('Next directory'), window.filehandler.open_next_directory),
            ('previous_directory', gtk.STOCK_UNDO, _('Previous directory'),
                None, _('Previous directory'), window.filehandler.open_previous_directory),
            ('zoom_in', gtk.STOCK_ZOOM_IN, _('Zoom _In'),
                None, None, window.manual_zoom_in),
            ('zoom_out', gtk.STOCK_ZOOM_OUT, _('Zoom _Out'),
                None, None, window.manual_zoom_out),
            ('zoom_original', gtk.STOCK_ZOOM_100, _('_Normal Size'),
                None, None, window.manual_zoom_original),
            ('minimize', gtk.STOCK_LEAVE_FULLSCREEN, _('Mi_nimize'),
                None, None, window.minimize),
            ('close', gtk.STOCK_CLOSE, _('_Close'),
                None, _('Closes all opened files.'), _action_lambda(window.filehandler.close_file)),
            ('quit', gtk.STOCK_QUIT, _('_Quit'),
                None, None, window.close_program),
            ('save_and_quit', gtk.STOCK_QUIT, _('_Save and quit'),
                None, _('Quits and restores the currently opened file next time the program starts.'),
                window.save_and_terminate_program),
            ('rotate_90', 'mcomix-rotate-90', _('_Rotate 90 degrees CW'),
                None, None, window.rotate_90),
            ('rotate_180','mcomix-rotate-180', _('Rotate 180 de_grees'),
                None, None, window.rotate_180),
            ('rotate_270', 'mcomix-rotate-270', _('Rotat_e 90 degrees CCW'),
                None, None, window.rotate_270),
            ('flip_horiz', 'mcomix-flip-horizontal', _('Fli_p horizontally'),
                None, None, window.flip_horizontally),
            ('flip_vert', 'mcomix-flip-vertical', _('Flip _vertically'),
                None, None, window.flip_vertically),
            ('extract_page', gtk.STOCK_SAVE_AS, _('Save _As'),
                None, None, window.extract_page),
            ('menu_zoom', 'mcomix-zoom', _('_Zoom')),
            ('menu_recent', gtk.STOCK_DND_MULTIPLE, _('_Recent')),
            ('menu_bookmarks_popup', 'comix-add-bookmark', _('_Bookmarks')),
            ('menu_bookmarks', None, _('_Bookmarks')),
            ('menu_toolbars', None, _('T_oolbars')),
            ('menu_edit', None, _('_Edit')),
            ('menu_open_with', gtk.STOCK_OPEN, _('Open _with'), ''),
            ('menu_open_with_popup', gtk.STOCK_OPEN, _('Open _with'), ''),
            ('menu_file', None, _('_File')),
            ('menu_view', None, _('_View')),
            ('menu_view_popup', 'comix-image', _('_View')),
            ('menu_go', None, _('_Go')),
            ('menu_go_popup', gtk.STOCK_GO_FORWARD, _('_Go')),
            ('menu_tools', None, _('_Tools')),
            ('menu_help', None, _('_Help')),
            ('menu_transform', 'mcomix-transform', _('_Transform image')),
            ('menu_autorotate', None, _('_Auto-rotate image')),
            ('menu_autorotate_width', None, _('...when width exceeds height')),
            ('menu_autorotate_height', None, _('...when height exceeds width')),
            ('expander', None, None, None, None, None)])

        self._actiongroup.add_toggle_actions([
            ('fullscreen', gtk.STOCK_FULLSCREEN, _('_Fullscreen'),
                None, _('Fullscreen mode'), window.change_fullscreen),
            ('double_page', 'mcomix-double-page', _('_Double page mode'),
                None, _('Double page mode'), window.change_double_page),
            ('toolbar', None, _('_Toolbar'),
                None, None, window.change_toolbar_visibility),
            ('menubar', None, _('_Menubar'),
                None, None, window.change_menubar_visibility),
            ('statusbar', None, _('St_atusbar'),
                None, None, window.change_statusbar_visibility),
            ('scrollbar', None, _('S_crollbars'),
                None, None, window.change_scrollbar_visibility),
            ('thumbnails', None, _('Th_umbnails'),
                None, None, window.change_thumbnails_visibility),
            ('hide_all', None, _('H_ide all'),
                None, None, window.change_hide_all),
            ('manga_mode', 'mcomix-manga', _('_Manga mode'),
                None, _('Manga mode'), window.change_manga_mode),
            ('invert_scroll', gtk.STOCK_UNDO, _('Invert smart scroll'),
                None, _('Invert smart scrolling direction.'), window.change_invert_scroll),
            ('keep_transformation', None, _('_Keep transformation'),
                None, _('Keeps the currently selected transformation for the next pages.'),
                window.change_keep_transformation),
            ('slideshow', gtk.STOCK_MEDIA_PLAY, _('Start _slideshow'),
                None, _('Start slideshow'), window.slideshow.toggle),
            ('lens', 'mcomix-lens', _('Magnifying _lens'),
                None, _('Magnifying lens'), window.lens.toggle),
            ('stretch', None, _('Stretch small images'),
                None, _('Stretch images to fit to the screen, depending on zoom mode.'),
                window.change_stretch)])

        # Note: Don't change the default value for the radio buttons unless
        # also fixing the code for setting the correct one on start-up in main.py.
        self._actiongroup.add_radio_actions([
            ('best_fit_mode', 'mcomix-fitbest', _('_Best fit mode'),
                None, _('Best fit mode'), constants.ZOOM_MODE_BEST),
            ('fit_width_mode', 'mcomix-fitwidth', _('Fit _width mode'),
                None, _('Fit width mode'), constants.ZOOM_MODE_WIDTH),
            ('fit_height_mode', 'mcomix-fitheight', _('Fit _height mode'),
                None, _('Fit height mode'), constants.ZOOM_MODE_HEIGHT),
            ('fit_size_mode', 'mcomix-fitsize', _('Fit _size mode'),
                None, _('Fit to size mode'), constants.ZOOM_MODE_SIZE),
            ('fit_manual_mode', 'mcomix-fitmanual', _('M_anual zoom mode'),
                None, _('Manual zoom mode'), constants.ZOOM_MODE_MANUAL)],
            3, window.change_zoom_mode)

        # Automatically rotate image if width>height or height>width
        self._actiongroup.add_radio_actions([
            ('no_autorotation', None, _('Never'),
             None, None, constants.AUTOROTATE_NEVER),
            ('rotate_90_width', 'mcomix-rotate-90', _('_Rotate 90 degrees CW'),
             None, None, constants.AUTOROTATE_WIDTH_90),
            ('rotate_270_width', 'mcomix-rotate-270', _('Rotat_e 90 degrees CCW'),
             None, None, constants.AUTOROTATE_WIDTH_270),
            ('rotate_90_height', 'mcomix-rotate-90', _('_Rotate 90 degrees CW'),
             None, None, constants.AUTOROTATE_HEIGHT_90),
            ('rotate_270_height', 'mcomix-rotate-270', _('Rotat_e 90 degrees CCW'),
             None, None, constants.AUTOROTATE_HEIGHT_270)],
            prefs['auto rotate depending on size'], window.change_autorotation)

        self._actiongroup.add_actions([
            ('about', gtk.STOCK_ABOUT, _('_About'),
             None, None, dialog_handler.open_dialog)], (window, 'about-dialog'))

        self._actiongroup.add_actions([
            ('comments', 'mcomix-comments', _('Co_mments...'),
             None, None, dialog_handler.open_dialog)], (window, 'comments-dialog'))

        self._actiongroup.add_actions([
            ('properties', gtk.STOCK_PROPERTIES, _('Proper_ties'),
            None, None, dialog_handler.open_dialog)], (window,'properties-dialog'))

        self._actiongroup.add_actions([
            ('preferences', gtk.STOCK_PREFERENCES, _('Pr_eferences'),
                None, None, preferences_dialog.open_dialog)], (window))

        # Some actions added separately since they need extra arguments.
        self._actiongroup.add_actions([
            ('edit_archive', gtk.STOCK_EDIT, _('_Edit archive...'),
                None, _('Opens the archive editor.'),
                edit_dialog.open_dialog),
            ('open', gtk.STOCK_OPEN, _('_Open...'),
                None, None, file_chooser_main_dialog.open_main_filechooser_dialog),
            ('enhance_image', 'mcomix-enhance-image', _('En_hance image...'),
                None, None, enhance_dialog.open_dialog)], window)

        self._actiongroup.add_actions([
            ('library', 'mcomix-library', _('_Library...'),
                None, None, library_main_dialog.open_dialog)], window)

        # fix some gtk magic: removing unreqired accelerators
        gtk.accel_map_change_entry('<Actions>/mcomix-main/%s' % 'close', 0, 0, True)

        ui_description = """
        <ui>
            <toolbar name="Tool">
                <toolitem action="previous_archive" />
                <toolitem action="first_page" />
                <toolitem action="previous_page" />
                <toolitem action="go_to" />
                <toolitem action="next_page" />
                <toolitem action="last_page" />
                <toolitem action="next_archive" />
                <separator />
                <toolitem action="fullscreen" />
                <toolitem action="slideshow" />
                <toolitem action="expander" />
                <toolitem action="best_fit_mode" />
                <toolitem action="fit_width_mode" />
                <toolitem action="fit_height_mode" />
                <toolitem action="fit_size_mode" />
                <toolitem action="fit_manual_mode" />
                <separator />
                <toolitem action="double_page" />
                <toolitem action="manga_mode" />
                <separator />
                <toolitem action="lens" />
            </toolbar>

            <menubar name="Menu">
                <menu action="menu_file">
                    <menuitem action="open" />
                    <menu action="menu_recent" />
                    <menuitem action="library" />
                    <separator />
                    <menuitem action="extract_page" />
                    <menuitem action="refresh_archive" />
                    <menuitem action="properties" />
                    <separator />
                    <menu action="menu_open_with"></menu>
                    <separator />
                    <menuitem action="delete" />
                    <separator />
                    <menuitem action="minimize" />
                    <menuitem action="close" />
                    <menuitem action="save_and_quit" />
                    <menuitem action="quit" />
                </menu>
                <menu action="menu_edit">
                    <menuitem action="copy_page" />
                    <separator />
                    <menuitem action="edit_archive" />
                    <menuitem action="comments" />
                    <separator />
                    <menuitem action="preferences" />
                </menu>
                <menu action="menu_view">
                    <menuitem action="fullscreen" />
                    <menuitem action="double_page" />
                    <menuitem action="manga_mode" />
                    <separator />
                    <menuitem action="best_fit_mode" />
                    <menuitem action="fit_width_mode" />
                    <menuitem action="fit_height_mode" />
                    <menuitem action="fit_size_mode" />
                    <menuitem action="fit_manual_mode" />
                    <separator />
                    <menuitem action="slideshow" />
                    <separator />
                    <menuitem action="stretch" />
                    <menuitem action="invert_scroll" />
                    <menuitem action="lens" />
                    <menu action="menu_zoom">
                        <menuitem action="zoom_in" />
                        <menuitem action="zoom_out" />
                        <menuitem action="zoom_original" />
                    </menu>
                    <separator />
                    <menu action="menu_toolbars">
                        <menuitem action="menubar" />
                        <menuitem action="toolbar" />
                        <menuitem action="statusbar" />
                        <menuitem action="scrollbar" />
                        <menuitem action="thumbnails" />
                        <separator />
                        <menuitem action="hide_all" />
                    </menu>
                </menu>
                <menu action="menu_go">
                    <menuitem action="next_page" />
                    <menuitem action="previous_page" />
                    <menuitem action="go_to" />
                    <menuitem action="first_page" />
                    <menuitem action="last_page" />
                    <separator />
                    <menuitem action="next_archive" />
                    <menuitem action="previous_archive" />
                    <separator />
                    <menuitem action="next_directory" />
                    <menuitem action="previous_directory" />
                </menu>
                <menu action="menu_bookmarks">
                </menu>
                <menu action="menu_tools">
                    <menuitem action="enhance_image" />
                    <menu action="menu_transform">
                        <menuitem action="rotate_90" />
                        <menuitem action="rotate_270" />
                        <menuitem action="rotate_180" />
                        <separator />
                        <menu action="menu_autorotate">
                            <menuitem action="no_autorotation" />
                            <separator />
                            <menuitem action="menu_autorotate_height" />
                            <separator />
                            <menuitem action="rotate_90_height" />
                            <menuitem action="rotate_270_height" />
                            <separator />
                            <menuitem action="menu_autorotate_width" />
                            <separator />
                            <menuitem action="rotate_90_width" />
                            <menuitem action="rotate_270_width" />
                        </menu>
                        <separator />
                        <menuitem action="flip_horiz" />
                        <menuitem action="flip_vert" />
                        <separator />
                        <menuitem action="keep_transformation" />
                    </menu>
                </menu>
                <menu action="menu_help">
                    <menuitem action="about" />
                </menu>
            </menubar>

            <popup name="Popup">
                <menu action="menu_go_popup">
                    <menuitem action="next_page" />
                    <menuitem action="previous_page" />
                    <menuitem action="go_to" />
                    <menuitem action="first_page" />
                    <menuitem action="last_page" />
                    <separator />
                    <menuitem action="next_archive" />
                    <menuitem action="previous_archive" />
                    <separator />
                    <menuitem action="next_directory" />
                    <menuitem action="previous_directory" />
                </menu>
                <menu action="menu_view_popup">
                    <menuitem action="fullscreen" />
                    <menuitem action="double_page" />
                    <menuitem action="manga_mode" />
                    <separator />
                    <menuitem action="best_fit_mode" />
                    <menuitem action="fit_width_mode" />
                    <menuitem action="fit_height_mode" />
                    <menuitem action="fit_size_mode" />
                    <menuitem action="fit_manual_mode" />
                    <separator />
                    <menuitem action="slideshow" />
                    <separator />
                    <menuitem action="enhance_image" />
                    <separator />
                    <menuitem action="stretch" />
                    <menuitem action="invert_scroll" />
                    <menuitem action="lens" />
                    <menu action="menu_zoom">
                        <menuitem action="zoom_in" />
                        <menuitem action="zoom_out" />
                        <menuitem action="zoom_original" />
                    </menu>
                    <separator />
                    <menu action="menu_toolbars">
                        <menuitem action="menubar" />
                        <menuitem action="toolbar" />
                        <menuitem action="statusbar" />
                        <menuitem action="scrollbar" />
                        <menuitem action="thumbnails" />
                        <separator />
                        <menuitem action="hide_all" />
                    </menu>
                </menu>
                <menu action="menu_bookmarks_popup">
                </menu>
                <separator />
                <menuitem action="open" />
                <menu action="menu_recent" />
                <menuitem action="library" />
                <separator />
                <menu action="menu_open_with_popup"></menu>
                <separator />
                <menuitem action="preferences" />
                <separator />
                <menuitem action="close" />
                <menuitem action="quit" />
            </popup>
        </ui>
        """

        self.add_ui_from_string(ui_description)
        self.insert_action_group(self._actiongroup, 0)

        self.bookmarks = bookmark_menu.BookmarksMenu(self, window)
        self.get_widget('/Menu/menu_bookmarks').set_submenu(self.bookmarks)
        self.get_widget('/Menu/menu_bookmarks').show()

        self.bookmarks_popup = bookmark_menu.BookmarksMenu(self, window)
        self.get_widget('/Popup/menu_bookmarks_popup').set_submenu(self.bookmarks_popup)
        self.get_widget('/Popup/menu_bookmarks_popup').show()

        self.recent = recent.RecentFilesMenu(self, window)
        self.get_widget('/Menu/menu_file/menu_recent').set_submenu(self.recent)
        self.get_widget('/Menu/menu_file/menu_recent').show()

        self.recentPopup = recent.RecentFilesMenu(self, window)
        self.get_widget('/Popup/menu_recent').set_submenu(self.recentPopup)
        self.get_widget('/Popup/menu_recent').show()

        openwith = openwith_menu.OpenWithMenu(self, window)
        self.get_widget('/Menu/menu_file/menu_open_with').set_submenu(openwith)
        self.get_widget('/Menu/menu_file/menu_open_with').show()
        openwith = openwith_menu.OpenWithMenu(self, window)
        self.get_widget('/Popup/menu_open_with_popup').set_submenu(openwith)
        self.get_widget('/Popup/menu_open_with_popup').show()

        window.add_accel_group(self.get_accel_group())

        # Is there no built-in way to do this?
        self.get_widget('/Tool/expander').set_expand(True)
        self.get_widget('/Tool/expander').set_sensitive(False)
Exemplo n.º 29
0
 def cmd_disable_document_accelerators(self):
     for act in self.__file_fallback.action_group.list_actions():
         gtk.accel_map_change_entry(act.accel_path, 0, 0, True)
Exemplo n.º 30
0
 def cmd_disable_document_accelerators(self):
     for act in self.__file_fallback.action_group.list_actions():
         gtk.accel_map_change_entry(act.accel_path, 0, 0, True)
Exemplo n.º 31
0
    def __init__(self, no_dialog=False):
        self.settings = EventCore()
        self.gui_is_active = False
        # during initialization any dialog (e.g. "Unit change") is not allowed
        # we set the final value later
        self.no_dialog = True
        self._batch_queue = []
        self._undo_states = []
        self.gui = gtk.Builder()
        gtk_build_file = get_ui_file_location(GTKBUILD_FILE)
        if gtk_build_file is None:
            gtk.main_quit()
        self.gui.add_from_file(gtk_build_file)
        if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
            gtkrc_file = get_ui_file_location(GTKRC_FILE_WINDOWS)
            if gtkrc_file:
                gtk.rc_add_default_file(gtkrc_file)
                gtk.rc_reparse_all_for_settings(gtk.settings_get_default(),
                                                True)
        self.window = self.gui.get_object("ProjectWindow")
        self.settings.set("main_window", self.window)
        # show stock items on buttons
        # increase the initial width of the window (due to hidden elements)
        self.window.set_default_size(400, -1)
        # initialize the RecentManager (TODO: check for Windows)
        if False and pycam.Utils.get_platform(
        ) == pycam.Utils.PLATFORM_WINDOWS:
            # The pyinstaller binary for Windows fails mysteriously when trying
            # to display the stock item.
            # Error message: Gtk:ERROR:gtkrecentmanager.c:1942:get_icon_fallback: assertion failed: (retval != NULL)
            self.recent_manager = None
        else:
            try:
                self.recent_manager = gtk.recent_manager_get_default()
            except AttributeError:
                # GTK 2.12.1 seems to have problems with "RecentManager" on
                # Windows. Sadly this is the version, that is shipped with the
                # "appunti" GTK packages for Windows (April 2010).
                # see http://www.daa.com.au/pipermail/pygtk/2009-May/017052.html
                self.recent_manager = None
        # file loading
        self.last_dirname = None
        self.last_task_settings_uri = None
        self.last_model_uri = None
        # define callbacks and accelerator keys for the menu actions
        for objname, callback, data, accel_key in (
            ("LoadTaskSettings", self.load_task_settings_file, None,
             "<Control>t"), ("SaveTaskSettings", self.save_task_settings_file,
                             lambda: self.last_task_settings_uri, None),
            ("SaveAsTaskSettings", self.save_task_settings_file, None,
             None), ("OpenModel", self.load_model_file, None,
                     "<Control>o"), ("Quit", self.destroy, None, "<Control>q"),
            ("GeneralSettings", self.toggle_preferences_window, None,
             "<Control>p"), ("UndoButton", self._restore_undo_state, None,
                             "<Control>z"), ("HelpUserManual", self.show_help,
                                             "User_Manual", "F1"),
            ("HelpIntroduction", self.show_help, "Introduction", None),
            ("HelpSupportedFormats", self.show_help, "SupportedFormats",
             None), ("HelpModelTransformations", self.show_help,
                     "ModelTransformations",
                     None), ("HelpToolTypes", self.show_help, "ToolTypes",
                             None), ("HelpProcessSettings", self.show_help,
                                     "ProcessSettings", None),
            ("HelpBoundsSettings", self.show_help, "BoundsSettings",
             None), ("HelpTaskSetup", self.show_help, "TaskSetup", None),
            ("HelpGCodeExport", self.show_help, "GCodeExport",
             None), ("HelpTouchOff", self.show_help, "TouchOff",
                     None), ("HelpSimulation", self.show_help, "Simulation",
                             None), ("Help3DView", self.show_help, "3D_View",
                                     None), ("HelpServerMode", self.show_help,
                                             "ServerMode", None),
            ("HelpCommandLine", self.show_help, "CommandlineExamples",
             None), ("HelpHotkeys", self.show_help, "KeyboardShortcuts",
                     None), ("ProjectWebsite", self.show_help,
                             "http://pycam.sourceforge.net",
                             None), ("DevelopmentBlog", self.show_help,
                                     "http://fab.senselab.org/pycam", None),
            ("Forum", self.show_help,
             "http://sourceforge.net/projects/pycam/forums", None),
            ("BugTracker", self.show_help,
             "http://sourceforge.net/tracker/?group_id=237831&atid=1104176",
             None),
            ("FeatureRequest", self.show_help,
             "http://sourceforge.net/tracker/?group_id=237831&atid=1104179",
             None)):
            item = self.gui.get_object(objname)
            action = "activate"
            if data is None:
                item.connect(action, callback)
            else:
                item.connect(action, callback, data)
            if accel_key:
                key, mod = gtk.accelerator_parse(accel_key)
                accel_path = "<pycam>/%s" % objname
                item.set_accel_path(accel_path)
                gtk.accel_map_change_entry(accel_path, key, mod, True)
        # LinkButton does not work on Windows: https://bugzilla.gnome.org/show_bug.cgi?id=617874
        if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:

            def open_url(widget, data=None):
                webbrowser.open(widget.get_uri())

            gtk.link_button_set_uri_hook(open_url)
        # no undo is allowed at the beginning
        self.gui.get_object("UndoButton").set_sensitive(False)
        self.settings.register_event("model-change-before",
                                     self._store_undo_state)
        self.settings.register_event(
            "model-change-after",
            lambda: self.settings.emit_event("visual-item-updated"))
        # set the availability of ODE
        self.enable_ode_control = self.gui.get_object("SettingEnableODE")
        self.settings.add_item("enable_ode",
                               self.enable_ode_control.get_active,
                               self.enable_ode_control.set_active)
        self.settings.register_event("parallel-processing-changed",
                                     self.update_ode_settings)
        # configure drag-n-drop for config files and models
        self.settings.set("configure-drag-drop-func",
                          self.configure_drag_and_drop)
        self.settings.get("configure-drag-drop-func")(self.window)
        # other events
        self.window.connect("destroy", self.destroy)
        self.window.connect("delete-event", self.destroy)
        # the settings window
        self.gui.get_object("CloseSettingsWindow").connect(
            "clicked", self.toggle_preferences_window, False)
        self.gui.get_object("ResetPreferencesButton").connect(
            "clicked", self.reset_preferences)
        self.preferences_window = self.gui.get_object("GeneralSettingsWindow")
        self.preferences_window.connect("delete-event",
                                        self.toggle_preferences_window, False)
        self._preferences_window_position = None
        self._preferences_window_visible = False
        # "about" window
        self.about_window = self.gui.get_object("AboutWindow")
        self.about_window.set_version(VERSION)
        self.gui.get_object("About").connect("activate",
                                             self.toggle_about_window, True)
        # we assume, that the last child of the window is the "close" button
        # TODO: fix this ugly hack!
        self.gui.get_object("AboutWindowButtons").get_children()[-1].connect(
            "clicked", self.toggle_about_window, False)
        self.about_window.connect("delete-event", self.toggle_about_window,
                                  False)
        # menu bar
        uimanager = gtk.UIManager()
        self.settings.set("gtk-uimanager", uimanager)
        self._accel_group = uimanager.get_accel_group()

        # send a "delete" event on "CTRL-w" for every window
        def handle_window_close(accel_group, window, *args):
            window.emit("delete-event", gtk.gdk.Event(gtk.gdk.DELETE))

        self._accel_group.connect_group(ord('w'), gtk.gdk.CONTROL_MASK,
                                        gtk.ACCEL_LOCKED, handle_window_close)
        self.settings.add_item("gtk-accel-group", lambda: self._accel_group)
        for obj in self.gui.get_objects():
            if isinstance(obj, gtk.Window):
                obj.add_accel_group(self._accel_group)
        # preferences tab
        preferences_book = self.gui.get_object("PreferencesNotebook")

        def clear_preferences():
            for child in preferences_book.get_children():
                preferences_book.remove(child)

        def add_preferences_item(item, name):
            preferences_book.append_page(item, gtk.Label(name))

        self.settings.register_ui_section("preferences", add_preferences_item,
                                          clear_preferences)
        for obj_name, label, priority in (("GeneralSettingsPrefTab", "General",
                                           -50), ("ProgramsPrefTab",
                                                  "Programs", 50)):
            obj = self.gui.get_object(obj_name)
            obj.unparent()
            self.settings.register_ui("preferences", label, obj, priority)
        # general preferences
        general_prefs = self.gui.get_object("GeneralPreferencesBox")

        def clear_general_prefs():
            for item in general_prefs.get_children():
                general_prefs.remove(item)

        def add_general_prefs_item(item, name):
            general_prefs.pack_start(item, expand=False, padding=3)

        self.settings.register_ui_section("preferences_general",
                                          add_general_prefs_item,
                                          clear_general_prefs)
        for obj_name, priority in (("SettingEnableODE", 10),
                                   ("TaskSettingsDefaultFileBox", 30)):
            obj = self.gui.get_object(obj_name)
            obj.unparent()
            self.settings.register_ui("preferences_general", None, obj,
                                      priority)
        # set defaults
        self.cutter = None
        # add some dummies - to be implemented later ...
        self.settings.add_item("cutter", lambda: self.cutter)
        main_tab = self.gui.get_object("MainTabs")

        def clear_main_tab():
            while main_tab.get_n_pages() > 0:
                main_tab.remove_page(0)

        def add_main_tab_item(item, name):
            main_tab.append_page(item, gtk.Label(name))

        # TODO: move these to plugins, as well
        self.settings.register_ui_section("main", add_main_tab_item,
                                          clear_main_tab)
        main_window = self.gui.get_object("WindowBox")

        def clear_main_window():
            main_window.foreach(lambda x: main_window.remove(x))

        def add_main_window_item(item, name, **extra_args):
            # some widgets may want to override the defaults
            args = {"expand": False, "fill": False}
            args.update(extra_args)
            main_window.pack_start(item, **args)

        main_tab.unparent()
        self.settings.register_ui_section("main_window", add_main_window_item,
                                          clear_main_window)
        self.settings.register_ui("main_window",
                                  "Tabs",
                                  main_tab,
                                  -20,
                                  args_dict={
                                      "expand": True,
                                      "fill": True
                                  })
        # autoload task settings file on startup
        autoload_enable = self.gui.get_object("AutoLoadTaskFile")
        autoload_box = self.gui.get_object("StartupTaskFileBox")
        autoload_source = self.gui.get_object("StartupTaskFile")

        # TODO: fix the extension filter
        #for one_filter in get_filters_from_list(FILTER_CONFIG):
        #    autoload_source.add_filter(one_filter)
        #    autoload_source.set_filter(one_filter)
        def get_autoload_task_file(autoload_source=autoload_source):
            if autoload_enable.get_active():
                return autoload_source.get_filename()
            else:
                return ""

        def set_autoload_task_file(filename):
            if filename:
                autoload_enable.set_active(True)
                autoload_box.show()
                autoload_source.set_filename(filename)
            else:
                autoload_enable.set_active(False)
                autoload_box.hide()
                autoload_source.unselect_all()

        def autoload_enable_switched(widget, box):
            if not widget.get_active():
                set_autoload_task_file(None)
            else:
                autoload_box.show()

        autoload_enable.connect("toggled", autoload_enable_switched,
                                autoload_box)
        self.settings.add_item("default_task_settings_file",
                               get_autoload_task_file, set_autoload_task_file)

        def disable_gui():
            self.menubar.set_sensitive(False)
            main_tab.set_sensitive(False)

        def enable_gui():
            self.menubar.set_sensitive(True)
            main_tab.set_sensitive(True)

        self.settings.register_event("gui-disable", disable_gui)
        self.settings.register_event("gui-enable", enable_gui)
        # configure locations of external programs
        for auto_control_name, location_control_name, browse_button, key in (
            ("ExternalProgramInkscapeAuto", "ExternalProgramInkscapeControl",
             "ExternalProgramInkscapeBrowse", "inkscape"),
            ("ExternalProgramPstoeditAuto", "ExternalProgramPstoeditControl",
             "ExternalProgramPstoeditBrowse", "pstoedit")):
            self.gui.get_object(auto_control_name).connect(
                "clicked", self._locate_external_program, key)
            location_control = self.gui.get_object(location_control_name)
            self.settings.add_item("external_program_%s" % key,
                                   location_control.get_text,
                                   location_control.set_text)
            self.gui.get_object(browse_button).connect(
                "clicked", self._browse_external_program_location, key)
        # set the icons (in different sizes) for all windows
        gtk.window_set_default_icon_list(*get_icons_pixbuffers())
        # load menu data
        gtk_menu_file = get_ui_file_location(GTKMENU_FILE)
        if gtk_menu_file is None:
            gtk.main_quit()
        uimanager.add_ui_from_file(gtk_menu_file)
        # make the actions defined in the GTKBUILD file available in the menu
        actiongroup = gtk.ActionGroup("menubar")
        for action in [
                action for action in self.gui.get_objects()
                if isinstance(action, gtk.Action)
        ]:
            actiongroup.add_action(action)
        # the "pos" parameter is optional since 2.12 - we can remove it later
        uimanager.insert_action_group(actiongroup, pos=-1)
        # the "recent files" sub-menu
        if not self.recent_manager is None:
            recent_files_menu = gtk.RecentChooserMenu(self.recent_manager)
            recent_files_menu.set_name("RecentFilesMenu")
            recent_menu_filter = gtk.RecentFilter()
            case_converter = pycam.Utils.get_case_insensitive_file_pattern
            for filter_name, patterns in FILTER_MODEL:
                if not isinstance(patterns, (list, set, tuple)):
                    patterns = [patterns]
                # convert it into a mutable list (instead of set/tuple)
                patterns = list(patterns)
                for index in range(len(patterns)):
                    patterns[index] = case_converter(patterns[index])
                for pattern in patterns:
                    recent_menu_filter.add_pattern(pattern)
            recent_files_menu.add_filter(recent_menu_filter)
            recent_files_menu.set_show_numbers(True)
            # non-local files (without "file://") are not supported. yet
            recent_files_menu.set_local_only(False)
            # most recent files to the top
            recent_files_menu.set_sort_type(gtk.RECENT_SORT_MRU)
            # show only ten files
            recent_files_menu.set_limit(10)
            uimanager.get_widget("/MenuBar/FileMenu/OpenRecentModelMenu")\
                    .set_submenu(recent_files_menu)
            recent_files_menu.connect("item-activated",
                                      self.load_recent_model_file)
        else:
            self.gui.get_object("OpenRecentModel").set_visible(False)
        # load the menubar and connect functions to its items
        self.menubar = uimanager.get_widget("/MenuBar")
        # dict of all merge-ids
        menu_merges = {}

        def clear_menu(menu_key):
            for merge in menu_merges.get(menu_key, []):
                uimanager.remove_ui(merge)

        def append_menu_item(menu_key, base_path, widget, name):
            merge_id = uimanager.new_merge_id()
            if widget:
                action_group = widget.props.action_group
                if not action_group in uimanager.get_action_groups():
                    uimanager.insert_action_group(action_group, -1)
                widget_name = widget.get_name()
                item_type = gtk.UI_MANAGER_MENUITEM
            else:
                widget_name = name
                item_type = gtk.UI_MANAGER_SEPARATOR
            uimanager.add_ui(merge_id, base_path, name, widget_name, item_type,
                             False)
            if not menu_key in menu_merges:
                menu_merges[menu_key] = []
            menu_merges[menu_key].append(merge_id)

        def get_menu_funcs(menu_key, base_path):
            append_func = lambda widget, name: \
                    append_menu_item(menu_key, base_path, widget, name)
            clear_func = lambda: clear_menu(menu_key)
            return append_func, clear_func

        for ui_name, base_path in (("view_menu", "/MenuBar/ViewMenu"),
                                   ("file_menu", "/MenuBar/FileMenu"),
                                   ("edit_menu", "/MenuBar/EditMenu"),
                                   ("export_menu",
                                    "/MenuBar/FileMenu/ExportMenu")):
            append_func, clear_func = get_menu_funcs(ui_name, base_path)
            self.settings.register_ui_section(ui_name, append_func, clear_func)
        self.settings.register_ui("file_menu", "Quit",
                                  self.gui.get_object("Quit"), 100)
        self.settings.register_ui("file_menu", "QuitSeparator", None, 95)
        self.settings.register_ui("main_window", "Main", self.menubar, -100)
        # initialize plugins
        self.plugin_manager = pycam.Plugins.PluginManager(core=self.settings)
        self.plugin_manager.import_plugins()
        # some more initialization
        self.reset_preferences()
        # TODO: preferences are not loaded until the new format is stable
        #self.load_preferences()
        #self.load_task_settings()
        self.settings.register_event("notify-file-saved",
                                     self.add_to_recent_file_list)
        self.settings.register_event("notify-file-opened",
                                     self.add_to_recent_file_list)
        # fallback - in case of a failure when opening a model file
        model = pycam.Importers.TestModel.get_test_model()
        self.settings.get("models").add_model(model, "Tiny pyramid")
        # Without this "gkt.main_iteration" loop the task settings file
        # control would not be updated in time.
        while gtk.events_pending():
            gtk.main_iteration()
        autoload_task_filename = self.settings.get(
            "default_task_settings_file")
        if autoload_task_filename:
            self.open_task_settings_file(autoload_task_filename)
        self.update_all_controls()
        self.no_dialog = no_dialog
        if not self.no_dialog:
            # register a logging handler for displaying error messages
            pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR)
            self.window.show()
Exemplo n.º 32
0
 def __init__(self, no_dialog=False):
     self.settings = EventCore()
     self.gui_is_active = False
     # during initialization any dialog (e.g. "Unit change") is not allowed
     # we set the final value later
     self.no_dialog = True
     self._batch_queue = []
     self._undo_states = []
     self.gui = gtk.Builder()
     gtk_build_file = get_ui_file_location(GTKBUILD_FILE)
     if gtk_build_file is None:
         gtk.main_quit()
     self.gui.add_from_file(gtk_build_file)
     if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
         gtkrc_file = get_ui_file_location(GTKRC_FILE_WINDOWS)
         if gtkrc_file:
             gtk.rc_add_default_file(gtkrc_file)
             gtk.rc_reparse_all_for_settings(gtk.settings_get_default(), True)
     self.window = self.gui.get_object("ProjectWindow")
     self.settings.set("main_window", self.window)
     # show stock items on buttons
     # increase the initial width of the window (due to hidden elements)
     self.window.set_default_size(400, -1)
     # initialize the RecentManager (TODO: check for Windows)
     if False and pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
         # The pyinstaller binary for Windows fails mysteriously when trying
         # to display the stock item.
         # Error message: Gtk:ERROR:gtkrecentmanager.c:1942:get_icon_fallback: assertion failed: (retval != NULL)
         self.recent_manager = None
     else:
         try:
             self.recent_manager = gtk.recent_manager_get_default()
         except AttributeError:
             # GTK 2.12.1 seems to have problems with "RecentManager" on
             # Windows. Sadly this is the version, that is shipped with the
             # "appunti" GTK packages for Windows (April 2010).
             # see http://www.daa.com.au/pipermail/pygtk/2009-May/017052.html
             self.recent_manager = None
     # file loading
     self.last_dirname = None
     self.last_task_settings_uri = None
     self.last_model_uri = None
     # define callbacks and accelerator keys for the menu actions
     for objname, callback, data, accel_key in (
             ("LoadTaskSettings", self.load_task_settings_file, None, "<Control>t"),
             ("SaveTaskSettings", self.save_task_settings_file, lambda: self.last_task_settings_uri, None),
             ("SaveAsTaskSettings", self.save_task_settings_file, None, None),
             ("OpenModel", self.load_model_file, None, "<Control>o"),
             ("Quit", self.destroy, None, "<Control>q"),
             ("GeneralSettings", self.toggle_preferences_window, None, "<Control>p"),
             ("UndoButton", self._restore_undo_state, None, "<Control>z"),
             ("HelpUserManual", self.show_help, "User_Manual", "F1"),
             ("HelpIntroduction", self.show_help, "Introduction", None),
             ("HelpSupportedFormats", self.show_help, "SupportedFormats", None),
             ("HelpModelTransformations", self.show_help, "ModelTransformations", None),
             ("HelpToolTypes", self.show_help, "ToolTypes", None),
             ("HelpProcessSettings", self.show_help, "ProcessSettings", None),
             ("HelpBoundsSettings", self.show_help, "BoundsSettings", None),
             ("HelpTaskSetup", self.show_help, "TaskSetup", None),
             ("HelpGCodeExport", self.show_help, "GCodeExport", None),
             ("HelpTouchOff", self.show_help, "TouchOff", None),
             ("HelpSimulation", self.show_help, "Simulation", None),
             ("Help3DView", self.show_help, "3D_View", None),
             ("HelpServerMode", self.show_help, "ServerMode", None),
             ("HelpCommandLine", self.show_help, "CommandlineExamples", None),
             ("HelpHotkeys", self.show_help, "KeyboardShortcuts", None),
             ("ProjectWebsite", self.show_help, "http://pycam.sourceforge.net", None),
             ("DevelopmentBlog", self.show_help, "http://fab.senselab.org/pycam", None),
             ("Forum", self.show_help, "http://sourceforge.net/projects/pycam/forums", None),
             ("BugTracker", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104176", None),
             ("FeatureRequest", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104179", None)):
         item = self.gui.get_object(objname)
         action = "activate"
         if data is None:
             item.connect(action, callback)
         else:
             item.connect(action, callback, data)
         if accel_key:
             key, mod = gtk.accelerator_parse(accel_key)
             accel_path = "<pycam>/%s" % objname
             item.set_accel_path(accel_path)
             gtk.accel_map_change_entry(accel_path, key, mod, True)
     # LinkButton does not work on Windows: https://bugzilla.gnome.org/show_bug.cgi?id=617874
     if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
         def open_url(widget, data=None):
             webbrowser.open(widget.get_uri())
         gtk.link_button_set_uri_hook(open_url)
     # no undo is allowed at the beginning
     self.gui.get_object("UndoButton").set_sensitive(False)
     self.settings.register_event("model-change-before",
             self._store_undo_state)
     self.settings.register_event("model-change-after",
             lambda: self.settings.emit_event("visual-item-updated"))
     # set the availability of ODE
     self.enable_ode_control = self.gui.get_object("SettingEnableODE")
     self.settings.add_item("enable_ode", self.enable_ode_control.get_active,
             self.enable_ode_control.set_active)
     self.settings.register_event("parallel-processing-changed",
             self.update_ode_settings)
     # configure drag-n-drop for config files and models
     self.settings.set("configure-drag-drop-func",
             self.configure_drag_and_drop)
     self.settings.get("configure-drag-drop-func")(self.window)
     # other events
     self.window.connect("destroy", self.destroy)
     self.window.connect("delete-event", self.destroy)
     # the settings window
     self.gui.get_object("CloseSettingsWindow").connect("clicked", self.toggle_preferences_window, False)
     self.gui.get_object("ResetPreferencesButton").connect("clicked", self.reset_preferences)
     self.preferences_window = self.gui.get_object("GeneralSettingsWindow")
     self.preferences_window.connect("delete-event", self.toggle_preferences_window, False)
     self._preferences_window_position = None
     self._preferences_window_visible = False
     # "about" window
     self.about_window = self.gui.get_object("AboutWindow")
     self.about_window.set_version(VERSION)
     self.gui.get_object("About").connect("activate", self.toggle_about_window, True)
     # we assume, that the last child of the window is the "close" button
     # TODO: fix this ugly hack!
     self.gui.get_object("AboutWindowButtons").get_children()[-1].connect("clicked", self.toggle_about_window, False)
     self.about_window.connect("delete-event", self.toggle_about_window, False)
     # menu bar
     uimanager = gtk.UIManager()
     self.settings.set("gtk-uimanager", uimanager)
     self._accel_group = uimanager.get_accel_group()
     # send a "delete" event on "CTRL-w" for every window
     def handle_window_close(accel_group, window, *args):
         window.emit("delete-event", gtk.gdk.Event(gtk.gdk.DELETE))
     self._accel_group.connect_group(ord('w'), gtk.gdk.CONTROL_MASK,
             gtk.ACCEL_LOCKED, handle_window_close)
     self.settings.add_item("gtk-accel-group", lambda: self._accel_group)
     for obj in self.gui.get_objects():
         if isinstance(obj, gtk.Window):
             obj.add_accel_group(self._accel_group)
     # preferences tab
     preferences_book = self.gui.get_object("PreferencesNotebook")
     def clear_preferences():
         for child in preferences_book.get_children():
             preferences_book.remove(child)
     def add_preferences_item(item, name):
         preferences_book.append_page(item, gtk.Label(name))
     self.settings.register_ui_section("preferences",
             add_preferences_item, clear_preferences)
     for obj_name, label, priority in (
             ("GeneralSettingsPrefTab", "General", -50),
             ("ProgramsPrefTab", "Programs", 50)):
         obj = self.gui.get_object(obj_name)
         obj.unparent()
         self.settings.register_ui("preferences", label, obj, priority)
     # general preferences
     general_prefs = self.gui.get_object("GeneralPreferencesBox")
     def clear_general_prefs():
         for item in general_prefs.get_children():
             general_prefs.remove(item)
     def add_general_prefs_item(item, name):
         general_prefs.pack_start(item, expand=False, padding=3)
     self.settings.register_ui_section("preferences_general",
             add_general_prefs_item, clear_general_prefs)
     for obj_name, priority in (("SettingEnableODE", 10),
             ("TaskSettingsDefaultFileBox", 30)):
         obj = self.gui.get_object(obj_name)
         obj.unparent()
         self.settings.register_ui("preferences_general", None,
                 obj, priority)
     # set defaults
     self.cutter = None
     # add some dummies - to be implemented later ...
     self.settings.add_item("cutter", lambda: self.cutter)
     main_tab = self.gui.get_object("MainTabs")
     def clear_main_tab():
         while main_tab.get_n_pages() > 0:
             main_tab.remove_page(0)
     def add_main_tab_item(item, name):
         main_tab.append_page(item, gtk.Label(name))
     # TODO: move these to plugins, as well
     self.settings.register_ui_section("main", add_main_tab_item,
             clear_main_tab)
     main_window = self.gui.get_object("WindowBox")
     def clear_main_window():
         main_window.foreach(lambda x: main_window.remove(x))
     def add_main_window_item(item, name, **extra_args):
         # some widgets may want to override the defaults
         args = {"expand": False, "fill": False}
         args.update(extra_args)
         main_window.pack_start(item, **args)
     main_tab.unparent()
     self.settings.register_ui_section("main_window", add_main_window_item,
             clear_main_window)
     self.settings.register_ui("main_window", "Tabs", main_tab, -20,
             args_dict={"expand": True, "fill": True})
     # autoload task settings file on startup
     autoload_enable = self.gui.get_object("AutoLoadTaskFile")
     autoload_box = self.gui.get_object("StartupTaskFileBox")
     autoload_source = self.gui.get_object("StartupTaskFile")
     # TODO: fix the extension filter
     #for one_filter in get_filters_from_list(FILTER_CONFIG):
     #    autoload_source.add_filter(one_filter)
     #    autoload_source.set_filter(one_filter)
     def get_autoload_task_file(autoload_source=autoload_source):
         if autoload_enable.get_active():
             return autoload_source.get_filename()
         else:
             return ""
     def set_autoload_task_file(filename):
         if filename:
             autoload_enable.set_active(True)
             autoload_box.show()
             autoload_source.set_filename(filename)
         else:
             autoload_enable.set_active(False)
             autoload_box.hide()
             autoload_source.unselect_all()
     def autoload_enable_switched(widget, box):
         if not widget.get_active():
             set_autoload_task_file(None)
         else:
             autoload_box.show()
     autoload_enable.connect("toggled", autoload_enable_switched,
             autoload_box)
     self.settings.add_item("default_task_settings_file",
             get_autoload_task_file, set_autoload_task_file)
     def disable_gui():
         self.menubar.set_sensitive(False)
         main_tab.set_sensitive(False)
     def enable_gui():
         self.menubar.set_sensitive(True)
         main_tab.set_sensitive(True)
     self.settings.register_event("gui-disable", disable_gui)
     self.settings.register_event("gui-enable", enable_gui)
     # configure locations of external programs
     for auto_control_name, location_control_name, browse_button, key in (
             ("ExternalProgramInkscapeAuto",
             "ExternalProgramInkscapeControl",
             "ExternalProgramInkscapeBrowse", "inkscape"),
             ("ExternalProgramPstoeditAuto",
             "ExternalProgramPstoeditControl",
             "ExternalProgramPstoeditBrowse", "pstoedit")):
         self.gui.get_object(auto_control_name).connect("clicked",
                 self._locate_external_program, key)
         location_control = self.gui.get_object(location_control_name)
         self.settings.add_item("external_program_%s" % key,
                 location_control.get_text, location_control.set_text)
         self.gui.get_object(browse_button).connect("clicked",
                 self._browse_external_program_location, key)
     # set the icons (in different sizes) for all windows
     gtk.window_set_default_icon_list(*get_icons_pixbuffers())
     # load menu data
     gtk_menu_file = get_ui_file_location(GTKMENU_FILE)
     if gtk_menu_file is None:
         gtk.main_quit()
     uimanager.add_ui_from_file(gtk_menu_file)
     # make the actions defined in the GTKBUILD file available in the menu
     actiongroup = gtk.ActionGroup("menubar")
     for action in [action for action in self.gui.get_objects()
             if isinstance(action, gtk.Action)]:
         actiongroup.add_action(action)
     # the "pos" parameter is optional since 2.12 - we can remove it later
     uimanager.insert_action_group(actiongroup, pos=-1)
     # the "recent files" sub-menu
     if not self.recent_manager is None:
         recent_files_menu = gtk.RecentChooserMenu(self.recent_manager)
         recent_files_menu.set_name("RecentFilesMenu")
         recent_menu_filter = gtk.RecentFilter()
         case_converter = pycam.Utils.get_case_insensitive_file_pattern
         for filter_name, patterns in FILTER_MODEL:
             if not isinstance(patterns, (list, set, tuple)):
                 patterns = [patterns]
             # convert it into a mutable list (instead of set/tuple)
             patterns = list(patterns)
             for index in range(len(patterns)):
                 patterns[index] = case_converter(patterns[index])
             for pattern in patterns:
                 recent_menu_filter.add_pattern(pattern)
         recent_files_menu.add_filter(recent_menu_filter)
         recent_files_menu.set_show_numbers(True)
         # non-local files (without "file://") are not supported. yet
         recent_files_menu.set_local_only(False)
         # most recent files to the top
         recent_files_menu.set_sort_type(gtk.RECENT_SORT_MRU)
         # show only ten files
         recent_files_menu.set_limit(10)
         uimanager.get_widget("/MenuBar/FileMenu/OpenRecentModelMenu")\
                 .set_submenu(recent_files_menu)
         recent_files_menu.connect("item-activated",
                 self.load_recent_model_file)
     else:
         self.gui.get_object("OpenRecentModel").set_visible(False)
     # load the menubar and connect functions to its items
     self.menubar = uimanager.get_widget("/MenuBar")
     # dict of all merge-ids
     menu_merges = {}
     def clear_menu(menu_key):
         for merge in menu_merges.get(menu_key, []):
             uimanager.remove_ui(merge)
     def append_menu_item(menu_key, base_path, widget, name):
         merge_id = uimanager.new_merge_id()
         if widget:
             action_group = widget.props.action_group
             if not action_group in uimanager.get_action_groups():
                 uimanager.insert_action_group(action_group, -1)
             widget_name = widget.get_name()
             item_type = gtk.UI_MANAGER_MENUITEM
         else:
             widget_name = name
             item_type = gtk.UI_MANAGER_SEPARATOR
         uimanager.add_ui(merge_id, base_path, name, widget_name, item_type,
                 False)
         if not menu_key in menu_merges:
             menu_merges[menu_key] = []
         menu_merges[menu_key].append(merge_id)
     def get_menu_funcs(menu_key, base_path):
         append_func = lambda widget, name: \
                 append_menu_item(menu_key, base_path, widget, name)
         clear_func = lambda: clear_menu(menu_key)
         return append_func, clear_func
     for ui_name, base_path in (("view_menu", "/MenuBar/ViewMenu"),
             ("file_menu", "/MenuBar/FileMenu"),
             ("edit_menu", "/MenuBar/EditMenu"),
             ("export_menu", "/MenuBar/FileMenu/ExportMenu")):
         append_func, clear_func = get_menu_funcs(ui_name, base_path)
         self.settings.register_ui_section(ui_name, append_func, clear_func)
     self.settings.register_ui("file_menu", "Quit",
             self.gui.get_object("Quit"), 100)
     self.settings.register_ui("file_menu", "QuitSeparator", None, 95)
     self.settings.register_ui("main_window", "Main", self.menubar, -100)
     # initialize plugins
     self.plugin_manager = pycam.Plugins.PluginManager(core=self.settings)
     self.plugin_manager.import_plugins()
     # some more initialization
     self.reset_preferences()
     # TODO: preferences are not loaded until the new format is stable
     #self.load_preferences()
     #self.load_task_settings()
     self.settings.register_event("notify-file-saved",
             self.add_to_recent_file_list)
     self.settings.register_event("notify-file-opened",
             self.add_to_recent_file_list)
     # fallback - in case of a failure when opening a model file
     model = pycam.Importers.TestModel.get_test_model()
     self.settings.get("models").add_model(model, "Tiny pyramid")
     # Without this "gkt.main_iteration" loop the task settings file
     # control would not be updated in time.
     while gtk.events_pending():
         gtk.main_iteration()
     autoload_task_filename = self.settings.get("default_task_settings_file")
     if autoload_task_filename:
         self.open_task_settings_file(autoload_task_filename)
     self.update_all_controls()
     self.no_dialog = no_dialog
     if not self.no_dialog:
         # register a logging handler for displaying error messages
         pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR)
         self.window.show()
Exemplo n.º 33
0
 def set_accel_keymap(self):
     if self.__keyval:
         gtk.accel_map_change_entry(self.accel_path, self.__keyval,
                                    self.__modmask, True)