Finished saving and loading of document tree and tree state.

This commit is contained in:
Veronica K. B. Olsen
2018-10-30 21:20:12 +01:00
parent 02ed230c24
commit e72e82afca
5 changed files with 65 additions and 27 deletions
+6 -5
View File
@@ -50,21 +50,22 @@ class GuiDocTree(QTreeWidget):
def saveTreeOrder(self): def saveTreeOrder(self):
theList = [] theList = []
for i in range(self.topLevelItemCount()): 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) self.theProject.setTreeOrder(theList)
return True return True
def _scanChildren(self, theList, theItem): def _scanChildren(self, theList, theItem, theIndex):
tHandle = theItem.text(3) tHandle = theItem.text(3)
nwItem = self.theProject.projTree[tHandle] nwItem = self.theProject.projTree[tHandle]
nwItem.setExpanded(theItem.isExpanded()) nwItem.setExpanded(theItem.isExpanded())
nwItem.setOrder(theIndex)
theList.append(tHandle) theList.append(tHandle)
for i in range(theItem.childCount()): for i in range(theItem.childCount()):
self._scanChildren(theList, theItem.child(i)) self._scanChildren(theList, theItem.child(i), i)
return theList return theList
def buildTree(self): def buildTree(self):
self.clear()
for tHandle in self.theProject.projTree: for tHandle in self.theProject.projTree:
nwItem = self.theProject.projTree[tHandle] nwItem = self.theProject.projTree[tHandle]
tName = nwItem.itemName tName = nwItem.itemName
@@ -79,7 +80,7 @@ class GuiDocTree(QTreeWidget):
self.addTopLevelItem(newItem) self.addTopLevelItem(newItem)
else: else:
self.theMap[pHandle].addChild(newItem) self.theMap[pHandle].addChild(newItem)
newItem.setExpanded(nwItem.isExpanded)
return True return True
def getColumnSizes(self): def getColumnSizes(self):
+2
View File
@@ -86,6 +86,7 @@ class GuiMain(QMainWindow):
self,"Open novelWriter Project","","novelWriter Project File (nwProject.nwx);;All Files (*)", options=dlgOpt) self,"Open novelWriter Project","","novelWriter Project File (nwProject.nwx);;All Files (*)", options=dlgOpt)
if projPath: if projPath:
self.theProject.openProject(projPath) self.theProject.openProject(projPath)
self.treeView.buildTree()
self._setWindowTitle(self.theProject.projName) self._setWindowTitle(self.theProject.projName)
else: else:
return False return False
@@ -113,6 +114,7 @@ class GuiMain(QMainWindow):
def openRecentProject(self, recentItem): def openRecentProject(self, recentItem):
logger.vverbose("User requested opening recent project #%d" % recentItem) logger.vverbose("User requested opening recent project #%d" % recentItem)
self.theProject.openProject(self.mainConf.recentList[recentItem]) self.theProject.openProject(self.mainConf.recentList[recentItem])
self.treeView.buildTree()
self._setWindowTitle(self.theProject.projName) self._setWindowTitle(self.theProject.projName)
return True return True
+13 -1
View File
@@ -42,6 +42,15 @@ class NWItem():
return 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): def setName(self, theName):
self.itemName = theName.strip() self.itemName = theName.strip()
return return
@@ -89,7 +98,10 @@ class NWItem():
return return
def setExpanded(self, expState): def setExpanded(self, expState):
self.isExpanded = expState if isinstance(expState, str):
self.isExpanded = expState == str(True)
else:
self.isExpanded = expState
return return
def getType(self): def getType(self):
+36 -13
View File
@@ -16,7 +16,8 @@ import nw
from os import path, mkdir from os import path, mkdir
from lxml import etree from lxml import etree
from hashlib import sha256 from hashlib import sha256
from datetime import datetime, time from datetime import datetime
from time import time
from nw.project.item import NWItem from nw.project.item import NWItem
@@ -28,7 +29,6 @@ class NWProject():
# Internal # Internal
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.seedCount = 0
# Project Settings # Project Settings
self.projTree = {} self.projTree = {}
@@ -92,6 +92,7 @@ class NWProject():
return False return False
self.projPath = path.dirname(fileName) self.projPath = path.dirname(fileName)
logger.debug("Opening project: %s" % self.projPath)
nwXML = etree.parse(fileName) nwXML = etree.parse(fileName)
xRoot = nwXML.getroot() xRoot = nwXML.getroot()
@@ -109,7 +110,7 @@ class NWProject():
for xChild in xRoot: for xChild in xRoot:
if xChild.tag == "project": if xChild.tag == "project":
logger.debug("Found book data") logger.debug("Found project meta")
for xItem in xChild: for xItem in xChild:
if xItem.text is None: continue if xItem.text is None: continue
if xItem.tag == "name": if xItem.tag == "name":
@@ -121,7 +122,24 @@ class NWProject():
elif xItem.tag == "author": elif xItem.tag == "author":
logger.verbose("Author: '%s'" % xItem.text) logger.verbose("Author: '%s'" % xItem.text)
self.bookAuthors.append(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) self.mainConf.setRecent(self.projPath)
return True return True
@@ -136,7 +154,10 @@ class NWProject():
logger.info("Created folder %s" % self.projPath) logger.info("Created folder %s" % self.projPath)
mkdir(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={ nwXML = etree.Element("novelWriterXML",attrib={
"fileVersion" : "1.0", "fileVersion" : "1.0",
"appVersion" : str(nw.__version__), "appVersion" : str(nw.__version__),
@@ -153,6 +174,7 @@ class NWProject():
xBookAuthor.text = bookAuthor xBookAuthor.text = bookAuthor
# Save Tree Content # Save Tree Content
logger.debug("Writing project content")
xContent = etree.SubElement(nwXML,"content",attrib={"count":str(len(self.projTree))}) xContent = etree.SubElement(nwXML,"content",attrib={"count":str(len(self.projTree))})
itemIdx = 0 itemIdx = 0
for tHandle in self.treeOrder: for tHandle in self.treeOrder:
@@ -167,10 +189,11 @@ class NWProject():
xItemType = etree.SubElement(xItem,"type") xItemType = etree.SubElement(xItem,"type")
xItemType.text = str(nwItem.getType()) xItemType.text = str(nwItem.getType())
if nwItem.getClass() is not "NONE": if nwItem.getClass() is not "NONE":
xItemClass = etree.SubElement(xItem,"class") xItemValue = etree.SubElement(xItem,"class")
xItemClass.text = str(nwItem.getClass()) xItemValue.text = str(nwItem.getClass())
if nwItem.isExpanded: if nwItem.isExpanded:
xItemExpanded = etree.SubElement(xItem,"expanded") xItemValue = etree.SubElement(xItem,"expanded")
xItemValue.text = str(nwItem.isExpanded)
# Write the xml tree to file # Write the xml tree to file
with open(path.join(self.projPath,self.projFile),"wb") as outFile: with open(path.join(self.projPath,self.projFile),"wb") as outFile:
@@ -230,13 +253,13 @@ class NWProject():
self.treeOrder.append(tHandle) self.treeOrder.append(tHandle)
return return
def _makeHandle(self, seed=""): def _makeHandle(self, addSeed=""):
seed += str(self.seedCount) newSeed = str(time()) + addSeed
self.seedCount += 1 logger.vverbose("Generating handle with seed '%s'" % newSeed)
itemHandle = sha256((str(time())+seed).encode()).hexdigest()[0:13] itemHandle = sha256(newSeed.encode()).hexdigest()[0:13]
if itemHandle in self.projTree.keys(): if itemHandle in self.projTree.keys():
logger.warning("Duplicate handle encountered! Retrying ...") logger.warning("Duplicate handle encountered! Retrying ...")
itemHandle = self._makeHandle(seed+"!") itemHandle = self._makeHandle(addSeed+"!")
return itemHandle return itemHandle
def _checkString(self,checkValue,defaultValue,allowNone=False): def _checkString(self,checkValue,defaultValue,allowNone=False):
+8 -8
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.1.0" fileVersion="1.0" timeStamp="2018-10-28 22:31:56"> <novelWriterXML appVersion="0.1.0" fileVersion="1.0" timeStamp="2018-10-30 21:03:03">
<project> <project>
<name>Sample Project</name> <name>Sample Project</name>
<title>Sample Project</title> <title>Sample Project</title>
@@ -7,27 +7,27 @@
<author>Jay Doh</author> <author>Jay Doh</author>
</project> </project>
<content count="5"> <content count="5">
<item handle="7031beac91f75" order="None" parent="None"> <item handle="7031beac91f75" order="0" parent="None">
<name>Novel</name> <name>Novel</name>
<type>ROOT</type> <type>ROOT</type>
<class>NOVEL</class> <class>NOVEL</class>
<expanded/> <expanded>True</expanded>
</item> </item>
<item handle="e7ded148d6e4a" order="None" parent="7031beac91f75"> <item handle="e7ded148d6e4a" order="0" parent="7031beac91f75">
<name>New Chapter</name> <name>New Chapter</name>
<type>FOLDER</type> <type>FOLDER</type>
<expanded/> <expanded>True</expanded>
</item> </item>
<item handle="96b68994dfa3d" order="None" parent="e7ded148d6e4a"> <item handle="96b68994dfa3d" order="0" parent="e7ded148d6e4a">
<name>New Scene</name> <name>New Scene</name>
<type>FILE</type> <type>FILE</type>
</item> </item>
<item handle="f6622b4617424" order="None" parent="None"> <item handle="f6622b4617424" order="1" parent="None">
<name>Characters</name> <name>Characters</name>
<type>ROOT</type> <type>ROOT</type>
<class>CHARACTER</class> <class>CHARACTER</class>
</item> </item>
<item handle="73eee34351f85" order="None" parent="None"> <item handle="73eee34351f85" order="2" parent="None">
<name>World</name> <name>World</name>
<type>ROOT</type> <type>ROOT</type>
<class>WORLD</class> <class>WORLD</class>