diff --git a/novelwriter/core/spellcheck.py b/novelwriter/core/spellcheck.py index 7f9d7f4f..879007a0 100644 --- a/novelwriter/core/spellcheck.py +++ b/novelwriter/core/spellcheck.py @@ -97,6 +97,7 @@ class NWSpellEnchant: if self._enchant is None: self._enchant = FakeEnchant() else: + self._userDict.load() for word in self._userDict: self._enchant.add_to_session(word) @@ -136,11 +137,6 @@ class NWSpellEnchant: return added - def loadUserWordList(self) -> None: - """Load the user word list from the project.""" - self._userDict.load() - return - def listDictionaries(self) -> list[tuple[str, str]]: """Wrapper function for pyenchant.""" retList = [] diff --git a/novelwriter/dialogs/projsettings.py b/novelwriter/dialogs/projsettings.py index 861c36b6..cd4280e4 100644 --- a/novelwriter/dialogs/projsettings.py +++ b/novelwriter/dialogs/projsettings.py @@ -89,9 +89,6 @@ class GuiProjectSettings(NPagedDialog): self.buttonBox.rejected.connect(self._doClose) self.addControls(self.buttonBox) - # Flags - self._spellChanged = False - # Focus Tab self._focusTab(focusTab) @@ -103,10 +100,6 @@ class GuiProjectSettings(NPagedDialog): logger.debug("Delete: GuiProjectSettings") return - @property - def spellChanged(self): - return self._spellChanged - ## # Slots ## @@ -125,9 +118,7 @@ class GuiProjectSettings(NPagedDialog): project.data.setTitle(bookTitle) project.data.setAuthor(bookAuthor) project.data.setDoBackup(doBackup) - - # Remember this as updating spell dictionary can be expensive - self._spellChanged = project.data.setSpellLang(spellLang) + project.data.setSpellLang(spellLang) if self.tabStatus.colChanged: newList, delList = self.tabStatus.getNewList() diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 311fbe4e..2063627b 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -73,7 +73,6 @@ class GuiDocEditor(QTextEdit): statusMessage = pyqtSignal(str) docCountsChanged = pyqtSignal(str, int, int, int) editedStatusChanged = pyqtSignal(bool) - spellDictionaryChanged = pyqtSignal(str, str) loadDocumentTagRequest = pyqtSignal(str, Enum) novelStructureChanged = pyqtSignal() novelItemMetaChanged = pyqtSignal(str) @@ -301,7 +300,7 @@ class GuiDocEditor(QTextEdit): self._typPadAfter = CONFIG.fmtPadAfter # Reload spell check and dictionaries - self.setDictionaries() + SHARED.updateSpellCheckLanguage() # Set font textFont = QFont() @@ -691,24 +690,6 @@ class GuiDocEditor(QTextEdit): # Spell Checking ## - def setDictionaries(self): - """Set the spell checker dictionary language, and emit the - dictionary changed signal. - """ - if SHARED.project.data.spellLang is None: - theLang = CONFIG.spellLanguage - else: - theLang = SHARED.project.data.spellLang - - SHARED.spelling.setLanguage(theLang) - _, theProvider = SHARED.spelling.describeDict() - - self.spellDictionaryChanged.emit(str(theLang), str(theProvider)) - if not self._bigDoc: - self.spellCheckDocument() - - return True - def toggleSpellCheck(self, state: bool) -> None: """This is the main spell check setting function, and this one should call all other setSpellCheck functions in other classes. diff --git a/novelwriter/gui/statusbar.py b/novelwriter/gui/statusbar.py index 597124de..a80864ca 100644 --- a/novelwriter/gui/statusbar.py +++ b/novelwriter/gui/statusbar.py @@ -121,7 +121,7 @@ class GuiMainStatus(QStatusBar): def clearStatus(self) -> None: """Reset all widgets on the status bar to default values.""" self.setRefTime(-1.0) - self.setLanguage(None, "") + self.setLanguage(*SHARED.spelling.describeDict()) self.setProjectStats(0, 0) self.setProjectStatus(StatusLED.S_NONE) self.setDocumentStatus(StatusLED.S_NONE) diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index fbb16c0b..96806648 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -234,6 +234,7 @@ class GuiMain(QMainWindow): SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus) SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage) + SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage) self.viewsBar.viewChangeRequested.connect(self._changeView) @@ -251,7 +252,6 @@ class GuiMain(QMainWindow): self.novelView.selectedItemChanged.connect(self.itemDetails.updateViewBox) self.novelView.openDocumentRequest.connect(self._openDocument) - self.docEditor.spellDictionaryChanged.connect(self.mainStatus.setLanguage) self.docEditor.editedStatusChanged.connect(self.mainStatus.updateDocumentStatus) self.docEditor.docCountsChanged.connect(self.itemDetails.updateCounts) self.docEditor.docCountsChanged.connect(self.projView.updateCounts) @@ -428,7 +428,6 @@ class GuiMain(QMainWindow): SHARED.closeProject() - self.docEditor.setDictionaries() self._updateWindowTitle() self._changeView(nwView.PROJECT) @@ -489,7 +488,6 @@ class GuiMain(QMainWindow): # Update GUI self._updateWindowTitle(SHARED.project.data.name) self.rebuildTrees() - self.docEditor.setDictionaries() self.docEditor.toggleSpellCheck(SHARED.project.data.spellCheck) self.mainStatus.setRefTime(SHARED.project.projOpened) self.projView.openProjectTasks() @@ -907,8 +905,7 @@ class GuiMain(QMainWindow): if dlgProj.result() == QDialog.Accepted: logger.debug("Applying new project settings") - if dlgProj.spellChanged: - self.docEditor.setDictionaries() + SHARED.updateSpellCheckLanguage() self.itemDetails.refreshDetails() self._updateWindowTitle(SHARED.project.data.name) @@ -982,7 +979,7 @@ class GuiMain(QMainWindow): if dlgWords.result() == QDialog.Accepted: logger.debug("Reloading word list") - self.docEditor.setDictionaries() + SHARED.updateSpellCheckLanguage(reload=True) return True diff --git a/novelwriter/shared.py b/novelwriter/shared.py index 09427760..9fc91c5e 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -65,6 +65,10 @@ class SharedData(QObject): self._idleRefTime = time() return + ## + # Properties + ## + @property def mainGui(self) -> GuiMain: """Return the Main GUI instance.""" @@ -141,7 +145,7 @@ class SharedData(QObject): self._lockedBy = self.project.lockStatus self._resetProject() - self.spelling.loadUserWordList() + self.updateSpellCheckLanguage(reload=True) self._resetIdleTimer() return status @@ -160,6 +164,16 @@ class SharedData(QObject): self._resetIdleTimer() return + def updateSpellCheckLanguage(self, reload: bool = False) -> None: + """Update the active spell check langauge from settings.""" + from novelwriter import CONFIG + language = self.project.data.spellLang or CONFIG.spellLanguage + if language != self.spelling.spellLanguage or reload: + self.spelling.setLanguage(language) + _, provider = self.spelling.describeDict() + self.spellLanguageChanged.emit(language, provider) + return + def updateIdleTime(self, currTime: float, userIdle: bool) -> None: """Update the idle time record. If the userIdle flag is True, the user idle counter is updated with the time difference since @@ -239,6 +253,7 @@ class SharedData(QObject): del self._spelling self._project = NWProject() self._spelling = NWSpellEnchant(self._project) + self.updateSpellCheckLanguage() return def _resetIdleTimer(self) -> None: diff --git a/tests/test_dialogs/test_dlg_projsettings.py b/tests/test_dialogs/test_dlg_projsettings.py index ddf426b3..a54639fc 100644 --- a/tests/test_dialogs/test_dlg_projsettings.py +++ b/tests/test_dialogs/test_dlg_projsettings.py @@ -43,7 +43,6 @@ def testDlgProjSettings_Dialog(qtbot, monkeypatch, nwGUI): # Block the GUI blocking thread monkeypatch.setattr(GuiProjectSettings, "exec_", lambda *a: None) monkeypatch.setattr(GuiProjectSettings, "result", lambda *a: QDialog.Accepted) - monkeypatch.setattr(GuiProjectSettings, "spellChanged", lambda *a: True) # Check that we cannot open when there is no project nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) @@ -129,7 +128,6 @@ def testDlgProjSettings_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockR assert tabMain.editName.text() == "Project Name" assert tabMain.editTitle.text() == "Project Title" assert tabMain.editAuthor.text() == "Jane Doe" - assert projSettings.spellChanged is False projSettings._doSave() assert theProject.data.name == "Project Name"