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", "widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
"novelRoot", "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 import CONFIG, SHARED
from novelwriter.common import elide from novelwriter.common import elide
from novelwriter.constants import nwLabels, trConst from novelwriter.constants import nwLabels, nwStats, trConst
from novelwriter.types import ( from novelwriter.types import (
QtAlignLeft, QtAlignLeftBase, QtAlignRight, QtAlignRightBase, QtAlignLeft, QtAlignLeftBase, QtAlignRight, QtAlignRightBase,
QtAlignRightMiddle QtAlignRightMiddle
@@ -62,6 +62,10 @@ class GuiItemDetails(QWidget):
fntValue = self.font() fntValue = self.font()
fntValue.setPointSizeF(0.9*fPt) 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 # Label
self.labelName = QLabel(self.tr("Label"), self) self.labelName = QLabel(self.tr("Label"), self)
self.labelName.setFont(fntLabel) self.labelName.setFont(fntLabel)
@@ -113,7 +117,7 @@ class GuiItemDetails(QWidget):
self.usageData.setWordWrap(True) self.usageData.setWordWrap(True)
# Character Count # Character Count
self.cCountName = QLabel(" "+self.tr("Characters"), self) self.cCountName = QLabel(trStats1, self)
self.cCountName.setFont(fntLabel) self.cCountName.setFont(fntLabel)
self.cCountName.setAlignment(QtAlignRight) self.cCountName.setAlignment(QtAlignRight)
@@ -122,7 +126,7 @@ class GuiItemDetails(QWidget):
self.cCountData.setAlignment(QtAlignRight) self.cCountData.setAlignment(QtAlignRight)
# Word Count # Word Count
self.wCountName = QLabel(" "+self.tr("Words"), self) self.wCountName = QLabel(trStats2, self)
self.wCountName.setFont(fntLabel) self.wCountName.setFont(fntLabel)
self.wCountName.setAlignment(QtAlignRight) self.wCountName.setAlignment(QtAlignRight)
@@ -131,7 +135,7 @@ class GuiItemDetails(QWidget):
self.wCountData.setAlignment(QtAlignRight) self.wCountData.setAlignment(QtAlignRight)
# Paragraph Count # Paragraph Count
self.pCountName = QLabel(" "+self.tr("Paragraphs"), self) self.pCountName = QLabel(trStats3, self)
self.pCountName.setFont(fntLabel) self.pCountName.setFont(fntLabel)
self.pCountName.setAlignment(QtAlignRight) self.pCountName.setAlignment(QtAlignRight)
+66 -163
View File
@@ -42,7 +42,7 @@ from PyQt5.QtWidgets import (
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe 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.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
from novelwriter.error import logException from novelwriter.error import logException
from novelwriter.extensions.configlayout import NColourLabel from novelwriter.extensions.configlayout import NColourLabel
@@ -135,12 +135,14 @@ class GuiOutlineView(QWidget):
self.outlineBar.populateNovelList() self.outlineBar.populateNovelList()
self.outlineBar.setCurrentRoot(lastOutline) self.outlineBar.setCurrentRoot(lastOutline)
self.outlineBar.setEnabled(True) self.outlineBar.setEnabled(True)
self.outlineData.loadGuiSettings()
return return
def closeProjectTasks(self) -> None: def closeProjectTasks(self) -> None:
"""Run closing project tasks.""" """Run closing project tasks."""
self.outlineTree.closeProjectTasks() self.outlineTree.closeProjectTasks()
self.outlineData.saveGuiSettings()
self.outlineData.updateClasses() self.outlineData.updateClasses()
self.clearOutline() self.clearOutline()
return return
@@ -799,6 +801,10 @@ class GuiOutlineDetails(QScrollArea):
bFont = SHARED.theme.guiFontB 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 # Details Area
self.titleLabel = QLabel(self.tr("Title"), self) self.titleLabel = QLabel(self.tr("Title"), self)
self.fileLabel = QLabel(self.tr("Document"), self) self.fileLabel = QLabel(self.tr("Document"), self)
@@ -819,9 +825,9 @@ class GuiOutlineDetails(QScrollArea):
self.itemValue.setMaximumWidth(maxTitle) self.itemValue.setMaximumWidth(maxTitle)
# Stats Area # Stats Area
self.cCLabel = QLabel(self.tr("Characters"), self) self.cCLabel = QLabel(trStats1, self)
self.wCLabel = QLabel(self.tr("Words"), self) self.wCLabel = QLabel(trStats2, self)
self.pCLabel = QLabel(self.tr("Paragraphs"), self) self.pCLabel = QLabel(trStats3, self)
self.cCValue = QLabel("", self) self.cCValue = QLabel("", self)
self.wCValue = QLabel("", self) self.wCValue = QLabel("", self)
self.pCValue = QLabel("", self) self.pCValue = QLabel("", self)
@@ -848,94 +854,9 @@ class GuiOutlineDetails(QScrollArea):
self.synopLWrap = QHBoxLayout() self.synopLWrap = QHBoxLayout()
self.synopLWrap.addWidget(self.synopValue, 1) 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 # Selected Item Details
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
self.mainForm = QGridLayout() self.mainForm = QGridLayout()
self.mainGroup = QGroupBox(self.tr("Title Details"), self)
self.mainGroup.setLayout(self.mainForm) self.mainGroup.setLayout(self.mainForm)
self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, QtAlignLeftTop) self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, QtAlignLeftTop)
@@ -959,46 +880,37 @@ class GuiOutlineDetails(QScrollArea):
self.mainForm.setVerticalSpacing(vSpace) self.mainForm.setVerticalSpacing(vSpace)
# Selected Item Tags # Selected Item Tags
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
self.tagsForm = QGridLayout() self.tagsForm = QGridLayout()
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
self.tagsGroup.setLayout(self.tagsForm) self.tagsGroup.setLayout(self.tagsForm)
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, QtAlignLeftTop) self.tagValues: dict[str, tuple[QLabel, QLabel]] = {}
self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, QtAlignLeftTop) for key in nwKeyWords.ALL_KEYS:
self.tagsForm.addWidget(self.focKeyLabel, 1, 0, QtAlignLeftTop) label = QLabel(trConst(nwLabels.KEY_NAME[key]), self)
self.tagsForm.addLayout(self.focKeyLWrap, 1, 1, QtAlignLeftTop) label.setFont(bFont)
self.tagsForm.addWidget(self.chrKeyLabel, 2, 0, QtAlignLeftTop) value = QLabel("", self)
self.tagsForm.addLayout(self.chrKeyLWrap, 2, 1, QtAlignLeftTop) value.setWordWrap(True)
self.tagsForm.addWidget(self.pltKeyLabel, 3, 0, QtAlignLeftTop) value.linkActivated.connect(lambda x: self.itemTagClicked.emit(x))
self.tagsForm.addLayout(self.pltKeyLWrap, 3, 1, QtAlignLeftTop) layout = QHBoxLayout()
self.tagsForm.addWidget(self.timKeyLabel, 4, 0, QtAlignLeftTop) layout.addWidget(value, 1)
self.tagsForm.addLayout(self.timKeyLWrap, 4, 1, QtAlignLeftTop) n = len(self.tagValues)
self.tagsForm.addWidget(self.wldKeyLabel, 5, 0, QtAlignLeftTop) self.tagsForm.addWidget(label, n, 0, QtAlignLeftTop)
self.tagsForm.addLayout(self.wldKeyLWrap, 5, 1, QtAlignLeftTop) self.tagsForm.addLayout(layout, n, 1, QtAlignLeftTop)
self.tagsForm.addWidget(self.objKeyLabel, 6, 0, QtAlignLeftTop) self.tagValues[key] = (label, value)
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.tagsForm.setColumnStretch(1, 1) self.tagsForm.setColumnStretch(1, 1)
self.tagsForm.setRowStretch(10, 1) self.tagsForm.setRowStretch(len(self.tagValues), 1)
self.tagsForm.setHorizontalSpacing(hSpace) self.tagsForm.setHorizontalSpacing(hSpace)
self.tagsForm.setVerticalSpacing(vSpace) self.tagsForm.setVerticalSpacing(vSpace)
# Assemble # Assemble
self.outerWidget = QWidget(self) self.mainSplit = QSplitter(Qt.Orientation.Horizontal)
self.outerBox = QHBoxLayout() self.mainSplit.addWidget(self.mainGroup)
self.outerBox.addWidget(self.mainGroup, 0) self.mainSplit.addWidget(self.tagsGroup)
self.outerBox.addWidget(self.tagsGroup, 1) self.mainSplit.setCollapsible(0, False)
self.mainSplit.setCollapsible(1, False)
self.outerWidget.setLayout(self.outerBox) self.setWidget(self.mainSplit)
self.setWidget(self.outerWidget)
self.setHorizontalScrollBarPolicy(QtScrollAsNeeded) self.setHorizontalScrollBarPolicy(QtScrollAsNeeded)
self.setVerticalScrollBarPolicy(QtScrollAsNeeded) self.setVerticalScrollBarPolicy(QtScrollAsNeeded)
@@ -1024,6 +936,28 @@ class GuiOutlineDetails(QScrollArea):
self.updateClasses() self.updateClasses()
return 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: def clearDetails(self) -> None:
"""Clear all the data labels.""" """Clear all the data labels."""
self.titleLabel.setText(self.tr("Title")) self.titleLabel.setText(self.tr("Title"))
@@ -1034,17 +968,10 @@ class GuiOutlineDetails(QScrollArea):
self.wCValue.setText("") self.wCValue.setText("")
self.pCValue.setText("") self.pCValue.setText("")
self.synopValue.setText("") self.synopValue.setText("")
self.povKeyValue.setText("")
self.focKeyValue.setText("") for _, value in self.tagValues.values():
self.chrKeyValue.setText("") value.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("")
self.updateClasses() self.updateClasses()
return return
@@ -1076,17 +1003,8 @@ class GuiOutlineDetails(QScrollArea):
self.synopValue.setText(novIdx.synopsis) self.synopValue.setText(novIdx.synopsis)
self.povKeyValue.setText(self._formatTags(novRefs, nwKeyWords.POV_KEY)) for key, (_, value) in self.tagValues.items():
self.focKeyValue.setText(self._formatTags(novRefs, nwKeyWords.FOCUS_KEY)) value.setText(self._formatTags(novRefs, 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))
return return
@@ -1094,27 +1012,12 @@ class GuiOutlineDetails(QScrollArea):
def updateClasses(self) -> None: def updateClasses(self) -> None:
"""Update the visibility status of class details.""" """Update the visibility status of class details."""
usedClasses = SHARED.project.tree.rootClasses() usedClasses = SHARED.project.tree.rootClasses()
for key, itemClass in nwKeyWords.KEY_CLASS.items():
pltVisible = nwItemClass.PLOT in usedClasses visible = itemClass in usedClasses
timVisible = nwItemClass.TIMELINE in usedClasses if key in self.tagValues:
wldVisible = nwItemClass.WORLD in usedClasses label, value = self.tagValues[key]
objVisible = nwItemClass.OBJECT in usedClasses label.setVisible(visible)
entVisible = nwItemClass.ENTITY in usedClasses value.setVisible(visible)
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)
return return
@staticmethod @staticmethod
+2 -1
View File
@@ -29,6 +29,7 @@ import pytest
from PyQt5.QtWidgets import QAction, QFileDialog, QWidget from PyQt5.QtWidgets import QAction, QFileDialog, QWidget
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.constants import nwKeyWords
from novelwriter.enum import nwItemClass, nwOutline, nwView from novelwriter.enum import nwItemClass, nwOutline, nwView
from novelwriter.types import QtScrollAlwaysOff, QtScrollAsNeeded from novelwriter.types import QtScrollAlwaysOff, QtScrollAsNeeded
@@ -261,7 +262,7 @@ def testGuiOutline_Content(qtbot, monkeypatch, nwGUI, prjLipsum, fncPath, tstPat
assert outlineData.itemValue.text() == "Finished" assert outlineData.itemValue.text() == "Finished"
# Click POV Link # 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") outlineView._tagClicked("Bod")
assert nwGUI.docViewer.docHandle == "4c4f28287af27" assert nwGUI.docViewer.docHandle == "4c4f28287af27"