From aadc576d0af4a15f6d6b2da6899efbc97b38aab3 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 15 Oct 2022 22:47:18 +0200 Subject: [PATCH 1/5] Require at least Qt 5.9 --- novelwriter/__init__.py | 8 ++++---- novelwriter/config.py | 14 +++----------- novelwriter/gui/doceditor.py | 18 +++++++----------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/novelwriter/__init__.py b/novelwriter/__init__.py index dc8f8c62..5c13cde9 100644 --- a/novelwriter/__init__.py +++ b/novelwriter/__init__.py @@ -214,14 +214,14 @@ def main(sysArgs=None): "At least Python 3.7 is required, found %s" % CONFIG.verPyString ) errorCode |= 0x04 - if CONFIG.verQtValue < 50300: + if CONFIG.verQtValue < 50900: errorData.append( - "At least Qt5 version 5.3 is required, found %s" % CONFIG.verQtString + "At least Qt5 version 5.9 is required, found %s" % CONFIG.verQtString ) errorCode |= 0x08 - if CONFIG.verPyQtValue < 50300: + if CONFIG.verPyQtValue < 50900: errorData.append( - "At least PyQt5 version 5.3 is required, found %s" % CONFIG.verPyQtString + "At least PyQt5 version 5.9 is required, found %s" % CONFIG.verPyQtString ) errorCode |= 0x10 diff --git a/novelwriter/config.py b/novelwriter/config.py index 81487a16..e86c850d 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -220,8 +220,8 @@ class Config: self.osUnknown = True # Other System Info - self.hostName = "Unknown" - self.kernelVer = "Unknown" + self.hostName = QSysInfo.machineHostName() + self.kernelVer = QSysInfo.kernelVersion() # Packages self.hasEnchant = False # The pyenchant package @@ -264,10 +264,7 @@ class Config: self.confPath = confPath if dataPath is None: - if self.verQtValue >= 50400: - dataRoot = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation) - else: - dataRoot = QStandardPaths.writableLocation(QStandardPaths.DataLocation) + dataRoot = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation) self.dataPath = os.path.join(os.path.abspath(dataRoot), self.appHandle) else: logger.info("Setting data path from alternative path: %s", dataPath) @@ -347,11 +344,6 @@ class Config: self.errData.append(formatException(exc)) self.dataPath = None - # Host and Kernel - if self.verQtValue >= 50600: - self.hostName = QSysInfo.machineHostName() - self.kernelVer = QSysInfo.kernelVersion() - # Load recent projects cache self.loadRecentCache() diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index ffdce1c7..5454341f 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -604,19 +604,15 @@ class GuiDocEditor(QTextEdit): ## def getText(self): - """Get the text content of the current document. This method - uses QTextEdit->toPlainText for Qt versions lower than 5.9, and - the QTextDocument->toRawText for higher version. The latter - preserves non-breaking spaces, which the former does not. - We still want to get rid of page and line separators though. + """Get the text content of the current document. This method uses + QTextDocument->toRawText instead of toPlainText(). The former preserves + non-breaking spaces, the latter does not. We still want to get rid of + page and line separators though. See: https://doc.qt.io/qt-5/qtextdocument.html#toPlainText """ - if self.mainConf.verQtValue >= 50900: - theText = self.document().toRawText() - theText = theText.replace(nwUnicode.U_LSEP, "\n") # Line separators - theText = theText.replace(nwUnicode.U_PSEP, "\n") # Paragraph separators - else: - theText = self.toPlainText() + theText = self.document().toRawText() + theText = theText.replace(nwUnicode.U_LSEP, "\n") # Line separators + theText = theText.replace(nwUnicode.U_PSEP, "\n") # Paragraph separators return theText def getCursorPosition(self): From 9c16b5832526b41f35e6fea6a52f1603cee33499 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 15 Oct 2022 22:50:07 +0200 Subject: [PATCH 2/5] Fix document editor test --- tests/test_gui/test_gui_doceditor.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 7f85ed3e..b3bc49b1 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -213,7 +213,8 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal): qtbot.wait(stepDelay) # Get Text - # Both methods should return the same result for line breaks, but not for spaces + # This should replace line and paragraph separators, but preserve + # non-breaking spaces. newText = ( "### New Scene\u2029\u2029" "Some\u2028text.\u2029" @@ -221,10 +222,6 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal): ) assert nwGUI.docEditor.replaceText(newText) assert nwGUI.docEditor.getText() == "### New Scene\n\nSome\ntext.\nMore\u00a0text.\n" - verQtValue = nwGUI.mainConf.verQtValue - nwGUI.mainConf.verQtValue = 50800 - assert nwGUI.docEditor.getText() == "### New Scene\n\nSome\ntext.\nMore text.\n" - nwGUI.mainConf.verQtValue = verQtValue # Check Propertoes assert nwGUI.docEditor.docChanged() is True @@ -250,7 +247,7 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal): nwGUI.docEditor.setDocumentChanged(True) assert nwGUI.docEditor._docChanged is True - # qtbot.stopForInteraction() + # qtbot.stop() # END Test testGuiEditor_MetaData From 30661130ca81fc5ff48b12bc7975b69a051c1521 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 15 Oct 2022 22:56:18 +0200 Subject: [PATCH 3/5] Ignore coverage of lines of old Qt versions --- novelwriter/gui/doceditor.py | 3 ++- novelwriter/gui/docviewer.py | 4 ++-- novelwriter/tools/build.py | 2 +- tests/test_base/test_base_config.py | 6 ------ tests/test_gui/test_gui_mainmenu.py | 10 ++-------- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 5454341f..2c908c2f 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2474,7 +2474,8 @@ class GuiDocEditSearch(QFrame): self._alertSearchValid(theRegEx.isValid()) return theRegEx - else: # >= 50300 to < 51300 + else: # pragma: no cover + # >= 50300 to < 51300 if self.isCaseSense: rxOpt = Qt.CaseSensitive else: diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index f4413805..5c9ae4ab 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -152,7 +152,7 @@ class GuiDocViewer(QTextBrowser): # Refresh the tab stops if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth()) - else: + else: # pragma: no cover self.setTabStopWidth(self.mainConf.getTabWidth()) # If we have a document open, we should reload it in case the font changed @@ -195,7 +195,7 @@ class GuiDocViewer(QTextBrowser): # Refresh the tab stops if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth()) - else: + else: # pragma: no cover self.setTabStopWidth(self.mainConf.getTabWidth()) # Must be before setHtml diff --git a/novelwriter/tools/build.py b/novelwriter/tools/build.py index 6260b039..1518a079 100644 --- a/novelwriter/tools/build.py +++ b/novelwriter/tools/build.py @@ -1267,7 +1267,7 @@ class GuiBuildNovelDocView(QTextBrowser): # Set the tab stops if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth()) - else: + else: # pragma: no cover self.setTabStopWidth(self.mainConf.getTabWidth()) docPalette = self.palette() diff --git a/tests/test_base/test_base_config.py b/tests/test_base/test_base_config.py index 83ff3160..49387ab0 100644 --- a/tests/test_base/test_base_config.py +++ b/tests/test_base/test_base_config.py @@ -96,12 +96,6 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir): # Let the config class figure out the path with monkeypatch.context() as mp: mp.setattr("PyQt5.QtCore.QStandardPaths.writableLocation", lambda *a: fncDir) - tstConf.verQtValue = 50600 - tstConf.initConfig() - assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) - assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) - assert not os.path.isfile(confFile) - tstConf.verQtValue = 50000 tstConf.initConfig() assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) diff --git a/tests/test_gui/test_gui_mainmenu.py b/tests/test_gui/test_gui_mainmenu.py index 8aeb6cd4..c4bf2dd3 100644 --- a/tests/test_gui/test_gui_mainmenu.py +++ b/tests/test_gui/test_gui_mainmenu.py @@ -566,10 +566,7 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd): nwGUI.docEditor.clear() nwGUI.mainMenu.aInsNBSpace.activate(QAction.Trigger) - if nwGUI.mainConf.verQtValue >= 50900: - assert nwGUI.docEditor.getText() == nwUnicode.U_NBSP - else: - assert nwGUI.docEditor.getText() == " " + assert nwGUI.docEditor.getText() == nwUnicode.U_NBSP nwGUI.docEditor.clear() nwGUI.mainMenu.aInsThinSpace.activate(QAction.Trigger) @@ -577,10 +574,7 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd): nwGUI.docEditor.clear() nwGUI.mainMenu.aInsThinNBSpace.activate(QAction.Trigger) - if nwGUI.mainConf.verQtValue >= 50900: - assert nwGUI.docEditor.getText() == nwUnicode.U_THNBSP - else: - assert nwGUI.docEditor.getText() == " " + assert nwGUI.docEditor.getText() == nwUnicode.U_THNBSP nwGUI.docEditor.clear() ## From 97724054ec743dff7755c112c714902fa2734156 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 15 Oct 2022 23:05:43 +0200 Subject: [PATCH 4/5] Require at least Qt 5.10 instead --- novelwriter/__init__.py | 8 ++++---- novelwriter/gui/doceditor.py | 5 +---- novelwriter/gui/docviewer.py | 10 ++-------- novelwriter/tools/build.py | 5 +---- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/novelwriter/__init__.py b/novelwriter/__init__.py index 5c13cde9..4ba051c1 100644 --- a/novelwriter/__init__.py +++ b/novelwriter/__init__.py @@ -214,14 +214,14 @@ def main(sysArgs=None): "At least Python 3.7 is required, found %s" % CONFIG.verPyString ) errorCode |= 0x04 - if CONFIG.verQtValue < 50900: + if CONFIG.verQtValue < 51000: errorData.append( - "At least Qt5 version 5.9 is required, found %s" % CONFIG.verQtString + "At least Qt5 version 5.10 is required, found %s" % CONFIG.verQtString ) errorCode |= 0x08 - if CONFIG.verPyQtValue < 50900: + if CONFIG.verPyQtValue < 51000: errorData.append( - "At least PyQt5 version 5.9 is required, found %s" % CONFIG.verPyQtString + "At least PyQt5 version 5.10 is required, found %s" % CONFIG.verPyQtString ) errorCode |= 0x10 diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 2c908c2f..cc96b9e9 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -303,10 +303,7 @@ class GuiDocEditor(QTextEdit): self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Refresh the tab stops - if self.mainConf.verQtValue >= 51000: - self.setTabStopDistance(self.mainConf.getTabWidth()) - else: # pragma: no cover - self.setTabStopWidth(self.mainConf.getTabWidth()) + self.setTabStopDistance(self.mainConf.getTabWidth()) # Initialise the syntax highlighter self.highLight.initHighlighter() diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 5c9ae4ab..1f14f165 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -150,10 +150,7 @@ class GuiDocViewer(QTextBrowser): self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Refresh the tab stops - if self.mainConf.verQtValue >= 51000: - self.setTabStopDistance(self.mainConf.getTabWidth()) - else: # pragma: no cover - self.setTabStopWidth(self.mainConf.getTabWidth()) + self.setTabStopDistance(self.mainConf.getTabWidth()) # If we have a document open, we should reload it in case the font changed if self._docHandle is not None: @@ -193,10 +190,7 @@ class GuiDocViewer(QTextBrowser): return False # Refresh the tab stops - if self.mainConf.verQtValue >= 51000: - self.setTabStopDistance(self.mainConf.getTabWidth()) - else: # pragma: no cover - self.setTabStopWidth(self.mainConf.getTabWidth()) + self.setTabStopDistance(self.mainConf.getTabWidth()) # Must be before setHtml if updateHistory: diff --git a/novelwriter/tools/build.py b/novelwriter/tools/build.py index 1518a079..d2b3faf7 100644 --- a/novelwriter/tools/build.py +++ b/novelwriter/tools/build.py @@ -1265,10 +1265,7 @@ class GuiBuildNovelDocView(QTextBrowser): self.setFont(theFont) # Set the tab stops - if self.mainConf.verQtValue >= 51000: - self.setTabStopDistance(self.mainConf.getTabWidth()) - else: # pragma: no cover - self.setTabStopWidth(self.mainConf.getTabWidth()) + self.setTabStopDistance(self.mainConf.getTabWidth()) docPalette = self.palette() docPalette.setColor(QPalette.Base, QColor(255, 255, 255)) From f5dcad8725b0cf381da758e4daec8fbaac7cdd9a Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 15 Oct 2022 23:14:34 +0200 Subject: [PATCH 5/5] Update references to Qt version in the docs --- docs/source/int_source.rst | 2 +- docs/source/tech_locations.rst | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/source/int_source.rst b/docs/source/int_source.rst index 86fb3b1e..879700a5 100644 --- a/docs/source/int_source.rst +++ b/docs/source/int_source.rst @@ -34,7 +34,7 @@ The following Python packages are needed to run novelWriter: * ``lxml`` – needed for full XML support. * ``PyEnchant`` – needed for spell checking (optional). -PyQt/Qt should be at least 5.3, but ideally 5.10 or higher for nearly all features to work. For +PyQt/Qt should be at least 5.10, but ideally 5.13 or higher for nearly all features to work. For instance, searching using regular expressions with full Unicode support requires 5.13. There is no known minimum version requirement for package ``lxml``, but the code was originally written with 4.2, which is therefore set as the minimum. It may work on lower versions. You have to test it. diff --git a/docs/source/tech_locations.rst b/docs/source/tech_locations.rst index 8f1d4db6..f3003e37 100644 --- a/docs/source/tech_locations.rst +++ b/docs/source/tech_locations.rst @@ -40,8 +40,7 @@ Application Data novelWriter also stores a bit of data that is generated by the user's actions. This includes the list of recent projects form the :guilabel:`Open Project` dialog. Custom themes are also saved -here. The system paths are provided by the Qt QStandardPaths_ class and its AppDataLocation value -on Qt 5.4 or greater, or DataLocation for earlier versions. +here. The system paths are provided by the Qt QStandardPaths_ class and its AppDataLocation. The standard paths are: