From e72e82afcaaf4eaef9f1f8837698b22835764ad8 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" Date: Tue, 30 Oct 2018 21:20:12 +0100 Subject: [PATCH] Finished saving and loading of document tree and tree state. --- nw/gui/doctree.py | 11 +++---- nw/gui/winmain.py | 2 ++ nw/project/item.py | 14 ++++++++- nw/project/project.py | 49 +++++++++++++++++++++++--------- sample/sampleNovel/nwProject.nwx | 16 +++++------ 5 files changed, 65 insertions(+), 27 deletions(-) diff --git a/nw/gui/doctree.py b/nw/gui/doctree.py index 7504d9fb..d0e24f93 100644 --- a/nw/gui/doctree.py +++ b/nw/gui/doctree.py @@ -50,21 +50,22 @@ class GuiDocTree(QTreeWidget): def saveTreeOrder(self): theList = [] for i in range(self.topLevelItemCount()): - theList = self._scanChildren(theList, self.topLevelItem(i)) + theList = self._scanChildren(theList, self.topLevelItem(i), i) self.theProject.setTreeOrder(theList) return True - def _scanChildren(self, theList, theItem): + def _scanChildren(self, theList, theItem, theIndex): tHandle = theItem.text(3) nwItem = self.theProject.projTree[tHandle] nwItem.setExpanded(theItem.isExpanded()) + nwItem.setOrder(theIndex) theList.append(tHandle) for i in range(theItem.childCount()): - self._scanChildren(theList, theItem.child(i)) + self._scanChildren(theList, theItem.child(i), i) return theList def buildTree(self): - + self.clear() for tHandle in self.theProject.projTree: nwItem = self.theProject.projTree[tHandle] tName = nwItem.itemName @@ -79,7 +80,7 @@ class GuiDocTree(QTreeWidget): self.addTopLevelItem(newItem) else: self.theMap[pHandle].addChild(newItem) - + newItem.setExpanded(nwItem.isExpanded) return True def getColumnSizes(self): diff --git a/nw/gui/winmain.py b/nw/gui/winmain.py index 3d3f6bcd..c0b49fb0 100644 --- a/nw/gui/winmain.py +++ b/nw/gui/winmain.py @@ -86,6 +86,7 @@ class GuiMain(QMainWindow): self,"Open novelWriter Project","","novelWriter Project File (nwProject.nwx);;All Files (*)", options=dlgOpt) if projPath: self.theProject.openProject(projPath) + self.treeView.buildTree() self._setWindowTitle(self.theProject.projName) else: return False @@ -113,6 +114,7 @@ class GuiMain(QMainWindow): def openRecentProject(self, recentItem): logger.vverbose("User requested opening recent project #%d" % recentItem) self.theProject.openProject(self.mainConf.recentList[recentItem]) + self.treeView.buildTree() self._setWindowTitle(self.theProject.projName) return True diff --git a/nw/project/item.py b/nw/project/item.py index 2d68e596..93d8d9b8 100644 --- a/nw/project/item.py +++ b/nw/project/item.py @@ -42,6 +42,15 @@ class NWItem(): return + def setFromTag(self, tagName, tagValue): + logger.verbose("Setting tag '%s' to value '%s'" % (tagName, str(tagValue))) + if tagName == "name": self.setName(tagValue) + elif tagName == "order": self.setOrder(tagValue) + elif tagName == "type": self.setType(tagValue) + elif tagName == "class": self.setClass(tagValue) + elif tagName == "expanded": self.setExpanded(tagValue) + return + def setName(self, theName): self.itemName = theName.strip() return @@ -89,7 +98,10 @@ class NWItem(): return def setExpanded(self, expState): - self.isExpanded = expState + if isinstance(expState, str): + self.isExpanded = expState == str(True) + else: + self.isExpanded = expState return def getType(self): diff --git a/nw/project/project.py b/nw/project/project.py index 916b0e96..fbf14093 100644 --- a/nw/project/project.py +++ b/nw/project/project.py @@ -16,7 +16,8 @@ import nw from os import path, mkdir from lxml import etree from hashlib import sha256 -from datetime import datetime, time +from datetime import datetime +from time import time from nw.project.item import NWItem @@ -28,7 +29,6 @@ class NWProject(): # Internal self.mainConf = nw.CONFIG - self.seedCount = 0 # Project Settings self.projTree = {} @@ -92,6 +92,7 @@ class NWProject(): return False self.projPath = path.dirname(fileName) + logger.debug("Opening project: %s" % self.projPath) nwXML = etree.parse(fileName) xRoot = nwXML.getroot() @@ -109,7 +110,7 @@ class NWProject(): for xChild in xRoot: if xChild.tag == "project": - logger.debug("Found book data") + logger.debug("Found project meta") for xItem in xChild: if xItem.text is None: continue if xItem.tag == "name": @@ -121,7 +122,24 @@ class NWProject(): elif xItem.tag == "author": logger.verbose("Author: '%s'" % xItem.text) self.bookAuthors.append(xItem.text) - + elif xChild.tag == "content": + logger.debug("Found project content") + for xItem in xChild: + itemAttrib = xItem.attrib + if "handle" in xItem.attrib: + tHandle = itemAttrib["handle"] + else: + logger.error("Skipping rntry missing handle") + continue + if "parent" in xItem.attrib: + pHandle = itemAttrib["parent"] + else: + pHandle = None + nwItem = NWItem() + for xValue in xItem: + nwItem.setFromTag(xValue.tag,xValue.text) + self._appendItem(tHandle,pHandle,nwItem) + self.mainConf.setRecent(self.projPath) return True @@ -136,7 +154,10 @@ class NWProject(): logger.info("Created folder %s" % self.projPath) mkdir(self.projPath) - # Root element and book details + logger.debug("Saving project: %s" % self.projPath) + + # Root element and project details + logger.debug("Writing project meta") nwXML = etree.Element("novelWriterXML",attrib={ "fileVersion" : "1.0", "appVersion" : str(nw.__version__), @@ -153,6 +174,7 @@ class NWProject(): xBookAuthor.text = bookAuthor # Save Tree Content + logger.debug("Writing project content") xContent = etree.SubElement(nwXML,"content",attrib={"count":str(len(self.projTree))}) itemIdx = 0 for tHandle in self.treeOrder: @@ -167,10 +189,11 @@ class NWProject(): xItemType = etree.SubElement(xItem,"type") xItemType.text = str(nwItem.getType()) if nwItem.getClass() is not "NONE": - xItemClass = etree.SubElement(xItem,"class") - xItemClass.text = str(nwItem.getClass()) + xItemValue = etree.SubElement(xItem,"class") + xItemValue.text = str(nwItem.getClass()) if nwItem.isExpanded: - xItemExpanded = etree.SubElement(xItem,"expanded") + xItemValue = etree.SubElement(xItem,"expanded") + xItemValue.text = str(nwItem.isExpanded) # Write the xml tree to file with open(path.join(self.projPath,self.projFile),"wb") as outFile: @@ -230,13 +253,13 @@ class NWProject(): self.treeOrder.append(tHandle) return - def _makeHandle(self, seed=""): - seed += str(self.seedCount) - self.seedCount += 1 - itemHandle = sha256((str(time())+seed).encode()).hexdigest()[0:13] + def _makeHandle(self, addSeed=""): + newSeed = str(time()) + addSeed + logger.vverbose("Generating handle with seed '%s'" % newSeed) + itemHandle = sha256(newSeed.encode()).hexdigest()[0:13] if itemHandle in self.projTree.keys(): logger.warning("Duplicate handle encountered! Retrying ...") - itemHandle = self._makeHandle(seed+"!") + itemHandle = self._makeHandle(addSeed+"!") return itemHandle def _checkString(self,checkValue,defaultValue,allowNone=False): diff --git a/sample/sampleNovel/nwProject.nwx b/sample/sampleNovel/nwProject.nwx index 1dda2c5b..0c881926 100644 --- a/sample/sampleNovel/nwProject.nwx +++ b/sample/sampleNovel/nwProject.nwx @@ -1,5 +1,5 @@ - + Sample Project Sample Project @@ -7,27 +7,27 @@ Jay Doh - + Novel ROOT NOVEL - + True - + New Chapter FOLDER - + True - + New Scene FILE - + Characters ROOT CHARACTER - + World ROOT WORLD