diff --git a/novelwriter/dialogs/about.py b/novelwriter/dialogs/about.py index f22a8238..13d60d18 100644 --- a/novelwriter/dialogs/about.py +++ b/novelwriter/dialogs/about.py @@ -28,8 +28,8 @@ import novelwriter from datetime import datetime -from PyQt5.QtGui import QCursor -from PyQt5.QtCore import Qt, pyqtSlot +from PyQt5.QtGui import QCloseEvent, QCursor +from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( qApp, QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QTabWidget, QTextBrowser, QVBoxLayout, QWidget @@ -101,7 +101,7 @@ class GuiAbout(QDialog): # OK Button self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) - self.buttonBox.accepted.connect(self._doClose) + self.buttonBox.accepted.connect(self.close) self.outerBox.addLayout(self.innerBox) self.outerBox.addWidget(self.buttonBox) @@ -132,13 +132,12 @@ class GuiAbout(QDialog): return ## - # Private Slots + # Events ## - @pyqtSlot() - def _doClose(self) -> None: - """Close the dialog""" - self.close() + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the close event and perform cleanup.""" + event.accept() self.deleteLater() return diff --git a/novelwriter/dialogs/docmerge.py b/novelwriter/dialogs/docmerge.py index fe508221..e6a2aedd 100644 --- a/novelwriter/dialogs/docmerge.py +++ b/novelwriter/dialogs/docmerge.py @@ -26,7 +26,8 @@ from __future__ import annotations import logging -from PyQt5.QtCore import Qt, QSize +from PyQt5.QtGui import QCloseEvent +from PyQt5.QtCore import Qt, QSize, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QDialogButtonBox, QGridLayout, QLabel, QListWidget, QListWidgetItem, QVBoxLayout, QWidget @@ -125,10 +126,21 @@ class GuiDocMerge(QDialog): return self._data + ## + # Events + ## + + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the close event and perform cleanup.""" + event.accept() + self.deleteLater() + return + ## # Private Slots ## + @pyqtSlot() def _resetList(self) -> None: """Reset the content of the list box to its original state.""" logger.debug("Resetting list box content") diff --git a/novelwriter/dialogs/docsplit.py b/novelwriter/dialogs/docsplit.py index daf0dc29..172ff7e1 100644 --- a/novelwriter/dialogs/docsplit.py +++ b/novelwriter/dialogs/docsplit.py @@ -26,6 +26,7 @@ from __future__ import annotations import logging +from PyQt5.QtGui import QCloseEvent from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QComboBox, QDialog, QDialogButtonBox, QGridLayout, @@ -167,6 +168,7 @@ class GuiDocSplit(QDialog): self._data["docHierarchy"] = docHierarchy self._data["moveToTrash"] = moveToTrash + logger.debug("Saving State: GuiDocSplit") pOptions = SHARED.project.options pOptions.setValue("GuiDocSplit", "spLevel", spLevel) pOptions.setValue("GuiDocSplit", "intoFolder", intoFolder) @@ -174,6 +176,16 @@ class GuiDocSplit(QDialog): return self._data, self._text + ## + # Events + ## + + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the close event and perform cleanup.""" + event.accept() + self.deleteLater() + return + ## # Private Slots ## diff --git a/novelwriter/dialogs/editlabel.py b/novelwriter/dialogs/editlabel.py index 6cf11b03..6da4947a 100644 --- a/novelwriter/dialogs/editlabel.py +++ b/novelwriter/dialogs/editlabel.py @@ -88,6 +88,9 @@ class GuiEditLabel(QDialog): def getLabel(cls, parent: QWidget, text: str) -> tuple[str, bool]: cls = GuiEditLabel(parent, text=text) cls.exec_() - return cls.itemLabel, cls.result() == QDialog.Accepted + label = cls.itemLabel + accepted = cls.result() == QDialog.Accepted + cls.deleteLater() + return label, accepted # END Class GuiEditLabel diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 6d6943be..af167bdf 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -66,7 +66,7 @@ class GuiPreferences(NPagedDialog): self.addTab(self.tabAuto, self.tr("Automation")) self.addTab(self.tabQuote, self.tr("Quotes")) - self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) self.buttonBox.accepted.connect(self._doSave) self.buttonBox.rejected.connect(self._doClose) self.addControls(self.buttonBox) @@ -169,7 +169,7 @@ class GuiPreferencesGeneral(QWidget): minWidth = CONFIG.pxInt(200) # Select Locale - self.guiLocale = QComboBox() + self.guiLocale = QComboBox(self) self.guiLocale.setMinimumWidth(minWidth) theLangs = CONFIG.listLanguages(CONFIG.LANG_NW) for lang, langName in theLangs: @@ -187,7 +187,7 @@ class GuiPreferencesGeneral(QWidget): ) # Select Theme - self.guiTheme = QComboBox() + self.guiTheme = QComboBox(self) self.guiTheme.setMinimumWidth(minWidth) self.theThemes = SHARED.theme.listThemes() for themeDir, themeName in self.theThemes: @@ -203,7 +203,7 @@ class GuiPreferencesGeneral(QWidget): ) # Editor Theme - self.guiSyntax = QComboBox() + self.guiSyntax = QComboBox(self) self.guiSyntax.setMinimumWidth(CONFIG.pxInt(200)) self.theSyntaxes = SHARED.theme.listSyntax() for syntaxFile, syntaxName in self.theSyntaxes: @@ -219,11 +219,11 @@ class GuiPreferencesGeneral(QWidget): ) # Font Family - self.guiFont = QLineEdit() + self.guiFont = QLineEdit(self) self.guiFont.setReadOnly(True) self.guiFont.setFixedWidth(CONFIG.pxInt(162)) self.guiFont.setText(CONFIG.guiFont) - self.fontButton = QPushButton("...") + self.fontButton = QPushButton("...", self) self.fontButton.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("..."))) self.fontButton.clicked.connect(self._selectFont) self.mainForm.addRow( @@ -378,7 +378,7 @@ class GuiPreferencesProjects(QWidget): # Backup Path self.backupPath = CONFIG.backupPath() - self.backupGetPath = QPushButton(self.tr("Browse")) + self.backupGetPath = QPushButton(self.tr("Browse"), self) self.backupGetPath.clicked.connect(self._backupFolder) self.backupPathRow = self.mainForm.addRow( self.tr("Backup storage location"), @@ -421,7 +421,7 @@ class GuiPreferencesProjects(QWidget): ) # Inactive time for idle - self.userIdleTime = QDoubleSpinBox() + self.userIdleTime = QDoubleSpinBox(self) self.userIdleTime.setMinimum(0.5) self.userIdleTime.setMaximum(600.0) self.userIdleTime.setSingleStep(0.5) @@ -496,11 +496,11 @@ class GuiPreferencesDocuments(QWidget): self.mainForm.addGroupLabel(self.tr("Text Style")) # Font Family - self.textFont = QLineEdit() + self.textFont = QLineEdit(self) self.textFont.setReadOnly(True) self.textFont.setFixedWidth(CONFIG.pxInt(162)) self.textFont.setText(CONFIG.textFont) - self.fontButton = QPushButton("...") + self.fontButton = QPushButton("...", self) self.fontButton.setMaximumWidth(int(2.5*SHARED.theme.getTextWidth("..."))) self.fontButton.clicked.connect(self._selectFont) self.mainForm.addRow( @@ -960,7 +960,7 @@ class GuiPreferencesAutomation(QWidget): self.mainForm.addGroupLabel(self.tr("Automatic Padding")) # Pad Before - self.fmtPadBefore = QLineEdit() + self.fmtPadBefore = QLineEdit(self) self.fmtPadBefore.setMaxLength(32) self.fmtPadBefore.setText(CONFIG.fmtPadBefore) self.mainForm.addRow( @@ -970,7 +970,7 @@ class GuiPreferencesAutomation(QWidget): ) # Pad After - self.fmtPadAfter = QLineEdit() + self.fmtPadAfter = QLineEdit(self) self.fmtPadAfter.setMaxLength(32) self.fmtPadAfter.setText(CONFIG.fmtPadAfter) self.mainForm.addRow( @@ -1046,13 +1046,13 @@ class GuiPreferencesQuotes(QWidget): self.quoteSym = {} # Single Quote Style - self.quoteSym["SO"] = QLineEdit() + self.quoteSym["SO"] = QLineEdit(self) self.quoteSym["SO"].setMaxLength(1) self.quoteSym["SO"].setReadOnly(True) self.quoteSym["SO"].setFixedWidth(qWidth) self.quoteSym["SO"].setAlignment(Qt.AlignCenter) self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen) - self.btnSingleStyleO = QPushButton("...") + self.btnSingleStyleO = QPushButton("...", self) self.btnSingleStyleO.setMaximumWidth(bWidth) self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO")) self.mainForm.addRow( @@ -1062,13 +1062,13 @@ class GuiPreferencesQuotes(QWidget): button=self.btnSingleStyleO ) - self.quoteSym["SC"] = QLineEdit() + self.quoteSym["SC"] = QLineEdit(self) self.quoteSym["SC"].setMaxLength(1) self.quoteSym["SC"].setReadOnly(True) self.quoteSym["SC"].setFixedWidth(qWidth) self.quoteSym["SC"].setAlignment(Qt.AlignCenter) self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose) - self.btnSingleStyleC = QPushButton("...") + self.btnSingleStyleC = QPushButton("...", self) self.btnSingleStyleC.setMaximumWidth(bWidth) self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC")) self.mainForm.addRow( @@ -1079,13 +1079,13 @@ class GuiPreferencesQuotes(QWidget): ) # Double Quote Style - self.quoteSym["DO"] = QLineEdit() + self.quoteSym["DO"] = QLineEdit(self) self.quoteSym["DO"].setMaxLength(1) self.quoteSym["DO"].setReadOnly(True) self.quoteSym["DO"].setFixedWidth(qWidth) self.quoteSym["DO"].setAlignment(Qt.AlignCenter) self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen) - self.btnDoubleStyleO = QPushButton("...") + self.btnDoubleStyleO = QPushButton("...", self) self.btnDoubleStyleO.setMaximumWidth(bWidth) self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO")) self.mainForm.addRow( @@ -1095,13 +1095,13 @@ class GuiPreferencesQuotes(QWidget): button=self.btnDoubleStyleO ) - self.quoteSym["DC"] = QLineEdit() + self.quoteSym["DC"] = QLineEdit(self) self.quoteSym["DC"].setMaxLength(1) self.quoteSym["DC"].setReadOnly(True) self.quoteSym["DC"].setFixedWidth(qWidth) self.quoteSym["DC"].setAlignment(Qt.AlignCenter) self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose) - self.btnDoubleStyleC = QPushButton("...") + self.btnDoubleStyleC = QPushButton("...", self) self.btnDoubleStyleC.setMaximumWidth(bWidth) self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC")) self.mainForm.addRow( diff --git a/novelwriter/dialogs/projdetails.py b/novelwriter/dialogs/projdetails.py index 272a20a4..6747f522 100644 --- a/novelwriter/dialogs/projdetails.py +++ b/novelwriter/dialogs/projdetails.py @@ -26,7 +26,7 @@ from __future__ import annotations import math import logging -from PyQt5.QtGui import QFont +from PyQt5.QtGui import QCloseEvent, QFont from PyQt5.QtCore import Qt, QSize, pyqtSlot from PyQt5.QtWidgets import ( QAbstractItemView, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel, @@ -89,6 +89,16 @@ class GuiProjectDetails(NPagedDialog): self.tabContents.updateValues() return + ## + # Events + ## + + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the close event and perform cleanup.""" + event.accept() + self.deleteLater() + return + ## # Private Slots ## @@ -98,7 +108,6 @@ class GuiProjectDetails(NPagedDialog): """Save settings and close the dialog.""" self._saveGuiSettings() self.close() - self.deleteLater() return ## @@ -121,6 +130,7 @@ class GuiProjectDetails(NPagedDialog): countFrom = self.tabContents.poValue.value() clearDouble = self.tabContents.dblValue.isChecked() + logger.debug("Saving State: GuiProjectDetails") pOptions = SHARED.project.options pOptions.setValue("GuiProjectDetails", "winWidth", winWidth) pOptions.setValue("GuiProjectDetails", "winHeight", winHeight) diff --git a/novelwriter/dialogs/projsettings.py b/novelwriter/dialogs/projsettings.py index 20b11c53..06a3f850 100644 --- a/novelwriter/dialogs/projsettings.py +++ b/novelwriter/dialogs/projsettings.py @@ -173,6 +173,7 @@ class GuiProjectSettings(NPagedDialog): statusColW = CONFIG.rpxInt(self.tabStatus.listBox.columnWidth(0)) importColW = CONFIG.rpxInt(self.tabImport.listBox.columnWidth(0)) + logger.debug("Saving State: GuiProjectSettings") pOptions = SHARED.project.options pOptions.setValue("GuiProjectSettings", "winWidth", winWidth) pOptions.setValue("GuiProjectSettings", "winHeight", winHeight) diff --git a/novelwriter/dialogs/quotes.py b/novelwriter/dialogs/quotes.py index d8d649a7..c8cd8b39 100644 --- a/novelwriter/dialogs/quotes.py +++ b/novelwriter/dialogs/quotes.py @@ -25,7 +25,7 @@ from __future__ import annotations import logging -from PyQt5.QtGui import QFontMetrics +from PyQt5.QtGui import QCloseEvent, QFontMetrics from PyQt5.QtCore import QSize, Qt, pyqtSlot from PyQt5.QtWidgets import ( QDialog, QDialogButtonBox, QFrame, QHBoxLayout, QLabel, QListWidget, @@ -90,8 +90,8 @@ class GuiQuoteSelect(QDialog): # Buttons self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self.buttonBox.accepted.connect(self._doAccept) - self.buttonBox.rejected.connect(self._doReject) + self.buttonBox.accepted.connect(self.accept) + self.buttonBox.rejected.connect(self.reject) # Assemble self.labelBox.addWidget(self.previewLabel, 0, Qt.AlignTop) @@ -113,6 +113,16 @@ class GuiQuoteSelect(QDialog): logger.debug("Delete: GuiQuoteSelect") return + ## + # Events + ## + + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the close event and perform cleanup.""" + event.accept() + self.deleteLater() + return + ## # Private Slots ## @@ -127,16 +137,4 @@ class GuiQuoteSelect(QDialog): self.selectedQuote = theSymbol return - @pyqtSlot() - def _doAccept(self) -> None: - """Handle Ok button clicked.""" - self.accept() - return - - @pyqtSlot() - def _doReject(self) -> None: - """Handle Cancel button clicked.""" - self.reject() - return - # END Class GuiQuoteSelect diff --git a/novelwriter/dialogs/updates.py b/novelwriter/dialogs/updates.py index bbdaf038..e2752dad 100644 --- a/novelwriter/dialogs/updates.py +++ b/novelwriter/dialogs/updates.py @@ -30,7 +30,7 @@ from datetime import datetime from urllib.request import Request, urlopen from PyQt5.QtGui import QCloseEvent, QCursor -from PyQt5.QtCore import Qt, pyqtSlot +from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( QWidget, qApp, QDialog, QHBoxLayout, QVBoxLayout, QDialogButtonBox, QLabel ) @@ -95,7 +95,7 @@ class GuiUpdates(QDialog): # Buttons self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close) - self.buttonBox.rejected.connect(self._doClose) + self.buttonBox.rejected.connect(self.close) # Assemble self.innerBox = QHBoxLayout() @@ -169,14 +169,4 @@ class GuiUpdates(QDialog): self.deleteLater() return - ## - # Private Slots - ## - - @pyqtSlot() - def _doClose(self) -> None: - """Close the dialog.""" - self.close() - return - # END Class GuiUpdates diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index a233d17a..7a264914 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -27,7 +27,8 @@ import logging from typing import TYPE_CHECKING -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSlot +from PyQt5.QtGui import QCloseEvent from PyQt5.QtWidgets import ( QAbstractItemView, QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem, QPushButton, QVBoxLayout @@ -87,7 +88,7 @@ class GuiWordList(QDialog): self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) self.buttonBox.accepted.connect(self._doSave) - self.buttonBox.rejected.connect(self._doClose) + self.buttonBox.rejected.connect(self.close) # Assemble # ======== @@ -113,9 +114,21 @@ class GuiWordList(QDialog): return ## - # Slots + # Events ## + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the close event and perform cleanup.""" + self._saveGuiSettings() + event.accept() + self.deleteLater() + return + + ## + # Private Slots + ## + + @pyqtSlot() def _doAdd(self) -> None: """Add a new word to the word list.""" word = self.newEntry.text().strip() @@ -134,6 +147,7 @@ class GuiWordList(QDialog): return + @pyqtSlot() def _doDelete(self) -> None: """Delete the selected item.""" selItem = self.listBox.selectedItems() @@ -141,9 +155,9 @@ class GuiWordList(QDialog): self.listBox.takeItem(self.listBox.row(selItem[0])) return + @pyqtSlot() def _doSave(self) -> None: """Save the new word list and close.""" - self._saveGuiSettings() userDict = UserDictionary(SHARED.project) for i in range(self.listBox.count()): item = self.listBox.item(i) @@ -152,13 +166,7 @@ class GuiWordList(QDialog): if word: userDict.add(word) userDict.save() - self.accept() - return - - def _doClose(self) -> None: - """Close without saving the word list.""" - self._saveGuiSettings() - self.reject() + self.close() return ## @@ -180,6 +188,7 @@ class GuiWordList(QDialog): winWidth = CONFIG.rpxInt(self.width()) winHeight = CONFIG.rpxInt(self.height()) + logger.debug("Saving State: GuiWordList") pOptions = SHARED.project.options pOptions.setValue("GuiWordList", "winWidth", winWidth) pOptions.setValue("GuiWordList", "winHeight", winHeight) diff --git a/novelwriter/gui/docviewerpanel.py b/novelwriter/gui/docviewerpanel.py index 5444bad3..e601565a 100644 --- a/novelwriter/gui/docviewerpanel.py +++ b/novelwriter/gui/docviewerpanel.py @@ -123,6 +123,7 @@ class GuiDocViewerPanel(QWidget): widths = {} for key, tab in self.kwTabs.items(): widths[key] = tab.getColumnWidths() + logger.debug("Saving State: GuiDocViewerPanel") SHARED.project.options.setValue("GuiDocViewerPanel", "colWidths", widths) return diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index 40aae9ef..d59a668a 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -145,6 +145,7 @@ class GuiNovelView(QWidget): """Run closing project tasks.""" lastColType = self.novelTree.lastColType lastColSize = self.novelTree.lastColSize + logger.debug("Saving State: GuiNovelView") pOptions = SHARED.project.options pOptions.setValue("GuiNovelView", "lastCol", lastColType) pOptions.setValue("GuiNovelView", "lastColSize", lastColSize) diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 95b2b612..0a1a3df8 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -606,6 +606,7 @@ class GuiOutlineTree(QTreeWidget): logHidden, orgWidth if logHidden and logWidth == 0 else logWidth ] + logger.debug("Saving State: GuiOutline") pOptions = SHARED.project.options pOptions.setValue("GuiOutline", "columnState", colState) pOptions.saveSettings() diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index 3decd730..d7a8096e 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -344,8 +344,6 @@ class GuiManuscriptBuild(QDialog): def _saveSettings(self): """Save the user GUI settings.""" - logger.debug("Saving GuiManuscriptBuild settings") - winWidth = CONFIG.rpxInt(self.width()) winHeight = CONFIG.rpxInt(self.height()) @@ -353,6 +351,7 @@ class GuiManuscriptBuild(QDialog): fmtWidth = CONFIG.rpxInt(mainSplit[0]) sumWidth = CONFIG.rpxInt(mainSplit[1]) + logger.debug("Saving State: GuiManuscriptBuild") pOptions = SHARED.project.options pOptions.setValue("GuiManuscriptBuild", "winWidth", winWidth) pOptions.setValue("GuiManuscriptBuild", "winHeight", winHeight) diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index e166ffbb..5f7b6856 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -417,8 +417,6 @@ class GuiManuscript(QDialog): def _saveSettings(self): """Save the user GUI settings.""" - logger.debug("Saving GuiManuscript settings") - buildOrder = [] for i in range(self.buildList.count()): if item := self.buildList.item(i): @@ -442,6 +440,7 @@ class GuiManuscript(QDialog): detailsWidth = CONFIG.rpxInt(self.buildDetails.getColumnWidth()) detailsExpanded = self.buildDetails.getExpandedState() + logger.debug("Saving State: GuiManuscript") pOptions = SHARED.project.options pOptions.setValue("GuiManuscript", "winWidth", winWidth) pOptions.setValue("GuiManuscript", "winHeight", winHeight) diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 95235424..e0525144 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -253,13 +253,11 @@ class GuiBuildSettings(QDialog): def _saveSettings(self) -> None: """Save the various user settings.""" - logger.debug("Saving GuiBuildSettings settings") - winWidth = CONFIG.rpxInt(self.width()) winHeight = CONFIG.rpxInt(self.height()) - treeWidth, filterWidth = self.optTabSelect.mainSplitSizes() + logger.debug("Saving State: GuiBuildSettings") pOptions = SHARED.project.options pOptions.setValue("GuiBuildSettings", "winWidth", winWidth) pOptions.setValue("GuiBuildSettings", "winHeight", winHeight) diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index e8e4edef..2100dc14 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -29,7 +29,7 @@ import logging from datetime import datetime from typing import TYPE_CHECKING -from PyQt5.QtGui import QPixmap, QCursor +from PyQt5.QtGui import QCloseEvent, QPixmap, QCursor from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import ( qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout, @@ -307,9 +307,20 @@ class GuiWritingStats(QDialog): return ## - # Slots + # Events ## + def closeEvent(self, event: QCloseEvent) -> None: + """Capture the user closing the window.""" + event.accept() + self.deleteLater() + return + + ## + # Private Slots + ## + + @pyqtSlot() def _doClose(self) -> None: """Save the state of the window, clear cache, end close.""" self.logData = [] @@ -330,6 +341,7 @@ class GuiWritingStats(QDialog): showIdleTime = self.showIdleTime.isChecked() histMax = self.histMax.value() + logger.debug("Saving State: GuiWritingStats") pOptions = SHARED.project.options pOptions.setValue("GuiWritingStats", "winWidth", winWidth) pOptions.setValue("GuiWritingStats", "winHeight", winHeight) @@ -347,6 +359,7 @@ class GuiWritingStats(QDialog): pOptions.setValue("GuiWritingStats", "showIdleTime", showIdleTime) pOptions.setValue("GuiWritingStats", "histMax", histMax) pOptions.saveSettings() + self.close() return diff --git a/tests/test_dialogs/test_dlg_about.py b/tests/test_dialogs/test_dlg_about.py index 36ba5d42..ffcdb5be 100644 --- a/tests/test_dialogs/test_dlg_about.py +++ b/tests/test_dialogs/test_dlg_about.py @@ -56,14 +56,7 @@ def testDlgAbout_NWDialog(qtbot, monkeypatch, nwGUI): msgAbout.showReleaseNotes() assert msgAbout.tabBox.currentWidget() == msgAbout.pageNotes - msgAbout._doClose() - - # Open Again from Menu - nwGUI.mainMenu.aAboutNW.activate(QAction.Trigger) - qtbot.waitUntil(lambda: getGuiItem("GuiAbout") is not None, timeout=1000) - msgAbout = getGuiItem("GuiAbout") - assert msgAbout is not None - msgAbout._doClose() + msgAbout.close() # END Test testDlgAbout_NWDialog diff --git a/tests/test_dialogs/test_dlg_dialogs.py b/tests/test_dialogs/test_dlg_dialogs.py index ad0c338a..239a45c5 100644 --- a/tests/test_dialogs/test_dlg_dialogs.py +++ b/tests/test_dialogs/test_dlg_dialogs.py @@ -45,12 +45,11 @@ def testDlgOther_QuoteSelect(qtbot, nwGUI): lastItem = anItem.text()[2] assert nwQuot.previewLabel.text() == lastItem - nwQuot._doAccept() + nwQuot.accept() assert nwQuot.result() == QDialog.Accepted assert nwQuot.selectedQuote == lastItem # qtbot.stop() - nwQuot._doReject() nwQuot.close() # END Test testDlgOther_QuoteSelect @@ -89,7 +88,7 @@ def testDlgOther_Updates(qtbot, monkeypatch, nwGUI): nwGUI.mainMenu.aUpdates.activate(QAction.Trigger) # qtbot.stop() - nwUpdate._doClose() + nwUpdate.close() # END Test testDlgOther_Updates @@ -101,13 +100,13 @@ def testDlgOther_EditLabel(qtbot, monkeypatch): with monkeypatch.context() as mp: mp.setattr(GuiEditLabel, "result", lambda *a: QDialog.Accepted) - newLabel, dlgOk = GuiEditLabel.getLabel(None, text="Hello World") + newLabel, dlgOk = GuiEditLabel.getLabel(None, text="Hello World") # type: ignore assert dlgOk is True assert newLabel == "Hello World" with monkeypatch.context() as mp: mp.setattr(GuiEditLabel, "result", lambda *a: QDialog.Rejected) - newLabel, dlgOk = GuiEditLabel.getLabel(None, text="Hello World") + newLabel, dlgOk = GuiEditLabel.getLabel(None, text="Hello World") # type: ignore assert dlgOk is False assert newLabel == "Hello World" diff --git a/tests/test_dialogs/test_dlg_wordlist.py b/tests/test_dialogs/test_dlg_wordlist.py index 0459237f..5dc223b4 100644 --- a/tests/test_dialogs/test_dlg_wordlist.py +++ b/tests/test_dialogs/test_dlg_wordlist.py @@ -68,11 +68,11 @@ def testDlgWordList_Dialog(qtbot, monkeypatch, nwGUI, projPath): wList._loadWordList() # Check that the content was loaded - assert wList.listBox.item(0).text() == "word_a" - assert wList.listBox.item(1).text() == "word_b" - assert wList.listBox.item(2).text() == "word_c" - assert wList.listBox.item(3).text() == "word_f" - assert wList.listBox.item(4).text() == "word_g" + assert wList.listBox.item(0).text() == "word_a" # type: ignore + assert wList.listBox.item(1).text() == "word_b" # type: ignore + assert wList.listBox.item(2).text() == "word_c" # type: ignore + assert wList.listBox.item(3).text() == "word_f" # type: ignore + assert wList.listBox.item(4).text() == "word_g" # type: ignore assert wList.listBox.count() == 5 # Add a blank word, which is ignored @@ -91,24 +91,24 @@ def testDlgWordList_Dialog(qtbot, monkeypatch, nwGUI, projPath): assert wList.listBox.count() == 6 # Check that the content now - assert wList.listBox.item(0).text() == "word_a" - assert wList.listBox.item(1).text() == "word_b" - assert wList.listBox.item(2).text() == "word_c" - assert wList.listBox.item(3).text() == "word_d" - assert wList.listBox.item(4).text() == "word_f" - assert wList.listBox.item(5).text() == "word_g" + assert wList.listBox.item(0).text() == "word_a" # type: ignore + assert wList.listBox.item(1).text() == "word_b" # type: ignore + assert wList.listBox.item(2).text() == "word_c" # type: ignore + assert wList.listBox.item(3).text() == "word_d" # type: ignore + assert wList.listBox.item(4).text() == "word_f" # type: ignore + assert wList.listBox.item(5).text() == "word_g" # type: ignore # Delete a word wList.newEntry.setText("delete_me") wList._doAdd() - assert wList.listBox.item(0).text() == "delete_me" + assert wList.listBox.item(0).text() == "delete_me" # type: ignore delItem = wList.listBox.findItems("delete_me", Qt.MatchExactly)[0] assert delItem.text() == "delete_me" delItem.setSelected(True) wList._doDelete() assert wList.listBox.findItems("delete_me", Qt.MatchExactly) == [] - assert wList.listBox.item(0).text() == "word_a" + assert wList.listBox.item(0).text() == "word_a" # type: ignore # Save files wList._doSave() @@ -122,6 +122,6 @@ def testDlgWordList_Dialog(qtbot, monkeypatch, nwGUI, projPath): assert "word_g" in userDict # qtbot.stop() - wList._doClose() + wList.close() # END Test testDlgWordList_Dialog