Restructured the index a bit, and added more columns to the outline
This commit is contained in:
@@ -15,6 +15,7 @@ import nw
|
|||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem
|
QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem
|
||||||
)
|
)
|
||||||
@@ -25,6 +26,31 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class GuiProjectOutline(QWidget):
|
class GuiProjectOutline(QWidget):
|
||||||
|
|
||||||
|
I_TITLE = 0
|
||||||
|
I_LEVEL = 1
|
||||||
|
I_LABEL = 2
|
||||||
|
I_LINE = 3
|
||||||
|
I_WORDS = 4
|
||||||
|
I_CHARS = 5
|
||||||
|
I_PARAS = 6
|
||||||
|
I_SYNOP = 7
|
||||||
|
|
||||||
|
COL_ORDER = [
|
||||||
|
I_TITLE, I_LEVEL, I_LABEL, I_LINE,
|
||||||
|
I_WORDS, I_CHARS, I_PARAS, I_SYNOP,
|
||||||
|
]
|
||||||
|
|
||||||
|
COL_LABELS = {
|
||||||
|
I_TITLE : "Title",
|
||||||
|
I_LEVEL : "Level",
|
||||||
|
I_LABEL : "Document",
|
||||||
|
I_LINE : "Line",
|
||||||
|
I_WORDS : "Words",
|
||||||
|
I_CHARS : "Chars",
|
||||||
|
I_PARAS : "Pars",
|
||||||
|
I_SYNOP : "Synopsis",
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, theParent, theProject):
|
def __init__(self, theParent, theProject):
|
||||||
QWidget.__init__(self, theParent)
|
QWidget.__init__(self, theParent)
|
||||||
|
|
||||||
@@ -39,8 +65,9 @@ class GuiProjectOutline(QWidget):
|
|||||||
self.showSynopsis = True
|
self.showSynopsis = True
|
||||||
self.showFilePath = False
|
self.showFilePath = False
|
||||||
|
|
||||||
self.outerBox = QVBoxLayout()
|
self.outerBox = QVBoxLayout()
|
||||||
self.mainTree = QTreeWidget()
|
self.mainTree = QTreeWidget()
|
||||||
|
self.treeOrder = self.COL_ORDER
|
||||||
|
|
||||||
self.outerBox.addWidget(self.mainTree)
|
self.outerBox.addWidget(self.mainTree)
|
||||||
self.outerBox.setContentsMargins(0,0,0,0)
|
self.outerBox.setContentsMargins(0,0,0,0)
|
||||||
@@ -52,8 +79,17 @@ class GuiProjectOutline(QWidget):
|
|||||||
|
|
||||||
def populateTree(self):
|
def populateTree(self):
|
||||||
|
|
||||||
|
theLabels = []
|
||||||
|
for n in self.treeOrder:
|
||||||
|
theLabels.append(self.COL_LABELS[n])
|
||||||
|
|
||||||
self.mainTree.clear()
|
self.mainTree.clear()
|
||||||
self.mainTree.setHeaderLabels(["Title","Level","Document","Line"])
|
self.mainTree.setHeaderLabels(theLabels)
|
||||||
|
|
||||||
|
treeHead = self.mainTree.headerItem()
|
||||||
|
treeHead.setTextAlignment(self.I_CHARS,Qt.AlignRight)
|
||||||
|
treeHead.setTextAlignment(self.I_WORDS,Qt.AlignRight)
|
||||||
|
treeHead.setTextAlignment(self.I_PARAS,Qt.AlignRight)
|
||||||
|
|
||||||
currTitle = None
|
currTitle = None
|
||||||
currChapter = None
|
currChapter = None
|
||||||
@@ -69,11 +105,22 @@ class GuiProjectOutline(QWidget):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for tEntry in self.theIndex.novelIndex[tHandle]:
|
for tEntry in self.theIndex.novelIndex[tHandle]:
|
||||||
|
|
||||||
|
theLine = str(tEntry[0])
|
||||||
|
|
||||||
newItem = QTreeWidgetItem([""]*4)
|
newItem = QTreeWidgetItem([""]*4)
|
||||||
newItem.setText(0, tEntry[2])
|
newItem.setText(self.I_TITLE, tEntry[2])
|
||||||
newItem.setText(1, str(tEntry[1]))
|
newItem.setText(self.I_LEVEL, str(tEntry[1]))
|
||||||
newItem.setText(2, nwItem.itemName)
|
newItem.setText(self.I_LABEL, nwItem.itemName)
|
||||||
newItem.setText(3, str(tEntry[0]))
|
newItem.setText(self.I_LINE, theLine)
|
||||||
|
|
||||||
|
cC, wC, pC = self.theIndex.getCounts(tHandle, theLine)
|
||||||
|
newItem.setText(self.I_CHARS, str(cC))
|
||||||
|
newItem.setText(self.I_WORDS, str(wC))
|
||||||
|
newItem.setText(self.I_PARAS, str(pC))
|
||||||
|
newItem.setTextAlignment(self.I_CHARS,Qt.AlignRight)
|
||||||
|
newItem.setTextAlignment(self.I_WORDS,Qt.AlignRight)
|
||||||
|
newItem.setTextAlignment(self.I_PARAS,Qt.AlignRight)
|
||||||
|
|
||||||
if tEntry[1] == 1:
|
if tEntry[1] == 1:
|
||||||
currTitle = newItem
|
currTitle = newItem
|
||||||
|
|||||||
+83
-33
@@ -62,8 +62,9 @@ class NWIndex():
|
|||||||
self.noteIndex = {}
|
self.noteIndex = {}
|
||||||
|
|
||||||
# Meta Data
|
# Meta Data
|
||||||
|
self.fileCounts = {}
|
||||||
self.textCounts = {}
|
self.textCounts = {}
|
||||||
self.fileSynopsis = {}
|
self.textSynopsis = {}
|
||||||
|
|
||||||
# Lists
|
# Lists
|
||||||
self.novelList = []
|
self.novelList = []
|
||||||
@@ -79,8 +80,9 @@ class NWIndex():
|
|||||||
self.refIndex = {}
|
self.refIndex = {}
|
||||||
self.novelIndex = {}
|
self.novelIndex = {}
|
||||||
self.noteIndex = {}
|
self.noteIndex = {}
|
||||||
|
self.fileCounts = {}
|
||||||
self.textCounts = {}
|
self.textCounts = {}
|
||||||
self.fileSynopsis = {}
|
self.textSynopsis = {}
|
||||||
return
|
return
|
||||||
|
|
||||||
def deleteHandle(self, tHandle):
|
def deleteHandle(self, tHandle):
|
||||||
@@ -145,10 +147,12 @@ class NWIndex():
|
|||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if "fileCounts" in theData.keys():
|
||||||
|
self.fileCounts = theData["fileCounts"]
|
||||||
if "textCounts" in theData.keys():
|
if "textCounts" in theData.keys():
|
||||||
self.textCounts = theData["textCounts"]
|
self.textCounts = theData["textCounts"]
|
||||||
if "fileSynopsis" in theData.keys():
|
if "textSynopsis" in theData.keys():
|
||||||
self.fileSynopsis = theData["fileSynopsis"]
|
self.textSynopsis = theData["textSynopsis"]
|
||||||
|
|
||||||
loadsOK &= True
|
loadsOK &= True
|
||||||
|
|
||||||
@@ -186,8 +190,9 @@ class NWIndex():
|
|||||||
try:
|
try:
|
||||||
with open(metaFile,mode="w+",encoding="utf8") as outFile:
|
with open(metaFile,mode="w+",encoding="utf8") as outFile:
|
||||||
outFile.write(json.dumps({
|
outFile.write(json.dumps({
|
||||||
|
"fileCounts" : self.fileCounts,
|
||||||
"textCounts" : self.textCounts,
|
"textCounts" : self.textCounts,
|
||||||
"fileSynopsis" : self.fileSynopsis,
|
"textSynopsis" : self.textSynopsis,
|
||||||
}, indent=nIndent))
|
}, indent=nIndent))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Failed to save meta file")
|
logger.error("Failed to save meta file")
|
||||||
@@ -203,28 +208,37 @@ class NWIndex():
|
|||||||
|
|
||||||
self.indexBroken = False
|
self.indexBroken = False
|
||||||
|
|
||||||
for tTag in self.tagIndex:
|
try:
|
||||||
if len(self.tagIndex[tTag]) != 3:
|
for tTag in self.tagIndex:
|
||||||
self.indexBroken = True
|
if len(self.tagIndex[tTag]) != 3:
|
||||||
|
|
||||||
for tHandle in self.refIndex:
|
|
||||||
for tEntry in self.refIndex[tHandle]:
|
|
||||||
if len(tEntry) != 4:
|
|
||||||
self.indexBroken = True
|
self.indexBroken = True
|
||||||
|
|
||||||
for tHandle in self.novelIndex:
|
for tHandle in self.refIndex:
|
||||||
for tEntry in self.novelIndex[tHandle]:
|
for tEntry in self.refIndex[tHandle]:
|
||||||
if len(tEntry) != 4:
|
if len(tEntry) != 4:
|
||||||
|
self.indexBroken = True
|
||||||
|
|
||||||
|
for tHandle in self.novelIndex:
|
||||||
|
for tEntry in self.novelIndex[tHandle]:
|
||||||
|
if len(tEntry) != 4:
|
||||||
|
self.indexBroken = True
|
||||||
|
|
||||||
|
for tHandle in self.noteIndex:
|
||||||
|
for tEntry in self.noteIndex[tHandle]:
|
||||||
|
if len(tEntry) != 4:
|
||||||
|
self.indexBroken = True
|
||||||
|
|
||||||
|
for tHandle in self.fileCounts:
|
||||||
|
if len(self.fileCounts[tHandle]) != 3:
|
||||||
self.indexBroken = True
|
self.indexBroken = True
|
||||||
|
|
||||||
for tHandle in self.noteIndex:
|
for tHandle in self.textCounts:
|
||||||
for tEntry in self.noteIndex[tHandle]:
|
for tLine in self.textCounts[tHandle]:
|
||||||
if len(tEntry) != 4:
|
if len(self.textCounts[tHandle][tLine]) != 3:
|
||||||
self.indexBroken = True
|
self.indexBroken = True
|
||||||
|
|
||||||
for tHandle in self.textCounts:
|
except:
|
||||||
if len(self.textCounts[tHandle]) != 3:
|
self.indexBroken = True
|
||||||
self.indexBroken = True
|
|
||||||
|
|
||||||
if self.indexBroken:
|
if self.indexBroken:
|
||||||
self.clearIndex()
|
self.clearIndex()
|
||||||
@@ -275,24 +289,47 @@ class NWIndex():
|
|||||||
|
|
||||||
nLine = 0
|
nLine = 0
|
||||||
nTitle = 0
|
nTitle = 0
|
||||||
for aLine in theText.splitlines():
|
theSynopsis = {}
|
||||||
|
theCounts = {}
|
||||||
|
theLines = theText.splitlines()
|
||||||
|
for aLine in theLines:
|
||||||
aLine = aLine
|
aLine = aLine
|
||||||
nLine += 1
|
nLine += 1
|
||||||
nChar = len(aLine.strip())
|
nChar = len(aLine.strip())
|
||||||
if nChar == 0: continue
|
if nChar == 0: continue
|
||||||
|
|
||||||
if aLine.startswith(r"#"):
|
if aLine.startswith(r"#"):
|
||||||
isTitle = self.indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
isTitle = self.indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
||||||
if isTitle:
|
if isTitle and nLine > 0:
|
||||||
|
# Count words in the previous section, before we tag
|
||||||
|
# the new title location
|
||||||
|
if nTitle > 0:
|
||||||
|
lastText = "\n".join(theLines[nTitle-1:nLine-1])
|
||||||
|
cC, wC, pC = countWords(lastText)
|
||||||
|
theCounts[str(nTitle)] = [cC, wC, pC]
|
||||||
nTitle = nLine
|
nTitle = nLine
|
||||||
|
|
||||||
elif aLine.startswith(r"@"):
|
elif aLine.startswith(r"@"):
|
||||||
self.indexNoteRef(tHandle, aLine, nLine, nTitle)
|
self.indexNoteRef(tHandle, aLine, nLine, nTitle)
|
||||||
self.indexTag(tHandle, aLine, nLine, itemClass)
|
self.indexTag(tHandle, aLine, nLine, itemClass)
|
||||||
elif aLine.startswith(r"%synopsis:"):
|
|
||||||
self.fileSynopsis[tHandle] = aLine[10:].strip()
|
|
||||||
|
|
||||||
# Run word counter
|
elif aLine.startswith(r"%synopsis:"):
|
||||||
|
theSynopsis[str(nTitle)] = aLine[10:].strip()
|
||||||
|
|
||||||
|
# Count words for remaining text after last heading
|
||||||
|
if nTitle > 0:
|
||||||
|
lastText = "\n".join(theLines[nTitle-1:])
|
||||||
|
cC, wC, pC = countWords(lastText)
|
||||||
|
theCounts[str(nTitle)] = [cC, wC, pC]
|
||||||
|
|
||||||
|
if theSynopsis:
|
||||||
|
self.textSynopsis[tHandle] = theSynopsis
|
||||||
|
if theCounts:
|
||||||
|
self.textCounts[tHandle] = theCounts
|
||||||
|
|
||||||
|
# Run word counter for whole text
|
||||||
cC, wC, pC = countWords(theText)
|
cC, wC, pC = countWords(theText)
|
||||||
self.textCounts[tHandle] = [cC, wC, pC]
|
self.fileCounts[tHandle] = [cC, wC, pC]
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -438,14 +475,27 @@ class NWIndex():
|
|||||||
# Extract Data
|
# Extract Data
|
||||||
##
|
##
|
||||||
|
|
||||||
def getCounts(self, tHandle):
|
def getCounts(self, tHandle, tLine=None):
|
||||||
|
"""Returns the counts for a file, or a section of a file
|
||||||
|
starting at line tLine.
|
||||||
|
"""
|
||||||
|
|
||||||
cC = 0
|
cC = 0
|
||||||
wC = 0
|
wC = 0
|
||||||
pC = 0
|
pC = 0
|
||||||
if tHandle in self.textCounts:
|
|
||||||
cC = self.textCounts[tHandle][0]
|
if tLine is None:
|
||||||
wC = self.textCounts[tHandle][1]
|
if tHandle in self.fileCounts:
|
||||||
pC = self.textCounts[tHandle][2]
|
cC = self.fileCounts[tHandle][0]
|
||||||
|
wC = self.fileCounts[tHandle][1]
|
||||||
|
pC = self.fileCounts[tHandle][2]
|
||||||
|
else:
|
||||||
|
if tHandle in self.textCounts:
|
||||||
|
if tLine in self.textCounts[tHandle]:
|
||||||
|
cC = self.textCounts[tHandle][tLine][0]
|
||||||
|
wC = self.textCounts[tHandle][tLine][1]
|
||||||
|
pC = self.textCounts[tHandle][tLine][2]
|
||||||
|
|
||||||
return cC, wC, pC
|
return cC, wC, pC
|
||||||
|
|
||||||
def buildNovelList(self):
|
def buildNovelList(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user