From 6db67e909d66e93d2710f00dd737ab549e0022d5 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 26 Oct 2025 14:02:18 +0100 Subject: [PATCH] Add icon colour settings to themes and enforce them on all GUI icons --- novelwriter/core/novelmodel.py | 2 +- novelwriter/dialogs/preferences.py | 20 ++++---- novelwriter/dialogs/projectsettings.py | 16 +++---- novelwriter/dialogs/wordlist.py | 8 ++-- novelwriter/extensions/modified.py | 19 ++++---- novelwriter/extensions/novelselector.py | 2 +- novelwriter/gui/doceditor.py | 54 ++++++++++----------- novelwriter/gui/docviewer.py | 16 +++---- novelwriter/gui/docviewerpanel.py | 14 +++--- novelwriter/gui/noveltree.py | 6 +-- novelwriter/gui/outline.py | 6 +-- novelwriter/gui/projtree.py | 14 +++--- novelwriter/gui/search.py | 10 ++-- novelwriter/gui/sidebar.py | 18 +++---- novelwriter/gui/theme.py | 62 +++++++++++++++++-------- novelwriter/shared.py | 8 ++-- novelwriter/tools/dictionaries.py | 6 +-- novelwriter/tools/lipsum.py | 2 +- novelwriter/tools/manusbuild.py | 20 ++++---- novelwriter/tools/manuscript.py | 16 +++---- novelwriter/tools/manussettings.py | 43 +++++++++-------- novelwriter/tools/welcome.py | 12 ++--- novelwriter/tools/writingstats.py | 2 +- tests/test_ext/test_ext_modified.py | 6 +-- tests/test_gui/test_gui_theme.py | 21 +++++---- 25 files changed, 216 insertions(+), 187 deletions(-) diff --git a/novelwriter/core/novelmodel.py b/novelwriter/core/novelmodel.py index 7b1cd426..6418b1bc 100644 --- a/novelwriter/core/novelmodel.py +++ b/novelwriter/core/novelmodel.py @@ -61,7 +61,7 @@ class NovelModel(QAbstractTableModel): def __init__(self) -> None: super().__init__() self._rows: list[dict[int, T_NodeData]] = [] - self._more = SHARED.theme.getIcon("more_arrow") + self._more = SHARED.theme.getIcon("more_arrow", "tool") self._columns = 3 self._extraKey = "" self._extraLabel = "" diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index d36ca9ba..df976d21 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -71,7 +71,7 @@ class GuiPreferences(NDialog): ) # Search Box - self.searchAction = QAction(SHARED.theme.getIcon("search"), "") + self.searchAction = QAction(SHARED.theme.getIcon("search", "apply"), "") self.searchAction.triggered.connect(self._gotoSearch) self.searchText = QLineEdit(self) @@ -211,7 +211,7 @@ class GuiPreferences(NDialog): self.guiFont.setMinimumWidth(162) self.guiFont.setText(describeFont(self._guiFont)) self.guiFont.setCursorPosition(0) - self.guiFontButton = NIconToolButton(self, iSz, "font") + self.guiFontButton = NIconToolButton(self, iSz, "font", "tool") self.guiFontButton.clicked.connect(self._selectGuiFont) self.mainForm.addRow( self.tr("Application font"), self.guiFont, @@ -265,7 +265,7 @@ class GuiPreferences(NDialog): self.textFont.setMinimumWidth(162) self.textFont.setText(describeFont(CONFIG.textFont)) self.textFont.setCursorPosition(0) - self.textFontButton = NIconToolButton(self, iSz, "font") + self.textFontButton = NIconToolButton(self, iSz, "font", "tool") self.textFontButton.clicked.connect(self._selectTextFont) self.mainForm.addRow( self.tr("Document font"), self.textFont, @@ -373,7 +373,9 @@ class GuiPreferences(NDialog): # Backup Path self.backupPath = CONFIG.backupPath() - self.backupGetPath = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Browse"), self) + self.backupGetPath = QPushButton( + SHARED.theme.getIcon("browse", "systemio"), self.tr("Browse"), self + ) self.backupGetPath.setIconSize(iSz) self.backupGetPath.clicked.connect(self._backupFolder) self.mainForm.addRow( @@ -665,7 +667,7 @@ class GuiPreferences(NDialog): self.dialogLine.setAlignment(QtAlignCenter) self.dialogLine.setText(" ".join(CONFIG.dialogLine)) - self.dialogLineButton = NIconToolButton(self, iSz, "add", "green") + self.dialogLineButton = NIconToolButton(self, iSz, "add", "add") self.dialogLineButton.setMenu(self.mnLineSymbols) self.mainForm.addRow( @@ -807,7 +809,7 @@ class GuiPreferences(NDialog): self.fmtSQuoteOpen.setFixedWidth(boxFixed) self.fmtSQuoteOpen.setAlignment(QtAlignCenter) self.fmtSQuoteOpen.setText(CONFIG.fmtSQuoteOpen) - self.btnSQuoteOpen = NIconToolButton(self, iSz, "quote") + self.btnSQuoteOpen = NIconToolButton(self, iSz, "quote", "tool") self.btnSQuoteOpen.clicked.connect(self._changeSingleQuoteOpen) self.mainForm.addRow( self.tr("Single quote open style"), self.fmtSQuoteOpen, @@ -821,7 +823,7 @@ class GuiPreferences(NDialog): self.fmtSQuoteClose.setFixedWidth(boxFixed) self.fmtSQuoteClose.setAlignment(QtAlignCenter) self.fmtSQuoteClose.setText(CONFIG.fmtSQuoteClose) - self.btnSQuoteClose = NIconToolButton(self, iSz, "quote") + self.btnSQuoteClose = NIconToolButton(self, iSz, "quote", "tool") self.btnSQuoteClose.clicked.connect(self._changeSingleQuoteClose) self.mainForm.addRow( self.tr("Single quote close style"), self.fmtSQuoteClose, @@ -836,7 +838,7 @@ class GuiPreferences(NDialog): self.fmtDQuoteOpen.setFixedWidth(boxFixed) self.fmtDQuoteOpen.setAlignment(QtAlignCenter) self.fmtDQuoteOpen.setText(CONFIG.fmtDQuoteOpen) - self.btnDQuoteOpen = NIconToolButton(self, iSz, "quote") + self.btnDQuoteOpen = NIconToolButton(self, iSz, "quote", "tool") self.btnDQuoteOpen.clicked.connect(self._changeDoubleQuoteOpen) self.mainForm.addRow( self.tr("Double quote open style"), self.fmtDQuoteOpen, @@ -850,7 +852,7 @@ class GuiPreferences(NDialog): self.fmtDQuoteClose.setFixedWidth(boxFixed) self.fmtDQuoteClose.setAlignment(QtAlignCenter) self.fmtDQuoteClose.setText(CONFIG.fmtDQuoteClose) - self.btnDQuoteClose = NIconToolButton(self, iSz, "quote") + self.btnDQuoteClose = NIconToolButton(self, iSz, "quote", "tool") self.btnDQuoteClose.clicked.connect(self._changeDoubleQuoteClose) self.mainForm.addRow( self.tr("Double quote close style"), self.fmtDQuoteClose, diff --git a/novelwriter/dialogs/projectsettings.py b/novelwriter/dialogs/projectsettings.py index 31af45a5..16a4a865 100644 --- a/novelwriter/dialogs/projectsettings.py +++ b/novelwriter/dialogs/projectsettings.py @@ -356,27 +356,27 @@ class _StatusPage(NFixedPage): self._addItem(key, StatusEntry.duplicate(entry)) # List Controls - self.addButton = NIconToolButton(self, iSz, "add", "green") + self.addButton = NIconToolButton(self, iSz, "add", "add") self.addButton.setToolTip(self.tr("Add Label")) self.addButton.clicked.connect(self._onItemCreate) - self.delButton = NIconToolButton(self, iSz, "remove", "red") + self.delButton = NIconToolButton(self, iSz, "remove", "remove") self.delButton.setToolTip(self.tr("Delete Label")) self.delButton.clicked.connect(self._onItemDelete) - self.upButton = NIconToolButton(self, iSz, "chevron_up", "blue") + self.upButton = NIconToolButton(self, iSz, "chevron_up", "action") self.upButton.setToolTip(self.tr("Move Up")) self.upButton.clicked.connect(qtLambda(self._moveItem, -1)) - self.downButton = NIconToolButton(self, iSz, "chevron_down", "blue") + self.downButton = NIconToolButton(self, iSz, "chevron_down", "action") self.downButton.setToolTip(self.tr("Move Down")) self.downButton.clicked.connect(qtLambda(self._moveItem, 1)) - self.importButton = NIconToolButton(self, iSz, "import", "green") + self.importButton = NIconToolButton(self, iSz, "import", "apply") self.importButton.setToolTip(self.tr("Import Labels")) self.importButton.clicked.connect(self._importLabels) - self.exportButton = NIconToolButton(self, iSz, "export", "blue") + self.exportButton = NIconToolButton(self, iSz, "export", "action") self.exportButton.setToolTip(self.tr("Export Labels")) self.exportButton.clicked.connect(self._exportLabels) @@ -729,10 +729,10 @@ class _ReplacePage(NFixedPage): self.listBox.setSortingEnabled(True) # List Controls - self.addButton = NIconToolButton(self, iSz, "add", "green") + self.addButton = NIconToolButton(self, iSz, "add", "add") self.addButton.clicked.connect(self._onEntryCreated) - self.delButton = NIconToolButton(self, iSz, "remove", "red") + self.delButton = NIconToolButton(self, iSz, "remove", "remove") self.delButton.clicked.connect(self._onEntryDeleted) # Edit Form diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index a2f60b91..927d6f21 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -75,11 +75,11 @@ class GuiWordList(NDialog): scale=NColorLabel.HEADER_SCALE ) - self.importButton = NIconToolButton(self, iSz, "import", "green") + self.importButton = NIconToolButton(self, iSz, "import", "apply") self.importButton.setToolTip(self.tr("Import words from text file")) self.importButton.clicked.connect(self._importWords) - self.exportButton = NIconToolButton(self, iSz, "export", "blue") + self.exportButton = NIconToolButton(self, iSz, "export", "action") self.exportButton.setToolTip(self.tr("Export words to text file")) self.exportButton.clicked.connect(self._exportWords) @@ -97,11 +97,11 @@ class GuiWordList(NDialog): # Add/Remove Form self.newEntry = QLineEdit(self) - self.addButton = NIconToolButton(self, iSz, "add", "green") + self.addButton = NIconToolButton(self, iSz, "add", "add") self.addButton.setToolTip(self.tr("Add Word")) self.addButton.clicked.connect(self._doAdd) - self.delButton = NIconToolButton(self, iSz, "remove", "red") + self.delButton = NIconToolButton(self, iSz, "remove", "remove") self.delButton.setToolTip(self.tr("Remove Word")) self.delButton.clicked.connect(self._doDelete) diff --git a/novelwriter/extensions/modified.py b/novelwriter/extensions/modified.py index 054665ce..d6a01b44 100644 --- a/novelwriter/extensions/modified.py +++ b/novelwriter/extensions/modified.py @@ -220,7 +220,7 @@ class NPushButton(QPushButton): def updateIcon(self) -> None: """Update the theme icon.""" - if self._icon: + if self._icon and self._color: self.setIcon(SHARED.theme.getIcon(self._icon, self._color)) @@ -238,10 +238,10 @@ class NIconToolButton(QToolButton): self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) self.setIconSize(iconSize) self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) - if icon: + if icon and color: self.setThemeIcon(icon, color) - def setThemeIcon(self, icon: str, color: str | None = None) -> None: + def setThemeIcon(self, icon: str, color: str) -> None: """Set an icon from the current theme.""" self.setIcon(SHARED.theme.getIcon(icon, color)) @@ -252,20 +252,23 @@ class NIconToggleButton(QToolButton): A quicker way to create a toggle button using the app theme. """ - def __init__(self, parent: QWidget, iconSize: QSize, icon: str | None = None) -> None: + def __init__( + self, parent: QWidget, iconSize: QSize, + icon: str | None = None, color: str | None = None + ) -> None: super().__init__(parent=parent) self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) self.setIconSize(iconSize) self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) self.setCheckable(True) self.setStyleSheet("border: none; background: transparent;") - if icon: - self.setThemeIcon(icon) + if icon and color: + self.setThemeIcon(icon, color) - def setThemeIcon(self, icon: str) -> None: + def setThemeIcon(self, icon: str, color: str) -> None: """Set an icon from the current theme.""" size = self.iconSize() - self.setIcon(SHARED.theme.getToggleIcon(icon, (size.width(), size.height()))) + self.setIcon(SHARED.theme.getToggleIcon(icon, (size.width(), size.height()), color)) class NClickableLabel(QLabel): diff --git a/novelwriter/extensions/novelselector.py b/novelwriter/extensions/novelselector.py index 27d217c6..64513378 100644 --- a/novelwriter/extensions/novelselector.py +++ b/novelwriter/extensions/novelselector.py @@ -110,7 +110,7 @@ class NovelSelector(QComboBox): self._firstHandle = None self.clear() - icon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL], "blue") + icon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL], "root") for tHandle, nwItem in SHARED.project.tree.iterRoots(nwItemClass.NOVEL): if self._listFormat: name = self._listFormat.format(nwItem.itemName) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index d7a96765..fc05f063 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2489,17 +2489,17 @@ class GuiDocToolBar(QWidget): palette.setColor(QPalette.ColorRole.Text, syntax.text) self.setPalette(palette) - self.tbBoldMD.setThemeIcon("fmt_bold", "orange") - self.tbItalicMD.setThemeIcon("fmt_italic", "orange") - self.tbStrikeMD.setThemeIcon("fmt_strike", "orange") - self.tbMarkMD.setThemeIcon("fmt_mark", "orange") - self.tbBold.setThemeIcon("fmt_bold") - self.tbItalic.setThemeIcon("fmt_italic") - self.tbStrike.setThemeIcon("fmt_strike") - self.tbUnderline.setThemeIcon("fmt_underline") - self.tbMark.setThemeIcon("fmt_mark") - self.tbSuperscript.setThemeIcon("fmt_superscript") - self.tbSubscript.setThemeIcon("fmt_subscript") + self.tbBoldMD.setThemeIcon("fmt_bold", "mdformat") + self.tbItalicMD.setThemeIcon("fmt_italic", "mdformat") + self.tbStrikeMD.setThemeIcon("fmt_strike", "mdformat") + self.tbMarkMD.setThemeIcon("fmt_mark", "mdformat") + self.tbBold.setThemeIcon("fmt_bold", "scformat") + self.tbItalic.setThemeIcon("fmt_italic", "scformat") + self.tbStrike.setThemeIcon("fmt_strike", "scformat") + self.tbUnderline.setThemeIcon("fmt_underline", "scformat") + self.tbMark.setThemeIcon("fmt_mark", "scformat") + self.tbSuperscript.setThemeIcon("fmt_superscript", "scformat") + self.tbSubscript.setThemeIcon("fmt_subscript", "scformat") class GuiDocEditSearch(QFrame): @@ -2727,16 +2727,16 @@ class GuiDocEditSearch(QFrame): self.replaceBox.setPalette(palette) # Set icons - self.toggleCase.setIcon(SHARED.theme.getIcon("search_case")) - self.toggleWord.setIcon(SHARED.theme.getIcon("search_word")) - self.toggleRegEx.setIcon(SHARED.theme.getIcon("search_regex")) - self.toggleLoop.setIcon(SHARED.theme.getIcon("search_loop")) - self.toggleProject.setIcon(SHARED.theme.getIcon("search_project")) - self.toggleMatchCap.setIcon(SHARED.theme.getIcon("search_preserve")) - self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel")) - self.searchButton.setThemeIcon("search", "green") - self.replaceButton.setThemeIcon("search_replace", "green") - self.showReplace.setThemeIcon("unfold") + self.toggleCase.setIcon(SHARED.theme.getIcon("search_case", "tool")) + self.toggleWord.setIcon(SHARED.theme.getIcon("search_word", "tool")) + self.toggleRegEx.setIcon(SHARED.theme.getIcon("search_regex", "tool")) + self.toggleLoop.setIcon(SHARED.theme.getIcon("search_loop", "tool")) + self.toggleProject.setIcon(SHARED.theme.getIcon("search_project", "tool")) + self.toggleMatchCap.setIcon(SHARED.theme.getIcon("search_preserve", "tool")) + self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel", "tool")) + self.searchButton.setThemeIcon("search", "action") + self.replaceButton.setThemeIcon("search_replace", "apply") + self.showReplace.setThemeIcon("unfold", "default") # Set stylesheets self.searchOpt.setStyleSheet("QToolBar {padding: 0;}") @@ -2967,11 +2967,11 @@ class GuiDocEditHeader(QWidget): """Update theme elements.""" logger.debug("Theme Update: GuiDocEditHeader") - self.tbButton.setThemeIcon("fmt_toolbar", "blue") - self.outlineButton.setThemeIcon("list", "blue") - self.searchButton.setThemeIcon("search", "blue") - self.minmaxButton.setThemeIcon("maximise", "blue") - self.closeButton.setThemeIcon("close", "red") + self.tbButton.setThemeIcon("fmt_toolbar", "action") + self.outlineButton.setThemeIcon("list", "action") + self.searchButton.setThemeIcon("search", "action") + self.minmaxButton.setThemeIcon("maximise", "action") + self.closeButton.setThemeIcon("close", "reject") buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) self.tbButton.setStyleSheet(buttonStyle) @@ -3037,7 +3037,7 @@ class GuiDocEditHeader(QWidget): @pyqtSlot(bool) def _focusModeChanged(self, focusMode: bool) -> None: """Update minimise/maximise icon of the Focus Mode button.""" - self.minmaxButton.setThemeIcon("minimise" if focusMode else "maximise", "blue") + self.minmaxButton.setThemeIcon("minimise" if focusMode else "maximise", "action") ## # Events diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 5cd44e27..b9dcb3d6 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -727,12 +727,12 @@ class GuiDocViewHeader(QWidget): """Update theme elements.""" logger.debug("Theme Update: GuiDocViewHeader") - self.outlineButton.setThemeIcon("list", "blue") - self.backButton.setThemeIcon("chevron_left", "blue") - self.forwardButton.setThemeIcon("chevron_right", "blue") - self.editButton.setThemeIcon("edit", "green") - self.refreshButton.setThemeIcon("refresh", "green") - self.closeButton.setThemeIcon("close", "red") + self.outlineButton.setThemeIcon("list", "action") + self.backButton.setThemeIcon("chevron_left", "action") + self.forwardButton.setThemeIcon("chevron_right", "action") + self.editButton.setThemeIcon("edit", "change") + self.refreshButton.setThemeIcon("refresh", "change") + self.closeButton.setThemeIcon("close", "reject") buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) self.outlineButton.setStyleSheet(buttonStyle) @@ -916,9 +916,9 @@ class GuiDocViewFooter(QWidget): logger.debug("Theme Update: GuiDocViewFooter") fPx = int(0.9*SHARED.theme.fontPixelSize) - bulletIcon = SHARED.theme.getToggleIcon("bullet", (fPx, fPx), "blue") + bulletIcon = SHARED.theme.getToggleIcon("bullet", (fPx, fPx), "action") - self.showHide.setThemeIcon("panel") + self.showHide.setThemeIcon("panel", "default") self.showComments.setIcon(bulletIcon) self.showSynopsis.setIcon(bulletIcon) self.showNotes.setIcon(bulletIcon) diff --git a/novelwriter/gui/docviewerpanel.py b/novelwriter/gui/docviewerpanel.py index 9f3fd209..fed0e4a3 100644 --- a/novelwriter/gui/docviewerpanel.py +++ b/novelwriter/gui/docviewerpanel.py @@ -108,7 +108,7 @@ class GuiDocViewerPanel(QWidget): """Update theme elements.""" logger.debug("Theme Update: GuiDocViewerPanel") - self.optsButton.setThemeIcon("more_vertical") + self.optsButton.setThemeIcon("more_vertical", "default") self.optsButton.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)) self.mainTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS)) if updateTabs: @@ -263,8 +263,8 @@ class _ViewPanelBackRefs(QTreeWidget): header.setSectionsMovable(False) # Cache Icons Locally - self._editIcon = SHARED.theme.getIcon("edit", "green") - self._viewIcon = SHARED.theme.getIcon("view", "blue") + self._editIcon = SHARED.theme.getIcon("edit", "change") + self._viewIcon = SHARED.theme.getIcon("view", "action") # Signals self.clicked.connect(self._treeItemClicked) @@ -274,8 +274,8 @@ class _ViewPanelBackRefs(QTreeWidget): """Update theme elements.""" logger.debug("Theme Update: _ViewPanelBackRefs") - self._editIcon = SHARED.theme.getIcon("edit", "green") - self._viewIcon = SHARED.theme.getIcon("view", "blue") + self._editIcon = SHARED.theme.getIcon("edit", "change") + self._viewIcon = SHARED.theme.getIcon("view", "action") for i in range(self.topLevelItemCount()): if item := self.topLevelItem(i): item.setIcon(self.C_EDIT, self._editIcon) @@ -407,8 +407,8 @@ class _ViewPanelKeyWords(QTreeWidget): logger.debug("Theme Update: _ViewPanelKeyWords") self._classIcon = SHARED.theme.getIcon(nwLabels.CLASS_ICON[self._class], "root") - self._editIcon = SHARED.theme.getIcon("edit", "green") - self._viewIcon = SHARED.theme.getIcon("view", "blue") + self._editIcon = SHARED.theme.getIcon("edit", "change") + self._viewIcon = SHARED.theme.getIcon("view", "action") def countEntries(self) -> int: """Return the number of items in the list.""" diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index feb5e703..25b9cb9e 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -247,9 +247,9 @@ class GuiNovelToolBar(QWidget): """Update theme elements.""" logger.debug("Theme Update: GuiNovelToolBar") - self.tbNovel.setThemeIcon("cls_novel", "red") - self.tbRefresh.setThemeIcon("refresh", "green") - self.tbMore.setThemeIcon("more_vertical") + self.tbNovel.setThemeIcon("cls_novel", "root") + self.tbRefresh.setThemeIcon("refresh", "change") + self.tbMore.setThemeIcon("more_vertical", "default") buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) self.tbNovel.setStyleSheet(buttonStyle) diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 3a97ec35..1bc185a7 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -264,9 +264,9 @@ class GuiOutlineToolBar(QToolBar): self.setStyleSheet("QToolBar {border: 0px;}") self.novelValue.refreshNovelList() - self.aRefresh.setIcon(SHARED.theme.getIcon("refresh", "green")) - self.aExport.setIcon(SHARED.theme.getIcon("export", "blue")) - self.tbColumns.setIcon(SHARED.theme.getIcon("more_vertical")) + self.aRefresh.setIcon(SHARED.theme.getIcon("refresh", "change")) + self.aExport.setIcon(SHARED.theme.getIcon("export", "action")) + self.tbColumns.setIcon(SHARED.theme.getIcon("more_vertical", "default")) self.tbColumns.setStyleSheet("QToolButton::menu-indicator {image: none;}") self.novelLabel.setTextColors(color=self.palette().windowText().color()) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 758b15cd..de427a1d 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -356,11 +356,11 @@ class GuiProjectToolBar(QWidget): self.tbAdd.setStyleSheet(buttonStyle) self.tbMore.setStyleSheet(buttonStyle) - self.tbQuick.setThemeIcon("bookmarks", "blue") - self.tbMoveU.setThemeIcon("chevron_up", "blue") - self.tbMoveD.setThemeIcon("chevron_down", "blue") - self.tbAdd.setThemeIcon("add", "green") - self.tbMore.setThemeIcon("more_vertical") + self.tbQuick.setThemeIcon("bookmarks", "action") + self.tbMoveU.setThemeIcon("chevron_up", "action") + self.tbMoveD.setThemeIcon("chevron_down", "action") + self.tbAdd.setThemeIcon("add", "add") + self.tbMore.setThemeIcon("more_vertical", "default") self.aAddScene.setIcon(SHARED.theme.getIcon("prj_scene", "scene")) self.aAddChap.setIcon(SHARED.theme.getIcon("prj_chapter", "chapter")) @@ -1183,10 +1183,10 @@ class _TreeContextMenu(QMenu): if len(self._indices) > 1: mSub = qtAddMenu(self, self.tr("Set Active to ...")) aOne = qtAddAction(mSub, self._tree.trActive) - aOne.setIcon(SHARED.theme.getIcon("checked", "green")) + aOne.setIcon(SHARED.theme.getIcon("checked", "accept")) aOne.triggered.connect(qtLambda(self._iterItemActive, True)) aTwo = qtAddAction(mSub, self._tree.trInactive) - aTwo.setIcon(SHARED.theme.getIcon("unchecked", "red")) + aTwo.setIcon(SHARED.theme.getIcon("unchecked", "reject")) aTwo.triggered.connect(qtLambda(self._iterItemActive, False)) else: action = qtAddAction(self, self.tr("Toggle Active")) diff --git a/novelwriter/gui/search.py b/novelwriter/gui/search.py index e49770b3..1571591b 100644 --- a/novelwriter/gui/search.py +++ b/novelwriter/gui/search.py @@ -107,7 +107,7 @@ class GuiProjectSearch(QWidget): # Search Box self.searchAction = QAction("", self) - self.searchAction.setIcon(SHARED.theme.getIcon("search", "blue")) + self.searchAction.setIcon(SHARED.theme.getIcon("search", "apply")) self.searchAction.triggered.connect(self._processSearch) self.searchText = QLineEdit(self) @@ -170,10 +170,10 @@ class GuiProjectSearch(QWidget): f"QLineEdit:focus {{border: 1px solid {colFocus};}} " ) - self.searchAction.setIcon(SHARED.theme.getIcon("search", "blue")) - self.toggleCase.setIcon(SHARED.theme.getIcon("search_case")) - self.toggleWord.setIcon(SHARED.theme.getIcon("search_word")) - self.toggleRegEx.setIcon(SHARED.theme.getIcon("search_regex")) + self.searchAction.setIcon(SHARED.theme.getIcon("search", "apply")) + self.toggleCase.setIcon(SHARED.theme.getIcon("search_case", "tool")) + self.toggleWord.setIcon(SHARED.theme.getIcon("search_word", "tool")) + self.toggleRegEx.setIcon(SHARED.theme.getIcon("search_regex", "tool")) def processReturn(self) -> None: """Process a return keypress forwarded from the main GUI.""" diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py index 8e6acfd3..5aceb0d5 100644 --- a/novelwriter/gui/sidebar.py +++ b/novelwriter/gui/sidebar.py @@ -142,14 +142,14 @@ class GuiSideBar(QWidget): self.tbTheme.setStyleSheet(buttonStyle) self.tbSettings.setStyleSheet(buttonStyle) - self.tbProject.setThemeIcon("sb_project") - self.tbNovel.setThemeIcon("sb_novel") - self.tbSearch.setThemeIcon("sb_search") - self.tbOutline.setThemeIcon("sb_outline") - self.tbBuild.setThemeIcon("sb_build") - self.tbDetails.setThemeIcon("sb_details") - self.tbStats.setThemeIcon("sb_stats") - self.tbSettings.setThemeIcon("settings") + self.tbProject.setThemeIcon("sb_project", "default") + self.tbNovel.setThemeIcon("sb_novel", "default") + self.tbSearch.setThemeIcon("sb_search", "default") + self.tbOutline.setThemeIcon("sb_outline", "default") + self.tbBuild.setThemeIcon("sb_build", "default") + self.tbDetails.setThemeIcon("sb_details", "default") + self.tbStats.setThemeIcon("sb_stats", "default") + self.tbSettings.setThemeIcon("settings", "default") self._setThemeModeIcon() @@ -176,7 +176,7 @@ class GuiSideBar(QWidget): def _setThemeModeIcon(self) -> None: """Set the theme button icon.""" - self.tbTheme.setThemeIcon(nwLabels.THEME_MODE_ICON[CONFIG.themeMode]) + self.tbTheme.setThemeIcon(nwLabels.THEME_MODE_ICON[CONFIG.themeMode], "default") self.tbTheme.setToolTip(trConst(nwLabels.THEME_MODE_LABEL[CONFIG.themeMode])) diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index 407e87a9..8f92304d 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -57,23 +57,23 @@ STYLES_MIN_TOOLBUTTON = "minimalToolButton" STYLES_BIG_TOOLBUTTON = "bigToolButton" STANDARD_BUTTONS = { - nwStandardButton.OK: (QT_TRANSLATE_NOOP("Button", "OK"), "btn_ok", "blue"), - nwStandardButton.CANCEL: (QT_TRANSLATE_NOOP("Button", "Cancel"), "btn_cancel", "red"), - nwStandardButton.YES: (QT_TRANSLATE_NOOP("Button", "&Yes"), "btn_yes", "green"), - nwStandardButton.NO: (QT_TRANSLATE_NOOP("Button", "&No"), "btn_no", "red"), - nwStandardButton.OPEN: (QT_TRANSLATE_NOOP("Button", "Open"), "btn_open", "blue"), - nwStandardButton.CLOSE: (QT_TRANSLATE_NOOP("Button", "Close"), "btn_close", "faded"), - nwStandardButton.SAVE: (QT_TRANSLATE_NOOP("Button", "Save"), "btn_save", "blue"), - nwStandardButton.BROWSE: (QT_TRANSLATE_NOOP("Button", "Browse"), "btn_browse", "yellow"), - nwStandardButton.LIST: (QT_TRANSLATE_NOOP("Button", "List"), "btn_list", "blue"), - nwStandardButton.NEW: (QT_TRANSLATE_NOOP("Button", "New"), "btn_new", "green"), - nwStandardButton.CREATE: (QT_TRANSLATE_NOOP("Button", "Create"), "btn_create", "yellow"), - nwStandardButton.RESET: (QT_TRANSLATE_NOOP("Button", "Reset"), "btn_reset", "green"), - nwStandardButton.INSERT: (QT_TRANSLATE_NOOP("Button", "Insert"), "btn_insert", "blue"), - nwStandardButton.APPLY: (QT_TRANSLATE_NOOP("Button", "Apply"), "btn_apply", "blue"), - nwStandardButton.BUILD: (QT_TRANSLATE_NOOP("Button", "Build"), "btn_build", "blue"), - nwStandardButton.PRINT: (QT_TRANSLATE_NOOP("Button", "Print"), "btn_print", "blue"), - nwStandardButton.PREVIEW: (QT_TRANSLATE_NOOP("Button", "Preview"), "btn_preview", "blue"), + nwStandardButton.OK: (QT_TRANSLATE_NOOP("Button", "OK"), "btn_ok", "action"), + nwStandardButton.CANCEL: (QT_TRANSLATE_NOOP("Button", "Cancel"), "btn_cancel", "reject"), + nwStandardButton.YES: (QT_TRANSLATE_NOOP("Button", "&Yes"), "btn_yes", "accept"), + nwStandardButton.NO: (QT_TRANSLATE_NOOP("Button", "&No"), "btn_no", "reject"), + nwStandardButton.OPEN: (QT_TRANSLATE_NOOP("Button", "Open"), "btn_open", "action"), + nwStandardButton.CLOSE: (QT_TRANSLATE_NOOP("Button", "Close"), "btn_close", "destroy"), + nwStandardButton.SAVE: (QT_TRANSLATE_NOOP("Button", "Save"), "btn_save", "action"), + nwStandardButton.BROWSE: (QT_TRANSLATE_NOOP("Button", "Browse"), "btn_browse", "systemio"), + nwStandardButton.LIST: (QT_TRANSLATE_NOOP("Button", "List"), "btn_list", "action"), + nwStandardButton.NEW: (QT_TRANSLATE_NOOP("Button", "New"), "btn_new", "apply"), + nwStandardButton.CREATE: (QT_TRANSLATE_NOOP("Button", "Create"), "btn_create", "create"), + nwStandardButton.RESET: (QT_TRANSLATE_NOOP("Button", "Reset"), "btn_reset", "reset"), + nwStandardButton.INSERT: (QT_TRANSLATE_NOOP("Button", "Insert"), "btn_insert", "action"), + nwStandardButton.APPLY: (QT_TRANSLATE_NOOP("Button", "Apply"), "btn_apply", "apply"), + nwStandardButton.BUILD: (QT_TRANSLATE_NOOP("Button", "Build"), "btn_build", "action"), + nwStandardButton.PRINT: (QT_TRANSLATE_NOOP("Button", "Print"), "btn_print", "action"), + nwStandardButton.PREVIEW: (QT_TRANSLATE_NOOP("Button", "Preview"), "btn_preview", "action"), } @@ -357,6 +357,28 @@ class GuiTheme: self._setBaseColor("inactive", self._readColor(parser, sec, "inactive")) self._setBaseColor("disabled", self._readColor(parser, sec, "disabled")) + # Icon + sec = "Icon" + if parser.has_section(sec): + self._setBaseColor("tool", self._readColor(parser, sec, "tool")) + self._setBaseColor("accept", self._readColor(parser, sec, "accept")) + self._setBaseColor("reject", self._readColor(parser, sec, "reject")) + self._setBaseColor("action", self._readColor(parser, sec, "action")) + self._setBaseColor("altaction", self._readColor(parser, sec, "altaction")) + self._setBaseColor("apply", self._readColor(parser, sec, "apply")) + self._setBaseColor("create", self._readColor(parser, sec, "create")) + self._setBaseColor("destroy", self._readColor(parser, sec, "destroy")) + self._setBaseColor("reset", self._readColor(parser, sec, "reset")) + self._setBaseColor("add", self._readColor(parser, sec, "add")) + self._setBaseColor("change", self._readColor(parser, sec, "change")) + self._setBaseColor("remove", self._readColor(parser, sec, "remove")) + self._setBaseColor("scformat", self._readColor(parser, sec, "scformat")) + self._setBaseColor("mdformat", self._readColor(parser, sec, "mdformat")) + self._setBaseColor("systemio", self._readColor(parser, sec, "systemio")) + self._setBaseColor("info", self._readColor(parser, sec, "info")) + self._setBaseColor("warning", self._readColor(parser, sec, "warning")) + self._setBaseColor("error", self._readColor(parser, sec, "error")) + # Palette sec = "Palette" if parser.has_section(sec): @@ -767,7 +789,7 @@ class GuiIcons: # Access Functions ## - def getIcon(self, name: str, color: str | None = None, w: int = 24, h: int = 24) -> QIcon: + def getIcon(self, name: str, color: str, w: int = 24, h: int = 24) -> QIcon: """Return an icon from the icon buffer, or load it.""" variant = f"{name}-{color}" if color else name if (key := f"{variant}-{w}x{h}") in self._qIcons: @@ -778,7 +800,7 @@ class GuiIcons: logger.debug("Icon: %s", key) return icon - def getToggleIcon(self, name: str, size: tuple[int, int], color: str | None = None) -> QIcon: + def getToggleIcon(self, name: str, size: tuple[int, int], color: str) -> QIcon: """Return a toggle icon from the icon buffer, or load it.""" if name in self.TOGGLE_ICON_KEYS: pOne = self.getPixmap(self.TOGGLE_ICON_KEYS[name][0], size, color) @@ -830,7 +852,7 @@ class GuiIcons: doesn't exist, return an empty QPixmap. """ w, h = size - return self.getIcon(name, color, w, h).pixmap(w, h, QIcon.Mode.Normal) + return self.getIcon(name, color or "default", w, h).pixmap(w, h, QIcon.Mode.Normal) def getStandardButton(self, button: nwStandardButton, parent: QWidget) -> NPushButton: """Return a standard button with icon and text.""" diff --git a/novelwriter/shared.py b/novelwriter/shared.py index b76ad165..eacf2298 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -514,16 +514,16 @@ class _GuiAlert(QMessageBox): pSz = 2*self._theme.baseIconHeight if level == self.INFO: - self.setIconPixmap(self._theme.getPixmap("alert_info", (pSz, pSz), "blue")) + self.setIconPixmap(self._theme.getPixmap("alert_info", (pSz, pSz), "info")) self.setWindowTitle(self.tr("Information")) elif level == self.WARN: - self.setIconPixmap(self._theme.getPixmap("alert_warn", (pSz, pSz), "orange")) + self.setIconPixmap(self._theme.getPixmap("alert_warn", (pSz, pSz), "warning")) self.setWindowTitle(self.tr("Warning")) elif level == self.ERROR: - self.setIconPixmap(self._theme.getPixmap("alert_error", (pSz, pSz), "red")) + self.setIconPixmap(self._theme.getPixmap("alert_error", (pSz, pSz), "error")) self.setWindowTitle(self.tr("Error")) elif level == self.ASK: - self.setIconPixmap(self._theme.getPixmap("alert_question", (pSz, pSz), "blue")) + self.setIconPixmap(self._theme.getPixmap("alert_question", (pSz, pSz), "info")) self.setWindowTitle(self.tr("Question")) @pyqtSlot() diff --git a/novelwriter/tools/dictionaries.py b/novelwriter/tools/dictionaries.py index bd19b78d..9195b49a 100644 --- a/novelwriter/tools/dictionaries.py +++ b/novelwriter/tools/dictionaries.py @@ -79,10 +79,10 @@ class GuiDictionaries(NNonBlockingDialog): self.huInfo.setOpenExternalLinks(True) self.huInfo.setWordWrap(True) self.huInput = QLineEdit(self) - self.huBrowse = NIconToolButton(self, iSz, "browse") + self.huBrowse = NIconToolButton(self, iSz, "browse", "systemio") self.huBrowse.clicked.connect(self._doBrowseHunspell) self.huImport = QPushButton(self.tr("Add Dictionary"), self) - self.huImport.setIcon(SHARED.theme.getIcon("add", "green")) + self.huImport.setIcon(SHARED.theme.getIcon("add", "add")) self.huImport.clicked.connect(self._doImportHunspell) self.huPathBox = QHBoxLayout() @@ -97,7 +97,7 @@ class GuiDictionaries(NNonBlockingDialog): self.inInfo = QLabel(self.tr("Dictionary install location"), self) self.inPath = QLineEdit(self) self.inPath.setReadOnly(True) - self.inBrowse = NIconToolButton(self, iSz, "browse") + self.inBrowse = NIconToolButton(self, iSz, "browse", "systemio") self.inBrowse.clicked.connect(self._doOpenInstallLocation) self.inBox = QHBoxLayout() diff --git a/novelwriter/tools/lipsum.py b/novelwriter/tools/lipsum.py index 3cd2fea7..55119317 100644 --- a/novelwriter/tools/lipsum.py +++ b/novelwriter/tools/lipsum.py @@ -59,7 +59,7 @@ class GuiLipsum(NDialog): # Icon self.docIcon = QLabel(self) - self.docIcon.setPixmap(SHARED.theme.getPixmap("text", (64, 64), "blue")) + self.docIcon.setPixmap(SHARED.theme.getPixmap("text", (64, 64), "info")) self.leftBox = QVBoxLayout() self.leftBox.setSpacing(4) diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index ffbef09d..5520982d 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -43,7 +43,7 @@ from novelwriter.core.item import NWItem from novelwriter.enum import nwBuildFmt, nwStandardButton from novelwriter.extensions.modified import NDialog, NIconToolButton, NPushButton from novelwriter.extensions.progressbars import NProgressSimple -from novelwriter.types import QtAlignCenter, QtRoleAction, QtRoleDestruct, QtRoleReject, QtUserRole +from novelwriter.types import QtAlignCenter, QtRoleAction, QtRoleDestruct, QtUserRole if TYPE_CHECKING: from PyQt6.QtGui import QCloseEvent @@ -143,7 +143,7 @@ class GuiManuscriptBuild(NDialog): # Build Path self.lblPath = QLabel(self.tr("Path"), self) self.buildPath = QLineEdit(self) - self.btnBrowse = NIconToolButton(self, iSz, "browse") + self.btnBrowse = NIconToolButton(self, iSz, "browse", "systemio") self.pathBox = QHBoxLayout() self.pathBox.addWidget(self.buildPath) @@ -153,7 +153,7 @@ class GuiManuscriptBuild(NDialog): # Build Name self.lblName = QLabel(self.tr("File Name"), self) self.buildName = QLineEdit(self) - self.btnReset = NIconToolButton(self, iSz, "revert", "green") + self.btnReset = NIconToolButton(self, iSz, "revert", "reset") self.btnReset.setToolTip(self.tr("Reset file name to default")) self.nameBox = QHBoxLayout() @@ -178,7 +178,7 @@ class GuiManuscriptBuild(NDialog): self.buildBox.setVerticalSpacing(4) # Dialog Buttons - self.btnOpen = NPushButton(self, self.tr("Open Folder"), bSz, "browse", "yellow") + self.btnOpen = NPushButton(self, self.tr("Open Folder"), bSz, "browse", "systemio") self.btnOpen.setAutoDefault(False) self.btnBuild = SHARED.theme.getStandardButton(nwStandardButton.BUILD, self) @@ -260,13 +260,11 @@ class GuiManuscriptBuild(NDialog): @pyqtSlot("QAbstractButton*") def _dialogButtonClicked(self, button: QAbstractButton) -> None: """Handle button clicks from the dialog button box.""" - role = self.btnBox.buttonRole(button) - if role == QtRoleAction: - if button == self.btnBuild: - self._runBuild() - elif button == self.btnOpen: - self._openOutputFolder() - elif role == QtRoleReject: + if button == self.btnBuild: + self._runBuild() + elif button == self.btnOpen: + self._openOutputFolder() + elif button == self.btnClose: self.close() @pyqtSlot() diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index e3c5679b..5bf30983 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -271,10 +271,10 @@ class GuiManuscript(NToolDialog): self.btnBuild.updateIcon() self.btnClose.updateIcon() - self.tbAdd.setThemeIcon("add", "green") - self.tbDel.setThemeIcon("remove", "red") - self.tbCopy.setThemeIcon("copy", "blue") - self.tbEdit.setThemeIcon("edit", "green") + self.tbAdd.setThemeIcon("add", "add") + self.tbDel.setThemeIcon("remove", "remove") + self.tbCopy.setThemeIcon("copy", "accept") + self.tbEdit.setThemeIcon("edit", "change") buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) self.tbAdd.setStyleSheet(buttonStyle) @@ -484,7 +484,7 @@ class GuiManuscript(NToolDialog): for key, name in self._builds.builds(): bItem = QListWidgetItem() bItem.setText(name) - bItem.setIcon(SHARED.theme.getIcon("build_settings", "blue")) + bItem.setIcon(SHARED.theme.getIcon("build_settings", "action")) bItem.setData(self.D_KEY, key) self.buildList.addItem(bItem) self._buildMap[key] = bItem @@ -574,8 +574,8 @@ class _DetailsWidget(QWidget): self.listView.clear() - on = SHARED.theme.getIcon("bullet-on", "blue") - off = SHARED.theme.getIcon("bullet-off", "blue") + on = SHARED.theme.getIcon("bullet-on", "action") + off = SHARED.theme.getIcon("bullet-off", "action") # Name item = QTreeWidgetItem() @@ -991,7 +991,7 @@ class _StatsWidget(QWidget): def updateTheme(self) -> None: """Update theme elements.""" logger.debug("Theme Update: _StatsWidget") - self.toggleButton.setThemeIcon("unfold") + self.toggleButton.setThemeIcon("unfold", "default") ## # Private Slots diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 7f00f6ff..35fe49f6 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -52,7 +52,7 @@ from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.types import ( QtAlignCenter, QtAlignLeft, QtHeaderFixed, QtHeaderStretch, QtRoleAccept, - QtRoleApply, QtRoleDestruct, QtRoleReject, QtUserRole + QtRoleApply, QtRoleDestruct, QtUserRole ) if TYPE_CHECKING: @@ -229,15 +229,14 @@ class GuiBuildSettings(NToolDialog): @pyqtSlot("QAbstractButton*") def _dialogButtonClicked(self, button: QAbstractButton) -> None: """Handle button clicks from the dialog button box.""" - role = self.btnBox.buttonRole(button) - if role == QtRoleApply: + if button == self.btnApply: self._applyChanges() self._emitBuildData() - elif role == QtRoleAccept: + elif button == self.btnSave: self._applyChanges() self._emitBuildData() self.close() - elif role == QtRoleReject: + elif button == self.btnClose: self._build.resetChangedState() self.close() @@ -302,9 +301,9 @@ class _FilterTab(NFixedPage): self._statusFlags: dict[int, QIcon] = { self.F_NONE: QIcon(), - self.F_FILTERED: SHARED.theme.getIcon("filter", "orange"), - self.F_INCLUDED: SHARED.theme.getIcon("pin", "blue"), - self.F_EXCLUDED: SHARED.theme.getIcon("exclude", "red"), + self.F_FILTERED: SHARED.theme.getIcon("filter", "altaction"), + self.F_INCLUDED: SHARED.theme.getIcon("pin", "action"), + self.F_EXCLUDED: SHARED.theme.getIcon("exclude", "reject"), } self._trIncluded = self.tr("Included in manuscript") @@ -410,14 +409,14 @@ class _FilterTab(NFixedPage): logger.debug("Theme Update: _FilterTab, init=%s", init) if not init: - self._statusFlags[self.F_FILTERED] = SHARED.theme.getIcon("filter", "orange") - self._statusFlags[self.F_INCLUDED] = SHARED.theme.getIcon("pin", "blue") - self._statusFlags[self.F_EXCLUDED] = SHARED.theme.getIcon("exclude", "red") + self._statusFlags[self.F_FILTERED] = SHARED.theme.getIcon("filter", "altaction") + self._statusFlags[self.F_INCLUDED] = SHARED.theme.getIcon("pin", "action") + self._statusFlags[self.F_EXCLUDED] = SHARED.theme.getIcon("exclude", "reject") self.loadContent() self.includedButton.setIcon(self._statusFlags[self.F_INCLUDED]) self.excludedButton.setIcon(self._statusFlags[self.F_EXCLUDED]) - self.resetButton.setThemeIcon("revert", "green") + self.resetButton.setThemeIcon("revert", "reset") ## # Slots @@ -492,7 +491,7 @@ class _FilterTab(NFixedPage): default=self._build.getBool("filter.includeNotes") ) self.filterOpt.addItem( - SHARED.theme.getIcon("unchecked", "red"), + SHARED.theme.getIcon("unchecked", "reject"), self._build.getLabel("filter.includeInactive"), "doc:filter.includeInactive", default=self._build.getBool("filter.includeInactive") @@ -811,12 +810,12 @@ class _HeadingsTab(NScrollablePage): """Update theme elements.""" logger.debug("Theme Update: _HeadingsTab") - self.btnPart.setThemeIcon("edit", "green") - self.btnChapter.setThemeIcon("edit", "green") - self.btnUnnumbered.setThemeIcon("edit", "green") - self.btnScene.setThemeIcon("edit", "green") - self.btnAScene.setThemeIcon("edit", "green") - self.btnSection.setThemeIcon("edit", "green") + self.btnPart.setThemeIcon("edit", "change") + self.btnChapter.setThemeIcon("edit", "change") + self.btnUnnumbered.setThemeIcon("edit", "change") + self.btnScene.setThemeIcon("edit", "change") + self.btnAScene.setThemeIcon("edit", "change") + self.btnSection.setThemeIcon("edit", "change") self.formSyntax.initHighlighter() self.formSyntax.rehighlight() @@ -1318,9 +1317,9 @@ class _FormattingTab(NScrollableForm): """Update theme elements.""" logger.debug("Theme Update: _FormattingTab") - self.ignoredKeywordsButton.setThemeIcon("add", "green") - self.btnTextFont.setThemeIcon("font") - self.btnPageHeader.setThemeIcon("revert", "green") + self.ignoredKeywordsButton.setThemeIcon("add", "add") + self.btnTextFont.setThemeIcon("font", "tool") + self.btnPageHeader.setThemeIcon("revert", "reset") iPx = SHARED.theme.baseIconHeight self.pixT.setPixmap(SHARED.theme.getPixmap("margin_top", (iPx, iPx))) diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index 041a0031..933ecec1 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -258,7 +258,7 @@ class _OpenProjectPage(QWidget): # Info / Tool self.aMissing = QAction(self) - self.aMissing.setIcon(SHARED.theme.getIcon("alert_warn", "orange")) + self.aMissing.setIcon(SHARED.theme.getIcon("alert_warn", "warning")) self.aMissing.setToolTip(self.tr("The project path is not reachable.")) self.selectedPath = QLineEdit(self) @@ -534,7 +534,7 @@ class _NewProjectForm(QWidget): self.projPath = QLineEdit(self) self.projPath.setReadOnly(True) - self.browsePath = NIconToolButton(self, iSz, "browse") + self.browsePath = NIconToolButton(self, iSz, "browse", "systemio") self.browsePath.clicked.connect(self._doBrowse) self.pathBox = QHBoxLayout() @@ -545,20 +545,20 @@ class _NewProjectForm(QWidget): self.projFill = QLineEdit(self) self.projFill.setReadOnly(True) - self.browseFill = NIconToolButton(self, iSz, "document_add", "blue") + self.browseFill = NIconToolButton(self, iSz, "document_add", "add") self.fillMenu = QMenu(self.browseFill) self.fillBlank = qtAddAction(self.fillMenu, self.tr("Create a fresh project")) - self.fillBlank.setIcon(SHARED.theme.getIcon("document")) + self.fillBlank.setIcon(SHARED.theme.getIcon("document", "file")) self.fillBlank.triggered.connect(self._setFillBlank) self.fillSample = qtAddAction(self.fillMenu, self.tr("Create an example project")) - self.fillSample.setIcon(SHARED.theme.getIcon("document_add", "blue")) + self.fillSample.setIcon(SHARED.theme.getIcon("document_add", "add")) self.fillSample.triggered.connect(self._setFillSample) self.fillCopy = qtAddAction(self.fillMenu, self.tr("Copy an existing project")) - self.fillCopy.setIcon(SHARED.theme.getIcon("project_copy", "green")) + self.fillCopy.setIcon(SHARED.theme.getIcon("project_copy", "action")) self.fillCopy.triggered.connect(self._setFillCopy) self.browseFill.setMenu(self.fillMenu) diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index fea44864..c8034487 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -292,7 +292,7 @@ class GuiWritingStats(NToolDialog): self.saveMenu.addAction(self.saveJSON) self.saveMenu.addAction(self.saveCSV) - self.btnSave = NPushButton(self, self.tr("Save As"), bSz, "btn_save", "blue") + self.btnSave = NPushButton(self, self.tr("Save As"), bSz, "btn_save", "action") self.btnSave.setAutoDefault(False) self.btnSave.setMenu(self.saveMenu) diff --git a/tests/test_ext/test_ext_modified.py b/tests/test_ext/test_ext_modified.py index fa66a528..d7c2ae09 100644 --- a/tests/test_ext/test_ext_modified.py +++ b/tests/test_ext/test_ext_modified.py @@ -185,13 +185,13 @@ def testExtModified_NClickableLabel(qtbot): @pytest.mark.gui -def testExtModified_ToolButtons(qtbot): +def testExtModified_ToolButtons(qtbot, mockGUI): """Test the NIconToolButton and NIconToggleButton classes.""" dialog = SimpleDialog(None) size = QSize(16, 16) - button1 = NIconToolButton(dialog, size, "add", "green") - button2 = NIconToggleButton(dialog, size, "bullet") + button1 = NIconToolButton(dialog, size, "add", "add") + button2 = NIconToggleButton(dialog, size, "bullet", "action") assert button1.iconSize() == size assert button2.iconSize() == size diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index 7f4d976a..beff6b21 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -421,36 +421,36 @@ def testGuiTheme_LoadIcons(): # ========== # Load an unknown icon - qIcon = iconCache.getIcon("stuff") + qIcon = iconCache.getIcon("stuff", "tool") assert isinstance(qIcon, QIcon) assert qIcon == iconCache._noIcon # Load an icon, it is likely already cached - qIcon = iconCache.getIcon("add") + qIcon = iconCache.getIcon("add", "tool") assert isinstance(qIcon, QIcon) assert qIcon.isNull() is False # Load it as a pixmap with a size # If this part of the test fails, you may need to set the # environment variable: QT_SCALE_FACTOR=1 - qPix = iconCache.getPixmap("add", (50, 50)) + qPix = iconCache.getPixmap("add", (50, 50), "tool") assert isinstance(qPix, QPixmap) assert qPix.isNull() is False assert qPix.width() == 50, "If this fails, make sure QT_SCALE_FACTOR=1" assert qPix.height() == 50, "If this fails, make sure QT_SCALE_FACTOR=1" # Load app icon - qIcon = iconCache.getIcon("novelwriter") + qIcon = iconCache.getIcon("novelwriter", "tool") assert isinstance(qIcon, QIcon) assert qIcon != iconCache._noIcon # Load mime icon - qIcon = iconCache.getIcon("proj_nwx") + qIcon = iconCache.getIcon("proj_nwx", "tool") assert isinstance(qIcon, QIcon) assert qIcon != iconCache._noIcon # Toggle icon - qIcon = iconCache.getToggleIcon("bullet", (24, 24)) + qIcon = iconCache.getToggleIcon("bullet", (24, 24), "tool") assert isinstance(qIcon, QIcon) assert qIcon != iconCache._noIcon pOn = qIcon.pixmap(24, 24, QIcon.Mode.Normal, QIcon.State.On) @@ -458,7 +458,7 @@ def testGuiTheme_LoadIcons(): assert pOn != pOff # Unknown toggle icon - qIcon = iconCache.getToggleIcon("stuff", (24, 24)) + qIcon = iconCache.getToggleIcon("stuff", (24, 24), "tool") assert isinstance(qIcon, QIcon) assert qIcon == iconCache._noIcon @@ -610,7 +610,7 @@ def testGuiTheme_CheckTheme(theme): parser = ConfigParser() parser.read(current.path, encoding="utf-8") - sections = ["Main", "Base", "Project", "Palette", "GUI", "Syntax"] + sections = ["Main", "Base", "Project", "Icon", "Palette", "GUI", "Syntax"] assert sorted(parser.sections()) == sorted(sections) structure = { @@ -625,6 +625,11 @@ def testGuiTheme_CheckTheme(theme): "root", "folder", "file", "title", "chapter", "scene", "note", "active", "inactive", "disabled", ], + "Icon": [ + "tool", "accept", "reject", "action", "altaction", "apply", + "create", "destroy", "reset", "add", "change", "remove", + "scformat", "mdformat", "systemio", "info", "warning", "error", + ], "Palette": [ "window", "windowtext", "base", "alternatebase", "text", "tooltipbase", "tooltiptext", "button", "buttontext", "brighttext",