Details panel now has all the data
This commit is contained in:
+16
-6
@@ -95,6 +95,7 @@ class Config:
|
||||
self.projColWidth = [140, 55, 140]
|
||||
self.mainPanePos = [300, 800]
|
||||
self.docPanePos = [400, 400]
|
||||
self.outlnPanePos = [500, 150]
|
||||
self.isFullScreen = False
|
||||
|
||||
## Project
|
||||
@@ -342,6 +343,9 @@ class Config:
|
||||
self.docPanePos = self._parseLine(
|
||||
cnfParse, cnfSec, "docpane", self.CNF_LIST, self.docPanePos
|
||||
)
|
||||
self.outlnPanePos = self._parseLine(
|
||||
cnfParse, cnfSec, "outlinepane", self.CNF_LIST, self.outlnPanePos
|
||||
)
|
||||
self.isFullScreen = self._parseLine(
|
||||
cnfParse, cnfSec, "fullscreen", self.CNF_BOOL, self.isFullScreen
|
||||
)
|
||||
@@ -481,12 +485,13 @@ class Config:
|
||||
## Sizes
|
||||
cnfSec = "Sizes"
|
||||
cnfParse.add_section(cnfSec)
|
||||
cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry))
|
||||
cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth))
|
||||
cnfParse.set(cnfSec,"projcols", self._packList(self.projColWidth))
|
||||
cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos))
|
||||
cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos))
|
||||
cnfParse.set(cnfSec,"fullscreen", str(self.isFullScreen))
|
||||
cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry))
|
||||
cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth))
|
||||
cnfParse.set(cnfSec,"projcols", self._packList(self.projColWidth))
|
||||
cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos))
|
||||
cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos))
|
||||
cnfParse.set(cnfSec,"outlinepane", self._packList(self.outlnPanePos))
|
||||
cnfParse.set(cnfSec,"fullscreen", str(self.isFullScreen))
|
||||
|
||||
## Project
|
||||
cnfSec = "Project"
|
||||
@@ -700,6 +705,11 @@ class Config:
|
||||
self.confChanged = True
|
||||
return True
|
||||
|
||||
def setOutlinePanePos(self, panePos):
|
||||
self.outlnPanePos = panePos
|
||||
self.confChanged = True
|
||||
return True
|
||||
|
||||
def setShowRefPanel(self, checkState):
|
||||
self.showRefPanel = checkState
|
||||
self.confChanged = True
|
||||
|
||||
+15
-11
@@ -268,6 +268,21 @@ class GuiDocViewer(QTextBrowser):
|
||||
logger.verbose("Cursor moved to line %d" % theLine)
|
||||
return True
|
||||
|
||||
##
|
||||
# Slots
|
||||
##
|
||||
|
||||
def _linkClicked(self, theURL):
|
||||
"""Slot for a link in the document being clicked.
|
||||
"""
|
||||
theLink = theURL.url()
|
||||
logger.verbose("Clicked link: '%s'" % theLink)
|
||||
if len(theLink) > 0:
|
||||
theBits = theLink.split("=")
|
||||
if len(theBits) == 2:
|
||||
self.loadFromTag(theBits[1])
|
||||
return
|
||||
|
||||
##
|
||||
# Events
|
||||
##
|
||||
@@ -293,17 +308,6 @@ class GuiDocViewer(QTextBrowser):
|
||||
self.setTextCursor(theCursor)
|
||||
return
|
||||
|
||||
def _linkClicked(self, theURL):
|
||||
"""Slot for a link in the document being clicked.
|
||||
"""
|
||||
theLink = theURL.url()
|
||||
logger.verbose("Clicked link: '%s'" % theLink)
|
||||
if len(theLink) > 0:
|
||||
theBits = theLink.split("=")
|
||||
if len(theBits) == 2:
|
||||
self.loadFromTag(theBits[1])
|
||||
return
|
||||
|
||||
def _makeStyleSheet(self):
|
||||
"""Generate an appropriate style sheet for the document viewer,
|
||||
based on the current syntax highlighter theme,
|
||||
|
||||
@@ -100,6 +100,7 @@ class GuiOutline(QTreeWidget):
|
||||
self.setExpandsOnDoubleClick(False)
|
||||
self.setDragEnabled(False)
|
||||
self.itemDoubleClicked.connect(self._treeDoubleClick)
|
||||
self.itemSelectionChanged.connect(self._itemSelected)
|
||||
|
||||
iPx = self.theTheme.textIconSize
|
||||
self.setIconSize(QSize(iPx, iPx))
|
||||
@@ -198,6 +199,18 @@ class GuiOutline(QTreeWidget):
|
||||
self.theParent.openDocument(tHandle, tLine - 1)
|
||||
return
|
||||
|
||||
def _itemSelected(self):
|
||||
"""Extract the handle and line number of the currently selected
|
||||
title, and send it to the details panel.
|
||||
"""
|
||||
selItems = self.selectedItems()
|
||||
if selItems:
|
||||
tHandle = selItems[0].data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
|
||||
sTitle = selItems[0].data(self.colIndex[nwOutline.LINE], Qt.UserRole)
|
||||
logger.verbose("User selected entry %s:%s" % (tHandle, sTitle))
|
||||
self.theParent.projMeta.showItem(tHandle, sTitle)
|
||||
return
|
||||
|
||||
def _headerRightClick(self, clickPos):
|
||||
"""Show the header column menu.
|
||||
"""
|
||||
@@ -415,6 +428,7 @@ class GuiOutline(QTreeWidget):
|
||||
newItem.setText(self.colIndex[nwOutline.LABEL], nwItem.itemName)
|
||||
newItem.setIcon(self.colIndex[nwOutline.LABEL], self.theTheme.getIcon("proj_document"))
|
||||
newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0"))
|
||||
newItem.setData(self.colIndex[nwOutline.LINE], Qt.UserRole, sTitle)
|
||||
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
|
||||
newItem.setText(self.colIndex[nwOutline.CCOUNT], str(novIdx["cCount"]))
|
||||
newItem.setText(self.colIndex[nwOutline.WCOUNT], str(novIdx["wCount"]))
|
||||
|
||||
+209
-1
@@ -30,13 +30,22 @@ import nw
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import (
|
||||
QWidget
|
||||
QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel, QSizePolicy
|
||||
)
|
||||
|
||||
from nw.constants import nwLabels, nwKeyWords
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GuiOutlineDetails(QWidget):
|
||||
|
||||
LVL_MAP = {
|
||||
"H1" : "Title",
|
||||
"H2" : "Chapter",
|
||||
"H3" : "Scene",
|
||||
"H4" : "Section"
|
||||
}
|
||||
|
||||
def __init__(self, theParent):
|
||||
QWidget.__init__(self, theParent)
|
||||
|
||||
@@ -49,8 +58,207 @@ class GuiOutlineDetails(QWidget):
|
||||
self.theIndex = theParent.theIndex
|
||||
self.optState = theParent.theProject.optState
|
||||
|
||||
# Sizes
|
||||
minTitle = self.theTheme.getTextWidth("X"*30)
|
||||
maxTitle = self.theTheme.getTextWidth("X"*50)
|
||||
wCount = self.theTheme.getTextWidth("99,999")
|
||||
hSpace = int(0.5*self.theTheme.fontPixelSize)
|
||||
vSpace = int(0.3*self.theTheme.fontPixelSize)
|
||||
|
||||
# Details Area
|
||||
self.titleLabel = QLabel("<b>Title</b>")
|
||||
self.levelLabel = QLabel("<b>Level</b>")
|
||||
self.fileLabel = QLabel("<b>Document</b>")
|
||||
self.titleValue = QLabel("")
|
||||
self.levelValue = QLabel("")
|
||||
self.fileValue = QLabel("")
|
||||
self.titleValue.setMinimumWidth(minTitle)
|
||||
self.titleValue.setMaximumWidth(maxTitle)
|
||||
self.levelValue.setMinimumWidth(minTitle)
|
||||
self.levelValue.setMaximumWidth(maxTitle)
|
||||
self.fileValue.setMinimumWidth(minTitle)
|
||||
self.fileValue.setMaximumWidth(maxTitle)
|
||||
|
||||
# Stats Area
|
||||
self.cCLabel = QLabel("<b>Characters</b>")
|
||||
self.wCLabel = QLabel("<b>Words</b>")
|
||||
self.pCLabel = QLabel("<b>Paragraphs</b>")
|
||||
self.cCValue = QLabel("")
|
||||
self.wCValue = QLabel("")
|
||||
self.pCValue = QLabel("")
|
||||
self.cCValue.setMinimumWidth(wCount)
|
||||
self.wCValue.setMinimumWidth(wCount)
|
||||
self.pCValue.setMinimumWidth(wCount)
|
||||
self.cCValue.setAlignment(Qt.AlignRight)
|
||||
self.wCValue.setAlignment(Qt.AlignRight)
|
||||
self.pCValue.setAlignment(Qt.AlignRight)
|
||||
|
||||
# Synopsis
|
||||
self.synopLabel = QLabel("<b>Synopsis</b>")
|
||||
self.synopValue = QLabel("")
|
||||
self.synopLWrap = QHBoxLayout()
|
||||
self.synopValue.setWordWrap(True)
|
||||
self.synopValue.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||||
self.synopValue.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
self.synopLWrap.addWidget(self.synopValue, 1)
|
||||
|
||||
# Tags
|
||||
self.povKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
|
||||
self.chrKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY])
|
||||
self.pltKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])
|
||||
self.timKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.TIME_KEY])
|
||||
self.wldKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY])
|
||||
self.objKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY])
|
||||
self.entKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY])
|
||||
self.cstKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY])
|
||||
self.povKeyValue = QLabel("")
|
||||
self.chrKeyValue = QLabel("")
|
||||
self.pltKeyValue = QLabel("")
|
||||
self.timKeyValue = QLabel("")
|
||||
self.wldKeyValue = QLabel("")
|
||||
self.objKeyValue = QLabel("")
|
||||
self.entKeyValue = QLabel("")
|
||||
self.cstKeyValue = QLabel("")
|
||||
self.povKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.chrKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.pltKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.timKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.wldKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.objKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.entKeyValue.linkActivated.connect(self._tagClicked)
|
||||
self.cstKeyValue.linkActivated.connect(self._tagClicked)
|
||||
|
||||
# Selected Item Details
|
||||
self.mainGroup = QGroupBox("Title Details", self)
|
||||
self.mainForm = QGridLayout()
|
||||
self.mainGroup.setLayout(self.mainForm)
|
||||
|
||||
self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1, Qt.AlignTop | Qt.AlignRight)
|
||||
self.mainForm.addWidget(self.levelLabel, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.levelValue, 1, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1, Qt.AlignTop | Qt.AlignRight)
|
||||
self.mainForm.addWidget(self.fileLabel, 2, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.fileValue, 2, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, Qt.AlignTop | Qt.AlignRight)
|
||||
self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, Qt.AlignTop | Qt.AlignLeft)
|
||||
|
||||
self.mainForm.setColumnStretch(1, 1)
|
||||
self.mainForm.setRowStretch(4, 1)
|
||||
self.mainForm.setHorizontalSpacing(hSpace)
|
||||
self.mainForm.setVerticalSpacing(vSpace)
|
||||
|
||||
# Selected Item Tags
|
||||
self.tagsGroup = QGroupBox("Tags", self)
|
||||
self.tagsForm = QGridLayout()
|
||||
self.tagsGroup.setLayout(self.tagsForm)
|
||||
|
||||
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.povKeyValue, 0, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.chrKeyLabel, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.chrKeyValue, 1, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.pltKeyLabel, 2, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.pltKeyValue, 2, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.timKeyLabel, 3, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.timKeyValue, 3, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.wldKeyLabel, 4, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.wldKeyValue, 4, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.objKeyLabel, 5, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.objKeyValue, 5, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.entKeyLabel, 6, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.entKeyValue, 6, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.cstKeyLabel, 7, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
self.tagsForm.addWidget(self.cstKeyValue, 7, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
|
||||
|
||||
self.tagsForm.setColumnStretch(1, 1)
|
||||
self.tagsForm.setRowStretch(8, 1)
|
||||
self.tagsForm.setHorizontalSpacing(hSpace)
|
||||
self.tagsForm.setVerticalSpacing(vSpace)
|
||||
|
||||
# Assemble
|
||||
self.outerBox = QHBoxLayout()
|
||||
self.outerBox.addWidget(self.mainGroup, 0)
|
||||
self.outerBox.addWidget(self.tagsGroup, 1)
|
||||
self.outerBox.addStretch(1)
|
||||
|
||||
self.setLayout(self.outerBox)
|
||||
|
||||
logger.debug("GuiOutlineDetails initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
def showItem(self, tHandle, sTitle):
|
||||
"""Update the content of the tree with the given handle and line
|
||||
number pointing to a header.
|
||||
"""
|
||||
try:
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
novIdx = self.theIndex.novelIndex[tHandle][sTitle]
|
||||
theRefs = self.theIndex.getReferences(tHandle, sTitle)
|
||||
except:
|
||||
return False
|
||||
|
||||
self.titleValue.setText(novIdx["title"])
|
||||
if novIdx["level"] in self.LVL_MAP:
|
||||
self.levelValue.setText(self.LVL_MAP[novIdx["level"]])
|
||||
else:
|
||||
self.levelValue.setText("Unknown")
|
||||
self.fileValue.setText(nwItem.itemName)
|
||||
|
||||
self.cCValue.setText("{:n}".format(novIdx["cCount"]))
|
||||
self.wCValue.setText("{:n}".format(novIdx["pCount"]))
|
||||
self.pCValue.setText("{:n}".format(novIdx["wCount"]))
|
||||
|
||||
self.synopValue.setText(novIdx["synopsis"])
|
||||
self.synopValue.adjustSize()
|
||||
# print(self.mainForm.sizeHint().width())
|
||||
# self.synopValue.setSizePolicy() (self.mainForm.sizeHint().width())
|
||||
|
||||
self.povKeyValue.setText(self._formatTags(theRefs, nwKeyWords.POV_KEY))
|
||||
self.chrKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CHAR_KEY))
|
||||
self.pltKeyValue.setText(self._formatTags(theRefs, nwKeyWords.PLOT_KEY))
|
||||
self.timKeyValue.setText(self._formatTags(theRefs, nwKeyWords.TIME_KEY))
|
||||
self.wldKeyValue.setText(self._formatTags(theRefs, nwKeyWords.WORLD_KEY))
|
||||
self.objKeyValue.setText(self._formatTags(theRefs, nwKeyWords.OBJECT_KEY))
|
||||
self.entKeyValue.setText(self._formatTags(theRefs, nwKeyWords.ENTITY_KEY))
|
||||
self.cstKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CUSTOM_KEY))
|
||||
|
||||
return True
|
||||
|
||||
##
|
||||
# Slots
|
||||
##
|
||||
|
||||
def _tagClicked(self, theLink):
|
||||
"""Capture the click of a tag in the right-most column.
|
||||
"""
|
||||
logger.verbose("Clicked link: '%s'" % theLink)
|
||||
if len(theLink) > 0:
|
||||
theBits = theLink.split("=")
|
||||
if len(theBits) == 2:
|
||||
self.theParent.docViewer.loadFromTag(theBits[1])
|
||||
self.theParent.tabWidget.setCurrentWidget(self.theParent.splitView)
|
||||
return
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _formatTags(self, theRefs, theKey):
|
||||
"""Format the tags as clickable links.
|
||||
"""
|
||||
if theKey not in theKey:
|
||||
return ""
|
||||
refTags = []
|
||||
for tTag in theRefs[theKey]:
|
||||
refTags.append("<a href='#%s=%s'>%s</a>" % (
|
||||
theKey[1:], tTag, tTag
|
||||
))
|
||||
return ", ".join(refTags)
|
||||
|
||||
# END Class GuiOutlineDetails
|
||||
|
||||
@@ -139,6 +139,7 @@ class GuiMain(QMainWindow):
|
||||
self.splitOutline = QSplitter(Qt.Vertical)
|
||||
self.splitOutline.addWidget(self.projView)
|
||||
self.splitOutline.addWidget(self.projMeta)
|
||||
self.splitOutline.setSizes(self.mainConf.outlnPanePos)
|
||||
|
||||
self.tabWidget = QTabWidget()
|
||||
self.tabWidget.setTabPosition(QTabWidget.East)
|
||||
@@ -849,6 +850,7 @@ class GuiMain(QMainWindow):
|
||||
if not self.isZenMode:
|
||||
self.mainConf.setMainPanePos(self.splitMain.sizes())
|
||||
self.mainConf.setDocPanePos(self.splitView.sizes())
|
||||
self.mainConf.setOutlinePanePos(self.splitOutline.sizes())
|
||||
self.mainConf.saveConfig()
|
||||
self.reportConfErr()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user