Moved a couple more functions to the NWTree class, and cleaned up the source file a bit

This commit is contained in:
Veronica K. B. Olsen
2020-05-07 23:59:32 +02:00
parent 5b3291e4ee
commit d75243418f
2 changed files with 96 additions and 66 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ class GuiDocTitleBar(QLabel):
if self.mainConf.showFullPath: if self.mainConf.showFullPath:
tTitle = [] tTitle = []
tTree = self.theProject.getItemPath(tHandle) tTree = self.theProject.projTree.getItemPath(tHandle)
for aHandle in reversed(tTree): for aHandle in reversed(tTree):
nwItem = self.theProject.projTree[aHandle] nwItem = self.theProject.projTree[aHandle]
if nwItem is not None: if nwItem is not None:
+95 -65
View File
@@ -6,9 +6,12 @@
Class holding a project Class holding a project
File History: File History:
Created: 2018-09-29 [0.0.1] Created: 2018-09-29 [0.0.1] NWProject
Merged: 2020-05-07 [0.4.5] Merged NWItem class into file Added: 2018-10-27 [0.0.1] NWItem
Merged: 2020-05-07 [0.4.5] Merged NWStatus class into file Added: 2019-05-19 [0.1.3] NWStatus
Merged: 2020-05-07 [0.4.5] Moved NWItem class to this file
Merged: 2020-05-07 [0.4.5] Moved NWStatus class to this file
Added: 2020-05-07 [0.4.5] NWTree
This file is a part of novelWriter This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen Copyright 2020, Veronica Berglyd Olsen
@@ -49,9 +52,14 @@ class NWProject():
def __init__(self, theParent): def __init__(self, theParent):
# Internal # Internal
self.theParent = theParent self.theParent = theParent
self.mainConf = self.theParent.mainConf self.mainConf = nw.CONFIG
self.optState = OptionState(self)
# Core Elements
self.optState = OptionState(self) # Project-specific GUI options
self.projTree = NWTree(self) # The project tree
# Project Status
self.projOpened = None # The time stamp of when the project file was opened self.projOpened = None # The time stamp of when the project file was opened
self.projChanged = None # The project has unsaved changes self.projChanged = None # The project has unsaved changes
self.projAltered = None # The project has been altered this session self.projAltered = None # The project has been altered this session
@@ -60,11 +68,10 @@ class NWProject():
self.autoCount = None # Meta data: number of automatic saves self.autoCount = None # Meta data: number of automatic saves
# Class Settings # Class Settings
self.projTree = NWTree(self)
self.projPath = None # The full path to where the currently open project is saved self.projPath = None # The full path to where the currently open project is saved
self.projMeta = None # The full path to the project's meta data folder self.projMeta = None # The full path to the project's meta data folder
self.projDict = None # The spell check dictionary self.projDict = None # The spell check dictionary
self.projFile = None # The file name of the project main xml file self.projFile = None # The file name of the project main XML file
# Project Meta # Project Meta
self.projName = None self.projName = None
@@ -154,6 +161,9 @@ class NWProject():
## ##
def newProject(self): def newProject(self):
"""Create a new project by populating the project tree with a
few starter items.
"""
hNovel = self.newRoot("Novel", nwItemClass.NOVEL) hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
hChars = self.newRoot("Characters", nwItemClass.CHARACTER) hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
hWorld = self.newRoot("Plot", nwItemClass.PLOT) hWorld = self.newRoot("Plot", nwItemClass.PLOT)
@@ -469,7 +479,7 @@ class NWProject():
return True return True
## ##
# Set Functions # Setters
## ##
def setProjectPath(self, projPath): def setProjectPath(self, projPath):
@@ -590,60 +600,25 @@ class NWProject():
return self.projChanged return self.projChanged
## ##
# Get Functions # Getters
## ##
def getSessionWordCount(self): def getSessionWordCount(self):
"""Returns the number of words added or removed this session.
"""
return self.currWCount - self.lastWCount return self.currWCount - self.lastWCount
def getRootItem(self, tHandle):
"""Iterate upwards in the tree until we find the item with
parent None, the root item. We do this with a for loop with a
maximum depth of 200 to make infinite loops impossible.
"""
tItem = self.projTree[tHandle]
if tItem is not None:
for i in range(200):
if tItem.parHandle is None:
return tHandle
else:
tHandle = tItem.parHandle
tItem = self.projTree[tHandle]
if tItem is None:
return tHandle
return None
def getItemPath(self, tHandle):
"""Iterate upwards in the tree until we find the item with
parent None, the root item, and return the list of handles.
We do this with a for loop with a maximum depth of 200 to make
infinite loops impossible.
"""
tTree = []
tItem = self.projTree[tHandle]
if tItem is not None:
tTree.append(tHandle)
for i in range(200):
if tItem.parHandle is None:
return tTree
else:
tHandle = tItem.parHandle
tItem = self.projTree[tHandle]
if tItem is None:
return tTree
else:
tTree.append(tHandle)
return tTree
def getProjectItems(self): def getProjectItems(self):
"""This function is called from the tree view when building the """This function ensures that the item tree loaded is sent to
tree. Each item in the project is returned in the order saved in the GUI tree view in such a way that the tree can be built. That
the project file, but first it checks that it has a parent item is, the parent item must be sent before its child. In principle,
already sent to the tree. a proper XML file will already ensure that, but in the event the
order has been altered, or a file is orphaned, this function is
capable of handling it.
""" """
sentItems = [] sentItems = []
iterItems = self.projTree.handles() iterItems = self.projTree.handles()
n = 0 n = 0
nMax = len(iterItems) nMax = len(iterItems)
while n < nMax: while n < nMax:
tHandle = iterItems[n] tHandle = iterItems[n]
@@ -786,6 +761,11 @@ class NWProject():
return return
def _scanProjectFolder(self): def _scanProjectFolder(self):
"""Scan the project folder and check that the files in it are
also in the project CML file. If they aren't, import them as
orphaned files so the user can either delete them, or put them
back into the project tree.
"""
if self.projPath is None: if self.projPath is None:
return return
@@ -829,16 +809,18 @@ class NWProject():
nOrph = 0 nOrph = 0
for oHandle in orphanFiles: for oHandle in orphanFiles:
nOrph += 1 nOrph += 1
orItem = NWItem(self) orphItem = NWItem(self)
orItem.setName("Orphaned File %d" % nOrph) orphItem.setName("Orphaned File %d" % nOrph)
orItem.setType(nwItemType.FILE) orphItem.setType(nwItemType.FILE)
orItem.setClass(nwItemClass.NO_CLASS) orphItem.setClass(nwItemClass.NO_CLASS)
orItem.setLayout(nwItemLayout.NO_LAYOUT) orphItem.setLayout(nwItemLayout.NO_LAYOUT)
self.projTree.append(oHandle, None, orItem) self.projTree.append(oHandle, None, orphItem)
return return
def _appendSessionStats(self): def _appendSessionStats(self):
"""Append session statistics to the sessions log file.
"""
if self.projMeta is None: if self.projMeta is None:
return False return False
@@ -895,8 +877,8 @@ class NWTree():
self._treeOrder = [] self._treeOrder = []
self._treeRoots = [] self._treeRoots = []
self._trashRoot = "" self._trashRoot = ""
self._theLength = 0 self._theLength = 0
self._theIndex = 0 self._theIndex = 0
self._treeChanged = False self._treeChanged = False
return return
@@ -937,6 +919,10 @@ class NWTree():
return return
##
# Tree Structure Methods
##
def trashRoot(self): def trashRoot(self):
"""Returns the handle of the trash folder, or None if there """Returns the handle of the trash folder, or None if there
isn't one. isn't one.
@@ -969,6 +955,45 @@ class NWTree():
return False return False
return True return True
def getRootItem(self, tHandle):
"""Iterate upwards in the tree until we find the item with
parent None, the root item. We do this with a for loop with a
maximum depth of 200 to make infinite loops impossible.
"""
tItem = self.__getitem__(tHandle)
if tItem is not None:
for i in range(200):
if tItem.parHandle is None:
return tHandle
else:
tHandle = tItem.parHandle
tItem = self.__getitem__(tHandle)
if tItem is None:
return tHandle
return None
def getItemPath(self, tHandle):
"""Iterate upwards in the tree until we find the item with
parent None, the root item, and return the list of handles.
We do this with a for loop with a maximum depth of 200 to make
infinite loops impossible.
"""
tTree = []
tItem = self.__getitem__(tHandle)
if tItem is not None:
tTree.append(tHandle)
for i in range(200):
if tItem.parHandle is None:
return tTree
else:
tHandle = tItem.parHandle
tItem = self.__getitem__(tHandle)
if tItem is None:
return tTree
else:
tTree.append(tHandle)
return tTree
## ##
# Setters # Setters
## ##
@@ -1053,7 +1078,7 @@ class NWTree():
## ##
def __iter__(self): def __iter__(self):
"""Initiates the iterator, """Initiates the iterator.
""" """
self._theIndex = 0 self._theIndex = 0
return self return self
@@ -1074,7 +1099,7 @@ class NWTree():
def _setTreeChanged(self, theState): def _setTreeChanged(self, theState):
"""Set the changed flag to theState, and if being set to True, """Set the changed flag to theState, and if being set to True,
propagate that change to the parent NWProject class. propagate that state change to the parent NWProject class.
""" """
self._treeChanged = theState self._treeChanged = theState
if theState: if theState:
@@ -1130,7 +1155,7 @@ class NWItem():
return return
## ##
# XML Pack # XML Pack/Unpack
## ##
def packXML(self, xParent): def packXML(self, xParent):
@@ -1375,6 +1400,9 @@ class NWStatus():
return return
def packEntries(self, xParent): def packEntries(self, xParent):
"""Pack the status entries into an XML object for saving to the
main project file.
"""
for n in range(self.theLength): for n in range(self.theLength):
xSub = etree.SubElement(xParent,"entry",attrib={ xSub = etree.SubElement(xParent,"entry",attrib={
"blue" : str(self.theColours[n][2]), "blue" : str(self.theColours[n][2]),
@@ -1385,6 +1413,8 @@ class NWStatus():
return True return True
def unpackEntries(self, xParent): def unpackEntries(self, xParent):
"""Unpack an XML tree and set the class values.
"""
theLabels = [] theLabels = []
theColours = [] theColours = []