From 52ede26f3df6a689ce50bbdc6c8968d0cb2218c5 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Tue, 25 Oct 2022 23:12:21 +0200 Subject: [PATCH] Add updateTheme functions to most GUI components --- novelwriter/gui/doceditor.py | 80 +++++++++++++++++++------- novelwriter/gui/docviewer.py | 86 ++++++++++++++++++---------- novelwriter/gui/noveltree.py | 52 +++++++++++------ novelwriter/gui/projtree.py | 107 +++++++++++++++++++++-------------- novelwriter/gui/theme.py | 10 +++- novelwriter/gui/viewsbar.py | 25 +++++--- novelwriter/guimain.py | 9 ++- 7 files changed, 251 insertions(+), 118 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index d401a9dd..6b098959 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -206,6 +206,14 @@ class GuiDocEditor(QTextEdit): return True + def updateTheme(self): + """Update theme elements + """ + self.docSearch.updateTheme() + self.docHeader.updateTheme() + self.docFooter.updateTheme() + return + def initEditor(self): """Initialise or re-initialise the editor with the user's settings. This function is both called when the editor is @@ -2251,7 +2259,6 @@ class GuiDocEditSearch(QFrame): self.searchOpt.setToolButtonStyle(Qt.ToolButtonIconOnly) self.searchOpt.setIconSize(QSize(tPx, tPx)) self.searchOpt.setContentsMargins(0, 0, 0, 0) - self.searchOpt.setStyleSheet("QToolBar {padding: 0;}") self.searchLabel = QLabel(self.tr("Search")) self.searchLabel.setFont(self.boxFont) @@ -2262,35 +2269,30 @@ class GuiDocEditSearch(QFrame): self.resultLabel.setMinimumWidth(self.mainTheme.getTextWidth("?/?", self.boxFont)) self.toggleCase = QAction(self.tr("Case Sensitive"), self) - self.toggleCase.setIcon(self.mainTheme.getIcon("search_case")) self.toggleCase.setCheckable(True) self.toggleCase.setChecked(self.isCaseSense) self.toggleCase.toggled.connect(self._doToggleCase) self.searchOpt.addAction(self.toggleCase) self.toggleWord = QAction(self.tr("Whole Words Only"), self) - self.toggleWord.setIcon(self.mainTheme.getIcon("search_word")) self.toggleWord.setCheckable(True) self.toggleWord.setChecked(self.isWholeWord) self.toggleWord.toggled.connect(self._doToggleWord) self.searchOpt.addAction(self.toggleWord) self.toggleRegEx = QAction(self.tr("RegEx Mode"), self) - self.toggleRegEx.setIcon(self.mainTheme.getIcon("search_regex")) self.toggleRegEx.setCheckable(True) self.toggleRegEx.setChecked(self.isRegEx) self.toggleRegEx.toggled.connect(self._doToggleRegEx) self.searchOpt.addAction(self.toggleRegEx) self.toggleLoop = QAction(self.tr("Loop Search"), self) - self.toggleLoop.setIcon(self.mainTheme.getIcon("search_loop")) self.toggleLoop.setCheckable(True) self.toggleLoop.setChecked(self.doLoop) self.toggleLoop.toggled.connect(self._doToggleLoop) self.searchOpt.addAction(self.toggleLoop) self.toggleProject = QAction(self.tr("Search Next File"), self) - self.toggleProject.setIcon(self.mainTheme.getIcon("search_project")) self.toggleProject.setCheckable(True) self.toggleProject.setChecked(self.doNextFile) self.toggleProject.toggled.connect(self._doToggleProject) @@ -2299,7 +2301,6 @@ class GuiDocEditSearch(QFrame): self.searchOpt.addSeparator() self.toggleMatchCap = QAction(self.tr("Preserve Case"), self) - self.toggleMatchCap.setIcon(self.mainTheme.getIcon("search_preserve")) self.toggleMatchCap.setCheckable(True) self.toggleMatchCap.setChecked(self.doMatchCap) self.toggleMatchCap.toggled.connect(self._doToggleMatchCap) @@ -2308,7 +2309,6 @@ class GuiDocEditSearch(QFrame): self.searchOpt.addSeparator() self.cancelSearch = QAction(self.tr("Close Search"), self) - self.cancelSearch.setIcon(self.mainTheme.getIcon("search_cancel")) self.cancelSearch.triggered.connect(self._doClose) self.searchOpt.addAction(self.cancelSearch) @@ -2320,15 +2320,14 @@ class GuiDocEditSearch(QFrame): self.showReplace = QToolButton(self) self.showReplace.setArrowType(Qt.RightArrow) self.showReplace.setCheckable(True) - self.showReplace.setStyleSheet("QToolButton {border: none; background: transparent;}") self.showReplace.toggled.connect(self._doToggleReplace) - self.searchButton = QPushButton(self.mainTheme.getIcon("search"), "") + self.searchButton = QPushButton("") self.searchButton.setFixedSize(QSize(bPx, bPx)) self.searchButton.setToolTip(self.tr("Find in current document")) self.searchButton.clicked.connect(self._doSearch) - self.replaceButton = QPushButton(self.mainTheme.getIcon("search_replace"), "") + self.replaceButton = QPushButton("") self.replaceButton.setFixedSize(QSize(bPx, bPx)) self.replaceButton.setToolTip(self.tr("Find and replace in current document")) self.replaceButton.clicked.connect(self._doReplace) @@ -2358,6 +2357,35 @@ class GuiDocEditSearch(QFrame): self.replaceButton.setVisible(False) self.adjustSize() + self.updateTheme() + + logger.debug("GuiDocEditSearch initialisation complete") + + return + + def updateTheme(self): + """Update theme elements. + """ + qPalette = qApp.palette() + self.setPalette(qPalette) + self.searchBox.setPalette(qPalette) + self.replaceBox.setPalette(qPalette) + + # Set icons + self.toggleCase.setIcon(self.mainTheme.getIcon("search_case")) + self.toggleWord.setIcon(self.mainTheme.getIcon("search_word")) + self.toggleRegEx.setIcon(self.mainTheme.getIcon("search_regex")) + self.toggleLoop.setIcon(self.mainTheme.getIcon("search_loop")) + self.toggleProject.setIcon(self.mainTheme.getIcon("search_project")) + self.toggleMatchCap.setIcon(self.mainTheme.getIcon("search_preserve")) + self.cancelSearch.setIcon(self.mainTheme.getIcon("search_cancel")) + self.searchButton.setIcon(self.mainTheme.getIcon("search")) + self.replaceButton.setIcon(self.mainTheme.getIcon("search_replace")) + + # Set stylesheets + self.searchOpt.setStyleSheet("QToolBar {padding: 0;}") + self.showReplace.setStyleSheet("QToolButton {border: none; background: transparent;}") + # Construct Box Colours qPalette = self.searchBox.palette() baseCol = qPalette.base().color() @@ -2376,8 +2404,6 @@ class GuiDocEditSearch(QFrame): False: errCol } - logger.debug("GuiDocEditSearch initialisation complete") - return def closeSearch(self): @@ -2403,10 +2429,10 @@ class GuiDocEditSearch(QFrame): """ if self.replaceBox.isVisible(): if self.searchBox.hasFocus(): - self.replaceBox.setFocus(True) + self.replaceBox.setFocus() return True elif self.replaceBox.hasFocus(): - self.searchBox.setFocus(True) + self.searchBox.setFocus() return True return False @@ -2631,7 +2657,6 @@ class GuiDocEditHeader(QWidget): # Buttons self.editButton = QToolButton(self) - self.editButton.setIcon(self.mainTheme.getIcon("edit")) self.editButton.setContentsMargins(0, 0, 0, 0) self.editButton.setIconSize(QSize(fPx, fPx)) self.editButton.setFixedSize(fPx, fPx) @@ -2642,7 +2667,6 @@ class GuiDocEditHeader(QWidget): self.editButton.clicked.connect(self._editDocument) self.searchButton = QToolButton(self) - self.searchButton.setIcon(self.mainTheme.getIcon("search")) self.searchButton.setContentsMargins(0, 0, 0, 0) self.searchButton.setIconSize(QSize(fPx, fPx)) self.searchButton.setFixedSize(fPx, fPx) @@ -2653,7 +2677,6 @@ class GuiDocEditHeader(QWidget): self.searchButton.clicked.connect(self._searchDocument) self.minmaxButton = QToolButton(self) - self.minmaxButton.setIcon(self.mainTheme.getIcon("maximise")) self.minmaxButton.setContentsMargins(0, 0, 0, 0) self.minmaxButton.setIconSize(QSize(fPx, fPx)) self.minmaxButton.setFixedSize(fPx, fPx) @@ -2664,7 +2687,6 @@ class GuiDocEditHeader(QWidget): self.minmaxButton.clicked.connect(self._minmaxDocument) self.closeButton = QToolButton(self) - self.closeButton.setIcon(self.mainTheme.getIcon("close")) self.closeButton.setContentsMargins(0, 0, 0, 0) self.closeButton.setIconSize(QSize(fPx, fPx)) self.closeButton.setFixedSize(fPx, fPx) @@ -2692,6 +2714,7 @@ class GuiDocEditHeader(QWidget): self.setMinimumHeight(fPx + 2*cM) # Fix the Colours + self.updateTheme() self.matchColours() logger.debug("GuiDocEditHeader initialisation complete") @@ -2702,6 +2725,15 @@ class GuiDocEditHeader(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + self.editButton.setIcon(self.mainTheme.getIcon("edit")) + self.searchButton.setIcon(self.mainTheme.getIcon("search")) + self.minmaxButton.setIcon(self.mainTheme.getIcon("maximise")) + self.closeButton.setIcon(self.mainTheme.getIcon("close")) + return + def matchColours(self): """Update the colours of the widget to match those of the syntax theme rather than the main GUI. @@ -2860,7 +2892,6 @@ class GuiDocEditFooter(QWidget): # Lines self.linesIcon = QLabel("") - self.linesIcon.setPixmap(self.mainTheme.getPixmap("status_lines", (self.sPx, self.sPx))) self.linesIcon.setContentsMargins(0, 0, 0, 0) self.linesIcon.setFixedHeight(self.sPx) self.linesIcon.setAlignment(Qt.AlignLeft | Qt.AlignTop) @@ -2876,7 +2907,6 @@ class GuiDocEditFooter(QWidget): # Words self.wordsIcon = QLabel("") - self.wordsIcon.setPixmap(self.mainTheme.getPixmap("status_stats", (self.sPx, self.sPx))) self.wordsIcon.setContentsMargins(0, 0, 0, 0) self.wordsIcon.setFixedHeight(self.sPx) self.wordsIcon.setAlignment(Qt.AlignLeft | Qt.AlignTop) @@ -2911,6 +2941,7 @@ class GuiDocEditFooter(QWidget): self.setMinimumHeight(fPx + 2*cM) # Fix the Colours + self.updateTheme() self.matchColours() self.updateLineCount() self.updateCounts() @@ -2923,6 +2954,13 @@ class GuiDocEditFooter(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + self.linesIcon.setPixmap(self.mainTheme.getPixmap("status_lines", (self.sPx, self.sPx))) + self.wordsIcon.setPixmap(self.mainTheme.getPixmap("status_stats", (self.sPx, self.sPx))) + return + def matchColours(self): """Update the colours of the widget to match those of the syntax theme rather than the main GUI. diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 644c3b6d..d3cac0b0 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -102,6 +102,13 @@ class GuiDocViewer(QTextBrowser): self.docHeader.setTitleFromHandle(self._docHandle) return True + def updateTheme(self): + """Update theme elements. + """ + self.docHeader.updateTheme() + self.docFooter.updateTheme() + return + def initViewer(self): """Set editor settings from main config. """ @@ -742,7 +749,6 @@ class GuiDocViewHeader(QWidget): # Buttons self.backButton = QToolButton(self) - self.backButton.setIcon(self.mainTheme.getIcon("backward")) self.backButton.setContentsMargins(0, 0, 0, 0) self.backButton.setIconSize(QSize(fPx, fPx)) self.backButton.setFixedSize(fPx, fPx) @@ -753,7 +759,6 @@ class GuiDocViewHeader(QWidget): self.backButton.clicked.connect(self.docViewer.navBackward) self.forwardButton = QToolButton(self) - self.forwardButton.setIcon(self.mainTheme.getIcon("forward")) self.forwardButton.setContentsMargins(0, 0, 0, 0) self.forwardButton.setIconSize(QSize(fPx, fPx)) self.forwardButton.setFixedSize(fPx, fPx) @@ -764,7 +769,6 @@ class GuiDocViewHeader(QWidget): self.forwardButton.clicked.connect(self.docViewer.navForward) self.refreshButton = QToolButton(self) - self.refreshButton.setIcon(self.mainTheme.getIcon("refresh")) self.refreshButton.setContentsMargins(0, 0, 0, 0) self.refreshButton.setIconSize(QSize(fPx, fPx)) self.refreshButton.setFixedSize(fPx, fPx) @@ -775,7 +779,6 @@ class GuiDocViewHeader(QWidget): self.refreshButton.clicked.connect(self._refreshDocument) self.closeButton = QToolButton(self) - self.closeButton.setIcon(self.mainTheme.getIcon("close")) self.closeButton.setContentsMargins(0, 0, 0, 0) self.closeButton.setIconSize(QSize(fPx, fPx)) self.closeButton.setFixedSize(fPx, fPx) @@ -803,6 +806,7 @@ class GuiDocViewHeader(QWidget): self.setMinimumHeight(fPx + 2*cM) # Fix the Colours + self.updateTheme() self.matchColours() logger.debug("GuiDocViewHeader initialisation complete") @@ -813,6 +817,15 @@ class GuiDocViewHeader(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + self.backButton.setIcon(self.mainTheme.getIcon("backward")) + self.forwardButton.setIcon(self.mainTheme.getIcon("forward")) + self.refreshButton.setIcon(self.mainTheme.getIcon("refresh")) + self.closeButton.setIcon(self.mainTheme.getIcon("close")) + return + def matchColours(self): """Update the colours of the widget to match those of the syntax theme rather than the main GUI. @@ -926,33 +939,13 @@ class GuiDocViewFooter(QWidget): bSp = self.mainConf.pxInt(2) hSp = self.mainConf.pxInt(8) - # Icons - stickyOn = self.mainTheme.getPixmap("sticky-on", (fPx, fPx)) - stickyOff = self.mainTheme.getPixmap("sticky-off", (fPx, fPx)) - stickyIcon = QIcon() - stickyIcon.addPixmap(stickyOn, QIcon.Normal, QIcon.On) - stickyIcon.addPixmap(stickyOff, QIcon.Normal, QIcon.Off) - - bulletOn = self.mainTheme.getPixmap("bullet-on", (fPx, fPx)) - bulletOff = self.mainTheme.getPixmap("bullet-off", (fPx, fPx)) - bulletIcon = QIcon() - bulletIcon.addPixmap(bulletOn, QIcon.Normal, QIcon.On) - bulletIcon.addPixmap(bulletOff, QIcon.Normal, QIcon.Off) - # Main Widget Settings self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) - buttonStyle = ( - "QToolButton {{border: none; background: transparent;}} " - "QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}" - ).format(*self.mainTheme.colText) - # Show/Hide Details self.showHide = QToolButton(self) self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly) - self.showHide.setStyleSheet(buttonStyle) - self.showHide.setIcon(self.mainTheme.getIcon("reference")) self.showHide.setIconSize(QSize(fPx, fPx)) self.showHide.setFixedSize(QSize(fPx, fPx)) self.showHide.clicked.connect(self._doShowHide) @@ -962,8 +955,6 @@ class GuiDocViewFooter(QWidget): self.stickyRefs = QToolButton(self) self.stickyRefs.setCheckable(True) self.stickyRefs.setToolButtonStyle(Qt.ToolButtonIconOnly) - self.stickyRefs.setStyleSheet(buttonStyle) - self.stickyRefs.setIcon(stickyIcon) self.stickyRefs.setIconSize(QSize(fPx, fPx)) self.stickyRefs.setFixedSize(QSize(fPx, fPx)) self.stickyRefs.toggled.connect(self._doToggleSticky) @@ -976,8 +967,6 @@ class GuiDocViewFooter(QWidget): self.showComments.setCheckable(True) self.showComments.setChecked(self.mainConf.viewComments) self.showComments.setToolButtonStyle(Qt.ToolButtonIconOnly) - self.showComments.setStyleSheet(buttonStyle) - self.showComments.setIcon(bulletIcon) self.showComments.setIconSize(QSize(fPx, fPx)) self.showComments.setFixedSize(QSize(fPx, fPx)) self.showComments.toggled.connect(self._doToggleComments) @@ -988,8 +977,6 @@ class GuiDocViewFooter(QWidget): self.showSynopsis.setCheckable(True) self.showSynopsis.setChecked(self.mainConf.viewSynopsis) self.showSynopsis.setToolButtonStyle(Qt.ToolButtonIconOnly) - self.showSynopsis.setStyleSheet(buttonStyle) - self.showSynopsis.setIcon(bulletIcon) self.showSynopsis.setIconSize(QSize(fPx, fPx)) self.showSynopsis.setFixedSize(QSize(fPx, fPx)) self.showSynopsis.toggled.connect(self._doToggleSynopsis) @@ -1063,6 +1050,7 @@ class GuiDocViewFooter(QWidget): self.setMinimumHeight(fPx + 2*cM) # Fix the Colours + self.updateTheme() self.matchColours() logger.debug("GuiDocViewFooter initialisation complete") @@ -1073,6 +1061,44 @@ class GuiDocViewFooter(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + # Icons + + fPx = int(0.9*self.mainTheme.fontPixelSize) + + stickyOn = self.mainTheme.getPixmap("sticky-on", (fPx, fPx)) + stickyOff = self.mainTheme.getPixmap("sticky-off", (fPx, fPx)) + stickyIcon = QIcon() + stickyIcon.addPixmap(stickyOn, QIcon.Normal, QIcon.On) + stickyIcon.addPixmap(stickyOff, QIcon.Normal, QIcon.Off) + + bulletOn = self.mainTheme.getPixmap("bullet-on", (fPx, fPx)) + bulletOff = self.mainTheme.getPixmap("bullet-off", (fPx, fPx)) + bulletIcon = QIcon() + bulletIcon.addPixmap(bulletOn, QIcon.Normal, QIcon.On) + bulletIcon.addPixmap(bulletOff, QIcon.Normal, QIcon.Off) + + self.showHide.setIcon(self.mainTheme.getIcon("reference")) + self.stickyRefs.setIcon(stickyIcon) + self.showComments.setIcon(bulletIcon) + self.showSynopsis.setIcon(bulletIcon) + + # StyleSheets + + buttonStyle = ( + "QToolButton {{border: none; background: transparent;}} " + "QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}" + ).format(*self.mainTheme.colText) + + self.showHide.setStyleSheet(buttonStyle) + self.stickyRefs.setStyleSheet(buttonStyle) + self.showComments.setStyleSheet(buttonStyle) + self.showSynopsis.setStyleSheet(buttonStyle) + + return + def matchColours(self): """Update the colours of the widget to match those of the syntax theme rather than the main GUI. diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index acadd29f..489b7ab6 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -92,6 +92,13 @@ class GuiNovelView(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + self.novelBar.updateTheme() + self.refreshTree() + return + def initSettings(self): """Initialise GUI elements that depend on specific settings. """ @@ -181,16 +188,6 @@ class GuiNovelToolBar(QWidget): self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) - qPalette = self.palette() - qPalette.setBrush(QPalette.Window, qPalette.base()) - self.setPalette(qPalette) - - fadeCol = qPalette.text().color() - buttonStyle = ( - "QToolButton {{padding: {0}px; border: none; background: transparent;}} " - "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" - ).format(mPx, fadeCol.red(), fadeCol.green(), fadeCol.blue()) - # Widget Label self.viewLabel = QLabel("%s" % self.tr("Novel Outline")) self.viewLabel.setContentsMargins(0, 0, 0, 0) @@ -199,9 +196,7 @@ class GuiNovelToolBar(QWidget): # Refresh Button self.tbRefresh = QToolButton(self) self.tbRefresh.setToolTip(self.tr("Refresh")) - self.tbRefresh.setIcon(self.mainTheme.getIcon("refresh")) self.tbRefresh.setIconSize(QSize(iPx, iPx)) - self.tbRefresh.setStyleSheet(buttonStyle) self.tbRefresh.clicked.connect(self._refreshNovelTree) # Novel Root Menu @@ -211,9 +206,7 @@ class GuiNovelToolBar(QWidget): self.tbRoot = QToolButton(self) self.tbRoot.setToolTip(self.tr("Novel Root")) - self.tbRoot.setIcon(self.mainTheme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL])) self.tbRoot.setIconSize(QSize(iPx, iPx)) - self.tbRoot.setStyleSheet(buttonStyle) self.tbRoot.setMenu(self.mRoot) self.tbRoot.setPopupMode(QToolButton.InstantPopup) @@ -230,9 +223,7 @@ class GuiNovelToolBar(QWidget): self.tbMore = QToolButton(self) self.tbMore.setToolTip(self.tr("More Options")) - self.tbMore.setIcon(self.mainTheme.getIcon("menu")) self.tbMore.setIconSize(QSize(iPx, iPx)) - self.tbMore.setStyleSheet(buttonStyle) self.tbMore.setMenu(self.mMore) self.tbMore.setPopupMode(QToolButton.InstantPopup) @@ -247,6 +238,8 @@ class GuiNovelToolBar(QWidget): self.setLayout(self.outerBox) + self.updateTheme() + logger.debug("GuiNovelToolBar initialisation complete") return @@ -255,6 +248,33 @@ class GuiNovelToolBar(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + # Icons + + self.tbRefresh.setIcon(self.mainTheme.getIcon("refresh")) + self.tbRoot.setIcon(self.mainTheme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL])) + self.tbMore.setIcon(self.mainTheme.getIcon("menu")) + + qPalette = self.palette() + qPalette.setBrush(QPalette.Window, qPalette.base()) + self.setPalette(qPalette) + + # StyleSheets + + fadeCol = qPalette.text().color() + buttonStyle = ( + "QToolButton {{padding: {0}px; border: none; background: transparent;}} " + "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" + ).format(self.mainConf.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue()) + + self.tbRefresh.setStyleSheet(buttonStyle) + self.tbRoot.setStyleSheet(buttonStyle) + self.tbMore.setStyleSheet(buttonStyle) + + return + def clearContent(self): """Run clearing project tasks. """ diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index e34419d1..19d8af38 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -119,6 +119,13 @@ class GuiProjectView(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + self.projBar.updateTheme() + self.populateTree() + return + def initSettings(self): """Initialise GUI elements that depend on specific settings. """ @@ -213,16 +220,6 @@ class GuiProjectToolBar(QWidget): self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) - qPalette = self.palette() - qPalette.setBrush(QPalette.Window, qPalette.base()) - self.setPalette(qPalette) - - fadeCol = qPalette.text().color() - buttonStyle = ( - "QToolButton {{padding: {0}px; border: none; background: transparent;}} " - "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" - ).format(mPx, fadeCol.red(), fadeCol.green(), fadeCol.blue()) - # Widget Label self.viewLabel = QLabel("%s" % self.tr("Project Content")) self.viewLabel.setContentsMargins(0, 0, 0, 0) @@ -234,78 +231,56 @@ class GuiProjectToolBar(QWidget): self.tbQuick = QToolButton(self) self.tbQuick.setToolTip("%s [Ctrl+L]" % self.tr("Quick Links")) self.tbQuick.setShortcut("Ctrl+L") - self.tbQuick.setIcon(self.mainTheme.getIcon("bookmark")) self.tbQuick.setIconSize(QSize(iPx, iPx)) - self.tbQuick.setStyleSheet(buttonStyle) self.tbQuick.setMenu(self.mQuick) self.tbQuick.setPopupMode(QToolButton.InstantPopup) # Move Buttons self.tbMoveU = QToolButton(self) self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up")) - self.tbMoveU.setIcon(self.mainTheme.getIcon("up")) self.tbMoveU.setIconSize(QSize(iPx, iPx)) - self.tbMoveU.setStyleSheet(buttonStyle) self.tbMoveU.clicked.connect(lambda: self.projTree.moveTreeItem(-1)) self.tbMoveD = QToolButton(self) self.tbMoveD.setToolTip("%s [Ctrl+Down]" % self.tr("Move Down")) - self.tbMoveD.setIcon(self.mainTheme.getIcon("down")) self.tbMoveD.setIconSize(QSize(iPx, iPx)) - self.tbMoveD.setStyleSheet(buttonStyle) self.tbMoveD.clicked.connect(lambda: self.projTree.moveTreeItem(1)) # Add Item Menu self.mAdd = QMenu() self.aAddEmpty = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["document"])) - self.aAddEmpty.setIcon(self.mainTheme.getIcon("proj_document")) self.aAddEmpty.triggered.connect( lambda: self.projTree.newTreeItem(nwItemType.FILE, hLevel=0, isNote=False) ) self.aAddChap = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["doc_h2"])) - self.aAddChap.setIcon(self.mainTheme.getIcon("proj_chapter")) self.aAddChap.triggered.connect( lambda: self.projTree.newTreeItem(nwItemType.FILE, hLevel=2, isNote=False) ) self.aAddScene = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["doc_h3"])) - self.aAddScene.setIcon(self.mainTheme.getIcon("proj_scene")) self.aAddScene.triggered.connect( lambda: self.projTree.newTreeItem(nwItemType.FILE, hLevel=3, isNote=False) ) self.aAddNote = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["note"])) - self.aAddNote.setIcon(self.mainTheme.getIcon("proj_note")) self.aAddNote.triggered.connect( lambda: self.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) ) self.aAddFolder = self.mAdd.addAction(trConst(nwLabels.ITEM_DESCRIPTION["folder"])) - self.aAddFolder.setIcon(self.mainTheme.getIcon("proj_folder")) self.aAddFolder.triggered.connect( lambda: self.projTree.newTreeItem(nwItemType.FOLDER) ) self.mAddRoot = self.mAdd.addMenu(trConst(nwLabels.ITEM_DESCRIPTION["root"])) - self._addRootFolderEntry(nwItemClass.NOVEL) - self._addRootFolderEntry(nwItemClass.ARCHIVE) - self.mAddRoot.addSeparator() - self._addRootFolderEntry(nwItemClass.PLOT) - self._addRootFolderEntry(nwItemClass.CHARACTER) - self._addRootFolderEntry(nwItemClass.WORLD) - self._addRootFolderEntry(nwItemClass.TIMELINE) - self._addRootFolderEntry(nwItemClass.OBJECT) - self._addRootFolderEntry(nwItemClass.ENTITY) - self._addRootFolderEntry(nwItemClass.CUSTOM) + self._buildRootMenu() self.tbAdd = QToolButton(self) self.tbAdd.setToolTip("%s [Ctrl+N]" % self.tr("Add Item")) self.tbAdd.setShortcut("Ctrl+N") - self.tbAdd.setIcon(self.mainTheme.getIcon("add")) self.tbAdd.setIconSize(QSize(iPx, iPx)) - self.tbAdd.setStyleSheet(buttonStyle) self.tbAdd.setMenu(self.mAdd) self.tbAdd.setPopupMode(QToolButton.InstantPopup) @@ -326,9 +301,7 @@ class GuiProjectToolBar(QWidget): self.tbMore = QToolButton(self) self.tbMore.setToolTip(self.tr("More Options")) - self.tbMore.setIcon(self.mainTheme.getIcon("menu")) self.tbMore.setIconSize(QSize(iPx, iPx)) - self.tbMore.setStyleSheet(buttonStyle) self.tbMore.setMenu(self.mMore) self.tbMore.setPopupMode(QToolButton.InstantPopup) @@ -344,6 +317,7 @@ class GuiProjectToolBar(QWidget): self.outerBox.setSpacing(0) self.setLayout(self.outerBox) + self.updateTheme() logger.debug("GuiProjectToolBar initialisation complete") @@ -353,6 +327,41 @@ class GuiProjectToolBar(QWidget): # Methods ## + def updateTheme(self): + """Update theme elements. + """ + qPalette = self.palette() + qPalette.setBrush(QPalette.Window, qPalette.base()) + self.setPalette(qPalette) + + fadeCol = qPalette.text().color() + buttonStyle = ( + "QToolButton {{padding: {0}px; border: none; background: transparent;}} " + "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" + ).format(self.mainConf.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue()) + + self.tbQuick.setStyleSheet(buttonStyle) + self.tbMoveU.setStyleSheet(buttonStyle) + self.tbMoveD.setStyleSheet(buttonStyle) + self.tbAdd.setStyleSheet(buttonStyle) + self.tbMore.setStyleSheet(buttonStyle) + + self.tbQuick.setIcon(self.mainTheme.getIcon("bookmark")) + self.tbMoveU.setIcon(self.mainTheme.getIcon("up")) + self.tbMoveD.setIcon(self.mainTheme.getIcon("down")) + self.aAddEmpty.setIcon(self.mainTheme.getIcon("proj_document")) + self.aAddChap.setIcon(self.mainTheme.getIcon("proj_chapter")) + self.aAddScene.setIcon(self.mainTheme.getIcon("proj_scene")) + self.aAddNote.setIcon(self.mainTheme.getIcon("proj_note")) + self.aAddFolder.setIcon(self.mainTheme.getIcon("proj_folder")) + self.tbAdd.setIcon(self.mainTheme.getIcon("add")) + self.tbMore.setIcon(self.mainTheme.getIcon("menu")) + + self.buildQuickLinkMenu() + self._buildRootMenu() + + return + def clearContent(self): """Clear dynamic content on the tool bar. """ @@ -379,13 +388,29 @@ class GuiProjectToolBar(QWidget): # Internal Functions ## - def _addRootFolderEntry(self, itemClass): - """Add a menu entry for a root folder of a given class. + def _buildRootMenu(self): + """Build the rood folder menu. """ - aNew = self.mAddRoot.addAction(trConst(nwLabels.CLASS_NAME[itemClass])) - aNew.setIcon(self.mainTheme.getIcon(nwLabels.CLASS_ICON[itemClass])) - aNew.triggered.connect(lambda: self.projTree.newTreeItem(nwItemType.ROOT, itemClass)) - self.mAddRoot.addAction(aNew) + def addClass(itemClass): + aNew = self.mAddRoot.addAction(trConst(nwLabels.CLASS_NAME[itemClass])) + aNew.setIcon(self.mainTheme.getIcon(nwLabels.CLASS_ICON[itemClass])) + aNew.triggered.connect(lambda: self.projTree.newTreeItem(nwItemType.ROOT, itemClass)) + self.mAddRoot.addAction(aNew) + return + + self.mAddRoot.clear() + addClass(nwItemClass.NOVEL) + addClass(nwItemClass.ARCHIVE) + self.mAddRoot.addSeparator() + addClass(nwItemClass.PLOT) + addClass(nwItemClass.CHARACTER) + addClass(nwItemClass.WORLD) + addClass(nwItemClass.TIMELINE) + addClass(nwItemClass.OBJECT) + addClass(nwItemClass.ENTITY) + addClass(nwItemClass.CUSTOM) + + return # END Class GuiProjectToolBar diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index b13e43ca..1c52f7dd 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -130,7 +130,6 @@ class GuiTheme: self.updateFont() self.updateTheme() - self.iconCache.updateTheme() # Icon Functions self.getIcon = self.iconCache.getIcon @@ -220,6 +219,7 @@ class GuiTheme: else: self.cssFile = self.themeFile[:-5]+".css" self.loadTheme() + self.iconCache.updateTheme() self.syntaxFile = self._availSyntax.get(self.guiSyntax, None) if self.syntaxFile is None: @@ -287,6 +287,8 @@ class GuiTheme: self._setPalette(confParser, cnfSec, "highlightedtext", QPalette.HighlightedText) self._setPalette(confParser, cnfSec, "link", QPalette.Link) self._setPalette(confParser, cnfSec, "linkvisited", QPalette.LinkVisited) + else: + self._guiPalette = qApp.style().standardPalette() # GUI cnfSec = "GUI" @@ -578,6 +580,12 @@ class GuiIcons: if iconKey not in self._themeMap: logger.error("No icon file specified for '%s'", iconKey) + # Refresh icons + for iconKey in self._qIcons: + logger.debug("Reloading icon: '%s'", iconKey) + qIcon = self._loadIcon(iconKey) + self._qIcons[iconKey] = qIcon + return True ## diff --git a/novelwriter/gui/viewsbar.py b/novelwriter/gui/viewsbar.py index dcd697db..da85275c 100644 --- a/novelwriter/gui/viewsbar.py +++ b/novelwriter/gui/viewsbar.py @@ -61,7 +61,6 @@ class GuiViewsBar(QToolBar): self.setIconSize(QSize(iPx, iPx)) self.setMaximumWidth(mPx) self.setContentsMargins(0, 0, 0, 0) - self.setStyleSheet("QToolBar {border: 0px;}") stretch = QWidget(self) stretch.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) @@ -70,37 +69,31 @@ class GuiViewsBar(QToolBar): self.aProject = QAction(self.tr("Project"), self) self.aProject.setFont(lblFont) self.aProject.setToolTip(self.tr("Project Tree View")) - self.aProject.setIcon(self.mainTheme.getIcon("view_editor")) self.aProject.triggered.connect(lambda: self.viewChangeRequested.emit(nwView.PROJECT)) self.aNovel = QAction(self.tr("Novel"), self) self.aNovel.setFont(lblFont) self.aNovel.setToolTip(self.tr("Novel Tree View")) - self.aNovel.setIcon(self.mainTheme.getIcon("view_novel")) self.aNovel.triggered.connect(lambda: self.viewChangeRequested.emit(nwView.NOVEL)) self.aOutline = QAction(self.tr("Outline"), self) self.aOutline.setFont(lblFont) self.aOutline.setToolTip(self.tr("Novel Outline View")) - self.aOutline.setIcon(self.mainTheme.getIcon("view_outline")) self.aOutline.triggered.connect(lambda: self.viewChangeRequested.emit(nwView.OUTLINE)) self.aBuild = QAction(self.tr("Build"), self) self.aBuild.setFont(lblFont) self.aBuild.setToolTip(self.tr("Build Novel Project")) - self.aBuild.setIcon(self.mainTheme.getIcon("view_build")) self.aBuild.triggered.connect(lambda: self.mainGui.showBuildProjectDialog()) self.aDetails = QAction(self.tr("Details"), self) self.aDetails.setFont(lblFont) self.aDetails.setToolTip(self.tr("Project Details")) - self.aDetails.setIcon(self.mainTheme.getIcon("proj_details")) self.aDetails.triggered.connect(lambda: self.mainGui.showProjectDetailsDialog()) self.aStats = QAction(self.tr("Stats"), self) self.aStats.setFont(lblFont) self.aStats.setToolTip(self.tr("Writing Statistics")) - self.aStats.setIcon(self.mainTheme.getIcon("proj_stats")) self.aStats.triggered.connect(lambda: self.mainGui.showWritingStatsDialog()) # Settings Menu @@ -114,7 +107,6 @@ class GuiViewsBar(QToolBar): self.tbSettings = QToolButton(self) self.tbSettings.setFont(lblFont) self.tbSettings.setText(self.tr("Settings")) - self.tbSettings.setIcon(self.mainTheme.getIcon("settings")) self.tbSettings.setMenu(self.mSettings) self.tbSettings.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.tbSettings.setPopupMode(QToolButton.InstantPopup) @@ -129,8 +121,25 @@ class GuiViewsBar(QToolBar): self.addAction(self.aStats) self.addWidget(self.tbSettings) + self.updateTheme() + logger.debug("GuiViewsBar initialisation complete") return + def updateTheme(self): + """Initialise GUI elements that depend on specific settings. + """ + self.setStyleSheet("QToolBar {border: 0px;}") + + self.aProject.setIcon(self.mainTheme.getIcon("view_editor")) + self.aNovel.setIcon(self.mainTheme.getIcon("view_novel")) + self.aOutline.setIcon(self.mainTheme.getIcon("view_outline")) + self.aBuild.setIcon(self.mainTheme.getIcon("view_build")) + self.aDetails.setIcon(self.mainTheme.getIcon("proj_details")) + self.aStats.setIcon(self.mainTheme.getIcon("proj_stats")) + self.tbSettings.setIcon(self.mainTheme.getIcon("settings")) + + return + # END Class GuiViewsBar diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index cf0a9dff..9b18220a 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -907,8 +907,15 @@ class GuiMain(QMainWindow): if dlgConf.result() == QDialog.Accepted: logger.debug("Applying new preferences") self.initMain() - self.mainTheme.updateTheme() self.saveDocument() + + self.mainTheme.updateTheme() + self.viewsBar.updateTheme() + self.projView.updateTheme() + self.novelView.updateTheme() + self.docEditor.updateTheme() + self.docViewer.updateTheme() + self.docEditor.initEditor() self.docViewer.initViewer() self.projView.initSettings()