Merge branch 'main' into outline_view
This commit is contained in:
@@ -29,7 +29,6 @@ class MockGuiMain():
|
||||
def __init__(self):
|
||||
self.mainConf = None
|
||||
self.hasProject = True
|
||||
self.theIndex = None
|
||||
self.theProject = None
|
||||
self.statusBar = MockStatusBar()
|
||||
|
||||
|
||||
@@ -1,99 +1,125 @@
|
||||
{
|
||||
"tagIndex": {
|
||||
"Bod": [3, "4c4f28287af27", "CHARACTER", "T000001"],
|
||||
"Main": [3, "2426c6f0ca922", "PLOT", "T000001"],
|
||||
"Europe": [3, "04468803b92e1", "WORLD", "T000001"]
|
||||
},
|
||||
"refIndex": {
|
||||
"fb609cd8319dc": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
"tagsIndex": {
|
||||
"Bod": {"handle": "4c4f28287af27", "heading": "T000001", "class": "CHARACTER"},
|
||||
"Main": {"handle": "2426c6f0ca922", "heading": "T000001", "class": "PLOT"},
|
||||
"Europe": {"handle": "04468803b92e1", "heading": "T000001", "class": "WORLD"}
|
||||
},
|
||||
"88243afbe5ed8": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
},
|
||||
"f96ec11c6a3da": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
},
|
||||
"441420a886d82": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
},
|
||||
"eb103bc70c90c": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
},
|
||||
"f8c0562e50f1b": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
},
|
||||
"47666c91c7ccf": {
|
||||
"T000001": [[3, "@pov", "Bod"], [4, "@plot", "Main"], [5, "@location", "Europe"]]
|
||||
},
|
||||
"4c4f28287af27": {
|
||||
"T000001": [[4, "@plot", "Main"]]
|
||||
"itemIndex": {
|
||||
"7a992350f3eb6": {
|
||||
"level": "H1",
|
||||
"headings": {
|
||||
"T000001": {"level": "H1", "title": "Lorem Ipsum", "tag": "", "cCount": 230, "wCount": 40, "pCount": 3, "synopsis": ""}
|
||||
}
|
||||
},
|
||||
"8c58a65414c23": {
|
||||
"level": "H0",
|
||||
"headings": {
|
||||
"T000000": {"level": "H0", "title": "", "tag": "", "cCount": 1058, "wCount": 176, "pCount": 2, "synopsis": ""}
|
||||
}
|
||||
},
|
||||
"88d59a277361b": {
|
||||
"level": "H2",
|
||||
"headings": {
|
||||
"T000001": {"level": "H2", "title": "Prologue", "tag": "", "cCount": 584, "wCount": 92, "pCount": 1, "synopsis": "Explanation from the lipsum.com website."}
|
||||
}
|
||||
},
|
||||
"db7e733775d4d": {
|
||||
"level": "H1",
|
||||
"headings": {
|
||||
"T000001": {"level": "H1", "title": "Act One", "tag": "", "cCount": 35, "wCount": 6, "pCount": 1, "synopsis": ""}
|
||||
}
|
||||
},
|
||||
"fb609cd8319dc": {
|
||||
"level": "H2",
|
||||
"headings": {
|
||||
"T000001": {"level": "H2", "title": "Chapter One", "tag": "", "cCount": 419, "wCount": 67, "pCount": 1, "synopsis": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam."}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"88243afbe5ed8": {
|
||||
"level": "H3",
|
||||
"headings": {
|
||||
"T000001": {"level": "H3", "title": "Scene One", "tag": "", "cCount": 1197, "wCount": 174, "pCount": 2, "synopsis": "Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur."},
|
||||
"T000013": {"level": "H4", "title": "Scene One, Section Two", "tag": "", "cCount": 1561, "wCount": 230, "pCount": 2, "synopsis": ""}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"f96ec11c6a3da": {
|
||||
"level": "H3",
|
||||
"headings": {
|
||||
"T000001": {"level": "H3", "title": "Scene Two", "tag": "", "cCount": 2034, "wCount": 299, "pCount": 3, "synopsis": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci."},
|
||||
"T000015": {"level": "H4", "title": "Scene Two, Section Two", "tag": "", "cCount": 2009, "wCount": 301, "pCount": 3, "synopsis": ""}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"846352075de7d": {
|
||||
"level": "H2",
|
||||
"headings": {
|
||||
"T000001": {"level": "H2", "title": "Why do we use it?", "tag": "", "cCount": 631, "wCount": 109, "pCount": 3, "synopsis": ""}
|
||||
}
|
||||
},
|
||||
"441420a886d82": {
|
||||
"level": "H2",
|
||||
"headings": {
|
||||
"T000001": {"level": "H2", "title": "Chapter Two", "tag": "", "cCount": 477, "wCount": 70, "pCount": 1, "synopsis": "Curabitur a elit posuere, varius ex et, convallis neque. Phasellus sagittis pharetra sem vitae dapibus. Curabitur varius lorem non pulvinar congue."}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"eb103bc70c90c": {
|
||||
"level": "H3",
|
||||
"headings": {
|
||||
"T000001": {"level": "H3", "title": "Scene Three", "tag": "", "cCount": 3006, "wCount": 439, "pCount": 4, "synopsis": "Aenean ut libero ut lectus porttitor rhoncus vel et massa. Nam pretium, nibh et varius vehicula, urna metus blandit eros, euismod pharetra diam diam et libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"f8c0562e50f1b": {
|
||||
"level": "H3",
|
||||
"headings": {
|
||||
"T000001": {"level": "H3", "title": "Scene Four", "tag": "", "cCount": 3839, "wCount": 563, "pCount": 6, "synopsis": "Nam tempor blandit magna laoreet aliquet. Vestibulum auctor posuere leo, ac gravida nisi rhoncus varius. Aenean posuere dolor vitae condimentum volutpat. Donec egestas volutpat risus, quis luctus justo."}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"47666c91c7ccf": {
|
||||
"level": "H3",
|
||||
"headings": {
|
||||
"T000001": {"level": "H3", "title": "Scene Five", "tag": "", "cCount": 3644, "wCount": 543, "pCount": 5, "synopsis": "Praesent eget est porta, dictum ante in, egestas risus. Mauris risus mauris, consequat aliquam mauris et, feugiat iaculis ipsum. Aliquam arcu ipsum, fermentum ut arcu sed, lobortis euismod sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Bod": "@pov", "Main": "@plot", "Europe": "@location"}
|
||||
}
|
||||
},
|
||||
"4c4f28287af27": {
|
||||
"level": "H1",
|
||||
"headings": {
|
||||
"T000001": {"level": "H1", "title": "Nobody Owens", "tag": "Bod", "cCount": 1864, "wCount": 284, "pCount": 3, "synopsis": ""}
|
||||
},
|
||||
"references": {
|
||||
"T000001": {"Main": "@plot"}
|
||||
}
|
||||
},
|
||||
"2426c6f0ca922": {
|
||||
"level": "H1",
|
||||
"headings": {
|
||||
"T000001": {"level": "H1", "title": "Main Plot", "tag": "Main", "cCount": 1369, "wCount": 195, "pCount": 2, "synopsis": ""}
|
||||
}
|
||||
},
|
||||
"04468803b92e1": {
|
||||
"level": "H1",
|
||||
"headings": {
|
||||
"T000001": {"level": "H1", "title": "Ancient Europe", "tag": "Europe", "cCount": 1770, "wCount": 259, "pCount": 3, "synopsis": ""}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fileIndex": {
|
||||
"7a992350f3eb6": {
|
||||
"T000001": {"level": "H1", "title": "Lorem Ipsum", "layout": "DOCUMENT", "cCount": 230, "wCount": 40, "pCount": 3, "synopsis": ""}
|
||||
},
|
||||
"8c58a65414c23": {
|
||||
"T000000": {"level": "H0", "title": "", "layout": "DOCUMENT", "cCount": 1058, "wCount": 176, "pCount": 2, "synopsis": ""}
|
||||
},
|
||||
"88d59a277361b": {
|
||||
"T000001": {"level": "H2", "title": "Prologue", "layout": "DOCUMENT", "cCount": 584, "wCount": 92, "pCount": 1, "synopsis": "Explanation from the lipsum.com website."}
|
||||
},
|
||||
"db7e733775d4d": {
|
||||
"T000001": {"level": "H1", "title": "Act One", "layout": "DOCUMENT", "cCount": 35, "wCount": 6, "pCount": 1, "synopsis": ""}
|
||||
},
|
||||
"fb609cd8319dc": {
|
||||
"T000001": {"level": "H2", "title": "Chapter One", "layout": "DOCUMENT", "cCount": 419, "wCount": 67, "pCount": 1, "synopsis": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam."}
|
||||
},
|
||||
"88243afbe5ed8": {
|
||||
"T000001": {"level": "H3", "title": "Scene One", "layout": "DOCUMENT", "cCount": 1197, "wCount": 174, "pCount": 2, "synopsis": "Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur."},
|
||||
"T000013": {"level": "H4", "title": "Scene One, Section Two", "layout": "DOCUMENT", "cCount": 1561, "wCount": 230, "pCount": 2, "synopsis": ""}
|
||||
},
|
||||
"f96ec11c6a3da": {
|
||||
"T000001": {"level": "H3", "title": "Scene Two", "layout": "DOCUMENT", "cCount": 2034, "wCount": 299, "pCount": 3, "synopsis": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci."},
|
||||
"T000015": {"level": "H4", "title": "Scene Two, Section Two", "layout": "DOCUMENT", "cCount": 2009, "wCount": 301, "pCount": 3, "synopsis": ""}
|
||||
},
|
||||
"846352075de7d": {
|
||||
"T000001": {"level": "H2", "title": "Why do we use it?", "layout": "DOCUMENT", "cCount": 631, "wCount": 109, "pCount": 3, "synopsis": ""}
|
||||
},
|
||||
"441420a886d82": {
|
||||
"T000001": {"level": "H2", "title": "Chapter Two", "layout": "DOCUMENT", "cCount": 477, "wCount": 70, "pCount": 1, "synopsis": "Curabitur a elit posuere, varius ex et, convallis neque. Phasellus sagittis pharetra sem vitae dapibus. Curabitur varius lorem non pulvinar congue."}
|
||||
},
|
||||
"eb103bc70c90c": {
|
||||
"T000001": {"level": "H3", "title": "Scene Three", "layout": "DOCUMENT", "cCount": 3006, "wCount": 439, "pCount": 4, "synopsis": "Aenean ut libero ut lectus porttitor rhoncus vel et massa. Nam pretium, nibh et varius vehicula, urna metus blandit eros, euismod pharetra diam diam et libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."}
|
||||
},
|
||||
"f8c0562e50f1b": {
|
||||
"T000001": {"level": "H3", "title": "Scene Four", "layout": "DOCUMENT", "cCount": 3839, "wCount": 563, "pCount": 6, "synopsis": "Nam tempor blandit magna laoreet aliquet. Vestibulum auctor posuere leo, ac gravida nisi rhoncus varius. Aenean posuere dolor vitae condimentum volutpat. Donec egestas volutpat risus, quis luctus justo."}
|
||||
},
|
||||
"47666c91c7ccf": {
|
||||
"T000001": {"level": "H3", "title": "Scene Five", "layout": "DOCUMENT", "cCount": 3644, "wCount": 543, "pCount": 5, "synopsis": "Praesent eget est porta, dictum ante in, egestas risus. Mauris risus mauris, consequat aliquam mauris et, feugiat iaculis ipsum. Aliquam arcu ipsum, fermentum ut arcu sed, lobortis euismod sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."}
|
||||
},
|
||||
"4c4f28287af27": {
|
||||
"T000001": {"level": "H1", "title": "Nobody Owens", "layout": "NOTE", "cCount": 1864, "wCount": 284, "pCount": 3, "synopsis": ""}
|
||||
},
|
||||
"2426c6f0ca922": {
|
||||
"T000001": {"level": "H1", "title": "Main Plot", "layout": "NOTE", "cCount": 1369, "wCount": 195, "pCount": 2, "synopsis": ""}
|
||||
},
|
||||
"04468803b92e1": {
|
||||
"T000001": {"level": "H1", "title": "Ancient Europe", "layout": "NOTE", "cCount": 1770, "wCount": 259, "pCount": 3, "synopsis": ""}
|
||||
}
|
||||
},
|
||||
"fileMeta": {
|
||||
"7a992350f3eb6": ["H1", 230, 40, 3],
|
||||
"8c58a65414c23": ["H0", 1058, 176, 2],
|
||||
"88d59a277361b": ["H2", 584, 92, 1],
|
||||
"db7e733775d4d": ["H1", 35, 6, 1],
|
||||
"fb609cd8319dc": ["H2", 419, 67, 1],
|
||||
"88243afbe5ed8": ["H3", 2758, 404, 4],
|
||||
"f96ec11c6a3da": ["H3", 4043, 600, 6],
|
||||
"846352075de7d": ["H2", 631, 109, 3],
|
||||
"441420a886d82": ["H2", 477, 70, 1],
|
||||
"eb103bc70c90c": ["H3", 3006, 439, 4],
|
||||
"f8c0562e50f1b": ["H3", 3839, 563, 6],
|
||||
"47666c91c7ccf": ["H3", 3644, 543, 5],
|
||||
"4c4f28287af27": ["H1", 1864, 284, 3],
|
||||
"2426c6f0ca922": ["H1", 1369, 195, 2],
|
||||
"04468803b92e1": ["H1", 1770, 259, 3]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ def testCoreDocument_LoadSave(monkeypatch, mockGUI, nwMinimal):
|
||||
assert theDoc.readDocument() == "### New Scene\n\n"
|
||||
|
||||
# Try to open a new (non-existent) file
|
||||
nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL)
|
||||
nHandle = theProject.tree.findRoot(nwItemClass.NOVEL)
|
||||
assert nHandle is not None
|
||||
xHandle = theProject.newFile("New File", nHandle)
|
||||
theDoc = NWDoc(theProject, xHandle)
|
||||
|
||||
+604
-672
File diff suppressed because it is too large
Load Diff
@@ -634,17 +634,17 @@ def testCoreProject_AccessItems(nwMinimal, mockGUI):
|
||||
"afb3043c7b2b3", # ROOT: Characters
|
||||
"9d5247ab588e0", # ROOT: World
|
||||
]
|
||||
assert theProject.projTree.handles() == oldOrder
|
||||
assert theProject.tree.handles() == oldOrder
|
||||
assert theProject.setTreeOrder(newOrder)
|
||||
assert theProject.projTree.handles() == newOrder
|
||||
assert theProject.tree.handles() == newOrder
|
||||
|
||||
# Add a non-existing item
|
||||
theProject.projTree._treeOrder.append("01234567789abc")
|
||||
theProject.tree._treeOrder.append("01234567789abc")
|
||||
|
||||
# Add an item with a non-existent parent
|
||||
nHandle = theProject.newFile("Test File", "a6d311a93600a")
|
||||
theProject.projTree[nHandle].setParent("cba9876543210")
|
||||
assert theProject.projTree[nHandle].itemParent == "cba9876543210"
|
||||
theProject.tree[nHandle].setParent("cba9876543210")
|
||||
assert theProject.tree[nHandle].itemParent == "cba9876543210"
|
||||
|
||||
retOrder = []
|
||||
for tItem in theProject.getProjectItems():
|
||||
@@ -661,7 +661,7 @@ def testCoreProject_AccessItems(nwMinimal, mockGUI):
|
||||
"f5ab3e30151e1", # FILE: New Chapter
|
||||
"8c659a11cd429", # FILE: New Scene
|
||||
]
|
||||
assert theProject.projTree[nHandle].itemParent is None
|
||||
assert theProject.tree[nHandle].itemParent is None
|
||||
|
||||
# END Test testCoreProject_AccessItems
|
||||
|
||||
@@ -679,15 +679,15 @@ def testCoreProject_StatusImport(mockGUI, fncDir, mockRnd):
|
||||
# Change Status
|
||||
# =============
|
||||
|
||||
theProject.projTree["0000000000014"].setStatus("Finished")
|
||||
theProject.projTree["0000000000015"].setStatus("Draft")
|
||||
theProject.projTree["0000000000016"].setStatus("Note")
|
||||
theProject.projTree["0000000000017"].setStatus("Finished")
|
||||
theProject.tree["0000000000014"].setStatus("Finished")
|
||||
theProject.tree["0000000000015"].setStatus("Draft")
|
||||
theProject.tree["0000000000016"].setStatus("Note")
|
||||
theProject.tree["0000000000017"].setStatus("Finished")
|
||||
|
||||
assert theProject.projTree["0000000000014"].itemStatus == statusKeys[3]
|
||||
assert theProject.projTree["0000000000015"].itemStatus == statusKeys[2]
|
||||
assert theProject.projTree["0000000000016"].itemStatus == statusKeys[1]
|
||||
assert theProject.projTree["0000000000017"].itemStatus == statusKeys[3]
|
||||
assert theProject.tree["0000000000014"].itemStatus == statusKeys[3]
|
||||
assert theProject.tree["0000000000015"].itemStatus == statusKeys[2]
|
||||
assert theProject.tree["0000000000016"].itemStatus == statusKeys[1]
|
||||
assert theProject.tree["0000000000017"].itemStatus == statusKeys[3]
|
||||
|
||||
newList = [
|
||||
{"key": statusKeys[0], "name": "New", "cols": (1, 1, 1)},
|
||||
@@ -723,9 +723,9 @@ def testCoreProject_StatusImport(mockGUI, fncDir, mockRnd):
|
||||
# =================
|
||||
|
||||
fHandle = theProject.newFile("Jane Doe", "8b9d2e465e150")
|
||||
theProject.projTree[fHandle].setImport("Main")
|
||||
theProject.tree[fHandle].setImport("Main")
|
||||
|
||||
assert theProject.projTree[fHandle].itemImport == importKeys[3]
|
||||
assert theProject.tree[fHandle].itemImport == importKeys[3]
|
||||
newList = [
|
||||
{"key": importKeys[0], "name": "New", "cols": (1, 1, 1)},
|
||||
{"key": importKeys[1], "name": "Minor", "cols": (2, 2, 2)},
|
||||
@@ -851,7 +851,7 @@ def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd):
|
||||
# Trash folder
|
||||
# Should create on first call, and just returned on later calls
|
||||
hTrash = "0000000000018"
|
||||
assert theProject.projTree[hTrash] is None
|
||||
assert theProject.tree[hTrash] is None
|
||||
assert theProject.trashFolder() == hTrash
|
||||
assert theProject.trashFolder() == hTrash
|
||||
|
||||
@@ -929,11 +929,11 @@ def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd):
|
||||
"0000000000010", "0000000000011", "0000000000012",
|
||||
"0000000000016", "0000000000017",
|
||||
]
|
||||
assert theProject.projTree.handles() == oldOrder
|
||||
assert theProject.tree.handles() == oldOrder
|
||||
assert theProject.setTreeOrder(newOrder)
|
||||
assert theProject.projTree.handles() == newOrder
|
||||
assert theProject.tree.handles() == newOrder
|
||||
assert theProject.setTreeOrder(oldOrder)
|
||||
assert theProject.projTree.handles() == oldOrder
|
||||
assert theProject.tree.handles() == oldOrder
|
||||
|
||||
# Session stats
|
||||
theProject.currWCount = 200
|
||||
@@ -1003,7 +1003,7 @@ def testCoreProject_OrphanedFiles(mockGUI, nwLipsum):
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
assert theProject.openProject(nwLipsum) is True
|
||||
assert theProject.projTree["636b6aa9b697b"] is None
|
||||
assert theProject.tree["636b6aa9b697b"] is None
|
||||
|
||||
# Add a file with non-existent parent
|
||||
# This file will be renoved from the project on open
|
||||
@@ -1041,11 +1041,11 @@ def testCoreProject_OrphanedFiles(mockGUI, nwLipsum):
|
||||
|
||||
assert theProject.openProject(nwLipsum)
|
||||
assert theProject.projPath is not None
|
||||
assert theProject.projTree["636b6aa9b697bb"] is None
|
||||
assert theProject.projTree["abcdefghijklm"] is None
|
||||
assert theProject.tree["636b6aa9b697bb"] is None
|
||||
assert theProject.tree["abcdefghijklm"] is None
|
||||
|
||||
# First Item with Meta Data
|
||||
oItem = theProject.projTree["636b6aa9b697b"]
|
||||
oItem = theProject.tree["636b6aa9b697b"]
|
||||
assert oItem is not None
|
||||
assert oItem.itemName == "[Recovered] Mars"
|
||||
assert oItem.itemHandle == "636b6aa9b697b"
|
||||
@@ -1055,7 +1055,7 @@ def testCoreProject_OrphanedFiles(mockGUI, nwLipsum):
|
||||
assert oItem.itemLayout == nwItemLayout.NOTE
|
||||
|
||||
# Second Item without Meta Data
|
||||
oItem = theProject.projTree["736b6aa9b697b"]
|
||||
oItem = theProject.tree["736b6aa9b697b"]
|
||||
assert oItem is not None
|
||||
assert oItem.itemName == "Recovered File 1"
|
||||
assert oItem.itemHandle == "736b6aa9b697b"
|
||||
|
||||
@@ -24,7 +24,8 @@ import pytest
|
||||
|
||||
from tools import readFile
|
||||
|
||||
from novelwriter.core import NWProject, NWIndex, ToHtml
|
||||
from novelwriter.core import NWProject, ToHtml
|
||||
from novelwriter.core.index import NWIndex
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
|
||||
@@ -24,7 +24,8 @@ import pytest
|
||||
|
||||
from tools import readFile
|
||||
|
||||
from novelwriter.core import NWProject, NWIndex, ToMarkdown
|
||||
from novelwriter.core import NWProject, ToMarkdown
|
||||
from novelwriter.core.index import NWIndex
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
|
||||
@@ -28,7 +28,8 @@ from shutil import copyfile
|
||||
|
||||
from tools import cmpFiles
|
||||
|
||||
from novelwriter.core import NWProject, NWIndex, ToOdt
|
||||
from novelwriter.core import NWProject, ToOdt
|
||||
from novelwriter.core.index import NWIndex
|
||||
from novelwriter.core.toodt import ODTParagraphStyle, ODTTextStyle, XMLParagraph, _mkTag
|
||||
|
||||
XML_NS = [
|
||||
|
||||
@@ -65,9 +65,9 @@ def testDlgItemEditor_Dialog(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
|
||||
assert nwGUI.editItem() is False
|
||||
|
||||
# Invalid Type
|
||||
nwGUI.theProject.projTree[tHandle]._type = nwItemType.NO_TYPE
|
||||
nwGUI.theProject.tree[tHandle]._type = nwItemType.NO_TYPE
|
||||
assert nwGUI.editItem() is False
|
||||
nwGUI.theProject.projTree[tHandle]._type = nwItemType.FILE
|
||||
nwGUI.theProject.tree[tHandle]._type = nwItemType.FILE
|
||||
|
||||
# Open Properly
|
||||
assert nwGUI.editItem() is True
|
||||
|
||||
@@ -185,10 +185,10 @@ def testGuiEditor_SaveText(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ipsumTe
|
||||
assert "Could not save document." in caplog.text
|
||||
|
||||
# Change header level
|
||||
assert nwGUI.theProject.projTree[sHandle].itemLayout == nwItemLayout.DOCUMENT
|
||||
assert nwGUI.theProject.tree[sHandle].itemLayout == nwItemLayout.DOCUMENT
|
||||
nwGUI.docEditor.replaceText(longText[1:])
|
||||
assert nwGUI.docEditor.saveText() is True
|
||||
assert nwGUI.theProject.projTree[sHandle].itemLayout == nwItemLayout.DOCUMENT
|
||||
assert nwGUI.theProject.tree[sHandle].itemLayout == nwItemLayout.DOCUMENT
|
||||
|
||||
# Regular save
|
||||
assert nwGUI.docEditor.saveText() is True
|
||||
@@ -236,9 +236,9 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal):
|
||||
assert nwGUI.docEditor.setCursorPosition(None) is False
|
||||
assert nwGUI.docEditor.setCursorPosition(10) is True
|
||||
assert nwGUI.docEditor.getCursorPosition() == 10
|
||||
assert nwGUI.theProject.projTree[sHandle].cursorPos != 10
|
||||
assert nwGUI.theProject.tree[sHandle].cursorPos != 10
|
||||
nwGUI.docEditor.saveCursorPosition()
|
||||
assert nwGUI.theProject.projTree[sHandle].cursorPos == 10
|
||||
assert nwGUI.theProject.tree[sHandle].cursorPos == 10
|
||||
|
||||
assert nwGUI.docEditor.setCursorLine(None) is False
|
||||
assert nwGUI.docEditor.setCursorLine(2) is True
|
||||
@@ -1226,8 +1226,8 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ips
|
||||
|
||||
# Open a document and populate it
|
||||
sHandle = "8c659a11cd429"
|
||||
nwGUI.theProject.projTree[sHandle]._initCount = 0 # Clear item's count
|
||||
nwGUI.theProject.projTree[sHandle]._wordCount = 0 # Clear item's count
|
||||
nwGUI.theProject.tree[sHandle]._initCount = 0 # Clear item's count
|
||||
nwGUI.theProject.tree[sHandle]._wordCount = 0 # Clear item's count
|
||||
assert nwGUI.openDocument(sHandle) is True
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
@@ -1253,9 +1253,9 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ips
|
||||
nwGUI.docEditor.wCounterDoc.run()
|
||||
# nwGUI.docEditor._updateDocCounts(cC, wC, pC)
|
||||
qtbot.wait(stepDelay)
|
||||
assert nwGUI.theProject.projTree[sHandle]._charCount == cC
|
||||
assert nwGUI.theProject.projTree[sHandle]._wordCount == wC
|
||||
assert nwGUI.theProject.projTree[sHandle]._paraCount == pC
|
||||
assert nwGUI.theProject.tree[sHandle]._charCount == cC
|
||||
assert nwGUI.theProject.tree[sHandle]._wordCount == wC
|
||||
assert nwGUI.theProject.tree[sHandle]._paraCount == pC
|
||||
assert nwGUI.docEditor.docFooter.wordsText.text() == f"Words: {wC} (+{wC})"
|
||||
|
||||
# Select all text
|
||||
|
||||
@@ -47,8 +47,8 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, nwLipsum):
|
||||
|
||||
# Rebuild the index
|
||||
nwGUI.mainMenu.aRebuildIndex.activate(QAction.Trigger)
|
||||
assert nwGUI.theIndex._tagIndex != {}
|
||||
assert nwGUI.theIndex._refIndex != {}
|
||||
assert nwGUI.theProject.index._tagsIndex._tags != {}
|
||||
assert nwGUI.theProject.index._itemIndex._items != {}
|
||||
|
||||
# Select a document in the project tree
|
||||
nwGUI.treeView.setSelectedHandle("88243afbe5ed8")
|
||||
@@ -140,7 +140,7 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, nwLipsum):
|
||||
nwGUI.docViewer.reloadText()
|
||||
|
||||
# Change document title
|
||||
nwItem = nwGUI.theProject.projTree["4c4f28287af27"]
|
||||
nwItem = nwGUI.theProject.tree["4c4f28287af27"]
|
||||
nwItem.setName("Test Title")
|
||||
assert nwItem.itemName == "Test Title"
|
||||
nwGUI.docViewer.updateDocInfo("4c4f28287af27")
|
||||
|
||||
@@ -180,10 +180,10 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
assert nwGUI.saveProject()
|
||||
assert nwGUI.closeProject()
|
||||
|
||||
assert len(nwGUI.theProject.projTree) == 0
|
||||
assert len(nwGUI.theProject.projTree._treeOrder) == 0
|
||||
assert len(nwGUI.theProject.projTree._treeRoots) == 0
|
||||
assert nwGUI.theProject.projTree.trashRoot() is None
|
||||
assert len(nwGUI.theProject.tree) == 0
|
||||
assert len(nwGUI.theProject.tree._treeOrder) == 0
|
||||
assert len(nwGUI.theProject.tree._treeRoots) == 0
|
||||
assert nwGUI.theProject.tree.trashRoot() is None
|
||||
assert nwGUI.theProject.projPath is None
|
||||
assert nwGUI.theProject.projMeta is None
|
||||
assert nwGUI.theProject.projFile == "nwProject.nwx"
|
||||
@@ -207,10 +207,10 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
# Check that we loaded the data
|
||||
assert len(nwGUI.theProject.projTree) == 8
|
||||
assert len(nwGUI.theProject.projTree._treeOrder) == 8
|
||||
assert len(nwGUI.theProject.projTree._treeRoots) == 4
|
||||
assert nwGUI.theProject.projTree.trashRoot() is None
|
||||
assert len(nwGUI.theProject.tree) == 8
|
||||
assert len(nwGUI.theProject.tree._treeOrder) == 8
|
||||
assert len(nwGUI.theProject.tree._treeRoots) == 4
|
||||
assert nwGUI.theProject.tree.trashRoot() is None
|
||||
assert nwGUI.theProject.projPath == fncProj
|
||||
assert nwGUI.theProject.projMeta == os.path.join(fncProj, "meta")
|
||||
assert nwGUI.theProject.projFile == "nwProject.nwx"
|
||||
@@ -463,11 +463,11 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock
|
||||
# Check a Quick Create and Delete
|
||||
assert nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
|
||||
newHandle = nwGUI.treeView.getSelectedHandle()
|
||||
assert nwGUI.theProject.projTree["0000000000020"] is not None
|
||||
assert nwGUI.theProject.tree["0000000000020"] is not None
|
||||
assert nwGUI.treeView.deleteItem()
|
||||
assert nwGUI.treeView.setSelectedHandle(newHandle)
|
||||
assert nwGUI.treeView.deleteItem()
|
||||
assert nwGUI.theProject.projTree["0000000000024"] is not None # Trash
|
||||
assert nwGUI.theProject.tree["0000000000024"] is not None # Trash
|
||||
assert nwGUI.saveProject()
|
||||
|
||||
# Check the files
|
||||
|
||||
@@ -87,7 +87,7 @@ def testGuiOutline_Main(qtbot, monkeypatch, nwGUI, nwLipsum):
|
||||
assert outlineData.itemValue.text() == "Finished"
|
||||
|
||||
# Click POV Link
|
||||
assert outlineData.povKeyValue.text() == "<a href='#pov=Bod'>Bod</a>"
|
||||
assert outlineData.povKeyValue.text() == "<a href='Bod'>Bod</a>"
|
||||
outlineData._tagClicked("#pov=Bod")
|
||||
assert nwGUI.docViewer.docHandle() == "4c4f28287af27"
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
||||
|
||||
# Create root item
|
||||
assert nwTree.newTreeItem(nwItemType.ROOT, nwItemClass.WORLD) is True
|
||||
assert "0000000000010" in nwGUI.theProject.projTree
|
||||
assert "0000000000010" in nwGUI.theProject.tree
|
||||
|
||||
# File/Folder Items
|
||||
# =================
|
||||
@@ -78,42 +78,42 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
||||
# Create new folder as child of Novel folder
|
||||
nwTree.setSelectedHandle("0000000000008")
|
||||
assert nwTree.newTreeItem(nwItemType.FOLDER) is True
|
||||
assert nwGUI.theProject.projTree["0000000000011"].itemParent == "0000000000008"
|
||||
assert nwGUI.theProject.projTree["0000000000011"].itemRoot == "0000000000008"
|
||||
assert nwGUI.theProject.projTree["0000000000011"].itemClass == nwItemClass.NOVEL
|
||||
assert nwGUI.theProject.tree["0000000000011"].itemParent == "0000000000008"
|
||||
assert nwGUI.theProject.tree["0000000000011"].itemRoot == "0000000000008"
|
||||
assert nwGUI.theProject.tree["0000000000011"].itemClass == nwItemClass.NOVEL
|
||||
|
||||
# Add a new file in the new folder
|
||||
nwTree.setSelectedHandle("0000000000011")
|
||||
assert nwTree.newTreeItem(nwItemType.FILE) is True
|
||||
assert nwGUI.theProject.projTree["0000000000012"].itemParent == "0000000000011"
|
||||
assert nwGUI.theProject.projTree["0000000000012"].itemRoot == "0000000000008"
|
||||
assert nwGUI.theProject.projTree["0000000000012"].itemClass == nwItemClass.NOVEL
|
||||
assert nwGUI.theProject.tree["0000000000012"].itemParent == "0000000000011"
|
||||
assert nwGUI.theProject.tree["0000000000012"].itemRoot == "0000000000008"
|
||||
assert nwGUI.theProject.tree["0000000000012"].itemClass == nwItemClass.NOVEL
|
||||
|
||||
# Add a new file next to the other new file
|
||||
nwTree.setSelectedHandle("0000000000012")
|
||||
assert nwTree.newTreeItem(nwItemType.FILE) is True
|
||||
assert nwGUI.theProject.projTree["0000000000013"].itemParent == "0000000000011"
|
||||
assert nwGUI.theProject.projTree["0000000000013"].itemRoot == "0000000000008"
|
||||
assert nwGUI.theProject.projTree["0000000000013"].itemClass == nwItemClass.NOVEL
|
||||
assert nwGUI.theProject.tree["0000000000013"].itemParent == "0000000000011"
|
||||
assert nwGUI.theProject.tree["0000000000013"].itemRoot == "0000000000008"
|
||||
assert nwGUI.theProject.tree["0000000000013"].itemClass == nwItemClass.NOVEL
|
||||
assert nwGUI.openDocument("0000000000013")
|
||||
assert nwGUI.docEditor.getText() == "### New Document\n\n"
|
||||
|
||||
# Add a new file to the characters folder
|
||||
nwTree.setSelectedHandle("000000000000a")
|
||||
assert nwTree.newTreeItem(nwItemType.FILE) is True
|
||||
assert nwGUI.theProject.projTree["0000000000014"].itemParent == "000000000000a"
|
||||
assert nwGUI.theProject.projTree["0000000000014"].itemRoot == "000000000000a"
|
||||
assert nwGUI.theProject.projTree["0000000000014"].itemClass == nwItemClass.CHARACTER
|
||||
assert nwGUI.theProject.tree["0000000000014"].itemParent == "000000000000a"
|
||||
assert nwGUI.theProject.tree["0000000000014"].itemRoot == "000000000000a"
|
||||
assert nwGUI.theProject.tree["0000000000014"].itemClass == nwItemClass.CHARACTER
|
||||
assert nwGUI.openDocument("0000000000014")
|
||||
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
||||
|
||||
# Make sure the sibling folder bug trap works
|
||||
nwTree.setSelectedHandle("0000000000013")
|
||||
nwGUI.theProject.projTree["0000000000013"].setParent(None) # This should not happen
|
||||
nwGUI.theProject.tree["0000000000013"].setParent(None) # This should not happen
|
||||
caplog.clear()
|
||||
assert nwTree.newTreeItem(nwItemType.FILE) is False
|
||||
assert "Internal error" in caplog.text
|
||||
nwGUI.theProject.projTree["0000000000013"].setParent("0000000000011")
|
||||
nwGUI.theProject.tree["0000000000013"].setParent("0000000000011")
|
||||
|
||||
# Get the trash folder
|
||||
nwTree._addTrashRoot()
|
||||
@@ -242,22 +242,22 @@ def testGuiProjTree_MoveItems(qtbot, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||
# ===========
|
||||
|
||||
nwTree.setSelectedHandle("0000000000008")
|
||||
assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 0
|
||||
assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 0
|
||||
|
||||
# Move novel folder up
|
||||
assert nwTree.moveTreeItem(-1) is False
|
||||
nwTree.flushTreeOrder()
|
||||
assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 0
|
||||
assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 0
|
||||
|
||||
# Move novel folder down
|
||||
assert nwTree.moveTreeItem(1) is True
|
||||
nwTree.flushTreeOrder()
|
||||
assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 1
|
||||
assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 1
|
||||
|
||||
# Move novel folder up again
|
||||
assert nwTree.moveTreeItem(-1) is True
|
||||
nwTree.flushTreeOrder()
|
||||
assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 0
|
||||
assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 0
|
||||
|
||||
# Clean up
|
||||
# qtbot.stopForInteraction()
|
||||
@@ -341,7 +341,7 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
||||
"000000000000d", "000000000000e", "000000000000f",
|
||||
"0000000000010"
|
||||
]
|
||||
trashHandle = nwGUI.theProject.projTree.trashRoot()
|
||||
trashHandle = nwGUI.theProject.tree.trashRoot()
|
||||
assert nwTree.getTreeFromHandle(trashHandle) == [
|
||||
trashHandle, "0000000000012", "0000000000011"
|
||||
]
|
||||
@@ -349,30 +349,30 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
||||
# Delete the first file again (permanent), and ask for permission
|
||||
# Also open the document in the editor, which should trigger a close
|
||||
assert os.path.isfile(os.path.join(prjDir, "content", "0000000000012.nwd"))
|
||||
assert "0000000000012" in nwGUI.theProject.projTree
|
||||
assert "0000000000012" in nwGUI.theProject.tree
|
||||
assert nwGUI.docEditor.docHandle() is None
|
||||
assert nwGUI.openDocument("0000000000012") is True
|
||||
assert nwGUI.docEditor.docHandle() == "0000000000012"
|
||||
assert nwTree.deleteItem("0000000000012") is True
|
||||
assert nwGUI.docEditor.docHandle() is None
|
||||
assert not os.path.isfile(os.path.join(prjDir, "content", "0000000000012.nwd"))
|
||||
assert "0000000000012" not in nwGUI.theProject.projTree
|
||||
assert "0000000000012" not in nwGUI.theProject.tree
|
||||
assert nwTree.getTreeFromHandle(trashHandle) == [
|
||||
trashHandle, "0000000000011"
|
||||
]
|
||||
|
||||
# Delete the second file, and skip asking for permission
|
||||
assert os.path.isfile(os.path.join(prjDir, "content", "0000000000011.nwd"))
|
||||
assert "0000000000011" in nwGUI.theProject.projTree
|
||||
assert "0000000000011" in nwGUI.theProject.tree
|
||||
assert nwTree.deleteItem("0000000000011", alreadyAsked=True) is True
|
||||
assert not os.path.isfile(os.path.join(prjDir, "content", "0000000000011.nwd"))
|
||||
assert "0000000000011" not in nwGUI.theProject.projTree
|
||||
assert "0000000000011" not in nwGUI.theProject.tree
|
||||
assert nwTree.getTreeFromHandle(trashHandle) == [trashHandle]
|
||||
|
||||
# Delete Folder
|
||||
# =============
|
||||
|
||||
trashHandle = nwGUI.theProject.projTree.trashRoot()
|
||||
trashHandle = nwGUI.theProject.tree.trashRoot()
|
||||
|
||||
# Add a folder with two files
|
||||
nwTree.setSelectedHandle("0000000000009")
|
||||
|
||||
Reference in New Issue
Block a user