From d473615ccf7b94297c92f765503522f7826a63f5 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sun, 25 Apr 2021 17:10:12 +0200 Subject: [PATCH] Rename open and save document to read and write in NWDoc --- nw/core/document.py | 8 +++---- nw/core/index.py | 2 +- nw/core/project.py | 30 +++++++++++++------------- nw/core/tokenizer.py | 7 ++++-- nw/dialogs/docmerge.py | 9 ++++---- nw/dialogs/docsplit.py | 15 ++++++++----- nw/gui/doceditor.py | 6 +++--- nw/gui/projtree.py | 7 ++++-- nw/guimain.py | 8 ++----- tests/test_core/test_core_document.py | 30 +++++++++++++------------- tests/test_core/test_core_tokenizer.py | 4 ++-- 11 files changed, 67 insertions(+), 59 deletions(-) diff --git a/nw/core/document.py b/nw/core/document.py index 1d7600c2..d9fe3268 100644 --- a/nw/core/document.py +++ b/nw/core/document.py @@ -68,8 +68,8 @@ class NWDoc(): self._docMeta = {} return - def openDocument(self, tHandle, showStatus=True, isOrphan=False): - """Open a document from handle, capturing potential file system + def readDocument(self, tHandle, showStatus=True, isOrphan=False): + """Read a document from handle, capturing potential file system errors and parse meta data. If the document doesn't exist on disk, return an empty string. If something went wrong, return None. @@ -134,8 +134,8 @@ class NWDoc(): return theText - def saveDocument(self, docText): - """Save the document. The file is saved via a temp file in case + def writeDocument(self, docText): + """Write the document. The file is saved via a temp file in case of save failure. Returns True if successful, False if not. """ if self._docHandle is None: diff --git a/nw/core/index.py b/nw/core/index.py index 986e4f93..6b8f53e3 100644 --- a/nw/core/index.py +++ b/nw/core/index.py @@ -117,7 +117,7 @@ class NWIndex(): return False theDoc = NWDoc(self.theProject, self.theParent) - theText = theDoc.openDocument(tHandle, showStatus=False) + theText = theDoc.readDocument(tHandle, showStatus=False) if theText: self.scanText(tHandle, theText) diff --git a/nw/core/project.py b/nw/core/project.py index 99bd0d1a..832e9c9b 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -284,16 +284,16 @@ class NWProject(): self.projTree.setFileItemLayout(xHandle[5], nwItemLayout.TITLE) self.projTree.setFileItemLayout(xHandle[7], nwItemLayout.CHAPTER) - aDoc.openDocument(xHandle[5], showStatus=False) - aDoc.saveDocument(titlePage) + aDoc.readDocument(xHandle[5], showStatus=False) + aDoc.writeDocument(titlePage) aDoc.clearDocument() - aDoc.openDocument(xHandle[7], showStatus=False) - aDoc.saveDocument("## %s\n\n" % self.tr("New Chapter")) + aDoc.readDocument(xHandle[7], showStatus=False) + aDoc.writeDocument("## %s\n\n" % self.tr("New Chapter")) aDoc.clearDocument() - aDoc.openDocument(xHandle[8], showStatus=False) - aDoc.saveDocument("### %s\n\n" % self.tr("New Scene")) + aDoc.readDocument(xHandle[8], showStatus=False) + aDoc.writeDocument("### %s\n\n" % self.tr("New Scene")) aDoc.clearDocument() elif popCustom: @@ -311,8 +311,8 @@ class NWProject(): tHandle = self.newFile(self.tr("Title Page"), nwItemClass.NOVEL, nHandle) self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE) - aDoc.openDocument(tHandle, showStatus=False) - aDoc.saveDocument(titlePage) + aDoc.readDocument(tHandle, showStatus=False) + aDoc.writeDocument(titlePage) aDoc.clearDocument() # Create chapters and scenes @@ -331,8 +331,8 @@ class NWProject(): cHandle = self.newFile(chTitle, nwItemClass.NOVEL, pHandle) self.projTree.setFileItemLayout(cHandle, nwItemLayout.CHAPTER) - aDoc.openDocument(cHandle, showStatus=False) - aDoc.saveDocument("## %s\n\n" % chTitle) + aDoc.readDocument(cHandle, showStatus=False) + aDoc.writeDocument("## %s\n\n" % chTitle) aDoc.clearDocument() # Create chapter scenes @@ -341,8 +341,8 @@ class NWProject(): scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}") sHandle = self.newFile(scTitle, nwItemClass.NOVEL, pHandle) - aDoc.openDocument(sHandle, showStatus=False) - aDoc.saveDocument("### %s\n\n" % scTitle) + aDoc.readDocument(sHandle, showStatus=False) + aDoc.writeDocument("### %s\n\n" % scTitle) aDoc.clearDocument() # Create scenes (no chapters) @@ -351,8 +351,8 @@ class NWProject(): scTitle = self.tr("Scene {0}").format(f"{sc+1:d}") sHandle = self.newFile(scTitle, nwItemClass.NOVEL, nHandle) - aDoc.openDocument(sHandle, showStatus=False) - aDoc.saveDocument("### %s\n\n" % scTitle) + aDoc.readDocument(sHandle, showStatus=False) + aDoc.writeDocument("### %s\n\n" % scTitle) aDoc.clearDocument() # Finalise @@ -1404,7 +1404,7 @@ class NWProject(): oParent = None oClass = None oLayout = None - if aDoc.openDocument(oHandle, showStatus=False, isOrphan=True) is not None: + if aDoc.readDocument(oHandle, showStatus=False, isOrphan=True) is not None: oName, oParent, oClass, oLayout = aDoc.getMeta() if oName: diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py index 921f7cef..713d2dd5 100644 --- a/nw/core/tokenizer.py +++ b/nw/core/tokenizer.py @@ -278,13 +278,16 @@ class Tokenizer(): if self.theItem is None: return False + self.theText = "" if theText is not None: # If the text is set, just use that self.theText = theText else: # Otherwise, load it from file - theDocument = NWDoc(self.theProject, self.theParent) - self.theText = theDocument.openDocument(theHandle) + theDoc = NWDoc(self.theProject, self.theParent) + theText = theDoc.readDocument(theHandle) + if theText: + self.theText = theText docSize = len(self.theText) if docSize > nwConst.MAX_DOCSIZE: diff --git a/nw/dialogs/docmerge.py b/nw/dialogs/docmerge.py index 4a6fe00f..4dd397c5 100644 --- a/nw/dialogs/docmerge.py +++ b/nw/dialogs/docmerge.py @@ -110,8 +110,9 @@ class GuiDocMerge(QDialog): theDoc = NWDoc(self.theProject, self.theParent) theText = "" for tHandle in finalOrder: - theText += theDoc.openDocument(tHandle, False).rstrip("\n") - theText += "\n\n" + docText = theDoc.readDocument(tHandle, False).rstrip("\n") + if docText: + theText += docText+"\n\n" if self.sourceItem is None: self.theParent.makeAlert( @@ -130,8 +131,8 @@ class GuiDocMerge(QDialog): newItem = self.theProject.projTree[nHandle] newItem.setStatus(srcItem.itemStatus) - theDoc.openDocument(nHandle, False) - theDoc.saveDocument(theText) + theDoc.readDocument(nHandle, False) + theDoc.writeDocument(theText) self.theParent.treeView.revealNewTreeItem(nHandle) self.theParent.openDocument(nHandle, doScroll=True) diff --git a/nw/dialogs/docsplit.py b/nw/dialogs/docsplit.py index da5b27f0..184e7089 100644 --- a/nw/dialogs/docsplit.py +++ b/nw/dialogs/docsplit.py @@ -127,8 +127,11 @@ class GuiDocSplit(QDialog): ) return - theDoc = NWDoc(self.theProject, self.theParent) - theText = theDoc.openDocument(self.sourceItem, False) + theDoc = NWDoc(self.theProject, self.theParent) + theText = theDoc.readDocument(self.sourceItem, False) + if theText is None: + theText = "" + theLines = theText.splitlines() nLines = len(theLines) theLines.insert(0, "%Split Doc") @@ -214,8 +217,8 @@ class GuiDocSplit(QDialog): theText = "\n".join(theLines[iStart:iEnd]) theText = theText.rstrip("\n") + "\n\n" - theDoc.openDocument(nHandle, False) - theDoc.saveDocument(theText) + theDoc.readDocument(nHandle, False) + theDoc.writeDocument(theText) theDoc.clearDocument() self.theParent.treeView.revealNewTreeItem(nHandle) @@ -257,7 +260,9 @@ class GuiDocSplit(QDialog): self.listBox.clear() theDoc = NWDoc(self.theProject, self.theParent) - theText = theDoc.openDocument(self.sourceItem, False) + theText = theDoc.readDocument(self.sourceItem, False) + if theText is None: + theText = "" spLevel = self.splitLevel.currentData() self.optState.setValue("GuiDocSplit", "spLevel", spLevel) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 91abfce9..6e6f74c9 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -297,7 +297,7 @@ class GuiDocEditor(QTextEdit): document is new (empty string), we set up the editor for editing the file. """ - theDoc = self.nwDocument.openDocument(tHandle, showStatus=showStatus) + theDoc = self.nwDocument.readDocument(tHandle, showStatus=showStatus) if theDoc is None: # There was an io error self.clearEditor() @@ -438,7 +438,7 @@ class GuiDocEditor(QTextEdit): theItem.setParaCount(self.paraCount) self.saveCursorPosition() - self.nwDocument.saveDocument(docText) + self.nwDocument.writeDocument(docText) self.setDocumentChanged(False) self.theIndex.scanText(tHandle, docText) @@ -454,7 +454,7 @@ class GuiDocEditor(QTextEdit): if self.theProject.projTree.updateItemLayout(tHandle, hLevel): self.theParent.treeView.setTreeItemValues(tHandle) - self.nwDocument.saveDocument(docText) + self.nwDocument.writeDocument(docText) self.docFooter.updateInfo() return True diff --git a/nw/gui/projtree.py b/nw/gui/projtree.py index e0d5b4b3..dfa71b67 100644 --- a/nw/gui/projtree.py +++ b/nw/gui/projtree.py @@ -287,7 +287,10 @@ class GuiProjectTree(QTreeWidget): # This is a new files, so let's add some content newDoc = NWDoc(self.theProject, self.theParent) - curTxt = newDoc.openDocument(tHandle, showStatus=False) + curTxt = newDoc.readDocument(tHandle, showStatus=False) + if curTxt is None: + curTxt = "" + if curTxt == "": if nwItem.itemLayout == nwItemLayout.CHAPTER: newText = f"## {nwItem.itemName}\n\n" @@ -299,7 +302,7 @@ class GuiProjectTree(QTreeWidget): newText = f"# {nwItem.itemName}\n\n" # Save the text and index it - newDoc.saveDocument(newText) + newDoc.writeDocument(newText) self.theIndex.scanText(tHandle, newText) # Get Word Counts diff --git a/nw/guimain.py b/nw/guimain.py index 300c00a7..aff3bea0 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -48,7 +48,7 @@ from nw.dialogs import ( GuiProjectLoad, GuiProjectSettings, GuiWordList ) from nw.tools import GuiBuildNovel, GuiProjectWizard, GuiWritingStats -from nw.core import NWProject, NWDoc, NWIndex +from nw.core import NWProject, NWIndex from nw.enum import nwItemType, nwItemClass, nwAlert, nwWidget from nw.common import getGuiItem, hexToInt from nw.constants import nwLists @@ -878,7 +878,6 @@ class GuiMain(QMainWindow): self.treeView.saveTreeOrder() self.theIndex.clearIndex() - theDoc = NWDoc(self.theProject, self) for nDone, tItem in enumerate(self.theProject.projTree): if tItem is not None: @@ -888,10 +887,7 @@ class GuiMain(QMainWindow): if tItem is not None and tItem.itemType == nwItemType.FILE: logger.verbose("Scanning: %s" % tItem.itemName) - theText = theDoc.openDocument(tItem.itemHandle, showStatus=False) - - # Build tag index - self.theIndex.scanText(tItem.itemHandle, theText) + self.theIndex.reIndexHandle(tItem.itemHandle) # Get Word Counts cC, wC, pC = self.theIndex.getCounts(tItem.itemHandle) diff --git a/tests/test_core/test_core_document.py b/tests/test_core/test_core_document.py index 1eab9824..df02ea1b 100644 --- a/tests/test_core/test_core_document.py +++ b/tests/test_core/test_core_document.py @@ -41,10 +41,10 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal): sHandle = "8c659a11cd429" # Not a valid handle - assert theDoc.openDocument("dummy") is None + assert theDoc.readDocument("dummy") is None # Non-existent handle - assert theDoc.openDocument("0000000000000") is None + assert theDoc.readDocument("0000000000000") is None # Cause open() to fail while loading def dummyOpen(*args, **kwargs): @@ -52,29 +52,29 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal): with monkeypatch.context() as mp: mp.setattr("builtins.open", dummyOpen) - assert theDoc.openDocument(sHandle) is None + assert theDoc.readDocument(sHandle) is None # Load the text - assert theDoc.openDocument(sHandle) == "### New Scene\n\n" + assert theDoc.readDocument(sHandle) == "### New Scene\n\n" # Try to open a new (non-existent) file nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL) assert nHandle is not None xHandle = theProject.newFile("New File", nwItemClass.NOVEL, nHandle) - assert theDoc.openDocument(xHandle) == "" + assert theDoc.readDocument(xHandle) == "" # Check cached item assert isinstance(theDoc._theItem, NWItem) - assert theDoc.openDocument(xHandle, isOrphan=True) == "" + assert theDoc.readDocument(xHandle, isOrphan=True) == "" assert theDoc._theItem is None # Set handle and save again theText = "### Test File\n\nText ...\n\n" - assert theDoc.openDocument(xHandle) == "" - assert theDoc.saveDocument(theText) + assert theDoc.readDocument(xHandle) == "" + assert theDoc.writeDocument(theText) # Save again to ensure temp file and previous file is handled - assert theDoc.saveDocument(theText) + assert theDoc.writeDocument(theText) # Check file content docPath = os.path.join(nwMinimal, "content", xHandle+".nwd") @@ -89,7 +89,7 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal): # Force no meta data theDoc._theItem = None - assert theDoc.saveDocument(theText) + assert theDoc.writeDocument(theText) with open(docPath, mode="r", encoding="utf8") as inFile: assert inFile.read() == theText @@ -97,11 +97,11 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal): # Cause open() to fail while saving with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) - assert not theDoc.saveDocument(theText) + assert not theDoc.writeDocument(theText) # Saving with no handle theDoc.clearDocument() - assert not theDoc.saveDocument(theText) + assert not theDoc.writeDocument(theText) # Delete the last document assert not theDoc.deleteDocument("dummy") @@ -130,7 +130,7 @@ def testCoreDocument_Methods(monkeypatch, dummyGUI, nwMinimal): sHandle = "8c659a11cd429" docPath = os.path.join(nwMinimal, "content", sHandle+".nwd") - assert theDoc.openDocument(sHandle) == "### New Scene\n\n" + assert theDoc.readDocument(sHandle) == "### New Scene\n\n" # Check location assert theDoc.getFileLocation() == docPath @@ -147,7 +147,7 @@ def testCoreDocument_Methods(monkeypatch, dummyGUI, nwMinimal): assert theLayout == nwItemLayout.SCENE # Add meta data garbage - assert theDoc.saveDocument("%%~ stuff\n### Test File\n\nText ...\n\n") + assert theDoc.writeDocument("%%~ stuff\n### Test File\n\nText ...\n\n") with open(docPath, mode="r", encoding="utf8") as inFile: assert inFile.read() == ( "%%~name: New Scene\n" @@ -158,6 +158,6 @@ def testCoreDocument_Methods(monkeypatch, dummyGUI, nwMinimal): "Text ...\n\n" ) - assert theDoc.openDocument(sHandle) == "### Test File\n\nText ...\n\n" + assert theDoc.readDocument(sHandle) == "### Test File\n\nText ...\n\n" # END Test testCoreDocument_Methods diff --git a/tests/test_core/test_core_tokenizer.py b/tests/test_core/test_core_tokenizer.py index 4062f710..743c45f5 100644 --- a/tests/test_core/test_core_tokenizer.py +++ b/tests/test_core/test_core_tokenizer.py @@ -138,8 +138,8 @@ def testCoreToken_TextOps(monkeypatch, nwMinimal, dummyGUI): docTextR = docText.replace("", "this").replace("", "that") nDoc = NWDoc(theProject, dummyGUI) - nDoc.openDocument(sHandle) - nDoc.saveDocument(docText) + nDoc.readDocument(sHandle) + nDoc.writeDocument(docText) nDoc.clearDocument() theProject.setAutoReplace({"A": "this", "B": "that"})