Add theme update handling to manuscript build tool
This commit is contained in:
@@ -214,10 +214,10 @@ class NPushButton(QPushButton):
|
|||||||
self._color = color
|
self._color = color
|
||||||
self.setText(text)
|
self.setText(text)
|
||||||
self.setIconSize(iconSize)
|
self.setIconSize(iconSize)
|
||||||
self.refreshIcon()
|
self.updateIcon()
|
||||||
|
|
||||||
def refreshIcon(self) -> None:
|
def updateIcon(self) -> None:
|
||||||
"""Reload the theme icon."""
|
"""Update the theme icon."""
|
||||||
if self._icon:
|
if self._icon:
|
||||||
self.setIcon(SHARED.theme.getIcon(self._icon, self._color))
|
self.setIcon(SHARED.theme.getIcon(self._icon, self._color))
|
||||||
|
|
||||||
@@ -262,8 +262,8 @@ class NIconToggleButton(QToolButton):
|
|||||||
|
|
||||||
def setThemeIcon(self, iconKey: str) -> None:
|
def setThemeIcon(self, iconKey: str) -> None:
|
||||||
"""Set an icon from the current theme."""
|
"""Set an icon from the current theme."""
|
||||||
iconSize = self.iconSize()
|
size = self.iconSize()
|
||||||
self.setIcon(SHARED.theme.getToggleIcon(iconKey, (iconSize.width(), iconSize.height())))
|
self.setIcon(SHARED.theme.getToggleIcon(iconKey, (size.width(), size.height())))
|
||||||
|
|
||||||
|
|
||||||
class NClickableLabel(QLabel):
|
class NClickableLabel(QLabel):
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ from novelwriter.types import QtNoPen, QtPaintAntiAlias, QtSizeFixed
|
|||||||
class NSwitch(QAbstractButton):
|
class NSwitch(QAbstractButton):
|
||||||
"""Custom: Toggle Switch."""
|
"""Custom: Toggle Switch."""
|
||||||
|
|
||||||
__slots__ = ("_cOff", "_cOn", "_offset", "_rH", "_rR", "_xH", "_xR", "_xW")
|
__slots__ = ("_offset", "_rH", "_rR", "_xH", "_xR", "_xW")
|
||||||
|
|
||||||
def __init__(self, parent: QWidget, height: int = 0) -> None:
|
def __init__(self, parent: QWidget, height: int = 0) -> None:
|
||||||
super().__init__(parent=parent)
|
super().__init__(parent=parent)
|
||||||
@@ -45,13 +45,11 @@ class NSwitch(QAbstractButton):
|
|||||||
self._rH = self._xH - 4
|
self._rH = self._xH - 4
|
||||||
self._rR = self._xR - 2
|
self._rR = self._xR - 2
|
||||||
|
|
||||||
self._cOn = SHARED.theme.accentCol
|
|
||||||
self._cOff = self.palette().alternateBase()
|
|
||||||
|
|
||||||
self.setCheckable(True)
|
self.setCheckable(True)
|
||||||
self.setSizePolicy(QtSizeFixed, QtSizeFixed)
|
self.setSizePolicy(QtSizeFixed, QtSizeFixed)
|
||||||
self.setFixedWidth(self._xW)
|
self.setFixedWidth(self._xW)
|
||||||
self.setFixedHeight(self._xH)
|
self.setFixedHeight(self._xH)
|
||||||
|
self.setUpdatesEnabled(True)
|
||||||
self._offset = self._xR
|
self._offset = self._xR
|
||||||
|
|
||||||
self.clicked.connect(self._onClick)
|
self.clicked.connect(self._onClick)
|
||||||
@@ -96,7 +94,7 @@ class NSwitch(QAbstractButton):
|
|||||||
painter.setOpacity(1.0 if self.isEnabled() else 0.5)
|
painter.setOpacity(1.0 if self.isEnabled() else 0.5)
|
||||||
|
|
||||||
painter.setPen(palette.highlight().color() if self.hasFocus() else palette.mid().color())
|
painter.setPen(palette.highlight().color() if self.hasFocus() else palette.mid().color())
|
||||||
painter.setBrush(self._cOn if self.isChecked() else self._cOff)
|
painter.setBrush(SHARED.theme.accentCol if self.isChecked() else palette.alternateBase())
|
||||||
painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
|
painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
|
||||||
|
|
||||||
painter.setPen(QtNoPen)
|
painter.setPen(QtNoPen)
|
||||||
@@ -110,6 +108,10 @@ class NSwitch(QAbstractButton):
|
|||||||
self.setCursor(Qt.CursorShape.PointingHandCursor)
|
self.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
super().enterEvent(event)
|
super().enterEvent(event)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Internal Functions
|
||||||
|
##
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
@pyqtSlot(bool)
|
||||||
def _onClick(self, checked: bool) -> None:
|
def _onClick(self, checked: bool) -> None:
|
||||||
"""Animate the toggle action."""
|
"""Animate the toggle action."""
|
||||||
|
|||||||
@@ -2590,7 +2590,7 @@ class GuiDocEditSearch(QFrame):
|
|||||||
# Buttons
|
# Buttons
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
self.showReplace = NIconToggleButton(self, iSz, "unfold")
|
self.showReplace = NIconToggleButton(self, iSz)
|
||||||
self.showReplace.toggled.connect(self._doToggleReplace)
|
self.showReplace.toggled.connect(self._doToggleReplace)
|
||||||
|
|
||||||
self.searchButton = NIconToolButton(self, iSz)
|
self.searchButton = NIconToolButton(self, iSz)
|
||||||
@@ -2732,6 +2732,7 @@ class GuiDocEditSearch(QFrame):
|
|||||||
self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel"))
|
self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel"))
|
||||||
self.searchButton.setThemeIcon("search", "green")
|
self.searchButton.setThemeIcon("search", "green")
|
||||||
self.replaceButton.setThemeIcon("search_replace", "green")
|
self.replaceButton.setThemeIcon("search_replace", "green")
|
||||||
|
self.showReplace.setThemeIcon("unfold")
|
||||||
|
|
||||||
# Set stylesheets
|
# Set stylesheets
|
||||||
self.searchOpt.setStyleSheet("QToolBar {padding: 0;}")
|
self.searchOpt.setStyleSheet("QToolBar {padding: 0;}")
|
||||||
|
|||||||
@@ -910,6 +910,9 @@ class GuiMain(QMainWindow):
|
|||||||
self.mainStatus.updateTheme()
|
self.mainStatus.updateTheme()
|
||||||
SHARED.project.tree.refreshAllItems()
|
SHARED.project.tree.refreshAllItems()
|
||||||
|
|
||||||
|
if dialog := SHARED.findTopLevelWidget(GuiManuscript):
|
||||||
|
dialog.updateTheme()
|
||||||
|
|
||||||
if syntax:
|
if syntax:
|
||||||
self.docEditor.updateSyntaxColors()
|
self.docEditor.updateSyntaxColors()
|
||||||
|
|
||||||
|
|||||||
@@ -101,30 +101,20 @@ class GuiManuscript(NToolDialog):
|
|||||||
# Build Controls
|
# Build Controls
|
||||||
# ==============
|
# ==============
|
||||||
|
|
||||||
qPalette = self.palette()
|
self.tbAdd = NIconToolButton(self, iSz)
|
||||||
qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base())
|
|
||||||
self.setPalette(qPalette)
|
|
||||||
|
|
||||||
buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
|
|
||||||
|
|
||||||
self.tbAdd = NIconToolButton(self, iSz, "add", "green")
|
|
||||||
self.tbAdd.setToolTip(self.tr("Add New Build"))
|
self.tbAdd.setToolTip(self.tr("Add New Build"))
|
||||||
self.tbAdd.setStyleSheet(buttonStyle)
|
|
||||||
self.tbAdd.clicked.connect(self._createNewBuild)
|
self.tbAdd.clicked.connect(self._createNewBuild)
|
||||||
|
|
||||||
self.tbDel = NIconToolButton(self, iSz, "remove", "red")
|
self.tbDel = NIconToolButton(self, iSz)
|
||||||
self.tbDel.setToolTip(self.tr("Delete Selected Build"))
|
self.tbDel.setToolTip(self.tr("Delete Selected Build"))
|
||||||
self.tbDel.setStyleSheet(buttonStyle)
|
|
||||||
self.tbDel.clicked.connect(self._deleteSelectedBuild)
|
self.tbDel.clicked.connect(self._deleteSelectedBuild)
|
||||||
|
|
||||||
self.tbCopy = NIconToolButton(self, iSz, "copy", "blue")
|
self.tbCopy = NIconToolButton(self, iSz)
|
||||||
self.tbCopy.setToolTip(self.tr("Duplicate Selected Build"))
|
self.tbCopy.setToolTip(self.tr("Duplicate Selected Build"))
|
||||||
self.tbCopy.setStyleSheet(buttonStyle)
|
|
||||||
self.tbCopy.clicked.connect(self._copySelectedBuild)
|
self.tbCopy.clicked.connect(self._copySelectedBuild)
|
||||||
|
|
||||||
self.tbEdit = NIconToolButton(self, iSz, "edit", "green")
|
self.tbEdit = NIconToolButton(self, iSz)
|
||||||
self.tbEdit.setToolTip(self.tr("Edit Selected Build"))
|
self.tbEdit.setToolTip(self.tr("Edit Selected Build"))
|
||||||
self.tbEdit.setStyleSheet(buttonStyle)
|
|
||||||
self.tbEdit.clicked.connect(self._editSelectedBuild)
|
self.tbEdit.clicked.connect(self._editSelectedBuild)
|
||||||
|
|
||||||
self.lblBuilds = QLabel("<b>{0}</b>".format(self.tr("Builds")), self)
|
self.lblBuilds = QLabel("<b>{0}</b>".format(self.tr("Builds")), self)
|
||||||
@@ -159,7 +149,6 @@ class GuiManuscript(NToolDialog):
|
|||||||
self.detailsTabs = QTabWidget(self)
|
self.detailsTabs = QTabWidget(self)
|
||||||
self.detailsTabs.addTab(self.buildDetails, self.tr("Details"))
|
self.detailsTabs.addTab(self.buildDetails, self.tr("Details"))
|
||||||
self.detailsTabs.addTab(self.buildOutline, self.tr("Outline"))
|
self.detailsTabs.addTab(self.buildOutline, self.tr("Outline"))
|
||||||
self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
|
|
||||||
|
|
||||||
self.buildSplit = QSplitter(Qt.Orientation.Vertical, self)
|
self.buildSplit = QSplitter(Qt.Orientation.Vertical, self)
|
||||||
self.buildSplit.addWidget(self.buildList)
|
self.buildSplit.addWidget(self.buildList)
|
||||||
@@ -247,6 +236,8 @@ class GuiManuscript(NToolDialog):
|
|||||||
self.setLayout(self.outerBox)
|
self.setLayout(self.outerBox)
|
||||||
self.setSizeGripEnabled(True)
|
self.setSizeGripEnabled(True)
|
||||||
|
|
||||||
|
self.updateTheme(init=True)
|
||||||
|
|
||||||
# Signals
|
# Signals
|
||||||
self.buildOutline.outlineEntryClicked.connect(self.docPreview.navigateTo)
|
self.buildOutline.outlineEntryClicked.connect(self.docPreview.navigateTo)
|
||||||
|
|
||||||
@@ -270,6 +261,31 @@ class GuiManuscript(NToolDialog):
|
|||||||
self.buildList.setCurrentItem(self._buildMap[selected])
|
self.buildList.setCurrentItem(self._buildMap[selected])
|
||||||
QTimer.singleShot(200, self._generatePreview)
|
QTimer.singleShot(200, self._generatePreview)
|
||||||
|
|
||||||
|
def updateTheme(self, *, init: bool = False) -> None:
|
||||||
|
"""Update theme elements."""
|
||||||
|
self.tbAdd.setThemeIcon("add", "green")
|
||||||
|
self.tbDel.setThemeIcon("remove", "red")
|
||||||
|
self.tbCopy.setThemeIcon("copy", "blue")
|
||||||
|
self.tbEdit.setThemeIcon("edit", "green")
|
||||||
|
|
||||||
|
if not init:
|
||||||
|
self.btnPreview.updateIcon()
|
||||||
|
self.btnPrint.updateIcon()
|
||||||
|
self.btnBuild.updateIcon()
|
||||||
|
self.btnClose.updateIcon()
|
||||||
|
|
||||||
|
buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)
|
||||||
|
self.tbAdd.setStyleSheet(buttonStyle)
|
||||||
|
self.tbDel.setStyleSheet(buttonStyle)
|
||||||
|
self.tbCopy.setStyleSheet(buttonStyle)
|
||||||
|
self.tbEdit.setStyleSheet(buttonStyle)
|
||||||
|
|
||||||
|
self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS))
|
||||||
|
|
||||||
|
self.buildDetails.updateTheme()
|
||||||
|
self.buildOutline.updateTheme()
|
||||||
|
self.docPreview.updateTheme()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Events
|
# Events
|
||||||
##
|
##
|
||||||
@@ -490,6 +506,7 @@ class _DetailsWidget(QWidget):
|
|||||||
super().__init__(parent=parent)
|
super().__init__(parent=parent)
|
||||||
|
|
||||||
self._initExpanded = True
|
self._initExpanded = True
|
||||||
|
self._build = None
|
||||||
|
|
||||||
# Tree Widget
|
# Tree Widget
|
||||||
self.listView = QTreeWidget(self)
|
self.listView = QTreeWidget(self)
|
||||||
@@ -612,9 +629,16 @@ class _DetailsWidget(QWidget):
|
|||||||
sub.setIcon(1, on if build.getBool(key) else off)
|
sub.setIcon(1, on if build.getBool(key) else off)
|
||||||
item.addChild(sub)
|
item.addChild(sub)
|
||||||
|
|
||||||
|
self._build = build
|
||||||
|
|
||||||
# Restore expanded state
|
# Restore expanded state
|
||||||
self.setExpandedState(expanded)
|
self.setExpandedState(expanded)
|
||||||
|
|
||||||
|
def updateTheme(self) -> None:
|
||||||
|
"""Update theme elements."""
|
||||||
|
if self._build:
|
||||||
|
self.updateInfo(self._build)
|
||||||
|
|
||||||
|
|
||||||
class _OutlineWidget(QWidget):
|
class _OutlineWidget(QWidget):
|
||||||
|
|
||||||
@@ -639,9 +663,9 @@ class _OutlineWidget(QWidget):
|
|||||||
self.outerBox.setContentsMargins(0, 0, 0, 0)
|
self.outerBox.setContentsMargins(0, 0, 0, 0)
|
||||||
self.setLayout(self.outerBox)
|
self.setLayout(self.outerBox)
|
||||||
|
|
||||||
def updateOutline(self, data: dict[str, str]) -> None:
|
def updateOutline(self, data: dict[str, str], *, force: bool = False) -> None:
|
||||||
"""Update the outline."""
|
"""Update the outline."""
|
||||||
if isinstance(data, dict) and data != self._outline:
|
if isinstance(data, dict) and (data != self._outline or force):
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
|
|
||||||
tFont = self.font()
|
tFont = self.font()
|
||||||
@@ -679,6 +703,10 @@ class _OutlineWidget(QWidget):
|
|||||||
self.listView.setIndentation(SHARED.theme.baseIconHeight if indent else 4)
|
self.listView.setIndentation(SHARED.theme.baseIconHeight if indent else 4)
|
||||||
self._outline = data
|
self._outline = data
|
||||||
|
|
||||||
|
def updateTheme(self) -> None:
|
||||||
|
"""Update theme elements."""
|
||||||
|
self.updateOutline(self._outline, force=True)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Private Slots
|
# Private Slots
|
||||||
##
|
##
|
||||||
@@ -721,17 +749,12 @@ class _PreviewWidget(QTextBrowser):
|
|||||||
self.anchorClicked.connect(self._linkClicked)
|
self.anchorClicked.connect(self._linkClicked)
|
||||||
|
|
||||||
# Document Age
|
# Document Age
|
||||||
aPalette = self.palette()
|
|
||||||
aPalette.setColor(QPalette.ColorRole.Window, aPalette.toolTipBase().color())
|
|
||||||
aPalette.setColor(QPalette.ColorRole.WindowText, aPalette.toolTipText().color())
|
|
||||||
|
|
||||||
aFont = self.font()
|
aFont = self.font()
|
||||||
aFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
|
aFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
|
||||||
|
|
||||||
self.ageLabel = QLabel("", self)
|
self.ageLabel = QLabel("", self)
|
||||||
self.ageLabel.setIndent(0)
|
self.ageLabel.setIndent(0)
|
||||||
self.ageLabel.setFont(aFont)
|
self.ageLabel.setFont(aFont)
|
||||||
self.ageLabel.setPalette(aPalette)
|
|
||||||
self.ageLabel.setAutoFillBackground(True)
|
self.ageLabel.setAutoFillBackground(True)
|
||||||
self.ageLabel.setAlignment(QtAlignCenter)
|
self.ageLabel.setAlignment(QtAlignCenter)
|
||||||
self.ageLabel.setFixedHeight(int(2.1*SHARED.theme.fontPixelSize))
|
self.ageLabel.setFixedHeight(int(2.1*SHARED.theme.fontPixelSize))
|
||||||
@@ -750,6 +773,7 @@ class _PreviewWidget(QTextBrowser):
|
|||||||
self._updateDocMargins()
|
self._updateDocMargins()
|
||||||
self._updateBuildAge()
|
self._updateBuildAge()
|
||||||
|
|
||||||
|
self.updateTheme()
|
||||||
self.setTextFont(CONFIG.textFont)
|
self.setTextFont(CONFIG.textFont)
|
||||||
|
|
||||||
# Age Timer
|
# Age Timer
|
||||||
@@ -815,6 +839,13 @@ class _PreviewWidget(QTextBrowser):
|
|||||||
QApplication.processEvents()
|
QApplication.processEvents()
|
||||||
QTimer.singleShot(300, self._postUpdate)
|
QTimer.singleShot(300, self._postUpdate)
|
||||||
|
|
||||||
|
def updateTheme(self) -> None:
|
||||||
|
"""Update theme elements."""
|
||||||
|
palette = QApplication.palette()
|
||||||
|
palette.setColor(QPalette.ColorRole.Window, palette.toolTipBase().color())
|
||||||
|
palette.setColor(QPalette.ColorRole.WindowText, palette.toolTipText().color())
|
||||||
|
self.ageLabel.setPalette(palette)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Events
|
# Events
|
||||||
##
|
##
|
||||||
@@ -907,7 +938,7 @@ class _StatsWidget(QWidget):
|
|||||||
self.minWidget = QWidget(self)
|
self.minWidget = QWidget(self)
|
||||||
self.maxWidget = QWidget(self)
|
self.maxWidget = QWidget(self)
|
||||||
|
|
||||||
self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize, "unfold")
|
self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize)
|
||||||
self.toggleButton.toggled.connect(self._toggleView)
|
self.toggleButton.toggled.connect(self._toggleView)
|
||||||
|
|
||||||
self._buildBottomPanel()
|
self._buildBottomPanel()
|
||||||
@@ -922,6 +953,7 @@ class _StatsWidget(QWidget):
|
|||||||
self.outerBox.setContentsMargins(0, 0, 0, 0)
|
self.outerBox.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
self.setLayout(self.outerBox)
|
self.setLayout(self.outerBox)
|
||||||
|
self.updateTheme()
|
||||||
|
|
||||||
self._toggleView(False)
|
self._toggleView(False)
|
||||||
|
|
||||||
@@ -946,6 +978,10 @@ class _StatsWidget(QWidget):
|
|||||||
self.maxHeadWordChars.setText(f"{data.get(nwStats.WCHARS_TITLE, 0):n}")
|
self.maxHeadWordChars.setText(f"{data.get(nwStats.WCHARS_TITLE, 0):n}")
|
||||||
self.maxTextWordChars.setText(f"{data.get(nwStats.WCHARS_TEXT, 0):n}")
|
self.maxTextWordChars.setText(f"{data.get(nwStats.WCHARS_TEXT, 0):n}")
|
||||||
|
|
||||||
|
def updateTheme(self) -> None:
|
||||||
|
"""Update theme elements."""
|
||||||
|
self.toggleButton.setThemeIcon("unfold")
|
||||||
|
|
||||||
##
|
##
|
||||||
# Private Slots
|
# Private Slots
|
||||||
##
|
##
|
||||||
|
|||||||
Reference in New Issue
Block a user