From 6e64ede90b8b1f9dc35a2994cafb14c43db730d6 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 12 Feb 2021 17:01:46 +0100 Subject: [PATCH] Add a starting widget for the word liste ditor and connect it to the GUI --- nw/core/options.py | 4 ++ nw/gui/__init__.py | 2 + nw/gui/mainmenu.py | 13 +++-- nw/gui/wordlist.py | 142 +++++++++++++++++++++++++++++++++++++++++++++ nw/guimain.py | 18 +++++- 5 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 nw/gui/wordlist.py diff --git a/nw/core/options.py b/nw/core/options.py index 52a30af5..51fba3b6 100644 --- a/nw/core/options.py +++ b/nw/core/options.py @@ -104,6 +104,10 @@ class OptionState(): "countFrom", "clearDouble", }, + "GuiWordList": { + "winWidth", + "winHeight", + } } return diff --git a/nw/gui/__init__.py b/nw/gui/__init__.py index aa7455b5..8744348f 100644 --- a/nw/gui/__init__.py +++ b/nw/gui/__init__.py @@ -20,6 +20,7 @@ from nw.gui.projtree import GuiProjectTree from nw.gui.projwizard import GuiProjectWizard from nw.gui.statusbar import GuiMainStatus from nw.gui.theme import GuiTheme +from nw.gui.wordlist import GuiWordList from nw.gui.writingstats import GuiWritingStats __all__ = [ @@ -44,5 +45,6 @@ __all__ = [ "GuiProjectTree", "GuiProjectWizard", "GuiTheme", + "GuiWordList", "GuiWritingStats", ] diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 4cf4960a..6d6267a9 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -910,23 +910,28 @@ class GuiMainMenu(QMenuBar): # Tools self.toolsMenu = self.addMenu("&Tools") - # Tools > Toggle Spell Check + # Tools > Check Spelling self.aSpellCheck = QAction("Check Spelling", self) self.aSpellCheck.setStatusTip("Toggle check spelling") self.aSpellCheck.setCheckable(True) self.aSpellCheck.setChecked(self.theProject.spellCheck) - # Here we must used triggered, not toggled, to avoid recursion - self.aSpellCheck.triggered.connect(self._toggleSpellCheck) + self.aSpellCheck.triggered.connect(self._toggleSpellCheck) # triggered, not toggled! self.aSpellCheck.setShortcut("Ctrl+F7") self.toolsMenu.addAction(self.aSpellCheck) - # Tools > Update Spell Check + # Tools > Re-Run Spell Check self.aReRunSpell = QAction("Re-Run Spell Check", self) self.aReRunSpell.setStatusTip("Run the spell checker on current document") self.aReRunSpell.setShortcut("F7") self.aReRunSpell.triggered.connect(lambda: self.theParent.docEditor.spellCheckDocument()) self.toolsMenu.addAction(self.aReRunSpell) + # Tools > Project Word List + self.aEditWordList = QAction("Project Word List", self) + self.aEditWordList.setStatusTip("Edit the project's word list") + self.aEditWordList.triggered.connect(lambda: self.theParent.showProjectWordListDialog()) + self.toolsMenu.addAction(self.aEditWordList) + # Tools > Separator self.toolsMenu.addSeparator() diff --git a/nw/gui/wordlist.py b/nw/gui/wordlist.py new file mode 100644 index 00000000..fcf8682f --- /dev/null +++ b/nw/gui/wordlist.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +""" +novelWriter – GUI User Wordlist +=============================== +Class holding the user's wordlist dialog + +File History: +Created: 2021-02-12 [1.2b1] + +This file is a part of novelWriter +Copyright 2018–2021, Veronica Berglyd Olsen + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +import nw +import logging +import os + +from PyQt5.QtWidgets import ( + QDialog, QDialogButtonBox, QVBoxLayout, QListWidget, QAbstractItemView +) + +from nw.constants import nwFiles + +logger = logging.getLogger(__name__) + +class GuiWordList(QDialog): + + def __init__(self, theParent, theProject): + QDialog.__init__(self, theParent) + + logger.debug("Initialising GuiWordList ...") + self.setObjectName("GuiWordList") + + self.mainConf = nw.CONFIG + self.theParent = theParent + self.theProject = theProject + self.optState = theProject.optState + + self.setWindowTitle("Project Word List") + + wW = self.mainConf.pxInt(250) + wH = self.mainConf.pxInt(300) + + self.setMinimumWidth(wW) + self.setMinimumHeight(wH) + self.resize( + self.mainConf.pxInt(self.optState.getInt("GuiWordList", "winWidth", wW)), + self.mainConf.pxInt(self.optState.getInt("GuiWordList", "winHeight", wH)) + ) + + # Main Widgets + # ============ + + self.listBox = QListWidget() + self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop) + self.listBox.setSortingEnabled(True) + + self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) + self.buttonBox.accepted.connect(self._doSave) + self.buttonBox.rejected.connect(self._doClose) + + # Assemble + # ======== + + self.outerBox = QVBoxLayout() + self.outerBox.addWidget(self.listBox, 1) + self.outerBox.addWidget(self.buttonBox, 0) + + self.setLayout(self.outerBox) + + self._loadWordList() + + logger.debug("GuiWordList initialisation complete") + + return + + ## + # Slots + ## + + def _doSave(self): + """Save the new word list and close. + """ + self._saveGuiSettings() + self.accept() + return + + def _doClose(self): + """Close without saving the word list. + """ + self._saveGuiSettings() + self.reject() + return + + ## + # Internal Functions + ## + + def _loadWordList(self): + """Load the project's word list, if it exists. + """ + self.listBox.clear() + + wordList = os.path.join(self.theProject.projMeta, nwFiles.PROJ_DICT) + if not os.path.isfile(wordList): + logger.debug("No project dictionary file found") + return False + + with open(wordList, mode="r", encoding="utf8") as inFile: + for inLine in inFile: + theWord = inLine.strip() + if len(theWord) == 0: + continue + self.listBox.addItem(theWord) + + return True + + def _saveGuiSettings(self): + """Save GUI settings. + """ + winWidth = self.mainConf.rpxInt(self.width()) + winHeight = self.mainConf.rpxInt(self.height()) + + self.optState.setValue("GuiWordList", "winWidth", winWidth) + self.optState.setValue("GuiWordList", "winHeight", winHeight) + + return + +# END Class GuiWordList diff --git a/nw/guimain.py b/nw/guimain.py index cb2756cc..268862b3 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -43,7 +43,7 @@ from nw.gui import ( GuiDocViewDetails, GuiDocViewer, GuiItemDetails, GuiItemEditor, GuiMainMenu, GuiMainStatus, GuiNovelTree, GuiOutline, GuiOutlineDetails, GuiPreferences, GuiProjectDetails, GuiProjectLoad, GuiProjectSettings, - GuiProjectTree, GuiProjectWizard, GuiTheme, GuiWritingStats + GuiProjectTree, GuiProjectWizard, GuiTheme, GuiWordList, GuiWritingStats ) from nw.core import NWProject, NWDoc, NWIndex from nw.constants import nwItemType, nwItemClass, nwAlert, nwLists @@ -1017,6 +1017,22 @@ class GuiMain(QMainWindow): return + def showProjectWordListDialog(self): + """Open the project word list dialog. + """ + if not self.hasProject: + logger.error("No project open") + return + + dlgWords = GuiWordList(self, self.theProject) + dlgWords.exec_() + + if dlgWords.result() == QDialog.Accepted: + logger.debug("Reloading word list") + # ToDo + + return + def showWritingStatsDialog(self): """Open the session log dialog. """