Merge branch 'main' into release_2.0rc1

This commit is contained in:
Veronica Berglyd Olsen
2022-10-15 23:30:43 +02:00
10 changed files with 27 additions and 66 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ The following Python packages are needed to run novelWriter:
* ``lxml`` needed for full XML support. * ``lxml`` needed for full XML support.
* ``PyEnchant`` needed for spell checking (optional). * ``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 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 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. 4.2, which is therefore set as the minimum. It may work on lower versions. You have to test it.
+1 -2
View File
@@ -40,8 +40,7 @@ Application Data
novelWriter also stores a bit of data that is generated by the user's actions. This includes the 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 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 here. The system paths are provided by the Qt QStandardPaths_ class and its AppDataLocation.
on Qt 5.4 or greater, or DataLocation for earlier versions.
The standard paths are: The standard paths are:
+4 -4
View File
@@ -214,14 +214,14 @@ def main(sysArgs=None):
"At least Python 3.7 is required, found %s" % CONFIG.verPyString "At least Python 3.7 is required, found %s" % CONFIG.verPyString
) )
errorCode |= 0x04 errorCode |= 0x04
if CONFIG.verQtValue < 50300: if CONFIG.verQtValue < 51000:
errorData.append( errorData.append(
"At least Qt5 version 5.3 is required, found %s" % CONFIG.verQtString "At least Qt5 version 5.10 is required, found %s" % CONFIG.verQtString
) )
errorCode |= 0x08 errorCode |= 0x08
if CONFIG.verPyQtValue < 50300: if CONFIG.verPyQtValue < 51000:
errorData.append( errorData.append(
"At least PyQt5 version 5.3 is required, found %s" % CONFIG.verPyQtString "At least PyQt5 version 5.10 is required, found %s" % CONFIG.verPyQtString
) )
errorCode |= 0x10 errorCode |= 0x10
+3 -11
View File
@@ -220,8 +220,8 @@ class Config:
self.osUnknown = True self.osUnknown = True
# Other System Info # Other System Info
self.hostName = "Unknown" self.hostName = QSysInfo.machineHostName()
self.kernelVer = "Unknown" self.kernelVer = QSysInfo.kernelVersion()
# Packages # Packages
self.hasEnchant = False # The pyenchant package self.hasEnchant = False # The pyenchant package
@@ -264,10 +264,7 @@ class Config:
self.confPath = confPath self.confPath = confPath
if dataPath is None: if dataPath is None:
if self.verQtValue >= 50400: dataRoot = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)
dataRoot = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)
else:
dataRoot = QStandardPaths.writableLocation(QStandardPaths.DataLocation)
self.dataPath = os.path.join(os.path.abspath(dataRoot), self.appHandle) self.dataPath = os.path.join(os.path.abspath(dataRoot), self.appHandle)
else: else:
logger.info("Setting data path from alternative path: %s", dataPath) logger.info("Setting data path from alternative path: %s", dataPath)
@@ -347,11 +344,6 @@ class Config:
self.errData.append(formatException(exc)) self.errData.append(formatException(exc))
self.dataPath = None self.dataPath = None
# Host and Kernel
if self.verQtValue >= 50600:
self.hostName = QSysInfo.machineHostName()
self.kernelVer = QSysInfo.kernelVersion()
# Load recent projects cache # Load recent projects cache
self.loadRecentCache() self.loadRecentCache()
+10 -16
View File
@@ -303,10 +303,7 @@ class GuiDocEditor(QTextEdit):
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
# Refresh the tab stops # Refresh the tab stops
if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth())
self.setTabStopDistance(self.mainConf.getTabWidth())
else: # pragma: no cover
self.setTabStopWidth(self.mainConf.getTabWidth())
# Initialise the syntax highlighter # Initialise the syntax highlighter
self.highLight.initHighlighter() self.highLight.initHighlighter()
@@ -604,19 +601,15 @@ class GuiDocEditor(QTextEdit):
## ##
def getText(self): def getText(self):
"""Get the text content of the current document. This method """Get the text content of the current document. This method uses
uses QTextEdit->toPlainText for Qt versions lower than 5.9, and QTextDocument->toRawText instead of toPlainText(). The former preserves
the QTextDocument->toRawText for higher version. The latter non-breaking spaces, the latter does not. We still want to get rid of
preserves non-breaking spaces, which the former does not. page and line separators though.
We still want to get rid of page and line separators though.
See: https://doc.qt.io/qt-5/qtextdocument.html#toPlainText See: https://doc.qt.io/qt-5/qtextdocument.html#toPlainText
""" """
if self.mainConf.verQtValue >= 50900: theText = self.document().toRawText()
theText = self.document().toRawText() theText = theText.replace(nwUnicode.U_LSEP, "\n") # Line separators
theText = theText.replace(nwUnicode.U_LSEP, "\n") # Line separators theText = theText.replace(nwUnicode.U_PSEP, "\n") # Paragraph separators
theText = theText.replace(nwUnicode.U_PSEP, "\n") # Paragraph separators
else:
theText = self.toPlainText()
return theText return theText
def getCursorPosition(self): def getCursorPosition(self):
@@ -2478,7 +2471,8 @@ class GuiDocEditSearch(QFrame):
self._alertSearchValid(theRegEx.isValid()) self._alertSearchValid(theRegEx.isValid())
return theRegEx return theRegEx
else: # >= 50300 to < 51300 else: # pragma: no cover
# >= 50300 to < 51300
if self.isCaseSense: if self.isCaseSense:
rxOpt = Qt.CaseSensitive rxOpt = Qt.CaseSensitive
else: else:
+2 -8
View File
@@ -150,10 +150,7 @@ class GuiDocViewer(QTextBrowser):
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
# Refresh the tab stops # Refresh the tab stops
if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth())
self.setTabStopDistance(self.mainConf.getTabWidth())
else:
self.setTabStopWidth(self.mainConf.getTabWidth())
# If we have a document open, we should reload it in case the font changed # If we have a document open, we should reload it in case the font changed
if self._docHandle is not None: if self._docHandle is not None:
@@ -193,10 +190,7 @@ class GuiDocViewer(QTextBrowser):
return False return False
# Refresh the tab stops # Refresh the tab stops
if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth())
self.setTabStopDistance(self.mainConf.getTabWidth())
else:
self.setTabStopWidth(self.mainConf.getTabWidth())
# Must be before setHtml # Must be before setHtml
if updateHistory: if updateHistory:
+1 -4
View File
@@ -1265,10 +1265,7 @@ class GuiBuildNovelDocView(QTextBrowser):
self.setFont(theFont) self.setFont(theFont)
# Set the tab stops # Set the tab stops
if self.mainConf.verQtValue >= 51000: self.setTabStopDistance(self.mainConf.getTabWidth())
self.setTabStopDistance(self.mainConf.getTabWidth())
else:
self.setTabStopWidth(self.mainConf.getTabWidth())
docPalette = self.palette() docPalette = self.palette()
docPalette.setColor(QPalette.Base, QColor(255, 255, 255)) docPalette.setColor(QPalette.Base, QColor(255, 255, 255))
-6
View File
@@ -96,12 +96,6 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
# Let the config class figure out the path # Let the config class figure out the path
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setattr("PyQt5.QtCore.QStandardPaths.writableLocation", lambda *a: fncDir) 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() tstConf.initConfig()
assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle)
assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle)
+3 -6
View File
@@ -213,7 +213,8 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal):
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
# Get Text # 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 = ( newText = (
"### New Scene\u2029\u2029" "### New Scene\u2029\u2029"
"Some\u2028text.\u2029" "Some\u2028text.\u2029"
@@ -221,10 +222,6 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal):
) )
assert nwGUI.docEditor.replaceText(newText) assert nwGUI.docEditor.replaceText(newText)
assert nwGUI.docEditor.getText() == "### New Scene\n\nSome\ntext.\nMore\u00a0text.\n" 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 # Check Propertoes
assert nwGUI.docEditor.docChanged() is True assert nwGUI.docEditor.docChanged() is True
@@ -250,7 +247,7 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal):
nwGUI.docEditor.setDocumentChanged(True) nwGUI.docEditor.setDocumentChanged(True)
assert nwGUI.docEditor._docChanged is True assert nwGUI.docEditor._docChanged is True
# qtbot.stopForInteraction() # qtbot.stop()
# END Test testGuiEditor_MetaData # END Test testGuiEditor_MetaData
+2 -8
View File
@@ -566,10 +566,7 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd):
nwGUI.docEditor.clear() nwGUI.docEditor.clear()
nwGUI.mainMenu.aInsNBSpace.activate(QAction.Trigger) nwGUI.mainMenu.aInsNBSpace.activate(QAction.Trigger)
if nwGUI.mainConf.verQtValue >= 50900: assert nwGUI.docEditor.getText() == nwUnicode.U_NBSP
assert nwGUI.docEditor.getText() == nwUnicode.U_NBSP
else:
assert nwGUI.docEditor.getText() == " "
nwGUI.docEditor.clear() nwGUI.docEditor.clear()
nwGUI.mainMenu.aInsThinSpace.activate(QAction.Trigger) nwGUI.mainMenu.aInsThinSpace.activate(QAction.Trigger)
@@ -577,10 +574,7 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncDir, fncProj, mockRnd):
nwGUI.docEditor.clear() nwGUI.docEditor.clear()
nwGUI.mainMenu.aInsThinNBSpace.activate(QAction.Trigger) nwGUI.mainMenu.aInsThinNBSpace.activate(QAction.Trigger)
if nwGUI.mainConf.verQtValue >= 50900: assert nwGUI.docEditor.getText() == nwUnicode.U_THNBSP
assert nwGUI.docEditor.getText() == nwUnicode.U_THNBSP
else:
assert nwGUI.docEditor.getText() == " "
nwGUI.docEditor.clear() nwGUI.docEditor.clear()
## ##