diff --git a/nw/core/document.py b/nw/core/document.py index 44f94203..956dee5d 100644 --- a/nw/core/document.py +++ b/nw/core/document.py @@ -40,26 +40,20 @@ class NWDoc(): # Internal Variables self._docHandle = theHandle - self._theItem = self.theProject.projTree[theHandle] + self._theItem = None self._fileLoc = None self._docMeta = {} self._docError = "" + if theHandle is not None: + self._theItem = self.theProject.projTree[theHandle] + return ## # Class Methods ## - def clearDocument(self): - """Clear the document contents. - """ - self._theItem = None - self._docHandle = None - self._fileLoc = None - self._docMeta = {} - return - def readDocument(self, isOrphan=False): """Read a document from set handle, capturing potential file system errors and parse meta data. If the document doesn't exist @@ -68,11 +62,11 @@ class NWDoc(): """ self._docError = "" if not isHandle(self._docHandle): - self._docError = "No document handle set." + logger.error("No document handle set") return None if self._theItem is None and not isOrphan: - self._docError = "Unknown novelWriter document." + logger.error("Unknown novelWriter document") return None docFile = self._docHandle+".nwd" @@ -101,10 +95,6 @@ class NWDoc(): except Exception as e: self._docError = str(e) - # Note: Document must be cleared in case of an io error, - # or else the auto-save or save will try to overwrite it - # with an empty file. Return None to alert the caller. - self.clearDocument() return None else: @@ -121,7 +111,7 @@ class NWDoc(): """ self._docError = "" if not isHandle(self._docHandle): - self._docError = "No document handle set." + logger.error("No document handle set") return False self.theProject.ensureFolderStructure() @@ -164,7 +154,7 @@ class NWDoc(): """ self._docError = "" if not isHandle(self._docHandle): - self._docError = "No document handle set." + logger.error("No document handle set") return False docFile = self._docHandle+".nwd" diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 3a9fe5c4..ebcd16f1 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -75,7 +75,9 @@ class GuiDocEditor(QTextEdit): self.theTheme = theParent.theTheme self.theIndex = theParent.theIndex self.theProject = theParent.theProject - self.nwDocument = NWDoc(self.theProject, None) + + self.nwDocument = None + self.nwItem = None self.docChanged = False # Flag for changed status of document self.spellCheck = False # Flag for spell checking enabled @@ -165,7 +167,7 @@ class GuiDocEditor(QTextEdit): """Clear the current document and reset all document related flags and counters. """ - self.nwDocument = NWDoc(self.theProject, None) + self.nwDocument = None self.setReadOnly(True) self.clear() self.wcTimer.stop() @@ -298,6 +300,7 @@ class GuiDocEditor(QTextEdit): the file. """ self.nwDocument = NWDoc(self.theProject, tHandle) + self.nwItem = self.nwDocument.getCurrentItem() theDoc = self.nwDocument.readDocument() if theDoc is None: @@ -352,16 +355,15 @@ class GuiDocEditor(QTextEdit): self.updateDocMargins() self.hLight.spellCheck = spTemp - theItem = self.nwDocument.getCurrentItem() - if tLine is None and theItem is not None: + if tLine is None and self.nwItem is not None: # For large documents we queue the repositioning until the # document layout has grown past the point we want to move # the cursor to. This makes the loading significantly # faster. if docSize > 50000: - self.queuePos = theItem.cursorPos + self.queuePos = self.nwItem.cursorPos else: - self.setCursorPosition(theItem.cursorPos) + self.setCursorPosition(self.nwItem.cursorPos) else: self.setCursorLine(tLine) @@ -380,9 +382,9 @@ class GuiDocEditor(QTextEdit): self.setCursorPosition(0) # Update the status bar - if theItem is not None: + if self.nwItem is not None: self.theParent.setStatus( - self.tr("Opened Document: {0}").format(theItem.itemName) + self.tr("Opened Document: {0}").format(self.nwItem.itemName) ) return True @@ -431,19 +433,25 @@ class GuiDocEditor(QTextEdit): """Save the text currently in the editor to the NWDoc object, and update the NWItem meta data. """ - theItem = self.nwDocument.getCurrentItem() - if theItem is None: + if self.nwItem is None or self.nwDocument is None: + logger.error("Cannot save text as no document is open") + return False + + tHandle = self.nwItem.itemHandle + if self.theHandle != tHandle: + logger.error("Editor handle %s and item handle %s do not match" % ( + self.theHandle, tHandle + )) return False docText = self.getText() - tHandle = theItem.itemHandle cC, wC, pC = countWords(docText) self._updateCounts(cC, wC, pC) - theItem.setCharCount(self.charCount) - theItem.setWordCount(self.wordCount) - theItem.setParaCount(self.paraCount) + self.nwItem.setCharCount(self.charCount) + self.nwItem.setWordCount(self.wordCount) + self.nwItem.setParaCount(self.paraCount) self.saveCursorPosition() if not self.nwDocument.writeDocument(docText): @@ -472,7 +480,7 @@ class GuiDocEditor(QTextEdit): # Update the status bar self.theParent.setStatus( - self.tr("Saved Document: {0}").format(theItem.itemName) + self.tr("Saved Document: {0}").format(self.nwItem.itemName) ) return True @@ -599,10 +607,9 @@ class GuiDocEditor(QTextEdit): def saveCursorPosition(self): """Save the cursor position to the current project item object. """ - theItem = self.nwDocument.getCurrentItem() - if theItem is not None: + if self.nwItem is not None: cursPos = self.getCursorPosition() - theItem.setCursorPos(cursPos) + self.nwItem.setCursorPos(cursPos) return def setCursorLine(self, theLine): @@ -773,7 +780,7 @@ class GuiDocEditor(QTextEdit): """Tell the user where on the file system the file in the editor is saved. """ - if self.theHandle is None: + if self.nwDocument is None: logger.error("No document open") return False @@ -1140,8 +1147,7 @@ class GuiDocEditor(QTextEdit): def _updateCounts(self, cCount, wCount, pCount): """Slot for the word counter's finished signal """ - theItem = self.nwDocument.getCurrentItem() - if self.theHandle is None or theItem is None: + if self.theHandle is None or self.nwItem is None: return logger.verbose("Updating word count") @@ -1149,9 +1155,10 @@ class GuiDocEditor(QTextEdit): self.charCount = cCount self.wordCount = wCount self.paraCount = pCount - theItem.setCharCount(cCount) - theItem.setWordCount(wCount) - theItem.setParaCount(pCount) + + self.nwItem.setCharCount(cCount) + self.nwItem.setWordCount(wCount) + self.nwItem.setParaCount(pCount) self.theParent.treeView.propagateCount(self.theHandle, wCount) self.theParent.treeView.projectWordCount() diff --git a/tests/test_core/test_core_document.py b/tests/test_core/test_core_document.py index d44b3a08..82028d61 100644 --- a/tests/test_core/test_core_document.py +++ b/tests/test_core/test_core_document.py @@ -98,7 +98,7 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal): assert theDoc.getError() == "OSError" # Saving with no handle - theDoc.clearDocument() + theDoc._docHandle = None assert not theDoc.writeDocument(theText) # Delete the last document