diff --git a/novelwriter/common.py b/novelwriter/common.py index 83a364bf..f03fa823 100644 --- a/novelwriter/common.py +++ b/novelwriter/common.py @@ -445,6 +445,7 @@ def fontMatcher(font: QFont) -> QFont: default Qt font matching algorithm doesn't handle well changing application fonts at runtime. """ + font.setStyleName(None) # Make sure no font style name is set from config, see #2502 info = QFontInfo(font) if (famRequest := font.family()) != (famActual := info.family()): logger.warning("Font mismatch: Requested '%s', but got '%s'", famRequest, famActual) diff --git a/novelwriter/config.py b/novelwriter/config.py index 93d8fb02..df820029 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -202,7 +202,7 @@ class Config: self.doJustify = False # Justify text self.showTabsNSpaces = False # Show tabs and spaces 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.doReplaceSQuote = True # Smart single quotes diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index f13efb40..7f51dd38 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -701,7 +701,7 @@ class GuiPreferences(NDialog): self.showMultiSpaces = NSwitch(self) self.showMultiSpaces.setChecked(CONFIG.showMultiSpaces) 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.") ) diff --git a/novelwriter/gui/dochighlight.py b/novelwriter/gui/dochighlight.py index 114acdb3..60c28d4b 100644 --- a/novelwriter/gui/dochighlight.py +++ b/novelwriter/gui/dochighlight.py @@ -141,7 +141,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): # Multiple or Trailing Spaces if CONFIG.showMultiSpaces: - rxRule = re.compile(r"[ ]{2,}|[ ]*$", re.UNICODE) + rxRule = re.compile(r"\s{2,}") hlRule = { 0: self._hStyles["mspaces"], } @@ -150,7 +150,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): self._cmnRules.append((rxRule, hlRule)) # 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 = { 0: self._hStyles["nobreak"], } @@ -239,7 +239,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): self._cmnRules.append((rxRule, hlRule)) # Alignment Tags - rxRule = re.compile(r"(^>{1,2}|<{1,2}$)", re.UNICODE) + rxRule = re.compile(r"(^>{1,2}|<{1,2}$)") hlRule = { 1: self._hStyles["markup"], } @@ -247,7 +247,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): self._txtRules.append((rxRule, hlRule)) # Auto-Replace Tags - rxRule = re.compile(r"<(\S+?)>", re.UNICODE) + rxRule = re.compile(r"<(\S+?)>") hlRule = { 0: self._hStyles["replace"], } diff --git a/pyproject.toml b/pyproject.toml index 3610e012..5860b722 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,7 +124,6 @@ markers = [ "base: Base classes tests", "core: Core classes tests", "gui: GUI classes tests", - "serial", ] [tool.coverage.run] diff --git a/run_tests.py b/run_tests.py index cedf071b..b9687aa9 100755 --- a/run_tests.py +++ b/run_tests.py @@ -18,6 +18,7 @@ if __name__ == "__main__": args = parser.parse_args() env = os.environ.copy() + env["QT_SCALE_FACTOR"] = "1.0" cmd = [sys.executable, "-m", "pytest", "-vv"] if args.o: diff --git a/setup/description_pypi.md b/setup/description_pypi.md index 0221db8d..23c85909 100644 --- a/setup/description_pypi.md +++ b/setup/description_pypi.md @@ -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 JSON files. -The application is written with Python 3 (3.10+) using Qt6 and PyQt6 (5.10+). It is developed on -Linux, but should in principle work fine on other operating systems as well as long as dependencies -are met. It is regularly tested on Debian and Ubuntu Linux, Windows, and MacOS. +The application is written with Python 3 using Qt6 and PyQt6. It is developed on Linux, but should +in principle work fine on other operating systems as well as long as dependencies are met. It is +regularly tested on Debian and Ubuntu Linux, Windows, and MacOS. novelWriter is developed and maintained by [Veronica Berglyd Olsen](https://github.com/vkbo). diff --git a/setup/iss_license.txt b/setup/iss_license.txt index fe023cb4..dbcf6b7d 100644 --- a/setup/iss_license.txt +++ b/setup/iss_license.txt @@ -1,6 +1,6 @@ novelWriter License -Copyright (C) 2018-2025 Veronica Berglyd Olsen +Copyright (C) Veronica Berglyd Olsen and novelWriter contributors License: GPL v3+ This program is free software: you can redistribute it and/or modify diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index c3a45e6a..7a281145 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -1,5 +1,5 @@ [Meta] -timestamp = 2025-06-14 17:03:01 +timestamp = 2025-08-24 15:30:16 [Main] font = @@ -63,7 +63,7 @@ fmtpadthin = False spellcheck = en showtabsnspaces = False showlineendings = False -showmultispaces = True +showmultispaces = False incnoteswcount = True showfullpath = True dialogstyle = 2 diff --git a/tests/test_base/test_base_common.py b/tests/test_base/test_base_common.py index 76a11bd7..a46f02d0 100644 --- a/tests/test_base/test_base_common.py +++ b/tests/test_base/test_base_common.py @@ -537,6 +537,11 @@ def testBaseCommon_fontMatcher(monkeypatch): nonsense = QFont("nonesense", 10) assert fontMatcher(nonsense) is nonsense + # Style is reset + nonsense.setStyleName("blabla") + assert nonsense.styleName() == "blabla" + assert fontMatcher(nonsense).styleName() == "" + # General font if len(QFontDatabase.families()) > 1: fontOne = QFont(QFontDatabase.families()[0]) diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index bf1ee362..03b23a01 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -279,7 +279,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): prefs.altDialogOpen.setText("%") # Symbol also tests for #2455 prefs.altDialogClose.setText("%") # Symbol also tests for #2455 prefs.highlightEmph.setChecked(False) - prefs.showMultiSpaces.setChecked(False) + prefs.showMultiSpaces.setChecked(True) prefs._insertDialogLineSymbol(nwUnicode.U_ENDASH) 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.altDialogClose == "" assert CONFIG.highlightEmph is True - assert CONFIG.showMultiSpaces is True + assert CONFIG.showMultiSpaces is False # Text Automation prefs.doReplaceSQuote.setChecked(False) @@ -413,7 +413,7 @@ def testDlgPreferences_Settings(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): assert CONFIG.altDialogOpen == "%" assert CONFIG.altDialogClose == "%" assert CONFIG.highlightEmph is False - assert CONFIG.showMultiSpaces is False + assert CONFIG.showMultiSpaces is True # Text Automation assert CONFIG.doReplace is False diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index 68b75fd4..aa2af3cf 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -431,11 +431,13 @@ def testGuiTheme_LoadIcons(): assert qIcon.isNull() is False # 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)) assert isinstance(qPix, QPixmap) assert qPix.isNull() is False - assert qPix.width() == 50 - assert qPix.height() == 50 + assert qPix.width() == 50, "If this fails, make sure QT_SCALE_FACTOR=1" + assert qPix.height() == 50, "If this fails, make sure QT_SCALE_FACTOR=1" # Load app icon qIcon = iconCache.getIcon("novelwriter")