diff --git a/.github/workflows/pytest_cov.yml b/.github/workflows/pytest_cov.yml index e46773a4..b47b943a 100644 --- a/.github/workflows/pytest_cov.yml +++ b/.github/workflows/pytest_cov.yml @@ -14,7 +14,9 @@ jobs: python-version: 3.8 architecture: x64 - name: Install Packages - run: sudo apt install xvfb libenchant-dev qt5-default + run: | + sudo apt update + sudo apt install xvfb libenchant-dev qt5-default - name: Checkout Source uses: actions/checkout@v2 - name: Install Dependencies @@ -44,7 +46,9 @@ jobs: python-version: ${{ matrix.python-version }} architecture: x64 - name: Install Packages - run: sudo apt install xvfb libenchant-dev qt5-default + run: | + sudo apt update + sudo apt install xvfb libenchant-dev qt5-default - name: Checkout Source uses: actions/checkout@v2 - name: Install Dependencies diff --git a/nw/core/project.py b/nw/core/project.py index a2a670f5..dd3f8c05 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -76,6 +76,7 @@ class NWProject(): self.projCache = None # The full path to the project's cache folder self.projContent = None # The full path to the project's content folder self.projDict = None # The spell check dictionary + self.projLang = None # The spell check language, if different than default self.projFile = None # The file name of the project main XML file # Project Meta @@ -190,6 +191,7 @@ class NWProject(): self.projCache = None self.projContent = None self.projDict = None + self.projLang = None self.projFile = nwFiles.PROJ_FILE self.projName = "" self.bookTitle = "" @@ -561,6 +563,8 @@ class NWProject(): self.doBackup = checkBool(xItem.text, False) elif xItem.tag == "spellCheck": self.spellCheck = checkBool(xItem.text, False) + elif xItem.tag == "spellLang": + self.projLang = checkString(xItem.text, None, True) elif xItem.tag == "autoOutline": self.autoOutline = checkBool(xItem.text, True) elif xItem.tag == "lastEdited": @@ -654,8 +658,8 @@ class NWProject(): # Save Project Meta xProject = etree.SubElement(nwXML, "project") - self._packProjectValue(xProject, "name", self.projName, True) - self._packProjectValue(xProject, "title", self.bookTitle, True) + self._packProjectValue(xProject, "name", self.projName) + self._packProjectValue(xProject, "title", self.bookTitle) self._packProjectValue(xProject, "author", self.bookAuthors) self._packProjectValue(xProject, "saveCount", str(self.saveCount)) self._packProjectValue(xProject, "autoCount", str(self.autoCount)) @@ -665,6 +669,7 @@ class NWProject(): xSettings = etree.SubElement(nwXML, "settings") self._packProjectValue(xSettings, "doBackup", self.doBackup) self._packProjectValue(xSettings, "spellCheck", self.spellCheck) + self._packProjectValue(xSettings, "spellLang", self.projLang) self._packProjectValue(xSettings, "autoOutline", self.autoOutline) self._packProjectValue(xSettings, "lastEdited", self.lastEdited) self._packProjectValue(xSettings, "lastViewed", self.lastViewed) @@ -990,6 +995,12 @@ class NWProject(): self.setProjectChanged(True) return True + def setSpellLang(self, theLang): + """Set the project-specific spell check language. + """ + self.projLang = checkString(theLang, None, True) + return True + def setAutoOutline(self, theMode): """Enable/disable automatic update of project outline. """ @@ -1240,12 +1251,10 @@ class NWProject(): if not isinstance(theValue, list): theValue = [theValue] for aValue in theValue: - if not isinstance(aValue, str): - aValue = str(aValue) - if aValue == "" and not allowNone: + if (aValue == "" or aValue is None) and not allowNone: continue xItem = etree.SubElement(xParent, theName) - xItem.text = aValue + xItem.text = str(aValue) return def _packProjectKeyValue(self, xParent, theName, theDict): diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index b0e4b5f4..dc2b632f 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -48,7 +48,7 @@ from PyQt5.QtWidgets import ( QFrame ) -from nw.core import NWDoc, NWSpellSimple, countWords +from nw.core import NWDoc, NWSpellCheck, NWSpellSimple, countWords from nw.gui.dochighlight import GuiDocHighlighter from nw.common import transferCase from nw.constants import ( @@ -73,6 +73,7 @@ class GuiDocEditor(QTextEdit): self.spellCheck = False self.nwDocument = NWDoc(self.theProject, self.theParent) self.theHandle = None + self.theDict = None # Document Variables self.charCount = 0 @@ -447,8 +448,17 @@ class GuiDocEditor(QTextEdit): status bar to show the one actually loaded by the spell checker class. """ - self.theDict.setLanguage(self.mainConf.spellLanguage, self.theProject.projDict) + if self.theProject.projLang is None: + theLang = self.mainConf.spellLanguage + else: + theLang = self.theProject.projLang + + self.theDict.setLanguage(theLang, self.theProject.projDict) self.theParent.statusBar.setLanguage(self.theDict.spellLanguage) + + if not self.bigDoc: + self.spellCheckDocument() + return True def setSpellCheck(self, theMode): @@ -494,6 +504,8 @@ class GuiDocEditor(QTextEdit): "Document re-highlighted in %.3f milliseconds" % (1000*(afTime-bfTime)) ) + self.theParent.statusBar.showMessage("Spell check complete") + return True ## @@ -1334,7 +1346,7 @@ class GuiDocEditor(QTextEdit): """Create the spell checking object based on the spellTool setting in config. """ - if self.mainConf.spellTool == "enchant": + if self.mainConf.spellTool == NWSpellCheck.SP_ENCHANT: from nw.core.spellcheck import NWSpellEnchant self.theDict = NWSpellEnchant() else: diff --git a/nw/gui/projsettings.py b/nw/gui/projsettings.py index 066c618f..a00d345e 100644 --- a/nw/gui/projsettings.py +++ b/nw/gui/projsettings.py @@ -33,7 +33,7 @@ from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush from PyQt5.QtWidgets import ( QHBoxLayout, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit, QLabel, QWidget, QDialogButtonBox, QListWidget, QPushButton, QListWidgetItem, - QColorDialog, QAbstractItemView, QTreeWidget, QTreeWidgetItem + QColorDialog, QAbstractItemView, QTreeWidget, QTreeWidgetItem, QComboBox ) from nw.constants import nwAlert @@ -55,12 +55,15 @@ class GuiProjectSettings(PagedDialog): self.theProject.countStatus() self.setWindowTitle("Project Settings") - self.setMinimumWidth(self.mainConf.pxInt(570)) - self.setMinimumHeight(self.mainConf.pxInt(355)) + wW = self.mainConf.pxInt(570) + wH = self.mainConf.pxInt(375) + + self.setMinimumWidth(wW) + self.setMinimumHeight(wH) self.resize( - self.mainConf.pxInt(self.optState.getInt("GuiProjectSettings", "winWidth", 570)), - self.mainConf.pxInt(self.optState.getInt("GuiProjectSettings", "winHeight", 355)) + self.mainConf.pxInt(self.optState.getInt("GuiProjectSettings", "winWidth", wW)), + self.mainConf.pxInt(self.optState.getInt("GuiProjectSettings", "winHeight", wH)) ) self.tabMain = GuiProjectEditMain(self.theParent, self.theProject) @@ -96,11 +99,13 @@ class GuiProjectSettings(PagedDialog): projName = self.tabMain.editName.text() bookTitle = self.tabMain.editTitle.text() bookAuthors = self.tabMain.editAuthors.toPlainText() + spellLang = self.tabMain.spellLang.currentData() doBackup = not self.tabMain.doBackup.isChecked() self.theProject.setProjectName(projName) self.theProject.setBookTitle(bookTitle) self.theProject.setBookAuthors(bookAuthors) + self.theProject.setSpellLang(spellLang) self.theProject.setProjBackup(doBackup) if self.tabStatus.colChanged: @@ -191,6 +196,26 @@ class GuiProjectEditMain(QWidget): "One name per line." ) + self.spellLang = QComboBox(self) + theDict = self.theParent.docEditor.theDict + self.spellLang.addItem("Default", "None") + if theDict is not None: + for spTag, spName in theDict.listDictionaries(): + self.spellLang.addItem(spName, spTag) + + self.mainForm.addRow( + "Spell check language", + self.spellLang, + "Overrides main preferences." + ) + + if self.theProject.projLang is None: + spellIdx = 0 + else: + spellIdx = self.spellLang.findData(self.theProject.projLang) + if spellIdx != -1: + self.spellLang.setCurrentIndex(spellIdx) + self.doBackup = QSwitch(self) self.doBackup.setChecked(not self.theProject.doBackup) self.mainForm.addRow( diff --git a/nw/guimain.py b/nw/guimain.py index 66bcc7cb..86401a5b 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -803,6 +803,7 @@ class GuiMain(QMainWindow): if self.hasProject: dlgProj = GuiProjectSettings(self, self.theProject) dlgProj.exec_() + self.docEditor.setDictionaries() self._setWindowTitle(self.theProject.projName) return True diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index 01631b07..226c40ba 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,17 +1,18 @@ - + Sample Project Sample Project Jane Smith Jay Doh - 723 - 140 - 35485 + 743 + 143 + 36089 False - False + True + None True 636b6aa9b697b 636b6aa9b697b @@ -119,7 +120,7 @@ 1811 318 8 - 1364 + 1880 Another Scene diff --git a/tests/reference/gui/0_nwProject.nwx b/tests/reference/gui/0_nwProject.nwx index 4bd15d6f..77eff6e9 100644 --- a/tests/reference/gui/0_nwProject.nwx +++ b/tests/reference/gui/0_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project @@ -10,6 +10,7 @@ True False + None True None None diff --git a/tests/reference/gui/1_nwProject.nwx b/tests/reference/gui/1_nwProject.nwx index 43dcf523..5ef10130 100644 --- a/tests/reference/gui/1_nwProject.nwx +++ b/tests/reference/gui/1_nwProject.nwx @@ -1,15 +1,16 @@ - + New Project - 5 + 4 1 - 14 + 8 True True + None True 0e17daca5f3e1 None diff --git a/tests/reference/gui/2_nwProject.nwx b/tests/reference/gui/2_nwProject.nwx index 1e3a2ca3..11cad874 100644 --- a/tests/reference/gui/2_nwProject.nwx +++ b/tests/reference/gui/2_nwProject.nwx @@ -1,17 +1,18 @@ - + Project Name Project Title Jane Doe John Doh - 2 + 1 1 0 True False + None True None None diff --git a/tests/reference/gui/3_nwProject.nwx b/tests/reference/gui/3_nwProject.nwx index 11be0c01..cb018a6a 100644 --- a/tests/reference/gui/3_nwProject.nwx +++ b/tests/reference/gui/3_nwProject.nwx @@ -1,15 +1,16 @@ - + New Project - 2 + 1 1 0 True False + None True 0e17daca5f3e1 None diff --git a/tests/reference/proj/1_nwProject.nwx b/tests/reference/proj/1_nwProject.nwx index 0c891d8b..61ece12f 100644 --- a/tests/reference/proj/1_nwProject.nwx +++ b/tests/reference/proj/1_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project @@ -10,6 +10,7 @@ True False + None True None None diff --git a/tests/reference/proj/2_nwProject.nwx b/tests/reference/proj/2_nwProject.nwx index fd73b637..cc7b54ea 100644 --- a/tests/reference/proj/2_nwProject.nwx +++ b/tests/reference/proj/2_nwProject.nwx @@ -1,15 +1,16 @@ - + New Project - 4 + 2 1 0 True False + None True None None diff --git a/tests/reference/proj/3_nwProject.nwx b/tests/reference/proj/3_nwProject.nwx index c2be9007..c9e450d6 100644 --- a/tests/reference/proj/3_nwProject.nwx +++ b/tests/reference/proj/3_nwProject.nwx @@ -1,5 +1,5 @@ - + New Project @@ -10,6 +10,7 @@ True False + None True None None diff --git a/tests/reference/proj/4_nwProject.nwx b/tests/reference/proj/4_nwProject.nwx index 3dd716cc..4c9c30eb 100644 --- a/tests/reference/proj/4_nwProject.nwx +++ b/tests/reference/proj/4_nwProject.nwx @@ -1,5 +1,5 @@ - + Test Custom Test Novel @@ -12,6 +12,7 @@ True False + None True None None