Moved a couple more functions to the NWTree class, and cleaned up the source file a bit
This commit is contained in:
@@ -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
@@ -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 = []
|
||||||
|
|||||||
Reference in New Issue
Block a user