Fix how document font is set (#1877)

This commit is contained in:
Veronica Berglyd Olsen
2024-05-20 12:16:41 +02:00
committed by GitHub
4 changed files with 100 additions and 55 deletions
+52 -25
View File
@@ -43,8 +43,8 @@ from PyQt5.QtCore import (
pyqtSignal, pyqtSlot pyqtSignal, pyqtSlot
) )
from PyQt5.QtGui import ( from PyQt5.QtGui import (
QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette, QColor, QCursor, QKeyEvent, QKeySequence, QMouseEvent, QPalette, QPixmap,
QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAction, QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QAction, QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit,
@@ -329,10 +329,7 @@ class GuiDocEditor(QPlainTextEdit):
SHARED.updateSpellCheckLanguage() SHARED.updateSpellCheckLanguage()
# Set font # Set font
font = QFont() self.initFont()
font.setFamily(CONFIG.textFont)
font.setPointSize(CONFIG.textSize)
self._qDocument.setDefaultFont(font)
# Update highlighter settings # Update highlighter settings
self._qDocument.syntaxHighlighter.initHighlighter() self._qDocument.syntaxHighlighter.initHighlighter()
@@ -382,6 +379,23 @@ class GuiDocEditor(QPlainTextEdit):
return return
def initFont(self) -> None:
"""Set the font of the main widget and sub-widgets. This needs
special attention since there appears to be a bug in Qt 5.15.3.
See issues #1862 and #1875.
"""
font = self.font()
font.setFamily(CONFIG.textFont)
font.setPointSize(CONFIG.textSize)
self.setFont(font)
# Reset sub-widget font to GUI font
self.docHeader.updateFont()
self.docFooter.updateFont()
self.docSearch.updateFont()
return
def loadText(self, tHandle: str, tLine: int | None = None) -> bool: def loadText(self, tHandle: str, tLine: int | None = None) -> bool:
"""Load text from a document into the editor. If we have an I/O """Load text from a document into the editor. If we have an I/O
error, we must handle this and clear the editor so that we don't error, we must handle this and clear the editor so that we don't
@@ -2396,9 +2410,6 @@ class GuiDocEditSearch(QFrame):
iSz = SHARED.theme.baseIconSize iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(6) mPx = CONFIG.pxInt(6)
self.boxFont = SHARED.theme.guiFont
self.boxFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True) self.setAutoFillBackground(True)
self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain) self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
@@ -2410,12 +2421,10 @@ class GuiDocEditSearch(QFrame):
# ========== # ==========
self.searchBox = QLineEdit(self) self.searchBox = QLineEdit(self)
self.searchBox.setFont(self.boxFont)
self.searchBox.setPlaceholderText(self.tr("Search for")) self.searchBox.setPlaceholderText(self.tr("Search for"))
self.searchBox.returnPressed.connect(self._doSearch) self.searchBox.returnPressed.connect(self._doSearch)
self.replaceBox = QLineEdit(self) self.replaceBox = QLineEdit(self)
self.replaceBox.setFont(self.boxFont)
self.replaceBox.setPlaceholderText(self.tr("Replace with")) self.replaceBox.setPlaceholderText(self.tr("Replace with"))
self.replaceBox.returnPressed.connect(self._doReplace) self.replaceBox.returnPressed.connect(self._doReplace)
@@ -2425,12 +2434,9 @@ class GuiDocEditSearch(QFrame):
self.searchOpt.setContentsMargins(0, 0, 0, 0) self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.searchLabel = QLabel(self.tr("Search"), self) self.searchLabel = QLabel(self.tr("Search"), self)
self.searchLabel.setFont(self.boxFont)
self.searchLabel.setIndent(CONFIG.pxInt(6)) self.searchLabel.setIndent(CONFIG.pxInt(6))
self.resultLabel = QLabel("?/?", self) self.resultLabel = QLabel("?/?", self)
self.resultLabel.setFont(self.boxFont)
self.resultLabel.setMinimumWidth(SHARED.theme.getTextWidth("?/?", self.boxFont))
self.toggleCase = QAction(self.tr("Case Sensitive"), self) self.toggleCase = QAction(self.tr("Case Sensitive"), self)
self.toggleCase.setCheckable(True) self.toggleCase.setCheckable(True)
@@ -2515,6 +2521,7 @@ class GuiDocEditSearch(QFrame):
self.replaceButton.setVisible(False) self.replaceButton.setVisible(False)
self.adjustSize() self.adjustSize()
self.updateFont()
self.updateTheme() self.updateTheme()
logger.debug("Ready: GuiDocEditSearch") logger.debug("Ready: GuiDocEditSearch")
@@ -2598,7 +2605,9 @@ class GuiDocEditSearch(QFrame):
numCount = f"{lim:n}+" if (resCount or 0) > lim else f"{resCount:n}" numCount = f"{lim:n}+" if (resCount or 0) > lim else f"{resCount:n}"
sCurrRes = "?" if currRes is None else str(currRes) sCurrRes = "?" if currRes is None else str(currRes)
sResCount = "?" if resCount is None else numCount sResCount = "?" if resCount is None else numCount
minWidth = SHARED.theme.getTextWidth(f"{sResCount}//{sResCount}", self.boxFont) minWidth = SHARED.theme.getTextWidth(
f"{sResCount}//{sResCount}", SHARED.theme.guiFontSmall
)
self.resultLabel.setText(f"{sCurrRes}/{sResCount}") self.resultLabel.setText(f"{sCurrRes}/{sResCount}")
self.resultLabel.setMinimumWidth(minWidth) self.resultLabel.setMinimumWidth(minWidth)
self.adjustSize() self.adjustSize()
@@ -2609,6 +2618,18 @@ class GuiDocEditSearch(QFrame):
# Methods # Methods
## ##
def updateFont(self) -> None:
"""Update the font settings."""
self.setFont(SHARED.theme.guiFont)
self.searchBox.setFont(SHARED.theme.guiFontSmall)
self.replaceBox.setFont(SHARED.theme.guiFontSmall)
self.searchLabel.setFont(SHARED.theme.guiFontSmall)
self.resultLabel.setFont(SHARED.theme.guiFontSmall)
self.resultLabel.setMinimumWidth(
SHARED.theme.getTextWidth("?/?", SHARED.theme.guiFontSmall)
)
return
def updateTheme(self) -> None: def updateTheme(self) -> None:
"""Update theme elements.""" """Update theme elements."""
qPalette = QApplication.palette() qPalette = QApplication.palette()
@@ -2793,10 +2814,6 @@ class GuiDocEditHeader(QWidget):
self.itemTitle.setAlignment(QtAlignCenterTop) self.itemTitle.setAlignment(QtAlignCenterTop)
self.itemTitle.setFixedHeight(iPx) self.itemTitle.setFixedHeight(iPx)
lblFont = self.itemTitle.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.itemTitle.setFont(lblFont)
# Other Widgets # Other Widgets
self.outlineMenu = QMenu(self) self.outlineMenu = QMenu(self)
@@ -2850,6 +2867,7 @@ class GuiDocEditHeader(QWidget):
self.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0)
self.setMinimumHeight(iPx + 2*mPx) self.setMinimumHeight(iPx + 2*mPx)
self.updateFont()
self.updateTheme() self.updateTheme()
logger.debug("Ready: GuiDocEditHeader") logger.debug("Ready: GuiDocEditHeader")
@@ -2888,6 +2906,12 @@ class GuiDocEditHeader(QWidget):
logger.debug("Document outline updated in %.3f ms", 1000*(time() - tStart)) logger.debug("Document outline updated in %.3f ms", 1000*(time() - tStart))
return return
def updateFont(self) -> None:
"""Update the font settings."""
self.setFont(SHARED.theme.guiFont)
self.itemTitle.setFont(SHARED.theme.guiFontSmall)
return
def updateTheme(self) -> None: def updateTheme(self) -> None:
"""Update theme elements.""" """Update theme elements."""
self.tbButton.setThemeIcon("menu") self.tbButton.setThemeIcon("menu")
@@ -3001,9 +3025,6 @@ class GuiDocEditFooter(QWidget):
bSp = CONFIG.pxInt(4) bSp = CONFIG.pxInt(4)
hSp = CONFIG.pxInt(6) hSp = CONFIG.pxInt(6)
lblFont = self.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
# Cached Translations # Cached Translations
self._trLineCount = self.tr("Line: {0} ({1})") self._trLineCount = self.tr("Line: {0} ({1})")
self._trWordCount = self.tr("Words: {0} ({1})") self._trWordCount = self.tr("Words: {0} ({1})")
@@ -3026,7 +3047,6 @@ class GuiDocEditFooter(QWidget):
self.statusText.setAutoFillBackground(True) self.statusText.setAutoFillBackground(True)
self.statusText.setFixedHeight(fPx) self.statusText.setFixedHeight(fPx)
self.statusText.setAlignment(QtAlignLeftTop) self.statusText.setAlignment(QtAlignLeftTop)
self.statusText.setFont(lblFont)
# Lines # Lines
self.linesIcon = QLabel("", self) self.linesIcon = QLabel("", self)
@@ -3041,7 +3061,6 @@ class GuiDocEditFooter(QWidget):
self.linesText.setAutoFillBackground(True) self.linesText.setAutoFillBackground(True)
self.linesText.setFixedHeight(fPx) self.linesText.setFixedHeight(fPx)
self.linesText.setAlignment(QtAlignLeftTop) self.linesText.setAlignment(QtAlignLeftTop)
self.linesText.setFont(lblFont)
# Words # Words
self.wordsIcon = QLabel("", self) self.wordsIcon = QLabel("", self)
@@ -3056,7 +3075,6 @@ class GuiDocEditFooter(QWidget):
self.wordsText.setAutoFillBackground(True) self.wordsText.setAutoFillBackground(True)
self.wordsText.setFixedHeight(fPx) self.wordsText.setFixedHeight(fPx)
self.wordsText.setAlignment(QtAlignLeftTop) self.wordsText.setAlignment(QtAlignLeftTop)
self.wordsText.setFont(lblFont)
# Assemble Layout # Assemble Layout
self.outerBox = QHBoxLayout() self.outerBox = QHBoxLayout()
@@ -3079,6 +3097,7 @@ class GuiDocEditFooter(QWidget):
self.setMinimumHeight(fPx + 2*mPx) self.setMinimumHeight(fPx + 2*mPx)
# Fix the Colours # Fix the Colours
self.updateFont()
self.updateTheme() self.updateTheme()
# Initialise Info # Initialise Info
@@ -3092,6 +3111,14 @@ class GuiDocEditFooter(QWidget):
# Methods # Methods
## ##
def updateFont(self) -> None:
"""Update the font settings."""
self.setFont(SHARED.theme.guiFont)
self.statusText.setFont(SHARED.theme.guiFontSmall)
self.linesText.setFont(SHARED.theme.guiFontSmall)
self.wordsText.setFont(SHARED.theme.guiFontSmall)
return
def updateTheme(self) -> None: def updateTheme(self) -> None:
"""Update theme elements.""" """Update theme elements."""
iPx = round(0.9*SHARED.theme.baseIconHeight) iPx = round(0.9*SHARED.theme.baseIconHeight)
+33 -21
View File
@@ -31,10 +31,7 @@ import logging
from enum import Enum from enum import Enum
from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import ( from PyQt5.QtGui import QCursor, QMouseEvent, QPalette, QResizeEvent, QTextCursor, QTextOption
QCursor, QFont, QMouseEvent, QPalette, QResizeEvent, QTextCursor,
QTextOption
)
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser, QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
QToolButton, QWidget QToolButton, QWidget
@@ -141,12 +138,7 @@ class GuiDocViewer(QTextBrowser):
def initViewer(self) -> None: def initViewer(self) -> None:
"""Set editor settings from main config.""" """Set editor settings from main config."""
self._makeStyleSheet() self._makeStyleSheet()
self.initFont()
# Set Font
font = QFont()
font.setFamily(CONFIG.textFont)
font.setPointSize(CONFIG.textSize)
self.document().setDefaultFont(font)
# Set the widget colours to match syntax theme # Set the widget colours to match syntax theme
mainPalette = self.palette() mainPalette = self.palette()
@@ -189,6 +181,22 @@ class GuiDocViewer(QTextBrowser):
return return
def initFont(self) -> None:
"""Set the font of the main widget and sub-widgets. This needs
special attention since there appears to be a bug in Qt 5.15.3.
See issues #1862 and #1875.
"""
font = self.font()
font.setFamily(CONFIG.textFont)
font.setPointSize(CONFIG.textSize)
self.setFont(font)
# Reset sub-widget font to GUI font
self.docHeader.updateFont()
self.docFooter.updateFont()
return
def loadText(self, tHandle: str, updateHistory: bool = True) -> bool: def loadText(self, tHandle: str, updateHistory: bool = True) -> bool:
"""Load text into the viewer from an item handle.""" """Load text into the viewer from an item handle."""
if not SHARED.project.tree.checkType(tHandle, nwItemType.FILE): if not SHARED.project.tree.checkType(tHandle, nwItemType.FILE):
@@ -646,10 +654,6 @@ class GuiDocViewHeader(QWidget):
self.itemTitle.setAlignment(QtAlignCenterTop) self.itemTitle.setAlignment(QtAlignCenterTop)
self.itemTitle.setFixedHeight(iPx) self.itemTitle.setFixedHeight(iPx)
lblFont = self.itemTitle.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.itemTitle.setFont(lblFont)
# Other Widgets # Other Widgets
self.outlineMenu = QMenu(self) self.outlineMenu = QMenu(self)
@@ -700,7 +704,7 @@ class GuiDocViewHeader(QWidget):
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx) self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.setMinimumHeight(iPx + 2*mPx) self.setMinimumHeight(iPx + 2*mPx)
# Fix the Colours self.updateFont()
self.updateTheme() self.updateTheme()
logger.debug("Ready: GuiDocViewHeader") logger.debug("Ready: GuiDocViewHeader")
@@ -745,6 +749,12 @@ class GuiDocViewHeader(QWidget):
self._docOutline = data self._docOutline = data
return return
def updateFont(self) -> None:
"""Update the font settings."""
self.setFont(SHARED.theme.guiFont)
self.itemTitle.setFont(SHARED.theme.guiFontSmall)
return
def updateTheme(self) -> None: def updateTheme(self) -> None:
"""Update theme elements.""" """Update theme elements."""
self.outlineButton.setThemeIcon("list") self.outlineButton.setThemeIcon("list")
@@ -886,11 +896,6 @@ class GuiDocViewFooter(QWidget):
self.showSynopsis.toggled.connect(self._doToggleSynopsis) self.showSynopsis.toggled.connect(self._doToggleSynopsis)
self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments")) self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments"))
lblFont = self.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.showComments.setFont(lblFont)
self.showSynopsis.setFont(lblFont)
# Assemble Layout # Assemble Layout
self.outerBox = QHBoxLayout() self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.showHide, 0) self.outerBox.addWidget(self.showHide, 0)
@@ -906,7 +911,7 @@ class GuiDocViewFooter(QWidget):
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx) self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.setMinimumHeight(iPx + 2*mPx) self.setMinimumHeight(iPx + 2*mPx)
# Fix the Colours self.updateFont()
self.updateTheme() self.updateTheme()
logger.debug("Ready: GuiDocViewFooter") logger.debug("Ready: GuiDocViewFooter")
@@ -917,6 +922,13 @@ class GuiDocViewFooter(QWidget):
# Methods # Methods
## ##
def updateFont(self) -> None:
"""Update the font settings."""
self.setFont(SHARED.theme.guiFont)
self.showComments.setFont(SHARED.theme.guiFontSmall)
self.showSynopsis.setFont(SHARED.theme.guiFontSmall)
return
def updateTheme(self) -> None: def updateTheme(self) -> None:
"""Update theme elements.""" """Update theme elements."""
# Icons # Icons
+3 -3
View File
@@ -30,9 +30,7 @@ from math import ceil
from pathlib import Path from pathlib import Path
from PyQt5.QtCore import QSize, Qt from PyQt5.QtCore import QSize, Qt
from PyQt5.QtGui import ( from PyQt5.QtGui import QColor, QFont, QFontDatabase, QFontMetrics, QIcon, QPalette, QPixmap
QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap
)
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from novelwriter import CONFIG from novelwriter import CONFIG
@@ -154,6 +152,8 @@ class GuiTheme:
self.guiFont = QApplication.font() self.guiFont = QApplication.font()
self.guiFontB = QApplication.font() self.guiFontB = QApplication.font()
self.guiFontB.setBold(True) self.guiFontB.setBold(True)
self.guiFontSmall = QApplication.font()
self.guiFontSmall.setPointSizeF(0.9*self.guiFont.pointSizeF())
qMetric = QFontMetrics(self.guiFont) qMetric = QFontMetrics(self.guiFont)
fHeight = qMetric.height() fHeight = qMetric.height()
+12 -6
View File
@@ -31,7 +31,7 @@ from time import time
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QPalette, QResizeEvent
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout, QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
@@ -761,7 +761,6 @@ class _PreviewWidget(QTextBrowser):
self.setPalette(dPalette) self.setPalette(dPalette)
self.setMinimumWidth(40*SHARED.theme.textNWidth) self.setMinimumWidth(40*SHARED.theme.textNWidth)
self.setTextFont(CONFIG.textFont, CONFIG.textSize)
self.setTabStopDistance(CONFIG.getTabWidth()) self.setTabStopDistance(CONFIG.getTabWidth())
self.setOpenExternalLinks(False) self.setOpenExternalLinks(False)
@@ -802,6 +801,8 @@ class _PreviewWidget(QTextBrowser):
self._updateDocMargins() self._updateDocMargins()
self._updateBuildAge() self._updateBuildAge()
self.setTextFont(CONFIG.textFont, CONFIG.textSize)
# Age Timer # Age Timer
self.ageTimer = QTimer(self) self.ageTimer = QTimer(self)
self.ageTimer.setInterval(10000) self.ageTimer.setInterval(10000)
@@ -831,12 +832,17 @@ class _PreviewWidget(QTextBrowser):
return return
def setTextFont(self, family: str, size: int) -> None: def setTextFont(self, family: str, size: int) -> None:
"""Set the text font properties.""" """Set the text font properties and then reset for sub-widgets.
if family: This needs special attention since there appears to be a bug in
font = QFont() Qt 5.15.3. See issues #1862 and #1875.
"""
if family and size > 4:
font = self.font()
font.setFamily(family) font.setFamily(family)
font.setPointSize(size) font.setPointSize(size)
self.document().setDefaultFont(font) self.setFont(font)
self.buildProgress.setFont(SHARED.theme.guiFont)
self.ageLabel.setFont(SHARED.theme.guiFontSmall)
return return
## ##