--- a/eric7/E5Gui/EricToolBarDialog.py Sat May 22 19:52:34 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,525 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2008 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a toolbar configuration dialog. -""" - -from PyQt6.QtCore import pyqtSlot, Qt -from PyQt6.QtGui import QColor -from PyQt6.QtWidgets import ( - QDialog, QDialogButtonBox, QTreeWidgetItem, QInputDialog, QLineEdit, - QListWidgetItem, QAbstractButton -) - -from E5Gui import EricMessageBox - -from .Ui_EricToolBarDialog import Ui_EricToolBarDialog - -import UI.PixmapCache - - -class EricToolBarItem: - """ - Class storing data belonging to a toolbar entry of the toolbar dialog. - """ - def __init__(self, toolBarId, actionIDs, default): - """ - Constructor - - @param toolBarId id of the toolbar object (integer) - @param actionIDs list of action IDs belonging to the toolbar - (list of integer) - @param default flag indicating a default toolbar (boolean) - """ - self.toolBarId = toolBarId - self.actionIDs = actionIDs[:] - self.isDefault = default - self.title = "" - self.isChanged = False - - -class EricToolBarDialog(QDialog, Ui_EricToolBarDialog): - """ - Class implementing a toolbar configuration dialog. - """ - ActionIdRole = Qt.ItemDataRole.UserRole - WidgetActionRole = Qt.ItemDataRole.UserRole + 1 - - def __init__(self, toolBarManager, parent=None): - """ - Constructor - - @param toolBarManager reference to a toolbar manager object - (EricToolBarManager) - @param parent reference to the parent widget (QWidget) - """ - super().__init__(parent) - self.setupUi(self) - - self.__manager = toolBarManager - self.__toolbarItems = {} - # maps toolbar item IDs to toolbar items - self.__currentToolBarItem = None - self.__removedToolBarIDs = [] - # remember custom toolbars to be deleted - - self.__widgetActionToToolBarItemID = {} - # maps widget action IDs to toolbar item IDs - self.__toolBarItemToWidgetActionID = {} - # maps toolbar item IDs to widget action IDs - - self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow")) - self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow")) - self.leftButton.setIcon(UI.PixmapCache.getIcon("1leftarrow")) - self.rightButton.setIcon(UI.PixmapCache.getIcon("1rightarrow")) - - self.__restoreDefaultsButton = self.buttonBox.button( - QDialogButtonBox.StandardButton.RestoreDefaults) - self.__resetButton = self.buttonBox.button( - QDialogButtonBox.StandardButton.Reset) - - self.actionsTree.header().hide() - self.__separatorText = self.tr("--Separator--") - itm = QTreeWidgetItem(self.actionsTree, [self.__separatorText]) - self.actionsTree.setCurrentItem(itm) - - for category in sorted(self.__manager.categories()): - categoryItem = QTreeWidgetItem(self.actionsTree, [category]) - for action in self.__manager.categoryActions(category): - item = QTreeWidgetItem(categoryItem) - item.setText(0, action.text()) - item.setIcon(0, action.icon()) - item.setTextAlignment( - 0, - Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter - ) - item.setData(0, EricToolBarDialog.ActionIdRole, int(id(action))) - item.setData(0, EricToolBarDialog.WidgetActionRole, False) - if self.__manager.isWidgetAction(action): - item.setData(0, EricToolBarDialog.WidgetActionRole, True) - item.setData(0, Qt.ItemDataRole.ForegroundRole, - QColor(Qt.GlobalColor.blue)) - self.__widgetActionToToolBarItemID[id(action)] = None - categoryItem.setExpanded(True) - - for tbID, actions in list(self.__manager.toolBarsActions().items()): - tb = self.__manager.toolBarById(tbID) - default = self.__manager.isDefaultToolBar(tb) - tbItem = EricToolBarItem(tbID, [], default) - self.__toolbarItems[id(tbItem)] = tbItem - self.__toolBarItemToWidgetActionID[id(tbItem)] = [] - actionIDs = [] - for action in actions: - if action is None: - actionIDs.append(None) - else: - aID = id(action) - actionIDs.append(aID) - if aID in self.__widgetActionToToolBarItemID: - self.__widgetActionToToolBarItemID[aID] = id(tbItem) - self.__toolBarItemToWidgetActionID[id(tbItem)].append( - aID) - tbItem.actionIDs = actionIDs - self.toolbarComboBox.addItem(tb.windowTitle(), int(id(tbItem))) - if default: - self.toolbarComboBox.setItemData( - self.toolbarComboBox.count() - 1, - QColor(Qt.GlobalColor.darkGreen), - Qt.ItemDataRole.ForegroundRole) - self.toolbarComboBox.model().sort(0) - - self.toolbarComboBox.currentIndexChanged[int].connect( - self.__toolbarComboBox_currentIndexChanged) - self.toolbarComboBox.setCurrentIndex(0) - - @pyqtSlot() - def on_newButton_clicked(self): - """ - Private slot to create a new toolbar. - """ - name, ok = QInputDialog.getText( - self, - self.tr("New Toolbar"), - self.tr("Toolbar Name:"), - QLineEdit.EchoMode.Normal) - if ok and name: - if self.toolbarComboBox.findText(name) != -1: - # toolbar with this name already exists - EricMessageBox.critical( - self, - self.tr("New Toolbar"), - self.tr( - """A toolbar with the name <b>{0}</b> already""" - """ exists.""") - .format(name)) - return - - tbItem = EricToolBarItem(None, [], False) - tbItem.title = name - tbItem.isChanged = True - self.__toolbarItems[id(tbItem)] = tbItem - self.__toolBarItemToWidgetActionID[id(tbItem)] = [] - self.toolbarComboBox.addItem(name, int(id(tbItem))) - self.toolbarComboBox.model().sort(0) - self.toolbarComboBox.setCurrentIndex( - self.toolbarComboBox.findText(name)) - - @pyqtSlot() - def on_removeButton_clicked(self): - """ - Private slot to remove a custom toolbar. - """ - name = self.toolbarComboBox.currentText() - res = EricMessageBox.yesNo( - self, - self.tr("Remove Toolbar"), - self.tr( - """Should the toolbar <b>{0}</b> really be removed?""") - .format(name)) - if res: - index = self.toolbarComboBox.currentIndex() - tbItemID = self.toolbarComboBox.itemData(index) - tbItem = self.__toolbarItems[tbItemID] - if ( - tbItem.toolBarId is not None and - tbItem.toolBarId not in self.__removedToolBarIDs - ): - self.__removedToolBarIDs.append(tbItem.toolBarId) - del self.__toolbarItems[tbItemID] - for widgetActionID in self.__toolBarItemToWidgetActionID[tbItemID]: - self.__widgetActionToToolBarItemID[widgetActionID] = None - del self.__toolBarItemToWidgetActionID[tbItemID] - self.toolbarComboBox.removeItem(index) - - @pyqtSlot() - def on_renameButton_clicked(self): - """ - Private slot to rename a custom toolbar. - """ - oldName = self.toolbarComboBox.currentText() - newName, ok = QInputDialog.getText( - self, - self.tr("Rename Toolbar"), - self.tr("New Toolbar Name:"), - QLineEdit.EchoMode.Normal, - oldName) - if ok and newName: - if oldName == newName: - return - if self.toolbarComboBox.findText(newName) != -1: - # toolbar with this name already exists - EricMessageBox.critical( - self, - self.tr("Rename Toolbar"), - self.tr( - """A toolbar with the name <b>{0}</b> already""" - """ exists.""") - .format(newName)) - return - index = self.toolbarComboBox.currentIndex() - self.toolbarComboBox.setItemText(index, newName) - tbItem = self.__toolbarItems[self.toolbarComboBox.itemData(index)] - tbItem.title = newName - tbItem.isChanged = True - - def __setupButtons(self): - """ - Private slot to set the buttons state. - """ - index = self.toolbarComboBox.currentIndex() - if index > -1: - itemID = self.toolbarComboBox.itemData(index) - self.__currentToolBarItem = self.__toolbarItems[itemID] - self.renameButton.setEnabled( - not self.__currentToolBarItem.isDefault) - self.removeButton.setEnabled( - not self.__currentToolBarItem.isDefault) - self.__restoreDefaultsButton.setEnabled( - self.__currentToolBarItem.isDefault) - self.__resetButton.setEnabled( - self.__currentToolBarItem.toolBarId is not None) - - row = self.toolbarActionsList.currentRow() - self.upButton.setEnabled(row > 0) - self.downButton.setEnabled(row < self.toolbarActionsList.count() - 1) - self.leftButton.setEnabled(self.toolbarActionsList.count() > 0) - rightEnable = ( - self.actionsTree.currentItem().parent() is not None or - self.actionsTree.currentItem().text(0) == self.__separatorText - ) - self.rightButton.setEnabled(rightEnable) - - @pyqtSlot(int) - def __toolbarComboBox_currentIndexChanged(self, index): - """ - Private slot called upon a selection of the current toolbar. - - @param index index of the new current toolbar (integer) - """ - itemID = self.toolbarComboBox.itemData(index) - self.__currentToolBarItem = self.__toolbarItems[itemID] - self.toolbarActionsList.clear() - for actionID in self.__currentToolBarItem.actionIDs: - item = QListWidgetItem(self.toolbarActionsList) - if actionID is None: - item.setText(self.__separatorText) - else: - action = self.__manager.actionById(actionID) - item.setText(action.text()) - item.setIcon(action.icon()) - item.setTextAlignment(Qt.AlignmentFlag.AlignLeft | - Qt.AlignmentFlag.AlignVCenter) - item.setData(EricToolBarDialog.ActionIdRole, int(id(action))) - item.setData(EricToolBarDialog.WidgetActionRole, False) - if self.__manager.isWidgetAction(action): - item.setData(EricToolBarDialog.WidgetActionRole, True) - item.setData(Qt.ItemDataRole.ForegroundRole, - QColor(Qt.GlobalColor.blue)) - self.toolbarActionsList.setCurrentRow(0) - - self.__setupButtons() - - @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) - def on_actionsTree_currentItemChanged(self, current, previous): - """ - Private slot called, when the currently selected action changes. - - @param current reference to the current item (QTreeWidgetItem) - @param previous reference to the previous current item - (QTreeWidgetItem) - """ - self.__setupButtons() - - @pyqtSlot(QListWidgetItem, QListWidgetItem) - def on_toolbarActionsList_currentItemChanged(self, current, previous): - """ - Private slot to handle a change of the current item. - - @param current reference to the current item (QListWidgetItem) - @param previous reference to the previous current item - (QListWidgetItem) - """ - self.__setupButtons() - - @pyqtSlot() - def on_upButton_clicked(self): - """ - Private slot used to move an action up in the list. - """ - row = self.toolbarActionsList.currentRow() - if row == 0: - # we're already at the top - return - - actionID = self.__currentToolBarItem.actionIDs.pop(row) - self.__currentToolBarItem.actionIDs.insert(row - 1, actionID) - self.__currentToolBarItem.isChanged = True - itm = self.toolbarActionsList.takeItem(row) - self.toolbarActionsList.insertItem(row - 1, itm) - self.toolbarActionsList.setCurrentItem(itm) - self.__setupButtons() - - @pyqtSlot() - def on_downButton_clicked(self): - """ - Private slot used to move an action down in the list. - """ - row = self.toolbarActionsList.currentRow() - if row == self.toolbarActionsList.count() - 1: - # we're already at the end - return - - actionID = self.__currentToolBarItem.actionIDs.pop(row) - self.__currentToolBarItem.actionIDs.insert(row + 1, actionID) - self.__currentToolBarItem.isChanged = True - itm = self.toolbarActionsList.takeItem(row) - self.toolbarActionsList.insertItem(row + 1, itm) - self.toolbarActionsList.setCurrentItem(itm) - self.__setupButtons() - - @pyqtSlot() - def on_leftButton_clicked(self): - """ - Private slot to delete an action from the list. - """ - row = self.toolbarActionsList.currentRow() - actionID = self.__currentToolBarItem.actionIDs.pop(row) - self.__currentToolBarItem.isChanged = True - if actionID in self.__widgetActionToToolBarItemID: - self.__widgetActionToToolBarItemID[actionID] = None - self.__toolBarItemToWidgetActionID[ - id(self.__currentToolBarItem)].remove(actionID) - itm = self.toolbarActionsList.takeItem(row) - del itm - self.toolbarActionsList.setCurrentRow(row) - self.__setupButtons() - - @pyqtSlot() - def on_rightButton_clicked(self): - """ - Private slot to add an action to the list. - """ - row = self.toolbarActionsList.currentRow() + 1 - - item = QListWidgetItem() - if self.actionsTree.currentItem().text(0) == self.__separatorText: - item.setText(self.__separatorText) - actionID = None - else: - actionID = self.actionsTree.currentItem().data( - 0, EricToolBarDialog.ActionIdRole) - action = self.__manager.actionById(actionID) - item.setText(action.text()) - item.setIcon(action.icon()) - item.setTextAlignment(Qt.AlignmentFlag.AlignLeft | - Qt.AlignmentFlag.AlignVCenter) - item.setData(EricToolBarDialog.ActionIdRole, int(id(action))) - item.setData(EricToolBarDialog.WidgetActionRole, False) - if self.__manager.isWidgetAction(action): - item.setData(EricToolBarDialog.WidgetActionRole, True) - item.setData(Qt.ItemDataRole.ForegroundRole, - QColor(Qt.GlobalColor.blue)) - oldTbItemID = self.__widgetActionToToolBarItemID[actionID] - if oldTbItemID is not None: - self.__toolbarItems[oldTbItemID].actionIDs.remove(actionID) - self.__toolbarItems[oldTbItemID].isChanged = True - self.__toolBarItemToWidgetActionID[oldTbItemID].remove( - actionID) - self.__widgetActionToToolBarItemID[actionID] = id( - self.__currentToolBarItem) - self.__toolBarItemToWidgetActionID[ - id(self.__currentToolBarItem)].append(actionID) - self.toolbarActionsList.insertItem(row, item) - self.__currentToolBarItem.actionIDs.insert(row, actionID) - self.__currentToolBarItem.isChanged = True - self.toolbarActionsList.setCurrentRow(row) - self.__setupButtons() - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot called, when a button of the button box was clicked. - - @param button reference to the button clicked (QAbstractButton) - """ - if button == self.buttonBox.button( - QDialogButtonBox.StandardButton.Cancel - ): - self.reject() - elif button == self.buttonBox.button( - QDialogButtonBox.StandardButton.Apply - ): - self.__saveToolBars() - self.__setupButtons() - elif button == self.buttonBox.button( - QDialogButtonBox.StandardButton.Ok - ): - self.__saveToolBars() - self.accept() - elif button == self.buttonBox.button( - QDialogButtonBox.StandardButton.Reset - ): - self.__resetCurrentToolbar() - self.__setupButtons() - elif button == self.buttonBox.button( - QDialogButtonBox.StandardButton.RestoreDefaults - ): - self.__restoreCurrentToolbarToDefault() - self.__setupButtons() - - def __saveToolBars(self): - """ - Private method to save the configured toolbars. - - @exception RuntimeError raised to indicate an invalid action - """ - # step 1: remove toolbars marked for deletion - for tbID in self.__removedToolBarIDs: - tb = self.__manager.toolBarById(tbID) - self.__manager.deleteToolBar(tb) - self.__removedToolBarIDs = [] - - # step 2: save configured toolbars - for tbItem in list(self.__toolbarItems.values()): - if not tbItem.isChanged: - continue - - if tbItem.toolBarId is None: - # new custom toolbar - tb = self.__manager.createToolBar(tbItem.title) - tbItem.toolBarId = id(tb) - else: - tb = self.__manager.toolBarById(tbItem.toolBarId) - if not tbItem.isDefault and tbItem.title: - self.__manager.renameToolBar(tb, tbItem.title) - - actions = [] - for actionID in tbItem.actionIDs: - if actionID is None: - actions.append(None) - else: - action = self.__manager.actionById(actionID) - if action is None: - raise RuntimeError( - "No such action, id: 0x{0:x}".format(actionID)) - actions.append(action) - self.__manager.setToolBar(tb, actions) - tbItem.isChanged = False - - def __restoreCurrentToolbar(self, actions): - """ - Private methdo to restore the current toolbar to the given list of - actions. - - @param actions list of actions to set for the current toolbar - (list of QAction) - """ - tbItemID = id(self.__currentToolBarItem) - for widgetActionID in self.__toolBarItemToWidgetActionID[tbItemID]: - self.__widgetActionToToolBarItemID[widgetActionID] = None - self.__toolBarItemToWidgetActionID[tbItemID] = [] - self.__currentToolBarItem.actionIDs = [] - - for action in actions: - if action is None: - self.__currentToolBarItem.actionIDs.append(None) - else: - actionID = id(action) - self.__currentToolBarItem.actionIDs.append(actionID) - if actionID in self.__widgetActionToToolBarItemID: - oldTbItemID = self.__widgetActionToToolBarItemID[actionID] - if oldTbItemID is not None: - self.__toolbarItems[oldTbItemID].actionIDs.remove( - actionID) - self.__toolbarItems[oldTbItemID].isChanged = True - self.__toolBarItemToWidgetActionID[oldTbItemID].remove( - actionID) - self.__widgetActionToToolBarItemID[actionID] = tbItemID - self.__toolBarItemToWidgetActionID[tbItemID].append( - actionID) - self.__toolbarComboBox_currentIndexChanged( - self.toolbarComboBox.currentIndex()) - - def __resetCurrentToolbar(self): - """ - Private method to revert all changes made to the current toolbar. - """ - tbID = self.__currentToolBarItem.toolBarId - actions = self.__manager.toolBarActions(tbID) - self.__restoreCurrentToolbar(actions) - self.__currentToolBarItem.isChanged = False - - def __restoreCurrentToolbarToDefault(self): - """ - Private method to set the current toolbar to its default configuration. - """ - if not self.__currentToolBarItem.isDefault: - return - - tbID = self.__currentToolBarItem.toolBarId - actions = self.__manager.defaultToolBarActions(tbID) - self.__restoreCurrentToolbar(actions) - self.__currentToolBarItem.isChanged = True