Save all font info for GUI font
This commit is contained in:
@@ -217,6 +217,7 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
# Import GUI (after dependency checks), and launch
|
# Import GUI (after dependency checks), and launch
|
||||||
from novelwriter.guimain import GuiMain
|
from novelwriter.guimain import GuiMain
|
||||||
if testMode:
|
if testMode:
|
||||||
|
CONFIG.loadConfig()
|
||||||
nwGUI = GuiMain()
|
nwGUI = GuiMain()
|
||||||
return nwGUI
|
return nwGUI
|
||||||
|
|
||||||
@@ -232,6 +233,7 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
sys.excepthook = exceptionHandler
|
sys.excepthook = exceptionHandler
|
||||||
|
|
||||||
# Run Config steps that require the QApplication
|
# Run Config steps that require the QApplication
|
||||||
|
CONFIG.loadConfig()
|
||||||
CONFIG.initLocalisation(nwApp)
|
CONFIG.initLocalisation(nwApp)
|
||||||
CONFIG.setTextFont(CONFIG.textFont, CONFIG.textSize) # Makes sure these are valid
|
CONFIG.setTextFont(CONFIG.textFont, CONFIG.textSize) # Makes sure these are valid
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ from urllib.parse import urljoin
|
|||||||
from urllib.request import pathname2url
|
from urllib.request import pathname2url
|
||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication, QUrl
|
from PyQt5.QtCore import QCoreApplication, QUrl
|
||||||
from PyQt5.QtGui import QColor, QDesktopServices
|
from PyQt5.QtGui import QColor, QDesktopServices, QFont, QFontInfo
|
||||||
|
|
||||||
from novelwriter.constants import nwConst, nwLabels, nwUnicode, trConst
|
from novelwriter.constants import nwConst, nwLabels, nwUnicode, trConst
|
||||||
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
|
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
|
||||||
@@ -401,6 +401,14 @@ def cssCol(col: QColor, alpha: int | None = None) -> str:
|
|||||||
return f"rgba({col.red()}, {col.green()}, {col.blue()}, {alpha or col.alpha()})"
|
return f"rgba({col.red()}, {col.green()}, {col.blue()}, {alpha or col.alpha()})"
|
||||||
|
|
||||||
|
|
||||||
|
def describeFont(font: QFont) -> str:
|
||||||
|
"""Describe a font in a way that can be displayed on the GUI."""
|
||||||
|
if isinstance(font, QFont):
|
||||||
|
info = QFontInfo(font)
|
||||||
|
return f"{font.family()} {info.styleName()} @ {font.pointSize()} pt"
|
||||||
|
return "Error"
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Encoder Functions
|
# Encoder Functions
|
||||||
##
|
##
|
||||||
|
|||||||
+56
-27
@@ -36,7 +36,7 @@ from PyQt5.QtCore import (
|
|||||||
PYQT_VERSION, PYQT_VERSION_STR, QT_VERSION, QT_VERSION_STR, QLibraryInfo,
|
PYQT_VERSION, PYQT_VERSION_STR, QT_VERSION, QT_VERSION_STR, QLibraryInfo,
|
||||||
QLocale, QStandardPaths, QSysInfo, QTranslator
|
QLocale, QStandardPaths, QSysInfo, QTranslator
|
||||||
)
|
)
|
||||||
from PyQt5.QtGui import QFontDatabase
|
from PyQt5.QtGui import QFont, QFontDatabase
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
from novelwriter.common import NWConfigParser, checkInt, checkPath, formatTimeStamp
|
from novelwriter.common import NWConfigParser, checkInt, checkPath, formatTimeStamp
|
||||||
@@ -106,15 +106,14 @@ class Config:
|
|||||||
self._recentObj = RecentProjects(self)
|
self._recentObj = RecentProjects(self)
|
||||||
|
|
||||||
# General GUI Settings
|
# General GUI Settings
|
||||||
self.guiLocale = self._qLocale.name()
|
self.guiLocale = self._qLocale.name()
|
||||||
self.guiTheme = "default" # GUI theme
|
self.guiTheme = "default" # GUI theme
|
||||||
self.guiSyntax = "default_light" # Syntax theme
|
self.guiSyntax = "default_light" # Syntax theme
|
||||||
self.guiFont = "" # Defaults to system default font in theme class
|
self.guiFont = QFont() # Defaults to system default font in theme class
|
||||||
self.guiFontSize = 11 # Is overridden if system default is loaded
|
self.guiScale = 1.0 # Set automatically by Theme class
|
||||||
self.guiScale = 1.0 # Set automatically by Theme class
|
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
||||||
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
||||||
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
self.lastNotes = "0x0" # The latest release notes that have been shown
|
||||||
self.lastNotes = "0x0" # The latest release notes that have been shown
|
|
||||||
|
|
||||||
# Size Settings
|
# Size Settings
|
||||||
self._mainWinSize = [1200, 650] # Last size of the main GUI window
|
self._mainWinSize = [1200, 650] # Last size of the main GUI window
|
||||||
@@ -362,6 +361,28 @@ class Config:
|
|||||||
self._backupPath = checkPath(path, self._backPath)
|
self._backupPath = checkPath(path, self._backPath)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def setGuiFont(self, value: QFont | str | None) -> None:
|
||||||
|
"""Update the GUI's font style from settings."""
|
||||||
|
if isinstance(value, QFont):
|
||||||
|
self.guiFont = value
|
||||||
|
elif value and isinstance(value, str):
|
||||||
|
self.guiFont = QFont()
|
||||||
|
self.guiFont.fromString(value)
|
||||||
|
else:
|
||||||
|
font = QFont()
|
||||||
|
fontDB = QFontDatabase()
|
||||||
|
if self.osWindows and "Arial" in fontDB.families():
|
||||||
|
# On Windows we default to Arial if possible
|
||||||
|
font.setFamily("Arial")
|
||||||
|
font.setPointSize(10)
|
||||||
|
else:
|
||||||
|
font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
|
||||||
|
self.guiFont = font
|
||||||
|
|
||||||
|
QApplication.setFont(self.guiFont)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def setTextFont(self, family: str | None, pointSize: int = 12) -> None:
|
def setTextFont(self, family: str | None, pointSize: int = 12) -> None:
|
||||||
"""Set the text font if it exists. If it doesn't, or is None,
|
"""Set the text font if it exists. If it doesn't, or is None,
|
||||||
set to default font.
|
set to default font.
|
||||||
@@ -502,12 +523,6 @@ class Config:
|
|||||||
(self._dataPath / "syntax").mkdir(exist_ok=True)
|
(self._dataPath / "syntax").mkdir(exist_ok=True)
|
||||||
(self._dataPath / "themes").mkdir(exist_ok=True)
|
(self._dataPath / "themes").mkdir(exist_ok=True)
|
||||||
|
|
||||||
# Check if config file exists, and load it. If not, we save defaults
|
|
||||||
if (self._confPath / nwFiles.CONF_FILE).is_file():
|
|
||||||
self.loadConfig()
|
|
||||||
else:
|
|
||||||
self.saveConfig()
|
|
||||||
|
|
||||||
self._recentObj.loadCache()
|
self._recentObj.loadCache()
|
||||||
self._checkOptionalPackages()
|
self._checkOptionalPackages()
|
||||||
|
|
||||||
@@ -548,6 +563,13 @@ class Config:
|
|||||||
|
|
||||||
conf = NWConfigParser()
|
conf = NWConfigParser()
|
||||||
cnfPath = self._confPath / nwFiles.CONF_FILE
|
cnfPath = self._confPath / nwFiles.CONF_FILE
|
||||||
|
|
||||||
|
if not cnfPath.exists():
|
||||||
|
# Initial file, so we just create one from defaults
|
||||||
|
self.saveConfig()
|
||||||
|
self.setGuiFont(None)
|
||||||
|
return True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(cnfPath, mode="r", encoding="utf-8") as inFile:
|
with open(cnfPath, mode="r", encoding="utf-8") as inFile:
|
||||||
conf.read_file(inFile)
|
conf.read_file(inFile)
|
||||||
@@ -561,15 +583,23 @@ class Config:
|
|||||||
|
|
||||||
# Main
|
# Main
|
||||||
sec = "Main"
|
sec = "Main"
|
||||||
self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
|
self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
|
||||||
self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
|
self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
|
||||||
self.guiFont = conf.rdStr(sec, "font", self.guiFont)
|
guiFont = conf.rdStr(sec, "guifont", "")
|
||||||
self.guiFontSize = conf.rdInt(sec, "fontsize", self.guiFontSize)
|
self.guiLocale = conf.rdStr(sec, "localisation", self.guiLocale)
|
||||||
self.guiLocale = conf.rdStr(sec, "localisation", self.guiLocale)
|
self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
|
||||||
self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
|
self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
|
||||||
self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
|
self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
|
||||||
self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
|
self._lastPath = conf.rdPath(sec, "lastpath", self._lastPath)
|
||||||
self._lastPath = conf.rdPath(sec, "lastpath", self._lastPath)
|
|
||||||
|
# If we have an old config file with the following settings, use those instead
|
||||||
|
legacyFont = conf.rdStr(sec, "font", "")
|
||||||
|
legacySize = conf.rdInt(sec, "fontsize", 11)
|
||||||
|
if legacyFont:
|
||||||
|
guiFont = QFont()
|
||||||
|
guiFont.fromString(f"{legacyFont},{legacySize}")
|
||||||
|
|
||||||
|
self.setGuiFont(guiFont)
|
||||||
|
|
||||||
# Sizes
|
# Sizes
|
||||||
sec = "Sizes"
|
sec = "Sizes"
|
||||||
@@ -674,8 +704,7 @@ class Config:
|
|||||||
conf["Main"] = {
|
conf["Main"] = {
|
||||||
"theme": str(self.guiTheme),
|
"theme": str(self.guiTheme),
|
||||||
"syntax": str(self.guiSyntax),
|
"syntax": str(self.guiSyntax),
|
||||||
"font": str(self.guiFont),
|
"guifont": str(self.guiFont.toString()),
|
||||||
"fontsize": str(self.guiFontSize),
|
|
||||||
"localisation": str(self.guiLocale),
|
"localisation": str(self.guiLocale),
|
||||||
"hidevscroll": str(self.hideVScroll),
|
"hidevscroll": str(self.hideVScroll),
|
||||||
"hidehscroll": str(self.hideHScroll),
|
"hidehscroll": str(self.hideHScroll),
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ from PyQt5.QtWidgets import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from novelwriter import CONFIG, SHARED
|
from novelwriter import CONFIG, SHARED
|
||||||
|
from novelwriter.common import describeFont
|
||||||
from novelwriter.constants import nwConst, nwUnicode
|
from novelwriter.constants import nwConst, nwUnicode
|
||||||
from novelwriter.dialogs.quotes import GuiQuoteSelect
|
from novelwriter.dialogs.quotes import GuiQuoteSelect
|
||||||
from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
|
from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
|
||||||
@@ -135,6 +136,10 @@ class GuiPreferences(QDialog):
|
|||||||
iSz = SHARED.theme.baseIconSize
|
iSz = SHARED.theme.baseIconSize
|
||||||
boxFixed = 5*SHARED.theme.textNWidth
|
boxFixed = 5*SHARED.theme.textNWidth
|
||||||
minWidth = CONFIG.pxInt(200)
|
minWidth = CONFIG.pxInt(200)
|
||||||
|
fontWidth = CONFIG.pxInt(162)
|
||||||
|
|
||||||
|
# Temporary Variables
|
||||||
|
self._guiFont = CONFIG.guiFont
|
||||||
|
|
||||||
# Label
|
# Label
|
||||||
self.sidebar.addLabel(self.tr("General"))
|
self.sidebar.addLabel(self.tr("General"))
|
||||||
@@ -174,27 +179,17 @@ class GuiPreferences(QDialog):
|
|||||||
# Application Font Family
|
# Application Font Family
|
||||||
self.guiFont = QLineEdit(self)
|
self.guiFont = QLineEdit(self)
|
||||||
self.guiFont.setReadOnly(True)
|
self.guiFont.setReadOnly(True)
|
||||||
self.guiFont.setMinimumWidth(CONFIG.pxInt(162))
|
self.guiFont.setMinimumWidth(fontWidth)
|
||||||
self.guiFont.setText(CONFIG.guiFont)
|
self.guiFont.setText(describeFont(self._guiFont))
|
||||||
|
self.guiFont.setCursorPosition(0)
|
||||||
self.guiFontButton = NIconToolButton(self, iSz, "more")
|
self.guiFontButton = NIconToolButton(self, iSz, "more")
|
||||||
self.guiFontButton.clicked.connect(self._selectGuiFont)
|
self.guiFontButton.clicked.connect(self._selectGuiFont)
|
||||||
self.mainForm.addRow(
|
self.mainForm.addRow(
|
||||||
self.tr("Application font family"), self.guiFont,
|
self.tr("Application font"), self.guiFont,
|
||||||
self.tr("Requires restart to take effect."), stretch=(3, 2),
|
self.tr("Requires restart to take effect."), stretch=(3, 2),
|
||||||
button=self.guiFontButton
|
button=self.guiFontButton
|
||||||
)
|
)
|
||||||
|
|
||||||
# Application Font Size
|
|
||||||
self.guiFontSize = NSpinBox(self)
|
|
||||||
self.guiFontSize.setMinimum(8)
|
|
||||||
self.guiFontSize.setMaximum(60)
|
|
||||||
self.guiFontSize.setSingleStep(1)
|
|
||||||
self.guiFontSize.setValue(CONFIG.guiFontSize)
|
|
||||||
self.mainForm.addRow(
|
|
||||||
self.tr("Application font size"), self.guiFontSize,
|
|
||||||
self.tr("Requires restart to take effect."), unit=self.tr("pt")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Vertical Scrollbars
|
# Vertical Scrollbars
|
||||||
self.hideVScroll = NSwitch(self)
|
self.hideVScroll = NSwitch(self)
|
||||||
self.hideVScroll.setChecked(CONFIG.hideVScroll)
|
self.hideVScroll.setChecked(CONFIG.hideVScroll)
|
||||||
@@ -234,7 +229,7 @@ class GuiPreferences(QDialog):
|
|||||||
# Document Font Family
|
# Document Font Family
|
||||||
self.textFont = QLineEdit(self)
|
self.textFont = QLineEdit(self)
|
||||||
self.textFont.setReadOnly(True)
|
self.textFont.setReadOnly(True)
|
||||||
self.textFont.setMinimumWidth(CONFIG.pxInt(162))
|
self.textFont.setMinimumWidth(fontWidth)
|
||||||
self.textFont.setText(CONFIG.textFont)
|
self.textFont.setText(CONFIG.textFont)
|
||||||
self.textFontButton = NIconToolButton(self, iSz, "more")
|
self.textFontButton = NIconToolButton(self, iSz, "more")
|
||||||
self.textFontButton.clicked.connect(self._selectTextFont)
|
self.textFontButton.clicked.connect(self._selectTextFont)
|
||||||
@@ -818,13 +813,11 @@ class GuiPreferences(QDialog):
|
|||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def _selectGuiFont(self) -> None:
|
def _selectGuiFont(self) -> None:
|
||||||
"""Open the QFontDialog and set a font for the font style."""
|
"""Open the QFontDialog and set a font for the font style."""
|
||||||
current = QFont()
|
font, status = QFontDialog.getFont(self._guiFont, self)
|
||||||
current.setFamily(CONFIG.guiFont)
|
|
||||||
current.setPointSize(CONFIG.guiFontSize)
|
|
||||||
font, status = QFontDialog.getFont(current, self)
|
|
||||||
if status:
|
if status:
|
||||||
self.guiFont.setText(font.family())
|
self.guiFont.setText(describeFont(font))
|
||||||
self.guiFontSize.setValue(font.pointSize())
|
self.guiFont.setCursorPosition(0)
|
||||||
|
self._guiFont = font
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
@@ -892,18 +885,14 @@ class GuiPreferences(QDialog):
|
|||||||
# Appearance
|
# Appearance
|
||||||
guiLocale = self.guiLocale.currentData()
|
guiLocale = self.guiLocale.currentData()
|
||||||
guiTheme = self.guiTheme.currentData()
|
guiTheme = self.guiTheme.currentData()
|
||||||
guiFont = self.guiFont.text()
|
|
||||||
guiFontSize = self.guiFontSize.value()
|
|
||||||
|
|
||||||
updateTheme |= CONFIG.guiTheme != guiTheme
|
updateTheme |= CONFIG.guiTheme != guiTheme
|
||||||
needsRestart |= CONFIG.guiLocale != guiLocale
|
needsRestart |= CONFIG.guiLocale != guiLocale
|
||||||
needsRestart |= CONFIG.guiFont != guiFont
|
needsRestart |= CONFIG.guiFont != self._guiFont
|
||||||
needsRestart |= CONFIG.guiFontSize != guiFontSize
|
|
||||||
|
|
||||||
CONFIG.guiLocale = guiLocale
|
CONFIG.guiLocale = guiLocale
|
||||||
CONFIG.guiTheme = guiTheme
|
CONFIG.guiTheme = guiTheme
|
||||||
CONFIG.guiFont = guiFont
|
CONFIG.guiFont = self._guiFont
|
||||||
CONFIG.guiFontSize = guiFontSize
|
|
||||||
CONFIG.hideVScroll = self.hideVScroll.isChecked()
|
CONFIG.hideVScroll = self.hideVScroll.isChecked()
|
||||||
CONFIG.hideHScroll = self.hideHScroll.isChecked()
|
CONFIG.hideHScroll = self.hideHScroll.isChecked()
|
||||||
|
|
||||||
|
|||||||
@@ -114,9 +114,6 @@ class GuiTheme:
|
|||||||
# Class Setup
|
# Class Setup
|
||||||
# ===========
|
# ===========
|
||||||
|
|
||||||
# Init GUI Font
|
|
||||||
self._setGuiFont()
|
|
||||||
|
|
||||||
# Load Themes
|
# Load Themes
|
||||||
self._guiPalette = QPalette()
|
self._guiPalette = QPalette()
|
||||||
self._themeList: list[tuple[str, str]] = []
|
self._themeList: list[tuple[str, str]] = []
|
||||||
@@ -411,27 +408,6 @@ class GuiTheme:
|
|||||||
self.errorText = QColor(255, 0, 0)
|
self.errorText = QColor(255, 0, 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _setGuiFont(self) -> None:
|
|
||||||
"""Update the GUI's font style from settings."""
|
|
||||||
font = QFont()
|
|
||||||
fontDB = QFontDatabase()
|
|
||||||
if CONFIG.guiFont not in fontDB.families():
|
|
||||||
if CONFIG.osWindows and "Arial" in fontDB.families():
|
|
||||||
# On Windows we default to Arial if possible
|
|
||||||
font.setFamily("Arial")
|
|
||||||
font.setPointSize(10)
|
|
||||||
else:
|
|
||||||
font = fontDB.systemFont(QFontDatabase.SystemFont.GeneralFont)
|
|
||||||
CONFIG.guiFont = font.family()
|
|
||||||
CONFIG.guiFontSize = font.pointSize()
|
|
||||||
else:
|
|
||||||
font.setFamily(CONFIG.guiFont)
|
|
||||||
font.setPointSize(CONFIG.guiFontSize)
|
|
||||||
|
|
||||||
QApplication.setFont(font)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _listConf(self, targetDict: dict, checkDir: Path) -> bool:
|
def _listConf(self, targetDict: dict, checkDir: Path) -> bool:
|
||||||
"""Scan for theme config files and populate the dictionary."""
|
"""Scan for theme config files and populate the dictionary."""
|
||||||
if not checkDir.is_dir():
|
if not checkDir.is_dir():
|
||||||
|
|||||||
Reference in New Issue
Block a user