From f35b1c0ad6c184ab3bdd422366260c197b8e2504 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 1 Nov 2020 18:14:43 +0100 Subject: [PATCH 1/4] Don't allow inserts when no document is open --- nw/gui/doceditor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 85a3f75d..005c6ffa 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -705,6 +705,10 @@ class GuiDocEditor(QTextEdit): def insertText(self, theInsert): """Insert a specific type of text at the cursor position. """ + if self.theHandle is None: + logger.error("No document open") + return False + if isinstance(theInsert, str): theText = theInsert elif isinstance(theInsert, nwDocInsert): From 98be2bd5b4103a086804321b5ff34d769d66d400 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 1 Nov 2020 18:25:00 +0100 Subject: [PATCH 2/4] Block a bunch more main GUI actions when no project is open --- nw/guimain.py | 131 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 43 deletions(-) diff --git a/nw/guimain.py b/nw/guimain.py index 1a6b5a16..574551c4 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -442,6 +442,7 @@ class GuiMain(QMainWindow): """Save the current project. """ if not self.hasProject: + logger.error("No project open") return False # If the project is new, it may not have a path, so we need one @@ -465,27 +466,33 @@ class GuiMain(QMainWindow): def closeDocument(self): """Close the document and clear the editor and title field. """ - if self.hasProject: - self.docEditor.saveCursorPosition() - if self.docEditor.docChanged: - self.saveDocument() - self.docEditor.clearEditor() + if not self.hasProject: + logger.error("No project open") + return False + + self.docEditor.saveCursorPosition() + if self.docEditor.docChanged: + self.saveDocument() + self.docEditor.clearEditor() return True def openDocument(self, tHandle, tLine=None, changeFocus=True, doScroll=False): """Open a specific document, optionally at a given line. """ - if self.hasProject: - self.closeDocument() - self.tabWidget.setCurrentWidget(self.splitDocs) - if self.docEditor.loadText(tHandle, tLine): - if changeFocus: - self.docEditor.setFocus() - self.theProject.setLastEdited(tHandle) - self.treeView.setSelectedHandle(tHandle, doScroll=doScroll) - else: - return False + if not self.hasProject: + logger.error("No project open") + return False + + self.closeDocument() + self.tabWidget.setCurrentWidget(self.splitDocs) + if self.docEditor.loadText(tHandle, tLine): + if changeFocus: + self.docEditor.setFocus() + self.theProject.setLastEdited(tHandle) + self.treeView.setSelectedHandle(tHandle, doScroll=doScroll) + else: + return False return True @@ -493,43 +500,54 @@ class GuiMain(QMainWindow): """Opens the next document in the project tree, following the document with the given handle. Stops when reaching the end. """ - if self.hasProject: - self.treeView.flushTreeOrder() - nHandle = None # The next handle after tHandle - fHandle = None # The first file handle we encounter - foundIt = False # We've found tHandle, pick the next we see - for tItem in self.theProject.projTree: - if tItem is None: - continue - if tItem.itemType != nwItemType.FILE: - continue - if fHandle is None: - fHandle = tItem.itemHandle - if tItem.itemHandle == tHandle: - foundIt = True - elif foundIt: - nHandle = tItem.itemHandle - break + if not self.hasProject: + logger.error("No project open") + return False - if nHandle is not None: - self.openDocument(nHandle, tLine=0, doScroll=True) - return True - elif wrapAround: - self.openDocument(fHandle, tLine=0, doScroll=True) - return False + self.treeView.flushTreeOrder() + nHandle = None # The next handle after tHandle + fHandle = None # The first file handle we encounter + foundIt = False # We've found tHandle, pick the next we see + for tItem in self.theProject.projTree: + if tItem is None: + continue + if tItem.itemType != nwItemType.FILE: + continue + if fHandle is None: + fHandle = tItem.itemHandle + if tItem.itemHandle == tHandle: + foundIt = True + elif foundIt: + nHandle = tItem.itemHandle + break + + if nHandle is not None: + self.openDocument(nHandle, tLine=0, doScroll=True) + return True + elif wrapAround: + self.openDocument(fHandle, tLine=0, doScroll=True) + return False return False def saveDocument(self): """Save the current documents. """ - if self.hasProject: - self.docEditor.saveText() + if not self.hasProject: + logger.error("No project open") + return False + + self.docEditor.saveText() + return True def viewDocument(self, tHandle=None, tAnchor=None): """Load a document for viewing in the view panel. """ + if not self.hasProject: + logger.error("No project open") + return False + if tHandle is None: logger.debug("Viewing document, but no handle provided") @@ -573,8 +591,11 @@ class GuiMain(QMainWindow): """Import the text contained in an out-of-project text file, and insert the text into the currently open document. """ - lastPath = self.mainConf.lastPath + if not self.hasProject: + logger.error("No project open") + return False + lastPath = self.mainConf.lastPath extFilter = [ "Text files (*.txt)", "Markdown files (*.md)", @@ -627,16 +648,26 @@ class GuiMain(QMainWindow): def mergeDocuments(self): """Merge multiple documents to one single new document. """ + if not self.hasProject: + logger.error("No project open") + return False + dlgMerge = GuiDocMerge(self, self.theProject) dlgMerge.exec_() - return + + return True def splitDocument(self): """Split a single document into multiple documents. """ + if not self.hasProject: + logger.error("No project open") + return False + dlgSplit = GuiDocSplit(self, self.theProject) dlgSplit.exec_() - return + + return True def passDocumentAction(self, theAction): """Pass on document action theAction to the document viewer if @@ -655,6 +686,10 @@ class GuiMain(QMainWindow): def openSelectedItem(self): """Open the selected documents. """ + if not self.hasProject: + logger.error("No project open") + return False + tHandle = self.treeView.getSelectedHandle() if tHandle is None: logger.warning("No item selected") @@ -673,6 +708,10 @@ class GuiMain(QMainWindow): def editItem(self, tHandle=None): """Open the edit item dialog. """ + if not self.hasProject: + logger.error("No project open") + return False + if tHandle is None: tHandle = self.treeView.getSelectedHandle() if tHandle is None: @@ -703,6 +742,7 @@ class GuiMain(QMainWindow): """Rebuild the entire index. """ if not self.hasProject: + logger.error("No project open") return False logger.debug("Rebuilding index ...") @@ -748,9 +788,14 @@ class GuiMain(QMainWindow): def rebuildOutline(self): """Force a rebuild of the Outline view. """ + if not self.hasProject: + logger.error("No project open") + return False + logger.verbose("Forcing a rebuild of the Project Outline") self.tabWidget.setCurrentWidget(self.splitOutline) self.projView.refreshTree(overRide=True) + return True ## From 2a0be718d7a4ea919765a79ddc5fb93d23fe88b9 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 1 Nov 2020 18:39:12 +0100 Subject: [PATCH 3/4] Added more checks on actions for project or document being open --- nw/core/project.py | 4 ++++ nw/gui/doceditor.py | 31 +++++++++++++++++++------------ nw/gui/projtree.py | 13 +++++++++++++ nw/guimain.py | 1 + 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/nw/core/project.py b/nw/core/project.py index 1bf53151..b077c53d 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -781,6 +781,10 @@ class NWProject(): def zipIt(self, doNotify): """Create a zip file of the entire project. """ + if not self.theParent.hasProject: + logger.error("No project open") + return False + logger.info("Backing up project") self.theParent.setStatus("Backing up project ...") diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 005c6ffa..8759d86e 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -620,9 +620,10 @@ class GuiDocEditor(QTextEdit): this class when calling these actions from other classes. """ logger.verbose("Requesting action: %s" % theAction.name) - if not self.theParent.hasProject: - logger.error("No project open") + if self.theHandle is None: + logger.error("No document open") return False + self._allowAutoReplace(False) if theAction == nwDocAction.UNDO: self.undo() @@ -678,7 +679,9 @@ class GuiDocEditor(QTextEdit): logger.debug("Unknown or unsupported document action %s" % str(theAction)) self._allowAutoReplace(True) return False + self._allowAutoReplace(True) + return True def isEmpty(self): @@ -690,16 +693,20 @@ class GuiDocEditor(QTextEdit): """Tell the user where on the file system the file in the editor is saved. """ - if self.theHandle is not None: - msgBox = QMessageBox() - msgBox.information(self, "File Location", ( - "File details for the currently open file
" - "Handle: {handle:s}
" - "Location: {fileLoc:s}" - ).format( - handle = self.theHandle, - fileLoc = str(self.nwDocument.getFileLocation()) - )) + if self.theHandle is None: + logger.error("No document open") + return False + + msgBox = QMessageBox() + msgBox.information(self, "File Location", ( + "File details for the currently open file
" + "Handle: {handle:s}
" + "Location: {fileLoc:s}" + ).format( + handle = self.theHandle, + fileLoc = str(self.nwDocument.getFileLocation()) + )) + return def insertText(self, theInsert): diff --git a/nw/gui/projtree.py b/nw/gui/projtree.py index f0d0bca9..4116a863 100644 --- a/nw/gui/projtree.py +++ b/nw/gui/projtree.py @@ -163,6 +163,7 @@ class GuiProjectTree(QTreeWidget): nHandle = None if not self.theParent.hasProject: + logger.error("No project open") return False # The item needs to be assigned an item class, so one must be @@ -281,6 +282,10 @@ class GuiProjectTree(QTreeWidget): """Move an item up or down in the tree, but only if the treeView has focus. This also applies when the menu is used. """ + if not self.theParent.hasProject: + logger.error("No project open") + return False + hasFocus = qApp.focusWidget() == self or not self.mainConf.showGUI if hasFocus and self.theParent.hasProject: @@ -364,6 +369,10 @@ class GuiProjectTree(QTreeWidget): function only asks for confirmation once, and calls the regular deleteItem function for each document in the Trash folder. """ + if not self.theParent.hasProject: + logger.error("No project open") + return False + trashHandle = self.theProject.projTree.trashRoot() logger.debug("Emptying Trash folder") @@ -409,6 +418,10 @@ class GuiProjectTree(QTreeWidget): delete the files on disk. Folders are deleted if they're empty only, and the deletion is always permanent. """ + if not self.theParent.hasProject: + logger.error("No project open") + return False + if tHandle is None: tHandle = self.getSelectedHandle() diff --git a/nw/guimain.py b/nw/guimain.py index 574551c4..bfca4255 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -1053,6 +1053,7 @@ class GuiMain(QMainWindow): """ if self.docEditor.theHandle is None: logger.error("No document open, so not activating Focus Mode") + self.mainMenu.aFocusMode.setChecked(self.isFocusMode) return False self.isFocusMode = not self.isFocusMode From ccc119ed8b8892bbcacc401ce5e13d58f3faf51b Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 1 Nov 2020 18:40:35 +0100 Subject: [PATCH 4/4] Fixed test --- tests/nwdummy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/nwdummy.py b/tests/nwdummy.py index 313af767..4b5302b7 100644 --- a/tests/nwdummy.py +++ b/tests/nwdummy.py @@ -6,6 +6,7 @@ class DummyMain(): def __init__(self): self.mainConf = None + self.hasProject = True self.statusBar = StatusBar() return