diff --git a/novelwriter/assets/icons/typicons_dark/icons.conf b/novelwriter/assets/icons/typicons_dark/icons.conf index d4106803..f372c60c 100644 --- a/novelwriter/assets/icons/typicons_dark/icons.conf +++ b/novelwriter/assets/icons/typicons_dark/icons.conf @@ -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 diff --git a/novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg b/novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg new file mode 100644 index 00000000..f42d3306 --- /dev/null +++ b/novelwriter/assets/icons/typicons_dark/nw_deco-noveltree-more.svg @@ -0,0 +1,30 @@ + + diff --git a/novelwriter/assets/icons/typicons_light/icons.conf b/novelwriter/assets/icons/typicons_light/icons.conf index 8d267a47..4514eab9 100644 --- a/novelwriter/assets/icons/typicons_light/icons.conf +++ b/novelwriter/assets/icons/typicons_light/icons.conf @@ -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 diff --git a/novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg b/novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg new file mode 100644 index 00000000..f42d3306 --- /dev/null +++ b/novelwriter/assets/icons/typicons_light/nw_deco-noveltree-more.svg @@ -0,0 +1,30 @@ + + diff --git a/novelwriter/assets/themes/default_dark.conf b/novelwriter/assets/themes/default_dark.conf index 14d0ad51..44317ac1 100644 --- a/novelwriter/assets/themes/default_dark.conf +++ b/novelwriter/assets/themes/default_dark.conf @@ -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 diff --git a/novelwriter/assets/themes/solarized_dark.conf b/novelwriter/assets/themes/solarized_dark.conf index 81a85a16..812d968d 100644 --- a/novelwriter/assets/themes/solarized_dark.conf +++ b/novelwriter/assets/themes/solarized_dark.conf @@ -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 diff --git a/novelwriter/config.py b/novelwriter/config.py index 7fb334c2..c3766553 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -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] diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index 8711dc8d..b96f5331 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -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"
{synopLabel}: {synopText}
" + + 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 = "{refList}
" + + 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"{trConst(nwLabels.KEY_NAME[key])}: {tags}") + return lines + # END Class GuiNovelTree diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 4b2077f6..0ae253f9 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -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) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 08b24232..13b0b619 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -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) diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index 6c4ff50e..e72a8c97 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -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 = { diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index e9535747..e34b873e 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -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 diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index 8018b089..56b5a807 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -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 diff --git a/tests/reference/guiPreferences_novelwriter.conf b/tests/reference/guiPreferences_novelwriter.conf index 71c08fb1..9d21830d 100644 --- a/tests/reference/guiPreferences_novelwriter.conf +++ b/tests/reference/guiPreferences_novelwriter.conf @@ -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 diff --git a/tests/test_base/test_base_config.py b/tests/test_base/test_base_config.py index 2e055884..83ff3160 100644 --- a/tests/test_base/test_base_config.py +++ b/tests/test_base/test_base_config.py @@ -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 diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index aa33ba82..1507d351 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -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) diff --git a/tests/test_gui/test_gui_noveltree.py b/tests/test_gui/test_gui_noveltree.py index 102b03d2..f8f18875 100644 --- a/tests/test_gui/test_gui_noveltree.py +++ b/tests/test_gui/test_gui_noveltree.py @@ -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 == ( + "Point of View: Jane
Focus: Jane
Synopsis: This is a scene.
" + ) + + # Other Checks + # ============ + + scItem = novelTree.topLevelItem(2) + scItem.setSelected(True) + assert scItem.isSelected() + novelTree.focusOutEvent(QFocusEvent(QEvent.None_, Qt.MouseFocusReason)) + assert not scItem.isSelected() + # Close # ===== diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index 8c7b934a..0014a4da 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -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)