208 lines
6.4 KiB
Python
208 lines
6.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""novelWriter GUI Project Outline
|
||
|
||
novelWriter – GUI Project Outline
|
||
===================================
|
||
Class holding the project outline view
|
||
|
||
File History:
|
||
Created: 2019-11-16 [0.4.1]
|
||
|
||
"""
|
||
|
||
import logging
|
||
import nw
|
||
|
||
from os import path
|
||
from time import time
|
||
|
||
from PyQt5.QtCore import Qt
|
||
from PyQt5.QtWidgets import (
|
||
QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem
|
||
)
|
||
|
||
from nw.constants import nwItemLayout, nwKeyWords, nwLabels
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class GuiProjectOutline(QWidget):
|
||
|
||
I_TITLE = 0
|
||
I_LEVEL = 1
|
||
I_LABEL = 2
|
||
I_LINE = 3
|
||
I_WCOUNT = 4
|
||
I_CCOUNT = 5
|
||
I_PCOUNT = 6
|
||
I_SYNOP = 7
|
||
I_POV = 8
|
||
I_CHAR = 9
|
||
I_PLOT = 10
|
||
I_TIME = 11
|
||
I_WORLD = 12
|
||
I_OBJECT = 13
|
||
I_ENTITY = 14
|
||
I_CUSTOM = 15
|
||
|
||
COL_ORDER = [
|
||
I_TITLE, I_LEVEL, I_LABEL, I_LINE,
|
||
I_WCOUNT, I_CCOUNT, I_PCOUNT, I_SYNOP,
|
||
I_POV, I_CHAR, I_PLOT, I_TIME,
|
||
I_WORLD, I_OBJECT, I_ENTITY, I_CUSTOM,
|
||
]
|
||
|
||
COL_LABELS = {
|
||
I_TITLE : "Title",
|
||
I_LEVEL : "Level",
|
||
I_LABEL : "Document",
|
||
I_LINE : "Line",
|
||
I_WCOUNT : "Words",
|
||
I_CCOUNT : "Chars",
|
||
I_PCOUNT : "Pars",
|
||
I_SYNOP : "Synopsis",
|
||
I_POV : "POV",
|
||
I_CHAR : nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY],
|
||
I_PLOT : nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY],
|
||
I_TIME : nwLabels.KEY_NAME[nwKeyWords.TIME_KEY],
|
||
I_WORLD : nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY],
|
||
I_OBJECT : nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY],
|
||
I_ENTITY : nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY],
|
||
I_CUSTOM : nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY],
|
||
}
|
||
|
||
def __init__(self, theParent, theProject):
|
||
QWidget.__init__(self, theParent)
|
||
|
||
logger.debug("Initialising ProjectOutline ...")
|
||
|
||
self.mainConf = nw.CONFIG
|
||
self.theParent = theParent
|
||
self.theProject = theProject
|
||
self.theIndex = self.theParent.theIndex
|
||
|
||
self.showWords = True
|
||
self.showSynopsis = True
|
||
self.showFilePath = False
|
||
|
||
self.outerBox = QVBoxLayout()
|
||
self.mainTree = QTreeWidget()
|
||
self.treeCols = self.COL_ORDER
|
||
self.lastBuild = 0
|
||
self.treeMap = {}
|
||
|
||
self.outerBox.addWidget(self.mainTree)
|
||
self.outerBox.setContentsMargins(0,0,0,0)
|
||
self.setLayout(self.outerBox)
|
||
|
||
logger.debug("ProjectOutline initialisation complete")
|
||
|
||
return
|
||
|
||
def populateTree(self):
|
||
|
||
theLabels = []
|
||
for n in self.treeCols:
|
||
theLabels.append(self.COL_LABELS[n])
|
||
|
||
self.mainTree.clear()
|
||
self.mainTree.setHeaderLabels(theLabels)
|
||
|
||
treeHead = self.mainTree.headerItem()
|
||
treeHead.setTextAlignment(self.I_CCOUNT,Qt.AlignRight)
|
||
treeHead.setTextAlignment(self.I_WCOUNT,Qt.AlignRight)
|
||
treeHead.setTextAlignment(self.I_PCOUNT,Qt.AlignRight)
|
||
|
||
currTitle = None
|
||
currChapter = None
|
||
currScene = None
|
||
|
||
for titleKey in self.theIndex.getNovelStructure():
|
||
|
||
if len(titleKey) < 16:
|
||
continue
|
||
|
||
tHandle = titleKey[:13]
|
||
sTitle = titleKey[14:]
|
||
|
||
if tHandle not in self.theIndex.novelIndex:
|
||
continue
|
||
if sTitle not in self.theIndex.novelIndex[tHandle]:
|
||
continue
|
||
|
||
tLevel = self.theIndex.novelIndex[tHandle][sTitle]["level"]
|
||
tTime = self.theIndex.novelIndex[tHandle][sTitle]["updated"]
|
||
tItem = self._createTreeItem(tHandle, sTitle)
|
||
self.treeMap[titleKey] = tItem
|
||
|
||
if tLevel == "H1":
|
||
currTitle = tItem
|
||
self.mainTree.addTopLevelItem(tItem)
|
||
elif tLevel == "H2":
|
||
if currTitle is None:
|
||
self.mainTree.addTopLevelItem(tItem)
|
||
else:
|
||
currTitle.addChild(tItem)
|
||
currChapter = tItem
|
||
elif tLevel == "H3":
|
||
if currChapter is None:
|
||
if currTitle is None:
|
||
self.mainTree.addTopLevelItem(tItem)
|
||
else:
|
||
currTitle.addChild(tItem)
|
||
else:
|
||
currChapter.addChild(tItem)
|
||
currScene = tItem
|
||
elif tLevel == "H4":
|
||
if currScene is None:
|
||
if currChapter is None:
|
||
if currTitle is None:
|
||
self.mainTree.addTopLevelItem(tItem)
|
||
else:
|
||
currTitle.addChild(tItem)
|
||
else:
|
||
currChapter.addChild(tItem)
|
||
else:
|
||
currScene.addChild(tItem)
|
||
|
||
tItem.setExpanded(True)
|
||
|
||
self.lastBuild = time()
|
||
|
||
return
|
||
|
||
##
|
||
# Internal Functions
|
||
##
|
||
|
||
def _createTreeItem(self, tHandle, sTitle):
|
||
|
||
nwItem = self.theProject.getItem(tHandle)
|
||
novIdx = self.theIndex.novelIndex[tHandle][sTitle]
|
||
|
||
newItem = QTreeWidgetItem()
|
||
newItem.setText(self.I_TITLE, novIdx["title"])
|
||
newItem.setText(self.I_LEVEL, novIdx["level"])
|
||
newItem.setText(self.I_LABEL, nwItem.itemName)
|
||
newItem.setText(self.I_LINE, sTitle[1:])
|
||
|
||
newItem.setText(self.I_CCOUNT, str(novIdx["cCount"]))
|
||
newItem.setText(self.I_WCOUNT, str(novIdx["wCount"]))
|
||
newItem.setText(self.I_PCOUNT, str(novIdx["pCount"]))
|
||
newItem.setTextAlignment(self.I_CCOUNT,Qt.AlignRight)
|
||
newItem.setTextAlignment(self.I_WCOUNT,Qt.AlignRight)
|
||
newItem.setTextAlignment(self.I_PCOUNT,Qt.AlignRight)
|
||
|
||
theRefs = self.theIndex.getReferences(tHandle, sTitle)
|
||
newItem.setText(self.I_POV, ", ".join(theRefs[nwKeyWords.POV_KEY]))
|
||
newItem.setText(self.I_CHAR, ", ".join(theRefs[nwKeyWords.CHAR_KEY]))
|
||
newItem.setText(self.I_PLOT, ", ".join(theRefs[nwKeyWords.PLOT_KEY]))
|
||
newItem.setText(self.I_TIME, ", ".join(theRefs[nwKeyWords.TIME_KEY]))
|
||
newItem.setText(self.I_WORLD, ", ".join(theRefs[nwKeyWords.WORLD_KEY]))
|
||
newItem.setText(self.I_OBJECT, ", ".join(theRefs[nwKeyWords.OBJECT_KEY]))
|
||
newItem.setText(self.I_ENTITY, ", ".join(theRefs[nwKeyWords.ENTITY_KEY]))
|
||
newItem.setText(self.I_CUSTOM, ", ".join(theRefs[nwKeyWords.CUSTOM_KEY]))
|
||
|
||
return newItem
|
||
|
||
# END Class GuiProjectOutline
|