Merge branch 'theme_fixes' of https://github.com/HeyMyian/novelWriter into theme_fixes
This commit is contained in:
@@ -445,6 +445,7 @@ def fontMatcher(font: QFont) -> QFont:
|
|||||||
default Qt font matching algorithm doesn't handle well changing
|
default Qt font matching algorithm doesn't handle well changing
|
||||||
application fonts at runtime.
|
application fonts at runtime.
|
||||||
"""
|
"""
|
||||||
|
font.setStyleName(None) # Make sure no font style name is set from config, see #2502
|
||||||
info = QFontInfo(font)
|
info = QFontInfo(font)
|
||||||
if (famRequest := font.family()) != (famActual := info.family()):
|
if (famRequest := font.family()) != (famActual := info.family()):
|
||||||
logger.warning("Font mismatch: Requested '%s', but got '%s'", famRequest, famActual)
|
logger.warning("Font mismatch: Requested '%s', but got '%s'", famRequest, famActual)
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class Config:
|
|||||||
self.doJustify = False # Justify text
|
self.doJustify = False # Justify text
|
||||||
self.showTabsNSpaces = False # Show tabs and spaces in editor
|
self.showTabsNSpaces = False # Show tabs and spaces in editor
|
||||||
self.showLineEndings = False # Show line endings in editor
|
self.showLineEndings = False # Show line endings in editor
|
||||||
self.showMultiSpaces = True # Highlight multiple spaces in the text
|
self.showMultiSpaces = False # Highlight multiple spaces in the text
|
||||||
|
|
||||||
self.doReplace = True # Enable auto-replace as you type
|
self.doReplace = True # Enable auto-replace as you type
|
||||||
self.doReplaceSQuote = True # Smart single quotes
|
self.doReplaceSQuote = True # Smart single quotes
|
||||||
|
|||||||
@@ -701,7 +701,7 @@ class GuiPreferences(NDialog):
|
|||||||
self.showMultiSpaces = NSwitch(self)
|
self.showMultiSpaces = NSwitch(self)
|
||||||
self.showMultiSpaces.setChecked(CONFIG.showMultiSpaces)
|
self.showMultiSpaces.setChecked(CONFIG.showMultiSpaces)
|
||||||
self.mainForm.addRow(
|
self.mainForm.addRow(
|
||||||
self.tr("Highlight multiple or trailing spaces"), self.showMultiSpaces,
|
self.tr("Highlight multiple spaces between words"), self.showMultiSpaces,
|
||||||
self.tr("Applies to the document editor only.")
|
self.tr("Applies to the document editor only.")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
|
|
||||||
# Multiple or Trailing Spaces
|
# Multiple or Trailing Spaces
|
||||||
if CONFIG.showMultiSpaces:
|
if CONFIG.showMultiSpaces:
|
||||||
rxRule = re.compile(r"[ ]{2,}|[ ]*$", re.UNICODE)
|
rxRule = re.compile(r"\s{2,}")
|
||||||
hlRule = {
|
hlRule = {
|
||||||
0: self._hStyles["mspaces"],
|
0: self._hStyles["mspaces"],
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
self._cmnRules.append((rxRule, hlRule))
|
self._cmnRules.append((rxRule, hlRule))
|
||||||
|
|
||||||
# Non-Breaking Spaces
|
# Non-Breaking Spaces
|
||||||
rxRule = re.compile(f"[{nwUnicode.U_NBSP}{nwUnicode.U_THNBSP}]+", re.UNICODE)
|
rxRule = re.compile(f"[{nwUnicode.U_NBSP}{nwUnicode.U_THNBSP}]+")
|
||||||
hlRule = {
|
hlRule = {
|
||||||
0: self._hStyles["nobreak"],
|
0: self._hStyles["nobreak"],
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
self._cmnRules.append((rxRule, hlRule))
|
self._cmnRules.append((rxRule, hlRule))
|
||||||
|
|
||||||
# Alignment Tags
|
# Alignment Tags
|
||||||
rxRule = re.compile(r"(^>{1,2}|<{1,2}$)", re.UNICODE)
|
rxRule = re.compile(r"(^>{1,2}|<{1,2}$)")
|
||||||
hlRule = {
|
hlRule = {
|
||||||
1: self._hStyles["markup"],
|
1: self._hStyles["markup"],
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
self._txtRules.append((rxRule, hlRule))
|
self._txtRules.append((rxRule, hlRule))
|
||||||
|
|
||||||
# Auto-Replace Tags
|
# Auto-Replace Tags
|
||||||
rxRule = re.compile(r"<(\S+?)>", re.UNICODE)
|
rxRule = re.compile(r"<(\S+?)>")
|
||||||
hlRule = {
|
hlRule = {
|
||||||
0: self._hStyles["replace"],
|
0: self._hStyles["replace"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,6 @@ markers = [
|
|||||||
"base: Base classes tests",
|
"base: Base classes tests",
|
||||||
"core: Core classes tests",
|
"core: Core classes tests",
|
||||||
"gui: GUI classes tests",
|
"gui: GUI classes tests",
|
||||||
"serial",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.coverage.run]
|
[tool.coverage.run]
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ if __name__ == "__main__":
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
|
env["QT_SCALE_FACTOR"] = "1.0"
|
||||||
cmd = [sys.executable, "-m", "pytest", "-vv"]
|
cmd = [sys.executable, "-m", "pytest", "-vv"]
|
||||||
|
|
||||||
if args.o:
|
if args.o:
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ synchronisation tools. All text is saved as plain text files with a meta data he
|
|||||||
project structure is stored in a single project XML file, and other meta data is primarily saved as
|
project structure is stored in a single project XML file, and other meta data is primarily saved as
|
||||||
JSON files.
|
JSON files.
|
||||||
|
|
||||||
The application is written with Python 3 (3.10+) using Qt6 and PyQt6 (5.10+). It is developed on
|
The application is written with Python 3 using Qt6 and PyQt6. It is developed on Linux, but should
|
||||||
Linux, but should in principle work fine on other operating systems as well as long as dependencies
|
in principle work fine on other operating systems as well as long as dependencies are met. It is
|
||||||
are met. It is regularly tested on Debian and Ubuntu Linux, Windows, and MacOS.
|
regularly tested on Debian and Ubuntu Linux, Windows, and MacOS.
|
||||||
|
|
||||||
novelWriter is developed and maintained by [Veronica Berglyd Olsen](https://github.com/vkbo).
|
novelWriter is developed and maintained by [Veronica Berglyd Olsen](https://github.com/vkbo).
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
novelWriter License
|
novelWriter License
|
||||||
|
|
||||||
Copyright (C) 2018-2025 Veronica Berglyd Olsen
|
Copyright (C) Veronica Berglyd Olsen and novelWriter contributors
|
||||||
License: GPL v3+ <https://www.gnu.org/licenses/gpl-3.0.html>
|
License: GPL v3+ <https://www.gnu.org/licenses/gpl-3.0.html>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Meta]
|
[Meta]
|
||||||
timestamp = 2025-06-14 17:03:01
|
timestamp = 2025-08-24 15:30:16
|
||||||
|
|
||||||
[Main]
|
[Main]
|
||||||
font =
|
font =
|
||||||
@@ -63,7 +63,7 @@ fmtpadthin = False
|
|||||||
spellcheck = en
|
spellcheck = en
|
||||||
showtabsnspaces = False
|
showtabsnspaces = False
|
||||||
showlineendings = False
|
showlineendings = False
|
||||||
showmultispaces = True
|
showmultispaces = False
|
||||||
incnoteswcount = True
|
incnoteswcount = True
|
||||||
showfullpath = True
|
showfullpath = True
|
||||||
dialogstyle = 2
|
dialogstyle = 2
|
||||||
|
|||||||
@@ -537,6 +537,11 @@ def testBaseCommon_fontMatcher(monkeypatch):
|
|||||||
nonsense = QFont("nonesense", 10)
|
nonsense = QFont("nonesense", 10)
|
||||||
assert fontMatcher(nonsense) is nonsense
|
assert fontMatcher(nonsense) is nonsense
|
||||||
|
|
||||||
|
# Style is reset
|
||||||
|
nonsense.setStyleName("blabla")
|
||||||
|
assert nonsense.styleName() == "blabla"
|
||||||
|
assert fontMatcher(nonsense).styleName() == ""
|
||||||
|
|
||||||
# General font
|
# General font
|
||||||
if len(QFontDatabase.families()) > 1:
|
if len(QFontDatabase.families()) > 1:
|
||||||
fontOne = QFont(QFontDatabase.families()[0])
|
fontOne = QFont(QFontDatabase.families()[0])
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
|
|||||||
prefs.altDialogOpen.setText("%") # Symbol also tests for #2455
|
prefs.altDialogOpen.setText("%") # Symbol also tests for #2455
|
||||||
prefs.altDialogClose.setText("%") # Symbol also tests for #2455
|
prefs.altDialogClose.setText("%") # Symbol also tests for #2455
|
||||||
prefs.highlightEmph.setChecked(False)
|
prefs.highlightEmph.setChecked(False)
|
||||||
prefs.showMultiSpaces.setChecked(False)
|
prefs.showMultiSpaces.setChecked(True)
|
||||||
|
|
||||||
prefs._insertDialogLineSymbol(nwUnicode.U_ENDASH)
|
prefs._insertDialogLineSymbol(nwUnicode.U_ENDASH)
|
||||||
assert prefs.dialogLine.text() == f"{nwUnicode.U_ENDASH} {nwUnicode.U_EMDASH}"
|
assert prefs.dialogLine.text() == f"{nwUnicode.U_ENDASH} {nwUnicode.U_EMDASH}"
|
||||||
@@ -292,7 +292,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
|
|||||||
assert CONFIG.altDialogOpen == ""
|
assert CONFIG.altDialogOpen == ""
|
||||||
assert CONFIG.altDialogClose == ""
|
assert CONFIG.altDialogClose == ""
|
||||||
assert CONFIG.highlightEmph is True
|
assert CONFIG.highlightEmph is True
|
||||||
assert CONFIG.showMultiSpaces is True
|
assert CONFIG.showMultiSpaces is False
|
||||||
|
|
||||||
# Text Automation
|
# Text Automation
|
||||||
prefs.doReplaceSQuote.setChecked(False)
|
prefs.doReplaceSQuote.setChecked(False)
|
||||||
@@ -413,7 +413,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths):
|
|||||||
assert CONFIG.altDialogOpen == "%"
|
assert CONFIG.altDialogOpen == "%"
|
||||||
assert CONFIG.altDialogClose == "%"
|
assert CONFIG.altDialogClose == "%"
|
||||||
assert CONFIG.highlightEmph is False
|
assert CONFIG.highlightEmph is False
|
||||||
assert CONFIG.showMultiSpaces is False
|
assert CONFIG.showMultiSpaces is True
|
||||||
|
|
||||||
# Text Automation
|
# Text Automation
|
||||||
assert CONFIG.doReplace is False
|
assert CONFIG.doReplace is False
|
||||||
|
|||||||
@@ -431,11 +431,13 @@ def testGuiTheme_LoadIcons():
|
|||||||
assert qIcon.isNull() is False
|
assert qIcon.isNull() is False
|
||||||
|
|
||||||
# Load it as a pixmap with a size
|
# Load it as a pixmap with a size
|
||||||
|
# If this part of the test fails, you may need to set the
|
||||||
|
# environment variable: QT_SCALE_FACTOR=1
|
||||||
qPix = iconCache.getPixmap("add", (50, 50))
|
qPix = iconCache.getPixmap("add", (50, 50))
|
||||||
assert isinstance(qPix, QPixmap)
|
assert isinstance(qPix, QPixmap)
|
||||||
assert qPix.isNull() is False
|
assert qPix.isNull() is False
|
||||||
assert qPix.width() == 50
|
assert qPix.width() == 50, "If this fails, make sure QT_SCALE_FACTOR=1"
|
||||||
assert qPix.height() == 50
|
assert qPix.height() == 50, "If this fails, make sure QT_SCALE_FACTOR=1"
|
||||||
|
|
||||||
# Load app icon
|
# Load app icon
|
||||||
qIcon = iconCache.getIcon("novelwriter")
|
qIcon = iconCache.getIcon("novelwriter")
|
||||||
|
|||||||
Reference in New Issue
Block a user