From 9a63a84fc113a1777f03068fd2195610cfb8fd75 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Sat, 22 Feb 2025 20:12:50 +0100
Subject: [PATCH] Add a basic model for the novel view
---
novelwriter/config.py | 57 +-
novelwriter/core/index.py | 24 +
novelwriter/core/indexdata.py | 5 +
novelwriter/core/itemmodel.py | 2 +-
novelwriter/core/novelmodel.py | 100 +++
novelwriter/gui/noveltree.py | 649 ++++++++++----------
tests/reference/baseConfig_novelwriter.conf | 3 +-
7 files changed, 497 insertions(+), 343 deletions(-)
create mode 100644 novelwriter/core/novelmodel.py
diff --git a/novelwriter/config.py b/novelwriter/config.py
index 15bce92b..949f49f3 100644
--- a/novelwriter/config.py
+++ b/novelwriter/config.py
@@ -68,23 +68,23 @@ class Config:
"_backupPath",
"appName", "appHandle", "guiLocale", "guiTheme", "guiSyntax", "guiFont", "hideVScroll",
- "hideHScroll", "lastNotes", "nativeFont", "iconTheme", "iconColTree", "iconColDocs",
- "mainWinSize", "welcomeWinSize", "prefsWinSize", "mainPanePos", "viewPanePos",
- "outlinePanePos", "autoSaveProj", "autoSaveDoc", "emphLabels", "backupOnClose",
- "askBeforeBackup", "askBeforeExit", "textFont", "textWidth", "textMargin", "tabWidth",
- "cursorWidth", "focusWidth", "hideFocusFooter", "showFullPath", "autoSelect", "doJustify",
- "showTabsNSpaces", "showLineEndings", "showMultiSpaces", "doReplace", "doReplaceSQuote",
- "doReplaceDQuote", "doReplaceDash", "doReplaceDots", "autoScroll", "autoScrollPos",
- "scrollPastEnd", "dialogStyle", "allowOpenDial", "dialogLine", "narratorBreak",
- "narratorDialog", "altDialogOpen", "altDialogClose", "highlightEmph", "stopWhenIdle",
- "userIdleTime", "incNotesWCount", "fmtApostrophe", "fmtSQuoteOpen", "fmtSQuoteClose",
- "fmtDQuoteOpen", "fmtDQuoteClose", "fmtPadBefore", "fmtPadAfter", "fmtPadThin",
- "spellLanguage", "showViewerPanel", "showEditToolBar", "showSessionTime", "viewComments",
- "viewSynopsis", "searchCase", "searchWord", "searchRegEx", "searchLoop", "searchNextFile",
- "searchMatchCap", "searchProjCase", "searchProjWord", "searchProjRegEx", "verQtString",
- "verQtValue", "verPyQtString", "verPyQtValue", "verPyString", "osType", "osLinux",
- "osWindows", "osDarwin", "osUnknown", "hostName", "kernelVer", "isDebug", "memInfo",
- "hasEnchant",
+ "hideHScroll", "lastNotes", "nativeFont", "useCharCount", "iconTheme", "iconColTree",
+ "iconColDocs", "mainWinSize", "welcomeWinSize", "prefsWinSize", "mainPanePos",
+ "viewPanePos", "outlinePanePos", "autoSaveProj", "autoSaveDoc", "emphLabels",
+ "backupOnClose", "askBeforeBackup", "askBeforeExit", "textFont", "textWidth", "textMargin",
+ "tabWidth", "cursorWidth", "focusWidth", "hideFocusFooter", "showFullPath", "autoSelect",
+ "doJustify", "showTabsNSpaces", "showLineEndings", "showMultiSpaces", "doReplace",
+ "doReplaceSQuote", "doReplaceDQuote", "doReplaceDash", "doReplaceDots", "autoScroll",
+ "autoScrollPos", "scrollPastEnd", "dialogStyle", "allowOpenDial", "dialogLine",
+ "narratorBreak", "narratorDialog", "altDialogOpen", "altDialogClose", "highlightEmph",
+ "stopWhenIdle", "userIdleTime", "incNotesWCount", "fmtApostrophe", "fmtSQuoteOpen",
+ "fmtSQuoteClose", "fmtDQuoteOpen", "fmtDQuoteClose", "fmtPadBefore", "fmtPadAfter",
+ "fmtPadThin", "spellLanguage", "showViewerPanel", "showEditToolBar", "showSessionTime",
+ "viewComments", "viewSynopsis", "searchCase", "searchWord", "searchRegEx", "searchLoop",
+ "searchNextFile", "searchMatchCap", "searchProjCase", "searchProjWord", "searchProjRegEx",
+ "verQtString", "verQtValue", "verPyQtString", "verPyQtValue", "verPyString", "osType",
+ "osLinux", "osWindows", "osDarwin", "osUnknown", "hostName", "kernelVer", "isDebug",
+ "memInfo", "hasEnchant",
)
LANG_NW = 1
@@ -157,6 +157,7 @@ class Config:
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
self.lastNotes = "0x0" # The latest release notes that have been shown
self.nativeFont = True # Use native font dialog
+ self.useCharCount = False # Use character count as primary count
# Icons
self.iconTheme = DEF_ICONS # Icons theme
@@ -591,16 +592,17 @@ class Config:
# Main
sec = "Main"
self.setGuiFont(conf.rdStr(sec, "font", ""))
- self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
- self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
- self.iconTheme = conf.rdStr(sec, "icons", self.iconTheme)
- self.iconColTree = conf.rdStr(sec, "iconcoltree", self.iconColTree)
- self.iconColDocs = conf.rdBool(sec, "iconcoldocs", self.iconColDocs)
- self.guiLocale = conf.rdStr(sec, "localisation", self.guiLocale)
- self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
- self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
- self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
- self.nativeFont = conf.rdBool(sec, "nativefont", self.nativeFont)
+ self.guiTheme = conf.rdStr(sec, "theme", self.guiTheme)
+ self.guiSyntax = conf.rdStr(sec, "syntax", self.guiSyntax)
+ self.iconTheme = conf.rdStr(sec, "icons", self.iconTheme)
+ self.iconColTree = conf.rdStr(sec, "iconcoltree", self.iconColTree)
+ self.iconColDocs = conf.rdBool(sec, "iconcoldocs", self.iconColDocs)
+ self.guiLocale = conf.rdStr(sec, "localisation", self.guiLocale)
+ self.hideVScroll = conf.rdBool(sec, "hidevscroll", self.hideVScroll)
+ self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll)
+ self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes)
+ self.nativeFont = conf.rdBool(sec, "nativefont", self.nativeFont)
+ self.useCharCount = conf.rdBool(sec, "usecharcount", self.useCharCount)
# Sizes
sec = "Sizes"
@@ -717,6 +719,7 @@ class Config:
"hidehscroll": str(self.hideHScroll),
"lastnotes": str(self.lastNotes),
"nativefont": str(self.nativeFont),
+ "usecharcount": str(self.useCharCount),
}
conf["Sizes"] = {
diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py
index 10edf7c0..4419dca0 100644
--- a/novelwriter/core/index.py
+++ b/novelwriter/core/index.py
@@ -38,6 +38,7 @@ from novelwriter import SHARED
from novelwriter.common import isHandle, isItemClass, isTitleTag, jsonEncode
from novelwriter.constants import nwFiles, nwKeyWords, nwStyles
from novelwriter.core.indexdata import NOTE_TYPES, TT_NONE, IndexHeading, IndexNode, T_NoteTypes
+from novelwriter.core.novelmodel import NovelModel
from novelwriter.enum import nwComment, nwItemClass, nwItemLayout, nwItemType
from novelwriter.error import logException
from novelwriter.text.comments import processComment
@@ -89,6 +90,9 @@ class Index:
self._itemIndex = ItemIndex(project)
self._indexBroken = False
+ # Models
+ self._novelModels: dict[str, NovelModel] = {}
+
# TimeStamps
self._indexChange = 0.0
self._rootChange = {}
@@ -106,6 +110,26 @@ class Index:
def indexBroken(self) -> bool:
return self._indexBroken
+ ##
+ # Getters
+ ##
+
+ def getNovelModel(self, tHandle: str) -> NovelModel | None:
+ """Get the model for a specific novel root."""
+ if tHandle not in self._novelModels:
+ self._generateNovelModel(tHandle)
+ return self._novelModels.get(tHandle)
+
+ def _generateNovelModel(self, tHandle: str) -> None:
+ """Generate a novel model for a specific handle."""
+ if (item := SHARED.project.tree[tHandle]) and item.isRootType() and item.isNovelLike():
+ model = NovelModel(item)
+ for handle in SHARED.project.tree.subTree(tHandle):
+ if node := self._itemIndex[handle]:
+ model.append(node)
+ self._novelModels[tHandle] = model
+ return
+
##
# Public Methods
##
diff --git a/novelwriter/core/indexdata.py b/novelwriter/core/indexdata.py
index 727b0d6e..1dc6043b 100644
--- a/novelwriter/core/indexdata.py
+++ b/novelwriter/core/indexdata.py
@@ -31,6 +31,7 @@ import logging
from collections.abc import ItemsView, Sequence
from typing import TYPE_CHECKING, Literal
+from novelwriter import CONFIG
from novelwriter.common import checkInt, isListInstance, isTitleTag
from novelwriter.constants import nwKeyWords, nwStyles
@@ -237,6 +238,10 @@ class IndexHeading:
def title(self) -> str:
return self._title
+ @property
+ def mainCount(self) -> int:
+ return self._counts[0 if CONFIG.useCharCount else 1]
+
@property
def charCount(self) -> int:
return self._counts[0]
diff --git a/novelwriter/core/itemmodel.py b/novelwriter/core/itemmodel.py
index cab012e0..a14b8cc0 100644
--- a/novelwriter/core/itemmodel.py
+++ b/novelwriter/core/itemmodel.py
@@ -331,7 +331,7 @@ class ProjectModel(QAbstractItemModel):
return QModelIndex()
def index(self, row: int, column: int, parent: QModelIndex = QModelIndex()) -> QModelIndex:
- """get the index of a child item of a parent."""
+ """Get the index of a child item of a parent."""
if self.hasIndex(row, column, parent):
node: ProjectNode = parent.internalPointer() if parent.isValid() else self._root
if child := node.child(row):
diff --git a/novelwriter/core/novelmodel.py b/novelwriter/core/novelmodel.py
new file mode 100644
index 00000000..6aac5552
--- /dev/null
+++ b/novelwriter/core/novelmodel.py
@@ -0,0 +1,100 @@
+"""
+novelWriter – Novel Model
+=========================
+
+File History:
+Created: 2025-02-22 [2.7b1] NovelModel
+
+This file is a part of novelWriter
+Copyright (C) 2025 Veronica Berglyd Olsen and novelWriter contributors
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+"""
+from __future__ import annotations
+
+import logging
+
+from PyQt6.QtCore import QAbstractTableModel, QModelIndex, Qt
+from PyQt6.QtGui import QIcon, QPixmap
+
+from novelwriter import SHARED
+from novelwriter.constants import nwStyles
+from novelwriter.core.indexdata import IndexNode
+from novelwriter.core.item import NWItem
+from novelwriter.types import QtAlignRight
+
+logger = logging.getLogger(__name__)
+
+C_FACTOR = 0x0100
+
+C_TITLE_TEXT = 0x0000 | Qt.ItemDataRole.DisplayRole
+C_TITLE_ICON = 0x0000 | Qt.ItemDataRole.DecorationRole
+C_COUNT_TEXT = 0x0100 | Qt.ItemDataRole.DisplayRole
+C_COUNT_ALIGN = 0x0100 | Qt.ItemDataRole.TextAlignmentRole
+C_EXTRA_TEXT = 0x0200 | Qt.ItemDataRole.DisplayRole
+C_EXTRA_TIP = 0x0200 | Qt.ItemDataRole.ToolTipRole
+C_MORE_ICON = 0x0300 | Qt.ItemDataRole.DecorationRole
+
+T_NodeData = str | QIcon | QPixmap | Qt.AlignmentFlag | None
+
+
+class NovelModel(QAbstractTableModel):
+
+ def __init__(self, rootItem: NWItem) -> None:
+ super().__init__()
+ self._root = rootItem
+ self._rows: list[tuple[str, str, dict]] = []
+ self._more = SHARED.theme.getIcon("more_arrow")
+ return
+
+ def __del__(self) -> None: # pragma: no cover
+ logger.debug("Delete: NovelModel")
+ return
+
+ ##
+ # Model Interface
+ ##
+
+ def rowCount(self, index: QModelIndex) -> int:
+ """Return the number of rows for an entry."""
+ return len(self._rows)
+
+ def columnCount(self, index: QModelIndex) -> int:
+ """Return the number of columns for an entry."""
+ return 4
+
+ def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> T_NodeData:
+ """Return display data for a node."""
+ if index.isValid() and (row := index.row()) < len(self._rows):
+ return self._rows[row][2].get(C_FACTOR*index.column() | role)
+ return None
+
+ ##
+ # Data Methods
+ ##
+
+ def append(self, node: IndexNode) -> None:
+ """Append a node to the model."""
+ handle = node.handle
+ for key, head in node.items():
+ if key != "T0000":
+ iLevel = nwStyles.H_LEVEL.get(head.level, 0)
+ data = {}
+ data[C_TITLE_TEXT] = head.title
+ data[C_TITLE_ICON] = SHARED.theme.getHeaderDecoration(iLevel)
+ data[C_COUNT_TEXT] = f"{head.mainCount:n}"
+ data[C_COUNT_ALIGN] = QtAlignRight
+ data[C_MORE_ICON] = self._more
+ self._rows.append((handle, key, data))
+ return
diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py
index cb226781..5bb709ce 100644
--- a/novelwriter/gui/noveltree.py
+++ b/novelwriter/gui/noveltree.py
@@ -28,26 +28,22 @@ from __future__ import annotations
import logging
from enum import Enum
-from time import time
-from PyQt6.QtCore import QModelIndex, QPoint, Qt, pyqtSignal, pyqtSlot
-from PyQt6.QtGui import QActionGroup, QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent
+from PyQt6.QtCore import pyqtSignal, pyqtSlot
+from PyQt6.QtGui import QActionGroup, QFont, QPalette
from PyQt6.QtWidgets import (
- QAbstractItemView, QFrame, QHBoxLayout, QInputDialog, QMenu, QToolTip,
- QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
+ QFrame, QHBoxLayout, QMenu, QTreeView, QTreeWidgetItem, QVBoxLayout,
+ QWidget
)
from novelwriter import CONFIG, SHARED
-from novelwriter.common import minmax, qtAddAction, qtAddMenu, qtLambda
-from novelwriter.constants import nwKeyWords, nwLabels, nwStyles, trConst
-from novelwriter.core.indexdata import IndexHeading
-from novelwriter.enum import nwChange, nwDocMode, nwItemClass, nwOutline
+from novelwriter.common import qtAddAction, qtAddMenu, qtLambda
+from novelwriter.enum import nwChange, nwItemClass
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.extensions.novelselector import NovelSelector
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
from novelwriter.types import (
- QtAlignRight, QtDecoration, QtHeaderStretch, QtHeaderToContents,
- QtMouseLeft, QtMouseMiddle, QtScrollAlwaysOff, QtScrollAsNeeded,
+ QtHeaderStretch, QtHeaderToContents, QtScrollAlwaysOff, QtScrollAsNeeded,
QtSizeExpanding, QtUserRole
)
@@ -124,9 +120,9 @@ class GuiNovelView(QWidget):
lastCol = SHARED.project.options.getEnum(
"GuiNovelView", "lastCol", NovelTreeColumn, NovelTreeColumn.HIDDEN
)
- lastColSize = SHARED.project.options.getInt(
- "GuiNovelView", "lastColSize", 25
- )
+ # lastColSize = SHARED.project.options.getInt(
+ # "GuiNovelView", "lastColSize", 25
+ # )
self.clearNovelView()
self.novelBar.buildNovelRootMenu()
@@ -134,18 +130,18 @@ class GuiNovelView(QWidget):
self.novelBar.setCurrentRoot(lastNovel)
self.novelBar.setEnabled(True)
- self.novelTree.setLastColSize(lastColSize)
+ # self.novelTree.setLastColSize(lastColSize)
return
def closeProjectTasks(self) -> None:
"""Run closing project tasks."""
- lastColType = self.novelTree.lastColType
- lastColSize = self.novelTree.lastColSize
- logger.debug("Saving State: GuiNovelView")
- pOptions = SHARED.project.options
- pOptions.setValue("GuiNovelView", "lastCol", lastColType)
- pOptions.setValue("GuiNovelView", "lastColSize", lastColSize)
+ # lastColType = self.novelTree.lastColType
+ # lastColSize = self.novelTree.lastColSize
+ # logger.debug("Saving State: GuiNovelView")
+ # pOptions = SHARED.project.options
+ # pOptions.setValue("GuiNovelView", "lastCol", lastColType)
+ # pOptions.setValue("GuiNovelView", "lastColSize", lastColSize)
self.clearNovelView()
return
@@ -162,16 +158,24 @@ class GuiNovelView(QWidget):
# Public Slots
##
+ @pyqtSlot(str)
+ def setCurrentNovel(self, rootHandle: str | None) -> None:
+ """Set the current novel to display."""
+ if rootHandle and (model := SHARED.project.index.getNovelModel(rootHandle)):
+ self.novelTree.setModel(model)
+ self.novelTree.resizeColumsn()
+ return
+
@pyqtSlot(str)
def setActiveHandle(self, tHandle: str) -> None:
"""Highlight the rows associated with a given handle."""
- self.novelTree.setActiveHandle(tHandle)
+ # self.novelTree.setActiveHandle(tHandle)
return
@pyqtSlot()
def refreshTree(self) -> None:
"""Refresh the current tree."""
- self.novelTree.refreshTree(rootHandle=SHARED.project.data.getLastHandle("novelTree"))
+ # self.novelTree.refreshTree(rootHandle=SHARED.project.data.getLastHandle("novelTree"))
return
@pyqtSlot(str, Enum)
@@ -185,7 +189,7 @@ class GuiNovelView(QWidget):
"""The meta data of a novel item has changed, and the tree item
needs to be refreshed.
"""
- self.novelTree.refreshHandle(tHandle)
+ # self.novelTree.refreshHandle(tHandle)
return
@@ -301,13 +305,14 @@ class GuiNovelToolBar(QWidget):
def setCurrentRoot(self, rootHandle: str | None) -> None:
"""Set the current active root handle."""
self.novelValue.setHandle(rootHandle)
- self.novelView.novelTree.refreshTree(rootHandle=rootHandle, overRide=True)
+ SHARED.project.data.setLastHandle(rootHandle, "novelTree")
+ self.novelView.setCurrentNovel(rootHandle)
return
def setLastColType(self, colType: NovelTreeColumn, doRefresh: bool = True) -> None:
"""Set the last column type."""
- self.aLastCol[colType].setChecked(True)
- self.novelView.novelTree.setLastColType(colType, doRefresh=doRefresh)
+ # self.aLastCol[colType].setChecked(True)
+ # self.novelView.novelTree.setLastColType(colType, doRefresh=doRefresh)
return
##
@@ -317,20 +322,19 @@ class GuiNovelToolBar(QWidget):
@pyqtSlot()
def _refreshNovelTree(self) -> None:
"""Rebuild the current tree."""
- rootHandle = SHARED.project.data.getLastHandle("novelTree")
- self.novelView.novelTree.refreshTree(rootHandle=rootHandle, overRide=True)
+ self.novelView.setCurrentNovel(SHARED.project.data.getLastHandle("novelTree"))
return
@pyqtSlot()
def _selectLastColumnSize(self) -> None:
"""Set the maximum width for the last column."""
- oldSize = self.novelView.novelTree.lastColSize
- newSize, isOk = QInputDialog.getInt(
- self, self.tr("Column Size"), self.tr("Maximum column size in %"), oldSize, 15, 75, 5
- )
- if isOk:
- self.novelView.novelTree.setLastColSize(newSize)
- self._refreshNovelTree()
+ # oldSize = self.novelView.novelTree.lastColSize
+ # newSize, isOk = QInputDialog.getInt(
+ # self, self.tr("Column Size"), self.tr("Maximum column size in %"), oldSize, 15, 75, 5
+ # )
+ # if isOk:
+ # self.novelView.novelTree.setLastColSize(newSize)
+ # self._refreshNovelTree()
return
##
@@ -347,7 +351,7 @@ class GuiNovelToolBar(QWidget):
return
-class GuiNovelTree(QTreeWidget):
+class GuiNovelTree(QTreeView):
C_DATA = 0
C_TITLE = 0
@@ -375,55 +379,61 @@ class GuiNovelTree(QTreeWidget):
self._treeMap: dict[str, QTreeWidgetItem] = {}
# Cached Strings
- self._povLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
- self._focLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY])
- self._pltLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])
+ # self._povLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
+ # self._focLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY])
+ # self._pltLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])
# Build GUI
# =========
- iPx = SHARED.theme.baseIconHeight
- iSz = SHARED.theme.baseIconSize
+ # iPx = SHARED.theme.baseIconHeight
- self.setIconSize(iSz)
+ self.setIconSize(SHARED.theme.baseIconSize)
self.setFrameStyle(QFrame.Shape.NoFrame)
self.setUniformRowHeights(True)
self.setAllColumnsShowFocus(True)
self.setHeaderHidden(True)
self.setIndentation(2)
- self.setColumnCount(4)
- self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
- self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
- self.setExpandsOnDoubleClick(False)
- self.setDragEnabled(False)
+
+ # self.setIconSize(iSz)
+ # self.setFrameStyle(QFrame.Shape.NoFrame)
+ # self.setUniformRowHeights(True)
+ # self.setAllColumnsShowFocus(True)
+ # self.setHeaderHidden(True)
+ # self.setIndentation(2)
+ # self.setColumnCount(4)
+ # self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
+ # self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
+ # self.setExpandsOnDoubleClick(False)
+ # self.setDragEnabled(False)
# Lock the column sizes
- if header := self.header():
- header.setStretchLastSection(False)
- header.setMinimumSectionSize(iPx + 6)
- header.setSectionResizeMode(self.C_TITLE, QtHeaderStretch)
- header.setSectionResizeMode(self.C_WORDS, QtHeaderToContents)
- header.setSectionResizeMode(self.C_EXTRA, QtHeaderToContents)
- header.setSectionResizeMode(self.C_MORE, QtHeaderToContents)
+ # if header := self.header():
+ # header.setStretchLastSection(False)
+ # header.setMinimumSectionSize(iPx + 6)
+ # header.setSectionResizeMode(self.C_TITLE, QtHeaderStretch)
+ # header.setSectionResizeMode(self.C_WORDS, QtHeaderToContents)
+ # header.setSectionResizeMode(self.C_EXTRA, QtHeaderToContents)
+ # header.setSectionResizeMode(self.C_MORE, QtHeaderToContents)
# Pre-Generate Tree Formatting
- fH1 = self.font()
- fH1.setBold(True)
- fH1.setUnderline(True)
+ # fH1 = self.font()
+ # fH1.setBold(True)
+ # fH1.setUnderline(True)
- fH2 = self.font()
- fH2.setBold(True)
+ # fH2 = self.font()
+ # fH2.setBold(True)
- self._hFonts = [self.font(), fH1, fH2, self.font(), self.font()]
+ # self._hFonts = [self.font(), fH1, fH2, self.font(), self.font()]
# Connect signals
- self.clicked.connect(self._treeItemClicked)
- self.itemDoubleClicked.connect(self._treeDoubleClick)
- self.itemSelectionChanged.connect(self._treeSelectionChange)
+ # self.clicked.connect(self._treeItemClicked)
+ # self.itemDoubleClicked.connect(self._treeDoubleClick)
+ # self.itemSelectionChanged.connect(self._treeSelectionChange)
# Set custom settings
self.initSettings()
- self.updateTheme()
+ # self.updateTheme()
logger.debug("Ready: GuiNovelTree")
@@ -446,21 +456,21 @@ class GuiNovelTree(QTreeWidget):
def updateTheme(self) -> None:
"""Update theme elements."""
- iPx = SHARED.theme.baseIconHeight
- self._pMore = SHARED.theme.getPixmap("more_arrow", (iPx, iPx))
+ # iPx = SHARED.theme.baseIconHeight
+ # self._pMore = SHARED.theme.getPixmap("more_arrow", (iPx, iPx))
return
##
# Properties
##
- @property
- def lastColType(self) -> NovelTreeColumn:
- return self._lastCol
+ # @property
+ # def lastColType(self) -> NovelTreeColumn:
+ # return self._lastCol
- @property
- def lastColSize(self) -> int:
- return int(self._lastColSize * 100)
+ # @property
+ # def lastColSize(self) -> int:
+ # return int(self._lastColSize * 100)
##
# Class Methods
@@ -468,302 +478,313 @@ class GuiNovelTree(QTreeWidget):
def clearContent(self) -> None:
"""Clear the GUI content and the related maps."""
- self.clear()
- self._treeMap = {}
- self._lastBuild = 0
+ # self.clear()
+ # self._treeMap = {}
+ # self._lastBuild = 0
return
- def refreshTree(self, rootHandle: str | None = None, overRide: bool = False) -> None:
- """Refresh the tree if it has been changed."""
- logger.debug("Requesting refresh of the novel tree")
- if rootHandle is None:
- rootHandle = SHARED.project.tree.findRoot(nwItemClass.NOVEL)
-
- titleKey = None
- if selItems := self.selectedItems():
- titleKey = selItems[0].data(self.C_DATA, self.D_KEY)
-
- self._populateTree(rootHandle)
- SHARED.project.data.setLastHandle(rootHandle, "novelTree")
-
- if titleKey is not None and titleKey in self._treeMap:
- self._treeMap[titleKey].setSelected(True)
-
+ def resizeColumsn(self) -> None:
+ """Set the correct column sizes."""
+ if header := self.header():
+ header.setStretchLastSection(False)
+ header.setMinimumSectionSize(SHARED.theme.baseIconHeight + 6)
+ header.setSectionResizeMode(self.C_TITLE, QtHeaderStretch)
+ header.setSectionResizeMode(self.C_WORDS, QtHeaderToContents)
+ header.setSectionResizeMode(self.C_EXTRA, QtHeaderToContents)
+ header.setSectionResizeMode(self.C_MORE, QtHeaderToContents)
return
- def refreshHandle(self, tHandle: str) -> None:
- """Refresh the data for a given handle."""
- if idxData := SHARED.project.index.getItemData(tHandle):
- logger.debug("Refreshing meta data for item '%s'", tHandle)
- for sTitle, tHeading in idxData.items():
- sKey = f"{tHandle}:{sTitle}"
- if trItem := self._treeMap.get(sKey, None):
- self._updateTreeItemValues(trItem, tHeading, tHandle, sTitle)
- else:
- logger.debug("Heading '%s' not in novel tree", sKey)
- self.refreshTree()
- return
- return
+ # def refreshTree(self, rootHandle: str | None = None, overRide: bool = False) -> None:
+ # """Refresh the tree if it has been changed."""
+ # logger.debug("Requesting refresh of the novel tree")
+ # if rootHandle is None:
+ # rootHandle = SHARED.project.tree.findRoot(nwItemClass.NOVEL)
+
+ # titleKey = None
+ # if selItems := self.selectedItems():
+ # titleKey = selItems[0].data(self.C_DATA, self.D_KEY)
+
+ # self._populateTree(rootHandle)
+ # SHARED.project.data.setLastHandle(rootHandle, "novelTree")
+
+ # if titleKey is not None and titleKey in self._treeMap:
+ # self._treeMap[titleKey].setSelected(True)
+
+ # return
+
+ # def refreshHandle(self, tHandle: str) -> None:
+ # """Refresh the data for a given handle."""
+ # if idxData := SHARED.project.index.getItemData(tHandle):
+ # logger.debug("Refreshing meta data for item '%s'", tHandle)
+ # for sTitle, tHeading in idxData.items():
+ # sKey = f"{tHandle}:{sTitle}"
+ # if trItem := self._treeMap.get(sKey, None):
+ # self._updateTreeItemValues(trItem, tHeading, tHandle, sTitle)
+ # else:
+ # logger.debug("Heading '%s' not in novel tree", sKey)
+ # self.refreshTree()
+ # return
+ # return
def getSelectedHandle(self) -> tuple[str | None, str | None]:
"""Get the currently selected or active handle. If multiple
items are selected, return the first.
"""
- selList = self.selectedItems()
- trItem = selList[0] if selList else self.currentItem()
- if isinstance(trItem, QTreeWidgetItem):
- tHandle = trItem.data(self.C_DATA, self.D_HANDLE)
- sTitle = trItem.data(self.C_DATA, self.D_TITLE)
- return tHandle, sTitle
+ # selList = self.selectedItems()
+ # trItem = selList[0] if selList else self.currentItem()
+ # if isinstance(trItem, QTreeWidgetItem):
+ # tHandle = trItem.data(self.C_DATA, self.D_HANDLE)
+ # sTitle = trItem.data(self.C_DATA, self.D_TITLE)
+ # return tHandle, sTitle
return None, None
- def setLastColType(self, colType: NovelTreeColumn, doRefresh: bool = True) -> None:
- """Change the content type of the last column and rebuild."""
- if self._lastCol != colType:
- logger.debug("Changing last column to %s", colType.name)
- self._lastCol = colType
- self.setColumnHidden(self.C_EXTRA, colType == NovelTreeColumn.HIDDEN)
- if doRefresh:
- lastNovel = SHARED.project.data.getLastHandle("novelTree")
- self.refreshTree(rootHandle=lastNovel, overRide=True)
- return
+ # def setLastColType(self, colType: NovelTreeColumn, doRefresh: bool = True) -> None:
+ # """Change the content type of the last column and rebuild."""
+ # if self._lastCol != colType:
+ # logger.debug("Changing last column to %s", colType.name)
+ # self._lastCol = colType
+ # self.setColumnHidden(self.C_EXTRA, colType == NovelTreeColumn.HIDDEN)
+ # if doRefresh:
+ # lastNovel = SHARED.project.data.getLastHandle("novelTree")
+ # self.refreshTree(rootHandle=lastNovel, overRide=True)
+ # return
- def setLastColSize(self, colSize: int) -> None:
- """Set the column size in integer values between 15 and 75."""
- self._lastColSize = minmax(colSize, 15, 75)/100.0
- return
+ # def setLastColSize(self, colSize: int) -> None:
+ # """Set the column size in integer values between 15 and 75."""
+ # self._lastColSize = minmax(colSize, 15, 75)/100.0
+ # return
- def setActiveHandle(self, tHandle: str | None) -> None:
- """Highlight the rows associated with a given handle."""
- didScroll = False
- brushOn = self.palette().alternateBase()
- brushOff = self.palette().base()
- if pHandle := self._actHandle:
- for key, item in self._treeMap.items():
- if key.startswith(pHandle):
- for i in range(self.columnCount()):
- item.setBackground(i, brushOff)
- if tHandle:
- for key, item in self._treeMap.items():
- if key.startswith(tHandle):
- for i in range(self.columnCount()):
- item.setBackground(i, brushOn)
- if not didScroll:
- self.scrollToItem(item, QAbstractItemView.ScrollHint.PositionAtCenter)
- didScroll = True
- self._actHandle = tHandle or None
- return
+ # def setActiveHandle(self, tHandle: str | None) -> None:
+ # """Highlight the rows associated with a given handle."""
+ # didScroll = False
+ # brushOn = self.palette().alternateBase()
+ # brushOff = self.palette().base()
+ # if pHandle := self._actHandle:
+ # for key, item in self._treeMap.items():
+ # if key.startswith(pHandle):
+ # for i in range(self.columnCount()):
+ # item.setBackground(i, brushOff)
+ # if tHandle:
+ # for key, item in self._treeMap.items():
+ # if key.startswith(tHandle):
+ # for i in range(self.columnCount()):
+ # item.setBackground(i, brushOn)
+ # if not didScroll:
+ # self.scrollToItem(item, QAbstractItemView.ScrollHint.PositionAtCenter)
+ # didScroll = True
+ # self._actHandle = tHandle or None
+ # return
- ##
- # Events
- ##
+ # ##
+ # # Events
+ # ##
- def mousePressEvent(self, event: QMouseEvent) -> None:
- """Overload mousePressEvent to clear selection if clicking the
- mouse in a blank area of the tree view, and to load a document
- for viewing if the user middle-clicked.
- """
- super().mousePressEvent(event)
+ # def mousePressEvent(self, event: QMouseEvent) -> None:
+ # """Overload mousePressEvent to clear selection if clicking the
+ # mouse in a blank area of the tree view, and to load a document
+ # for viewing if the user middle-clicked.
+ # """
+ # super().mousePressEvent(event)
- if event.button() == QtMouseLeft:
- selItem = self.indexAt(event.pos())
- if not selItem.isValid():
- self.clearSelection()
+ # if event.button() == QtMouseLeft:
+ # selItem = self.indexAt(event.pos())
+ # if not selItem.isValid():
+ # self.clearSelection()
- elif event.button() == QtMouseMiddle:
- selItem = self.itemAt(event.pos())
- if not isinstance(selItem, QTreeWidgetItem):
- return
+ # elif event.button() == QtMouseMiddle:
+ # selItem = self.itemAt(event.pos())
+ # if not isinstance(selItem, QTreeWidgetItem):
+ # return
- tHandle, sTitle = self.getSelectedHandle()
- if tHandle is None:
- return
+ # tHandle, sTitle = self.getSelectedHandle()
+ # if tHandle is None:
+ # return
- self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, sTitle or "", False)
+ # self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.VIEW, sTitle or "", False)
- return
+ # return
- def focusOutEvent(self, event: QFocusEvent) -> None:
- """Clear the selection when the tree no longer has focus."""
- super().focusOutEvent(event)
- self.clearSelection()
- return
+ # def focusOutEvent(self, event: QFocusEvent) -> None:
+ # """Clear the selection when the tree no longer has focus."""
+ # super().focusOutEvent(event)
+ # self.clearSelection()
+ # return
- def resizeEvent(self, event: QResizeEvent) -> None:
- """Elide labels in the extra column."""
- super().resizeEvent(event)
- newW = event.size().width()
- oldW = event.oldSize().width()
- if newW != oldW:
- eliW = int(self._lastColSize * newW)
- fMetric = self.fontMetrics()
- for i in range(self.topLevelItemCount()):
- trItem = self.topLevelItem(i)
- if isinstance(trItem, QTreeWidgetItem):
- lastText = trItem.data(self.C_DATA, self.D_EXTRA)
- trItem.setText(
- self.C_EXTRA,
- fMetric.elidedText(lastText, Qt.TextElideMode.ElideRight, eliW)
- )
- return
+ # def resizeEvent(self, event: QResizeEvent) -> None:
+ # """Elide labels in the extra column."""
+ # super().resizeEvent(event)
+ # newW = event.size().width()
+ # oldW = event.oldSize().width()
+ # if newW != oldW:
+ # eliW = int(self._lastColSize * newW)
+ # fMetric = self.fontMetrics()
+ # for i in range(self.topLevelItemCount()):
+ # trItem = self.topLevelItem(i)
+ # if isinstance(trItem, QTreeWidgetItem):
+ # lastText = trItem.data(self.C_DATA, self.D_EXTRA)
+ # trItem.setText(
+ # self.C_EXTRA,
+ # fMetric.elidedText(lastText, Qt.TextElideMode.ElideRight, eliW)
+ # )
+ # return
##
# Private Slots
##
- @pyqtSlot("QModelIndex")
- def _treeItemClicked(self, index: QModelIndex) -> None:
- """The user clicked on an item in the tree."""
- if index.column() == self.C_MORE:
- tHandle = index.siblingAtColumn(self.C_DATA).data(self.D_HANDLE)
- sTitle = index.siblingAtColumn(self.C_DATA).data(self.D_TITLE)
- tipPos = self.mapToGlobal(self.visualRect(index).topRight())
- self._popMetaBox(tipPos, tHandle, sTitle)
- return
+ # @pyqtSlot("QModelIndex")
+ # def _treeItemClicked(self, index: QModelIndex) -> None:
+ # """The user clicked on an item in the tree."""
+ # if index.column() == self.C_MORE:
+ # tHandle = index.siblingAtColumn(self.C_DATA).data(self.D_HANDLE)
+ # sTitle = index.siblingAtColumn(self.C_DATA).data(self.D_TITLE)
+ # tipPos = self.mapToGlobal(self.visualRect(index).topRight())
+ # self._popMetaBox(tipPos, tHandle, sTitle)
+ # return
- @pyqtSlot()
- def _treeSelectionChange(self) -> None:
- """Extract the handle and line number of the currently selected
- title, and send it to the tree meta panel.
- """
- tHandle, _ = self.getSelectedHandle()
- if tHandle is not None:
- self.novelView.selectedItemChanged.emit(tHandle)
- return
+ # @pyqtSlot()
+ # def _treeSelectionChange(self) -> None:
+ # """Extract the handle and line number of the currently selected
+ # title, and send it to the tree meta panel.
+ # """
+ # tHandle, _ = self.getSelectedHandle()
+ # if tHandle is not None:
+ # self.novelView.selectedItemChanged.emit(tHandle)
+ # return
- @pyqtSlot("QTreeWidgetItem*", int)
- def _treeDoubleClick(self, item: QTreeWidgetItem, column: int) -> None:
- """Extract the handle and line number of the title double-
- clicked, and send it to the main gui class for opening in the
- document editor.
- """
- tHandle, sTitle = self.getSelectedHandle()
- self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, sTitle or "", True)
- return
+ # @pyqtSlot("QTreeWidgetItem*", int)
+ # def _treeDoubleClick(self, item: QTreeWidgetItem, column: int) -> None:
+ # """Extract the handle and line number of the title double-
+ # clicked, and send it to the main gui class for opening in the
+ # document editor.
+ # """
+ # tHandle, sTitle = self.getSelectedHandle()
+ # self.novelView.openDocumentRequest.emit(tHandle, nwDocMode.EDIT, sTitle or "", True)
+ # return
##
# Internal Functions
##
- def _populateTree(self, rootHandle: str | None) -> None:
- """Build the tree based on the project index."""
- self.clearContent()
- tStart = time()
- logger.debug("Building novel tree for root item '%s'", rootHandle)
+ # def _populateTree(self, rootHandle: str | None) -> None:
+ # """Build the tree based on the project index."""
+ # self.clearContent()
+ # tStart = time()
+ # logger.debug("Building novel tree for root item '%s'", rootHandle)
- novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True)
- for tKey, tHandle, sTitle, novIdx in novStruct:
- if novIdx.level == "H0":
- continue
+ # novStruct = SHARED.project.index.novelStructure(rootHandle=rootHandle, activeOnly=True)
+ # for tKey, tHandle, sTitle, novIdx in novStruct:
+ # if novIdx.level == "H0":
+ # continue
- newItem = QTreeWidgetItem()
- newItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
- newItem.setData(self.C_DATA, self.D_TITLE, sTitle)
- newItem.setData(self.C_DATA, self.D_KEY, tKey)
- newItem.setTextAlignment(self.C_WORDS, QtAlignRight)
+ # newItem = QTreeWidgetItem()
+ # newItem.setData(self.C_DATA, self.D_HANDLE, tHandle)
+ # newItem.setData(self.C_DATA, self.D_TITLE, sTitle)
+ # newItem.setData(self.C_DATA, self.D_KEY, tKey)
+ # newItem.setTextAlignment(self.C_WORDS, QtAlignRight)
- self._updateTreeItemValues(newItem, novIdx, tHandle, sTitle)
- self._treeMap[tKey] = newItem
- self.addTopLevelItem(newItem)
+ # self._updateTreeItemValues(newItem, novIdx, tHandle, sTitle)
+ # self._treeMap[tKey] = newItem
+ # self.addTopLevelItem(newItem)
- self.setActiveHandle(self._actHandle)
+ # self.setActiveHandle(self._actHandle)
- logger.debug("Novel Tree built in %.3f ms", (time() - tStart)*1000)
- self._lastBuild = time()
+ # logger.debug("Novel Tree built in %.3f ms", (time() - tStart)*1000)
+ # self._lastBuild = time()
- return
+ # return
- def _updateTreeItemValues(
- self, trItem: QTreeWidgetItem, idxItem: IndexHeading, tHandle: str, sTitle: str
- ) -> None:
- """Set the tree item values from the index entry."""
- iLevel = nwStyles.H_LEVEL.get(idxItem.level, 0)
- hDec = SHARED.theme.getHeaderDecoration(iLevel)
+ # def _updateTreeItemValues(
+ # self, trItem: QTreeWidgetItem, idxItem: IndexHeading, tHandle: str, sTitle: str
+ # ) -> None:
+ # """Set the tree item values from the index entry."""
+ # iLevel = nwStyles.H_LEVEL.get(idxItem.level, 0)
+ # hDec = SHARED.theme.getHeaderDecoration(iLevel)
- trItem.setData(self.C_TITLE, QtDecoration, hDec)
- trItem.setText(self.C_TITLE, idxItem.title)
- trItem.setFont(self.C_TITLE, self._hFonts[iLevel])
- trItem.setText(self.C_WORDS, f"{idxItem.wordCount:n}")
- trItem.setData(self.C_MORE, QtDecoration, self._pMore)
+ # trItem.setData(self.C_TITLE, QtDecoration, hDec)
+ # trItem.setText(self.C_TITLE, idxItem.title)
+ # trItem.setFont(self.C_TITLE, self._hFonts[iLevel])
+ # trItem.setText(self.C_WORDS, f"{idxItem.wordCount:n}")
+ # trItem.setData(self.C_MORE, QtDecoration, self._pMore)
- # Custom column
- viewport = self.viewport()
- mW = int(self._lastColSize * (viewport.width() if viewport else 100))
- lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
- elideText = self.fontMetrics().elidedText(lastText, Qt.TextElideMode.ElideRight, mW)
- trItem.setText(self.C_EXTRA, elideText)
- trItem.setData(self.C_DATA, self.D_EXTRA, lastText)
- trItem.setToolTip(self.C_EXTRA, toolTip)
+ # # Custom column
+ # viewport = self.viewport()
+ # mW = int(self._lastColSize * (viewport.width() if viewport else 100))
+ # lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
+ # elideText = self.fontMetrics().elidedText(lastText, Qt.TextElideMode.ElideRight, mW)
+ # trItem.setText(self.C_EXTRA, elideText)
+ # trItem.setData(self.C_DATA, self.D_EXTRA, lastText)
+ # trItem.setToolTip(self.C_EXTRA, toolTip)
- return
+ # return
- def _getLastColumnText(self, tHandle: str, sTitle: str) -> tuple[str, str]:
- """Generate text for the last column based on user settings."""
- if self._lastCol == NovelTreeColumn.HIDDEN:
- return "", ""
+ # def _getLastColumnText(self, tHandle: str, sTitle: str) -> tuple[str, str]:
+ # """Generate text for the last column based on user settings."""
+ # if self._lastCol == NovelTreeColumn.HIDDEN:
+ # return "", ""
- refData = []
- refName = ""
- refs = SHARED.project.index.getReferences(tHandle, sTitle)
- if self._lastCol == NovelTreeColumn.POV:
- refData = refs[nwKeyWords.POV_KEY]
- refName = self._povLabel
+ # refData = []
+ # refName = ""
+ # refs = SHARED.project.index.getReferences(tHandle, sTitle)
+ # if self._lastCol == NovelTreeColumn.POV:
+ # refData = refs[nwKeyWords.POV_KEY]
+ # refName = self._povLabel
- elif self._lastCol == NovelTreeColumn.FOCUS:
- refData = refs[nwKeyWords.FOCUS_KEY]
- refName = self._focLabel
+ # elif self._lastCol == NovelTreeColumn.FOCUS:
+ # refData = refs[nwKeyWords.FOCUS_KEY]
+ # refName = self._focLabel
- elif self._lastCol == NovelTreeColumn.PLOT:
- refData = refs[nwKeyWords.PLOT_KEY]
- refName = self._pltLabel
+ # elif self._lastCol == NovelTreeColumn.PLOT:
+ # refData = refs[nwKeyWords.PLOT_KEY]
+ # refName = self._pltLabel
- if refData:
- toolText = ", ".join(refData)
- return toolText, f"{refName}: {toolText}"
+ # if refData:
+ # toolText = ", ".join(refData)
+ # return toolText, f"{refName}: {toolText}"
- return "", ""
+ # return "", ""
- def _popMetaBox(self, qPos: QPoint, tHandle: str, sTitle: str) -> None:
- """Show the novel meta data box."""
- logger.debug("Generating meta data tooltip for '%s:%s'", tHandle, sTitle)
+ # def _popMetaBox(self, qPos: QPoint, tHandle: str, sTitle: str) -> None:
+ # """Show the novel meta data box."""
+ # logger.debug("Generating meta data tooltip for '%s:%s'", tHandle, sTitle)
- pIndex = SHARED.project.index
- novIdx = pIndex.getItemHeading(tHandle, sTitle)
- refTags = pIndex.getReferences(tHandle, sTitle)
- if not novIdx:
- return
+ # pIndex = SHARED.project.index
+ # novIdx = pIndex.getItemHeading(tHandle, sTitle)
+ # refTags = pIndex.getReferences(tHandle, sTitle)
+ # if not novIdx:
+ # return
- synopText = novIdx.synopsis
- if synopText:
- synopLabel = trConst(nwLabels.OUTLINE_COLS[nwOutline.SYNOP])
- synopText = f"
{synopLabel}: {synopText}
"
+ # 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)
+ # 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 = "
".join(refLines)
- refText = f"{refList}
"
+ # refText = ""
+ # if refLines:
+ # refList = "
".join(refLines)
+ # refText = f"{refList}
"
- ttText = refText + synopText or self.tr("No meta data")
- if ttText:
- QToolTip.showText(qPos, ttText)
+ # ttText = refText + synopText or self.tr("No meta data")
+ # if ttText:
+ # QToolTip.showText(qPos, ttText)
- return
+ # return
- @staticmethod
- def _appendMetaTag(refs: dict, key: str, lines: list[str]) -> list[str]:
- """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
+ # @staticmethod
+ # def _appendMetaTag(refs: dict, key: str, lines: list[str]) -> list[str]:
+ # """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
diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf
index 1a8dd31b..fb701405 100644
--- a/tests/reference/baseConfig_novelwriter.conf
+++ b/tests/reference/baseConfig_novelwriter.conf
@@ -1,5 +1,5 @@
[Meta]
-timestamp = 2025-02-06 11:05:16
+timestamp = 2025-02-22 19:57:47
[Main]
font =
@@ -13,6 +13,7 @@ hidevscroll = False
hidehscroll = False
lastnotes = 0x0
nativefont = True
+usecharcount = False
[Sizes]
mainwindow = 1200, 650