Update tests other than tree-related

This commit is contained in:
Veronica Berglyd Olsen
2024-11-23 19:30:29 +01:00
parent ca8bd8d271
commit 1bf42ceb55
29 changed files with 229 additions and 205 deletions
+6 -1
View File
@@ -91,6 +91,10 @@ class ProjectNode:
f"children={len(self._children)}>"
)
def __bool__(self) -> bool:
"""A node should always evaluate to True."""
return True
##
# Properties
##
@@ -190,10 +194,10 @@ class ProjectNode:
self._updateRelationships(child)
if 0 <= pos < len(self._children):
self._children.insert(pos, child)
self._refreshChildrenPos()
else:
child._row = len(self._children)
self._children.append(child)
self._refreshChildrenPos()
return
def takeChild(self, pos: int) -> ProjectNode | None:
@@ -229,6 +233,7 @@ class ProjectNode:
"""Update the row value on all children."""
for n, child in enumerate(self._children):
child._row = n
child.item.setOrder(n)
return
def _updateRelationships(self, child: ProjectNode) -> None:
+13
View File
@@ -44,6 +44,7 @@ from novelwriter.core.options import OptionState
from novelwriter.core.projectdata import NWProjectData
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
from novelwriter.core.sessions import NWSessionLog
from novelwriter.core.status import T_StatusKinds, T_UpdateEntry
from novelwriter.core.storage import NWStorage, NWStorageOpen
from novelwriter.core.tree import NWTree
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType
@@ -531,6 +532,18 @@ class NWProject:
self._data.itemImport.increment(nwItem.itemImport)
return
def updateStatus(self, kind: T_StatusKinds, update: T_UpdateEntry) -> None:
"""Update status or import entries."""
if kind == "s":
self._data.itemStatus.update(update)
SHARED.projectSignalProxy({"event": "statusLabels", "kind": kind})
self._tree.refreshAllItems()
elif kind == "i":
self._data.itemImport.update(update)
SHARED.projectSignalProxy({"event": "statusLabels", "kind": kind})
self._tree.refreshAllItems()
return
def localLookup(self, word: str | int) -> str:
"""Look up a word or number in the translation map for the
project and return it. The variable is cast to a string before
+5 -6
View File
@@ -65,6 +65,9 @@ class StatusEntry:
NO_ENTRY = StatusEntry("", QColor(0, 0, 0), nwStatusShape.SQUARE, QIcon(), 0)
T_UpdateEntry = list[tuple[str | None, StatusEntry]]
T_StatusKinds = Literal["s", "i"]
class NWStatus:
@@ -73,7 +76,7 @@ class NWStatus:
__slots__ = ("_store", "_default", "_prefix", "_height")
def __init__(self, prefix: Literal["s", "i"]) -> None:
def __init__(self, prefix: T_StatusKinds) -> None:
self._store: dict[str, StatusEntry] = {}
self._default = None
self._prefix = prefix[:1]
@@ -120,7 +123,7 @@ class NWStatus:
return key
def update(self, update: list[tuple[str | None, StatusEntry]]) -> None:
def update(self, update: T_UpdateEntry) -> None:
"""Update the list of statuses."""
self._store.clear()
for key, entry in update:
@@ -130,10 +133,6 @@ class NWStatus:
if self._default not in self._store:
self._default = next(iter(self._store)) if self._store else None
# Emit the change signal and refresh tree
SHARED.projectSignalProxy({"event": "statusLabels", "kind": self._prefix})
SHARED.project.tree.refreshAllItems()
return
def check(self, value: str) -> str:
+13 -6
View File
@@ -128,7 +128,7 @@ class NWTree:
self._model.insertChild(node, index, pos)
self._nodes[item.itemHandle] = node
self._items[item.itemHandle] = item
self._itemChange(item.itemHandle, nwChange.CREATE)
self._itemChange(item, nwChange.CREATE)
else:
logger.error("Could not locate parent of '%s'", item.itemHandle)
return False
@@ -137,7 +137,7 @@ class NWTree:
self._model.insertChild(node, QModelIndex(), pos)
self._nodes[item.itemHandle] = node
self._items[item.itemHandle] = item
self._itemChange(item.itemHandle, nwChange.CREATE)
self._itemChange(item, nwChange.CREATE)
else:
logger.error("Invalid project item '%s'", item.itemHandle)
return False
@@ -148,7 +148,7 @@ class NWTree:
if (node := self._nodes.get(tHandle)) and tHandle in self._items:
index = self._model.indexFromNode(node)
if index.isValid() and self._model.removeChild(index.parent(), index.row()):
self._itemChange(tHandle, nwChange.DELETE)
self._itemChange(node.item, nwChange.DELETE)
del self._nodes[tHandle]
del self._items[tHandle]
return True
@@ -246,7 +246,7 @@ class NWTree:
indexS = self._model.indexFromNode(node, 0)
indexE = self._model.indexFromNode(node, 3)
self._model.dataChanged.emit(indexS, indexE)
self._itemChange(tHandle, nwChange.UPDATE)
self._itemChange(node.item, nwChange.UPDATE)
return
def refreshAllItems(self) -> None:
@@ -464,11 +464,18 @@ class NWTree:
# Internal Functions
##
def _itemChange(self, tHandle: str, change: nwChange) -> None:
def _itemChange(self, item: NWItem, change: nwChange) -> None:
"""Signal item change and notify project."""
tHandle = item.itemHandle
logger.debug("Item change: %s -> %s", tHandle, change.name)
self._project.setProjectChanged(True)
SHARED.projectSignalProxy({"event": "itemChanged", "handle": tHandle, "change": change})
SHARED.projectSignalProxy(
{"event": "itemChanged", "handle": tHandle, "change": change}
)
if item.isRootType():
SHARED.projectSignalProxy(
{"event": "rootChanged", "handle": tHandle, "change": change}
)
return
def _getTrashNode(self) -> ProjectNode | None:
+2 -2
View File
@@ -185,11 +185,11 @@ class GuiProjectSettings(NDialog):
if self.statusPage.changed:
logger.debug("Updating status labels")
project.data.itemStatus.update(self.statusPage.getNewList())
project.updateStatus("s", self.statusPage.getNewList())
if self.importPage.changed:
logger.debug("Updating importance labels")
project.data.itemImport.update(self.importPage.getNewList())
project.updateStatus("i", self.importPage.getNewList())
if self.replacePage.changed:
logger.debug("Updating auto-replace settings")
+3 -3
View File
@@ -41,7 +41,7 @@ from novelwriter import CONFIG, SHARED
from novelwriter.common import minmax, qtLambda
from novelwriter.constants import nwKeyWords, nwLabels, nwStyles, trConst
from novelwriter.core.index import IndexHeading
from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
from novelwriter.enum import nwChange, nwDocMode, nwItemClass, nwOutline
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.extensions.novelselector import NovelSelector
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
@@ -174,8 +174,8 @@ class GuiNovelView(QWidget):
self.novelTree.refreshTree(rootHandle=SHARED.project.data.getLastHandle("novelTree"))
return
@pyqtSlot(str)
def updateRootItem(self, tHandle: str) -> None:
@pyqtSlot(str, Enum)
def updateRootItem(self, tHandle: str, change: nwChange) -> None:
"""If any root item changes, rebuild the novel root menu."""
self.novelBar.buildNovelRootMenu()
return
+10 -11
View File
@@ -43,7 +43,7 @@ from PyQt5.QtWidgets import (
from novelwriter import CONFIG, SHARED
from novelwriter.common import checkInt, formatFileFilter, makeFileNameSafe
from novelwriter.constants import nwKeyWords, nwLabels, nwStats, nwStyles, trConst
from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
from novelwriter.enum import nwChange, nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline
from novelwriter.error import logException
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.novelselector import NovelSelector
@@ -165,8 +165,8 @@ class GuiOutlineView(QWidget):
# Public Slots
##
@pyqtSlot(str)
def updateRootItem(self, tHandle: str) -> None:
@pyqtSlot(str, Enum)
def updateRootItem(self, tHandle: str, change: nwChange) -> None:
"""Handle tasks whenever a root folders changes."""
self.outlineBar.populateNovelList()
self.outlineData.updateClasses()
@@ -380,8 +380,8 @@ class GuiOutlineTree(QTreeWidget):
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.setExpandsOnDoubleClick(False)
self.setDragEnabled(False)
self.itemDoubleClicked.connect(self._treeDoubleClick)
self.itemSelectionChanged.connect(self._itemSelected)
self.itemDoubleClicked.connect(self._onItemDoubleClicked)
self.itemSelectionChanged.connect(self._onItemSelectionChanged)
self.setIconSize(SHARED.theme.baseIconSize)
self.setIndentation(0)
@@ -563,7 +563,7 @@ class GuiOutlineTree(QTreeWidget):
##
@pyqtSlot("QTreeWidgetItem*", int)
def _treeDoubleClick(self, tItem: QTreeWidgetItem, tCol: int) -> None:
def _onItemDoubleClicked(self, tItem: QTreeWidgetItem, tCol: 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.
@@ -574,14 +574,13 @@ class GuiOutlineTree(QTreeWidget):
return
@pyqtSlot()
def _itemSelected(self) -> None:
def _onItemSelectionChanged(self) -> None:
"""Extract the handle and line number of the currently selected
title, and send it to the details panel.
"""
selItems = self.selectedItems()
if selItems:
tHandle = selItems[0].data(self._colIdx[nwOutline.TITLE], self.D_HANDLE)
sTitle = selItems[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
if items := self.selectedItems():
tHandle = items[0].data(self._colIdx[nwOutline.TITLE], self.D_HANDLE)
sTitle = items[0].data(self._colIdx[nwOutline.TITLE], self.D_TITLE)
self.activeItemChanged.emit(tHandle, sTitle)
return
+8 -12
View File
@@ -66,15 +66,9 @@ class GuiProjectView(QWidget):
available are mapped through to the project tree class.
"""
# Signals triggered when the meta data values of items change
rootFolderChanged = pyqtSignal(str)
# Signals for user interaction with the project tree
selectedItemChanged = pyqtSignal(str)
openDocumentRequest = pyqtSignal(str, Enum, str, bool)
# Requests for the main GUI
projectSettingsRequest = pyqtSignal(int)
selectedItemChanged = pyqtSignal(str)
def __init__(self, parent: QWidget) -> None:
super().__init__(parent=parent)
@@ -229,8 +223,8 @@ class GuiProjectView(QWidget):
self.projTree.newTreeItem(nwItemType.FILE, copyDoc=tHandle)
return
@pyqtSlot(str)
def updateRootItem(self, tHandle: str) -> None:
@pyqtSlot(str, Enum)
def updateRootItem(self, tHandle: str, change: nwChange) -> None:
"""Process root item changes."""
self.projBar.buildQuickLinksMenu()
return
@@ -625,9 +619,8 @@ class GuiProjectTree(QTreeView):
if root := SHARED.project.tree.nodes.get(itemRoot):
pos = root.row() + 1
SHARED.project.newRoot(itemClass, pos)
tHandle = SHARED.project.newRoot(itemClass, pos)
self.restoreExpandedState()
self.projView.rootFolderChanged.emit(tHandle)
elif itemType in (nwItemType.FILE, nwItemType.FOLDER):
@@ -684,7 +677,10 @@ class GuiProjectTree(QTreeView):
SHARED.project.index.reIndexHandle(tHandle)
SHARED.project.tree.refreshItems([tHandle])
else:
SHARED.project.newFolder(newLabel, sHandle, pos)
tHandle = SHARED.project.newFolder(newLabel, sHandle, pos)
# Select the new item automatically
self.setSelectedHandle(tHandle)
return
+6 -3
View File
@@ -221,6 +221,9 @@ class GuiMain(QMainWindow):
SHARED.projectItemChanged.connect(self.projView.onProjectItemChanged)
SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus)
SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage)
SHARED.rootFolderChanged.connect(self.novelView.updateRootItem)
SHARED.rootFolderChanged.connect(self.outlineView.updateRootItem)
SHARED.rootFolderChanged.connect(self.projView.updateRootItem)
SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage)
SHARED.statusLabelsChanged.connect(self.docViewerPanel.updateStatusLabels)
@@ -235,9 +238,6 @@ class GuiMain(QMainWindow):
self.projView.openDocumentRequest.connect(self._openDocument)
self.projView.projectSettingsRequest.connect(self.showProjectSettingsDialog)
self.projView.rootFolderChanged.connect(self.novelView.updateRootItem)
self.projView.rootFolderChanged.connect(self.outlineView.updateRootItem)
self.projView.rootFolderChanged.connect(self.projView.updateRootItem)
self.projView.selectedItemChanged.connect(self.itemDetails.updateViewBox)
self.novelView.openDocumentRequest.connect(self._openDocument)
@@ -1083,6 +1083,9 @@ class GuiMain(QMainWindow):
self.projView.initSettings()
self.novelView.initSettings()
self.outlineView.initSettings()
# Force update of word count
self._lastTotalCount = 0
self._updateStatusWordCount()
return
+5
View File
@@ -63,6 +63,7 @@ class SharedData(QObject):
indexCleared = pyqtSignal()
mainClockTick = pyqtSignal()
projectItemChanged = pyqtSignal(str, Enum)
rootFolderChanged = pyqtSignal(str, Enum)
projectStatusChanged = pyqtSignal(bool)
projectStatusMessage = pyqtSignal(str)
spellLanguageChanged = pyqtSignal(str, str)
@@ -338,6 +339,10 @@ class SharedData(QObject):
self.projectItemChanged.emit(
data.get("handle", ""), data.get("change", nwChange.UPDATE)
)
elif event == "rootChanged":
self.rootFolderChanged.emit(
data.get("handle", ""), data.get("change", nwChange.UPDATE)
)
return
##