Beispiel #1
0
 def __init__(self, action, collection, name):
     QTreeWidgetItem.__init__(self)
     self.collection = collection
     self.name = name
     self.setIcon(0, action.icon())
     self.setText(0, actioncollection.removeAccels(action.text()))
     self._shortcuts = {}
Beispiel #2
0
 def __init__(self, dialog):
     super(Shortcuts, self).__init__(dialog)
     
     layout = QVBoxLayout()
     layout.setContentsMargins(0, 0, 0, 0)
     self.setLayout(layout)
     
     self.scheme = SchemeSelector(self)
     layout.addWidget(self.scheme)
     self.tree = QTreeWidget(self)
     self.tree.setHeaderLabels([_("Command"), _("Shortcut")])
     self.tree.setRootIsDecorated(False)
     self.tree.setColumnCount(2)
     self.tree.setAllColumnsShowFocus(True)
     self.tree.setAnimated(True)
     layout.addWidget(self.tree)
     
     self.edit = QPushButton(icons.get("configure-shortcuts"), '')
     layout.addWidget(self.edit)
     
     # signals
     self.scheme.currentChanged.connect(self.slotSchemeChanged)
     self.scheme.changed.connect(self.changed)
     self.tree.currentItemChanged.connect(self.slotCurrentItemChanged)
     self.tree.itemDoubleClicked.connect(self.editCurrentItem)
     self.edit.clicked.connect(self.editCurrentItem)
     
     # make a dict of all actions with the actions as key and the names as
     # value, with the collection prepended (for loading/saving)
     win = dialog.parent()
     allactions = {}
     for collection in actioncollectionmanager.manager(win).actionCollections():
         for name, action in collection.actions().items():
             allactions[action] = (collection, name)
     
     # keep a list of actions not in the menu structure
     left = allactions.keys()
     
     def childactions(menu):
         for a in menu.actions():
             if a.menu():
                 for a in childactions(a.menu()):
                     yield a
             elif a in left:
                 yield a
                 left.remove(a)
             
     # present the actions nicely ordered as in the menus
     for a in win.menuBar().actions():
         menuitem = QTreeWidgetItem()
         menu = a.menu()
         text = actioncollection.removeAccels(a.text())
         for a in childactions(menu):
             menuitem.addChild(ShortcutItem(a, *allactions[a]))
         if menuitem.childCount():
             menuitem.setText(0, _("Menu {name}:").format(name=text))
             self.tree.addTopLevelItem(menuitem)
             menuitem.setExpanded(True)
             menuitem.setFlags(Qt.ItemIsEnabled) # disable selection
     
     # sort leftover actions
     left.sort(key=lambda i: i.text())
     
     # show actions that are left, grouped by collection
     titlegroups = {}
     for a in left[:]: # copy
         collection, name = allactions[a]
         if collection.title():
             titlegroups.setdefault(collection.title(), []).append(a)
             left.remove(a)
     for title in sorted(titlegroups):
         item = QTreeWidgetItem(["{0}:".format(title)])
         for a in titlegroups[title]:
             item.addChild(ShortcutItem(a, *allactions[a]))
         self.tree.addTopLevelItem(item)
         item.setExpanded(True)
         item.setFlags(Qt.ItemIsEnabled) # disable selection
         
     # show other actions that were not in the menus
     item = QTreeWidgetItem([_("Other commands:")])
     for a in left:
         if a.text() and not a.menu():
             item.addChild(ShortcutItem(a, *allactions[a]))
     if item.childCount():
         self.tree.addTopLevelItem(item)
         item.setExpanded(True)
         item.setFlags(Qt.ItemIsEnabled) # disable selection
     
     item = self.tree.topLevelItem(0).child(0)
     if _lastaction:
         # find the previously selected item
         for i in self.items():
             if i.name == _lastaction:
                 item = i
                 break
     self.tree.setCurrentItem(item)
     self.tree.resizeColumnToContents(0)
 def editAction(self, parent, action, default=None, skip=None):
     """Edits the keyboard shortcut for a single action.
     
     Returns True if editing was Ok, False if cancelled.
     parent is the widget to show the dialog above.
     default gives None or a list with QKeySequence objects that are the default shortcut.
     
     Use skip to give the action to skip (e.g. the action that is about to be changed).
     skip can also be a tuple (collection, name) to define the action to skip.
     
     Just uses the dialog in widgets.shortcuteditdialog but implements conflict checking
     (without altering other shortcuts. The implementation of conflict checking in 
     preferences/shortcuts.py also can change other shortcuts in the prefs dialog.)
    
     """
     skip_ = lambda: a is skip
     if skip is None:
         skip = action
     elif isinstance(skip, tuple):
         skip_ = lambda: (collection, name) == skip
         
     from widgets import shortcuteditdialog
     dlg = shortcuteditdialog.ShortcutEditDialog(parent)
     
     with util.deleteLater(dlg):
         while dlg.editAction(action, default):
             # conflict checking
             shortcuts = action.shortcuts()
             if shortcuts:
                 conflicts = {}
                 for collection in self.actionCollections():
                     for name, a in collection.actions().items():
                         # we use collection.shortcuts(name) instead of a.shortcuts()
                         # because the (real) actions returned by ShortcutCollection.action()
                         # don't have the shortcuts set.
                         if not skip_() and collection.shortcuts(name):
                             for s1 in collection.shortcuts(name):
                                 for s2 in action.shortcuts():
                                     if s2.matches(s1) or s1.matches(s2):
                                         # s2 conflicts with a
                                         conflicts.setdefault(a, []).append(s2)
                                         # do shortcuts remain?
                                         if s2 in shortcuts:
                                             shortcuts.remove(s2)
                 if conflicts:
                     msg = [_("This shortcut conflicts with the following command:",
                             "This shortcut conflicts with the following commands:", len(conflicts))]
                     msg.append("<br/>".join("{name} ({key})".format(
                         name = actioncollection.removeAccels(a.text()),
                         key=' \u2014 '.join(s.toString() for s in conflicts[a])) for a in conflicts))
                     msg = '<p>{0}</p>'.format('</p><p>'.join(msg))
                     box = QMessageBox(QMessageBox.Warning, _("Shortcut Conflict"), msg,
                             QMessageBox.Ok | QMessageBox.Cancel, parent)
                     box.button(QMessageBox.Ok).setText(_("Edit again"))
                     if box.exec_() == QMessageBox.Ok:
                         action.setShortcuts(shortcuts)
                         continue
                     else:
                         break
             return True
     return False