Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase minimum Qt version to 5.10 #1174

Merged
merged 5 commits into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/int_source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 1 addition & 2 deletions docs/source/tech_locations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
8 changes: 4 additions & 4 deletions novelwriter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 < 51000:
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
if CONFIG.verPyQtValue < 50300:
if CONFIG.verPyQtValue < 51000:
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

Expand Down
14 changes: 3 additions & 11 deletions novelwriter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ def __init__(self):
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
Expand Down Expand Up @@ -264,10 +264,7 @@ def initConfig(self, confPath=None, dataPath=None):
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)
Expand Down Expand Up @@ -347,11 +344,6 @@ def initConfig(self, confPath=None, dataPath=None):
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()

Expand Down
26 changes: 10 additions & 16 deletions novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,7 @@ def initEditor(self):
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()
Expand Down Expand Up @@ -604,19 +601,15 @@ def isEmpty(self):
##

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):
Expand Down Expand Up @@ -2478,7 +2471,8 @@ def getSearchObject(self):
self._alertSearchValid(theRegEx.isValid())
return theRegEx

else: # >= 50300 to < 51300
else: # pragma: no cover
# >= 50300 to < 51300
if self.isCaseSense:
rxOpt = Qt.CaseSensitive
else:
Expand Down
10 changes: 2 additions & 8 deletions novelwriter/gui/docviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,7 @@ def initViewer(self):
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

# Refresh the tab stops
if self.mainConf.verQtValue >= 51000:
self.setTabStopDistance(self.mainConf.getTabWidth())
else:
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:
Expand Down Expand Up @@ -193,10 +190,7 @@ def loadText(self, tHandle, updateHistory=True):
return False

# Refresh the tab stops
if self.mainConf.verQtValue >= 51000:
self.setTabStopDistance(self.mainConf.getTabWidth())
else:
self.setTabStopWidth(self.mainConf.getTabWidth())
self.setTabStopDistance(self.mainConf.getTabWidth())

# Must be before setHtml
if updateHistory:
Expand Down
5 changes: 1 addition & 4 deletions novelwriter/tools/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1265,10 +1265,7 @@ def __init__(self, mainGui, theProject):
self.setFont(theFont)

# Set the tab stops
if self.mainConf.verQtValue >= 51000:
self.setTabStopDistance(self.mainConf.getTabWidth())
else:
self.setTabStopWidth(self.mainConf.getTabWidth())
self.setTabStopDistance(self.mainConf.getTabWidth())

docPalette = self.palette()
docPalette.setColor(QPalette.Base, QColor(255, 255, 255))
Expand Down
6 changes: 0 additions & 6 deletions tests/test_base/test_base_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 3 additions & 6 deletions tests/test_gui/test_gui_doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,18 +213,15 @@ 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"
"More\u00a0text.\u2029"
)
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
Expand All @@ -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

Expand Down
10 changes: 2 additions & 8 deletions tests/test_gui/test_gui_mainmenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,21 +566,15 @@ 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)
assert nwGUI.docEditor.getText() == nwUnicode.U_THSP
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()

##
Expand Down