From c000307f14b8772d6afddac88dc2b8a344cf9c85 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:39:54 +0200 Subject: [PATCH 1/6] Add a base button size, and make it default for switches and tool buttons --- novelwriter/extensions/switch.py | 8 ++++---- novelwriter/gui/sidebar.py | 2 +- novelwriter/gui/theme.py | 2 ++ novelwriter/tools/lipsum.py | 7 ++++--- novelwriter/tools/writingstats.py | 14 +++++++------- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/novelwriter/extensions/switch.py b/novelwriter/extensions/switch.py index ab32ddbb..5d020385 100644 --- a/novelwriter/extensions/switch.py +++ b/novelwriter/extensions/switch.py @@ -27,20 +27,20 @@ from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent from PyQt5.QtCore import QEvent, QPropertyAnimation, Qt, pyqtProperty from PyQt5.QtWidgets import QAbstractButton, QSizePolicy, QWidget -from novelwriter import CONFIG +from novelwriter import CONFIG, SHARED class NSwitch(QAbstractButton): __slots__ = ("_xW", "_xH", "_xR", "_rB", "_rH", "_rR", "_offset") - def __init__(self, parent: QWidget | None = None, height: int = 0) -> None: + def __init__(self, parent: QWidget, height: int = 0) -> None: super().__init__(parent=parent) - self._xH = height or CONFIG.pxInt(20) + self._xH = height or SHARED.theme.baseButtonHeight self._xW = 2*self._xH self._xR = int(self._xH*0.5) - self._rB = int(CONFIG.guiScale*2) + self._rB = CONFIG.pxInt(2) self._rH = self._xH - 2*self._rB self._rR = self._xR - self._rB diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py index e9129ef6..2030985e 100644 --- a/novelwriter/gui/sidebar.py +++ b/novelwriter/gui/sidebar.py @@ -54,7 +54,7 @@ class GuiSideBar(QWidget): self.mainGui = mainGui - iPx = CONFIG.pxInt(24) + iPx = int(1.2*SHARED.theme.baseButtonHeight) self.setContentsMargins(0, 0, 0, 0) self.installEventFilter(StatusTipFilter(mainGui)) diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index 7a841ad6..3d530c4c 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -159,6 +159,7 @@ class GuiTheme: self.fontPointSize = self.guiFont.pointSizeF() self.fontPixelSize = int(round(qMetric.height())) self.baseIconSize = int(round(qMetric.ascent())) + self.baseButtonHeight = int(round(1.35*qMetric.ascent())) self.textNHeight = qMetric.boundingRect("N").height() self.textNWidth = qMetric.boundingRect("N").width() @@ -171,6 +172,7 @@ class GuiTheme: logger.debug("GUI Font Point Size: %.2f", self.fontPointSize) logger.debug("GUI Font Pixel Size: %d", self.fontPixelSize) logger.debug("GUI Base Icon Size: %d", self.baseIconSize) + logger.debug("GUI Base Button Height: %d", self.baseButtonHeight) logger.debug("Text 'N' Height: %d", self.textNHeight) logger.debug("Text 'N' Width: %d", self.textNWidth) diff --git a/novelwriter/tools/lipsum.py b/novelwriter/tools/lipsum.py index 617c81ca..06c4970d 100644 --- a/novelwriter/tools/lipsum.py +++ b/novelwriter/tools/lipsum.py @@ -53,12 +53,13 @@ class GuiLipsum(QDialog): self.setWindowTitle(self.tr("Insert Placeholder Text")) + vSp = CONFIG.pxInt(4) + nPx = CONFIG.pxInt(64) + self.innerBox = QHBoxLayout() self.innerBox.setSpacing(CONFIG.pxInt(16)) # Icon - nPx = CONFIG.pxInt(64) - vSp = CONFIG.pxInt(4) self.docIcon = QLabel() self.docIcon.setPixmap(SHARED.theme.getPixmap("proj_document", (nPx, nPx))) @@ -78,7 +79,7 @@ class GuiLipsum(QDialog): self.paraCount.setValue(5) self.randLabel = QLabel(self.tr("Randomise order")) - self.randSwitch = NSwitch() + self.randSwitch = NSwitch(self) self.formBox = QGridLayout() self.formBox.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignLeft) diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index 95f737e2..8dc36891 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -187,43 +187,43 @@ class GuiWritingStats(QDialog): self.infoForm.setRowStretch(6, 1) # Filter Options - sPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconSize self.filterBox = QGroupBox(self.tr("Filters"), self) self.filterForm = QGridLayout(self) self.filterBox.setLayout(self.filterForm) - self.incNovel = NSwitch(self, height=sPx) + self.incNovel = NSwitch(self, height=iPx) self.incNovel.setChecked( pOptions.getBool("GuiWritingStats", "incNovel", True) ) self.incNovel.clicked.connect(self._updateListBox) - self.incNotes = NSwitch(self, height=sPx) + self.incNotes = NSwitch(self, height=iPx) self.incNotes.setChecked( pOptions.getBool("GuiWritingStats", "incNotes", True) ) self.incNotes.clicked.connect(self._updateListBox) - self.hideZeros = NSwitch(self, height=sPx) + self.hideZeros = NSwitch(self, height=iPx) self.hideZeros.setChecked( pOptions.getBool("GuiWritingStats", "hideZeros", True) ) self.hideZeros.clicked.connect(self._updateListBox) - self.hideNegative = NSwitch(self, height=sPx) + self.hideNegative = NSwitch(self, height=iPx) self.hideNegative.setChecked( pOptions.getBool("GuiWritingStats", "hideNegative", False) ) self.hideNegative.clicked.connect(self._updateListBox) - self.groupByDay = NSwitch(self, height=sPx) + self.groupByDay = NSwitch(self, height=iPx) self.groupByDay.setChecked( pOptions.getBool("GuiWritingStats", "groupByDay", False) ) self.groupByDay.clicked.connect(self._updateListBox) - self.showIdleTime = NSwitch(self, height=sPx) + self.showIdleTime = NSwitch(self, height=iPx) self.showIdleTime.setChecked( pOptions.getBool("GuiWritingStats", "showIdleTime", False) ) From 1eafa1c8b67afb3e9f339725cd2b9e7c1512c2d2 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:48:12 +0200 Subject: [PATCH 2/6] Make sure all tool buttons scale to base icon size --- novelwriter/dialogs/preferences.py | 10 ++++++- novelwriter/gui/docviewer.py | 5 ++-- novelwriter/gui/outline.py | 4 +-- novelwriter/tools/manussettings.py | 42 +++++++++++++++++++++--------- novelwriter/tools/welcome.py | 4 +++ 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 142b837d..d79f81ef 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -27,7 +27,7 @@ from __future__ import annotations import logging from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractButton, QCompleter, QDialog, QDialogButtonBox, QFileDialog, QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QToolButton, QVBoxLayout, @@ -133,6 +133,8 @@ class GuiPreferences(QDialog): """Build the settings form.""" section = 0 minWidth = CONFIG.pxInt(200) + iPx = SHARED.theme.baseIconSize + iconSize = QSize(iPx, iPx) mIcon = SHARED.theme.getIcon("more") # Label @@ -177,6 +179,7 @@ class GuiPreferences(QDialog): self.guiFont.setText(CONFIG.guiFont) self.guiFontButton = QToolButton(self) self.guiFontButton.setIcon(mIcon) + self.guiFontButton.setIconSize(iconSize) self.guiFontButton.clicked.connect(self._selectGuiFont) self.mainForm.addRow( self.tr("Application font family"), self.guiFont, @@ -238,6 +241,7 @@ class GuiPreferences(QDialog): self.textFont.setText(CONFIG.textFont) self.textFontButton = QToolButton(self) self.textFontButton.setIcon(mIcon) + self.textFontButton.setIconSize(iconSize) self.textFontButton.clicked.connect(self._selectTextFont) self.mainForm.addRow( self.tr("Document font family"), self.textFont, @@ -679,6 +683,7 @@ class GuiPreferences(QDialog): self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen) self.btnSingleStyleO = QToolButton(self) self.btnSingleStyleO.setIcon(mIcon) + self.btnSingleStyleO.setIconSize(iconSize) self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO")) self.mainForm.addRow( self.tr("Single quote open style"), self.quoteSym["SO"], @@ -694,6 +699,7 @@ class GuiPreferences(QDialog): self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose) self.btnSingleStyleC = QToolButton(self) self.btnSingleStyleC.setIcon(mIcon) + self.btnSingleStyleC.setIconSize(iconSize) self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC")) self.mainForm.addRow( self.tr("Single quote close style"), self.quoteSym["SC"], @@ -710,6 +716,7 @@ class GuiPreferences(QDialog): self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen) self.btnDoubleStyleO = QToolButton(self) self.btnDoubleStyleO.setIcon(mIcon) + self.btnDoubleStyleO.setIconSize(iconSize) self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO")) self.mainForm.addRow( self.tr("Double quote open style"), self.quoteSym["DO"], @@ -725,6 +732,7 @@ class GuiPreferences(QDialog): self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose) self.btnDoubleStyleC = QToolButton(self) self.btnDoubleStyleC.setIcon(mIcon) + self.btnDoubleStyleC.setIconSize(iconSize) self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC")) self.mainForm.addRow( self.tr("Double quote close style"), self.quoteSym["DC"], diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index a6ddead8..b3e405e1 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -851,6 +851,7 @@ class GuiDocViewFooter(QWidget): iPx = SHARED.theme.baseIconSize hSp = CONFIG.pxInt(4) mPx = CONFIG.pxInt(4) + iconSize = QSize(iPx, iPx) # Main Widget Settings self.setContentsMargins(0, 0, 0, 0) @@ -867,7 +868,7 @@ class GuiDocViewFooter(QWidget): self.showComments.setCheckable(True) self.showComments.setChecked(CONFIG.viewComments) self.showComments.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) - self.showComments.setIconSize(QSize(iPx, iPx)) + self.showComments.setIconSize(iconSize) self.showComments.toggled.connect(self._doToggleComments) self.showComments.setToolTip(self.tr("Show Comments")) @@ -877,7 +878,7 @@ class GuiDocViewFooter(QWidget): self.showSynopsis.setCheckable(True) self.showSynopsis.setChecked(CONFIG.viewSynopsis) self.showSynopsis.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) - self.showSynopsis.setIconSize(QSize(iPx, iPx)) + self.showSynopsis.setIconSize(iconSize) self.showSynopsis.toggled.connect(self._doToggleSynopsis) self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments")) diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 8bb7cc0c..262c6c49 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -206,11 +206,11 @@ class GuiOutlineToolBar(QToolBar): logger.debug("Create: GuiOutlineToolBar") - iPx = CONFIG.pxInt(22) + bPx = SHARED.theme.baseButtonHeight mPx = CONFIG.pxInt(12) self.setMovable(False) - self.setIconSize(QSize(iPx, iPx)) + self.setIconSize(QSize(bPx, bPx)) self.setContentsMargins(0, 0, 0, 0) stretch = QWidget(self) diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 821b48fe..a6bb27fd 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -318,6 +318,7 @@ class _FilterTab(NFixedPage): # Tree Settings iPx = SHARED.theme.baseIconSize cMg = CONFIG.pxInt(6) + iconSize = QSize(iPx, iPx) # Tree Widget self.optTree = QTreeWidget(self) @@ -347,16 +348,19 @@ class _FilterTab(NFixedPage): self.includedButton = QToolButton(self) self.includedButton.setToolTip(self.tr("Always included")) self.includedButton.setIcon(self._statusFlags[self.F_INCLUDED]) + self.includedButton.setIconSize(iconSize) self.includedButton.clicked.connect(lambda: self._setSelectedMode(self.F_INCLUDED)) self.excludedButton = QToolButton(self) self.excludedButton.setToolTip(self.tr("Always excluded")) self.excludedButton.setIcon(self._statusFlags[self.F_EXCLUDED]) + self.excludedButton.setIconSize(iconSize) self.excludedButton.clicked.connect(lambda: self._setSelectedMode(self.F_EXCLUDED)) self.resetButton = QToolButton(self) self.resetButton.setToolTip(self.tr("Reset to default")) self.resetButton.setIcon(SHARED.theme.getIcon("revert")) + self.resetButton.setIconSize(iconSize) self.resetButton.clicked.connect(lambda: self._setSelectedMode(self.F_FILTERED)) self.modeBox = QHBoxLayout() @@ -597,6 +601,9 @@ class _HeadingsTab(NScrollablePage): sSp = CONFIG.pxInt(16) vSp = CONFIG.pxInt(12) bSp = CONFIG.pxInt(6) + iconSize = QSize(iPx, iPx) + editIcon = SHARED.theme.getIcon("edit") + trHide = self.tr("Hide") # Format Boxes # ============ @@ -608,9 +615,10 @@ class _HeadingsTab(NScrollablePage): self.fmtTitle = QLineEdit("", self) self.fmtTitle.setReadOnly(True) self.btnTitle = QToolButton(self) - self.btnTitle.setIcon(SHARED.theme.getIcon("edit")) + self.btnTitle.setIcon(editIcon) + self.btnTitle.setIconSize(iconSize) self.btnTitle.clicked.connect(lambda: self._editHeading(self.EDIT_TITLE)) - self.hdeTitle = QLabel(self.tr("Hide"), self) + self.hdeTitle = QLabel(trHide, self) self.hdeTitle.setIndent(bSp) self.swtTitle = NSwitch(self, height=iPx) @@ -625,9 +633,10 @@ class _HeadingsTab(NScrollablePage): self.fmtChapter = QLineEdit("", self) self.fmtChapter.setReadOnly(True) self.btnChapter = QToolButton(self) - self.btnChapter.setIcon(SHARED.theme.getIcon("edit")) + self.btnChapter.setIcon(editIcon) + self.btnChapter.setIconSize(iconSize) self.btnChapter.clicked.connect(lambda: self._editHeading(self.EDIT_CHAPTER)) - self.hdeChapter = QLabel(self.tr("Hide"), self) + self.hdeChapter = QLabel(trHide, self) self.hdeChapter.setIndent(bSp) self.swtChapter = NSwitch(self, height=iPx) @@ -642,9 +651,10 @@ class _HeadingsTab(NScrollablePage): self.fmtUnnumbered = QLineEdit("", self) self.fmtUnnumbered.setReadOnly(True) self.btnUnnumbered = QToolButton(self) - self.btnUnnumbered.setIcon(SHARED.theme.getIcon("edit")) + self.btnUnnumbered.setIcon(editIcon) + self.btnUnnumbered.setIconSize(iconSize) self.btnUnnumbered.clicked.connect(lambda: self._editHeading(self.EDIT_UNNUM)) - self.hdeUnnumbered = QLabel(self.tr("Hide"), self) + self.hdeUnnumbered = QLabel(trHide, self) self.hdeUnnumbered.setIndent(bSp) self.swtUnnumbered = NSwitch(self, height=iPx) @@ -659,9 +669,10 @@ class _HeadingsTab(NScrollablePage): self.fmtScene = QLineEdit("", self) self.fmtScene.setReadOnly(True) self.btnScene = QToolButton(self) - self.btnScene.setIcon(SHARED.theme.getIcon("edit")) + self.btnScene.setIcon(editIcon) + self.btnScene.setIconSize(iconSize) self.btnScene.clicked.connect(lambda: self._editHeading(self.EDIT_SCENE)) - self.hdeScene = QLabel(self.tr("Hide"), self) + self.hdeScene = QLabel(trHide, self) self.hdeScene.setIndent(bSp) self.swtScene = NSwitch(self, height=iPx) @@ -676,9 +687,10 @@ class _HeadingsTab(NScrollablePage): self.fmtHScene = QLineEdit("", self) self.fmtHScene.setReadOnly(True) self.btnHScene = QToolButton(self) - self.btnHScene.setIcon(SHARED.theme.getIcon("edit")) + self.btnHScene.setIcon(editIcon) + self.btnHScene.setIconSize(iconSize) self.btnHScene.clicked.connect(lambda: self._editHeading(self.EDIT_HSCENE)) - self.hdeHScene = QLabel(self.tr("Hide"), self) + self.hdeHScene = QLabel(trHide, self) self.hdeHScene.setIndent(bSp) self.swtHScene = NSwitch(self, height=iPx) @@ -693,9 +705,10 @@ class _HeadingsTab(NScrollablePage): self.fmtSection = QLineEdit("", self) self.fmtSection.setReadOnly(True) self.btnSection = QToolButton(self) - self.btnSection.setIcon(SHARED.theme.getIcon("edit")) + self.btnSection.setIcon(editIcon) + self.btnSection.setIconSize(iconSize) self.btnSection.clicked.connect(lambda: self._editHeading(self.EDIT_SECTION)) - self.hdeSection = QLabel(self.tr("Hide"), self) + self.hdeSection = QLabel(trHide, self) self.hdeSection.setIndent(bSp) self.swtSection = NSwitch(self, height=iPx) @@ -983,6 +996,7 @@ class _ContentTab(NScrollableForm): self._build = build iPx = SHARED.theme.baseIconSize + iconSize = QSize(iPx, iPx) # Text Content self.incBodyText = NSwitch(self, height=iPx) @@ -1001,6 +1015,7 @@ class _ContentTab(NScrollableForm): self.ignoredKeywordsButton = QToolButton(self) self.ignoredKeywordsButton.setIcon(SHARED.theme.getIcon("add")) + self.ignoredKeywordsButton.setIconSize(iconSize) self.ignoredKeywordsButton.setMenu(self.mnKeywords) self.ignoredKeywordsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) @@ -1339,6 +1354,7 @@ class _OutputTab(NScrollableForm): iPx = SHARED.theme.baseIconSize spW = 6*SHARED.theme.textNWidth + iconSize = QSize(iPx, iPx) # Open Document self.addGroupLabel(self._build.getLabel("odt")) @@ -1350,6 +1366,7 @@ class _OutputTab(NScrollableForm): self.odtPageHeader.setMinimumWidth(CONFIG.pxInt(200)) self.btnPageHeader = QToolButton(self) self.btnPageHeader.setIcon(SHARED.theme.getIcon("revert")) + self.btnPageHeader.setIconSize(iconSize) self.btnPageHeader.clicked.connect(self._resetPageHeader) self.addRow( self._build.getLabel("odt.pageHeader"), self.odtPageHeader, @@ -1395,6 +1412,7 @@ class _OutputTab(NScrollableForm): self.htmlAddStyles.setChecked(self._build.getBool("html.addStyles")) self.htmlPreserveTabs.setChecked(self._build.getBool("html.preserveTabs")) self.mdPreserveBreaks.setChecked(self._build.getBool("md.preserveBreaks")) + self.odtPageHeader.setCursorPosition(0) return def saveContent(self) -> None: diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index c71d7855..796c4e22 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -561,6 +561,8 @@ class _NewProjectForm(QWidget): iPx = SHARED.theme.baseIconSize sPx = CONFIG.pxInt(16) + iconSize = QSize(iPx, iPx) + # Project Settings # ================ @@ -581,6 +583,7 @@ class _NewProjectForm(QWidget): self.browsePath = QToolButton(self) self.browsePath.setIcon(SHARED.theme.getIcon("browse")) + self.browsePath.setIconSize(iconSize) self.browsePath.clicked.connect(self._doBrowse) self.pathBox = QHBoxLayout() @@ -592,6 +595,7 @@ class _NewProjectForm(QWidget): self.projFill.setReadOnly(True) self.browseFill = QToolButton(self) + self.browseFill.setIconSize(iconSize) self.browseFill.setIcon(SHARED.theme.getIcon("add_document")) self.fillMenu = _PopLeftDirectionMenu(self.browseFill) From 468a0e7416b5fbf6601fb88d136e5d6e5604e943 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:03:35 +0200 Subject: [PATCH 3/6] Clean up item details panel --- novelwriter/gui/itemdetails.py | 83 ++++++++++++++++------------------ novelwriter/types.py | 32 +++++++++++++ 2 files changed, 72 insertions(+), 43 deletions(-) create mode 100644 novelwriter/types.py diff --git a/novelwriter/gui/itemdetails.py b/novelwriter/gui/itemdetails.py index 27c3a017..e0e4ae50 100644 --- a/novelwriter/gui/itemdetails.py +++ b/novelwriter/gui/itemdetails.py @@ -25,25 +25,22 @@ from __future__ import annotations import logging -from typing import TYPE_CHECKING - -from PyQt5.QtGui import QFont -from PyQt5.QtCore import Qt, pyqtSlot +from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel from novelwriter import CONFIG, SHARED from novelwriter.constants import trConst, nwLabels - -if TYPE_CHECKING: # pragma: no cover - from novelwriter.guimain import GuiMain +from novelwriter.types import ( + QtAlignLeft, QtAlignLeftBase, QtAlignRight, QtAlignRightBase, QtAlignRightMiddle +) logger = logging.getLogger(__name__) class GuiItemDetails(QWidget): - def __init__(self, mainGui: GuiMain) -> None: - super().__init__(parent=mainGui) + def __init__(self, parent: QWidget) -> None: + super().__init__(parent=parent) logger.debug("Create: GuiItemDetails") @@ -56,89 +53,89 @@ class GuiItemDetails(QWidget): mPx = CONFIG.pxInt(6) fPt = SHARED.theme.fontPointSize - fntLabel = QFont() + fntLabel = self.font() fntLabel.setBold(True) fntLabel.setPointSizeF(0.9*fPt) - fntValue = QFont() + fntValue = self.font() fntValue.setPointSizeF(0.9*fPt) # Label - self.labelName = QLabel(self.tr("Label")) + self.labelName = QLabel(self.tr("Label"), self) self.labelName.setFont(fntLabel) - self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline) + self.labelName.setAlignment(QtAlignLeftBase) - self.labelIcon = QLabel("") - self.labelIcon.setAlignment(Qt.AlignRight | Qt.AlignBaseline) + self.labelIcon = QLabel("", self) + self.labelIcon.setAlignment(QtAlignRightBase) - self.labelData = QLabel("") + self.labelData = QLabel("", self) self.labelData.setFont(fntValue) - self.labelData.setAlignment(Qt.AlignLeft | Qt.AlignBaseline) + self.labelData.setAlignment(QtAlignLeftBase) self.labelData.setWordWrap(True) # Status - self.statusName = QLabel(self.tr("Status")) + self.statusName = QLabel(self.tr("Status"), self) self.statusName.setFont(fntLabel) - self.statusName.setAlignment(Qt.AlignLeft) + self.statusName.setAlignment(QtAlignLeft) - self.statusIcon = QLabel("") - self.statusIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter) + self.statusIcon = QLabel("", self) + self.statusIcon.setAlignment(QtAlignRightMiddle) - self.statusData = QLabel("") + self.statusData = QLabel("", self) self.statusData.setFont(fntValue) - self.statusData.setAlignment(Qt.AlignLeft) + self.statusData.setAlignment(QtAlignLeft) # Class - self.className = QLabel(self.tr("Class")) + self.className = QLabel(self.tr("Class"), self) self.className.setFont(fntLabel) - self.className.setAlignment(Qt.AlignLeft) + self.className.setAlignment(QtAlignLeft) - self.classIcon = QLabel("") - self.classIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter) + self.classIcon = QLabel("", self) + self.classIcon.setAlignment(QtAlignRightMiddle) - self.classData = QLabel("") + self.classData = QLabel("", self) self.classData.setFont(fntValue) - self.classData.setAlignment(Qt.AlignLeft) + self.classData.setAlignment(QtAlignLeft) # Layout - self.usageName = QLabel(self.tr("Usage")) + self.usageName = QLabel(self.tr("Usage"), self) self.usageName.setFont(fntLabel) - self.usageName.setAlignment(Qt.AlignLeft) + self.usageName.setAlignment(QtAlignLeft) - self.usageIcon = QLabel("") - self.usageIcon.setAlignment(Qt.AlignRight | Qt.AlignVCenter) + self.usageIcon = QLabel("", self) + self.usageIcon.setAlignment(QtAlignRightMiddle) - self.usageData = QLabel("") + self.usageData = QLabel("", self) self.usageData.setFont(fntValue) - self.usageData.setAlignment(Qt.AlignLeft) + self.usageData.setAlignment(QtAlignLeft) self.usageData.setWordWrap(True) # Character Count - self.cCountName = QLabel(" "+self.tr("Characters")) + self.cCountName = QLabel(" "+self.tr("Characters"), self) self.cCountName.setFont(fntLabel) - self.cCountName.setAlignment(Qt.AlignRight) + self.cCountName.setAlignment(QtAlignRight) self.cCountData = QLabel("") self.cCountData.setFont(fntValue) - self.cCountData.setAlignment(Qt.AlignRight) + self.cCountData.setAlignment(QtAlignRight) # Word Count self.wCountName = QLabel(" "+self.tr("Words")) self.wCountName.setFont(fntLabel) - self.wCountName.setAlignment(Qt.AlignRight) + self.wCountName.setAlignment(QtAlignRight) self.wCountData = QLabel("") self.wCountData.setFont(fntValue) - self.wCountData.setAlignment(Qt.AlignRight) + self.wCountData.setAlignment(QtAlignRight) # Paragraph Count self.pCountName = QLabel(" "+self.tr("Paragraphs")) self.pCountName.setFont(fntLabel) - self.pCountName.setAlignment(Qt.AlignRight) + self.pCountName.setAlignment(QtAlignRight) self.pCountData = QLabel("") self.pCountData.setFont(fntValue) - self.pCountData.setAlignment(Qt.AlignRight) + self.pCountData.setAlignment(QtAlignRight) # Assemble self.mainBox = QGridLayout(self) @@ -234,7 +231,7 @@ class GuiItemDetails(QWidget): return self._handle = tHandle - iPx = int(round(0.8*SHARED.theme.baseIconSize)) + iPx = int(round(0.9*SHARED.theme.baseIconSize)) # Label # ===== diff --git a/novelwriter/types.py b/novelwriter/types.py new file mode 100644 index 00000000..6fc1f060 --- /dev/null +++ b/novelwriter/types.py @@ -0,0 +1,32 @@ +""" +novelWriter – Typings +===================== + +File History: +Created: 2024-04-01 [2.4rc1] + +This file is a part of novelWriter +Copyright 2018–2024, Veronica Berglyd Olsen + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +from __future__ import annotations + +from PyQt5.QtCore import Qt + +QtAlignLeft = Qt.AlignmentFlag.AlignLeft +QtAlignRight = Qt.AlignmentFlag.AlignRight +QtAlignLeftBase = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBaseline +QtAlignRightBase = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignBaseline +QtAlignRightMiddle = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter From c3467d89c207aac8501c76c15aa0fd0a38f8f0ae Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:27:18 +0200 Subject: [PATCH 4/6] Collect all alignment flags into a new types module --- novelwriter/dialogs/about.py | 6 +- novelwriter/dialogs/preferences.py | 13 ++-- novelwriter/dialogs/quotes.py | 5 +- novelwriter/error.py | 4 +- novelwriter/extensions/circularprogress.py | 4 +- novelwriter/extensions/configlayout.py | 2 - novelwriter/extensions/pagedsidebar.py | 6 +- novelwriter/extensions/switchbox.py | 15 ++-- novelwriter/gui/doceditor.py | 25 +++--- novelwriter/gui/docviewer.py | 5 +- novelwriter/gui/noveltree.py | 3 +- novelwriter/gui/outline.py | 88 +++++++++++----------- novelwriter/gui/projtree.py | 9 ++- novelwriter/gui/search.py | 5 +- novelwriter/tools/lipsum.py | 11 +-- novelwriter/tools/manusbuild.py | 9 ++- novelwriter/tools/manuscript.py | 37 ++++----- novelwriter/tools/manussettings.py | 9 ++- novelwriter/tools/noveldetails.py | 21 +++--- novelwriter/tools/welcome.py | 13 ++-- novelwriter/tools/writingstats.py | 29 +++---- novelwriter/types.py | 17 ++++- tests/test_gui/test_gui_doceditor.py | 9 ++- tests/test_tools/test_tools_manuscript.py | 21 +++--- 24 files changed, 195 insertions(+), 171 deletions(-) diff --git a/novelwriter/dialogs/about.py b/novelwriter/dialogs/about.py index 0ff62ff3..4b1ab060 100644 --- a/novelwriter/dialogs/about.py +++ b/novelwriter/dialogs/about.py @@ -26,7 +26,6 @@ from __future__ import annotations import logging from PyQt5.QtGui import QCloseEvent, QColor -from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QTextBrowser, QVBoxLayout, QWidget @@ -36,6 +35,7 @@ from novelwriter import CONFIG, SHARED from novelwriter.common import readTextFile from novelwriter.extensions.configlayout import NColourLabel from novelwriter.extensions.versioninfo import VersionInfoWidget +from novelwriter.types import QtAlignRightTop logger = logging.getLogger(__name__) @@ -100,10 +100,8 @@ class GuiAbout(QDialog): self.innerBox.addSpacing(hB) self.innerBox.addWidget(self.btnBox) - topRight = Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight - self.outerBox = QHBoxLayout() - self.outerBox.addWidget(self.nwLogo, 0, topRight) + self.outerBox.addWidget(self.nwLogo, 0, QtAlignRightTop) self.outerBox.addLayout(self.innerBox, 1) self.setLayout(self.outerBox) diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index d79f81ef..476275ca 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -37,10 +37,11 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.constants import nwConst, nwUnicode from novelwriter.dialogs.quotes import GuiQuoteSelect -from novelwriter.extensions.switch import NSwitch -from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm +from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox from novelwriter.extensions.pagedsidebar import NPagedSideBar +from novelwriter.extensions.switch import NSwitch +from novelwriter.types import QtAlignCenter logger = logging.getLogger(__name__) @@ -679,7 +680,7 @@ class GuiPreferences(QDialog): self.quoteSym["SO"].setMaxLength(1) self.quoteSym["SO"].setReadOnly(True) self.quoteSym["SO"].setFixedWidth(qWidth) - self.quoteSym["SO"].setAlignment(Qt.AlignCenter) + self.quoteSym["SO"].setAlignment(QtAlignCenter) self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen) self.btnSingleStyleO = QToolButton(self) self.btnSingleStyleO.setIcon(mIcon) @@ -695,7 +696,7 @@ class GuiPreferences(QDialog): self.quoteSym["SC"].setMaxLength(1) self.quoteSym["SC"].setReadOnly(True) self.quoteSym["SC"].setFixedWidth(qWidth) - self.quoteSym["SC"].setAlignment(Qt.AlignCenter) + self.quoteSym["SC"].setAlignment(QtAlignCenter) self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose) self.btnSingleStyleC = QToolButton(self) self.btnSingleStyleC.setIcon(mIcon) @@ -712,7 +713,7 @@ class GuiPreferences(QDialog): self.quoteSym["DO"].setMaxLength(1) self.quoteSym["DO"].setReadOnly(True) self.quoteSym["DO"].setFixedWidth(qWidth) - self.quoteSym["DO"].setAlignment(Qt.AlignCenter) + self.quoteSym["DO"].setAlignment(QtAlignCenter) self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen) self.btnDoubleStyleO = QToolButton(self) self.btnDoubleStyleO.setIcon(mIcon) @@ -728,7 +729,7 @@ class GuiPreferences(QDialog): self.quoteSym["DC"].setMaxLength(1) self.quoteSym["DC"].setReadOnly(True) self.quoteSym["DC"].setFixedWidth(qWidth) - self.quoteSym["DC"].setAlignment(Qt.AlignCenter) + self.quoteSym["DC"].setAlignment(QtAlignCenter) self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose) self.btnDoubleStyleC = QToolButton(self) self.btnDoubleStyleC.setIcon(mIcon) diff --git a/novelwriter/dialogs/quotes.py b/novelwriter/dialogs/quotes.py index 8ab4ab80..dac6fbc3 100644 --- a/novelwriter/dialogs/quotes.py +++ b/novelwriter/dialogs/quotes.py @@ -34,6 +34,7 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG from novelwriter.constants import trConst, nwQuotes +from novelwriter.types import QtAlignCenter, QtAlignTop logger = logging.getLogger(__name__) @@ -68,7 +69,7 @@ class GuiQuoteSelect(QDialog): self.previewLabel = QLabel(current) self.previewLabel.setFont(lblFont) self.previewLabel.setFixedSize(QSize(pxW, pxH)) - self.previewLabel.setAlignment(Qt.AlignCenter) + self.previewLabel.setAlignment(QtAlignCenter) self.previewLabel.setFrameStyle(QFrame.Box | QFrame.Plain) # Quote Symbols @@ -94,7 +95,7 @@ class GuiQuoteSelect(QDialog): self.buttonBox.rejected.connect(self.reject) # Assemble - self.labelBox.addWidget(self.previewLabel, 0, Qt.AlignTop) + self.labelBox.addWidget(self.previewLabel, 0, QtAlignTop) self.labelBox.addStretch(1) self.innerBox.addLayout(self.labelBox) diff --git a/novelwriter/error.py b/novelwriter/error.py index 1932e6b7..37b40857 100644 --- a/novelwriter/error.py +++ b/novelwriter/error.py @@ -93,8 +93,8 @@ class NWErrorMessage(QDialog): # Assemble self.mainBox = QGridLayout() - self.mainBox.addWidget(self.msgIcon, 0, 0, 2, 1, Qt.AlignTop) - self.mainBox.addWidget(self.msgHead, 0, 1, 1, 1, Qt.AlignTop) + self.mainBox.addWidget(self.msgIcon, 0, 0, 2, 1, Qt.AlignmentFlag.AlignTop) + self.mainBox.addWidget(self.msgHead, 0, 1, 1, 1, Qt.AlignmentFlag.AlignTop) self.mainBox.addWidget(self.msgBody, 1, 1, 1, 1) self.mainBox.addWidget(self.btnBox, 2, 0, 1, 2) self.mainBox.setSpacing(16) diff --git a/novelwriter/extensions/circularprogress.py b/novelwriter/extensions/circularprogress.py index c7ece503..70d84f31 100644 --- a/novelwriter/extensions/circularprogress.py +++ b/novelwriter/extensions/circularprogress.py @@ -29,6 +29,8 @@ from PyQt5.QtGui import QBrush, QColor, QPaintEvent, QPainter, QPen from PyQt5.QtCore import QRect, Qt from PyQt5.QtWidgets import QProgressBar, QSizePolicy, QWidget +from novelwriter.types import QtAlignCenter + class NProgressCircle(QProgressBar): """Extension: Circular Progress Widget @@ -94,7 +96,7 @@ class NProgressCircle(QProgressBar): painter.setPen(self._cPen) painter.drawArc(self._cRect, 90*16, -angle) painter.setPen(self._tColor) - painter.drawText(self._cRect, Qt.AlignCenter, self._text or f"{progress:.1f} %") + painter.drawText(self._cRect, QtAlignCenter, self._text or f"{progress:.1f} %") return # END Class NProgressCircle diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py index 280caedc..1357ea19 100644 --- a/novelwriter/extensions/configlayout.py +++ b/novelwriter/extensions/configlayout.py @@ -37,8 +37,6 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG DEFAULT_SCALE = 0.9 -RIGHT_TOP = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop -LEFT_TOP = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop class NFixedPage(QFrame): diff --git a/novelwriter/extensions/pagedsidebar.py b/novelwriter/extensions/pagedsidebar.py index 5cba8e41..5fb15516 100644 --- a/novelwriter/extensions/pagedsidebar.py +++ b/novelwriter/extensions/pagedsidebar.py @@ -32,6 +32,8 @@ from PyQt5.QtWidgets import ( QStyleOptionToolButton, QToolBar, QToolButton, QWidget ) +from novelwriter.types import QtAlignLeft + class NPagedSideBar(QToolBar): """Extensions: Paged Side Bar @@ -171,7 +173,7 @@ class _NPagedToolButton(QToolButton): paint.setPen(textCol) paint.setOpacity(1.0) - paint.drawText(QRectF(self._lM, self._tM, tW, tH), Qt.AlignLeft, self.text()) + paint.drawText(QRectF(self._lM, self._tM, tW, tH), QtAlignLeft, self.text()) tC = self.height()//2 tW = self.width() - self._aH - self._lM @@ -223,7 +225,7 @@ class _NPagedToolLabel(QLabel): paint.setPen(self._textCol) paint.setOpacity(1.0) - paint.drawText(QRectF(self._lM, self._tM, tW, tH), Qt.AlignLeft, self.text()) + paint.drawText(QRectF(self._lM, self._tM, tW, tH), QtAlignLeft, self.text()) return diff --git a/novelwriter/extensions/switchbox.py b/novelwriter/extensions/switchbox.py index 28f9d81a..e3913288 100644 --- a/novelwriter/extensions/switchbox.py +++ b/novelwriter/extensions/switchbox.py @@ -24,10 +24,11 @@ along with this program. If not, see . from __future__ import annotations from PyQt5.QtGui import QIcon -from PyQt5.QtCore import Qt, pyqtSignal +from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QGridLayout, QLabel, QScrollArea, QSizePolicy, QWidget from novelwriter.extensions.switch import NSwitch +from novelwriter.types import QtAlignLeft, QtAlignRight, QtAlignRightMiddle class NSwitchBox(QScrollArea): @@ -72,7 +73,7 @@ class NSwitchBox(QScrollArea): font = label.font() font.setBold(True) label.setFont(font) - self._content.addWidget(label, self._index, 0, 1, 3, Qt.AlignLeft) + self._content.addWidget(label, self._index, 0, 1, 3, QtAlignLeft) self._widgets.append(label) self._bumpIndex() return @@ -80,17 +81,17 @@ class NSwitchBox(QScrollArea): def addItem(self, qIcon: QIcon, text: str, identifier: str, default: bool = False) -> None: """Add an item to the content box.""" icon = QLabel("") - icon.setAlignment(Qt.AlignRight | Qt.AlignVCenter) + icon.setAlignment(QtAlignRightMiddle) icon.setPixmap(qIcon.pixmap(self._sIcon, self._sIcon)) - self._content.addWidget(icon, self._index, 0, Qt.AlignLeft) + self._content.addWidget(icon, self._index, 0, QtAlignLeft) label = QLabel(text) - self._content.addWidget(label, self._index, 1, Qt.AlignLeft) + self._content.addWidget(label, self._index, 1, QtAlignLeft) switch = NSwitch(self, height=self._hSwitch) switch.setChecked(default) switch.toggled.connect(lambda state: self._emitSwitchSignal(identifier, state)) - self._content.addWidget(switch, self._index, 2, Qt.AlignRight) + self._content.addWidget(switch, self._index, 2, QtAlignRight) self._widgets.append(switch) self._bumpIndex() @@ -101,7 +102,7 @@ class NSwitchBox(QScrollArea): """Add a blank entry in the content box.""" spacer = QWidget() spacer.setFixedHeight(int(0.5*self._sIcon)) - self._content.addWidget(spacer, self._index, 0, 1, 3, Qt.AlignLeft) + self._content.addWidget(spacer, self._index, 0, 1, 3, QtAlignLeft) self._widgets.append(spacer) self._bumpIndex() return diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index cd90bcfd..9f66c72b 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -64,6 +64,9 @@ from novelwriter.gui.editordocument import GuiTextDocument from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON from novelwriter.text.counting import standardCounter from novelwriter.tools.lipsum import GuiLipsum +from novelwriter.types import ( + QtAlignCenterTop, QtAlignJustify, QtAlignLeft, QtAlignLeftTop, QtAlignRight +) if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -339,7 +342,7 @@ class GuiDocEditor(QPlainTextEdit): options = QTextOption() if CONFIG.doJustify: - options.setAlignment(Qt.AlignmentFlag.AlignJustify) + options.setAlignment(QtAlignJustify) if CONFIG.showTabsNSpaces: options.setFlags(options.flags() | QTextOption.Flag.ShowTabsAndSpaces) if CONFIG.showLineEndings: @@ -2514,8 +2517,8 @@ class GuiDocEditSearch(QFrame): self.replaceButton.setToolTip(self.tr("Find and replace in current document")) self.replaceButton.clicked.connect(self._doReplace) - self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, Qt.AlignmentFlag.AlignLeft) - self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 3, Qt.AlignmentFlag.AlignRight) + self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, QtAlignLeft) + self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 3, QtAlignRight) self.mainBox.addWidget(self.showReplace, 1, 0, 1, 1) self.mainBox.addWidget(self.searchBox, 1, 1, 1, 2) self.mainBox.addWidget(self.searchButton, 1, 3, 1, 1) @@ -2830,7 +2833,7 @@ class GuiDocEditHeader(QWidget): self.itemTitle.setMargin(0) self.itemTitle.setContentsMargins(0, 0, 0, 0) self.itemTitle.setAutoFillBackground(True) - self.itemTitle.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop) + self.itemTitle.setAlignment(QtAlignCenterTop) self.itemTitle.setFixedHeight(iPx) lblFont = self.itemTitle.font() @@ -3053,13 +3056,11 @@ class GuiDocEditFooter(QWidget): self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) - alLeftTop = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop - # Status self.statusIcon = QLabel("", self) self.statusIcon.setContentsMargins(0, 0, 0, 0) self.statusIcon.setFixedHeight(iPx) - self.statusIcon.setAlignment(alLeftTop) + self.statusIcon.setAlignment(QtAlignLeftTop) self.statusText = QLabel(self.tr("Status")) self.statusText.setIndent(0) @@ -3067,14 +3068,14 @@ class GuiDocEditFooter(QWidget): self.statusText.setContentsMargins(0, 0, 0, 0) self.statusText.setAutoFillBackground(True) self.statusText.setFixedHeight(fPx) - self.statusText.setAlignment(alLeftTop) + self.statusText.setAlignment(QtAlignLeftTop) self.statusText.setFont(lblFont) # Lines self.linesIcon = QLabel("", self) self.linesIcon.setContentsMargins(0, 0, 0, 0) self.linesIcon.setFixedHeight(iPx) - self.linesIcon.setAlignment(alLeftTop) + self.linesIcon.setAlignment(QtAlignLeftTop) self.linesText = QLabel("", self) self.linesText.setIndent(0) @@ -3082,14 +3083,14 @@ class GuiDocEditFooter(QWidget): self.linesText.setContentsMargins(0, 0, 0, 0) self.linesText.setAutoFillBackground(True) self.linesText.setFixedHeight(fPx) - self.linesText.setAlignment(alLeftTop) + self.linesText.setAlignment(QtAlignLeftTop) self.linesText.setFont(lblFont) # Words self.wordsIcon = QLabel("", self) self.wordsIcon.setContentsMargins(0, 0, 0, 0) self.wordsIcon.setFixedHeight(iPx) - self.wordsIcon.setAlignment(alLeftTop) + self.wordsIcon.setAlignment(QtAlignLeftTop) self.wordsText = QLabel("", self) self.wordsText.setIndent(0) @@ -3097,7 +3098,7 @@ class GuiDocEditFooter(QWidget): self.wordsText.setContentsMargins(0, 0, 0, 0) self.wordsText.setAutoFillBackground(True) self.wordsText.setFixedHeight(fPx) - self.wordsText.setAlignment(alLeftTop) + self.wordsText.setAlignment(QtAlignLeftTop) self.wordsText.setFont(lblFont) # Assemble Layout diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index b3e405e1..d77f4cd4 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -49,6 +49,7 @@ from novelwriter.error import logException from novelwriter.extensions.eventfilters import WheelEventFilter from novelwriter.extensions.modified import NIconToolButton from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON +from novelwriter.types import QtAlignCenterTop, QtAlignJustify logger = logging.getLogger(__name__) @@ -164,7 +165,7 @@ class GuiDocViewer(QTextBrowser): self.document().setDocumentMargin(0) options = QTextOption() if CONFIG.doJustify: - options.setAlignment(Qt.AlignmentFlag.AlignJustify) + options.setAlignment(QtAlignJustify) self.document().setDefaultTextOption(options) # Scroll bars @@ -639,7 +640,7 @@ class GuiDocViewHeader(QWidget): self.itemTitle.setMargin(0) self.itemTitle.setContentsMargins(0, 0, 0, 0) self.itemTitle.setAutoFillBackground(True) - self.itemTitle.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop) + self.itemTitle.setAlignment(QtAlignCenterTop) self.itemTitle.setFixedHeight(iPx) lblFont = self.itemTitle.font() diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index 95a6e25f..bed371bb 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -47,6 +47,7 @@ from novelwriter.enum import nwDocMode, nwItemClass, nwOutline from novelwriter.extensions.modified import NIconToolButton from novelwriter.extensions.novelselector import NovelSelector from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON +from novelwriter.types import QtAlignRight if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -676,7 +677,7 @@ class GuiNovelTree(QTreeWidget): newItem.setData(self.C_DATA, self.D_HANDLE, tHandle) newItem.setData(self.C_DATA, self.D_TITLE, sTitle) newItem.setData(self.C_DATA, self.D_KEY, tKey) - newItem.setTextAlignment(self.C_WORDS, Qt.AlignmentFlag.AlignRight) + newItem.setTextAlignment(self.C_WORDS, QtAlignRight) self._updateTreeItemValues(newItem, novIdx, tHandle, sTitle) self._treeMap[tKey] = newItem diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 262c6c49..ffaeb0f0 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -48,6 +48,7 @@ from novelwriter.error import logException from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe from novelwriter.constants import nwHeaders, trConst, nwKeyWords, nwLabels from novelwriter.extensions.novelselector import NovelSelector +from novelwriter.types import QtAlignLeftTop, QtAlignRight, QtAlignRightTop logger = logging.getLogger(__name__) @@ -675,11 +676,11 @@ class GuiOutlineTree(QTreeWidget): headItem = self.headerItem() if isinstance(headItem, QTreeWidgetItem): headItem.setTextAlignment( - self._colIdx[nwOutline.CCOUNT], Qt.AlignmentFlag.AlignRight) + self._colIdx[nwOutline.CCOUNT], QtAlignRight) headItem.setTextAlignment( - self._colIdx[nwOutline.WCOUNT], Qt.AlignmentFlag.AlignRight) + self._colIdx[nwOutline.WCOUNT], QtAlignRight) headItem.setTextAlignment( - self._colIdx[nwOutline.PCOUNT], Qt.AlignmentFlag.AlignRight) + self._colIdx[nwOutline.PCOUNT], QtAlignRight) novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True) for _, tHandle, sTitle, novIdx in novStruct: @@ -705,9 +706,9 @@ class GuiOutlineTree(QTreeWidget): trItem.setText(self._colIdx[nwOutline.CCOUNT], f"{novIdx.charCount:n}") trItem.setText(self._colIdx[nwOutline.WCOUNT], f"{novIdx.wordCount:n}") trItem.setText(self._colIdx[nwOutline.PCOUNT], f"{novIdx.paraCount:n}") - trItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT], Qt.AlignmentFlag.AlignRight) - trItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT], Qt.AlignmentFlag.AlignRight) - trItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT], Qt.AlignmentFlag.AlignRight) + trItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT], QtAlignRight) + trItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT], QtAlignRight) + trItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT], QtAlignRight) refs = SHARED.project.index.getReferences(tHandle, sTitle) trItem.setText(self._colIdx[nwOutline.POV], ", ".join(refs[nwKeyWords.POV_KEY])) @@ -834,9 +835,9 @@ class GuiOutlineDetails(QScrollArea): self.cCValue.setMinimumWidth(wCount) self.wCValue.setMinimumWidth(wCount) self.pCValue.setMinimumWidth(wCount) - self.cCValue.setAlignment(Qt.AlignRight) - self.wCValue.setAlignment(Qt.AlignRight) - self.pCValue.setAlignment(Qt.AlignRight) + self.cCValue.setAlignment(QtAlignRight) + self.wCValue.setAlignment(QtAlignRight) + self.pCValue.setAlignment(QtAlignRight) # Synopsis self.synopLabel = QLabel(self.tr("Synopsis")) @@ -844,7 +845,7 @@ class GuiOutlineDetails(QScrollArea): self.synopValue = QLabel("") self.synopValue.setWordWrap(True) - self.synopValue.setAlignment(Qt.AlignTop | Qt.AlignLeft) + self.synopValue.setAlignment(QtAlignLeftTop) self.synopLWrap = QHBoxLayout() self.synopLWrap.addWidget(self.synopValue, 1) @@ -925,23 +926,20 @@ class GuiOutlineDetails(QScrollArea): self.mainForm = QGridLayout() self.mainGroup.setLayout(self.mainForm) - topLeft = Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft - topRight = Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight - - self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, topLeft) - self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1, topLeft) - self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1, topLeft) - self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1, topRight) - self.mainForm.addWidget(self.fileLabel, 1, 0, 1, 1, topLeft) - self.mainForm.addWidget(self.fileValue, 1, 1, 1, 1, topLeft) - self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1, topLeft) - self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1, topRight) - self.mainForm.addWidget(self.itemLabel, 2, 0, 1, 1, topLeft) - self.mainForm.addWidget(self.itemValue, 2, 1, 1, 1, topLeft) - self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1, topLeft) - self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, topRight) - self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, topLeft) - self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, topLeft) + self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1, QtAlignRightTop) + self.mainForm.addWidget(self.fileLabel, 1, 0, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.fileValue, 1, 1, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1, QtAlignRightTop) + self.mainForm.addWidget(self.itemLabel, 2, 0, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.itemValue, 2, 1, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1, QtAlignLeftTop) + self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, QtAlignRightTop) + self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, QtAlignLeftTop) + self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, QtAlignLeftTop) self.mainForm.setColumnStretch(1, 1) self.mainForm.setRowStretch(4, 1) @@ -953,24 +951,24 @@ class GuiOutlineDetails(QScrollArea): self.tagsForm = QGridLayout() self.tagsGroup.setLayout(self.tagsForm) - self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.focKeyLabel, 1, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.timKeyLabel, 4, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.objKeyLabel, 6, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1, topLeft) - self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1, topLeft) - self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1, topLeft) + self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.focKeyLabel, 1, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.timKeyLabel, 4, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.objKeyLabel, 6, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.entKeyLabel, 7, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, 1, 1, QtAlignLeftTop) + self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, 1, 1, QtAlignLeftTop) + self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, 1, 1, QtAlignLeftTop) self.tagsForm.setColumnStretch(1, 1) self.tagsForm.setRowStretch(8, 1) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 30958582..014195dd 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -54,6 +54,7 @@ from novelwriter.dialogs.projectsettings import GuiProjectSettings from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout from novelwriter.extensions.modified import NIconToolButton from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON +from novelwriter.types import QtAlignLeft, QtAlignRight if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -1585,10 +1586,10 @@ class GuiProjectTree(QTreeWidget): newItem.setText(self.C_ACTIVE, "") newItem.setText(self.C_STATUS, "") - newItem.setTextAlignment(self.C_NAME, Qt.AlignmentFlag.AlignLeft) - newItem.setTextAlignment(self.C_COUNT, Qt.AlignmentFlag.AlignRight) - newItem.setTextAlignment(self.C_ACTIVE, Qt.AlignmentFlag.AlignLeft) - newItem.setTextAlignment(self.C_STATUS, Qt.AlignmentFlag.AlignLeft) + newItem.setTextAlignment(self.C_NAME, QtAlignLeft) + newItem.setTextAlignment(self.C_COUNT, QtAlignRight) + newItem.setTextAlignment(self.C_ACTIVE, QtAlignLeft) + newItem.setTextAlignment(self.C_STATUS, QtAlignLeft) newItem.setData(self.C_DATA, self.D_HANDLE, tHandle) newItem.setData(self.C_DATA, self.D_WORDS, 0) diff --git a/novelwriter/gui/search.py b/novelwriter/gui/search.py index d0aafe0b..f2c83e65 100644 --- a/novelwriter/gui/search.py +++ b/novelwriter/gui/search.py @@ -38,6 +38,7 @@ from novelwriter import CONFIG, SHARED from novelwriter.common import checkInt, cssCol from novelwriter.core.coretools import DocSearch from novelwriter.core.item import NWItem +from novelwriter.types import QtAlignMiddle, QtAlignRight logger = logging.getLogger(__name__) @@ -124,7 +125,7 @@ class GuiProjectSearch(QWidget): # Assemble self.headerBox = QHBoxLayout() self.headerBox.addWidget(self.viewLabel, 1) - self.headerBox.addWidget(self.searchOpt, 0, Qt.AlignmentFlag.AlignVCenter) + self.headerBox.addWidget(self.searchOpt, 0, QtAlignMiddle) self.headerBox.setContentsMargins(0, 0, 0, 0) self.headerBox.setSpacing(0) @@ -328,7 +329,7 @@ class GuiProjectSearch(QWidget): tItem.setIcon(self.C_NAME, docIcon) tItem.setData(self.C_NAME, self.D_HANDLE, tHandle) tItem.setText(self.C_COUNT, f"({len(results):n}{ext})") - tItem.setTextAlignment(self.C_COUNT, Qt.AlignmentFlag.AlignRight) + tItem.setTextAlignment(self.C_COUNT, QtAlignRight) tItem.setForeground(self.C_COUNT, self.palette().highlight()) index = self._map.get(tHandle, (self.searchResult.topLevelItemCount(), 0.0))[0] diff --git a/novelwriter/tools/lipsum.py b/novelwriter/tools/lipsum.py index 06c4970d..3c05d99c 100644 --- a/novelwriter/tools/lipsum.py +++ b/novelwriter/tools/lipsum.py @@ -35,6 +35,7 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.common import readTextFile from novelwriter.extensions.switch import NSwitch +from novelwriter.types import QtAlignLeft, QtAlignRight logger = logging.getLogger(__name__) @@ -82,11 +83,11 @@ class GuiLipsum(QDialog): self.randSwitch = NSwitch(self) self.formBox = QGridLayout() - self.formBox.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignLeft) - self.formBox.addWidget(self.paraLabel, 1, 0, 1, 1, Qt.AlignLeft) - self.formBox.addWidget(self.paraCount, 1, 1, 1, 1, Qt.AlignRight) - self.formBox.addWidget(self.randLabel, 2, 0, 1, 1, Qt.AlignLeft) - self.formBox.addWidget(self.randSwitch, 2, 1, 1, 1, Qt.AlignRight) + self.formBox.addWidget(self.headLabel, 0, 0, 1, 2, QtAlignLeft) + self.formBox.addWidget(self.paraLabel, 1, 0, 1, 1, QtAlignLeft) + self.formBox.addWidget(self.paraCount, 1, 1, 1, 1, QtAlignRight) + self.formBox.addWidget(self.randLabel, 2, 0, 1, 1, QtAlignLeft) + self.formBox.addWidget(self.randSwitch, 2, 1, 1, 1, QtAlignRight) self.formBox.setVerticalSpacing(vSp) self.formBox.setRowStretch(3, 1) self.innerBox.addLayout(self.formBox) diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index 9f4a1039..501cb4bd 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -36,13 +36,14 @@ from PyQt5.QtWidgets import ( ) from novelwriter import CONFIG, SHARED -from novelwriter.enum import nwBuildFmt from novelwriter.common import makeFileNameSafe, openExternalPath from novelwriter.constants import nwLabels -from novelwriter.core.item import NWItem -from novelwriter.core.docbuild import NWBuildDocument from novelwriter.core.buildsettings import BuildSettings +from novelwriter.core.docbuild import NWBuildDocument +from novelwriter.core.item import NWItem +from novelwriter.enum import nwBuildFmt from novelwriter.extensions.simpleprogress import NProgressSimple +from novelwriter.types import QtAlignCenter logger = logging.getLogger(__name__) @@ -199,7 +200,7 @@ class GuiManuscriptBuild(QDialog): ]) self.outerBox = QVBoxLayout() - self.outerBox.addWidget(self.lblMain, 0, Qt.AlignCenter) + self.outerBox.addWidget(self.lblMain, 0, QtAlignCenter) self.outerBox.addSpacing(sp16) self.outerBox.addWidget(self.mainSplit, 1) self.outerBox.addSpacing(sp4) diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index 977a10be..fa67903f 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -52,6 +52,9 @@ from novelwriter.extensions.modified import NIconToolButton from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON from novelwriter.tools.manusbuild import GuiManuscriptBuild from novelwriter.tools.manussettings import GuiBuildSettings +from novelwriter.types import ( + QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignRight, QtAlignTop +) if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -777,7 +780,7 @@ class _PreviewWidget(QTextBrowser): self.ageLabel.setFont(aFont) self.ageLabel.setPalette(aPalette) self.ageLabel.setAutoFillBackground(True) - self.ageLabel.setAlignment(Qt.AlignmentFlag.AlignCenter) + self.ageLabel.setAlignment(QtAlignCenter) self.ageLabel.setFixedHeight(int(2.1*SHARED.theme.fontPixelSize)) # Progress @@ -816,9 +819,9 @@ class _PreviewWidget(QTextBrowser): """Enable/disable the justify text option.""" pOptions = self.document().defaultTextOption() if state: - pOptions.setAlignment(Qt.AlignmentFlag.AlignJustify) + pOptions.setAlignment(QtAlignJustify) else: - pOptions.setAlignment(Qt.AlignmentFlag.AlignAbsolute) + pOptions.setAlignment(QtAlignAbsolute) self.document().setDefaultTextOption(pOptions) return @@ -993,8 +996,8 @@ class _StatsWidget(QWidget): self.mainStack.addWidget(self.maxWidget) self.outerBox = QHBoxLayout() - self.outerBox.addWidget(self.toggleButton, 0, Qt.AlignmentFlag.AlignTop) - self.outerBox.addWidget(self.mainStack, 1, Qt.AlignmentFlag.AlignTop) + self.outerBox.addWidget(self.toggleButton, 0, QtAlignTop) + self.outerBox.addWidget(self.mainStack, 1, QtAlignTop) self.outerBox.setContentsMargins(0, 0, 0, 0) self.setLayout(self.outerBox) @@ -1083,8 +1086,6 @@ class _StatsWidget(QWidget): hPx = CONFIG.pxInt(12) vPx = CONFIG.pxInt(4) - alignRight = Qt.AlignmentFlag.AlignRight - # Left Column self.maxTotalWords = QLabel(self) self.maxHeaderWords = QLabel(self) @@ -1092,11 +1093,11 @@ class _StatsWidget(QWidget): self.maxTitleCount = QLabel(self) self.maxParCount = QLabel(self) - self.maxTotalWords.setAlignment(alignRight) - self.maxHeaderWords.setAlignment(alignRight) - self.maxTextWords.setAlignment(alignRight) - self.maxTitleCount.setAlignment(alignRight) - self.maxParCount.setAlignment(alignRight) + self.maxTotalWords.setAlignment(QtAlignRight) + self.maxHeaderWords.setAlignment(QtAlignRight) + self.maxTextWords.setAlignment(QtAlignRight) + self.maxTitleCount.setAlignment(QtAlignRight) + self.maxParCount.setAlignment(QtAlignRight) self.leftForm = QFormLayout() self.leftForm.addRow(self.tr("Words"), self.maxTotalWords) @@ -1117,13 +1118,13 @@ class _StatsWidget(QWidget): self.maxHeaderWordChars = QLabel(self) self.maxTextWordChars = QLabel(self) - self.maxTotalChars.setAlignment(alignRight) - self.maxHeaderChars.setAlignment(alignRight) - self.maxTextChars.setAlignment(alignRight) + self.maxTotalChars.setAlignment(QtAlignRight) + self.maxHeaderChars.setAlignment(QtAlignRight) + self.maxTextChars.setAlignment(QtAlignRight) - self.maxTotalWordChars.setAlignment(alignRight) - self.maxHeaderWordChars.setAlignment(alignRight) - self.maxTextWordChars.setAlignment(alignRight) + self.maxTotalWordChars.setAlignment(QtAlignRight) + self.maxHeaderWordChars.setAlignment(QtAlignRight) + self.maxTextWordChars.setAlignment(QtAlignRight) self.rightForm = QFormLayout() self.rightForm.addRow(self.tr("Characters"), self.maxTotalChars) diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index a6bb27fd..d36a0307 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -39,13 +39,14 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, trConst from novelwriter.core.buildsettings import BuildSettings, FilterMode -from novelwriter.extensions.switch import NSwitch -from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox -from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.extensions.configlayout import ( NColourLabel, NFixedPage, NScrollableForm, NScrollablePage ) +from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox from novelwriter.extensions.pagedsidebar import NPagedSideBar +from novelwriter.extensions.switch import NSwitch +from novelwriter.extensions.switchbox import NSwitchBox +from novelwriter.types import QtAlignLeft if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -473,7 +474,7 @@ class _FilterTab(NFixedPage): trItem.setData(self.C_DATA, self.D_FILE, isFile) trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName)) - trItem.setTextAlignment(self.C_NAME, Qt.AlignLeft) + trItem.setTextAlignment(self.C_NAME, QtAlignLeft) if pHandle is None and nwItem.isRootType(): self.optTree.addTopLevelItem(trItem) diff --git a/novelwriter/tools/noveldetails.py b/novelwriter/tools/noveldetails.py index 074df498..8750d273 100644 --- a/novelwriter/tools/noveldetails.py +++ b/novelwriter/tools/noveldetails.py @@ -37,10 +37,11 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.common import formatTime, numberToRoman from novelwriter.constants import nwUnicode -from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage -from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.novelselector import NovelSelector +from novelwriter.extensions.pagedsidebar import NPagedSideBar +from novelwriter.extensions.switch import NSwitch +from novelwriter.types import QtAlignRight logger = logging.getLogger(__name__) @@ -337,10 +338,10 @@ class _ContentsPage(NFixedPage): treeHeadItem = self.tocTree.headerItem() if treeHeadItem: - treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignmentFlag.AlignRight) - treeHeadItem.setTextAlignment(self.C_PAGES, Qt.AlignmentFlag.AlignRight) - treeHeadItem.setTextAlignment(self.C_PAGE, Qt.AlignmentFlag.AlignRight) - treeHeadItem.setTextAlignment(self.C_PROG, Qt.AlignmentFlag.AlignRight) + treeHeadItem.setTextAlignment(self.C_WORDS, QtAlignRight) + treeHeadItem.setTextAlignment(self.C_PAGES, QtAlignRight) + treeHeadItem.setTextAlignment(self.C_PAGE, QtAlignRight) + treeHeadItem.setTextAlignment(self.C_PROG, QtAlignRight) treeHeader = self.tocTree.header() treeHeader.setStretchLastSection(True) @@ -490,10 +491,10 @@ class _ContentsPage(NFixedPage): newItem.setText(self.C_PAGE, progPage) newItem.setText(self.C_PROG, progText) - newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight) - newItem.setTextAlignment(self.C_PAGES, Qt.AlignRight) - newItem.setTextAlignment(self.C_PAGE, Qt.AlignRight) - newItem.setTextAlignment(self.C_PROG, Qt.AlignRight) + newItem.setTextAlignment(self.C_WORDS, QtAlignRight) + newItem.setTextAlignment(self.C_PAGES, QtAlignRight) + newItem.setTextAlignment(self.C_PAGE, QtAlignRight) + newItem.setTextAlignment(self.C_PROG, QtAlignRight) # Make pages and titles/partitions stand out if tLevel < 2: diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index 796c4e22..945c06d5 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -41,14 +41,15 @@ from PyQt5.QtWidgets import ( ) from novelwriter import CONFIG, SHARED -from novelwriter.enum import nwItemClass from novelwriter.common import cssCol, formatInt, makeFileNameSafe from novelwriter.constants import nwFiles from novelwriter.core.coretools import ProjectBuilder +from novelwriter.enum import nwItemClass from novelwriter.extensions.configlayout import NWrappedWidgetBox -from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.modified import NSpinBox +from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.versioninfo import VersionInfoWidget +from novelwriter.types import QtAlignLeft, QtAlignRightTop logger = logging.getLogger(__name__) @@ -153,10 +154,8 @@ class GuiWelcome(QDialog): self.innerBox.addSpacing(hB) self.innerBox.addLayout(self.btnBox) - topRight = Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight - self.outerBox = QHBoxLayout() - self.outerBox.addWidget(self.nwLogo, 3, topRight) + self.outerBox.addWidget(self.nwLogo, 3, QtAlignRightTop) self.outerBox.addLayout(self.innerBox, 9) self.outerBox.setContentsMargins(hF, hE, hC, hE) @@ -621,7 +620,7 @@ class _NewProjectForm(QWidget): # Project Form self.projectForm = QFormLayout() - self.projectForm.setAlignment(Qt.AlignmentFlag.AlignLeft) + self.projectForm.setAlignment(QtAlignLeft) self.projectForm.addRow(self.tr("Project Name"), self.projName) self.projectForm.addRow(self.tr("Author"), self.projAuthor) self.projectForm.addRow(self.tr("Project Path"), self.pathBox) @@ -672,7 +671,7 @@ class _NewProjectForm(QWidget): self.addNotes.setChecked(False) self.notesForm = QFormLayout() - self.notesForm.setAlignment(Qt.AlignmentFlag.AlignLeft) + self.notesForm.setAlignment(QtAlignLeft) self.notesForm.addRow(self.tr("Add a folder for plot notes"), self.addPlot) self.notesForm.addRow(self.tr("Add a folder for character notes"), self.addChar) self.notesForm.addRow(self.tr("Add a folder for location notes"), self.addWorld) diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index 8dc36891..d9002175 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -37,10 +37,11 @@ from PyQt5.QtWidgets import ( ) from novelwriter import CONFIG, SHARED -from novelwriter.error import formatException from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax from novelwriter.constants import nwConst +from novelwriter.error import formatException from novelwriter.extensions.switch import NSwitch +from novelwriter.types import QtAlignLeftMiddle, QtAlignRight, QtAlignRightMiddle if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -116,9 +117,9 @@ class GuiWritingStats(QDialog): hHeader = self.listBox.headerItem() if hHeader is not None: - hHeader.setTextAlignment(self.C_LENGTH, Qt.AlignRight) - hHeader.setTextAlignment(self.C_IDLE, Qt.AlignRight) - hHeader.setTextAlignment(self.C_COUNT, Qt.AlignRight) + hHeader.setTextAlignment(self.C_LENGTH, QtAlignRight) + hHeader.setTextAlignment(self.C_IDLE, QtAlignRight) + hHeader.setTextAlignment(self.C_COUNT, QtAlignRight) sortCol = minmax(pOptions.getInt("GuiWritingStats", "sortCol", 0), 0, 2) sortOrder = checkIntTuple( @@ -141,27 +142,27 @@ class GuiWritingStats(QDialog): self.labelTotal = QLabel(formatTime(0)) self.labelTotal.setFont(SHARED.theme.guiFontFixed) - self.labelTotal.setAlignment(Qt.AlignVCenter | Qt.AlignRight) + self.labelTotal.setAlignment(QtAlignRightMiddle) self.labelIdleT = QLabel(formatTime(0)) self.labelIdleT.setFont(SHARED.theme.guiFontFixed) - self.labelIdleT.setAlignment(Qt.AlignVCenter | Qt.AlignRight) + self.labelIdleT.setAlignment(QtAlignRightMiddle) self.labelFilter = QLabel(formatTime(0)) self.labelFilter.setFont(SHARED.theme.guiFontFixed) - self.labelFilter.setAlignment(Qt.AlignVCenter | Qt.AlignRight) + self.labelFilter.setAlignment(QtAlignRightMiddle) self.novelWords = QLabel("0") self.novelWords.setFont(SHARED.theme.guiFontFixed) - self.novelWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight) + self.novelWords.setAlignment(QtAlignRightMiddle) self.notesWords = QLabel("0") self.notesWords.setFont(SHARED.theme.guiFontFixed) - self.notesWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight) + self.notesWords.setAlignment(QtAlignRightMiddle) self.totalWords = QLabel("0") self.totalWords.setFont(SHARED.theme.guiFontFixed) - self.totalWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight) + self.totalWords.setAlignment(QtAlignRightMiddle) lblTTime = QLabel(self.tr("Total Time:")) lblITime = QLabel(self.tr("Idle Time:")) @@ -593,10 +594,10 @@ class GuiWritingStats(QDialog): ) newItem.setData(self.C_BAR, Qt.DecorationRole, wBar) - newItem.setTextAlignment(self.C_LENGTH, Qt.AlignRight) - newItem.setTextAlignment(self.C_IDLE, Qt.AlignRight) - newItem.setTextAlignment(self.C_COUNT, Qt.AlignRight) - newItem.setTextAlignment(self.C_BAR, Qt.AlignLeft | Qt.AlignVCenter) + newItem.setTextAlignment(self.C_LENGTH, QtAlignRight) + newItem.setTextAlignment(self.C_IDLE, QtAlignRight) + newItem.setTextAlignment(self.C_COUNT, QtAlignRight) + newItem.setTextAlignment(self.C_BAR, QtAlignLeftMiddle) newItem.setFont(self.C_TIME, SHARED.theme.guiFontFixed) newItem.setFont(self.C_LENGTH, SHARED.theme.guiFontFixed) diff --git a/novelwriter/types.py b/novelwriter/types.py index 6fc1f060..eb20dce3 100644 --- a/novelwriter/types.py +++ b/novelwriter/types.py @@ -1,6 +1,6 @@ """ -novelWriter – Typings -===================== +novelWriter – Types and Flags +============================= File History: Created: 2024-04-01 [2.4rc1] @@ -25,8 +25,19 @@ from __future__ import annotations from PyQt5.QtCore import Qt +# Qt Alignment Flags + +QtAlignAbsolute = Qt.AlignmentFlag.AlignAbsolute +QtAlignCenter = Qt.AlignmentFlag.AlignCenter +QtAlignCenterTop = Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop +QtAlignJustify = Qt.AlignmentFlag.AlignJustify QtAlignLeft = Qt.AlignmentFlag.AlignLeft -QtAlignRight = Qt.AlignmentFlag.AlignRight QtAlignLeftBase = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBaseline +QtAlignLeftMiddle = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter +QtAlignLeftTop = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop +QtAlignMiddle = Qt.AlignmentFlag.AlignVCenter +QtAlignRight = Qt.AlignmentFlag.AlignRight QtAlignRightBase = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignBaseline QtAlignRightMiddle = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter +QtAlignRightTop = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop +QtAlignTop = Qt.AlignmentFlag.AlignTop diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 000bfdc6..fd947cda 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -30,13 +30,14 @@ from PyQt5.QtCore import QThreadPool, Qt from PyQt5.QtWidgets import QAction, QMenu, qApp from novelwriter import CONFIG, SHARED +from novelwriter.constants import nwKeyWords, nwUnicode +from novelwriter.dialogs.editlabel import GuiEditLabel from novelwriter.enum import ( nwDocAction, nwDocInsert, nwItemClass, nwItemLayout, nwTrinary, nwWidget ) -from novelwriter.constants import nwKeyWords, nwUnicode from novelwriter.gui.doceditor import GuiDocEditor, GuiDocToolBar from novelwriter.text.counting import standardCounter -from novelwriter.dialogs.editlabel import GuiEditLabel +from novelwriter.types import QtAlignJustify, QtAlignLeft KEY_DELAY = 1 @@ -53,7 +54,7 @@ def testGuiEditor_Init(qtbot, nwGUI, projPath, ipsumText, mockRnd): # Check Defaults qDoc = nwGUI.docEditor.document() - assert qDoc.defaultTextOption().alignment() == Qt.AlignLeft + assert qDoc.defaultTextOption().alignment() == QtAlignLeft assert nwGUI.docEditor.verticalScrollBarPolicy() == Qt.ScrollBarAsNeeded assert nwGUI.docEditor.horizontalScrollBarPolicy() == Qt.ScrollBarAsNeeded assert nwGUI.docEditor._typPadChar == nwUnicode.U_NBSP @@ -76,7 +77,7 @@ def testGuiEditor_Init(qtbot, nwGUI, projPath, ipsumText, mockRnd): qDoc = nwGUI.docEditor.document() assert CONFIG.textFont == qDoc.defaultFont().family() - assert qDoc.defaultTextOption().alignment() == Qt.AlignJustify + assert qDoc.defaultTextOption().alignment() == QtAlignJustify assert qDoc.defaultTextOption().flags() & QTextOption.ShowTabsAndSpaces assert qDoc.defaultTextOption().flags() & QTextOption.ShowLineAndParagraphSeparators assert nwGUI.docEditor.verticalScrollBarPolicy() == Qt.ScrollBarAlwaysOff diff --git a/tests/test_tools/test_tools_manuscript.py b/tests/test_tools/test_tools_manuscript.py index 635fb174..374bafa0 100644 --- a/tests/test_tools/test_tools_manuscript.py +++ b/tests/test_tools/test_tools_manuscript.py @@ -20,26 +20,27 @@ along with this program. If not, see . """ from __future__ import annotations -import sys import pytest +import sys from pathlib import Path from pytestqt.qtbot import QtBot -from novelwriter.constants import nwHeadFmt -from tools import C, buildTestProject from mocked import causeOSError +from tools import C, buildTestProject -from PyQt5.QtCore import Qt, pyqtSlot -from PyQt5.QtWidgets import QAction, QDialogButtonBox, QListWidgetItem +from PyQt5.QtCore import pyqtSlot from PyQt5.QtPrintSupport import QPrintPreviewDialog +from PyQt5.QtWidgets import QAction, QDialogButtonBox, QListWidgetItem from novelwriter import CONFIG, SHARED -from novelwriter.guimain import GuiMain +from novelwriter.constants import nwHeadFmt from novelwriter.core.buildsettings import BuildSettings -from novelwriter.tools.manuscript import GuiManuscript +from novelwriter.guimain import GuiMain from novelwriter.tools.manusbuild import GuiManuscriptBuild +from novelwriter.tools.manuscript import GuiManuscript from novelwriter.tools.manussettings import GuiBuildSettings +from novelwriter.types import QtAlignAbsolute, QtAlignJustify @pytest.mark.gui @@ -262,11 +263,11 @@ def testManuscript_Features(monkeypatch, qtbot, nwGUI, projPath, mockRnd): assert manus.docStats.maxTotalChars.text() == "117" # Toggle justify - assert manus.docPreview.document().defaultTextOption().alignment() == Qt.AlignAbsolute + assert manus.docPreview.document().defaultTextOption().alignment() == QtAlignAbsolute manus.docPreview.setJustify(True) - assert manus.docPreview.document().defaultTextOption().alignment() == Qt.AlignJustify + assert manus.docPreview.document().defaultTextOption().alignment() == QtAlignJustify manus.docPreview.setJustify(False) - assert manus.docPreview.document().defaultTextOption().alignment() == Qt.AlignAbsolute + assert manus.docPreview.document().defaultTextOption().alignment() == QtAlignAbsolute # Tests are too fast to trigger this one, so we trigger it manually to ensure it isn't failing manus.docPreview._hideProgress() From 24e45fb661e301ec13c091b3ba888b7e583af049 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:21:34 +0200 Subject: [PATCH 5/6] Improve how tool buttons are generated --- .../assets/icons/typicons_dark/icons.conf | 4 +- .../icons/typicons_dark/typ_arrow-down.svg | 4 - .../icons/typicons_dark/typ_arrow-right.svg | 4 - .../icons/typicons_dark/typ_unfold-hidden.svg | 4 + .../typicons_dark/typ_unfold-visible.svg | 4 + .../assets/icons/typicons_light/icons.conf | 4 +- .../icons/typicons_light/typ_arrow-down.svg | 4 - .../icons/typicons_light/typ_arrow-right.svg | 4 - .../typicons_light/typ_unfold-hidden.svg | 4 + .../typicons_light/typ_unfold-visible.svg | 4 + novelwriter/dialogs/docmerge.py | 9 ++- novelwriter/dialogs/docsplit.py | 2 +- novelwriter/dialogs/preferences.py | 37 +++------ novelwriter/dialogs/projectsettings.py | 30 ++++--- novelwriter/dialogs/wordlist.py | 12 +-- novelwriter/extensions/modified.py | 35 +++++++- novelwriter/gui/doceditor.py | 80 +++++++------------ novelwriter/gui/docviewer.py | 25 +++--- novelwriter/gui/docviewerpanel.py | 16 ++-- novelwriter/gui/itemdetails.py | 2 +- novelwriter/gui/noveltree.py | 17 ++-- novelwriter/gui/outline.py | 9 +-- novelwriter/gui/projtree.py | 20 ++--- novelwriter/gui/search.py | 9 ++- novelwriter/gui/sidebar.py | 20 ++--- novelwriter/gui/statusbar.py | 4 +- novelwriter/gui/theme.py | 21 +++-- novelwriter/shared.py | 2 +- novelwriter/tools/dictionaries.py | 10 +-- novelwriter/tools/manusbuild.py | 17 ++-- novelwriter/tools/manuscript.py | 31 +++---- novelwriter/tools/manussettings.py | 75 ++++++----------- novelwriter/tools/noveldetails.py | 7 +- novelwriter/tools/welcome.py | 29 +++---- novelwriter/tools/writingstats.py | 2 +- tests/mocked.py | 2 +- 36 files changed, 278 insertions(+), 285 deletions(-) delete mode 100644 novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg delete mode 100644 novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg create mode 100644 novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg create mode 100644 novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg delete mode 100644 novelwriter/assets/icons/typicons_light/typ_arrow-down.svg delete mode 100644 novelwriter/assets/icons/typicons_light/typ_arrow-right.svg create mode 100644 novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg create mode 100644 novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg diff --git a/novelwriter/assets/icons/typicons_dark/icons.conf b/novelwriter/assets/icons/typicons_dark/icons.conf index 75a95c5d..28d72c83 100644 --- a/novelwriter/assets/icons/typicons_dark/icons.conf +++ b/novelwriter/assets/icons/typicons_dark/icons.conf @@ -100,8 +100,8 @@ status_time = typ_stopwatch-grey.svg sticky-off = typ_pin-outline.svg sticky-on = typ_pin.svg unchecked = mixed_input-unchecked.svg -unfold-hide = typ_arrow-right.svg -unfold-show = typ_arrow-down.svg +unfold-hide = typ_unfold-hidden.svg +unfold-show = typ_unfold-visible.svg up = typ_chevron-up.svg view = typ_eye.svg view_build = typ_export-grey.svg diff --git a/novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg b/novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg deleted file mode 100644 index 356a1edd..00000000 --- a/novelwriter/assets/icons/typicons_dark/typ_arrow-down.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg b/novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg deleted file mode 100644 index 288465d0..00000000 --- a/novelwriter/assets/icons/typicons_dark/typ_arrow-right.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg b/novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg new file mode 100644 index 00000000..a44038ee --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/typ_unfold-hidden.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg b/novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg new file mode 100644 index 00000000..9062561c --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/typ_unfold-visible.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/icons.conf b/novelwriter/assets/icons/typicons_light/icons.conf index 57ad7afa..1af2ee60 100644 --- a/novelwriter/assets/icons/typicons_light/icons.conf +++ b/novelwriter/assets/icons/typicons_light/icons.conf @@ -100,8 +100,8 @@ status_time = typ_stopwatch-grey.svg sticky-off = typ_pin-outline.svg sticky-on = typ_pin.svg unchecked = mixed_input-unchecked.svg -unfold-hide = typ_arrow-right.svg -unfold-show = typ_arrow-down.svg +unfold-hide = typ_unfold-hidden.svg +unfold-show = typ_unfold-visible.svg up = typ_chevron-up.svg view = typ_eye.svg view_build = typ_export-grey.svg diff --git a/novelwriter/assets/icons/typicons_light/typ_arrow-down.svg b/novelwriter/assets/icons/typicons_light/typ_arrow-down.svg deleted file mode 100644 index f3c1a221..00000000 --- a/novelwriter/assets/icons/typicons_light/typ_arrow-down.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/novelwriter/assets/icons/typicons_light/typ_arrow-right.svg b/novelwriter/assets/icons/typicons_light/typ_arrow-right.svg deleted file mode 100644 index c7df8491..00000000 --- a/novelwriter/assets/icons/typicons_light/typ_arrow-right.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg b/novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg new file mode 100644 index 00000000..f187a8ad --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/typ_unfold-hidden.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg b/novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg new file mode 100644 index 00000000..8fad21e3 --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/typ_unfold-visible.svg @@ -0,0 +1,4 @@ + + + + diff --git a/novelwriter/dialogs/docmerge.py b/novelwriter/dialogs/docmerge.py index 0466b09c..0e5a313f 100644 --- a/novelwriter/dialogs/docmerge.py +++ b/novelwriter/dialogs/docmerge.py @@ -27,7 +27,7 @@ from __future__ import annotations import logging from PyQt5.QtGui import QCloseEvent -from PyQt5.QtCore import Qt, QSize, pyqtSlot +from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QDialogButtonBox, QGridLayout, QLabel, QListWidget, QListWidgetItem, QVBoxLayout, QWidget @@ -59,13 +59,14 @@ class GuiDocMerge(QDialog): SHARED.theme.helpText, parent=self, wrap=True ) - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize hSp = CONFIG.pxInt(12) vSp = CONFIG.pxInt(8) bSp = CONFIG.pxInt(12) - self.listBox = QListWidget() - self.listBox.setIconSize(QSize(iPx, iPx)) + self.listBox = QListWidget(self) + self.listBox.setIconSize(iSz) self.listBox.setMinimumWidth(CONFIG.pxInt(400)) self.listBox.setMinimumHeight(CONFIG.pxInt(180)) self.listBox.setSelectionBehavior(QAbstractItemView.SelectRows) diff --git a/novelwriter/dialogs/docsplit.py b/novelwriter/dialogs/docsplit.py index f1c3d295..1ad639f9 100644 --- a/novelwriter/dialogs/docsplit.py +++ b/novelwriter/dialogs/docsplit.py @@ -64,7 +64,7 @@ class GuiDocSplit(QDialog): ) # Values - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight hSp = CONFIG.pxInt(12) vSp = CONFIG.pxInt(8) bSp = CONFIG.pxInt(12) diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 476275ca..bef7b2bb 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -27,18 +27,18 @@ from __future__ import annotations import logging from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence -from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractButton, QCompleter, QDialog, QDialogButtonBox, QFileDialog, - QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QToolButton, QVBoxLayout, - QWidget, qApp + QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget, + qApp ) from novelwriter import CONFIG, SHARED from novelwriter.constants import nwConst, nwUnicode from novelwriter.dialogs.quotes import GuiQuoteSelect from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm -from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox +from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.switch import NSwitch from novelwriter.types import QtAlignCenter @@ -133,10 +133,8 @@ class GuiPreferences(QDialog): def buildForm(self) -> None: """Build the settings form.""" section = 0 + iSz = SHARED.theme.baseIconSize minWidth = CONFIG.pxInt(200) - iPx = SHARED.theme.baseIconSize - iconSize = QSize(iPx, iPx) - mIcon = SHARED.theme.getIcon("more") # Label self.sidebar.addLabel(self.tr("General")) @@ -178,9 +176,7 @@ class GuiPreferences(QDialog): self.guiFont.setReadOnly(True) self.guiFont.setMinimumWidth(CONFIG.pxInt(162)) self.guiFont.setText(CONFIG.guiFont) - self.guiFontButton = QToolButton(self) - self.guiFontButton.setIcon(mIcon) - self.guiFontButton.setIconSize(iconSize) + self.guiFontButton = NIconToolButton(self, iSz, "more") self.guiFontButton.clicked.connect(self._selectGuiFont) self.mainForm.addRow( self.tr("Application font family"), self.guiFont, @@ -240,9 +236,7 @@ class GuiPreferences(QDialog): self.textFont.setReadOnly(True) self.textFont.setMinimumWidth(CONFIG.pxInt(162)) self.textFont.setText(CONFIG.textFont) - self.textFontButton = QToolButton(self) - self.textFontButton.setIcon(mIcon) - self.textFontButton.setIconSize(iconSize) + self.textFontButton = NIconToolButton(self, iSz, "more") self.textFontButton.clicked.connect(self._selectTextFont) self.mainForm.addRow( self.tr("Document font family"), self.textFont, @@ -325,6 +319,7 @@ class GuiPreferences(QDialog): # Backup Path self.backupPath = CONFIG.backupPath() self.backupGetPath = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Browse"), self) + self.backupGetPath.setIconSize(iSz) self.backupGetPath.clicked.connect(self._backupFolder) self.mainForm.addRow( self.tr("Backup storage location"), self.backupGetPath, @@ -682,9 +677,7 @@ class GuiPreferences(QDialog): self.quoteSym["SO"].setFixedWidth(qWidth) self.quoteSym["SO"].setAlignment(QtAlignCenter) self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen) - self.btnSingleStyleO = QToolButton(self) - self.btnSingleStyleO.setIcon(mIcon) - self.btnSingleStyleO.setIconSize(iconSize) + self.btnSingleStyleO = NIconToolButton(self, iSz, "more") self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO")) self.mainForm.addRow( self.tr("Single quote open style"), self.quoteSym["SO"], @@ -698,9 +691,7 @@ class GuiPreferences(QDialog): self.quoteSym["SC"].setFixedWidth(qWidth) self.quoteSym["SC"].setAlignment(QtAlignCenter) self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose) - self.btnSingleStyleC = QToolButton(self) - self.btnSingleStyleC.setIcon(mIcon) - self.btnSingleStyleC.setIconSize(iconSize) + self.btnSingleStyleC = NIconToolButton(self, iSz, "more") self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC")) self.mainForm.addRow( self.tr("Single quote close style"), self.quoteSym["SC"], @@ -715,9 +706,7 @@ class GuiPreferences(QDialog): self.quoteSym["DO"].setFixedWidth(qWidth) self.quoteSym["DO"].setAlignment(QtAlignCenter) self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen) - self.btnDoubleStyleO = QToolButton(self) - self.btnDoubleStyleO.setIcon(mIcon) - self.btnDoubleStyleO.setIconSize(iconSize) + self.btnDoubleStyleO = NIconToolButton(self, iSz, "more") self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO")) self.mainForm.addRow( self.tr("Double quote open style"), self.quoteSym["DO"], @@ -731,9 +720,7 @@ class GuiPreferences(QDialog): self.quoteSym["DC"].setFixedWidth(qWidth) self.quoteSym["DC"].setAlignment(QtAlignCenter) self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose) - self.btnDoubleStyleC = QToolButton(self) - self.btnDoubleStyleC.setIcon(mIcon) - self.btnDoubleStyleC.setIconSize(iconSize) + self.btnDoubleStyleC = NIconToolButton(self, iSz, "more") self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC")) self.mainForm.addRow( self.tr("Double quote close style"), self.quoteSym["DC"], diff --git a/novelwriter/dialogs/projectsettings.py b/novelwriter/dialogs/projectsettings.py index da3146f8..c24137fc 100644 --- a/novelwriter/dialogs/projectsettings.py +++ b/novelwriter/dialogs/projectsettings.py @@ -36,10 +36,10 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.common import simplified -from novelwriter.extensions.switch import NSwitch -from novelwriter.extensions.modified import NComboBox from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm +from novelwriter.extensions.modified import NComboBox, NIconToolButton from novelwriter.extensions.pagedsidebar import NPagedSideBar +from novelwriter.extensions.switch import NSwitch logger = logging.getLogger(__name__) @@ -329,7 +329,9 @@ class _StatusPage(NFixedPage): self._colDeleted = [] self._selColour = QColor(100, 100, 100) - self.iPx = SHARED.theme.baseIconSize + self.iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize + bSz = SHARED.theme.buttonIconSize # Title self.pageTitle = NColourLabel( @@ -348,16 +350,16 @@ class _StatusPage(NFixedPage): self._addItem(key, entry["name"], entry["cols"], entry["count"]) # List Controls - self.addButton = QPushButton(SHARED.theme.getIcon("add"), "", self) + self.addButton = NIconToolButton(self, iSz, "add") self.addButton.clicked.connect(self._newItem) - self.delButton = QPushButton(SHARED.theme.getIcon("remove"), "", self) + self.delButton = NIconToolButton(self, iSz, "remove") self.delButton.clicked.connect(self._delItem) - self.upButton = QPushButton(SHARED.theme.getIcon("up"), "", self) + self.upButton = NIconToolButton(self, iSz, "up") self.upButton.clicked.connect(lambda: self._moveItem(-1)) - self.dnButton = QPushButton(SHARED.theme.getIcon("down"), "", self) + self.dnButton = NIconToolButton(self, iSz, "down") self.dnButton.clicked.connect(lambda: self._moveItem(1)) # Edit Form @@ -368,12 +370,12 @@ class _StatusPage(NFixedPage): self.colPixmap = QPixmap(self.iPx, self.iPx) self.colPixmap.fill(QColor(100, 100, 100)) - self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour")) - self.colButton.setIconSize(self.colPixmap.rect().size()) + self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"), self) + self.colButton.setIconSize(bSz) self.colButton.setEnabled(False) self.colButton.clicked.connect(self._selectColour) - self.saveButton = QPushButton(self.tr("Save")) + self.saveButton = QPushButton(self.tr("Save"), self) self.saveButton.setEnabled(False) self.saveButton.clicked.connect(self._saveItem) @@ -589,6 +591,8 @@ class _ReplacePage(NFixedPage): self._changed = False + iSz = SHARED.theme.baseIconSize + wCol0 = CONFIG.pxInt( SHARED.project.options.getInt("GuiProjectSettings", "replaceColW", 130) ) @@ -614,10 +618,10 @@ class _ReplacePage(NFixedPage): self.listBox.setSortingEnabled(True) # List Controls - self.addButton = QPushButton(SHARED.theme.getIcon("add"), "") + self.addButton = NIconToolButton(self, iSz, "add") self.addButton.clicked.connect(self._addEntry) - self.delButton = QPushButton(SHARED.theme.getIcon("remove"), "") + self.delButton = NIconToolButton(self, iSz, "remove") self.delButton.clicked.connect(self._delEntry) # Edit Form @@ -630,7 +634,7 @@ class _ReplacePage(NFixedPage): self.editValue.setEnabled(False) self.editValue.setMaxLength(80) - self.saveButton = QPushButton(self.tr("Save")) + self.saveButton = QPushButton(self.tr("Save"), self) self.saveButton.clicked.connect(self._saveEntry) # Assemble diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index d503c6a4..cd2908a9 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -32,13 +32,14 @@ from PyQt5.QtGui import QCloseEvent from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QDialogButtonBox, QFileDialog, QHBoxLayout, - QLineEdit, QListWidget, QPushButton, QVBoxLayout, qApp + QLineEdit, QListWidget, QVBoxLayout, qApp ) from novelwriter import CONFIG, SHARED from novelwriter.common import formatFileFilter from novelwriter.core.spellcheck import UserDictionary from novelwriter.extensions.configlayout import NColourLabel +from novelwriter.extensions.modified import NIconToolButton if TYPE_CHECKING: # pragma: no cover from novelwriter.guimain import GuiMain @@ -57,6 +58,7 @@ class GuiWordList(QDialog): self.setObjectName("GuiWordList") self.setWindowTitle(self.tr("Project Word List")) + iSz = SHARED.theme.baseIconSize mS = CONFIG.pxInt(250) wW = CONFIG.pxInt(320) wH = CONFIG.pxInt(340) @@ -74,11 +76,11 @@ class GuiWordList(QDialog): scale=NColourLabel.HEADER_SCALE ) - self.importButton = QPushButton(SHARED.theme.getIcon("import"), "", self) + self.importButton = NIconToolButton(self, iSz, "import") self.importButton.setToolTip(self.tr("Import words from text file")) self.importButton.clicked.connect(self._importWords) - self.exportButton = QPushButton(SHARED.theme.getIcon("export"), "", self) + self.exportButton = NIconToolButton(self, iSz, "export") self.exportButton.setToolTip(self.tr("Export words to text file")) self.exportButton.clicked.connect(self._exportWords) @@ -96,10 +98,10 @@ class GuiWordList(QDialog): # Add/Remove Form self.newEntry = QLineEdit(self) - self.addButton = QPushButton(SHARED.theme.getIcon("add"), "", self) + self.addButton = NIconToolButton(self, iSz, "add") self.addButton.clicked.connect(self._doAdd) - self.delButton = QPushButton(SHARED.theme.getIcon("remove"), "", self) + self.delButton = NIconToolButton(self, iSz, "remove") self.delButton.clicked.connect(self._doDelete) self.editBox = QHBoxLayout() diff --git a/novelwriter/extensions/modified.py b/novelwriter/extensions/modified.py index 15b61db0..4eb50cff 100644 --- a/novelwriter/extensions/modified.py +++ b/novelwriter/extensions/modified.py @@ -29,6 +29,8 @@ from PyQt5.QtCore import QSize, Qt from PyQt5.QtGui import QWheelEvent from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget +from novelwriter import SHARED + class NComboBox(QComboBox): @@ -89,11 +91,40 @@ class NDoubleSpinBox(QDoubleSpinBox): class NIconToolButton(QToolButton): - def __init__(self, parent: QWidget, iconSize: int) -> None: + def __init__(self, parent: QWidget, iconSize: QSize, icon: str | None = None) -> None: super().__init__(parent=parent) self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) - self.setIconSize(QSize(iconSize, iconSize)) + self.setIconSize(iconSize) self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) + if icon: + self.setThemeIcon(icon) + return + + def setThemeIcon(self, iconKey: str) -> None: + """Set an icon from the current theme.""" + self.setIcon(SHARED.theme.getIcon(iconKey)) return # END Class NIconToolButton + + +class NIconToggleButton(QToolButton): + + def __init__(self, parent: QWidget, iconSize: QSize, icon: 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) + return + + def setThemeIcon(self, iconKey: str) -> None: + """Set an icon from the current theme.""" + iconSize = self.iconSize() + self.setIcon(SHARED.theme.getToggleIcon(iconKey, (iconSize.width(), iconSize.height()))) + return + +# END Class NUnfoldButton diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 9f66c72b..31484f1c 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -40,7 +40,7 @@ from typing import TYPE_CHECKING from PyQt5.QtCore import ( pyqtSignal, pyqtSlot, QObject, QPoint, QRegExp, QRegularExpression, - QRunnable, QSize, Qt, QTimer + QRunnable, Qt, QTimer ) from PyQt5.QtGui import ( QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette, @@ -48,8 +48,7 @@ from PyQt5.QtGui import ( ) from PyQt5.QtWidgets import ( QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu, - QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QVBoxLayout, - QWidget, qApp + QPlainTextEdit, QShortcut, QToolBar, QVBoxLayout, QWidget, qApp ) from novelwriter import CONFIG, SHARED @@ -58,7 +57,7 @@ from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode from novelwriter.core.document import NWDocument from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary from novelwriter.extensions.eventfilters import WheelEventFilter -from novelwriter.extensions.modified import NIconToolButton +from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE from novelwriter.gui.editordocument import GuiTextDocument from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON @@ -2263,79 +2262,68 @@ class GuiDocToolBar(QWidget): logger.debug("Create: GuiDocToolBar") + iSz = SHARED.theme.baseIconSize cM = CONFIG.pxInt(4) - tPx = int(0.8*SHARED.theme.fontPixelSize) - iconSize = QSize(tPx, tPx) self.setContentsMargins(0, 0, 0, 0) # General Buttons # =============== - self.tbBoldMD = QToolButton(self) - self.tbBoldMD.setIconSize(iconSize) + self.tbBoldMD = NIconToolButton(self, iSz) self.tbBoldMD.setToolTip(self.tr("Markdown Bold")) self.tbBoldMD.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD) ) - self.tbItalicMD = QToolButton(self) - self.tbItalicMD.setIconSize(iconSize) + self.tbItalicMD = NIconToolButton(self, iSz) self.tbItalicMD.setToolTip(self.tr("Markdown Italic")) self.tbItalicMD.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC) ) - self.tbStrikeMD = QToolButton(self) - self.tbStrikeMD.setIconSize(iconSize) + self.tbStrikeMD = NIconToolButton(self, iSz) self.tbStrikeMD.setToolTip(self.tr("Markdown Strikethrough")) self.tbStrikeMD.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE) ) - self.tbBold = QToolButton(self) - self.tbBold.setIconSize(iconSize) + self.tbBold = NIconToolButton(self, iSz) self.tbBold.setToolTip(self.tr("Shortcode Bold")) self.tbBold.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD) ) - self.tbItalic = QToolButton(self) - self.tbItalic.setIconSize(iconSize) + self.tbItalic = NIconToolButton(self, iSz) self.tbItalic.setToolTip(self.tr("Shortcode Italic")) self.tbItalic.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC) ) - self.tbStrike = QToolButton(self) - self.tbStrike.setIconSize(iconSize) + self.tbStrike = NIconToolButton(self, iSz) self.tbStrike.setToolTip(self.tr("Shortcode Strikethrough")) self.tbStrike.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_STRIKE) ) - self.tbUnderline = QToolButton(self) - self.tbUnderline.setIconSize(iconSize) + self.tbUnderline = NIconToolButton(self, iSz) self.tbUnderline.setToolTip(self.tr("Shortcode Underline")) self.tbUnderline.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE) ) - self.tbMark = QToolButton(self) - self.tbMark.setIconSize(iconSize) + self.tbMark = NIconToolButton(self, iSz) self.tbMark.setToolTip(self.tr("Shortcode Highlight")) self.tbMark.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_MARK) ) - self.tbSuperscript = QToolButton(self) - self.tbSuperscript.setIconSize(iconSize) + self.tbSuperscript = NIconToolButton(self, iSz) self.tbSuperscript.setToolTip(self.tr("Shortcode Superscript")) self.tbSuperscript.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_SUP) ) - self.tbSubscript = QToolButton(self) - self.tbSubscript.setIconSize(iconSize) + self.tbSubscript = NIconToolButton(self, iSz) self.tbSubscript.setToolTip(self.tr("Shortcode Subscript")) self.tbSubscript.clicked.connect( lambda: self.requestDocAction.emit(nwDocAction.SC_SUB) @@ -2415,8 +2403,9 @@ class GuiDocEditSearch(QFrame): self.doNextFile = CONFIG.searchNextFile self.doMatchCap = CONFIG.searchMatchCap + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(6) - tPx = int(0.8*SHARED.theme.fontPixelSize) + self.boxFont = SHARED.theme.guiFont self.boxFont.setPointSizeF(0.9*SHARED.theme.fontPointSize) @@ -2442,7 +2431,7 @@ class GuiDocEditSearch(QFrame): self.searchOpt = QToolBar(self) self.searchOpt.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) - self.searchOpt.setIconSize(QSize(tPx, tPx)) + self.searchOpt.setIconSize(iSz) self.searchOpt.setContentsMargins(0, 0, 0, 0) self.searchLabel = QLabel(self.tr("Search")) @@ -2500,20 +2489,14 @@ class GuiDocEditSearch(QFrame): # Buttons # ======= - bPx = self.searchBox.sizeHint().height() - - self.showReplace = QToolButton(self) - self.showReplace.setArrowType(Qt.ArrowType.RightArrow) - self.showReplace.setCheckable(True) + self.showReplace = NIconToggleButton(self, iSz, "unfold") self.showReplace.toggled.connect(self._doToggleReplace) - self.searchButton = QPushButton("") - self.searchButton.setFixedSize(QSize(bPx, bPx)) + self.searchButton = NIconToolButton(self, iSz) self.searchButton.setToolTip(self.tr("Find in current document")) self.searchButton.clicked.connect(self._doSearch) - self.replaceButton = QPushButton("") - self.replaceButton.setFixedSize(QSize(bPx, bPx)) + self.replaceButton = NIconToolButton(self, iSz) self.replaceButton.setToolTip(self.tr("Find and replace in current document")) self.replaceButton.clicked.connect(self._doReplace) @@ -2738,10 +2721,6 @@ class GuiDocEditSearch(QFrame): @pyqtSlot(bool) def _doToggleReplace(self, state: bool) -> None: """Toggle the show/hide of the replace box.""" - if state: - self.showReplace.setArrowType(Qt.ArrowType.DownArrow) - else: - self.showReplace.setArrowType(Qt.ArrowType.RightArrow) self.replaceBox.setVisible(state) self.replaceButton.setVisible(state) self.repVisible = state @@ -2821,7 +2800,8 @@ class GuiDocEditHeader(QWidget): self._docHandle = None self._docOutline: dict[int, str] = {} - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(4) # Main Widget Settings @@ -2844,27 +2824,27 @@ class GuiDocEditHeader(QWidget): self.outlineMenu = QMenu(self) # Buttons - self.tbButton = NIconToolButton(self, iPx) + self.tbButton = NIconToolButton(self, iSz) self.tbButton.setVisible(False) self.tbButton.setToolTip(self.tr("Toggle Tool Bar")) self.tbButton.clicked.connect(lambda: self.toggleToolBarRequest.emit()) - self.outlineButton = NIconToolButton(self, iPx) + self.outlineButton = NIconToolButton(self, iSz) self.outlineButton.setVisible(False) self.outlineButton.setToolTip(self.tr("Outline")) self.outlineButton.setMenu(self.outlineMenu) - self.searchButton = NIconToolButton(self, iPx) + self.searchButton = NIconToolButton(self, iSz) self.searchButton.setVisible(False) self.searchButton.setToolTip(self.tr("Search")) self.searchButton.clicked.connect(self.docEditor.toggleSearch) - self.minmaxButton = NIconToolButton(self, iPx) + self.minmaxButton = NIconToolButton(self, iSz) self.minmaxButton.setVisible(False) self.minmaxButton.setToolTip(self.tr("Toggle Focus Mode")) self.minmaxButton.clicked.connect(lambda: self.docEditor.toggleFocusModeRequest.emit()) - self.closeButton = NIconToolButton(self, iPx) + self.closeButton = NIconToolButton(self, iSz) self.closeButton.setVisible(False) self.closeButton.setToolTip(self.tr("Close")) self.closeButton.clicked.connect(self._closeDocument) @@ -3038,7 +3018,7 @@ class GuiDocEditFooter(QWidget): self._tItem = None self._docHandle = None - iPx = round(0.9*SHARED.theme.baseIconSize) + iPx = round(0.9*SHARED.theme.baseIconHeight) fPx = int(0.9*SHARED.theme.fontPixelSize) mPx = CONFIG.pxInt(8) bSp = CONFIG.pxInt(4) @@ -3137,7 +3117,7 @@ class GuiDocEditFooter(QWidget): def updateTheme(self) -> None: """Update theme elements.""" - iPx = round(0.9*SHARED.theme.baseIconSize) + iPx = round(0.9*SHARED.theme.baseIconHeight) self.linesIcon.setPixmap(SHARED.theme.getPixmap("status_lines", (iPx, iPx))) self.wordsIcon.setPixmap(SHARED.theme.getPixmap("status_stats", (iPx, iPx))) self.matchColours() @@ -3179,7 +3159,7 @@ class GuiDocEditFooter(QWidget): sIcon = QPixmap() sText = "" else: - iPx = round(0.9*SHARED.theme.baseIconSize) + iPx = round(0.9*SHARED.theme.baseIconHeight) status, icon = self._tItem.getImportStatus(incIcon=True) sIcon = icon.pixmap(iPx, iPx) sText = f"{status} / {self._tItem.describeMe()}" diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index d77f4cd4..5d24807f 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -30,7 +30,7 @@ import logging from enum import Enum -from PyQt5.QtCore import pyqtSignal, pyqtSlot, QPoint, QSize, Qt, QUrl +from PyQt5.QtCore import pyqtSignal, pyqtSlot, QPoint, Qt, QUrl from PyQt5.QtGui import ( QCursor, QFont, QMouseEvent, QPalette, QResizeEvent, QTextCursor, QTextOption @@ -627,7 +627,8 @@ class GuiDocViewHeader(QWidget): self._docHandle = None self._docOutline: dict[str, tuple[str, int]] = {} - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(4) # Main Widget Settings @@ -651,27 +652,27 @@ class GuiDocViewHeader(QWidget): self.outlineMenu = QMenu(self) # Buttons - self.outlineButton = NIconToolButton(self, iPx) + self.outlineButton = NIconToolButton(self, iSz) self.outlineButton.setVisible(False) self.outlineButton.setToolTip(self.tr("Outline")) self.outlineButton.setMenu(self.outlineMenu) - self.backButton = NIconToolButton(self, iPx) + self.backButton = NIconToolButton(self, iSz) self.backButton.setVisible(False) self.backButton.setToolTip(self.tr("Go Backward")) self.backButton.clicked.connect(self.docViewer.navBackward) - self.forwardButton = NIconToolButton(self, iPx) + self.forwardButton = NIconToolButton(self, iSz) self.forwardButton.setVisible(False) self.forwardButton.setToolTip(self.tr("Go Forward")) self.forwardButton.clicked.connect(self.docViewer.navForward) - self.refreshButton = NIconToolButton(self, iPx) + self.refreshButton = NIconToolButton(self, iSz) self.refreshButton.setVisible(False) self.refreshButton.setToolTip(self.tr("Reload")) self.refreshButton.clicked.connect(self._refreshDocument) - self.closeButton = NIconToolButton(self, iPx) + self.closeButton = NIconToolButton(self, iSz) self.closeButton.setVisible(False) self.closeButton.setToolTip(self.tr("Close")) self.closeButton.clicked.connect(self._closeDocument) @@ -849,17 +850,17 @@ class GuiDocViewFooter(QWidget): # Internal Variables self._docHandle = None - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize hSp = CONFIG.pxInt(4) mPx = CONFIG.pxInt(4) - iconSize = QSize(iPx, iPx) # Main Widget Settings self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) # Show/Hide Details - self.showHide = NIconToolButton(self, iPx) + self.showHide = NIconToolButton(self, iSz) self.showHide.clicked.connect(lambda: self.docViewer.togglePanelVisibility.emit()) self.showHide.setToolTip(self.tr("Show/Hide Viewer Panel")) @@ -869,7 +870,7 @@ class GuiDocViewFooter(QWidget): self.showComments.setCheckable(True) self.showComments.setChecked(CONFIG.viewComments) self.showComments.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) - self.showComments.setIconSize(iconSize) + self.showComments.setIconSize(iSz) self.showComments.toggled.connect(self._doToggleComments) self.showComments.setToolTip(self.tr("Show Comments")) @@ -879,7 +880,7 @@ class GuiDocViewFooter(QWidget): self.showSynopsis.setCheckable(True) self.showSynopsis.setChecked(CONFIG.viewSynopsis) self.showSynopsis.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) - self.showSynopsis.setIconSize(iconSize) + self.showSynopsis.setIconSize(iSz) self.showSynopsis.toggled.connect(self._doToggleSynopsis) self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments")) diff --git a/novelwriter/gui/docviewerpanel.py b/novelwriter/gui/docviewerpanel.py index a58d7f02..18239b87 100644 --- a/novelwriter/gui/docviewerpanel.py +++ b/novelwriter/gui/docviewerpanel.py @@ -27,7 +27,7 @@ import logging from enum import Enum -from PyQt5.QtCore import QModelIndex, QSize, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QModelIndex, Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QFrame, QHeaderView, QMenu, QTabWidget, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget @@ -55,7 +55,7 @@ class GuiDocViewerPanel(QWidget): self._lastHandle = None - iPx = int(1.0*SHARED.theme.baseIconSize) + iSz = SHARED.theme.baseIconSize self.tabBackRefs = _ViewPanelBackRefs(self) @@ -66,7 +66,7 @@ class GuiDocViewerPanel(QWidget): self.aInactive.toggled.connect(self._toggleHideInactive) self.optsButton = QToolButton(self) - self.optsButton.setIconSize(QSize(iPx, iPx)) + self.optsButton.setIconSize(iSz) self.optsButton.setMenu(self.optsMenu) self.optsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) @@ -240,13 +240,14 @@ class _ViewPanelBackRefs(QTreeWidget): self._parent = parent self._treeMap: dict[str, QTreeWidgetItem] = {} - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize cMg = CONFIG.pxInt(6) self.setHeaderLabels([self.tr("Document"), "", "", self.tr("First Heading")]) self.setIndentation(0) self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) - self.setIconSize(QSize(iPx, iPx)) + self.setIconSize(iSz) self.setFrameStyle(QFrame.Shape.NoFrame) # Set Header Sizes @@ -382,7 +383,8 @@ class _ViewPanelKeyWords(QTreeWidget): self._class = itemClass self._treeMap: dict[str, QTreeWidgetItem] = {} - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize cMg = CONFIG.pxInt(6) self.setHeaderLabels([ @@ -390,7 +392,7 @@ class _ViewPanelKeyWords(QTreeWidget): self.tr("Heading"), self.tr("Short Description") ]) self.setIndentation(0) - self.setIconSize(QSize(iPx, iPx)) + self.setIconSize(iSz) self.setFrameStyle(QFrame.Shape.NoFrame) self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) self.setExpandsOnDoubleClick(False) diff --git a/novelwriter/gui/itemdetails.py b/novelwriter/gui/itemdetails.py index e0e4ae50..982770eb 100644 --- a/novelwriter/gui/itemdetails.py +++ b/novelwriter/gui/itemdetails.py @@ -231,7 +231,7 @@ class GuiItemDetails(QWidget): return self._handle = tHandle - iPx = int(round(0.9*SHARED.theme.baseIconSize)) + iPx = int(round(0.9*SHARED.theme.baseIconHeight)) # Label # ===== diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index bed371bb..6fca3486 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -32,7 +32,7 @@ from time import time from typing import TYPE_CHECKING from PyQt5.QtGui import QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent -from PyQt5.QtCore import QModelIndex, QPoint, Qt, QSize, pyqtSlot, pyqtSignal +from PyQt5.QtCore import QModelIndex, QPoint, Qt, pyqtSlot, pyqtSignal from PyQt5.QtWidgets import ( QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView, QInputDialog, QMenu, QSizePolicy, QToolTip, QTreeWidget, QTreeWidgetItem, @@ -201,7 +201,7 @@ class GuiNovelToolBar(QWidget): self.novelView = novelView self.mainGui = novelView.mainGui - iPx = SHARED.theme.baseIconSize + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(2) self.setContentsMargins(0, 0, 0, 0) @@ -218,12 +218,12 @@ class GuiNovelToolBar(QWidget): self.novelValue.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot) - self.tbNovel = NIconToolButton(self, iPx) + self.tbNovel = NIconToolButton(self, iSz) self.tbNovel.setToolTip(self.tr("Novel Root")) self.tbNovel.clicked.connect(self.novelValue.showPopup) # Refresh Button - self.tbRefresh = NIconToolButton(self, iPx) + self.tbRefresh = NIconToolButton(self, iSz) self.tbRefresh.setToolTip(self.tr("Refresh")) self.tbRefresh.clicked.connect(self._refreshNovelTree) @@ -242,7 +242,7 @@ class GuiNovelToolBar(QWidget): self.aLastColSize = self.mLastCol.addAction(self.tr("Column Size")) self.aLastColSize.triggered.connect(self._selectLastColumnSize) - self.tbMore = NIconToolButton(self, iPx) + self.tbMore = NIconToolButton(self, iSz) self.tbMore.setToolTip(self.tr("More Options")) self.tbMore.setMenu(self.mMore) @@ -392,10 +392,11 @@ class GuiNovelTree(QTreeWidget): # Build GUI # ========= - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize cMg = CONFIG.pxInt(6) - self.setIconSize(QSize(iPx, iPx)) + self.setIconSize(iSz) self.setFrameStyle(QFrame.Shape.NoFrame) self.setUniformRowHeights(True) self.setAllColumnsShowFocus(True) @@ -456,7 +457,7 @@ class GuiNovelTree(QTreeWidget): def updateTheme(self) -> None: """Update theme elements.""" - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight self._pMore = SHARED.theme.loadDecoration("deco_doc_more", h=iPx) return diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index ffaeb0f0..fc5c9ac9 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -33,7 +33,7 @@ import logging from time import time from enum import Enum -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QSize, QT_TRANSLATE_NOOP +from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QT_TRANSLATE_NOOP from PyQt5.QtWidgets import ( QAbstractItemView, QAction, QFileDialog, QFrame, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QMenu, QScrollArea, QSizePolicy, QSplitter, QToolBar, @@ -207,11 +207,11 @@ class GuiOutlineToolBar(QToolBar): logger.debug("Create: GuiOutlineToolBar") - bPx = SHARED.theme.baseButtonHeight + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(12) self.setMovable(False) - self.setIconSize(QSize(bPx, bPx)) + self.setIconSize(iSz) self.setContentsMargins(0, 0, 0, 0) stretch = QWidget(self) @@ -376,8 +376,7 @@ class GuiOutlineTree(QTreeWidget): self.itemDoubleClicked.connect(self._treeDoubleClick) self.itemSelectionChanged.connect(self._itemSelected) - iPx = SHARED.theme.baseIconSize - self.setIconSize(QSize(iPx, iPx)) + self.setIconSize(SHARED.theme.baseIconSize) self.setIndentation(0) self.treeHead = self.header() diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 014195dd..2b0406ef 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -35,7 +35,7 @@ from typing import TYPE_CHECKING from PyQt5.QtGui import ( QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette ) -from PyQt5.QtCore import QPoint, QTimer, Qt, QSize, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QPoint, QTimer, Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView, QLabel, QMenu, QShortcut, QSizePolicy, QTreeWidget, QTreeWidgetItem, @@ -264,7 +264,7 @@ class GuiProjectToolBar(QWidget): self.projTree = projView.projTree self.mainGui = projView.mainGui - iPx = SHARED.theme.baseIconSize + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(2) self.setContentsMargins(0, 0, 0, 0) @@ -279,17 +279,17 @@ class GuiProjectToolBar(QWidget): # Quick Links self.mQuick = QMenu(self) - self.tbQuick = NIconToolButton(self, iPx) + self.tbQuick = NIconToolButton(self, iSz) self.tbQuick.setToolTip("%s [Ctrl+L]" % self.tr("Quick Links")) self.tbQuick.setShortcut("Ctrl+L") self.tbQuick.setMenu(self.mQuick) # Move Buttons - self.tbMoveU = NIconToolButton(self, iPx) + self.tbMoveU = NIconToolButton(self, iSz) self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up")) self.tbMoveU.clicked.connect(lambda: self.projTree.moveTreeItem(-1)) - self.tbMoveD = NIconToolButton(self, iPx) + self.tbMoveD = NIconToolButton(self, iSz) self.tbMoveD.setToolTip("%s [Ctrl+Down]" % self.tr("Move Down")) self.tbMoveD.clicked.connect(lambda: self.projTree.moveTreeItem(1)) @@ -329,7 +329,7 @@ class GuiProjectToolBar(QWidget): self.mAddRoot = self.mAdd.addMenu(trConst(nwLabels.ITEM_DESCRIPTION["root"])) self._buildRootMenu() - self.tbAdd = NIconToolButton(self, iPx) + self.tbAdd = NIconToolButton(self, iSz) self.tbAdd.setToolTip("%s [Ctrl+N]" % self.tr("Add Item")) self.tbAdd.setShortcut("Ctrl+N") self.tbAdd.setMenu(self.mAdd) @@ -346,7 +346,7 @@ class GuiProjectToolBar(QWidget): self.aEmptyTrash = self.mMore.addAction(self.tr("Empty Trash")) self.aEmptyTrash.triggered.connect(lambda: self.projTree.emptyTrash()) - self.tbMore = NIconToolButton(self, iPx) + self.tbMore = NIconToolButton(self, iSz) self.tbMore.setToolTip(self.tr("More Options")) self.tbMore.setMenu(self.mMore) @@ -517,10 +517,10 @@ class GuiProjectTree(QTreeWidget): self.customContextMenuRequested.connect(self._openContextMenu) # Tree Settings - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight cMg = CONFIG.pxInt(6) - self.setIconSize(QSize(iPx, iPx)) + self.setIconSize(SHARED.theme.baseIconSize) self.setFrameStyle(QFrame.Shape.NoFrame) self.setUniformRowHeights(True) self.setAllColumnsShowFocus(True) @@ -564,7 +564,7 @@ class GuiProjectTree(QTreeWidget): self.itemSelectionChanged.connect(self._treeSelectionChange) # Auto Scroll - self._scrollMargin = SHARED.theme.baseIconSize + self._scrollMargin = SHARED.theme.baseIconHeight self._scrollDirection = 0 self._scrollTimer = QTimer(self) self._scrollTimer.timeout.connect(self._doAutoScroll) diff --git a/novelwriter/gui/search.py b/novelwriter/gui/search.py index f2c83e65..0394c26e 100644 --- a/novelwriter/gui/search.py +++ b/novelwriter/gui/search.py @@ -27,7 +27,7 @@ import logging from time import time -from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtGui import QCursor, QKeyEvent from PyQt5.QtWidgets import ( QFrame, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QToolBar, QTreeWidget, @@ -60,7 +60,8 @@ class GuiProjectSearch(QWidget): logger.debug("Create: GuiProjectSearch") - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize mPx = CONFIG.pxInt(2) tPx = CONFIG.pxInt(4) @@ -77,7 +78,7 @@ class GuiProjectSearch(QWidget): # Options self.searchOpt = QToolBar(self) self.searchOpt.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) - self.searchOpt.setIconSize(QSize(iPx, iPx)) + self.searchOpt.setIconSize(iSz) self.searchOpt.setContentsMargins(0, 0, 0, 0) self.toggleCase = self.searchOpt.addAction(self.tr("Case Sensitive")) @@ -109,7 +110,7 @@ class GuiProjectSearch(QWidget): self.searchResult = QTreeWidget(self) self.searchResult.setHeaderHidden(True) self.searchResult.setColumnCount(2) - self.searchResult.setIconSize(QSize(iPx, iPx)) + self.searchResult.setIconSize(iSz) self.searchResult.setIndentation(iPx) self.searchResult.setFrameStyle(QFrame.Shape.NoFrame) self.searchResult.setUniformRowHeights(True) diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py index 2030985e..efda9c17 100644 --- a/novelwriter/gui/sidebar.py +++ b/novelwriter/gui/sidebar.py @@ -28,7 +28,7 @@ import logging from typing import TYPE_CHECKING from PyQt5.QtGui import QPalette -from PyQt5.QtCore import QEvent, QPoint, pyqtSignal +from PyQt5.QtCore import QEvent, QPoint, QSize, pyqtSignal from PyQt5.QtWidgets import QMenu, QVBoxLayout, QWidget from novelwriter import CONFIG, SHARED @@ -55,40 +55,42 @@ class GuiSideBar(QWidget): self.mainGui = mainGui iPx = int(1.2*SHARED.theme.baseButtonHeight) + iSz = QSize(iPx, iPx) + self.setContentsMargins(0, 0, 0, 0) self.installEventFilter(StatusTipFilter(mainGui)) # Buttons - self.tbProject = NIconToolButton(self, iPx) + self.tbProject = NIconToolButton(self, iSz) self.tbProject.setToolTip("{0} [Ctrl+T]".format(self.tr("Project Tree View"))) self.tbProject.clicked.connect(lambda: self.requestViewChange.emit(nwView.PROJECT)) - self.tbNovel = NIconToolButton(self, iPx) + self.tbNovel = NIconToolButton(self, iSz) self.tbNovel.setToolTip("{0} [Ctrl+T]".format(self.tr("Novel Tree View"))) self.tbNovel.clicked.connect(lambda: self.requestViewChange.emit(nwView.NOVEL)) - self.tbSearch = NIconToolButton(self, iPx) + self.tbSearch = NIconToolButton(self, iSz) self.tbSearch.setToolTip("{0} [Ctrl+Shift+F]".format(self.tr("Project Search"))) self.tbSearch.clicked.connect(lambda: self.requestViewChange.emit(nwView.SEARCH)) - self.tbOutline = NIconToolButton(self, iPx) + self.tbOutline = NIconToolButton(self, iSz) self.tbOutline.setToolTip("{0} [Ctrl+Shift+T]".format(self.tr("Novel Outline View"))) self.tbOutline.clicked.connect(lambda: self.requestViewChange.emit(nwView.OUTLINE)) - self.tbBuild = NIconToolButton(self, iPx) + self.tbBuild = NIconToolButton(self, iSz) self.tbBuild.setToolTip("{0} [F5]".format(self.tr("Build Manuscript"))) self.tbBuild.clicked.connect(self.mainGui.showBuildManuscriptDialog) - self.tbDetails = NIconToolButton(self, iPx) + self.tbDetails = NIconToolButton(self, iSz) self.tbDetails.setToolTip("{0} [Shift+F6]".format(self.tr("Novel Details"))) self.tbDetails.clicked.connect(self.mainGui.showNovelDetailsDialog) - self.tbStats = NIconToolButton(self, iPx) + self.tbStats = NIconToolButton(self, iSz) self.tbStats.setToolTip("{0} [F6]".format(self.tr("Writing Statistics"))) self.tbStats.clicked.connect(self.mainGui.showWritingStatsDialog) # Settings Menu - self.tbSettings = NIconToolButton(self, iPx) + self.tbSettings = NIconToolButton(self, iSz) self.tbSettings.setToolTip(self.tr("Settings")) self.mSettings = _PopRightMenu(self.tbSettings) diff --git a/novelwriter/gui/statusbar.py b/novelwriter/gui/statusbar.py index 61168f20..85befc60 100644 --- a/novelwriter/gui/statusbar.py +++ b/novelwriter/gui/statusbar.py @@ -58,7 +58,7 @@ class GuiMainStatus(QStatusBar): colSaved = SHARED.theme.statSaved colUnsaved = SHARED.theme.statUnsaved - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight # Permanent Widgets # ================= @@ -130,7 +130,7 @@ class GuiMainStatus(QStatusBar): def updateTheme(self) -> None: """Update theme elements.""" - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight self.langIcon.setPixmap(SHARED.theme.getPixmap("status_lang", (iPx, iPx))) self.statsIcon.setPixmap(SHARED.theme.getPixmap("status_stats", (iPx, iPx))) self.timePixmap = SHARED.theme.getPixmap("status_time", (iPx, iPx)) diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index 3d530c4c..db993cb3 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -29,7 +29,7 @@ import logging from math import ceil from pathlib import Path -from PyQt5.QtCore import Qt +from PyQt5.QtCore import QSize, Qt from PyQt5.QtWidgets import qApp from PyQt5.QtGui import ( QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap @@ -156,13 +156,18 @@ class GuiTheme: self.guiFontB.setBold(True) qMetric = QFontMetrics(self.guiFont) + fHeight = qMetric.height() + fAscent = qMetric.ascent() self.fontPointSize = self.guiFont.pointSizeF() - self.fontPixelSize = int(round(qMetric.height())) - self.baseIconSize = int(round(qMetric.ascent())) - self.baseButtonHeight = int(round(1.35*qMetric.ascent())) + self.fontPixelSize = int(round(fHeight)) + self.baseIconHeight = int(round(fAscent)) + self.baseButtonHeight = int(round(1.35*fAscent)) self.textNHeight = qMetric.boundingRect("N").height() self.textNWidth = qMetric.boundingRect("N").width() + self.baseIconSize = QSize(self.baseIconHeight, self.baseIconHeight) + self.buttonIconSize = QSize(int(0.9*self.baseIconHeight), int(0.9*self.baseIconHeight)) + # Monospace Font self.guiFontFixed = QFont() self.guiFontFixed.setPointSizeF(0.95*self.fontPointSize) @@ -171,7 +176,7 @@ class GuiTheme: logger.debug("GUI Font Family: %s", self.guiFont.family()) logger.debug("GUI Font Point Size: %.2f", self.fontPointSize) logger.debug("GUI Font Pixel Size: %d", self.fontPixelSize) - logger.debug("GUI Base Icon Size: %d", self.baseIconSize) + logger.debug("GUI Base Icon Height: %d", self.baseIconHeight) logger.debug("GUI Base Button Height: %d", self.baseButtonHeight) logger.debug("Text 'N' Height: %d", self.textNHeight) logger.debug("Text 'N' Width: %d", self.textNWidth) @@ -679,7 +684,7 @@ class GuiIcons: def getToggleIcon(self, name: str, size: tuple[int, int]) -> 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) + pOne = self.getPixmap(self.TOGGLE_ICON_KEYS[name][0], size) pTwo = self.getPixmap(self.TOGGLE_ICON_KEYS[name][1], size) icon = QIcon() icon.addPixmap(pOne, QIcon.Mode.Normal, QIcon.State.On) @@ -724,7 +729,7 @@ class GuiIcons: def getHeaderDecoration(self, hLevel: int) -> QPixmap: """Get the decoration for a specific heading level.""" if not self._headerDec: - iPx = self.mainTheme.baseIconSize + iPx = self.mainTheme.baseIconHeight self._headerDec = [ self.loadDecoration("deco_doc_h0", h=iPx), self.loadDecoration("deco_doc_h1", h=iPx), @@ -737,7 +742,7 @@ class GuiIcons: def getHeaderDecorationNarrow(self, hLevel: int) -> QPixmap: """Get the narrow decoration for a specific heading level.""" if not self._headerDecNarrow: - iPx = self.mainTheme.baseIconSize + iPx = self.mainTheme.baseIconHeight self._headerDecNarrow = [ self.loadDecoration("deco_doc_h0_n", h=iPx), self.loadDecoration("deco_doc_h1_n", h=iPx), diff --git a/novelwriter/shared.py b/novelwriter/shared.py index 15b66a9e..af6767a6 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -404,7 +404,7 @@ class _GuiAlert(QMessageBox): self.setStandardButtons(QMessageBox.Yes | QMessageBox.No) else: self.setStandardButtons(QMessageBox.Ok) - pSz = 2*self._theme.baseIconSize + pSz = 2*self._theme.baseIconHeight if level == self.INFO: self.setIconPixmap(self._theme.getPixmap("alert_info", (pSz, pSz))) self.setWindowTitle(self.tr("Information")) diff --git a/novelwriter/tools/dictionaries.py b/novelwriter/tools/dictionaries.py index 7d122348..33d0d7af 100644 --- a/novelwriter/tools/dictionaries.py +++ b/novelwriter/tools/dictionaries.py @@ -36,8 +36,9 @@ from PyQt5.QtWidgets import ( ) from novelwriter import CONFIG, SHARED -from novelwriter.error import formatException from novelwriter.common import formatFileFilter, openExternalPath, formatInt, getFileSize +from novelwriter.error import formatException +from novelwriter.extensions.modified import NIconToolButton logger = logging.getLogger(__name__) @@ -54,6 +55,7 @@ class GuiDictionaries(QDialog): self._installPath = None self._currDicts = set() + iSz = SHARED.theme.baseIconSize iPx = CONFIG.pxInt(4) mPx = CONFIG.pxInt(8) sPx = CONFIG.pxInt(16) @@ -72,8 +74,7 @@ class GuiDictionaries(QDialog): self.huInfo.setOpenExternalLinks(True) self.huInfo.setWordWrap(True) self.huInput = QLineEdit(self) - self.huBrowse = QPushButton(self) - self.huBrowse.setIcon(SHARED.theme.getIcon("browse")) + self.huBrowse = NIconToolButton(self, iSz, "browse") self.huBrowse.clicked.connect(self._doBrowseHunspell) self.huImport = QPushButton(self.tr("Add Dictionary"), self) self.huImport.setIcon(SHARED.theme.getIcon("add")) @@ -91,8 +92,7 @@ class GuiDictionaries(QDialog): self.inInfo = QLabel(self.tr("Dictionary install location")) self.inPath = QLineEdit(self) self.inPath.setReadOnly(True) - self.inBrowse = QPushButton(self) - self.inBrowse.setIcon(SHARED.theme.getIcon("browse")) + self.inBrowse = NIconToolButton(self, iSz, "browse") self.inBrowse.clicked.connect(self._doOpenInstallLocation) self.inBox = QHBoxLayout() diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index 501cb4bd..5eef8aef 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -28,7 +28,7 @@ import logging from pathlib import Path from PyQt5.QtGui import QCloseEvent -from PyQt5.QtCore import QSize, QTimer, Qt, pyqtSlot +from PyQt5.QtCore import QTimer, Qt, pyqtSlot from PyQt5.QtWidgets import ( QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFileDialog, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem, @@ -42,6 +42,7 @@ from novelwriter.core.buildsettings import BuildSettings from novelwriter.core.docbuild import NWBuildDocument from novelwriter.core.item import NWItem from novelwriter.enum import nwBuildFmt +from novelwriter.extensions.modified import NIconToolButton from novelwriter.extensions.simpleprogress import NProgressSimple from novelwriter.types import QtAlignCenter @@ -70,7 +71,8 @@ class GuiManuscriptBuild(QDialog): self.setMinimumWidth(CONFIG.pxInt(500)) self.setMinimumHeight(CONFIG.pxInt(300)) - iPx = SHARED.theme.baseIconSize + iSz = SHARED.theme.baseIconSize + bSz = SHARED.theme.buttonIconSize sp4 = CONFIG.pxInt(4) sp8 = CONFIG.pxInt(8) sp16 = CONFIG.pxInt(16) @@ -88,7 +90,7 @@ class GuiManuscriptBuild(QDialog): self.lblFormat = QLabel(self.tr("Output Format")) self.listFormats = QListWidget() - self.listFormats.setIconSize(QSize(iPx, iPx)) + self.listFormats.setIconSize(iSz) current = None for key in nwBuildFmt: item = QListWidgetItem() @@ -115,7 +117,7 @@ class GuiManuscriptBuild(QDialog): self.lblContent = QLabel(self.tr("Table of Contents")) self.listContent = QListWidget(self) - self.listContent.setIconSize(QSize(iPx, iPx)) + self.listContent.setIconSize(iSz) self.listContent.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) self.contentBox = QVBoxLayout() @@ -142,7 +144,7 @@ class GuiManuscriptBuild(QDialog): # Build Path self.lblPath = QLabel(self.tr("Path")) self.buildPath = QLineEdit(self) - self.btnBrowse = QPushButton(SHARED.theme.getIcon("browse"), "") + self.btnBrowse = NIconToolButton(self, iSz, "browse") self.pathBox = QHBoxLayout() self.pathBox.addWidget(self.buildPath) @@ -152,7 +154,7 @@ class GuiManuscriptBuild(QDialog): # Build Name self.lblName = QLabel(self.tr("File Name")) self.buildName = QLineEdit(self) - self.btnReset = QPushButton(SHARED.theme.getIcon("revert"), "") + self.btnReset = NIconToolButton(self, iSz, "revert") self.btnReset.setToolTip(self.tr("Reset file name to default")) self.nameBox = QHBoxLayout() @@ -178,7 +180,10 @@ class GuiManuscriptBuild(QDialog): # Dialog Buttons self.btnOpen = QPushButton(SHARED.theme.getIcon("browse"), self.tr("Open Folder")) + self.btnOpen.setIconSize(bSz) self.btnBuild = QPushButton(SHARED.theme.getIcon("export"), self.tr("&Build")) + self.btnBuild.setIconSize(bSz) + self.dlgButtons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) self.dlgButtons.addButton(self.btnOpen, QDialogButtonBox.ButtonRole.ActionRole) self.dlgButtons.addButton(self.btnBuild, QDialogButtonBox.ButtonRole.ActionRole) diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index fa67903f..7528477a 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -31,7 +31,7 @@ from typing import TYPE_CHECKING from datetime import datetime from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent -from PyQt5.QtCore import QSize, QTimer, QUrl, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QTimer, QUrl, Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QFormLayout, QGridLayout, QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton, QSizePolicy, QSplitter, @@ -48,7 +48,7 @@ from novelwriter.core.tohtml import ToHtml from novelwriter.core.tokenizer import HeadingFormatter from novelwriter.error import logException from novelwriter.extensions.circularprogress import NProgressCircle -from novelwriter.extensions.modified import NIconToolButton +from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON from novelwriter.tools.manusbuild import GuiManuscriptBuild from novelwriter.tools.manussettings import GuiBuildSettings @@ -89,7 +89,7 @@ class GuiManuscript(QDialog): self.setMinimumWidth(CONFIG.pxInt(600)) self.setMinimumHeight(CONFIG.pxInt(500)) - iPx = SHARED.theme.baseIconSize + iSz = SHARED.theme.baseIconSize wWin = CONFIG.pxInt(900) hWin = CONFIG.pxInt(600) @@ -108,20 +108,17 @@ class GuiManuscript(QDialog): buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) - self.tbAdd = NIconToolButton(self, iPx) - self.tbAdd.setIcon(SHARED.theme.getIcon("add")) + self.tbAdd = NIconToolButton(self, iSz, "add") self.tbAdd.setToolTip(self.tr("Add New Build")) self.tbAdd.setStyleSheet(buttonStyle) self.tbAdd.clicked.connect(self._createNewBuild) - self.tbDel = NIconToolButton(self, iPx) - self.tbDel.setIcon(SHARED.theme.getIcon("remove")) + self.tbDel = NIconToolButton(self, iSz, "remove") self.tbDel.setToolTip(self.tr("Delete Selected Build")) self.tbDel.setStyleSheet(buttonStyle) self.tbDel.clicked.connect(self._deleteSelectedBuild) - self.tbEdit = NIconToolButton(self, iPx) - self.tbEdit.setIcon(SHARED.theme.getIcon("edit")) + self.tbEdit = NIconToolButton(self, iSz, "edit") self.tbEdit.setToolTip(self.tr("Edit Selected Build")) self.tbEdit.setStyleSheet(buttonStyle) self.tbEdit.clicked.connect(self._editSelectedBuild) @@ -140,7 +137,7 @@ class GuiManuscript(QDialog): # ====== self.buildList = QListWidget(self) - self.buildList.setIconSize(QSize(iPx, iPx)) + self.buildList.setIconSize(iSz) self.buildList.doubleClicked.connect(self._editSelectedBuild) self.buildList.currentItemChanged.connect(self._updateBuildDetails) self.buildList.setSelectionMode(QAbstractItemView.SingleSelection) @@ -529,7 +526,7 @@ class _DetailsWidget(QWidget): # Tree Widget self.listView = QTreeWidget(self) self.listView.setHeaderLabels([self.tr("Setting"), self.tr("Value")]) - self.listView.setIndentation(SHARED.theme.baseIconSize) + self.listView.setIndentation(SHARED.theme.baseIconHeight) self.listView.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) # Assemble @@ -724,7 +721,9 @@ class _OutlineWidget(QWidget): parent.addChild(item) indent = True - self.listView.setIndentation(SHARED.theme.baseIconSize if indent else CONFIG.pxInt(4)) + self.listView.setIndentation( + SHARED.theme.baseIconHeight if indent else CONFIG.pxInt(4) + ) self._outline = data return @@ -979,13 +978,7 @@ class _StatsWidget(QWidget): self.minWidget = QWidget(self) self.maxWidget = QWidget(self) - iPx = int(0.6*SHARED.theme.baseIconSize) - toggleIcon = SHARED.theme.getToggleIcon("unfold", (iPx, iPx)) - - self.toggleButton = NIconToolButton(self, iPx) - self.toggleButton.setCheckable(True) - self.toggleButton.setIcon(toggleIcon) - self.toggleButton.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)) + self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize, "unfold") self.toggleButton.toggled.connect(self._toggleView) self._buildMinimal() diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index d36a0307..a575fead 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -28,12 +28,12 @@ import logging from typing import TYPE_CHECKING from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument -from PyQt5.QtCore import QEvent, QSize, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QEvent, Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFontDialog, QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSplitter, QStackedWidget, - QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget + QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) from novelwriter import CONFIG, SHARED @@ -42,7 +42,7 @@ from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.extensions.configlayout import ( NColourLabel, NFixedPage, NScrollableForm, NScrollablePage ) -from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox +from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox @@ -316,14 +316,13 @@ class _FilterTab(NFixedPage): # Project Tree # ============ - # Tree Settings - iPx = SHARED.theme.baseIconSize + iSz = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight cMg = CONFIG.pxInt(6) - iconSize = QSize(iPx, iPx) # Tree Widget self.optTree = QTreeWidget(self) - self.optTree.setIconSize(QSize(iPx, iPx)) + self.optTree.setIconSize(iSz) self.optTree.setUniformRowHeights(True) self.optTree.setAllColumnsShowFocus(True) self.optTree.setHeaderHidden(True) @@ -346,22 +345,18 @@ class _FilterTab(NFixedPage): # Filters # ======= - self.includedButton = QToolButton(self) + self.includedButton = NIconToolButton(self, iSz) self.includedButton.setToolTip(self.tr("Always included")) self.includedButton.setIcon(self._statusFlags[self.F_INCLUDED]) - self.includedButton.setIconSize(iconSize) self.includedButton.clicked.connect(lambda: self._setSelectedMode(self.F_INCLUDED)) - self.excludedButton = QToolButton(self) + self.excludedButton = NIconToolButton(self, iSz) self.excludedButton.setToolTip(self.tr("Always excluded")) self.excludedButton.setIcon(self._statusFlags[self.F_EXCLUDED]) - self.excludedButton.setIconSize(iconSize) self.excludedButton.clicked.connect(lambda: self._setSelectedMode(self.F_EXCLUDED)) - self.resetButton = QToolButton(self) + self.resetButton = NIconToolButton(self, iSz, "revert") self.resetButton.setToolTip(self.tr("Reset to default")) - self.resetButton.setIcon(SHARED.theme.getIcon("revert")) - self.resetButton.setIconSize(iconSize) self.resetButton.clicked.connect(lambda: self._setSelectedMode(self.F_FILTERED)) self.modeBox = QHBoxLayout() @@ -598,12 +593,11 @@ class _HeadingsTab(NScrollablePage): self._build = build self._editing = 0 - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize sSp = CONFIG.pxInt(16) vSp = CONFIG.pxInt(12) bSp = CONFIG.pxInt(6) - iconSize = QSize(iPx, iPx) - editIcon = SHARED.theme.getIcon("edit") trHide = self.tr("Hide") # Format Boxes @@ -615,9 +609,7 @@ class _HeadingsTab(NScrollablePage): self.lblTitle = QLabel(self._build.getLabel("headings.fmtTitle"), self) self.fmtTitle = QLineEdit("", self) self.fmtTitle.setReadOnly(True) - self.btnTitle = QToolButton(self) - self.btnTitle.setIcon(editIcon) - self.btnTitle.setIconSize(iconSize) + self.btnTitle = NIconToolButton(self, iSz, "edit") self.btnTitle.clicked.connect(lambda: self._editHeading(self.EDIT_TITLE)) self.hdeTitle = QLabel(trHide, self) self.hdeTitle.setIndent(bSp) @@ -633,9 +625,7 @@ class _HeadingsTab(NScrollablePage): self.lblChapter = QLabel(self._build.getLabel("headings.fmtChapter"), self) self.fmtChapter = QLineEdit("", self) self.fmtChapter.setReadOnly(True) - self.btnChapter = QToolButton(self) - self.btnChapter.setIcon(editIcon) - self.btnChapter.setIconSize(iconSize) + self.btnChapter = NIconToolButton(self, iSz, "edit") self.btnChapter.clicked.connect(lambda: self._editHeading(self.EDIT_CHAPTER)) self.hdeChapter = QLabel(trHide, self) self.hdeChapter.setIndent(bSp) @@ -651,9 +641,7 @@ class _HeadingsTab(NScrollablePage): self.lblUnnumbered = QLabel(self._build.getLabel("headings.fmtUnnumbered"), self) self.fmtUnnumbered = QLineEdit("", self) self.fmtUnnumbered.setReadOnly(True) - self.btnUnnumbered = QToolButton(self) - self.btnUnnumbered.setIcon(editIcon) - self.btnUnnumbered.setIconSize(iconSize) + self.btnUnnumbered = NIconToolButton(self, iSz, "edit") self.btnUnnumbered.clicked.connect(lambda: self._editHeading(self.EDIT_UNNUM)) self.hdeUnnumbered = QLabel(trHide, self) self.hdeUnnumbered.setIndent(bSp) @@ -669,9 +657,7 @@ class _HeadingsTab(NScrollablePage): self.lblScene = QLabel(self._build.getLabel("headings.fmtScene"), self) self.fmtScene = QLineEdit("", self) self.fmtScene.setReadOnly(True) - self.btnScene = QToolButton(self) - self.btnScene.setIcon(editIcon) - self.btnScene.setIconSize(iconSize) + self.btnScene = NIconToolButton(self, iSz, "edit") self.btnScene.clicked.connect(lambda: self._editHeading(self.EDIT_SCENE)) self.hdeScene = QLabel(trHide, self) self.hdeScene.setIndent(bSp) @@ -687,9 +673,7 @@ class _HeadingsTab(NScrollablePage): self.lblHScene = QLabel(self._build.getLabel("headings.fmtHardScene"), self) self.fmtHScene = QLineEdit("", self) self.fmtHScene.setReadOnly(True) - self.btnHScene = QToolButton(self) - self.btnHScene.setIcon(editIcon) - self.btnHScene.setIconSize(iconSize) + self.btnHScene = NIconToolButton(self, iSz, "edit") self.btnHScene.clicked.connect(lambda: self._editHeading(self.EDIT_HSCENE)) self.hdeHScene = QLabel(trHide, self) self.hdeHScene.setIndent(bSp) @@ -705,9 +689,7 @@ class _HeadingsTab(NScrollablePage): self.lblSection = QLabel(self._build.getLabel("headings.fmtSection"), self) self.fmtSection = QLineEdit("", self) self.fmtSection.setReadOnly(True) - self.btnSection = QToolButton(self) - self.btnSection.setIcon(editIcon) - self.btnSection.setIconSize(iconSize) + self.btnSection = NIconToolButton(self, iSz, "edit") self.btnSection.clicked.connect(lambda: self._editHeading(self.EDIT_SECTION)) self.hdeSection = QLabel(trHide, self) self.hdeSection.setIndent(bSp) @@ -996,8 +978,8 @@ class _ContentTab(NScrollableForm): self._build = build - iPx = SHARED.theme.baseIconSize - iconSize = QSize(iPx, iPx) + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize # Text Content self.incBodyText = NSwitch(self, height=iPx) @@ -1014,11 +996,8 @@ class _ContentTab(NScrollableForm): lambda keyword=keyword: self._updateIgnoredKeywords(keyword) ) - self.ignoredKeywordsButton = QToolButton(self) - self.ignoredKeywordsButton.setIcon(SHARED.theme.getIcon("add")) - self.ignoredKeywordsButton.setIconSize(iconSize) + self.ignoredKeywordsButton = NIconToolButton(self, iSz, "add") self.ignoredKeywordsButton.setMenu(self.mnKeywords) - self.ignoredKeywordsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) self.addGroupLabel(self._build.getLabel("text.grpContent")) self.addRow(self._build.getLabel("text.includeBodyText"), self.incBodyText) @@ -1087,7 +1066,8 @@ class _FormatTab(NScrollableForm): self._build = build self._unitScale = 1.0 - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize spW = 6*SHARED.theme.textNWidth dbW = 8*SHARED.theme.textNWidth @@ -1099,8 +1079,7 @@ class _FormatTab(NScrollableForm): # Font Family self.textFont = QLineEdit(self) self.textFont.setReadOnly(True) - self.btnTextFont = QPushButton("...") - self.btnTextFont.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("..."))) + self.btnTextFont = NIconToolButton(self, iSz, "more") self.btnTextFont.clicked.connect(self._selectFont) self.addRow( self._build.getLabel("format.textFont"), self.textFont, @@ -1353,9 +1332,9 @@ class _OutputTab(NScrollableForm): self._build = build - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize spW = 6*SHARED.theme.textNWidth - iconSize = QSize(iPx, iPx) # Open Document self.addGroupLabel(self._build.getLabel("odt")) @@ -1365,9 +1344,7 @@ class _OutputTab(NScrollableForm): self.odtPageHeader = QLineEdit(self) self.odtPageHeader.setMinimumWidth(CONFIG.pxInt(200)) - self.btnPageHeader = QToolButton(self) - self.btnPageHeader.setIcon(SHARED.theme.getIcon("revert")) - self.btnPageHeader.setIconSize(iconSize) + self.btnPageHeader = NIconToolButton(self, iSz, "revert") self.btnPageHeader.clicked.connect(self._resetPageHeader) self.addRow( self._build.getLabel("odt.pageHeader"), self.odtPageHeader, diff --git a/novelwriter/tools/noveldetails.py b/novelwriter/tools/noveldetails.py index 8750d273..17780c0c 100644 --- a/novelwriter/tools/noveldetails.py +++ b/novelwriter/tools/noveldetails.py @@ -27,7 +27,7 @@ import math import logging from PyQt5.QtGui import QCloseEvent -from PyQt5.QtCore import QSize, Qt, pyqtSlot +from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QDialogButtonBox, QFormLayout, QGridLayout, QHBoxLayout, QLabel, QSpinBox, QStackedWidget, QTreeWidget, @@ -310,7 +310,8 @@ class _ContentsPage(NFixedPage): self._data = [] self._currentRoot = None - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize hPx = CONFIG.pxInt(12) vPx = CONFIG.pxInt(4) options = SHARED.project.options @@ -323,7 +324,7 @@ class _ContentsPage(NFixedPage): # Contents Tree self.tocTree = QTreeWidget(self) - self.tocTree.setIconSize(QSize(iPx, iPx)) + self.tocTree.setIconSize(iSz) self.tocTree.setIndentation(0) self.tocTree.setColumnCount(6) self.tocTree.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index 945c06d5..4a680e69 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -36,8 +36,8 @@ from PyQt5.QtCore import ( from PyQt5.QtWidgets import ( QAction, QDialog, QFileDialog, QFormLayout, QHBoxLayout, QLabel, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut, QStackedWidget, - QStyle, QStyleOptionViewItem, QStyledItemDelegate, QToolButton, - QVBoxLayout, QWidget, qApp + QStyle, QStyleOptionViewItem, QStyledItemDelegate, QVBoxLayout, QWidget, + qApp ) from novelwriter import CONFIG, SHARED @@ -46,7 +46,7 @@ from novelwriter.constants import nwFiles from novelwriter.core.coretools import ProjectBuilder from novelwriter.enum import nwItemClass from novelwriter.extensions.configlayout import NWrappedWidgetBox -from novelwriter.extensions.modified import NSpinBox +from novelwriter.extensions.modified import NIconToolButton, NSpinBox from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.versioninfo import VersionInfoWidget from novelwriter.types import QtAlignLeft, QtAlignRightTop @@ -76,8 +76,9 @@ class GuiWelcome(QDialog): hD = CONFIG.pxInt(36) hE = CONFIG.pxInt(48) hF = CONFIG.pxInt(128) - self._hPx = CONFIG.pxInt(600) + btnIconSize = SHARED.theme.buttonIconSize + self._hPx = CONFIG.pxInt(600) self.resize(*CONFIG.welcomeWinSize) # Elements @@ -110,26 +111,32 @@ class GuiWelcome(QDialog): self.btnList = QPushButton(self.tr("List"), self) self.btnList.setIcon(SHARED.theme.getIcon("list")) + self.btnList.setIconSize(btnIconSize) self.btnList.clicked.connect(self._showOpenProjectPage) self.btnNew = QPushButton(self.tr("New"), self) self.btnNew.setIcon(SHARED.theme.getIcon("add")) + self.btnNew.setIconSize(btnIconSize) self.btnNew.clicked.connect(self._showNewProjectPage) self.btnBrowse = QPushButton(self.tr("Browse"), self) self.btnBrowse.setIcon(SHARED.theme.getIcon("browse")) + self.btnBrowse.setIconSize(btnIconSize) self.btnBrowse.clicked.connect(self._browseForProject) self.btnCancel = QPushButton(self.tr("Cancel"), self) self.btnCancel.setIcon(SHARED.theme.getIcon("cross")) + self.btnCancel.setIconSize(btnIconSize) self.btnCancel.clicked.connect(self.close) self.btnCreate = QPushButton(self.tr("Create"), self) self.btnCreate.setIcon(SHARED.theme.getIcon("star")) + self.btnCreate.setIconSize(btnIconSize) self.btnCreate.clicked.connect(self.tabNew.createNewProject) self.btnOpen = QPushButton(self.tr("Open"), self) self.btnOpen.setIcon(SHARED.theme.getIcon("open")) + self.btnOpen.setIconSize(btnIconSize) self.btnOpen.clicked.connect(self._openSelectedItem) self.btnBox = QHBoxLayout() @@ -557,11 +564,10 @@ class _NewProjectForm(QWidget): self._fillMode = self.FILL_BLANK self._copyPath = None - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight + iSz = SHARED.theme.baseIconSize sPx = CONFIG.pxInt(16) - iconSize = QSize(iPx, iPx) - # Project Settings # ================ @@ -580,9 +586,7 @@ class _NewProjectForm(QWidget): self.projPath = QLineEdit(self) self.projPath.setReadOnly(True) - self.browsePath = QToolButton(self) - self.browsePath.setIcon(SHARED.theme.getIcon("browse")) - self.browsePath.setIconSize(iconSize) + self.browsePath = NIconToolButton(self, iSz, "browse") self.browsePath.clicked.connect(self._doBrowse) self.pathBox = QHBoxLayout() @@ -593,9 +597,7 @@ class _NewProjectForm(QWidget): self.projFill = QLineEdit(self) self.projFill.setReadOnly(True) - self.browseFill = QToolButton(self) - self.browseFill.setIconSize(iconSize) - self.browseFill.setIcon(SHARED.theme.getIcon("add_document")) + self.browseFill = NIconToolButton(self, iSz, "add_document") self.fillMenu = _PopLeftDirectionMenu(self.browseFill) @@ -612,7 +614,6 @@ class _NewProjectForm(QWidget): self.fillCopy.triggered.connect(self._setFillCopy) self.browseFill.setMenu(self.fillMenu) - self.browseFill.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) self.fillBox = QHBoxLayout() self.fillBox.addWidget(self.projFill) diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index d9002175..4a8e09a9 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -188,7 +188,7 @@ class GuiWritingStats(QDialog): self.infoForm.setRowStretch(6, 1) # Filter Options - iPx = SHARED.theme.baseIconSize + iPx = SHARED.theme.baseIconHeight self.filterBox = QGroupBox(self.tr("Filters"), self) self.filterForm = QGridLayout(self) diff --git a/tests/mocked.py b/tests/mocked.py index 1e9506ff..65b65d93 100644 --- a/tests/mocked.py +++ b/tests/mocked.py @@ -75,7 +75,7 @@ class MockStatusBar: class MockTheme: def __init__(self): - self.baseIconSize = 10 + self.baseIconHeight = 10 return def getPixmap(self, *a): From b44072a9fa196be99c0988797587c9ce2f9ebd2c Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:38:16 +0200 Subject: [PATCH 6/6] Use the simplified theme icon setter where possible --- novelwriter/gui/doceditor.py | 36 +++++++++++++++---------------- novelwriter/gui/docviewer.py | 12 +++++------ novelwriter/gui/docviewerpanel.py | 6 +++--- novelwriter/gui/noveltree.py | 6 +++--- novelwriter/gui/projtree.py | 11 +++++----- novelwriter/gui/sidebar.py | 24 ++++++++------------- 6 files changed, 45 insertions(+), 50 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 31484f1c..d695f041 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2365,16 +2365,16 @@ class GuiDocToolBar(QWidget): palette.setColor(QPalette.ColorRole.Text, SHARED.theme.colText) self.setPalette(palette) - self.tbBoldMD.setIcon(SHARED.theme.getIcon("fmt_bold-md")) - self.tbItalicMD.setIcon(SHARED.theme.getIcon("fmt_italic-md")) - self.tbStrikeMD.setIcon(SHARED.theme.getIcon("fmt_strike-md")) - self.tbBold.setIcon(SHARED.theme.getIcon("fmt_bold")) - self.tbItalic.setIcon(SHARED.theme.getIcon("fmt_italic")) - self.tbStrike.setIcon(SHARED.theme.getIcon("fmt_strike")) - self.tbUnderline.setIcon(SHARED.theme.getIcon("fmt_underline")) - self.tbMark.setIcon(SHARED.theme.getIcon("fmt_mark")) - self.tbSuperscript.setIcon(SHARED.theme.getIcon("fmt_superscript")) - self.tbSubscript.setIcon(SHARED.theme.getIcon("fmt_subscript")) + self.tbBoldMD.setThemeIcon("fmt_bold-md") + self.tbItalicMD.setThemeIcon("fmt_italic-md") + self.tbStrikeMD.setThemeIcon("fmt_strike-md") + 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") return @@ -2634,8 +2634,8 @@ class GuiDocEditSearch(QFrame): 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.setIcon(SHARED.theme.getIcon("search")) - self.replaceButton.setIcon(SHARED.theme.getIcon("search_replace")) + self.searchButton.setThemeIcon("search") + self.replaceButton.setThemeIcon("search_replace") # Set stylesheets self.searchOpt.setStyleSheet("QToolBar {padding: 0;}") @@ -2913,11 +2913,11 @@ class GuiDocEditHeader(QWidget): def updateTheme(self) -> None: """Update theme elements.""" - self.tbButton.setIcon(SHARED.theme.getIcon("menu")) - self.outlineButton.setIcon(SHARED.theme.getIcon("list")) - self.searchButton.setIcon(SHARED.theme.getIcon("search")) - self.minmaxButton.setIcon(SHARED.theme.getIcon("maximise")) - self.closeButton.setIcon(SHARED.theme.getIcon("close")) + self.tbButton.setThemeIcon("menu") + self.outlineButton.setThemeIcon("list") + self.searchButton.setThemeIcon("search") + self.minmaxButton.setThemeIcon("maximise") + self.closeButton.setThemeIcon("close") buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) self.tbButton.setStyleSheet(buttonStyle) @@ -2985,7 +2985,7 @@ class GuiDocEditHeader(QWidget): @pyqtSlot(bool) def _focusModeChanged(self, focusMode: bool) -> None: """Update minimise/maximise icon of the Focus Mode button.""" - self.minmaxButton.setIcon(SHARED.theme.getIcon("minimise" if focusMode else "maximise")) + self.minmaxButton.setThemeIcon("minimise" if focusMode else "maximise") return ## diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 5d24807f..4e4eee8d 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -745,11 +745,11 @@ class GuiDocViewHeader(QWidget): def updateTheme(self) -> None: """Update theme elements.""" - self.outlineButton.setIcon(SHARED.theme.getIcon("list")) - self.backButton.setIcon(SHARED.theme.getIcon("backward")) - self.forwardButton.setIcon(SHARED.theme.getIcon("forward")) - self.refreshButton.setIcon(SHARED.theme.getIcon("refresh")) - self.closeButton.setIcon(SHARED.theme.getIcon("close")) + self.outlineButton.setThemeIcon("list") + self.backButton.setThemeIcon("backward") + self.forwardButton.setThemeIcon("forward") + self.refreshButton.setThemeIcon("refresh") + self.closeButton.setThemeIcon("close") buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) self.outlineButton.setStyleSheet(buttonStyle) @@ -921,7 +921,7 @@ class GuiDocViewFooter(QWidget): fPx = int(0.9*SHARED.theme.fontPixelSize) bulletIcon = SHARED.theme.getToggleIcon("bullet", (fPx, fPx)) - self.showHide.setIcon(SHARED.theme.getIcon("panel")) + self.showHide.setThemeIcon("panel") self.showComments.setIcon(bulletIcon) self.showSynopsis.setIcon(bulletIcon) diff --git a/novelwriter/gui/docviewerpanel.py b/novelwriter/gui/docviewerpanel.py index 18239b87..0292e177 100644 --- a/novelwriter/gui/docviewerpanel.py +++ b/novelwriter/gui/docviewerpanel.py @@ -38,6 +38,7 @@ from novelwriter.common import checkInt from novelwriter.constants import nwHeaders, nwLabels, nwLists, trConst from novelwriter.core.index import IndexHeading, IndexItem from novelwriter.enum import nwDocMode, nwItemClass +from novelwriter.extensions.modified import NIconToolButton from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON logger = logging.getLogger(__name__) @@ -65,8 +66,7 @@ class GuiDocViewerPanel(QWidget): self.aInactive.setCheckable(True) self.aInactive.toggled.connect(self._toggleHideInactive) - self.optsButton = QToolButton(self) - self.optsButton.setIconSize(iSz) + self.optsButton = NIconToolButton(self, iSz) self.optsButton.setMenu(self.optsMenu) self.optsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) @@ -100,7 +100,7 @@ class GuiDocViewerPanel(QWidget): def updateTheme(self, updateTabs: bool = True) -> None: """Update theme elements.""" - self.optsButton.setIcon(SHARED.theme.getIcon("menu")) + self.optsButton.setThemeIcon("menu") self.optsButton.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON)) self.mainTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS)) self.updateHandle(self._lastHandle) diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index 6fca3486..cb05df4d 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -270,9 +270,9 @@ class GuiNovelToolBar(QWidget): def updateTheme(self) -> None: """Update theme elements.""" # Icons - self.tbNovel.setIcon(SHARED.theme.getIcon("cls_novel")) - self.tbRefresh.setIcon(SHARED.theme.getIcon("refresh")) - self.tbMore.setIcon(SHARED.theme.getIcon("menu")) + self.tbNovel.setThemeIcon("cls_novel") + self.tbRefresh.setThemeIcon("refresh") + self.tbMore.setThemeIcon("menu") qPalette = self.palette() qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base()) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 2b0406ef..8baed4c3 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -385,16 +385,17 @@ class GuiProjectToolBar(QWidget): self.tbAdd.setStyleSheet(buttonStyle) self.tbMore.setStyleSheet(buttonStyle) - self.tbQuick.setIcon(SHARED.theme.getIcon("bookmark")) - self.tbMoveU.setIcon(SHARED.theme.getIcon("up")) - self.tbMoveD.setIcon(SHARED.theme.getIcon("down")) + self.tbQuick.setThemeIcon("bookmark") + self.tbMoveU.setThemeIcon("up") + self.tbMoveD.setThemeIcon("down") + self.tbAdd.setThemeIcon("add") + self.tbMore.setThemeIcon("menu") + self.aAddEmpty.setIcon(SHARED.theme.getIcon("proj_document")) self.aAddChap.setIcon(SHARED.theme.getIcon("proj_chapter")) self.aAddScene.setIcon(SHARED.theme.getIcon("proj_scene")) self.aAddNote.setIcon(SHARED.theme.getIcon("proj_note")) self.aAddFolder.setIcon(SHARED.theme.getIcon("proj_folder")) - self.tbAdd.setIcon(SHARED.theme.getIcon("add")) - self.tbMore.setIcon(SHARED.theme.getIcon("menu")) self.buildQuickLinksMenu() self._buildRootMenu() diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py index efda9c17..202a2157 100644 --- a/novelwriter/gui/sidebar.py +++ b/novelwriter/gui/sidebar.py @@ -130,30 +130,24 @@ class GuiSideBar(QWidget): buttonStyle = SHARED.theme.getStyleSheet(STYLES_BIG_TOOLBUTTON) - self.tbProject.setIcon(SHARED.theme.getIcon("view_editor")) self.tbProject.setStyleSheet(buttonStyle) - - self.tbNovel.setIcon(SHARED.theme.getIcon("view_novel")) self.tbNovel.setStyleSheet(buttonStyle) - - self.tbSearch.setIcon(SHARED.theme.getIcon("view_search")) self.tbSearch.setStyleSheet(buttonStyle) - - self.tbOutline.setIcon(SHARED.theme.getIcon("view_outline")) self.tbOutline.setStyleSheet(buttonStyle) - - self.tbBuild.setIcon(SHARED.theme.getIcon("view_build")) self.tbBuild.setStyleSheet(buttonStyle) - - self.tbDetails.setIcon(SHARED.theme.getIcon("proj_details")) self.tbDetails.setStyleSheet(buttonStyle) - - self.tbStats.setIcon(SHARED.theme.getIcon("proj_stats")) self.tbStats.setStyleSheet(buttonStyle) - - self.tbSettings.setIcon(SHARED.theme.getIcon("settings")) self.tbSettings.setStyleSheet(buttonStyle) + self.tbProject.setThemeIcon("view_editor") + self.tbNovel.setThemeIcon("view_novel") + self.tbSearch.setThemeIcon("view_search") + self.tbOutline.setThemeIcon("view_outline") + self.tbBuild.setThemeIcon("view_build") + self.tbDetails.setThemeIcon("proj_details") + self.tbStats.setThemeIcon("proj_stats") + self.tbSettings.setThemeIcon("settings") + return # END Class GuiSideBar