From f8c1ee90ce4f645c8dc9a8b276dadfbbaa4542ff Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:02:48 +0200 Subject: [PATCH 1/7] Reimplement the reject slot for the parent dialog class --- novelwriter/extensions/modified.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/novelwriter/extensions/modified.py b/novelwriter/extensions/modified.py index 120484970..f07e25538 100644 --- a/novelwriter/extensions/modified.py +++ b/novelwriter/extensions/modified.py @@ -30,8 +30,8 @@ from enum import Enum from typing import TYPE_CHECKING -from PyQt5.QtCore import QSize, Qt -from PyQt5.QtGui import QKeyEvent, QKeySequence, QWheelEvent +from PyQt5.QtCore import QSize, Qt, pyqtSlot +from PyQt5.QtGui import QWheelEvent from PyQt5.QtWidgets import ( QApplication, QComboBox, QDialog, QDoubleSpinBox, QSpinBox, QToolButton, QWidget @@ -54,11 +54,11 @@ def softDelete(self) -> None: self.setParent(None) # type: ignore return - def keyPressEvent(self, event: QKeyEvent) -> None: - """Overload keyPressEvent and forward escape to close.""" - if event.matches(QKeySequence.StandardKey.Cancel): - self.close() - event.ignore() + @pyqtSlot() + def reject(self) -> None: + """Overload the reject slot and also call close.""" + super().reject() + self.close() return From 29b61c07b05ae85d3bde2041f5eba7b5da8af879 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:03:20 +0200 Subject: [PATCH 2/7] Restore the keyPressEvent overload for Preferences --- novelwriter/dialogs/preferences.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index fcd463b5c..d08498b2e 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -27,7 +27,7 @@ import logging from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot -from PyQt5.QtGui import QCloseEvent +from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence from PyQt5.QtWidgets import ( QAbstractButton, QCompleter, QDialogButtonBox, QFileDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget @@ -770,6 +770,16 @@ def closeEvent(self, event: QCloseEvent) -> None: self.softDelete() return + def keyPressEvent(self, event: QKeyEvent) -> None: + """Overload keyPressEvent and only accept escape. The main + purpose here is to prevent Enter/Return from closing the dialog + as it is used for the search box. + """ + if event.matches(QKeySequence.StandardKey.Cancel): + self.close() + event.ignore() + return + ## # Private Slots ## From 811db81a86b47988b20233fb83589c5ef32b0189 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:04:10 +0200 Subject: [PATCH 3/7] Use the reject slot for dialogs since close is not actually a slot --- novelwriter/dialogs/about.py | 2 +- novelwriter/dialogs/projectsettings.py | 2 +- novelwriter/dialogs/wordlist.py | 2 +- novelwriter/tools/dictionaries.py | 8 +------- novelwriter/tools/lipsum.py | 11 +++-------- novelwriter/tools/noveldetails.py | 2 +- 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/novelwriter/dialogs/about.py b/novelwriter/dialogs/about.py index 226d0054f..628c4e4ef 100644 --- a/novelwriter/dialogs/about.py +++ b/novelwriter/dialogs/about.py @@ -85,7 +85,7 @@ def __init__(self, parent: QWidget) -> None: # Buttons self.btnBox = QDialogButtonBox(QtDialogClose, self) - self.btnBox.rejected.connect(self.close) + self.btnBox.rejected.connect(self.reject) # Assemble self.innerBox = QVBoxLayout() diff --git a/novelwriter/dialogs/projectsettings.py b/novelwriter/dialogs/projectsettings.py index 010f50e19..c8d72d884 100644 --- a/novelwriter/dialogs/projectsettings.py +++ b/novelwriter/dialogs/projectsettings.py @@ -92,7 +92,7 @@ def __init__(self, parent: QWidget, gotoPage: int = PAGE_SETTINGS) -> None: # Buttons self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogCancel, self) self.buttonBox.accepted.connect(self._doSave) - self.buttonBox.rejected.connect(self.close) + self.buttonBox.rejected.connect(self.reject) # Content SHARED.project.countStatus() diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index 51ce49b60..8f3f53f5d 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -109,7 +109,7 @@ def __init__(self, parent: QWidget) -> None: # Buttons self.buttonBox = QDialogButtonBox(QtDialogSave | QtDialogClose, self) self.buttonBox.accepted.connect(self._doSave) - self.buttonBox.rejected.connect(self.close) + self.buttonBox.rejected.connect(self.reject) # Assemble self.outerBox = QVBoxLayout() diff --git a/novelwriter/tools/dictionaries.py b/novelwriter/tools/dictionaries.py index f56e57619..b495ea313 100644 --- a/novelwriter/tools/dictionaries.py +++ b/novelwriter/tools/dictionaries.py @@ -109,7 +109,7 @@ def __init__(self, parent: QWidget) -> None: # Buttons self.buttonBox = QDialogButtonBox(QtDialogClose, self) - self.buttonBox.rejected.connect(self._doClose) + self.buttonBox.rejected.connect(self.reject) # Assemble self.innerBox = QVBoxLayout() @@ -220,12 +220,6 @@ def _doOpenInstallLocation(self) -> None: SHARED.error("Path not found.") return - @pyqtSlot() - def _doClose(self) -> None: - """Close the dialog.""" - self.close() - return - ## # Internal Functions ## diff --git a/novelwriter/tools/lipsum.py b/novelwriter/tools/lipsum.py index 9296d5b8a..9d05c51ce 100644 --- a/novelwriter/tools/lipsum.py +++ b/novelwriter/tools/lipsum.py @@ -26,7 +26,7 @@ import logging import random -from PyQt5.QtCore import Qt, pyqtSlot +from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import ( QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel, QSpinBox, QVBoxLayout, QWidget @@ -48,13 +48,10 @@ def __init__(self, parent: QWidget) -> None: logger.debug("Create: GuiLipsum") self.setObjectName("GuiLipsum") - if CONFIG.osDarwin: - self.setWindowFlag(Qt.WindowType.Tool) + self.setWindowTitle(self.tr("Insert Placeholder Text")) self._lipsumText = "" - self.setWindowTitle(self.tr("Insert Placeholder Text")) - vSp = CONFIG.pxInt(4) nPx = CONFIG.pxInt(64) @@ -96,7 +93,7 @@ def __init__(self, parent: QWidget) -> None: # Buttons self.buttonBox = QDialogButtonBox(self) - self.buttonBox.rejected.connect(self.close) + self.buttonBox.rejected.connect(self.reject) self.btnClose = self.buttonBox.addButton(QtDialogClose) self.btnClose.setAutoDefault(False) @@ -105,8 +102,6 @@ def __init__(self, parent: QWidget) -> None: self.btnInsert.clicked.connect(self._doInsert) self.btnInsert.setAutoDefault(False) - self.rejected.connect(self.close) - # Assemble self.outerBox = QVBoxLayout() self.outerBox.addLayout(self.innerBox) diff --git a/novelwriter/tools/noveldetails.py b/novelwriter/tools/noveldetails.py index 9362c6406..cd7f5f38e 100644 --- a/novelwriter/tools/noveldetails.py +++ b/novelwriter/tools/noveldetails.py @@ -97,7 +97,7 @@ def __init__(self, parent: QWidget) -> None: # Buttons self.buttonBox = QDialogButtonBox(QtDialogClose, self) - self.buttonBox.rejected.connect(self.close) + self.buttonBox.rejected.connect(self.reject) # Assemble self.topBox = QHBoxLayout() From 255a4a327e72d4eada84bbcefb6a4c36e6d38694 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:05:13 +0200 Subject: [PATCH 4/7] Update tests --- tests/test_ext/test_ext_modified.py | 23 ++++++++++++++++++--- tests/test_tools/test_tools_dictionaries.py | 2 -- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/test_ext/test_ext_modified.py b/tests/test_ext/test_ext_modified.py index 2158bf606..8bc1b5b45 100644 --- a/tests/test_ext/test_ext_modified.py +++ b/tests/test_ext/test_ext_modified.py @@ -22,10 +22,12 @@ import pytest -from PyQt5.QtCore import QPoint, QPointF, Qt -from PyQt5.QtGui import QWheelEvent +from PyQt5.QtCore import QEvent, QPoint, QPointF, Qt +from PyQt5.QtGui import QKeyEvent, QWheelEvent +from PyQt5.QtWidgets import QWidget -from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox +from novelwriter.extensions.modified import NComboBox, NDialog, NDoubleSpinBox, NSpinBox +from novelwriter.types import QtModNone, QtRejected from tests.tools import SimpleDialog @@ -47,6 +49,21 @@ def ignore(self): return +@pytest.mark.gui +def testExtModified_NDialog(qtbot, monkeypatch): + """Test the QDialog class.""" + widget = QWidget() + dialog = NDialog(widget) + assert dialog.parent() is widget + + dialog.softDelete() + assert dialog.parent() is None + + with qtbot.waitSignal(dialog.rejected, timeout=1000): + dialog.keyPressEvent(QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_Escape, QtModNone)) + assert dialog.result() == QtRejected + + @pytest.mark.gui def testExtModified_NComboBox(qtbot, monkeypatch): """Test the NComboBox class.""" diff --git a/tests/test_tools/test_tools_dictionaries.py b/tests/test_tools/test_tools_dictionaries.py index 933f7ed2a..699c715a1 100644 --- a/tests/test_tools/test_tools_dictionaries.py +++ b/tests/test_tools/test_tools_dictionaries.py @@ -152,6 +152,4 @@ def testToolDictionaries_Main(qtbot, monkeypatch, nwGUI, fncPath): "Additional dictionaries found: 2" ) - # Close - nwDicts._doClose() # qtbot.stop() From b76c866c9d4c11267b28e6df0e99997154eb26a4 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:10:59 +0200 Subject: [PATCH 5/7] Fix typo in docstring --- tests/test_ext/test_ext_modified.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ext/test_ext_modified.py b/tests/test_ext/test_ext_modified.py index 8bc1b5b45..65865b273 100644 --- a/tests/test_ext/test_ext_modified.py +++ b/tests/test_ext/test_ext_modified.py @@ -51,7 +51,7 @@ def ignore(self): @pytest.mark.gui def testExtModified_NDialog(qtbot, monkeypatch): - """Test the QDialog class.""" + """Test the NDialog class.""" widget = QWidget() dialog = NDialog(widget) assert dialog.parent() is widget From eed4721ef072b0e0a2ea3e2c7442ffd180f997a6 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:25:20 +0200 Subject: [PATCH 6/7] Make lipusm test more robust --- tests/test_tools/test_tools_lipsum.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_tools/test_tools_lipsum.py b/tests/test_tools/test_tools_lipsum.py index 8720a3764..5c4e263fc 100644 --- a/tests/test_tools/test_tools_lipsum.py +++ b/tests/test_tools/test_tools_lipsum.py @@ -62,7 +62,8 @@ def testToolLipsum_Main(qtbot, monkeypatch, nwGUI, projPath, mockRnd): with monkeypatch.context() as mp: mp.setattr(GuiLipsum, "exec", lambda *a: None) mp.setattr(GuiLipsum, "lipsumText", "FooBar") - nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger) + with qtbot.waitSignal(nwGUI.docEditor.textChanged): + nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "### New Scene\n\nFooBar" # qtbot.stop() From 8a9b038d56fd9f15fe6a322f2a753556f5e7b3fc Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:44:47 +0200 Subject: [PATCH 7/7] Use the direct insert call --- tests/test_tools/test_tools_lipsum.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_tools/test_tools_lipsum.py b/tests/test_tools/test_tools_lipsum.py index 5c4e263fc..261afeb7f 100644 --- a/tests/test_tools/test_tools_lipsum.py +++ b/tests/test_tools/test_tools_lipsum.py @@ -25,6 +25,7 @@ from PyQt5.QtWidgets import QAction from novelwriter import SHARED +from novelwriter.enum import nwDocInsert from novelwriter.tools.lipsum import GuiLipsum from tests.tools import C, buildTestProject @@ -63,7 +64,7 @@ def testToolLipsum_Main(qtbot, monkeypatch, nwGUI, projPath, mockRnd): mp.setattr(GuiLipsum, "exec", lambda *a: None) mp.setattr(GuiLipsum, "lipsumText", "FooBar") with qtbot.waitSignal(nwGUI.docEditor.textChanged): - nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger) + nwGUI.docEditor.insertText(nwDocInsert.LIPSUM) assert nwGUI.docEditor.getText() == "### New Scene\n\nFooBar" # qtbot.stop()