Skip to content

Commit

Permalink
Fix how document font is set (#1877)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo authored May 20, 2024
2 parents fddd5fd + 9388ce6 commit f9292d6
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 55 deletions.
77 changes: 52 additions & 25 deletions novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
pyqtSignal, pyqtSlot
)
from PyQt5.QtGui import (
QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette,
QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
QColor, QCursor, QKeyEvent, QKeySequence, QMouseEvent, QPalette, QPixmap,
QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
)
from PyQt5.QtWidgets import (
QAction, QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit,
Expand Down Expand Up @@ -329,10 +329,7 @@ def initEditor(self) -> None:
SHARED.updateSpellCheckLanguage()

# Set font
font = QFont()
font.setFamily(CONFIG.textFont)
font.setPointSize(CONFIG.textSize)
self._qDocument.setDefaultFont(font)
self.initFont()

# Update highlighter settings
self._qDocument.syntaxHighlighter.initHighlighter()
Expand Down Expand Up @@ -382,6 +379,23 @@ def initEditor(self) -> None:

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:
"""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
Expand Down Expand Up @@ -2396,9 +2410,6 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(6)

self.boxFont = SHARED.theme.guiFont
self.boxFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)

self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
Expand All @@ -2410,12 +2421,10 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
# ==========

self.searchBox = QLineEdit(self)
self.searchBox.setFont(self.boxFont)
self.searchBox.setPlaceholderText(self.tr("Search for"))
self.searchBox.returnPressed.connect(self._doSearch)

self.replaceBox = QLineEdit(self)
self.replaceBox.setFont(self.boxFont)
self.replaceBox.setPlaceholderText(self.tr("Replace with"))
self.replaceBox.returnPressed.connect(self._doReplace)

Expand All @@ -2425,12 +2434,9 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
self.searchOpt.setContentsMargins(0, 0, 0, 0)

self.searchLabel = QLabel(self.tr("Search"), self)
self.searchLabel.setFont(self.boxFont)
self.searchLabel.setIndent(CONFIG.pxInt(6))

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.setCheckable(True)
Expand Down Expand Up @@ -2515,6 +2521,7 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
self.replaceButton.setVisible(False)
self.adjustSize()

self.updateFont()
self.updateTheme()

logger.debug("Ready: GuiDocEditSearch")
Expand Down Expand Up @@ -2598,7 +2605,9 @@ def setResultCount(self, currRes: int | None, resCount: int | None) -> None:
numCount = f"{lim:n}+" if (resCount or 0) > lim else f"{resCount:n}"
sCurrRes = "?" if currRes is None else str(currRes)
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.setMinimumWidth(minWidth)
self.adjustSize()
Expand All @@ -2609,6 +2618,18 @@ def setResultCount(self, currRes: int | None, resCount: int | None) -> None:
# 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:
"""Update theme elements."""
qPalette = QApplication.palette()
Expand Down Expand Up @@ -2793,10 +2814,6 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
self.itemTitle.setAlignment(QtAlignCenterTop)
self.itemTitle.setFixedHeight(iPx)

lblFont = self.itemTitle.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.itemTitle.setFont(lblFont)

# Other Widgets
self.outlineMenu = QMenu(self)

Expand Down Expand Up @@ -2850,6 +2867,7 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
self.setContentsMargins(0, 0, 0, 0)
self.setMinimumHeight(iPx + 2*mPx)

self.updateFont()
self.updateTheme()

logger.debug("Ready: GuiDocEditHeader")
Expand Down Expand Up @@ -2888,6 +2906,12 @@ def setOutline(self, data: dict[int, str]) -> None:
logger.debug("Document outline updated in %.3f ms", 1000*(time() - tStart))
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:
"""Update theme elements."""
self.tbButton.setThemeIcon("menu")
Expand Down Expand Up @@ -3001,9 +3025,6 @@ def __init__(self, parent: QWidget) -> None:
bSp = CONFIG.pxInt(4)
hSp = CONFIG.pxInt(6)

lblFont = self.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)

# Cached Translations
self._trLineCount = self.tr("Line: {0} ({1})")
self._trWordCount = self.tr("Words: {0} ({1})")
Expand All @@ -3026,7 +3047,6 @@ def __init__(self, parent: QWidget) -> None:
self.statusText.setAutoFillBackground(True)
self.statusText.setFixedHeight(fPx)
self.statusText.setAlignment(QtAlignLeftTop)
self.statusText.setFont(lblFont)

# Lines
self.linesIcon = QLabel("", self)
Expand All @@ -3041,7 +3061,6 @@ def __init__(self, parent: QWidget) -> None:
self.linesText.setAutoFillBackground(True)
self.linesText.setFixedHeight(fPx)
self.linesText.setAlignment(QtAlignLeftTop)
self.linesText.setFont(lblFont)

# Words
self.wordsIcon = QLabel("", self)
Expand All @@ -3056,7 +3075,6 @@ def __init__(self, parent: QWidget) -> None:
self.wordsText.setAutoFillBackground(True)
self.wordsText.setFixedHeight(fPx)
self.wordsText.setAlignment(QtAlignLeftTop)
self.wordsText.setFont(lblFont)

# Assemble Layout
self.outerBox = QHBoxLayout()
Expand All @@ -3079,6 +3097,7 @@ def __init__(self, parent: QWidget) -> None:
self.setMinimumHeight(fPx + 2*mPx)

# Fix the Colours
self.updateFont()
self.updateTheme()

# Initialise Info
Expand All @@ -3092,6 +3111,14 @@ def __init__(self, parent: QWidget) -> None:
# 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:
"""Update theme elements."""
iPx = round(0.9*SHARED.theme.baseIconHeight)
Expand Down
54 changes: 33 additions & 21 deletions novelwriter/gui/docviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
from enum import Enum

from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import (
QCursor, QFont, QMouseEvent, QPalette, QResizeEvent, QTextCursor,
QTextOption
)
from PyQt5.QtGui import QCursor, QMouseEvent, QPalette, QResizeEvent, QTextCursor, QTextOption
from PyQt5.QtWidgets import (
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
QToolButton, QWidget
Expand Down Expand Up @@ -141,12 +138,7 @@ def updateTheme(self) -> None:
def initViewer(self) -> None:
"""Set editor settings from main config."""
self._makeStyleSheet()

# Set Font
font = QFont()
font.setFamily(CONFIG.textFont)
font.setPointSize(CONFIG.textSize)
self.document().setDefaultFont(font)
self.initFont()

# Set the widget colours to match syntax theme
mainPalette = self.palette()
Expand Down Expand Up @@ -189,6 +181,22 @@ def initViewer(self) -> None:

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:
"""Load text into the viewer from an item handle."""
if not SHARED.project.tree.checkType(tHandle, nwItemType.FILE):
Expand Down Expand Up @@ -646,10 +654,6 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
self.itemTitle.setAlignment(QtAlignCenterTop)
self.itemTitle.setFixedHeight(iPx)

lblFont = self.itemTitle.font()
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
self.itemTitle.setFont(lblFont)

# Other Widgets
self.outlineMenu = QMenu(self)

Expand Down Expand Up @@ -700,7 +704,7 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.setMinimumHeight(iPx + 2*mPx)

# Fix the Colours
self.updateFont()
self.updateTheme()

logger.debug("Ready: GuiDocViewHeader")
Expand Down Expand Up @@ -745,6 +749,12 @@ def setOutline(self, data: dict[str, tuple[str, int]]) -> None:
self._docOutline = data
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:
"""Update theme elements."""
self.outlineButton.setThemeIcon("list")
Expand Down Expand Up @@ -886,11 +896,6 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
self.showSynopsis.toggled.connect(self._doToggleSynopsis)
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
self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.showHide, 0)
Expand All @@ -906,7 +911,7 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
self.setMinimumHeight(iPx + 2*mPx)

# Fix the Colours
self.updateFont()
self.updateTheme()

logger.debug("Ready: GuiDocViewFooter")
Expand All @@ -917,6 +922,13 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
# 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:
"""Update theme elements."""
# Icons
Expand Down
6 changes: 3 additions & 3 deletions novelwriter/gui/theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
from pathlib import Path

from PyQt5.QtCore import QSize, Qt
from PyQt5.QtGui import (
QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap
)
from PyQt5.QtGui import QColor, QFont, QFontDatabase, QFontMetrics, QIcon, QPalette, QPixmap
from PyQt5.QtWidgets import QApplication

from novelwriter import CONFIG
Expand Down Expand Up @@ -154,6 +152,8 @@ def __init__(self) -> None:
self.guiFont = QApplication.font()
self.guiFontB = QApplication.font()
self.guiFontB.setBold(True)
self.guiFontSmall = QApplication.font()
self.guiFontSmall.setPointSizeF(0.9*self.guiFont.pointSizeF())

qMetric = QFontMetrics(self.guiFont)
fHeight = qMetric.height()
Expand Down
18 changes: 12 additions & 6 deletions novelwriter/tools/manuscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from typing import TYPE_CHECKING

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.QtWidgets import (
QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
Expand Down Expand Up @@ -761,7 +761,6 @@ def __init__(self, parent: QWidget) -> None:
self.setPalette(dPalette)

self.setMinimumWidth(40*SHARED.theme.textNWidth)
self.setTextFont(CONFIG.textFont, CONFIG.textSize)
self.setTabStopDistance(CONFIG.getTabWidth())
self.setOpenExternalLinks(False)

Expand Down Expand Up @@ -802,6 +801,8 @@ def __init__(self, parent: QWidget) -> None:
self._updateDocMargins()
self._updateBuildAge()

self.setTextFont(CONFIG.textFont, CONFIG.textSize)

# Age Timer
self.ageTimer = QTimer(self)
self.ageTimer.setInterval(10000)
Expand Down Expand Up @@ -831,12 +832,17 @@ def setJustify(self, state: bool) -> None:
return

def setTextFont(self, family: str, size: int) -> None:
"""Set the text font properties."""
if family:
font = QFont()
"""Set the text font properties and then reset for sub-widgets.
This needs special attention since there appears to be a bug in
Qt 5.15.3. See issues #1862 and #1875.
"""
if family and size > 4:
font = self.font()
font.setFamily(family)
font.setPointSize(size)
self.document().setDefaultFont(font)
self.setFont(font)
self.buildProgress.setFont(SHARED.theme.guiFont)
self.ageLabel.setFont(SHARED.theme.guiFontSmall)
return

##
Expand Down

0 comments on commit f9292d6

Please sign in to comment.