diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Preferences/ShortcutsDialog.py --- a/src/eric7/Preferences/ShortcutsDialog.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Preferences/ShortcutsDialog.py Wed Jul 13 14:55:47 2022 +0200 @@ -27,70 +27,71 @@ """ Class implementing a dialog for the configuration of eric's keyboard shortcuts. - + @signal updateShortcuts() emitted when the user pressed the dialogs OK button """ + updateShortcuts = pyqtSignal() - + objectNameRole = Qt.ItemDataRole.UserRole noCheckRole = Qt.ItemDataRole.UserRole + 1 objectTypeRole = Qt.ItemDataRole.UserRole + 2 - + def __init__(self, parent=None): """ Constructor - + @param parent parent widget of this dialog @type QWidget """ super().__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.WindowType.Window) - + self.__helpViewer = None - - self.shortcutsList.headerItem().setText( - self.shortcutsList.columnCount(), "") - self.shortcutsList.header().setSortIndicator( - 0, Qt.SortOrder.AscendingOrder) - + + self.shortcutsList.headerItem().setText(self.shortcutsList.columnCount(), "") + self.shortcutsList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) + from .ShortcutDialog import ShortcutDialog + self.shortcutDialog = ShortcutDialog() self.shortcutDialog.shortcutChanged.connect(self.__shortcutChanged) - + def __resort(self): """ Private method to resort the tree. """ self.shortcutsList.sortItems( self.shortcutsList.sortColumn(), - self.shortcutsList.header().sortIndicatorOrder()) - + self.shortcutsList.header().sortIndicatorOrder(), + ) + def __resizeColumns(self): """ Private method to resize the list columns. """ self.shortcutsList.header().resizeSections( - QHeaderView.ResizeMode.ResizeToContents) + QHeaderView.ResizeMode.ResizeToContents + ) self.shortcutsList.header().setStretchLastSection(True) - + def __generateCategoryItem(self, title): """ Private method to generate a category item. - + @param title title for the item (string) @return reference to the category item (QTreeWidgetItem) """ itm = QTreeWidgetItem(self.shortcutsList, [title]) itm.setExpanded(True) return itm - - def __generateShortcutItem(self, category, action, - noCheck=False, objectType=""): + + def __generateShortcutItem(self, category, action, noCheck=False, objectType=""): """ Private method to generate a keyboard shortcut item. - + @param category reference to the category item (QTreeWidgetItem) @param action reference to the keyboard action (EricAction) @param noCheck flag indicating that no uniqueness check should @@ -100,8 +101,12 @@ """ itm = QTreeWidgetItem( category, - [action.iconText(), action.shortcut().toString(), - action.alternateShortcut().toString()]) + [ + action.iconText(), + action.shortcut().toString(), + action.alternateShortcut().toString(), + ], + ) itm.setIcon(0, action.icon()) itm.setData(0, self.objectNameRole, action.objectName()) itm.setData(0, self.noCheckRole, noCheck) @@ -109,163 +114,153 @@ itm.setData(0, self.objectTypeRole, objectType) else: itm.setData(0, self.objectTypeRole, None) - + def populate(self, helpViewer=None): """ Public method to populate the dialog. - + @param helpViewer reference to the help window object """ self.searchEdit.clear() self.searchEdit.setFocus() self.shortcutsList.clear() self.actionButton.setChecked(True) - + self.__helpViewer = helpViewer - + if helpViewer is None: # let the plugin manager create on demand plugin objects pm = ericApp().getObject("PluginManager") pm.initOnDemandPlugins() - + # populate the various lists self.projectItem = self.__generateCategoryItem(self.tr("Project")) for act in ericApp().getObject("Project").getActions(): self.__generateShortcutItem(self.projectItem, act) - + self.uiItem = self.__generateCategoryItem(self.tr("General")) - for act in ericApp().getObject("UserInterface").getActions('ui'): + for act in ericApp().getObject("UserInterface").getActions("ui"): self.__generateShortcutItem(self.uiItem, act) - + self.wizardsItem = self.__generateCategoryItem(self.tr("Wizards")) - for act in ( - ericApp().getObject("UserInterface").getActions('wizards') - ): + for act in ericApp().getObject("UserInterface").getActions("wizards"): self.__generateShortcutItem(self.wizardsItem, act) - + self.debugItem = self.__generateCategoryItem(self.tr("Debug")) for act in ericApp().getObject("DebugUI").getActions(): self.__generateShortcutItem(self.debugItem, act) - + self.editItem = self.__generateCategoryItem(self.tr("Edit")) - for act in ericApp().getObject("ViewManager").getActions('edit'): + for act in ericApp().getObject("ViewManager").getActions("edit"): self.__generateShortcutItem(self.editItem, act) - + self.fileItem = self.__generateCategoryItem(self.tr("File")) - for act in ericApp().getObject("ViewManager").getActions('file'): + for act in ericApp().getObject("ViewManager").getActions("file"): self.__generateShortcutItem(self.fileItem, act) - + self.searchItem = self.__generateCategoryItem(self.tr("Search")) - for act in ericApp().getObject("ViewManager").getActions('search'): + for act in ericApp().getObject("ViewManager").getActions("search"): self.__generateShortcutItem(self.searchItem, act) - + self.viewItem = self.__generateCategoryItem(self.tr("View")) - for act in ericApp().getObject("ViewManager").getActions('view'): + for act in ericApp().getObject("ViewManager").getActions("view"): self.__generateShortcutItem(self.viewItem, act) - + self.macroItem = self.__generateCategoryItem(self.tr("Macro")) - for act in ericApp().getObject("ViewManager").getActions('macro'): + for act in ericApp().getObject("ViewManager").getActions("macro"): self.__generateShortcutItem(self.macroItem, act) - - self.bookmarkItem = self.__generateCategoryItem( - self.tr("Bookmarks")) - for act in ( - ericApp().getObject("ViewManager").getActions('bookmark') - ): + + self.bookmarkItem = self.__generateCategoryItem(self.tr("Bookmarks")) + for act in ericApp().getObject("ViewManager").getActions("bookmark"): self.__generateShortcutItem(self.bookmarkItem, act) - - self.spellingItem = self.__generateCategoryItem( - self.tr("Spelling")) - for act in ( - ericApp().getObject("ViewManager").getActions('spelling') - ): + + self.spellingItem = self.__generateCategoryItem(self.tr("Spelling")) + for act in ericApp().getObject("ViewManager").getActions("spelling"): self.__generateShortcutItem(self.spellingItem, act) - - actions = ericApp().getObject("ViewManager").getActions('window') + + actions = ericApp().getObject("ViewManager").getActions("window") if actions: - self.windowItem = self.__generateCategoryItem( - self.tr("Window")) + self.windowItem = self.__generateCategoryItem(self.tr("Window")) for act in actions: self.__generateShortcutItem(self.windowItem, act) - + self.pluginCategoryItems = [] for category, ref in ericApp().getPluginObjects(): if hasattr(ref, "getActions"): categoryItem = self.__generateCategoryItem(category) objectType = ericApp().getPluginObjectType(category) for act in ref.getActions(): - self.__generateShortcutItem(categoryItem, act, - objectType=objectType) + self.__generateShortcutItem( + categoryItem, act, objectType=objectType + ) self.pluginCategoryItems.append(categoryItem) - + else: self.helpViewerItem = self.__generateCategoryItem( - self.tr("eric Web Browser")) + self.tr("eric Web Browser") + ) for act in helpViewer.getActions(): self.__generateShortcutItem(self.helpViewerItem, act, True) - + self.__resort() self.__resizeColumns() - + self.__editTopItem = None - + def on_shortcutsList_itemDoubleClicked(self, itm, column): """ Private slot to handle a double click in the shortcuts list. - + @param itm the list item that was double clicked (QTreeWidgetItem) @param column the list item was double clicked in (integer) """ if itm.childCount(): return - + self.__editTopItem = itm.parent() - + self.shortcutDialog.setKeys( QKeySequence(itm.text(1)), QKeySequence(itm.text(2)), itm.data(0, self.noCheckRole), - itm.data(0, self.objectTypeRole)) + itm.data(0, self.objectTypeRole), + ) self.shortcutDialog.show() - + def on_shortcutsList_itemClicked(self, itm, column): """ Private slot to handle a click in the shortcuts list. - + @param itm the list item that was clicked (QTreeWidgetItem) @param column the list item was clicked in (integer) """ if itm.childCount() or column not in [1, 2]: return - + self.shortcutsList.openPersistentEditor(itm, column) - + def on_shortcutsList_itemChanged(self, itm, column): """ Private slot to handle the edit of a shortcut key. - + @param itm reference to the item changed (QTreeWidgetItem) @param column column changed (integer) """ if column != 0: keystr = itm.text(column).title() - if ( - not itm.data(0, self.noCheckRole) and - not self.__checkShortcut(QKeySequence(keystr), - itm.data(0, self.objectTypeRole), - itm.parent()) + if not itm.data(0, self.noCheckRole) and not self.__checkShortcut( + QKeySequence(keystr), itm.data(0, self.objectTypeRole), itm.parent() ): itm.setText(column, "") else: itm.setText(column, keystr) self.shortcutsList.closePersistentEditor(itm, column) - def __shortcutChanged(self, keysequence, altKeysequence, noCheck, - objectType): + def __shortcutChanged(self, keysequence, altKeysequence, noCheck, objectType): """ Private slot to handle the shortcutChanged signal of the shortcut dialog. - + @param keysequence the keysequence of the changed action (QKeySequence) @param altKeysequence the alternative keysequence of the changed action (QKeySequence) @@ -273,25 +268,22 @@ be performed (boolean) @param objectType type of the object (string). """ - if ( - not noCheck and - (not self.__checkShortcut( - keysequence, objectType, self.__editTopItem) or - not self.__checkShortcut( - altKeysequence, objectType, self.__editTopItem)) + if not noCheck and ( + not self.__checkShortcut(keysequence, objectType, self.__editTopItem) + or not self.__checkShortcut(altKeysequence, objectType, self.__editTopItem) ): return - + self.shortcutsList.currentItem().setText(1, keysequence.toString()) self.shortcutsList.currentItem().setText(2, altKeysequence.toString()) - + self.__resort() self.__resizeColumns() - + def __checkShortcut(self, keysequence, objectType, origTopItem): """ Private method to check a keysequence for uniqueness. - + @param keysequence the keysequence to check (QKeySequence) @param objectType type of the object (string). Entries with the same object type are not checked for uniqueness. @@ -301,27 +293,27 @@ """ if keysequence.isEmpty(): return True - + keystr = keysequence.toString() keyname = self.shortcutsList.currentItem().text(0) for topIndex in range(self.shortcutsList.topLevelItemCount()): topItem = self.shortcutsList.topLevelItem(topIndex) for index in range(topItem.childCount()): itm = topItem.child(index) - + # 1. shall a check be performed? if itm.data(0, self.noCheckRole): continue - + # 2. check object type itmObjectType = itm.data(0, self.objectTypeRole) if ( - itmObjectType and - itmObjectType == objectType and - topItem != origTopItem + itmObjectType + and itmObjectType == objectType + and topItem != origTopItem ): continue - + # 3. check key name if itm.text(0) != keyname: for col in [1, 2]: @@ -335,18 +327,19 @@ self.tr( """<p><b>{0}</b> has already been""" """ allocated to the <b>{1}</b> action. """ - """Remove this binding?</p>""") - .format(keystr, itm.text(0)), - icon=EricMessageBox.Warning) + """Remove this binding?</p>""" + ).format(keystr, itm.text(0)), + icon=EricMessageBox.Warning, + ) if res: itm.setText(col, "") return True else: return False - + if not itmseq: continue - + # step 2: check if shortcut hides an already allocated if itmseq.startswith("{0}+".format(keystr)): res = EricMessageBox.yesNo( @@ -354,15 +347,16 @@ self.tr("Edit shortcuts"), self.tr( """<p><b>{0}</b> hides the <b>{1}</b>""" - """ action. Remove this binding?</p>""") - .format(keystr, itm.text(0)), - icon=EricMessageBox.Warning) + """ action. Remove this binding?</p>""" + ).format(keystr, itm.text(0)), + icon=EricMessageBox.Warning, + ) if res: itm.setText(col, "") return True else: return False - + # step 3: check if shortcut is hidden by an # already allocated if keystr.startswith("{0}+".format(itmseq)): @@ -372,21 +366,22 @@ self.tr( """<p><b>{0}</b> is hidden by the """ """<b>{1}</b> action. """ - """Remove this binding?</p>""") - .format(keystr, itm.text(0)), - icon=EricMessageBox.Warning) + """Remove this binding?</p>""" + ).format(keystr, itm.text(0)), + icon=EricMessageBox.Warning, + ) if res: itm.setText(col, "") return True else: return False - + return True - + def __saveCategoryActions(self, category, actions): """ Private method to save the actions for a category. - + @param category reference to the category item (QTreeWidgetItem) @param actions list of actions for the category (list of EricAction) """ @@ -397,75 +392,80 @@ if txt == act.objectName(): act.setShortcut(QKeySequence(itm.text(1))) act.setAlternateShortcut( - QKeySequence(itm.text(2)), removeEmpty=True) + QKeySequence(itm.text(2)), removeEmpty=True + ) break - + def on_buttonBox_accepted(self): """ Private slot to handle the OK button press. """ if self.__helpViewer is None: self.__saveCategoryActions( - self.projectItem, - ericApp().getObject("Project").getActions()) + self.projectItem, ericApp().getObject("Project").getActions() + ) self.__saveCategoryActions( - self.uiItem, - ericApp().getObject("UserInterface").getActions('ui')) + self.uiItem, ericApp().getObject("UserInterface").getActions("ui") + ) self.__saveCategoryActions( self.wizardsItem, - ericApp().getObject("UserInterface").getActions('wizards')) + ericApp().getObject("UserInterface").getActions("wizards"), + ) self.__saveCategoryActions( - self.debugItem, - ericApp().getObject("DebugUI").getActions()) + self.debugItem, ericApp().getObject("DebugUI").getActions() + ) self.__saveCategoryActions( - self.editItem, - ericApp().getObject("ViewManager").getActions('edit')) + self.editItem, ericApp().getObject("ViewManager").getActions("edit") + ) self.__saveCategoryActions( - self.fileItem, - ericApp().getObject("ViewManager").getActions('file')) + self.fileItem, ericApp().getObject("ViewManager").getActions("file") + ) self.__saveCategoryActions( - self.searchItem, - ericApp().getObject("ViewManager").getActions('search')) + self.searchItem, ericApp().getObject("ViewManager").getActions("search") + ) self.__saveCategoryActions( - self.viewItem, - ericApp().getObject("ViewManager").getActions('view')) + self.viewItem, ericApp().getObject("ViewManager").getActions("view") + ) self.__saveCategoryActions( - self.macroItem, - ericApp().getObject("ViewManager").getActions('macro')) + self.macroItem, ericApp().getObject("ViewManager").getActions("macro") + ) self.__saveCategoryActions( self.bookmarkItem, - ericApp().getObject("ViewManager").getActions('bookmark')) + ericApp().getObject("ViewManager").getActions("bookmark"), + ) self.__saveCategoryActions( self.spellingItem, - ericApp().getObject("ViewManager").getActions('spelling')) - - actions = ericApp().getObject("ViewManager").getActions('window') + ericApp().getObject("ViewManager").getActions("spelling"), + ) + + actions = ericApp().getObject("ViewManager").getActions("window") if actions: self.__saveCategoryActions(self.windowItem, actions) - + for categoryItem in self.pluginCategoryItems: category = categoryItem.text(0) ref = ericApp().getPluginObject(category) if ref is not None and hasattr(ref, "getActions"): self.__saveCategoryActions(categoryItem, ref.getActions()) - + Shortcuts.saveShortcuts() - + else: self.__saveCategoryActions( - self.helpViewerItem, self.__helpViewer.getActions()) + self.helpViewerItem, self.__helpViewer.getActions() + ) Shortcuts.saveShortcuts(helpViewer=self.__helpViewer) - + Preferences.syncPreferences() - + self.updateShortcuts.emit() self.hide() - + @pyqtSlot(str) def on_searchEdit_textChanged(self, txt): """ Private slot called, when the text in the search edit changes. - + @param txt text of the search edit (string) """ rx = re.compile(re.escape(txt), re.IGNORECASE) @@ -474,13 +474,12 @@ childHiddenCount = 0 for index in range(topItem.childCount()): itm = topItem.child(index) - if ( - txt and ( - (self.actionButton.isChecked() and - rx.search(itm.text(0)) is None) or - (self.shortcutButton.isChecked() and - txt.lower() not in itm.text(1).lower() and - txt.lower() not in itm.text(2).lower()) + if txt and ( + (self.actionButton.isChecked() and rx.search(itm.text(0)) is None) + or ( + self.shortcutButton.isChecked() + and txt.lower() not in itm.text(1).lower() + and txt.lower() not in itm.text(2).lower() ) ): itm.setHidden(True) @@ -488,22 +487,22 @@ else: itm.setHidden(False) topItem.setHidden(childHiddenCount == topItem.childCount()) - + @pyqtSlot(bool) def on_actionButton_toggled(self, checked): """ Private slot called, when the action radio button is toggled. - + @param checked state of the action radio button (boolean) """ if checked: self.on_searchEdit_textChanged(self.searchEdit.text()) - + @pyqtSlot(bool) def on_shortcutButton_toggled(self, checked): """ Private slot called, when the shortcuts radio button is toggled. - + @param checked state of the shortcuts radio button (boolean) """ if checked: