Add the Novel Tree meta data feature (#1088)

This commit is contained in:
Veronica Berglyd Olsen
2022-06-15 20:46:45 +02:00
committed by GitHub
18 changed files with 244 additions and 94 deletions
@@ -88,3 +88,4 @@ deco_doc_h1 = nw_deco-h1.svg
deco_doc_h2 = nw_deco-h2.svg
deco_doc_h3 = nw_deco-h3.svg
deco_doc_h4 = nw_deco-h4.svg
deco_doc_more = nw_deco-noveltree-more.svg
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg2161"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata2167">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs2165" />
<path
d="M 9.7,18.2 16,12 9.7,5.8 C 9.5,5.6 9.2,5.5 9,5.5 8.8,5.5 8.5,5.6 8.3,5.8 8.1,6 8,6.2 8,6.5 v 11 c 0,0.3 0.1,0.5 0.3,0.7 0.2,0.2 0.5,0.3 0.7,0.3 0.2,0 0.5,-0.1 0.7,-0.3 z"
id="path3096"
style="fill:#848484;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 928 B

@@ -88,3 +88,4 @@ deco_doc_h1 = nw_deco-h1.svg
deco_doc_h2 = nw_deco-h2.svg
deco_doc_h3 = nw_deco-h3.svg
deco_doc_h4 = nw_deco-h4.svg
deco_doc_more = nw_deco-noveltree-more.svg
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg2161"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata2167">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs2165" />
<path
d="M 9.7,18.2 16,12 9.7,5.8 C 9.5,5.6 9.2,5.5 9,5.5 8.8,5.5 8.5,5.6 8.3,5.8 8.1,6 8,6.2 8,6.5 v 11 c 0,0.3 0.1,0.5 0.3,0.7 0.2,0.2 0.5,0.3 0.7,0.3 0.2,0 0.5,-0.1 0.7,-0.3 z"
id="path3096"
style="fill:#848484;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 928 B

+1 -1
View File
@@ -10,7 +10,7 @@ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
window = 54, 54, 54
windowtext = 174, 174, 174
base = 62, 62, 62
alternatebase = 67, 67, 67
alternatebase = 78, 78, 78
text = 174, 174, 174
tooltipbase = 255, 255, 192
tooltiptext = 21, 21, 13
@@ -10,7 +10,7 @@ licenseurl = https://github.com/altercation/solarized/blob/master/LICENSE
window = 0, 43, 54
windowtext = 253, 246, 227
base = 7, 54, 66
alternatebase = 67, 67, 67
alternatebase = 0, 43, 54
text = 253, 246, 227
tooltipbase = 133, 153, 0
tooltiptext = 0, 43, 54
+1 -27
View File
@@ -96,8 +96,6 @@ class Config:
# Sizes
self.winGeometry = [1200, 650]
self.prefGeometry = [700, 615]
self.treeColWidth = [200, 50, 30]
self.novelColWidth = [200, 50]
self.projColWidth = [200, 60, 140]
self.mainPanePos = [300, 800]
self.docPanePos = [400, 400]
@@ -117,7 +115,7 @@ class Config:
# Text Editor
self.textFont = None # Editor font
self.textSize = 12 # Editor font size
self.textWidth = 600 # Editor text width
self.textWidth = 700 # Editor text width
self.textMargin = 40 # Editor/viewer text margin
self.tabWidth = 40 # Editor tabulator width
@@ -460,8 +458,6 @@ class Config:
cnfSec = "Sizes"
self.winGeometry = theConf.rdIntList(cnfSec, "geometry", self.winGeometry)
self.prefGeometry = theConf.rdIntList(cnfSec, "preferences", self.prefGeometry)
self.treeColWidth = theConf.rdIntList(cnfSec, "treecols", self.treeColWidth)
self.novelColWidth = theConf.rdIntList(cnfSec, "novelcols", self.novelColWidth)
self.projColWidth = theConf.rdIntList(cnfSec, "projcols", self.projColWidth)
self.mainPanePos = theConf.rdIntList(cnfSec, "mainpane", self.mainPanePos)
self.docPanePos = theConf.rdIntList(cnfSec, "docpane", self.docPanePos)
@@ -581,8 +577,6 @@ class Config:
theConf["Sizes"] = {
"geometry": self._packList(self.winGeometry),
"preferences": self._packList(self.prefGeometry),
"treecols": self._packList(self.treeColWidth),
"novelcols": self._packList(self.novelColWidth),
"projcols": self._packList(self.projColWidth),
"mainpane": self._packList(self.mainPanePos),
"docpane": self._packList(self.docPanePos),
@@ -811,20 +805,6 @@ class Config:
self.confChanged = True
return True
def setTreeColWidths(self, colWidths):
"""Set the column widths of the main project tree.
"""
self.treeColWidth = [int(x/self.guiScale) for x in colWidths]
self.confChanged = True
return True
def setNovelColWidths(self, colWidths):
"""Set the column widths of the novel tree.
"""
self.novelColWidth = [int(x/self.guiScale) for x in colWidths]
self.confChanged = True
return True
def setProjColWidths(self, colWidths):
"""Set the column widths of the Load Project dialog.
"""
@@ -910,12 +890,6 @@ class Config:
def getPreferencesSize(self):
return [int(x*self.guiScale) for x in self.prefGeometry]
def getTreeColWidths(self):
return [int(x*self.guiScale) for x in self.treeColWidth]
def getNovelColWidths(self):
return [int(x*self.guiScale) for x in self.novelColWidth]
def getProjColWidths(self):
return [int(x*self.guiScale) for x in self.projColWidth]
+120 -15
View File
@@ -35,11 +35,11 @@ from PyQt5.QtGui import QPalette
from PyQt5.QtCore import Qt, QSize, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView, QLabel,
QMenu, QSizePolicy, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
QWidget
QMenu, QSizePolicy, QToolButton, QToolTip, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget
)
from novelwriter.enum import nwDocMode, nwItemClass
from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
from novelwriter.common import checkInt
from novelwriter.constants import nwHeaders, nwKeyWords, nwLabels, trConst
@@ -84,6 +84,7 @@ class GuiNovelView(QWidget):
# Function Mappings
self.updateWordCounts = self.novelTree.updateWordCounts
self.getSelectedHandle = self.novelTree.getSelectedHandle
self.setActiveHandle = self.novelTree.setActiveHandle
return
@@ -322,7 +323,12 @@ class GuiNovelTree(QTreeWidget):
C_TITLE = 0
C_WORDS = 1
C_LAST = 2
C_EXTRA = 2
C_MORE = 3
D_HANDLE = Qt.UserRole
D_TITLE = Qt.UserRole + 1
D_KEY = Qt.UserRole + 2
def __init__(self, novelView):
QTreeWidget.__init__(self, novelView)
@@ -339,6 +345,7 @@ class GuiNovelTree(QTreeWidget):
self._treeMap = {}
self._lastBuild = 0
self._lastCol = NovelTreeColumn.POV
self._actHandle = None
# Cached Strings
self._povLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
@@ -353,9 +360,11 @@ class GuiNovelTree(QTreeWidget):
self.setIconSize(QSize(iPx, iPx))
self.setFrameStyle(QFrame.NoFrame)
self.setUniformRowHeights(True)
self.setAllColumnsShowFocus(True)
self.setHeaderHidden(True)
self.setIndentation(0)
self.setColumnCount(3)
self.setColumnCount(4)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.SingleSelection)
self.setExpandsOnDoubleClick(False)
@@ -367,7 +376,8 @@ class GuiNovelTree(QTreeWidget):
treeHeader.setMinimumSectionSize(iPx + cMg)
treeHeader.setSectionResizeMode(self.C_TITLE, QHeaderView.Stretch)
treeHeader.setSectionResizeMode(self.C_WORDS, QHeaderView.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_LAST, QHeaderView.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_EXTRA, QHeaderView.ResizeToContents)
treeHeader.setSectionResizeMode(self.C_MORE, QHeaderView.ResizeToContents)
# Pre-Generate Tree Formatting
fH1 = self.font()
@@ -385,8 +395,12 @@ class GuiNovelTree(QTreeWidget):
self.mainTheme.loadDecoration("deco_doc_h3", pxH=iPx),
self.mainTheme.loadDecoration("deco_doc_h4", pxH=iPx),
]
self._pMore = self.mainTheme.loadDecoration("deco_doc_more", pxH=iPx)
self._pActive = self.mainTheme.loadDecoration("deco_more_on", pxH=iPx)
self._pInactive = self.mainTheme.loadDecoration("deco_more_off", pxH=iPx)
# Connect signals
self.clicked.connect(self._treeItemClicked)
self.itemDoubleClicked.connect(self._treeDoubleClick)
self.itemSelectionChanged.connect(self._treeSelectionChange)
@@ -449,7 +463,7 @@ class GuiNovelTree(QTreeWidget):
selItem = self.selectedItems()
titleKey = None
if selItem:
titleKey = selItem[0].data(self.C_TITLE, Qt.UserRole)[2]
titleKey = selItem[0].data(self.C_TITLE, self.D_KEY)
self._populateTree(rootHandle)
self.theProject.setLastNovelViewed(rootHandle)
@@ -476,8 +490,9 @@ class GuiNovelTree(QTreeWidget):
tHandle = None
tLine = 0
if selItem:
tHandle = selItem[0].data(self.C_TITLE, Qt.UserRole)[0]
tLine = checkInt(selItem[0].data(self.C_TITLE, Qt.UserRole)[1], 1) - 1
tHandle = selItem[0].data(self.C_TITLE, self.D_HANDLE)
sTitle = selItem[0].data(self.C_TITLE, self.D_TITLE)
tLine = checkInt(sTitle[1:], 1) - 1
return tHandle, tLine
@@ -487,11 +502,34 @@ class GuiNovelTree(QTreeWidget):
if self._lastCol != colType:
logger.debug("Changing last column to %s", colType.name)
self._lastCol = colType
self.setColumnHidden(self.C_LAST, colType == NovelTreeColumn.HIDDEN)
self.setColumnHidden(self.C_EXTRA, colType == NovelTreeColumn.HIDDEN)
if doRefresh:
self.refreshTree(rootHandle=self.theProject.lastNovel, overRide=True)
return
def setActiveHandle(self, tHandle):
"""Highlight the rows associated with a given handle.
"""
tStart = time()
self._actHandle = tHandle
for i in range(self.topLevelItemCount()):
tItem = self.topLevelItem(i)
if tItem.data(self.C_TITLE, self.D_HANDLE) == tHandle:
tItem.setBackground(self.C_TITLE, self.palette().alternateBase())
tItem.setBackground(self.C_WORDS, self.palette().alternateBase())
tItem.setBackground(self.C_EXTRA, self.palette().alternateBase())
tItem.setBackground(self.C_MORE, self.palette().alternateBase())
else:
tItem.setBackground(self.C_TITLE, self.palette().base())
tItem.setBackground(self.C_WORDS, self.palette().base())
tItem.setBackground(self.C_EXTRA, self.palette().base())
tItem.setBackground(self.C_MORE, self.palette().base())
logger.verbose("Highlighted Novel Tree in %.3f ms", (time() - tStart)*1000)
return
##
# Events
##
@@ -521,10 +559,28 @@ class GuiNovelTree(QTreeWidget):
return
def focusOutEvent(self, theEvent):
"""Clear the selection when the tree no longer has focus.
"""
QTreeWidget.focusOutEvent(self, theEvent)
self.clearSelection()
return
##
# Private Slots
##
@pyqtSlot("QModelIndex")
def _treeItemClicked(self, mIndex):
"""The user clicked on an item in the tree.
"""
if mIndex.column() == self.C_MORE:
tHandle = mIndex.siblingAtColumn(self.C_TITLE).data(self.D_HANDLE)
sTitle = mIndex.siblingAtColumn(self.C_TITLE).data(self.D_TITLE)
tipPos = self.mapToGlobal(self.visualRect(mIndex).topRight())
self._popMetaBox(tipPos, tHandle, sTitle)
return
@pyqtSlot()
def _treeSelectionChange(self):
"""Extract the handle and line number of the currently selected
@@ -564,23 +620,27 @@ class GuiNovelTree(QTreeWidget):
continue
newItem = QTreeWidgetItem()
theData = (tHandle, sTitle[1:].lstrip("0"), tKey)
newItem.setData(self.C_TITLE, Qt.DecorationRole, self._pIndent[iLevel])
newItem.setText(self.C_TITLE, novIdx.title)
newItem.setData(self.C_TITLE, Qt.UserRole, theData)
newItem.setData(self.C_TITLE, self.D_HANDLE, tHandle)
newItem.setData(self.C_TITLE, self.D_TITLE, sTitle)
newItem.setData(self.C_TITLE, self.D_KEY, tKey)
newItem.setFont(self.C_TITLE, self._hFonts[iLevel])
newItem.setText(self.C_WORDS, f"{novIdx.wordCount:n}")
newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
newItem.setData(self.C_MORE, Qt.DecorationRole, self._pMore)
# Custom column
lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
newItem.setText(self.C_LAST, lastText)
newItem.setText(self.C_EXTRA, lastText)
if lastText:
newItem.setToolTip(self.C_LAST, toolTip)
newItem.setToolTip(self.C_EXTRA, toolTip)
self._treeMap[tKey] = newItem
self.addTopLevelItem(newItem)
self.setActiveHandle(self._actHandle)
logger.verbose("Novel Tree built in %.3f ms", (time() - tStart)*1000)
self._lastBuild = time()
@@ -607,4 +667,49 @@ class GuiNovelTree(QTreeWidget):
return "", ""
def _popMetaBox(self, qPos, tHandle, sTitle):
"""Show the novel meta data box.
"""
logger.debug("Generating meta data tooltip for '%s:%s'", tHandle, sTitle)
pIndex = self.theProject.index
novIdx = pIndex.getNovelData(tHandle, sTitle)
refTags = pIndex.getReferences(tHandle, sTitle)
synopText = novIdx.synopsis
if synopText:
synopLabel = trConst(nwLabels.OUTLINE_COLS[nwOutline.SYNOP])
synopText = f"<p><b>{synopLabel}</b>: {synopText}</p>"
refLines = []
refLines = self._appendMetaTag(refTags, nwKeyWords.POV_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.FOCUS_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.CHAR_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.PLOT_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.TIME_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.WORLD_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.OBJECT_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.ENTITY_KEY, refLines)
refLines = self._appendMetaTag(refTags, nwKeyWords.CUSTOM_KEY, refLines)
refText = ""
if refLines:
refList = "<br>".join(refLines)
refText = f"<p>{refList}</p>"
ttText = refText + synopText or self.tr("No meta data")
if ttText:
QToolTip.showText(qPos, ttText)
return
@staticmethod
def _appendMetaTag(refs, key, lines):
"""Generate a reference list for a given reference key.
"""
tags = ", ".join(refs.get(key, []))
if tags:
lines.append(f"<b>{trConst(nwLabels.KEY_NAME[key])}</b>: {tags}")
return lines
# END Class GuiNovelTree
+1
View File
@@ -326,6 +326,7 @@ class GuiOutlineTree(QTreeWidget):
self.theProject = theOutline.mainGui.theProject
self.mainTheme = theOutline.mainGui.mainTheme
self.setUniformRowHeights(True)
self.setFrameStyle(QFrame.NoFrame)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.SingleSelection)
+3
View File
@@ -350,7 +350,10 @@ class GuiProjectTree(QTreeWidget):
self.setIconSize(QSize(iPx, iPx))
self.setFrameStyle(QFrame.NoFrame)
self.setUniformRowHeights(True)
self.setAllColumnsShowFocus(True)
self.setExpandsOnDoubleClick(False)
self.setAutoExpandDelay(1000)
self.setHeaderHidden(True)
self.setIndentation(iPx)
self.setColumnCount(4)
+1 -1
View File
@@ -474,7 +474,7 @@ class GuiIcons:
"bullet-on", "bullet-off",
# Decorations
"deco_doc_h0", "deco_doc_h1", "deco_doc_h2", "deco_doc_h3", "deco_doc_h4",
"deco_doc_h0", "deco_doc_h1", "deco_doc_h2", "deco_doc_h3", "deco_doc_h4", "deco_doc_more",
}
IMAGE_MAP = {
+5 -2
View File
@@ -558,7 +558,7 @@ class GuiMain(QMainWindow):
# Document Actions
##
def closeDocument(self):
def closeDocument(self, beforeOpen=False):
"""Close the document and clear the editor and title field.
"""
if not self.hasProject:
@@ -573,6 +573,8 @@ class GuiMain(QMainWindow):
if self.docEditor.docChanged():
self.saveDocument()
self.docEditor.clearEditor()
if not beforeOpen:
self.novelView.setActiveHandle(None)
return True
@@ -587,13 +589,14 @@ class GuiMain(QMainWindow):
logger.debug("Requested item '%s' is not a document", tHandle)
return False
self.closeDocument()
self.closeDocument(beforeOpen=True)
self._changeView(nwView.EDITOR)
if self.docEditor.loadText(tHandle, tLine):
if changeFocus:
self.docEditor.setFocus()
self.theProject.setLastEdited(tHandle)
self.projView.setSelectedHandle(tHandle, doScroll=doScroll)
self.novelView.setActiveHandle(tHandle)
else:
return False
+1 -3
View File
@@ -13,8 +13,6 @@ hidehscroll = False
[Sizes]
geometry = 1200, 650
preferences = 700, 615
treecols = 200, 50, 30
novelcols = 200, 50
projcols = 200, 60, 140
mainpane = 300, 800
docpane = 400, 400
@@ -30,7 +28,7 @@ emphlabels = True
[Editor]
textfont = None
textsize = 12
width = 600
width = 700
margin = 40
tabwidth = 40
focuswidth = 800
@@ -13,8 +13,6 @@ hidehscroll = True
[Sizes]
geometry = 1200, 650
preferences = 670, 589
treecols = 200, 50, 30
novelcols = 200, 50
projcols = 200, 60, 140
mainpane = 300, 800
docpane = 400, 400
+2 -28
View File
@@ -410,32 +410,6 @@ def testBaseConfig_SettersGetters(tmpConf, tmpDir, outDir, refDir):
assert tmpConf.setPreferencesSize(700, 615)
# Project Tree Columns
tmpConf.guiScale = 2.0
assert tmpConf.setTreeColWidths([10, 20, 25])
assert tmpConf.getTreeColWidths() == [10, 20, 24]
assert tmpConf.treeColWidth == [5, 10, 12]
tmpConf.guiScale = 1.0
assert tmpConf.setTreeColWidths([10, 20, 25])
assert tmpConf.getTreeColWidths() == [10, 20, 25]
assert tmpConf.treeColWidth == [10, 20, 25]
assert tmpConf.setTreeColWidths([200, 50, 30])
# Novel Tree Columns
tmpConf.guiScale = 2.0
assert tmpConf.setNovelColWidths([10, 20])
assert tmpConf.getNovelColWidths() == [10, 20]
assert tmpConf.novelColWidth == [5, 10]
tmpConf.guiScale = 1.0
assert tmpConf.setNovelColWidths([10, 20])
assert tmpConf.getNovelColWidths() == [10, 20]
assert tmpConf.novelColWidth == [10, 20]
assert tmpConf.setNovelColWidths([200, 50])
# Project Settings Tree Columns
tmpConf.guiScale = 2.0
assert tmpConf.setProjColWidths([10, 20, 30])
@@ -505,13 +479,13 @@ def testBaseConfig_SettersGetters(tmpConf, tmpDir, outDir, refDir):
# ============
tmpConf.guiScale = 1.0
assert tmpConf.getTextWidth(False) == 600
assert tmpConf.getTextWidth(False) == 700
assert tmpConf.getTextWidth(True) == 800
assert tmpConf.getTextMargin() == 40
assert tmpConf.getTabWidth() == 40
tmpConf.guiScale = 2.0
assert tmpConf.getTextWidth(False) == 1200
assert tmpConf.getTextWidth(False) == 1400
assert tmpConf.getTextWidth(True) == 1600
assert tmpConf.getTextMargin() == 80
assert tmpConf.getTabWidth() == 80
+2 -2
View File
@@ -239,8 +239,8 @@ def testDlgPreferences_Main(qtbot, monkeypatch, fncDir, outDir, refDir):
copyfile(projFile, testFile)
ignTuple = (
"timestamp", "guifont", "lastnotes", "guilang", "geometry",
"preferences", "treecols", "novelcols", "projcols", "mainpane",
"docpane", "viewpane", "outlinepane", "textfont", "textsize"
"preferences", "projcols", "mainpane", "docpane", "viewpane",
"outlinepane", "textfont", "textsize"
)
assert cmpFiles(testFile, compFile, ignoreStart=ignTuple)
+43 -11
View File
@@ -24,8 +24,9 @@ import pytest
from tools import buildTestProject, writeFile
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtGui import QFocusEvent
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtWidgets import QMessageBox, QToolTip
from novelwriter.enum import nwWidget, nwItemType
from novelwriter.dialogs import GuiEditLabel
@@ -53,8 +54,12 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
"# Jane Doe\n\n@tag: Jane\n\n"
)
writeFile(
os.path.join(nwGUI.theProject.projContent, "000000000000f.nwd"),
"### Scene One\n\n@pov: Jane\n@focus: Jane\n\n"
os.path.join(nwGUI.theProject.projContent, "000000000000f.nwd"), (
"### Scene One\n\n"
"@pov: Jane\n"
"@focus: Jane\n\n"
"% Synopsis: This is a scene."
)
)
novelView = nwGUI.novelView
@@ -124,12 +129,12 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
assert nwGUI.docViewer.docHandle() is None
scRect = novelTree.visualItemRect(scItem)
oldData = scItem.data(novelTree.C_TITLE, Qt.UserRole)
scItem.setData(novelTree.C_TITLE, Qt.UserRole, (None, "", ""))
oldData = scItem.data(novelTree.C_TITLE, novelTree.D_HANDLE)
scItem.setData(novelTree.C_TITLE, novelTree.D_HANDLE, None)
qtbot.mouseClick(vPort, Qt.MiddleButton, pos=scRect.center(), delay=10)
assert nwGUI.docViewer.docHandle() is None
scItem.setData(novelTree.C_TITLE, Qt.UserRole, oldData)
scItem.setData(novelTree.C_TITLE, novelTree.D_HANDLE, oldData)
qtbot.mouseClick(vPort, Qt.MiddleButton, pos=scRect.center(), delay=10)
assert nwGUI.docViewer.docHandle() == "000000000000f"
@@ -137,26 +142,26 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
# ===========
novelBar.setLastColType(NovelTreeColumn.HIDDEN)
assert novelTree.isColumnHidden(novelTree.C_LAST) is True
assert novelTree.isColumnHidden(novelTree.C_EXTRA) is True
assert novelTree.lastColType == NovelTreeColumn.HIDDEN
assert novelTree._getLastColumnText("000000000000f", "T000001") == ("", "")
novelBar.setLastColType(NovelTreeColumn.POV)
assert novelTree.isColumnHidden(novelTree.C_LAST) is False
assert novelTree.isColumnHidden(novelTree.C_EXTRA) is False
assert novelTree.lastColType == NovelTreeColumn.POV
assert novelTree._getLastColumnText("000000000000f", "T000001") == (
"Jane", "Point of View: Jane"
)
novelBar.setLastColType(NovelTreeColumn.FOCUS)
assert novelTree.isColumnHidden(novelTree.C_LAST) is False
assert novelTree.isColumnHidden(novelTree.C_EXTRA) is False
assert novelTree.lastColType == NovelTreeColumn.FOCUS
assert novelTree._getLastColumnText("000000000000f", "T000001") == (
"Jane", "Focus: Jane"
)
novelBar.setLastColType(NovelTreeColumn.PLOT)
assert novelTree.isColumnHidden(novelTree.C_LAST) is False
assert novelTree.isColumnHidden(novelTree.C_EXTRA) is False
assert novelTree.lastColType == NovelTreeColumn.PLOT
assert novelTree._getLastColumnText("000000000000f", "T000001") == (
"", "Plot: "
@@ -165,6 +170,33 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
novelTree._lastCol = None
assert novelTree._getLastColumnText("0000000000000", "T000000") == ("", "")
# Item Meta
# =========
ttText = ""
def showText(pos, text):
nonlocal ttText
ttText = text
mIndex = novelTree.model().index(2, novelTree.C_MORE)
with monkeypatch.context() as mp:
mp.setattr(QToolTip, "showText", showText)
novelTree._treeItemClicked(mIndex)
assert ttText == (
"<p><b>Point of View</b>: Jane<br><b>Focus</b>: Jane</p>"
"<p><b>Synopsis</b>: This is a scene.</p>"
)
# Other Checks
# ============
scItem = novelTree.topLevelItem(2)
scItem.setSelected(True)
assert scItem.isSelected()
novelTree.focusOutEvent(QFocusEvent(QEvent.None_, Qt.MouseFocusReason))
assert not scItem.isSelected()
# Close
# =====
+1 -1
View File
@@ -81,7 +81,7 @@ def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir):
assert thePalette.window().color() == QColor(54, 54, 54)
assert thePalette.windowText().color() == QColor(174, 174, 174)
assert thePalette.base().color() == QColor(62, 62, 62)
assert thePalette.alternateBase().color() == QColor(67, 67, 67)
assert thePalette.alternateBase().color() == QColor(78, 78, 78)
assert thePalette.text().color() == QColor(174, 174, 174)
assert thePalette.toolTipBase().color() == QColor(255, 255, 192)
assert thePalette.toolTipText().color() == QColor(21, 21, 13)