Make the style of config dialogs consistent

This commit is contained in:
Veronica Berglyd Olsen
2024-01-26 21:31:14 +01:00
parent 0dc4719400
commit 3761b1729f
4 changed files with 144 additions and 85 deletions
+2 -2
View File
@@ -59,9 +59,9 @@ class GuiPreferences(QDialog):
# Title
self.titleLabel = NColourLabel(
self.tr("Preferences"), SHARED.theme.helpText, parent=self, scale=1.25
self.tr("Preferences"), SHARED.theme.helpText,
parent=self, scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
)
self.titleLabel.setIndent(CONFIG.pxInt(4))
# Search Box
self.searchText = QLineEdit(self)
+43 -39
View File
@@ -29,15 +29,15 @@ import logging
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (
QColorDialog, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout, QLabel,
QLineEdit, QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget, qApp
QColorDialog, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout, QLineEdit,
QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
QWidget, qApp
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import simplified
from novelwriter.extensions.switch import NSwitch
from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm
from novelwriter.extensions.pagedsidebar import NPagedSideBar
logger = logging.getLogger(__name__)
@@ -59,21 +59,18 @@ class GuiProjectSettings(QDialog):
self.setObjectName("GuiProjectSettings")
self.setWindowTitle(self.tr("Project Settings"))
wW = CONFIG.pxInt(500)
wH = CONFIG.pxInt(400)
options = SHARED.project.options
self.setMinimumSize(wW, wH)
self.setMinimumSize(CONFIG.pxInt(500), CONFIG.pxInt(400))
self.resize(
CONFIG.pxInt(options.getInt("GuiProjectSettings", "winWidth", wW)),
CONFIG.pxInt(options.getInt("GuiProjectSettings", "winHeight", wH))
CONFIG.pxInt(options.getInt("GuiProjectSettings", "winWidth", CONFIG.pxInt(650))),
CONFIG.pxInt(options.getInt("GuiProjectSettings", "winHeight", CONFIG.pxInt(500)))
)
# Title
self.titleLabel = NColourLabel(
self.tr("Project Settings"), SHARED.theme.helpText, parent=self, scale=1.25
self.tr("Project Settings"), SHARED.theme.helpText,
parent=self, scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
)
self.titleLabel.setIndent(CONFIG.pxInt(4))
# SideBar
self.sidebar = NPagedSideBar(self)
@@ -251,31 +248,33 @@ class _SettingsPage(NScrollableForm):
self.addRow(
self.tr("Author(s)"), self.projAuthor,
self.tr("Only used when building the manuscript."),
stretch=(2, 1)
stretch=(3, 2)
)
# Project Language
self.projLang = QComboBox(self)
self.projLang.setMaximumWidth(xW)
self.projLang.setMinimumWidth(xW)
for tag, language in CONFIG.listLanguages(CONFIG.LANG_PROJ):
self.projLang.addItem(language, tag)
self.addRow(
self.tr("Project language"), self.projLang,
self.tr("Only used when building the manuscript.")
self.tr("Only used when building the manuscript."),
stretch=(3, 2)
)
if (idx := self.projLang.findData(data.language)) != -1:
self.projLang.setCurrentIndex(idx)
# Spell Check Language
self.spellLang = QComboBox(self)
self.spellLang.setMaximumWidth(xW)
self.spellLang.setMinimumWidth(xW)
self.spellLang.addItem(self.tr("Default"), "None")
if CONFIG.hasEnchant:
for tag, language in SHARED.spelling.listDictionaries():
self.spellLang.addItem(language, tag)
self.addRow(
self.tr("Spell check language"), self.spellLang,
self.tr("Overrides main preferences.")
self.tr("Overrides main preferences."),
stretch=(3, 2)
)
if (idx := self.spellLang.findData(data.spellLang)) != -1:
self.spellLang.setCurrentIndex(idx)
@@ -295,7 +294,7 @@ class _SettingsPage(NScrollableForm):
# END Class _SettingsPage
class _StatusPage(QWidget):
class _StatusPage(NFixedPage):
COL_LABEL = 0
COL_USAGE = 1
@@ -326,9 +325,13 @@ class _StatusPage(QWidget):
self.iPx = SHARED.theme.baseIconSize
# The List
# ========
# Title
self.pageTitle = NColourLabel(
pageLabel, SHARED.theme.helpText, parent=self,
scale=NColourLabel.HEADER_SCALE
)
# List Box
self.listBox = QTreeWidget(self)
self.listBox.setHeaderLabels([
self.tr("Label"), self.tr("Usage"),
@@ -392,11 +395,10 @@ class _StatusPage(QWidget):
self.innerBox.addLayout(self.listControls)
self.outerBox = QVBoxLayout()
self.outerBox.addWidget(QLabel("<b>%s</b>" % pageLabel))
self.outerBox.addWidget(self.pageTitle)
self.outerBox.addLayout(self.innerBox)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.outerBox)
self.setCentralLayout(self.outerBox)
return
@@ -422,7 +424,6 @@ class _StatusPage(QWidget):
"cols": item.data(self.COL_LABEL, self.COL_ROLE),
})
return newList, self._colDeleted
return [], []
def columnWidth(self) -> int:
@@ -517,16 +518,16 @@ class _StatusPage(QWidget):
##
def _addItem(self, key: str | None, name: str,
cols: tuple[int, int, int], count: int) -> None:
colour: tuple[int, int, int], count: int) -> None:
"""Add a status item to the list."""
pixmap = QPixmap(self.iPx, self.iPx)
pixmap.fill(QColor(*cols))
pixmap.fill(QColor(*colour))
item = QTreeWidgetItem()
item.setText(self.COL_LABEL, name)
item.setIcon(self.COL_LABEL, QIcon(pixmap))
item.setData(self.COL_LABEL, self.KEY_ROLE, key)
item.setData(self.COL_LABEL, self.COL_ROLE, cols)
item.setData(self.COL_LABEL, self.COL_ROLE, colour)
item.setData(self.COL_LABEL, self.NUM_ROLE, count)
item.setText(self.COL_USAGE, self._usageString(count))
@@ -558,24 +559,23 @@ class _StatusPage(QWidget):
def _getSelectedItem(self) -> QTreeWidgetItem | None:
"""Get the currently selected item."""
selItem = self.listBox.selectedItems()
if len(selItem) > 0:
return selItem[0]
if items := self.listBox.selectedItems():
return items[0]
return None
def _usageString(self, nUse: int) -> str:
def _usageString(self, count: int) -> str:
"""Generate usage string."""
if nUse == 0:
if count == 0:
return self.tr("Not in use")
elif nUse == 1:
elif count == 1:
return self.tr("Used once")
else:
return self.tr("Used by {0} items").format(nUse)
return self.tr("Used by {0} items").format(count)
# END Class _StatusPage
class _ReplacePage(QWidget):
class _ReplacePage(NFixedPage):
COL_KEY = 0
COL_REPL = 1
@@ -588,7 +588,12 @@ class _ReplacePage(QWidget):
wCol0 = CONFIG.pxInt(
SHARED.project.options.getInt("GuiProjectSettings", "replaceColW", 130)
)
pageLabel = self.tr("Text Replace List for Preview and Export")
# Title
self.pageTitle = NColourLabel(
self.tr("Text Auto-Replace for Preview and Build"),
SHARED.theme.helpText, parent=self, scale=NColourLabel.HEADER_SCALE
)
# List Box
self.listBox = QTreeWidget()
@@ -644,11 +649,10 @@ class _ReplacePage(QWidget):
self.innerBox.addLayout(self.listControls)
self.outerBox = QVBoxLayout()
self.outerBox.addWidget(QLabel("<b>%s</b>" % pageLabel))
self.outerBox.addWidget(self.pageTitle)
self.outerBox.addLayout(self.innerBox)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.outerBox)
self.setCentralLayout(self.outerBox)
return
+72 -19
View File
@@ -6,6 +6,8 @@ File History:
Created: 2020-05-03 [0.4.5] NConfigLayout, NColourLabel
Created: 2023-05-23 [2.1b1] NSimpleLayout
Created: 2024-01-08 [2.3b1] NScrollableForm
Created: 2024-01-26 [2.3b1] NScrollablePage
Created: 2024-01-26 [2.3b1] NFixedPage
This file is a part of novelWriter
Copyright 20182024, Veronica Berglyd Olsen
@@ -28,17 +30,59 @@ from __future__ import annotations
from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QAbstractButton, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QScrollArea, QSizePolicy,
QVBoxLayout, QWidget
QAbstractButton, QFrame, QGridLayout, QHBoxLayout, QLabel, QLayout, QLineEdit,
QScrollArea, QSizePolicy, QVBoxLayout, QWidget
)
from novelwriter import CONFIG
FONT_SCALE = 0.9
DEFAULT_SCALE = 0.9
RIGHT_TOP = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
LEFT_TOP = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
class NFixedPage(QFrame):
"""Extension: Fixed Page Widget
A custom widget that holds a layout. This is just a wrapper around a
QFrame that sets the same frame style as the other Page widgets.
"""
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
self.setFrameShadow(QFrame.Shadow.Sunken)
self.setFrameShape(QFrame.Shape.StyledPanel)
self.setCentralLayout = self.setLayout
return
# END Class NFixedPage
class NScrollablePage(QScrollArea):
"""Extension: Scrollable Page Widget
A custom widget that holds a layout within a scrollable area.
"""
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
self._widget = QWidget(self)
self.setWidget(self._widget)
self.setWidgetResizable(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.setFrameShadow(QFrame.Shadow.Sunken)
self.setFrameShape(QFrame.Shape.StyledPanel)
return
def setCentralLayout(self, layout: QLayout) -> None:
"""Set the central layout of the scroll page."""
self._widget.setLayout(layout)
return
# END Class NScrollablePage
class NScrollableForm(QScrollArea):
"""Extension: Scrollable Form Widget
@@ -48,7 +92,7 @@ class NScrollableForm(QScrollArea):
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
self._helpCol = QColor(0, 0, 0)
self._fontScale = FONT_SCALE
self._fontScale = DEFAULT_SCALE
self._first = True
self._indent = CONFIG.pxInt(12)
@@ -66,6 +110,8 @@ class NScrollableForm(QScrollArea):
self.setWidgetResizable(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.setFrameShadow(QFrame.Shadow.Sunken)
self.setFrameShape(QFrame.Shape.StyledPanel)
return
@@ -81,7 +127,7 @@ class NScrollableForm(QScrollArea):
# Setters
##
def setHelpTextStyle(self, color: QColor, scale: float = FONT_SCALE) -> None:
def setHelpTextStyle(self, color: QColor, scale: float = DEFAULT_SCALE) -> None:
"""Set the text color for the help text."""
self._helpCol = color
self._fontScale = scale
@@ -145,13 +191,14 @@ class NScrollableForm(QScrollArea):
qLabel.setBuddy(widget)
if helpText:
qHelp = NColourLabel(str(helpText), self._helpCol, scale=self._fontScale, wrap=True)
qHelp.setIndent(self._indent)
qHelp = NColourLabel(
str(helpText), self._helpCol, parent=self,
scale=self._fontScale, wrap=True, indent=self._indent
)
labelBox = QVBoxLayout()
labelBox.addWidget(qLabel)
labelBox.addWidget(qHelp)
labelBox.setSpacing(0)
labelBox.addStretch(1)
row.addLayout(labelBox, stretch[0])
if editable:
self._editable[editable] = qHelp
@@ -193,7 +240,7 @@ class NConfigLayout(QGridLayout):
self._nextRow = 0
self._helpCol = QColor(0, 0, 0)
self._fontScale = FONT_SCALE
self._fontScale = DEFAULT_SCALE
self._itemMap = {}
wSp = CONFIG.pxInt(8)
@@ -207,7 +254,7 @@ class NConfigLayout(QGridLayout):
# Getters and Setters
##
def setHelpTextStyle(self, color: QColor, scale: float = FONT_SCALE) -> None:
def setHelpTextStyle(self, color: QColor, scale: float = DEFAULT_SCALE) -> None:
"""Set the text color for the help text."""
self._helpCol = color if isinstance(color, QColor) else QColor(*color)
self._fontScale = scale
@@ -238,8 +285,10 @@ class NConfigLayout(QGridLayout):
qHelp = None
if helpText is not None:
qHelp = NColourLabel(str(helpText), self._helpCol, scale=self._fontScale, wrap=True)
qHelp.setIndent(wSp)
qHelp = NColourLabel(
str(helpText), self._helpCol,
scale=self._fontScale, wrap=True, indent=wSp
)
labelBox = QVBoxLayout()
labelBox.addWidget(qLabel)
labelBox.addWidget(qHelp)
@@ -337,17 +386,21 @@ class NColourLabel(QLabel):
optionally at a specific size, and word wrapped.
"""
HELP_SCALE = DEFAULT_SCALE
HEADER_SCALE = 1.25
def __init__(self, text: str, color: QColor, parent: QWidget | None = None,
scale: float = FONT_SCALE, wrap: bool = False) -> None:
scale: float = HELP_SCALE, wrap: bool = False, indent: int = 0) -> None:
super().__init__(text, parent=parent)
lblCol = self.palette()
lblCol.setColor(QPalette.WindowText, color)
self.setPalette(lblCol)
font = self.font()
font.setPointSizeF(scale*font.pointSizeF())
colour = self.palette()
colour.setColor(QPalette.WindowText, color)
lblFont = self.font()
lblFont.setPointSizeF(scale*lblFont.pointSizeF())
self.setFont(lblFont)
self.setPalette(colour)
self.setFont(font)
self.setIndent(indent)
if wrap:
self.setWordWrap(True)
+27 -25
View File
@@ -38,14 +38,12 @@ 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
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollablePage
from novelwriter.extensions.pagedsidebar import NPagedSideBar
from novelwriter.extensions.novelselector import NovelSelector
logger = logging.getLogger(__name__)
HEADER_SIZE = 1.4
class GuiNovelDetails(QDialog):
@@ -59,21 +57,18 @@ class GuiNovelDetails(QDialog):
self.setObjectName("GuiNovelDetails")
self.setWindowTitle(self.tr("Novel Details"))
wW = CONFIG.pxInt(500)
wH = CONFIG.pxInt(400)
options = SHARED.project.options
self.setMinimumSize(wW, wH)
self.setMinimumSize(CONFIG.pxInt(500), CONFIG.pxInt(400))
self.resize(
CONFIG.pxInt(options.getInt("GuiNovelDetails", "winWidth", wW)),
CONFIG.pxInt(options.getInt("GuiNovelDetails", "winHeight", wH))
CONFIG.pxInt(options.getInt("GuiNovelDetails", "winWidth", CONFIG.pxInt(650))),
CONFIG.pxInt(options.getInt("GuiNovelDetails", "winHeight", CONFIG.pxInt(500)))
)
# Title
self.titleLabel = NColourLabel(
self.tr("Novel Details"), SHARED.theme.helpText, parent=self, scale=1.25
self.tr("Novel Details"), SHARED.theme.helpText,
parent=self, scale=NColourLabel.HEADER_SCALE, indent=CONFIG.pxInt(4)
)
self.titleLabel.setIndent(CONFIG.pxInt(4))
# Novel Selector
self.novelSelector = NovelSelector(self)
@@ -192,7 +187,7 @@ class GuiNovelDetails(QDialog):
# END Class GuiNovelDetails
class _OverviewPage(QWidget):
class _OverviewPage(NScrollablePage):
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
@@ -204,7 +199,8 @@ class _OverviewPage(QWidget):
# Project Info
self.projLabel = NColourLabel(
self.tr("Project"), SHARED.theme.helpText, parent=self, scale=HEADER_SIZE
self.tr("Project"), SHARED.theme.helpText,
parent=self, scale=NColourLabel.HEADER_SCALE
)
self.projName = QLabel("", self)
@@ -227,7 +223,8 @@ class _OverviewPage(QWidget):
# Novel Info
self.novelLabel = NColourLabel(
self.tr("Selected Novel"), SHARED.theme.helpText, parent=self, scale=HEADER_SIZE
self.tr("Selected Novel"), SHARED.theme.helpText,
parent=self, scale=NColourLabel.HEADER_SCALE
)
self.novelName = QLabel("", self)
@@ -250,11 +247,10 @@ class _OverviewPage(QWidget):
self.outerBox.addLayout(self.projForm)
self.outerBox.addWidget(self.novelLabel)
self.outerBox.addLayout(self.novelForm)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.outerBox.setSpacing(sPx)
self.outerBox.addStretch(1)
self.setLayout(self.outerBox)
self.setCentralLayout(self.outerBox)
return
@@ -299,7 +295,7 @@ class _OverviewPage(QWidget):
# END Class _OverviewPage
class _ContentsPage(QWidget):
class _ContentsPage(NFixedPage):
C_TITLE = 0
C_WORDS = 1
@@ -320,7 +316,8 @@ class _ContentsPage(QWidget):
# Title
self.contentLabel = NColourLabel(
self.tr("Table of Contents"), SHARED.theme.helpText, parent=self, scale=HEADER_SIZE
self.tr("Table of Contents"), SHARED.theme.helpText,
parent=self, scale=NColourLabel.HEADER_SCALE
)
# Contents Tree
@@ -407,20 +404,25 @@ class _ContentsPage(QWidget):
self.outerBox.addWidget(self.contentLabel)
self.outerBox.addWidget(self.tocTree)
self.outerBox.addLayout(self.optionsBox)
self.outerBox.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.outerBox)
self.setCentralLayout(self.outerBox)
return
def saveSettings(self) -> None:
"""Save the user GUI settings."""
widthCol0 = CONFIG.rpxInt(self.tocTree.columnWidth(0))
widthCol1 = CONFIG.rpxInt(self.tocTree.columnWidth(1))
widthCol2 = CONFIG.rpxInt(self.tocTree.columnWidth(2))
widthCol3 = CONFIG.rpxInt(self.tocTree.columnWidth(3))
widthCol4 = CONFIG.rpxInt(self.tocTree.columnWidth(4))
options = SHARED.project.options
options.setValue("GuiNovelDetails", "widthCol0", self.tocTree.columnWidth(0))
options.setValue("GuiNovelDetails", "widthCol1", self.tocTree.columnWidth(1))
options.setValue("GuiNovelDetails", "widthCol2", self.tocTree.columnWidth(2))
options.setValue("GuiNovelDetails", "widthCol3", self.tocTree.columnWidth(3))
options.setValue("GuiNovelDetails", "widthCol4", self.tocTree.columnWidth(4))
options.setValue("GuiNovelDetails", "widthCol0", widthCol0)
options.setValue("GuiNovelDetails", "widthCol1", widthCol1)
options.setValue("GuiNovelDetails", "widthCol2", widthCol2)
options.setValue("GuiNovelDetails", "widthCol3", widthCol3)
options.setValue("GuiNovelDetails", "widthCol4", widthCol4)
options.setValue("GuiNovelDetails", "wordsPerPage", self.wpValue.value())
options.setValue("GuiNovelDetails", "countFrom", self.poValue.value())
options.setValue("GuiNovelDetails", "clearDouble", self.dblValue.isChecked())