Merge pull request #196 from vkbo/project_structure
Project Class Restructure Merging into `dev` for further testing and code restructuring before we merge to master.
This commit is contained in:
@@ -164,12 +164,12 @@ class TextFile():
|
||||
* Items that appear in the TRASH folder
|
||||
"""
|
||||
|
||||
theItem = self.theProject.getItem(tHandle)
|
||||
theItem = self.theProject.projTree[tHandle]
|
||||
isNone = theItem.itemType != nwItemType.FILE
|
||||
isNone |= theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||
isNone |= theItem.itemClass == nwItemClass.NO_CLASS
|
||||
isNone |= theItem.itemClass == nwItemClass.TRASH
|
||||
isNone |= theItem.parHandle == self.theProject.trashRoot
|
||||
isNone |= theItem.parHandle == self.theProject.projTree.trashRoot()
|
||||
isNote = theItem.itemLayout == nwItemLayout.NOTE
|
||||
isNovel = not isNone and not isNote
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ class Tokenizer():
|
||||
def setText(self, theHandle, theText=None):
|
||||
|
||||
self.theHandle = theHandle
|
||||
self.theItem = self.theProject.getItem(theHandle)
|
||||
self.theItem = self.theProject.projTree[theHandle]
|
||||
|
||||
if theText is not None:
|
||||
# If the text is set, just use that
|
||||
|
||||
@@ -115,7 +115,7 @@ class GuiDocMerge(QDialog):
|
||||
), nwAlert.ERROR)
|
||||
return
|
||||
|
||||
srcItem = self.theProject.getItem(self.sourceItem)
|
||||
srcItem = self.theProject.projTree[self.sourceItem]
|
||||
nHandle = self.theProject.newFile(srcItem.itemName, srcItem.itemClass, srcItem.parHandle)
|
||||
self.theParent.treeView.revealTreeItem(nHandle)
|
||||
theDoc.openDocument(nHandle, False)
|
||||
@@ -149,7 +149,7 @@ class GuiDocMerge(QDialog):
|
||||
if tHandle is None:
|
||||
return
|
||||
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem is None:
|
||||
return
|
||||
if nwItem.itemType is not nwItemType.FOLDER:
|
||||
@@ -160,7 +160,7 @@ class GuiDocMerge(QDialog):
|
||||
|
||||
for sHandle in self.theParent.treeView.getTreeFromHandle(tHandle):
|
||||
newItem = QListWidgetItem()
|
||||
nwItem = self.theProject.getItem(sHandle)
|
||||
nwItem = self.theProject.projTree[sHandle]
|
||||
if nwItem.itemType is not nwItemType.FILE:
|
||||
continue
|
||||
newItem.setText(nwItem.itemName)
|
||||
|
||||
@@ -120,7 +120,7 @@ class GuiDocSplit(QDialog):
|
||||
), nwAlert.ERROR)
|
||||
return
|
||||
|
||||
srcItem = self.theProject.getItem(self.sourceItem)
|
||||
srcItem = self.theProject.projTree[self.sourceItem]
|
||||
if srcItem is None:
|
||||
self.theParent.makeAlert((
|
||||
"Could not parse source document."
|
||||
@@ -172,7 +172,7 @@ class GuiDocSplit(QDialog):
|
||||
wTitle = wTitle.strip()
|
||||
|
||||
nHandle = self.theProject.newFile(wTitle, srcItem.itemClass, fHandle)
|
||||
newItem = self.theProject.getItem(nHandle)
|
||||
newItem = self.theProject.projTree[nHandle]
|
||||
newItem.setLayout(itemLayout)
|
||||
logger.verbose(
|
||||
"Creating new document %s with text from line %d to %d" % (nHandle, iStart, iEnd-1)
|
||||
@@ -213,7 +213,7 @@ class GuiDocSplit(QDialog):
|
||||
if self.sourceItem is None:
|
||||
return
|
||||
|
||||
nwItem = self.theProject.getItem(self.sourceItem)
|
||||
nwItem = self.theProject.projTree[self.sourceItem]
|
||||
if nwItem is None:
|
||||
return
|
||||
if nwItem.itemType is not nwItemType.FILE:
|
||||
|
||||
@@ -134,7 +134,7 @@ class GuiExport(QDialog):
|
||||
self.exportStatus.setText("Export failed ...")
|
||||
return False
|
||||
|
||||
nItems = len(self.theProject.treeOrder)
|
||||
nItems = len(self.theProject.projTree)
|
||||
if eFormat == GuiExportMain.FMT_PDOC:
|
||||
nItems += int(0.2*nItems)
|
||||
self.exportProgress.setMinimum(0)
|
||||
@@ -182,16 +182,14 @@ class GuiExport(QDialog):
|
||||
time.sleep(0.5)
|
||||
|
||||
nDone = 0
|
||||
for tHandle in self.theProject.treeOrder:
|
||||
for tItem in self.theProject.projTree:
|
||||
|
||||
self.exportProgress.setValue(nDone)
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
|
||||
self.exportStatus.setText("Exporting: %s" % tItem.itemName)
|
||||
logger.verbose("Exporting: %s" % tItem.itemName)
|
||||
|
||||
if tItem is not None and tItem.itemType == nwItemType.FILE:
|
||||
outFile.addText(tHandle)
|
||||
outFile.addText(tItem.itemHandle)
|
||||
|
||||
nDone += 1
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class GuiItemEditor(QDialog):
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theProject = theProject
|
||||
self.theParent = theParent
|
||||
self.theItem = self.theProject.getItem(tHandle)
|
||||
self.theItem = self.theProject.projTree[tHandle]
|
||||
|
||||
self.outerBox = QHBoxLayout()
|
||||
self.innerBox = QVBoxLayout()
|
||||
|
||||
@@ -83,7 +83,7 @@ class GuiDocDetails(QFrame):
|
||||
|
||||
def buildViewBox(self, tHandle):
|
||||
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
|
||||
if nwItem is None:
|
||||
colTwo = [""]*4
|
||||
|
||||
@@ -87,15 +87,15 @@ class GuiDocTitleBar(QLabel):
|
||||
|
||||
if self.mainConf.showFullPath:
|
||||
tTitle = []
|
||||
tTree = self.theProject.getItemPath(tHandle)
|
||||
tTree = self.theProject.projTree.getItemPath(tHandle)
|
||||
for aHandle in reversed(tTree):
|
||||
nwItem = self.theProject.getItem(aHandle)
|
||||
nwItem = self.theProject.projTree[aHandle]
|
||||
if nwItem is not None:
|
||||
tTitle.append(nwItem.itemName)
|
||||
sSep = " %s " % nwUnicode.U_RSAQUO
|
||||
self.setText(sSep.join(tTitle))
|
||||
else:
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem is None:
|
||||
return False
|
||||
|
||||
|
||||
+29
-26
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
|
||||
QTreeWidget, QTreeWidgetItem, QAbstractItemView, QApplication, QMessageBox
|
||||
)
|
||||
|
||||
from nw.project import NWItem, NWDoc
|
||||
from nw.project import NWDoc
|
||||
from nw.constants import (
|
||||
nwLabels, nwItemType, nwItemClass, nwItemLayout, nwAlert
|
||||
)
|
||||
@@ -118,7 +118,7 @@ class GuiDocTree(QTreeWidget):
|
||||
return False
|
||||
|
||||
if itemClass is None and pHandle is not None:
|
||||
pItem = self.theProject.getItem(pHandle)
|
||||
pItem = self.theProject.projTree[pHandle]
|
||||
if pItem is not None:
|
||||
itemClass = pItem.itemClass
|
||||
|
||||
@@ -150,7 +150,7 @@ class GuiDocTree(QTreeWidget):
|
||||
# If no parent has been selected, make the new file under
|
||||
# the root NOVEL item.
|
||||
if pHandle is None:
|
||||
pHandle = self.theProject.findRootItem(nwItemClass.NOVEL)
|
||||
pHandle = self.theProject.projTree.findRoot(nwItemClass.NOVEL)
|
||||
|
||||
# If still nothing, give up
|
||||
if pHandle is None:
|
||||
@@ -159,7 +159,7 @@ class GuiDocTree(QTreeWidget):
|
||||
|
||||
# Now check if the selected item is a file, in which case
|
||||
# the new file will be a sibling
|
||||
pItem = self.theProject.getItem(pHandle)
|
||||
pItem = self.theProject.projTree[pHandle]
|
||||
if pItem.itemType == nwItemType.FILE:
|
||||
pHandle = pItem.parHandle
|
||||
|
||||
@@ -170,7 +170,7 @@ class GuiDocTree(QTreeWidget):
|
||||
)
|
||||
return False
|
||||
|
||||
if pHandle == self.theProject.trashRoot:
|
||||
if pHandle == self.theProject.projTree.trashRoot():
|
||||
self.makeAlert(
|
||||
"Cannot add new files or folders to the trash folder.", nwAlert.ERROR
|
||||
)
|
||||
@@ -194,7 +194,7 @@ class GuiDocTree(QTreeWidget):
|
||||
def revealTreeItem(self, tHandle):
|
||||
"""Reveal a newly added project item in the project tree.
|
||||
"""
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
trItem = self._addTreeItem(nwItem)
|
||||
pHandle = nwItem.parHandle
|
||||
if pHandle is not None and pHandle in self.theMap.keys():
|
||||
@@ -267,14 +267,16 @@ class GuiDocTree(QTreeWidget):
|
||||
deleteItem function for each document in the Trash folder.
|
||||
"""
|
||||
|
||||
trashHandle = self.theProject.projTree.trashRoot()
|
||||
|
||||
logger.debug("Emptying Trash folder")
|
||||
if self.theProject.trashRoot is None:
|
||||
if trashHandle is None:
|
||||
self.makeAlert("There is no Trash folder.", nwAlert.INFO)
|
||||
return False
|
||||
|
||||
theTrash = self.getTreeFromHandle(self.theProject.trashRoot)
|
||||
if self.theProject.trashRoot in theTrash:
|
||||
theTrash.remove(self.theProject.trashRoot)
|
||||
theTrash = self.getTreeFromHandle(trashHandle)
|
||||
if trashHandle in theTrash:
|
||||
theTrash.remove(trashHandle)
|
||||
|
||||
nTrash = len(theTrash)
|
||||
if nTrash == 0:
|
||||
@@ -291,8 +293,8 @@ class GuiDocTree(QTreeWidget):
|
||||
return False
|
||||
|
||||
logger.verbose("Deleting %d files from Trash" % nTrash)
|
||||
for tHandle in self.getTreeFromHandle(self.theProject.trashRoot):
|
||||
if tHandle == self.theProject.trashRoot:
|
||||
for tHandle in self.getTreeFromHandle(trashHandle):
|
||||
if tHandle == trashHandle:
|
||||
continue
|
||||
self.deleteItem(tHandle, True)
|
||||
|
||||
@@ -313,7 +315,7 @@ class GuiDocTree(QTreeWidget):
|
||||
return False
|
||||
|
||||
trItemS = self._getTreeItem(tHandle)
|
||||
nwItemS = self.theProject.getItem(tHandle)
|
||||
nwItemS = self.theProject.projTree[tHandle]
|
||||
|
||||
if nwItemS is None:
|
||||
return False
|
||||
@@ -327,7 +329,7 @@ class GuiDocTree(QTreeWidget):
|
||||
return False
|
||||
|
||||
pHandle = nwItemS.parHandle
|
||||
if pHandle is not None and pHandle == self.theProject.trashRoot:
|
||||
if pHandle is not None and pHandle == self.theProject.projTree.trashRoot():
|
||||
# If the file is in the trash folder already, as the
|
||||
# user if they want to permanently delete the file.
|
||||
|
||||
@@ -353,7 +355,7 @@ class GuiDocTree(QTreeWidget):
|
||||
|
||||
theDoc = NWDoc(self.theProject, self.theParent)
|
||||
theDoc.deleteDocument(tHandle)
|
||||
self.theProject.deleteItem(tHandle)
|
||||
del self.theProject.projTree[tHandle]
|
||||
self.theParent.theIndex.deleteHandle(tHandle)
|
||||
|
||||
else:
|
||||
@@ -366,7 +368,7 @@ class GuiDocTree(QTreeWidget):
|
||||
tIndex = trItemP.indexOfChild(trItemS)
|
||||
trItemC = trItemP.takeChild(tIndex)
|
||||
trItemT.addChild(trItemC)
|
||||
nwItemS.setParent(self.theProject.trashRoot)
|
||||
nwItemS.setParent(self.theProject.projTree.trashRoot())
|
||||
|
||||
self.theProject.setProjectChanged(True)
|
||||
self.theParent.theIndex.deleteHandle(tHandle)
|
||||
@@ -380,7 +382,7 @@ class GuiDocTree(QTreeWidget):
|
||||
tIndex = trItemP.indexOfChild(trItemS)
|
||||
if trItemS.childCount() == 0:
|
||||
trItemP.takeChild(tIndex)
|
||||
self.theProject.deleteItem(tHandle)
|
||||
del self.theProject.projTree[tHandle]
|
||||
else:
|
||||
self.makeAlert(["Cannot delete folder.","It is not empty."], nwAlert.ERROR)
|
||||
return False
|
||||
@@ -401,7 +403,7 @@ class GuiDocTree(QTreeWidget):
|
||||
def setTreeItemValues(self, tHandle):
|
||||
|
||||
trItem = self._getTreeItem(tHandle)
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
tName = nwItem.itemName
|
||||
tClass = nwItem.itemClass
|
||||
tHandle = nwItem.itemHandle
|
||||
@@ -552,14 +554,15 @@ class GuiDocTree(QTreeWidget):
|
||||
"""Adds the trash root folder if it doesn't already exist in the
|
||||
project tree.
|
||||
"""
|
||||
if self.theProject.trashRoot is None:
|
||||
trashHandle = self.theProject.projTree.trashRoot()
|
||||
if trashHandle is None:
|
||||
self.theProject.addTrash()
|
||||
trItem = self._addTreeItem(
|
||||
self.theProject.getItem(self.theProject.trashRoot)
|
||||
self.theProject.projTree[trashHandle]
|
||||
)
|
||||
trItem.setExpanded(True)
|
||||
else:
|
||||
trItem = self._getTreeItem(self.theProject.trashRoot)
|
||||
trItem = self._getTreeItem(trashHandle)
|
||||
return trItem
|
||||
|
||||
def _addOrphanedRoot(self):
|
||||
@@ -589,7 +592,7 @@ class GuiDocTree(QTreeWidget):
|
||||
"""
|
||||
|
||||
trItemS = self._getTreeItem(tHandle)
|
||||
nwItemS = self.theProject.getItem(tHandle)
|
||||
nwItemS = self.theProject.projTree[tHandle]
|
||||
trItemP = trItemS.parent()
|
||||
if trItemP is None:
|
||||
logger.error("Failed to find new parent item of %s" % tHandle)
|
||||
@@ -609,8 +612,8 @@ class GuiDocTree(QTreeWidget):
|
||||
|
||||
def _moveOrphanedItem(self, tHandle, dHandle):
|
||||
trItemS = self._getTreeItem(tHandle)
|
||||
nwItemS = self.theProject.getItem(tHandle)
|
||||
nwItemD = self.theProject.getItem(dHandle)
|
||||
nwItemS = self.theProject.projTree[tHandle]
|
||||
nwItemD = self.theProject.projTree[dHandle]
|
||||
trItemP = trItemS.parent()
|
||||
nwItemS.setClass(nwItemD.itemClass)
|
||||
if trItemP is None:
|
||||
@@ -652,8 +655,8 @@ class GuiDocTree(QTreeWidget):
|
||||
|
||||
dItem = self.itemFromIndex(dIndex)
|
||||
dHandle = dItem.text(self.C_HANDLE)
|
||||
snItem = self.theProject.getItem(sHandle)
|
||||
dnItem = self.theProject.getItem(dHandle)
|
||||
snItem = self.theProject.projTree[sHandle]
|
||||
dnItem = self.theProject.projTree[dHandle]
|
||||
if dnItem is None:
|
||||
self.makeAlert("The item cannot be moved to that location.", nwAlert.ERROR)
|
||||
return
|
||||
|
||||
@@ -123,7 +123,7 @@ class GuiDocViewer(QTextBrowser):
|
||||
"""Load text into the viewer from an item handle.
|
||||
"""
|
||||
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
tItem = self.theProject.projTree[tHandle]
|
||||
if tItem is None:
|
||||
logger.warning("Item not found")
|
||||
return False
|
||||
|
||||
@@ -405,7 +405,7 @@ class GuiProjectOutline(QTreeWidget):
|
||||
"""Populate a tree item with all the column values.
|
||||
"""
|
||||
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
novIdx = self.theIndex.novelIndex[tHandle][sTitle]
|
||||
|
||||
newItem = QTreeWidgetItem()
|
||||
|
||||
@@ -103,7 +103,7 @@ class GuiDocViewDetails(QWidget):
|
||||
theRefs = self.theParent.theIndex.getBackReferenceList(tHandle)
|
||||
theList = []
|
||||
for tHandle in theRefs:
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
tItem = self.theProject.projTree[tHandle]
|
||||
if tItem is not None:
|
||||
theList.append("<a href='#tag=%s'>%s</a>" % (tHandle,tItem.itemName))
|
||||
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ class GuiMainMenu(QMenuBar):
|
||||
if itemClass == nwItemClass.NO_CLASS: continue
|
||||
if itemClass == nwItemClass.TRASH: continue
|
||||
self.rootItems[itemClass].setEnabled(
|
||||
self.theProject.checkRootUnique(itemClass)
|
||||
self.theProject.projTree.checkRootUnique(itemClass)
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
||||
return
|
||||
|
||||
if theText.startswith("@"): # Keywords and commands
|
||||
tItem = self.theParent.theProject.getItem(self.theHandle)
|
||||
tItem = self.theParent.theProject.projTree[self.theHandle]
|
||||
isValid, theBits, thePos = self.theIndex.scanThis(theText)
|
||||
isGood = self.theIndex.checkThese(theBits, tItem)
|
||||
if isValid:
|
||||
|
||||
+14
-14
@@ -45,7 +45,7 @@ from nw.gui import (
|
||||
GuiConfigEditor, GuiProjectEditor, GuiItemEditor, GuiProjectOutline,
|
||||
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad
|
||||
)
|
||||
from nw.project import NWProject, NWDoc, NWItem, NWIndex, NWBackup
|
||||
from nw.project import NWProject, NWDoc, NWIndex, NWBackup
|
||||
from nw.tools import countWords
|
||||
from nw.constants import nwFiles, nwItemType, nwAlert
|
||||
|
||||
@@ -617,7 +617,7 @@ class GuiMain(QMainWindow):
|
||||
return False
|
||||
|
||||
logger.verbose("Opening item %s" % tHandle)
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
logger.verbose("Requested item %s is a file" % tHandle)
|
||||
self.openDocument(tHandle)
|
||||
@@ -656,7 +656,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
self.treeView.saveTreeOrder()
|
||||
self.theIndex.clearIndex()
|
||||
nItems = len(self.theProject.treeOrder)
|
||||
nItems = len(self.theProject.projTree)
|
||||
|
||||
dlgProg = QProgressDialog("Scanning files ...", "Cancel", 0, nItems, self)
|
||||
dlgProg.setWindowModality(Qt.WindowModal)
|
||||
@@ -668,27 +668,27 @@ class GuiMain(QMainWindow):
|
||||
time.sleep(0.5)
|
||||
|
||||
nDone = 0
|
||||
for tHandle in self.theProject.treeOrder:
|
||||
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
for tItem in self.theProject.projTree:
|
||||
|
||||
dlgProg.setValue(nDone)
|
||||
dlgProg.setLabelText("Scanning: %s" % tItem.itemName)
|
||||
logger.verbose("Scanning: %s" % tItem.itemName)
|
||||
|
||||
if tItem is not None and tItem.itemType == nwItemType.FILE:
|
||||
|
||||
dlgProg.setLabelText("Scanning: %s" % tItem.itemName)
|
||||
logger.verbose("Scanning: %s" % tItem.itemName)
|
||||
|
||||
theDoc = NWDoc(self.theProject, self)
|
||||
theText = theDoc.openDocument(tHandle, False)
|
||||
theText = theDoc.openDocument(tItem.itemHandle, False)
|
||||
|
||||
# Build tag index
|
||||
self.theIndex.scanText(tHandle, theText)
|
||||
self.theIndex.scanText(tItem.itemHandle, theText)
|
||||
|
||||
# Get Word Counts
|
||||
cC, wC, pC = self.theIndex.getCounts(tHandle)
|
||||
cC, wC, pC = self.theIndex.getCounts(tItem.itemHandle)
|
||||
tItem.setCharCount(cC)
|
||||
tItem.setWordCount(wC)
|
||||
tItem.setParaCount(pC)
|
||||
self.treeView.propagateCount(tHandle, wC)
|
||||
self.treeView.propagateCount(tItem.itemHandle, wC)
|
||||
self.treeView.projectWordCount()
|
||||
|
||||
nDone += 1
|
||||
@@ -1020,7 +1020,7 @@ class GuiMain(QMainWindow):
|
||||
def _treeDoubleClick(self, tItem, colNo):
|
||||
tHandle = tItem.text(3)
|
||||
logger.verbose("User double clicked tree item with handle %s" % tHandle)
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
logger.verbose("Requested item %s is a file" % tHandle)
|
||||
self.openDocument(tHandle)
|
||||
@@ -1031,7 +1031,7 @@ class GuiMain(QMainWindow):
|
||||
def _treeKeyPressReturn(self):
|
||||
tHandle = self.treeView.getSelectedHandle()
|
||||
logger.verbose("User pressed return on tree item with handle %s" % tHandle)
|
||||
nwItem = self.theProject.getItem(tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
logger.verbose("Requested item %s is a file" % tHandle)
|
||||
self.openDocument(tHandle)
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -62,7 +62,7 @@ class NWDoc():
|
||||
def openDocument(self, tHandle, showStatus=True):
|
||||
|
||||
self.docHandle = tHandle
|
||||
self.theItem = self.theProject.getItem(tHandle)
|
||||
self.theItem = self.theProject.projTree[tHandle]
|
||||
|
||||
if self.theItem is None:
|
||||
self.clearDocument()
|
||||
@@ -71,7 +71,7 @@ class NWDoc():
|
||||
# By default, the document is editable.
|
||||
# Except for files in the trash folder.
|
||||
self.docEditable = True
|
||||
if self.theItem.parHandle == self.theProject.trashRoot:
|
||||
if self.theItem.parHandle == self.theProject.projTree.trashRoot():
|
||||
self.docEditable = False
|
||||
|
||||
docDir, docFile = self.assemblePath(self.docHandle, self.FILE_MN)
|
||||
|
||||
+4
-4
@@ -249,12 +249,12 @@ class NWIndex():
|
||||
files before we save them, unless we're rebuilding the index.
|
||||
"""
|
||||
|
||||
theItem = self.theProject.getItem(tHandle)
|
||||
theItem = self.theProject.projTree[tHandle]
|
||||
if theItem is None:
|
||||
return False
|
||||
if theItem.itemType != nwItemType.FILE:
|
||||
return False
|
||||
if theItem.parHandle == self.theProject.trashRoot:
|
||||
if theItem.parHandle == self.theProject.projTree.trashRoot():
|
||||
return False
|
||||
if theItem.itemLayout == nwItemLayout.NO_LAYOUT:
|
||||
return False
|
||||
@@ -539,7 +539,7 @@ class NWIndex():
|
||||
"""
|
||||
|
||||
theStructure = []
|
||||
for tHandle in self.theProject.treeOrder:
|
||||
for tHandle in self.theProject.projTree.handles():
|
||||
if tHandle not in self.novelIndex:
|
||||
continue
|
||||
for sTitle in sorted(self.novelIndex[tHandle].keys()):
|
||||
@@ -605,7 +605,7 @@ class NWIndex():
|
||||
|
||||
theRefs = {}
|
||||
|
||||
tItem = self.theProject.getItem(tHandle)
|
||||
tItem = self.theProject.projTree[tHandle]
|
||||
if tHandle is None:
|
||||
return theRefs
|
||||
|
||||
|
||||
@@ -1,222 +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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
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):
|
||||
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 xPack
|
||||
|
||||
def _subPack(self, 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
|
||||
|
||||
##
|
||||
# Settings Wrapper
|
||||
##
|
||||
|
||||
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 == "layout":
|
||||
self.setLayout(tagValue)
|
||||
elif tagName == "status":
|
||||
self.setStatus(tagValue)
|
||||
elif tagName == "expanded":
|
||||
self.setExpanded(tagValue)
|
||||
elif tagName == "charCount":
|
||||
self.setCharCount(tagValue)
|
||||
elif tagName == "wordCount":
|
||||
self.setWordCount(tagValue)
|
||||
elif tagName == "paraCount":
|
||||
self.setParaCount(tagValue)
|
||||
elif tagName == "cursorPos":
|
||||
self.setCursorPos(tagValue)
|
||||
else:
|
||||
logger.error("Unknown tag '%s'" % tagName)
|
||||
return
|
||||
|
||||
##
|
||||
# Set Item Values
|
||||
##
|
||||
|
||||
def setName(self, theName):
|
||||
self.itemName = theName.strip()
|
||||
return
|
||||
|
||||
def setHandle(self, theHandle):
|
||||
self.itemHandle = theHandle
|
||||
return
|
||||
|
||||
def setParent(self, theParent):
|
||||
self.parHandle = theParent
|
||||
return
|
||||
|
||||
def setOrder(self, theOrder):
|
||||
self.itemOrder = theOrder
|
||||
return
|
||||
|
||||
def setType(self, theType):
|
||||
if isinstance(theType, nwItemType):
|
||||
self.itemType = theType
|
||||
return
|
||||
else:
|
||||
for itemType in nwItemType:
|
||||
if theType == itemType.name:
|
||||
self.itemType = itemType
|
||||
return
|
||||
logger.error("Unrecognised item type '%s'" % theType)
|
||||
self.itemType = nwItemType.NO_TYPE
|
||||
return
|
||||
|
||||
def setClass(self, theClass):
|
||||
if isinstance(theClass, nwItemClass):
|
||||
self.itemClass = theClass
|
||||
return
|
||||
else:
|
||||
for itemClass in nwItemClass:
|
||||
if theClass == itemClass.name:
|
||||
self.itemClass = itemClass
|
||||
return
|
||||
logger.error("Unrecognised item class '%s'" % theClass)
|
||||
self.itemClass = nwItemClass.NO_CLASS
|
||||
return
|
||||
|
||||
def setLayout(self, theLayout):
|
||||
if isinstance(theLayout, nwItemLayout):
|
||||
self.itemLayout = theLayout
|
||||
return
|
||||
else:
|
||||
for itemLayout in nwItemLayout:
|
||||
if theLayout == itemLayout.name:
|
||||
self.itemLayout = itemLayout
|
||||
return
|
||||
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
|
||||
return
|
||||
|
||||
##
|
||||
# Set Document Meta Data
|
||||
##
|
||||
|
||||
def setCharCount(self, theCount):
|
||||
theCount = checkInt(theCount,0)
|
||||
self.charCount = theCount
|
||||
return
|
||||
|
||||
def setWordCount(self, theCount):
|
||||
theCount = checkInt(theCount,0)
|
||||
self.wordCount = theCount
|
||||
return
|
||||
|
||||
def setParaCount(self, theCount):
|
||||
theCount = checkInt(theCount,0)
|
||||
self.paraCount = theCount
|
||||
return
|
||||
|
||||
def setCursorPos(self, thePosition):
|
||||
thePosition = checkInt(thePosition,0)
|
||||
self.cursorPos = thePosition
|
||||
return
|
||||
|
||||
# END Class NWItem
|
||||
+699
-174
File diff suppressed because it is too large
Load Diff
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
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
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="0.1.5" fileVersion="1.0" timeStamp="2019-06-27 20:31:37">
|
||||
<novelWriterXML appVersion="0.4.5" fileVersion="1.0" saveCount="4" autoCount="0" timeStamp="2020-05-07 22:03:17">
|
||||
<project>
|
||||
<name></name>
|
||||
<title></title>
|
||||
@@ -59,7 +59,7 @@
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="2fca346db6561" order="0" parent="44cb730c42048">
|
||||
<item handle="98010bd9270f9" order="0" parent="44cb730c42048">
|
||||
<name>New File</name>
|
||||
<type>FILE</type>
|
||||
<class>CHARACTER</class>
|
||||
@@ -78,7 +78,7 @@
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="02d20bbd7e394" order="0" parent="71ee45a3c0db9">
|
||||
<item handle="0e17daca5f3e1" order="0" parent="71ee45a3c0db9">
|
||||
<name>New File</name>
|
||||
<type>FILE</type>
|
||||
<class>PLOT</class>
|
||||
@@ -97,7 +97,7 @@
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="7688b6ef52555" order="0" parent="811786ad1ae74">
|
||||
<item handle="1a6562590ef19" order="0" parent="811786ad1ae74">
|
||||
<name>New File</name>
|
||||
<type>FILE</type>
|
||||
<class>WORLD</class>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="0.4.5" fileVersion="1.0" timeStamp="2020-02-26 22:05:41">
|
||||
<novelWriterXML appVersion="0.4.5" fileVersion="1.0" saveCount="4" autoCount="0" timeStamp="2020-05-07 22:52:18">
|
||||
<project>
|
||||
<name></name>
|
||||
<title></title>
|
||||
@@ -73,28 +73,28 @@
|
||||
<paraCount>0</paraCount>
|
||||
<cursorPos>0</cursorPos>
|
||||
</item>
|
||||
<item handle="8722616204217" order="None" parent="None">
|
||||
<item handle="98010bd9270f9" order="None" parent="None">
|
||||
<name>Timeline</name>
|
||||
<type>ROOT</type>
|
||||
<class>TIMELINE</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="96061e92f58e4" order="None" parent="None">
|
||||
<item handle="0e17daca5f3e1" order="None" parent="None">
|
||||
<name>Object</name>
|
||||
<type>ROOT</type>
|
||||
<class>OBJECT</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="eb624dbe56eb6" order="None" parent="None">
|
||||
<item handle="1a6562590ef19" order="None" parent="None">
|
||||
<name>Custom1</name>
|
||||
<type>ROOT</type>
|
||||
<class>CUSTOM</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="f369cb89fc627" order="None" parent="None">
|
||||
<item handle="031b4af5197ec" order="None" parent="None">
|
||||
<name>Custom2</name>
|
||||
<type>ROOT</type>
|
||||
<class>CUSTOM</class>
|
||||
|
||||
+15
-15
@@ -25,15 +25,15 @@ def testMainWindows(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Create new, save, close project
|
||||
nwGUI.theProject.handleSeed = 42
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject(nwTempGUI, True)
|
||||
assert nwGUI.saveProject()
|
||||
assert nwGUI.closeProject()
|
||||
|
||||
assert len(nwGUI.theProject.projTree) == 0
|
||||
assert len(nwGUI.theProject.treeOrder) == 0
|
||||
assert len(nwGUI.theProject.treeRoots) == 0
|
||||
assert nwGUI.theProject.trashRoot is None
|
||||
assert len(nwGUI.theProject.projTree._treeOrder) == 0
|
||||
assert len(nwGUI.theProject.projTree._treeRoots) == 0
|
||||
assert nwGUI.theProject.projTree.trashRoot() is None
|
||||
assert nwGUI.theProject.projPath is None
|
||||
assert nwGUI.theProject.projMeta is None
|
||||
assert nwGUI.theProject.projFile == "nwProject.nwx"
|
||||
@@ -55,9 +55,9 @@ def testMainWindows(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
|
||||
# Check that we loaded the data
|
||||
assert len(nwGUI.theProject.projTree) == 6
|
||||
assert len(nwGUI.theProject.treeOrder) == 6
|
||||
assert len(nwGUI.theProject.treeRoots) == 4
|
||||
assert nwGUI.theProject.trashRoot is None
|
||||
assert len(nwGUI.theProject.projTree._treeOrder) == 6
|
||||
assert len(nwGUI.theProject.projTree._treeRoots) == 4
|
||||
assert nwGUI.theProject.projTree.trashRoot() is None
|
||||
assert nwGUI.theProject.projPath == nwTempGUI
|
||||
assert nwGUI.theProject.projMeta == path.join(nwTempGUI,"meta")
|
||||
assert nwGUI.theProject.projFile == "nwProject.nwx"
|
||||
@@ -237,14 +237,14 @@ def testMainWindows(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
# Check the files
|
||||
refFile = path.join(nwTempGUI,"nwProject.nwx")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_nwProject.nwx"), [2])
|
||||
refFile = path.join(nwTempGUI,"data_0","2d20bbd7e394_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_2d20bbd7e394_main.nwd"))
|
||||
refFile = path.join(nwTempGUI,"data_2","fca346db6561_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_fca346db6561_main.nwd"))
|
||||
refFile = path.join(nwTempGUI,"data_0","e17daca5f3e1_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_e17daca5f3e1_main.nwd"))
|
||||
refFile = path.join(nwTempGUI,"data_9","8010bd9270f9_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_8010bd9270f9_main.nwd"))
|
||||
refFile = path.join(nwTempGUI,"data_3","1489056e0916_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_1489056e0916_main.nwd"))
|
||||
refFile = path.join(nwTempGUI,"data_7","688b6ef52555_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_688b6ef52555_main.nwd"))
|
||||
refFile = path.join(nwTempGUI,"data_1","a6562590ef19_main.nwd")
|
||||
assert cmpFiles(refFile, path.join(nwRef,"gui","1_a6562590ef19_main.nwd"))
|
||||
|
||||
nwGUI.closeMain()
|
||||
# qtbot.stopForInteraction()
|
||||
@@ -258,7 +258,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Create new, save, open project
|
||||
nwGUI.theProject.handleSeed = 42
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject(nwTempGUI, True)
|
||||
nwGUI.mainConf.backupPath = nwTempGUI
|
||||
|
||||
@@ -345,7 +345,7 @@ def testItemEditor(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Create new, save, open project
|
||||
nwGUI.theProject.handleSeed = 42
|
||||
nwGUI.theProject.projTree.setSeed(42)
|
||||
assert nwGUI.newProject(nwTempGUI, True)
|
||||
|
||||
itemEdit = GuiItemEditor(nwGUI, nwGUI.theProject, "31489056e0916")
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter NWItem Class Tester
|
||||
"""
|
||||
|
||||
import nw
|
||||
import pytest
|
||||
|
||||
from lxml import etree
|
||||
from nwdummy import DummyMain
|
||||
|
||||
from nw.config import Config
|
||||
from nw.project.project import NWProject, NWItem
|
||||
from nw.constants import nwItemClass, nwItemType, nwItemLayout
|
||||
|
||||
theConf = Config()
|
||||
theMain = DummyMain()
|
||||
theMain.mainConf = theConf
|
||||
|
||||
theProject = NWProject(theMain)
|
||||
theItem = NWItem(theProject)
|
||||
nwXML = etree.Element("novelWriterXML")
|
||||
|
||||
@pytest.mark.project
|
||||
def testItemSettersSimple():
|
||||
|
||||
# Name
|
||||
theItem.setName("A Name")
|
||||
assert theItem.itemName == "A Name"
|
||||
theItem.setName("\t A Name ")
|
||||
assert theItem.itemName == "A Name"
|
||||
|
||||
# Handle
|
||||
theItem.setHandle(123)
|
||||
assert theItem.itemHandle is None
|
||||
theItem.setHandle("0123456789abcdef")
|
||||
assert theItem.itemHandle is None
|
||||
theItem.setHandle("0123456789abc")
|
||||
assert theItem.itemHandle == "0123456789abc"
|
||||
|
||||
# Parent
|
||||
theItem.setParent(None)
|
||||
assert theItem.parHandle is None
|
||||
theItem.setParent(123)
|
||||
assert theItem.parHandle is None
|
||||
theItem.setParent("0123456789abcdef")
|
||||
assert theItem.parHandle is None
|
||||
theItem.setParent("0123456789abc")
|
||||
assert theItem.parHandle == "0123456789abc"
|
||||
|
||||
# Order
|
||||
theItem.setOrder(None)
|
||||
assert theItem.itemOrder == 0
|
||||
theItem.setOrder("1")
|
||||
assert theItem.itemOrder == 1
|
||||
theItem.setOrder(1)
|
||||
assert theItem.itemOrder == 1
|
||||
|
||||
# Status
|
||||
theItem.setStatus("Nonsense")
|
||||
assert theItem.itemStatus == "New"
|
||||
theItem.setStatus("New")
|
||||
assert theItem.itemStatus == "New"
|
||||
theItem.setStatus("Minor")
|
||||
assert theItem.itemStatus == "Minor"
|
||||
theItem.setStatus("Major")
|
||||
assert theItem.itemStatus == "Major"
|
||||
theItem.setStatus("Main")
|
||||
assert theItem.itemStatus == "Main"
|
||||
|
||||
# Expanded
|
||||
theItem.setExpanded(8)
|
||||
assert not theItem.isExpanded
|
||||
theItem.setExpanded(None)
|
||||
assert not theItem.isExpanded
|
||||
theItem.setExpanded("None")
|
||||
assert not theItem.isExpanded
|
||||
theItem.setExpanded("What?")
|
||||
assert not theItem.isExpanded
|
||||
theItem.setExpanded("True")
|
||||
assert theItem.isExpanded
|
||||
theItem.setExpanded(True)
|
||||
assert theItem.isExpanded
|
||||
|
||||
# CharCount
|
||||
theItem.setCharCount(None)
|
||||
assert theItem.charCount == 0
|
||||
theItem.setCharCount("1")
|
||||
assert theItem.charCount == 1
|
||||
theItem.setCharCount(1)
|
||||
assert theItem.charCount == 1
|
||||
|
||||
# WordCount
|
||||
theItem.setWordCount(None)
|
||||
assert theItem.wordCount == 0
|
||||
theItem.setWordCount("1")
|
||||
assert theItem.wordCount == 1
|
||||
theItem.setWordCount(1)
|
||||
assert theItem.wordCount == 1
|
||||
|
||||
# ParaCount
|
||||
theItem.setParaCount(None)
|
||||
assert theItem.paraCount == 0
|
||||
theItem.setParaCount("1")
|
||||
assert theItem.paraCount == 1
|
||||
theItem.setParaCount(1)
|
||||
assert theItem.paraCount == 1
|
||||
|
||||
# CursorPos
|
||||
theItem.setCursorPos(None)
|
||||
assert theItem.cursorPos == 0
|
||||
theItem.setCursorPos("1")
|
||||
assert theItem.cursorPos == 1
|
||||
theItem.setCursorPos(1)
|
||||
assert theItem.cursorPos == 1
|
||||
|
||||
@pytest.mark.project
|
||||
def testItemClassSetter():
|
||||
|
||||
# Class
|
||||
theItem.setClass(None)
|
||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
||||
theItem.setClass("NONSENSE")
|
||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
||||
theItem.setClass("NO_CLASS")
|
||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
||||
theItem.setClass("NOVEL")
|
||||
assert theItem.itemClass == nwItemClass.NOVEL
|
||||
theItem.setClass("PLOT")
|
||||
assert theItem.itemClass == nwItemClass.PLOT
|
||||
theItem.setClass("CHARACTER")
|
||||
assert theItem.itemClass == nwItemClass.CHARACTER
|
||||
theItem.setClass("WORLD")
|
||||
assert theItem.itemClass == nwItemClass.WORLD
|
||||
theItem.setClass("TIMELINE")
|
||||
assert theItem.itemClass == nwItemClass.TIMELINE
|
||||
theItem.setClass("OBJECT")
|
||||
assert theItem.itemClass == nwItemClass.OBJECT
|
||||
theItem.setClass("ENTITY")
|
||||
assert theItem.itemClass == nwItemClass.ENTITY
|
||||
theItem.setClass("CUSTOM")
|
||||
assert theItem.itemClass == nwItemClass.CUSTOM
|
||||
theItem.setClass("TRASH")
|
||||
assert theItem.itemClass == nwItemClass.TRASH
|
||||
|
||||
@pytest.mark.project
|
||||
def testItemTypeSetter():
|
||||
|
||||
# Class
|
||||
theItem.setType(None)
|
||||
assert theItem.itemType == nwItemType.NO_TYPE
|
||||
theItem.setType("NONSENSE")
|
||||
assert theItem.itemType == nwItemType.NO_TYPE
|
||||
theItem.setType("NO_TYPE")
|
||||
assert theItem.itemType == nwItemType.NO_TYPE
|
||||
theItem.setType("ROOT")
|
||||
assert theItem.itemType == nwItemType.ROOT
|
||||
theItem.setType("FOLDER")
|
||||
assert theItem.itemType == nwItemType.FOLDER
|
||||
theItem.setType("FILE")
|
||||
assert theItem.itemType == nwItemType.FILE
|
||||
theItem.setType("TRASH")
|
||||
assert theItem.itemType == nwItemType.TRASH
|
||||
|
||||
@pytest.mark.project
|
||||
def testItemLayoutSetter():
|
||||
|
||||
# Class
|
||||
theItem.setLayout(None)
|
||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||
theItem.setLayout("NONSENSE")
|
||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||
theItem.setLayout("NO_LAYOUT")
|
||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||
theItem.setLayout("TITLE")
|
||||
assert theItem.itemLayout == nwItemLayout.TITLE
|
||||
theItem.setLayout("BOOK")
|
||||
assert theItem.itemLayout == nwItemLayout.BOOK
|
||||
theItem.setLayout("PAGE")
|
||||
assert theItem.itemLayout == nwItemLayout.PAGE
|
||||
theItem.setLayout("PARTITION")
|
||||
assert theItem.itemLayout == nwItemLayout.PARTITION
|
||||
theItem.setLayout("UNNUMBERED")
|
||||
assert theItem.itemLayout == nwItemLayout.UNNUMBERED
|
||||
theItem.setLayout("CHAPTER")
|
||||
assert theItem.itemLayout == nwItemLayout.CHAPTER
|
||||
theItem.setLayout("SCENE")
|
||||
assert theItem.itemLayout == nwItemLayout.SCENE
|
||||
theItem.setLayout("NOTE")
|
||||
assert theItem.itemLayout == nwItemLayout.NOTE
|
||||
|
||||
@pytest.mark.project
|
||||
def testItemXMLPackUnpack():
|
||||
|
||||
# Pack
|
||||
xContent = etree.SubElement(nwXML, "content")
|
||||
theItem.packXML(xContent)
|
||||
assert etree.tostring(xContent, pretty_print=False, encoding="utf-8") == (
|
||||
b"<content>"
|
||||
b"<item handle=\"0123456789abc\" order=\"1\" parent=\"0123456789abc\">"
|
||||
b"<name>A Name</name><type>TRASH</type><class>TRASH</class><status>Main</status><expanded>True</expanded>"
|
||||
b"</item>"
|
||||
b"</content>"
|
||||
)
|
||||
|
||||
# Unpack
|
||||
assert theItem.unpackXML(xContent[0])
|
||||
assert theItem.itemHandle == "0123456789abc"
|
||||
assert theItem.parHandle == "0123456789abc"
|
||||
assert theItem.itemOrder == 1
|
||||
assert theItem.isExpanded
|
||||
assert theItem.charCount == 1
|
||||
assert theItem.wordCount == 1
|
||||
assert theItem.paraCount == 1
|
||||
assert theItem.cursorPos == 1
|
||||
assert theItem.itemClass == nwItemClass.TRASH
|
||||
assert theItem.itemType == nwItemType.TRASH
|
||||
assert theItem.itemLayout == nwItemLayout.NOTE
|
||||
@@ -2,24 +2,24 @@
|
||||
"""novelWriter Project Class Tester
|
||||
"""
|
||||
|
||||
import nw, pytest, types
|
||||
import nw
|
||||
import pytest
|
||||
from os import path
|
||||
|
||||
from nwtools import *
|
||||
from nwdummy import DummyMain
|
||||
|
||||
from nw.config import Config
|
||||
from nw.config import Config
|
||||
from nw.project.project import NWProject
|
||||
from nw.project.item import NWItem
|
||||
from nw.project.index import NWIndex
|
||||
from nw.constants import nwItemClass
|
||||
from nw.project.index import NWIndex
|
||||
from nw.constants import nwItemClass
|
||||
|
||||
theConf = Config()
|
||||
theMain = DummyMain()
|
||||
theMain.mainConf = theConf
|
||||
|
||||
theProject = NWProject(theMain)
|
||||
theProject.handleSeed = 42
|
||||
theProject.projTree.setSeed(42)
|
||||
|
||||
@pytest.mark.project
|
||||
def testProjectNew(nwTempProj,nwRef,nwTemp):
|
||||
|
||||
Reference in New Issue
Block a user