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