Finished saving and loading of document tree and tree state.
This commit is contained in:
+6
-5
@@ -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):
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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):
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user