Refactor outline details panel code

This commit is contained in:
Veronica Berglyd Olsen
2024-10-31 18:28:58 +01:00
parent ccb5f8418b
commit dd09d3af2f
4 changed files with 79 additions and 168 deletions
+3
View File
@@ -73,6 +73,9 @@ VALID_MAP: dict[str, set[str]] = {
"widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
"novelRoot",
},
"GuiOutlineDetails": {
"detailsWidth", "tagsWidth",
}
}
+8 -4
View File
@@ -30,7 +30,7 @@ from PyQt5.QtWidgets import QGridLayout, QLabel, QWidget
from novelwriter import CONFIG, SHARED
from novelwriter.common import elide
from novelwriter.constants import nwLabels, trConst
from novelwriter.constants import nwLabels, nwStats, trConst
from novelwriter.types import (
QtAlignLeft, QtAlignLeftBase, QtAlignRight, QtAlignRightBase,
QtAlignRightMiddle
@@ -62,6 +62,10 @@ class GuiItemDetails(QWidget):
fntValue = self.font()
fntValue.setPointSizeF(0.9*fPt)
trStats1 = trConst(nwLabels.STATS_NAME[nwStats.CHARS_ALL])
trStats2 = trConst(nwLabels.STATS_NAME[nwStats.WORDS_ALL])
trStats3 = trConst(nwLabels.STATS_NAME[nwStats.PARAGRAPHS])
# Label
self.labelName = QLabel(self.tr("Label"), self)
self.labelName.setFont(fntLabel)
@@ -113,7 +117,7 @@ class GuiItemDetails(QWidget):
self.usageData.setWordWrap(True)
# Character Count
self.cCountName = QLabel(" "+self.tr("Characters"), self)
self.cCountName = QLabel(trStats1, self)
self.cCountName.setFont(fntLabel)
self.cCountName.setAlignment(QtAlignRight)
@@ -122,7 +126,7 @@ class GuiItemDetails(QWidget):
self.cCountData.setAlignment(QtAlignRight)
# Word Count
self.wCountName = QLabel(" "+self.tr("Words"), self)
self.wCountName = QLabel(trStats2, self)
self.wCountName.setFont(fntLabel)
self.wCountName.setAlignment(QtAlignRight)
@@ -131,7 +135,7 @@ class GuiItemDetails(QWidget):
self.wCountData.setAlignment(QtAlignRight)
# Paragraph Count
self.pCountName = QLabel(" "+self.tr("Paragraphs"), self)
self.pCountName = QLabel(trStats3, self)
self.pCountName.setFont(fntLabel)
self.pCountName.setAlignment(QtAlignRight)
+66 -163
View File
@@ -42,7 +42,7 @@ from PyQt5.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe
from novelwriter.constants import nwKeyWords, nwLabels, nwStyles, trConst
from novelwriter.constants import nwKeyWords, nwLabels, nwStats, nwStyles, trConst
from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
from novelwriter.error import logException
from novelwriter.extensions.configlayout import NColourLabel
@@ -135,12 +135,14 @@ class GuiOutlineView(QWidget):
self.outlineBar.populateNovelList()
self.outlineBar.setCurrentRoot(lastOutline)
self.outlineBar.setEnabled(True)
self.outlineData.loadGuiSettings()
return
def closeProjectTasks(self) -> None:
"""Run closing project tasks."""
self.outlineTree.closeProjectTasks()
self.outlineData.saveGuiSettings()
self.outlineData.updateClasses()
self.clearOutline()
return
@@ -799,6 +801,10 @@ class GuiOutlineDetails(QScrollArea):
bFont = SHARED.theme.guiFontB
trStats1 = trConst(nwLabels.STATS_NAME[nwStats.CHARS_ALL])
trStats2 = trConst(nwLabels.STATS_NAME[nwStats.WORDS_ALL])
trStats3 = trConst(nwLabels.STATS_NAME[nwStats.PARAGRAPHS])
# Details Area
self.titleLabel = QLabel(self.tr("Title"), self)
self.fileLabel = QLabel(self.tr("Document"), self)
@@ -819,9 +825,9 @@ class GuiOutlineDetails(QScrollArea):
self.itemValue.setMaximumWidth(maxTitle)
# Stats Area
self.cCLabel = QLabel(self.tr("Characters"), self)
self.wCLabel = QLabel(self.tr("Words"), self)
self.pCLabel = QLabel(self.tr("Paragraphs"), self)
self.cCLabel = QLabel(trStats1, self)
self.wCLabel = QLabel(trStats2, self)
self.pCLabel = QLabel(trStats3, self)
self.cCValue = QLabel("", self)
self.wCValue = QLabel("", self)
self.pCValue = QLabel("", self)
@@ -848,94 +854,9 @@ class GuiOutlineDetails(QScrollArea):
self.synopLWrap = QHBoxLayout()
self.synopLWrap.addWidget(self.synopValue, 1)
# Tags
self.povKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY]), self)
self.focKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY]), self)
self.chrKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY]), self)
self.pltKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY]), self)
self.timKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.TIME_KEY]), self)
self.wldKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY]), self)
self.objKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY]), self)
self.entKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY]), self)
self.cstKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY]), self)
self.styKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.STORY_KEY]), self)
self.mntKeyLabel = QLabel(trConst(nwLabels.KEY_NAME[nwKeyWords.MENTION_KEY]), self)
self.povKeyLabel.setFont(bFont)
self.focKeyLabel.setFont(bFont)
self.chrKeyLabel.setFont(bFont)
self.pltKeyLabel.setFont(bFont)
self.timKeyLabel.setFont(bFont)
self.wldKeyLabel.setFont(bFont)
self.objKeyLabel.setFont(bFont)
self.entKeyLabel.setFont(bFont)
self.cstKeyLabel.setFont(bFont)
self.styKeyLabel.setFont(bFont)
self.mntKeyLabel.setFont(bFont)
self.povKeyLWrap = QHBoxLayout()
self.focKeyLWrap = QHBoxLayout()
self.chrKeyLWrap = QHBoxLayout()
self.pltKeyLWrap = QHBoxLayout()
self.timKeyLWrap = QHBoxLayout()
self.wldKeyLWrap = QHBoxLayout()
self.objKeyLWrap = QHBoxLayout()
self.entKeyLWrap = QHBoxLayout()
self.cstKeyLWrap = QHBoxLayout()
self.styKeyLWrap = QHBoxLayout()
self.mntKeyLWrap = QHBoxLayout()
self.povKeyValue = QLabel("", self)
self.focKeyValue = QLabel("", self)
self.chrKeyValue = QLabel("", self)
self.pltKeyValue = QLabel("", self)
self.timKeyValue = QLabel("", self)
self.wldKeyValue = QLabel("", self)
self.objKeyValue = QLabel("", self)
self.entKeyValue = QLabel("", self)
self.cstKeyValue = QLabel("", self)
self.styKeyValue = QLabel("", self)
self.mntKeyValue = QLabel("", self)
self.povKeyValue.setWordWrap(True)
self.focKeyValue.setWordWrap(True)
self.chrKeyValue.setWordWrap(True)
self.pltKeyValue.setWordWrap(True)
self.timKeyValue.setWordWrap(True)
self.wldKeyValue.setWordWrap(True)
self.objKeyValue.setWordWrap(True)
self.entKeyValue.setWordWrap(True)
self.cstKeyValue.setWordWrap(True)
self.styKeyValue.setWordWrap(True)
self.mntKeyValue.setWordWrap(True)
self.povKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.focKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.chrKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.pltKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.timKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.wldKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.objKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.entKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.cstKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.styKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.mntKeyValue.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.povKeyLWrap.addWidget(self.povKeyValue, 1)
self.focKeyLWrap.addWidget(self.focKeyValue, 1)
self.chrKeyLWrap.addWidget(self.chrKeyValue, 1)
self.pltKeyLWrap.addWidget(self.pltKeyValue, 1)
self.timKeyLWrap.addWidget(self.timKeyValue, 1)
self.wldKeyLWrap.addWidget(self.wldKeyValue, 1)
self.objKeyLWrap.addWidget(self.objKeyValue, 1)
self.entKeyLWrap.addWidget(self.entKeyValue, 1)
self.cstKeyLWrap.addWidget(self.cstKeyValue, 1)
self.styKeyLWrap.addWidget(self.styKeyValue, 1)
self.mntKeyLWrap.addWidget(self.mntKeyValue, 1)
# Selected Item Details
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
self.mainForm = QGridLayout()
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
self.mainGroup.setLayout(self.mainForm)
self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, QtAlignLeftTop)
@@ -959,46 +880,37 @@ class GuiOutlineDetails(QScrollArea):
self.mainForm.setVerticalSpacing(vSpace)
# Selected Item Tags
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
self.tagsForm = QGridLayout()
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
self.tagsGroup.setLayout(self.tagsForm)
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.focKeyLabel, 1, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.timKeyLabel, 4, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.objKeyLabel, 6, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.objKeyLWrap, 6, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.entKeyLabel, 7, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.entKeyLWrap, 7, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.cstKeyLabel, 8, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.cstKeyLWrap, 8, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.styKeyLabel, 9, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.styKeyLWrap, 9, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.mntKeyLabel, 10, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.mntKeyLWrap, 10, 1, QtAlignLeftTop)
self.tagValues: dict[str, tuple[QLabel, QLabel]] = {}
for key in nwKeyWords.ALL_KEYS:
label = QLabel(trConst(nwLabels.KEY_NAME[key]), self)
label.setFont(bFont)
value = QLabel("", self)
value.setWordWrap(True)
value.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
layout = QHBoxLayout()
layout.addWidget(value, 1)
n = len(self.tagValues)
self.tagsForm.addWidget(label, n, 0, QtAlignLeftTop)
self.tagsForm.addLayout(layout, n, 1, QtAlignLeftTop)
self.tagValues[key] = (label, value)
self.tagsForm.setColumnStretch(1, 1)
self.tagsForm.setRowStretch(10, 1)
self.tagsForm.setRowStretch(len(self.tagValues), 1)
self.tagsForm.setHorizontalSpacing(hSpace)
self.tagsForm.setVerticalSpacing(vSpace)
# Assemble
self.outerWidget = QWidget(self)
self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.mainGroup, 0)
self.outerBox.addWidget(self.tagsGroup, 1)
self.mainSplit = QSplitter(Qt.Orientation.Horizontal)
self.mainSplit.addWidget(self.mainGroup)
self.mainSplit.addWidget(self.tagsGroup)
self.mainSplit.setCollapsible(0, False)
self.mainSplit.setCollapsible(1, False)
self.outerWidget.setLayout(self.outerBox)
self.setWidget(self.outerWidget)
self.setWidget(self.mainSplit)
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
self.setVerticalScrollBarPolicy(QtScrollAsNeeded)
@@ -1024,6 +936,28 @@ class GuiOutlineDetails(QScrollArea):
self.updateClasses()
return
def loadGuiSettings(self) -> None:
"""Run open project tasks."""
half = self.width() // 2
pOptions = SHARED.project.options
self.mainSplit.setSizes([
CONFIG.pxInt(pOptions.getInt("GuiOutlineDetails", "detailsWidth", half)),
CONFIG.pxInt(pOptions.getInt("GuiOutlineDetails", "tagsWidth", half))
])
return
def saveGuiSettings(self) -> None:
"""Run close project tasks."""
mainSplit = self.mainSplit.sizes()
detailsWidth = CONFIG.rpxInt(mainSplit[0])
tagsWidth = CONFIG.rpxInt(mainSplit[1])
logger.debug("Saving State: GuiOutlineDetails")
pOptions = SHARED.project.options
pOptions.setValue("GuiOutlineDetails", "detailsWidth", detailsWidth)
pOptions.setValue("GuiOutlineDetails", "tagsWidth", tagsWidth)
return
def clearDetails(self) -> None:
"""Clear all the data labels."""
self.titleLabel.setText(self.tr("Title"))
@@ -1034,17 +968,10 @@ class GuiOutlineDetails(QScrollArea):
self.wCValue.setText("")
self.pCValue.setText("")
self.synopValue.setText("")
self.povKeyValue.setText("")
self.focKeyValue.setText("")
self.chrKeyValue.setText("")
self.pltKeyValue.setText("")
self.timKeyValue.setText("")
self.wldKeyValue.setText("")
self.objKeyValue.setText("")
self.entKeyValue.setText("")
self.cstKeyValue.setText("")
self.styKeyValue.setText("")
self.mntKeyValue.setText("")
for _, value in self.tagValues.values():
value.setText("")
self.updateClasses()
return
@@ -1076,17 +1003,8 @@ class GuiOutlineDetails(QScrollArea):
self.synopValue.setText(novIdx.synopsis)
self.povKeyValue.setText(self._formatTags(novRefs, nwKeyWords.POV_KEY))
self.focKeyValue.setText(self._formatTags(novRefs, nwKeyWords.FOCUS_KEY))
self.chrKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CHAR_KEY))
self.pltKeyValue.setText(self._formatTags(novRefs, nwKeyWords.PLOT_KEY))
self.timKeyValue.setText(self._formatTags(novRefs, nwKeyWords.TIME_KEY))
self.wldKeyValue.setText(self._formatTags(novRefs, nwKeyWords.WORLD_KEY))
self.objKeyValue.setText(self._formatTags(novRefs, nwKeyWords.OBJECT_KEY))
self.entKeyValue.setText(self._formatTags(novRefs, nwKeyWords.ENTITY_KEY))
self.cstKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CUSTOM_KEY))
self.styKeyValue.setText(self._formatTags(novRefs, nwKeyWords.STORY_KEY))
self.mntKeyValue.setText(self._formatTags(novRefs, nwKeyWords.MENTION_KEY))
for key, (_, value) in self.tagValues.items():
value.setText(self._formatTags(novRefs, key))
return
@@ -1094,27 +1012,12 @@ class GuiOutlineDetails(QScrollArea):
def updateClasses(self) -> None:
"""Update the visibility status of class details."""
usedClasses = SHARED.project.tree.rootClasses()
pltVisible = nwItemClass.PLOT in usedClasses
timVisible = nwItemClass.TIMELINE in usedClasses
wldVisible = nwItemClass.WORLD in usedClasses
objVisible = nwItemClass.OBJECT in usedClasses
entVisible = nwItemClass.ENTITY in usedClasses
cstVisible = nwItemClass.CUSTOM in usedClasses
self.pltKeyLabel.setVisible(pltVisible)
self.pltKeyValue.setVisible(pltVisible)
self.timKeyLabel.setVisible(timVisible)
self.timKeyValue.setVisible(timVisible)
self.wldKeyLabel.setVisible(wldVisible)
self.wldKeyValue.setVisible(wldVisible)
self.objKeyLabel.setVisible(objVisible)
self.objKeyValue.setVisible(objVisible)
self.entKeyLabel.setVisible(entVisible)
self.entKeyValue.setVisible(entVisible)
self.cstKeyLabel.setVisible(cstVisible)
self.cstKeyValue.setVisible(cstVisible)
for key, itemClass in nwKeyWords.KEY_CLASS.items():
visible = itemClass in usedClasses
if key in self.tagValues:
label, value = self.tagValues[key]
label.setVisible(visible)
value.setVisible(visible)
return
@staticmethod
+2 -1
View File
@@ -29,6 +29,7 @@ import pytest
from PyQt5.QtWidgets import QAction, QFileDialog, QWidget
from novelwriter import CONFIG, SHARED
from novelwriter.constants import nwKeyWords
from novelwriter.enum import nwItemClass, nwOutline, nwView
from novelwriter.types import QtScrollAlwaysOff, QtScrollAsNeeded
@@ -261,7 +262,7 @@ def testGuiOutline_Content(qtbot, monkeypatch, nwGUI, prjLipsum, fncPath, tstPat
assert outlineData.itemValue.text() == "Finished"
# Click POV Link
assert outlineData.povKeyValue.text() == "<a href='Bod'>Bod</a>"
assert outlineData.tagValues[nwKeyWords.POV_KEY][1].text() == "<a href='Bod'>Bod</a>"
outlineView._tagClicked("Bod")
assert nwGUI.docViewer.docHandle == "4c4f28287af27"