diff --git a/nw/project/__init__.py b/nw/project/__init__.py
index d7065c78..b36f5a5e 100644
--- a/nw/project/__init__.py
+++ b/nw/project/__init__.py
@@ -3,15 +3,11 @@
from nw.project.backup import NWBackup
from nw.project.document import NWDoc
from nw.project.index import NWIndex
-from nw.project.item import NWItem
from nw.project.project import NWProject
-from nw.project.status import NWStatus
__all__ = [
"NWBackup",
"NWDoc",
"NWIndex",
- "NWItem",
"NWProject",
- "NWStatus",
]
diff --git a/nw/project/item.py b/nw/project/item.py
deleted file mode 100644
index f0462dbe..00000000
--- a/nw/project/item.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# -*- coding: utf-8 -*-
-"""novelWriter Project Item
-
- novelWriter – Project Item
-============================
- Class holding a project item
-
- File History:
- Created: 2018-10-27 [0.0.1]
-
- This file is a part of novelWriter
- Copyright 2020, Veronica Berglyd Olsen
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-"""
-
-import logging
-import nw
-
-from lxml import etree
-
-from nw.common import checkInt
-from nw.constants import nwItemType, nwItemClass, nwItemLayout
-
-logger = logging.getLogger(__name__)
-
-class NWItem():
-
- def __init__(self, theProject):
-
- self.theProject = theProject
-
- self.itemName = ""
- self.itemHandle = None
- self.parHandle = None
- self.itemOrder = None
- self.itemType = nwItemType.NO_TYPE
- self.itemClass = nwItemClass.NO_CLASS
- self.itemLayout = nwItemLayout.NO_LAYOUT
- self.itemStatus = None
- self.isExpanded = False
-
- # Document Meta Data
- self.charCount = 0
- self.wordCount = 0
- self.paraCount = 0
- self.cursorPos = 0
-
- return
-
- ##
- # XML Pack
- ##
-
- def packXML(self, xParent):
- """Packs all the data in the class instance into an XML object.
- """
- xPack = etree.SubElement(xParent,"item",attrib={
- "handle" : str(self.itemHandle),
- "order" : str(self.itemOrder),
- "parent" : str(self.parHandle),
- })
- xSub = self._subPack(xPack,"name", text=str(self.itemName))
- xSub = self._subPack(xPack,"type", text=str(self.itemType.name))
- xSub = self._subPack(xPack,"class", text=str(self.itemClass.name))
- xSub = self._subPack(xPack,"status", text=str(self.itemStatus))
- xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded))
- if self.itemType == nwItemType.FILE:
- xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name))
- xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False)
- xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False)
- xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False)
- xSub = self._subPack(xPack,"cursorPos", text=str(self.cursorPos), none=False)
- return
-
- def unpackXML(self, xItem):
- """Sets the values from an XML entry of type 'item'.
- """
-
- if xItem.tag != "item":
- logger.error("XML entry is not an NWItem")
- return False
-
- if "handle" in xItem.attrib:
- self.itemHandle = xItem.attrib["handle"]
- else:
- logger.error("XML item entry does not have a handle")
- return False
-
- if "parent" in xItem.attrib:
- self.parHandle = xItem.attrib["parent"]
-
- setMap = {
- "name" : self.setName,
- "order" : self.setOrder,
- "type" : self.setType,
- "class" : self.setClass,
- "layout" : self.setLayout,
- "status" : self.setStatus,
- "expanded" : self.setExpanded,
- "charCount" : self.setCharCount,
- "wordCount" : self.setWordCount,
- "paraCount" : self.setParaCount,
- "cursorPos" : self.setCursorPos,
- }
- for xValue in xItem:
- if xValue.tag in setMap:
- setMap[xValue.tag](xValue.text)
- else:
- logger.error("Unknown tag '%s'" % xValue.tag)
-
- return True
-
- @staticmethod
- def _subPack(xParent, name, attrib=None, text=None, none=True):
- if not none and (text == None or text == "None"):
- return None
- xSub = etree.SubElement(xParent,name,attrib=attrib)
- if text is not None:
- xSub.text = text
- return xSub
-
- ##
- # Set Item Values
- ##
-
- def setName(self, theName):
- self.itemName = theName.strip()
- return
-
- def setHandle(self, theHandle):
- if isinstance(theHandle, str):
- if len(theHandle) == 13:
- self.itemHandle = theHandle
- else:
- self.itemHandle = None
- else:
- self.itemHandle = None
- return
-
- def setParent(self, theParent):
- if theParent is None:
- self.parHandle = None
- elif isinstance(theParent, str):
- if len(theParent) == 13:
- self.parHandle = theParent
- else:
- self.parHandle = None
- else:
- self.parHandle = None
- return
-
- def setOrder(self, theOrder):
- self.itemOrder = checkInt(theOrder, 0)
- return
-
- def setType(self, theType):
- if isinstance(theType, nwItemType):
- self.itemType = theType
- elif theType in nwItemType.__members__:
- self.itemType = nwItemType[theType]
- else:
- logger.error("Unrecognised item type '%s'" % theType)
- self.itemType = nwItemType.NO_TYPE
- return
-
- def setClass(self, theClass):
- if isinstance(theClass, nwItemClass):
- self.itemClass = theClass
- elif theClass in nwItemClass.__members__:
- self.itemClass = nwItemClass[theClass]
- else:
- logger.error("Unrecognised item class '%s'" % theClass)
- self.itemClass = nwItemClass.NO_CLASS
- return
-
- def setLayout(self, theLayout):
- if isinstance(theLayout, nwItemLayout):
- self.itemLayout = theLayout
- elif theLayout in nwItemLayout.__members__:
- self.itemLayout = nwItemLayout[theLayout]
- else:
- logger.error("Unrecognised item layout '%s'" % theLayout)
- self.itemLayout = nwItemLayout.NO_LAYOUT
- return
-
- def setStatus(self, theStatus):
- if self.itemClass == nwItemClass.NOVEL:
- self.itemStatus = self.theProject.statusItems.checkEntry(theStatus)
- else:
- self.itemStatus = self.theProject.importItems.checkEntry(theStatus)
- return
-
- def setExpanded(self, expState):
- if isinstance(expState, str):
- self.isExpanded = expState == str(True)
- else:
- self.isExpanded = expState == True
- return
-
- ##
- # Set Document Meta Data
- ##
-
- def setCharCount(self, theCount):
- self.charCount = checkInt(theCount,0)
- return
-
- def setWordCount(self, theCount):
- self.wordCount = checkInt(theCount,0)
- return
-
- def setParaCount(self, theCount):
- self.paraCount = checkInt(theCount,0)
- return
-
- def setCursorPos(self, thePosition):
- self.cursorPos = checkInt(thePosition,0)
- return
-
-# END Class NWItem
diff --git a/nw/project/project.py b/nw/project/project.py
index 674cba92..9ee3844f 100644
--- a/nw/project/project.py
+++ b/nw/project/project.py
@@ -7,6 +7,8 @@
File History:
Created: 2018-09-29 [0.0.1]
+ Merged: 2020-05-07 [0.4.5] Merged NWItem class into file
+ Merged: 2020-05-07 [0.4.5] Merged NWStatus class into file
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -34,8 +36,6 @@ from hashlib import sha256
from datetime import datetime
from time import time
-from nw.project.status import NWStatus
-from nw.project.item import NWItem
from nw.tools import projectMaintenance, OptionState
from nw.common import checkString, checkBool, checkInt
from nw.constants import (
@@ -934,3 +934,344 @@ class NWProject():
return itemHandle
# END Class NWProject
+
+# ================================================================================================ #
+# NWItem
+# Class holding the project items making up the NWProject
+# ================================================================================================ #
+
+class NWItem():
+
+ def __init__(self, theProject):
+
+ self.theProject = theProject
+
+ self.itemName = ""
+ self.itemHandle = None
+ self.parHandle = None
+ self.itemOrder = None
+ self.itemType = nwItemType.NO_TYPE
+ self.itemClass = nwItemClass.NO_CLASS
+ self.itemLayout = nwItemLayout.NO_LAYOUT
+ self.itemStatus = None
+ self.isExpanded = False
+
+ # Document Meta Data
+ self.charCount = 0
+ self.wordCount = 0
+ self.paraCount = 0
+ self.cursorPos = 0
+
+ return
+
+ ##
+ # XML Pack
+ ##
+
+ def packXML(self, xParent):
+ """Packs all the data in the class instance into an XML object.
+ """
+ xPack = etree.SubElement(xParent,"item",attrib={
+ "handle" : str(self.itemHandle),
+ "order" : str(self.itemOrder),
+ "parent" : str(self.parHandle),
+ })
+ xSub = self._subPack(xPack,"name", text=str(self.itemName))
+ xSub = self._subPack(xPack,"type", text=str(self.itemType.name))
+ xSub = self._subPack(xPack,"class", text=str(self.itemClass.name))
+ xSub = self._subPack(xPack,"status", text=str(self.itemStatus))
+ xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded))
+ if self.itemType == nwItemType.FILE:
+ xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name))
+ xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False)
+ xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False)
+ xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False)
+ xSub = self._subPack(xPack,"cursorPos", text=str(self.cursorPos), none=False)
+ return
+
+ def unpackXML(self, xItem):
+ """Sets the values from an XML entry of type 'item'.
+ """
+
+ if xItem.tag != "item":
+ logger.error("XML entry is not an NWItem")
+ return False
+
+ if "handle" in xItem.attrib:
+ self.itemHandle = xItem.attrib["handle"]
+ else:
+ logger.error("XML item entry does not have a handle")
+ return False
+
+ if "parent" in xItem.attrib:
+ self.parHandle = xItem.attrib["parent"]
+
+ setMap = {
+ "name" : self.setName,
+ "order" : self.setOrder,
+ "type" : self.setType,
+ "class" : self.setClass,
+ "layout" : self.setLayout,
+ "status" : self.setStatus,
+ "expanded" : self.setExpanded,
+ "charCount" : self.setCharCount,
+ "wordCount" : self.setWordCount,
+ "paraCount" : self.setParaCount,
+ "cursorPos" : self.setCursorPos,
+ }
+ for xValue in xItem:
+ if xValue.tag in setMap:
+ setMap[xValue.tag](xValue.text)
+ else:
+ logger.error("Unknown tag '%s'" % xValue.tag)
+
+ return True
+
+ @staticmethod
+ def _subPack(xParent, name, attrib=None, text=None, none=True):
+ if not none and (text == None or text == "None"):
+ return None
+ xSub = etree.SubElement(xParent,name,attrib=attrib)
+ if text is not None:
+ xSub.text = text
+ return xSub
+
+ ##
+ # Set Item Values
+ ##
+
+ def setName(self, theName):
+ self.itemName = theName.strip()
+ return
+
+ def setHandle(self, theHandle):
+ if isinstance(theHandle, str):
+ if len(theHandle) == 13:
+ self.itemHandle = theHandle
+ else:
+ self.itemHandle = None
+ else:
+ self.itemHandle = None
+ return
+
+ def setParent(self, theParent):
+ if theParent is None:
+ self.parHandle = None
+ elif isinstance(theParent, str):
+ if len(theParent) == 13:
+ self.parHandle = theParent
+ else:
+ self.parHandle = None
+ else:
+ self.parHandle = None
+ return
+
+ def setOrder(self, theOrder):
+ self.itemOrder = checkInt(theOrder, 0)
+ return
+
+ def setType(self, theType):
+ if isinstance(theType, nwItemType):
+ self.itemType = theType
+ elif theType in nwItemType.__members__:
+ self.itemType = nwItemType[theType]
+ else:
+ logger.error("Unrecognised item type '%s'" % theType)
+ self.itemType = nwItemType.NO_TYPE
+ return
+
+ def setClass(self, theClass):
+ if isinstance(theClass, nwItemClass):
+ self.itemClass = theClass
+ elif theClass in nwItemClass.__members__:
+ self.itemClass = nwItemClass[theClass]
+ else:
+ logger.error("Unrecognised item class '%s'" % theClass)
+ self.itemClass = nwItemClass.NO_CLASS
+ return
+
+ def setLayout(self, theLayout):
+ if isinstance(theLayout, nwItemLayout):
+ self.itemLayout = theLayout
+ elif theLayout in nwItemLayout.__members__:
+ self.itemLayout = nwItemLayout[theLayout]
+ else:
+ logger.error("Unrecognised item layout '%s'" % theLayout)
+ self.itemLayout = nwItemLayout.NO_LAYOUT
+ return
+
+ def setStatus(self, theStatus):
+ if self.itemClass == nwItemClass.NOVEL:
+ self.itemStatus = self.theProject.statusItems.checkEntry(theStatus)
+ else:
+ self.itemStatus = self.theProject.importItems.checkEntry(theStatus)
+ return
+
+ def setExpanded(self, expState):
+ if isinstance(expState, str):
+ self.isExpanded = expState == str(True)
+ else:
+ self.isExpanded = expState == True
+ return
+
+ ##
+ # Set Document Meta Data
+ ##
+
+ def setCharCount(self, theCount):
+ self.charCount = checkInt(theCount,0)
+ return
+
+ def setWordCount(self, theCount):
+ self.wordCount = checkInt(theCount,0)
+ return
+
+ def setParaCount(self, theCount):
+ self.paraCount = checkInt(theCount,0)
+ return
+
+ def setCursorPos(self, thePosition):
+ self.cursorPos = checkInt(thePosition,0)
+ return
+
+# END Class NWItem
+
+# ================================================================================================ #
+# NWStatus
+# Class holding the item status values stored in the NWProject
+# ================================================================================================ #
+
+class NWStatus():
+
+ def __init__(self):
+ self.theLabels = []
+ self.theColours = []
+ self.theCounts = []
+ self.theMap = {}
+ self.theLength = 0
+ self.theIndex = 0
+ return
+
+ def addEntry(self, theLabel, theColours):
+ theLabel = theLabel.strip()
+ if self.lookupEntry(theLabel) is None:
+ self.theLabels.append(theLabel)
+ self.theColours.append(theColours)
+ self.theCounts.append(0)
+ self.theMap[theLabel] = self.theLength
+ self.theLength += 1
+ return True
+
+ def lookupEntry(self, theLabel):
+ if theLabel is None:
+ return None
+ theLabel = theLabel.strip()
+ if theLabel in self.theMap.keys():
+ return self.theMap[theLabel]
+ return None
+
+ def checkEntry(self, theStatus):
+ if isinstance(theStatus, str):
+ theStatus = theStatus.strip()
+ if self.lookupEntry(theStatus) is not None:
+ return theStatus
+ theStatus = checkInt(theStatus, 0, False)
+ if theStatus >= 0 and theStatus < self.theLength:
+ return self.theLabels[theStatus]
+
+ def setNewEntries(self, newList):
+
+ replaceMap = {}
+
+ if newList is not None:
+
+ self.theLabels = []
+ self.theColours = []
+ self.theCounts = []
+ self.theMap = {}
+ self.theLength = 0
+ self.theIndex = 0
+
+ for nName, nR, nG, nB, oName in newList:
+ self.addEntry(nName, (nR, nG, nB))
+ if nName != oName and oName is not None:
+ replaceMap[oName] = nName
+
+ return replaceMap
+
+ def resetCounts(self):
+ self.theCounts = [0]*self.theLength
+ return
+
+ def countEntry(self, theLabel):
+ theIndex = self.lookupEntry(theLabel)
+ if theIndex is not None:
+ self.theCounts[theIndex] += 1
+ return
+
+ def packEntries(self, xParent):
+ for n in range(self.theLength):
+ xSub = etree.SubElement(xParent,"entry",attrib={
+ "blue" : str(self.theColours[n][2]),
+ "green" : str(self.theColours[n][1]),
+ "red" : str(self.theColours[n][0]),
+ })
+ xSub.text = self.theLabels[n]
+ return True
+
+ def unpackEntries(self, xParent):
+
+ theLabels = []
+ theColours = []
+
+ for xChild in xParent:
+ theLabels.append(xChild.text)
+ if "red" in xChild.attrib:
+ cR = checkInt(xChild.attrib["red"],0,False)
+ else:
+ cR = 0
+ if "green" in xChild.attrib:
+ cG = checkInt(xChild.attrib["green"],0,False)
+ else:
+ cG = 0
+ if "blue" in xChild.attrib:
+ cB = checkInt(xChild.attrib["blue"],0,False)
+ else:
+ cB = 0
+ theColours.append((cR,cG,cB))
+
+ if len(theLabels) > 0:
+ self.theLabels = []
+ self.theColours = []
+ self.theCounts = []
+ self.theMap = {}
+ self.theLength = 0
+ self.theIndex = 0
+
+ for n in range(len(theLabels)):
+ self.addEntry(theLabels[n], theColours[n])
+
+ return True
+
+ ##
+ # Iterator Bits
+ ##
+
+ def __getitem__(self, n):
+ if n >= 0 and n < self.theLength:
+ return self.theLabels[n], self.theColours[n], self.theCounts[n]
+ return None, None, None
+
+ def __iter__(self):
+ self.theIndex = 0
+ return self
+
+ def __next__(self):
+ if self.theIndex < self.theLength:
+ theLabel, theColour, theCount = self.__getitem__(self.theIndex)
+ self.theIndex += 1
+ return theLabel, theColour, theCount
+ else:
+ raise StopIteration
+
+# END Class NWStatus
diff --git a/nw/project/status.py b/nw/project/status.py
deleted file mode 100644
index c7771f3d..00000000
--- a/nw/project/status.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# -*- coding: utf-8 -*-
-"""novelWriter Item Status
-
- novelWriter – Item Status
-===========================
- Class holding the project's item statuses
-
- File History:
- Created: 2019-05-19 [0.1.3]
-
- This file is a part of novelWriter
- Copyright 2020, Veronica Berglyd Olsen
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-"""
-
-import logging
-import nw
-
-from lxml import etree
-
-from nw.common import checkInt
-
-logger = logging.getLogger(__name__)
-
-class NWStatus():
-
- def __init__(self):
- self.theLabels = []
- self.theColours = []
- self.theCounts = []
- self.theMap = {}
- self.theLength = 0
- self.theIndex = 0
- return
-
- def addEntry(self, theLabel, theColours):
- theLabel = theLabel.strip()
- if self.lookupEntry(theLabel) is None:
- self.theLabels.append(theLabel)
- self.theColours.append(theColours)
- self.theCounts.append(0)
- self.theMap[theLabel] = self.theLength
- self.theLength += 1
- return True
-
- def lookupEntry(self, theLabel):
- if theLabel is None:
- return None
- theLabel = theLabel.strip()
- if theLabel in self.theMap.keys():
- return self.theMap[theLabel]
- return None
-
- def checkEntry(self, theStatus):
- if isinstance(theStatus, str):
- theStatus = theStatus.strip()
- if self.lookupEntry(theStatus) is not None:
- return theStatus
- theStatus = checkInt(theStatus, 0, False)
- if theStatus >= 0 and theStatus < self.theLength:
- return self.theLabels[theStatus]
-
- def setNewEntries(self, newList):
-
- replaceMap = {}
-
- if newList is not None:
-
- self.theLabels = []
- self.theColours = []
- self.theCounts = []
- self.theMap = {}
- self.theLength = 0
- self.theIndex = 0
-
- for nName, nR, nG, nB, oName in newList:
- self.addEntry(nName, (nR, nG, nB))
- if nName != oName and oName is not None:
- replaceMap[oName] = nName
-
- return replaceMap
-
- def resetCounts(self):
- self.theCounts = [0]*self.theLength
- return
-
- def countEntry(self, theLabel):
- theIndex = self.lookupEntry(theLabel)
- if theIndex is not None:
- self.theCounts[theIndex] += 1
- return
-
- def packEntries(self, xParent):
- for n in range(self.theLength):
- xSub = etree.SubElement(xParent,"entry",attrib={
- "blue" : str(self.theColours[n][2]),
- "green" : str(self.theColours[n][1]),
- "red" : str(self.theColours[n][0]),
- })
- xSub.text = self.theLabels[n]
- return True
-
- def unpackEntries(self, xParent):
-
- theLabels = []
- theColours = []
-
- for xChild in xParent:
- theLabels.append(xChild.text)
- if "red" in xChild.attrib:
- cR = checkInt(xChild.attrib["red"],0,False)
- else:
- cR = 0
- if "green" in xChild.attrib:
- cG = checkInt(xChild.attrib["green"],0,False)
- else:
- cG = 0
- if "blue" in xChild.attrib:
- cB = checkInt(xChild.attrib["blue"],0,False)
- else:
- cB = 0
- theColours.append((cR,cG,cB))
-
- if len(theLabels) > 0:
- self.theLabels = []
- self.theColours = []
- self.theCounts = []
- self.theMap = {}
- self.theLength = 0
- self.theIndex = 0
-
- for n in range(len(theLabels)):
- self.addEntry(theLabels[n], theColours[n])
-
- return True
-
- ##
- # Iterator Bits
- ##
-
- def __getitem__(self, n):
- if n >= 0 and n < self.theLength:
- return self.theLabels[n], self.theColours[n], self.theCounts[n]
- return None, None, None
-
- def __iter__(self):
- self.theIndex = 0
- return self
-
- def __next__(self):
- if self.theIndex < self.theLength:
- theLabel, theColour, theCount = self.__getitem__(self.theIndex)
- self.theIndex += 1
- return theLabel, theColour, theCount
- else:
- raise StopIteration
-
-# END Class NWStatus
diff --git a/tests/test_item.py b/tests/test_item.py
index 101eda79..b58f1b7e 100644
--- a/tests/test_item.py
+++ b/tests/test_item.py
@@ -9,8 +9,7 @@ from lxml import etree
from nwdummy import DummyMain
from nw.config import Config
-from nw.project.project import NWProject
-from nw.project.item import NWItem
+from nw.project.project import NWProject, NWItem
from nw.constants import nwItemClass, nwItemType, nwItemLayout
theConf = Config()