From 1cd7986bfb1dc7d01cb74ff440c19b6d21f1e4f3 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 31 May 2020 10:52:25 +0200 Subject: [PATCH] Using QFontDialog instead of QFontComboBox, and GUI font is no selectable --- nw/config.py | 7 ++- nw/gui/additions/qconfiglayout.py | 8 +++- nw/gui/dialogs/preferences.py | 71 ++++++++++++++++++++++++++----- nw/gui/theme.py | 54 ++++++++++++++--------- tests/reference/novelwriter.conf | 2 +- 5 files changed, 110 insertions(+), 32 deletions(-) diff --git a/nw/config.py b/nw/config.py index 07b58c7e..985eca43 100644 --- a/nw/config.py +++ b/nw/config.py @@ -86,7 +86,8 @@ class Config: self.guiIcons = "typicons_grey_light" self.guiDark = False self.guiLang = "en" # Hardcoded for now - self.guiFontSize = 12 + self.guiFont = "" + self.guiFontSize = 11 ## Sizes self.winGeometry = [1100, 650] @@ -317,6 +318,9 @@ class Config: self.guiDark = self._parseLine( cnfParse, cnfSec, "guidark", self.CNF_BOOL, self.guiDark ) + self.guiFont = self._parseLine( + cnfParse, cnfSec, "guifont", self.CNF_STR, self.guiFont + ) self.guiFontSize = self._parseLine( cnfParse, cnfSec, "guifontsize", self.CNF_INT, self.guiFontSize ) @@ -471,6 +475,7 @@ class Config: cnfParse.set(cnfSec,"syntax", str(self.guiSyntax)) cnfParse.set(cnfSec,"icons", str(self.guiIcons)) cnfParse.set(cnfSec,"guidark", str(self.guiDark)) + cnfParse.set(cnfSec,"guifont", str(self.guiFont)) cnfParse.set(cnfSec,"guifontsize", str(self.guiFontSize)) ## Sizes diff --git a/nw/gui/additions/qconfiglayout.py b/nw/gui/additions/qconfiglayout.py index be7571b5..70b3042d 100644 --- a/nw/gui/additions/qconfiglayout.py +++ b/nw/gui/additions/qconfiglayout.py @@ -107,7 +107,7 @@ class QConfigLayout(QGridLayout): return - def addRow(self, theLabel, theWidget, helpText=None, theUnit=None): + def addRow(self, theLabel, theWidget, helpText=None, theUnit=None, theButton=None): """Add a label and a widget as a new row of the grid. """ thisEntry = { @@ -152,6 +152,12 @@ class QConfigLayout(QGridLayout): controlBox.addWidget(QLabel(theUnit), 0, Qt.AlignVCenter) controlBox.setSpacing(8) self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter) + elif theButton is not None: + controlBox = QHBoxLayout() + controlBox.addWidget(qWidget, 0, Qt.AlignVCenter) + controlBox.addWidget(theButton, 0, Qt.AlignVCenter) + controlBox.setSpacing(8) + self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter) else: self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter) diff --git a/nw/gui/dialogs/preferences.py b/nw/gui/dialogs/preferences.py index e6e6ca4f..014ef3c9 100644 --- a/nw/gui/dialogs/preferences.py +++ b/nw/gui/dialogs/preferences.py @@ -33,9 +33,8 @@ from os import path from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont from PyQt5.QtWidgets import ( - QDialog, QWidget, QHBoxLayout, QVBoxLayout, QTabWidget, QComboBox, QSpinBox, - QPushButton, QFontComboBox, QLineEdit, QDialogButtonBox, QMessageBox, - QFileDialog + QDialog, QWidget, QComboBox, QSpinBox, QPushButton, QLineEdit, QMessageBox, + QDialogButtonBox, QFileDialog, QFontDialog ) from nw.gui.additions import QSwitch, QConfigLayout, PagedDialog @@ -183,6 +182,21 @@ class GuiConfigEditGeneralTab(QWidget): "This may improve the look of icons on dark themes." ) + ## Font Family + self.guiFont = QLineEdit() + self.guiFont.setReadOnly(True) + self.guiFont.setFixedWidth(162) + self.guiFont.setText(self.mainConf.guiFont) + self.fontButton = QPushButton("...") + self.fontButton.setMaximumWidth(30) + self.fontButton.clicked.connect(self._selectFont) + self.mainForm.addRow( + "Font family", + self.guiFont, + "Changing this requires restarting %s." % nw.__package__, + theButton = self.fontButton + ) + ## Font Size self.guiFontSize = QSpinBox(self) self.guiFontSize.setMinimum(8) @@ -193,7 +207,7 @@ class GuiConfigEditGeneralTab(QWidget): "Font size", self.guiFontSize, "Changing this requires restarting %s." % nw.__package__, - theUnit="pt" + theUnit = "pt" ) # GUI Settings @@ -279,6 +293,7 @@ class GuiConfigEditGeneralTab(QWidget): guiTheme = self.selectTheme.currentData() guiIcons = self.selectIcons.currentData() guiDark = self.preferDarkIcons.isChecked() + guiFont = self.guiFont.text() guiFontSize = self.guiFontSize.value() showFullPath = self.showFullPath.isChecked() autoSaveDoc = self.autoSaveDoc.value() @@ -290,11 +305,13 @@ class GuiConfigEditGeneralTab(QWidget): # Check if restart is needed needsRestart |= self.mainConf.guiTheme != guiTheme needsRestart |= self.mainConf.guiIcons != guiIcons + needsRestart |= self.mainConf.guiFont != guiFont needsRestart |= self.mainConf.guiFontSize != guiFontSize self.mainConf.guiTheme = guiTheme self.mainConf.guiIcons = guiIcons self.mainConf.guiDark = guiDark + self.mainConf.guiFont = guiFont self.mainConf.guiFontSize = guiFontSize self.mainConf.showFullPath = showFullPath self.mainConf.autoSaveDoc = autoSaveDoc @@ -337,6 +354,18 @@ class GuiConfigEditGeneralTab(QWidget): self.askBeforeBackup.setEnabled(theState) return + def _selectFont(self): + """Open the QFontDialog and set a font for the font style. + """ + currFont = QFont() + currFont.setFamily(self.mainConf.guiFont) + currFont.setPointSize(self.mainConf.guiFontSize) + theFont, theStatus = QFontDialog.getFont(currFont, self) + if theStatus: + self.guiFont.setText(theFont.family()) + self.guiFontSize.setValue(theFont.pointSize()) + return + # END Class GuiConfigEditGeneralTab class GuiConfigEditLayoutTab(QWidget): @@ -357,14 +386,20 @@ class GuiConfigEditLayoutTab(QWidget): # ========== self.mainForm.addGroupLabel("Text Style") + ## Font Family - self.textStyleFont = QFontComboBox() - self.textStyleFont.setMaximumWidth(200) - self.textStyleFont.setCurrentFont(QFont(self.mainConf.textFont)) + self.textStyleFont = QLineEdit() + self.textStyleFont.setReadOnly(True) + self.textStyleFont.setFixedWidth(162) + self.textStyleFont.setText(self.mainConf.textFont) + self.fontButton = QPushButton("...") + self.fontButton.setMaximumWidth(30) + self.fontButton.clicked.connect(self._selectFont) self.mainForm.addRow( "Font family", self.textStyleFont, - "Font for the document editor and viewer." + "Font for the document editor and viewer.", + theButton = self.fontButton ) ## Font Size @@ -376,7 +411,7 @@ class GuiConfigEditLayoutTab(QWidget): self.mainForm.addRow( "Font size", self.textStyleSize, - theUnit="pt" + theUnit = "pt" ) # Text Flow @@ -477,7 +512,7 @@ class GuiConfigEditLayoutTab(QWidget): validEntries = True needsRestart = False - textFont = self.textStyleFont.currentFont().family() + textFont = self.textStyleFont.text() textSize = self.textStyleSize.value() textWidth = self.textFlowMax.value() zenWidth = self.zenDocWidth.value() @@ -503,6 +538,22 @@ class GuiConfigEditLayoutTab(QWidget): return validEntries, needsRestart + ## + # Slots + ## + + def _selectFont(self): + """Open the QFontDialog and set a font for the font style. + """ + currFont = QFont() + currFont.setFamily(self.mainConf.guiFont) + currFont.setPointSize(self.mainConf.guiFontSize) + theFont, theStatus = QFontDialog.getFont(currFont, self) + if theStatus: + self.textStyleFont.setText(theFont.family()) + self.textStyleSize.setValue(theFont.pointSize()) + return + # END Class GuiConfigEditLayoutTab class GuiConfigEditEditingTab(QWidget): diff --git a/nw/gui/theme.py b/nw/gui/theme.py index 95afd16e..2d4bff15 100644 --- a/nw/gui/theme.py +++ b/nw/gui/theme.py @@ -33,7 +33,7 @@ from os import path, listdir from PyQt5.QtWidgets import qApp from PyQt5.QtGui import ( - QPalette, QColor, QIcon, QFontMetrics, QFontDatabase + QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase ) from nw.constants import nwAlert @@ -50,7 +50,7 @@ class GuiTheme: self.theIcons = GuiIcons(self.theParent) self.guiPalette = QPalette() self.guiPath = "gui" - self.iconPath = "icons" + self.fontPath = "fonts" self.syntaxPath = "syntax" self.cssName = "style.qss" self.confName = "theme.conf" @@ -112,14 +112,10 @@ class GuiTheme: self.syntaxFile = None self.confFile = None self.cssFile = None + self.guiFontDB = QFontDatabase() self.loadFonts() - - # Set Font Size and Theme - self.guiFont = qApp.font() - self.guiFont.setPointSizeF(self.mainConf.guiFontSize) - qApp.setFont(self.guiFont) - + self.updateFont() self.updateTheme() self.theIcons.updateTheme() @@ -129,6 +125,7 @@ class GuiTheme: # Extract Other Info self.guiDPI = qApp.primaryScreen().physicalDotsPerInch() + self.guiFont = qApp.font() qMetric = QFontMetrics(self.guiFont) self.fontPointSize = self.guiFont.pointSizeF() @@ -152,29 +149,48 @@ class GuiTheme: """Add the fonts in the assets fonts folder to the app. """ ttfList = [] - fontAssets = path.join(self.mainConf.assetPath, "fonts") + fontAssets = path.join(self.mainConf.assetPath, self.fontPath) for fontFam in listdir(fontAssets): fontDir = path.join(fontAssets, fontFam) if path.isdir(fontDir): - for fontFile in listdir(fontDir): - ttfFile = path.join(fontDir, fontFile) - if path.isfile(ttfFile) and fontFile.endswith(".ttf"): - ttfList.append(ttfFile) - + if not fontFam in self.guiFontDB.families(): + for fontFile in listdir(fontDir): + ttfFile = path.join(fontDir, fontFile) + if path.isfile(ttfFile) and fontFile.endswith(".ttf"): + ttfList.append(ttfFile) + for ttfFile in ttfList: logger.verbose("Font asset: %s" % path.relpath(ttfFile)) - try: - QFontDatabase.addApplicationFont(ttfFile) - except Exception as e: + fontID = self.guiFontDB.addApplicationFont(ttfFile) + if fontID < 0: logger.error("Failed to add font: %s" % path.relpath(ttfFile)) - logger.error(str(e)) + + return + + def updateFont(self): + """Updated the GUI's font style from settings, + """ + theFont = QFont() + if self.mainConf.guiFont not in self.guiFontDB.families(): + if self.mainConf.osWindows: + # On Windows, default to Cantarell provided by novelWriter + theFont.setFamily("Cantarell") + theFont.setPointSize(11) + else: + theFont = self.guiFontDB.systemFont(QFontDatabase.GeneralFont) + self.mainConf.guiFont = theFont.family() + self.mainConf.guiFontSize = theFont.pointSize() + else: + theFont.setFamily(self.mainConf.guiFont) + theFont.setPointSize(self.mainConf.guiFontSize) + + qApp.setFont(theFont) return def updateTheme(self): """Update the GUI theme from theme files. """ - self.guiTheme = self.mainConf.guiTheme self.guiSyntax = self.mainConf.guiSyntax self.themeRoot = self.mainConf.themeRoot diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf index 5f4768e6..6c8f7a75 100644 --- a/tests/reference/novelwriter.conf +++ b/tests/reference/novelwriter.conf @@ -4,7 +4,7 @@ theme = default syntax = default_light icons = typicons_grey_light guidark = False -guifontsize = 12 +guifontsize = 11 [Sizes] geometry = 1100, 650