From 337f05f60ebcefdde34e0635852cb6eba0b13d87 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 18 Nov 2024 00:01:40 +0100 Subject: [PATCH] Re-enable item rename --- novelwriter/core/item.py | 17 ++++++++++++++++- novelwriter/core/status.py | 2 +- novelwriter/core/tree.py | 31 ++++++++++++++----------------- novelwriter/gui/projtree.py | 23 ++++++++--------------- novelwriter/guimain.py | 8 ++++---- novelwriter/shared.py | 17 ++++++++++------- 6 files changed, 53 insertions(+), 45 deletions(-) diff --git a/novelwriter/core/item.py b/novelwriter/core/item.py index efa6de18..b5915c1c 100644 --- a/novelwriter/core/item.py +++ b/novelwriter/core/item.py @@ -55,7 +55,7 @@ class NWItem: "_project", "_name", "_handle", "_parent", "_root", "_order", "_type", "_class", "_layout", "_status", "_import", "_active", "_expanded", "_heading", "_charCount", "_wordCount", - "_paraCount", "_cursorPos", "_initCount", + "_paraCount", "_cursorPos", "_initCount", "_blocked", ) def __init__(self, project: NWProject, handle: str) -> None: @@ -82,6 +82,8 @@ class NWItem: self._cursorPos = 0 # Last cursor position self._initCount = 0 # Initial word count + self._blocked = True + return def __repr__(self) -> str: @@ -257,6 +259,7 @@ class NWItem: self._cursorPos = 0 self._initCount = self._wordCount + self._blocked = False return True @@ -281,6 +284,7 @@ class NWItem: cls._paraCount = source._paraCount cls._cursorPos = source._cursorPos cls._initCount = source._initCount + cls._blocked = source._blocked return cls ## @@ -415,6 +419,7 @@ class NWItem: self._name = simplified(name) else: self._name = "" + self._notifyChange() return def setParent(self, handle: Any) -> None: @@ -560,3 +565,13 @@ class NWItem: """Save the initial word count.""" self._initCount = self._wordCount return + + ## + # Internal Functions + ## + + def _notifyChange(self) -> None: + """Notify project tree on user changes to the item.""" + if not self._blocked: + self._project.tree.refreshNode(self._handle) + return diff --git a/novelwriter/core/status.py b/novelwriter/core/status.py index de017f51..dc0ef397 100644 --- a/novelwriter/core/status.py +++ b/novelwriter/core/status.py @@ -131,7 +131,7 @@ class NWStatus: self._default = next(iter(self._store)) if self._store else None # Emit the change signal - SHARED.projectSingalProxy({"event": "statusLabels", "kind": self._prefix}) + SHARED.projectSignalProxy({"event": "statusLabels", "kind": self._prefix}) return diff --git a/novelwriter/core/tree.py b/novelwriter/core/tree.py index 8b5a6226..36d1dbfc 100644 --- a/novelwriter/core/tree.py +++ b/novelwriter/core/tree.py @@ -30,6 +30,7 @@ from collections.abc import Iterable, Iterator from pathlib import Path from typing import TYPE_CHECKING, Literal, overload +from novelwriter import SHARED from novelwriter.constants import nwFiles from novelwriter.core.item import NWItem from novelwriter.core.itemmodel import ProjectModel, ProjectNode @@ -68,20 +69,12 @@ class NWTree: ) def __init__(self, project: NWProject) -> None: - self._project = project - - # self._tree: dict[str, NWItem] = {} # Holds all the items of the project - # self._order: list[str] = [] # The order of the tree items in the tree view - # self._roots: dict[str, NWItem] = {} # The root items of the tree - self._model = ProjectModel(self) self._items: dict[str, NWItem] = {} self._nodes: dict[str, ProjectNode] = {} - self._trash = None # The handle of the trash root folder self._changed = False # True if tree structure has changed - return ## @@ -107,15 +100,10 @@ class NWTree: def clear(self) -> None: """Clear the item tree entirely.""" - # self._tree = {} - # self._order = [] - # self._roots = {} - - self._model = ProjectModel(self) - self._items = {} - self._nodes = {} - - self._trash = None + self._model = ProjectModel(self) + self._items = {} + self._nodes = {} + self._trash = None self._changed = False return @@ -237,6 +225,15 @@ class NWTree: return + def refreshNode(self, tHandle: str) -> None: + """Refresh node data on item change.""" + if node := self._nodes.get(tHandle): + node.refresh() + index = self._model.indexFromNode(node) + SHARED.projectSignalProxy({"event": "projectItem", "handle": tHandle}) + self._model.dataChanged.emit(index, index) + return + def _buildTree(self, items: dict[str, NWItem]) -> dict[str, NWItem]: """""" remains: dict[str, NWItem] = {} diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index 159ce44d..4017b3f5 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -42,6 +42,7 @@ from novelwriter.common import qtLambda from novelwriter.constants import nwLabels, nwUnicode, trConst from novelwriter.core.item import NWItem from novelwriter.core.itemmodel import ProjectModel, ProjectNode +from novelwriter.dialogs.editlabel import GuiEditLabel from novelwriter.dialogs.projectsettings import GuiProjectSettings from novelwriter.enum import nwDocMode, nwItemClass, nwItemLayout, nwItemType from novelwriter.extensions.modified import NIconToolButton @@ -58,7 +59,7 @@ class GuiProjectView(QWidget): """ # Signals triggered when the meta data values of items change - treeItemChanged = pyqtSignal(str) + # treeItemChanged = pyqtSignal(str) rootFolderChanged = pyqtSignal(str) wordCountsChanged = pyqtSignal() @@ -193,8 +194,10 @@ class GuiProjectView(QWidget): """ if tHandle is None: tHandle = self.projTree.getSelectedHandle() - if tHandle: - self.projTree.renameTreeItem(tHandle, name=name) + if nwItem := SHARED.project.tree[tHandle]: + newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or nwItem.itemName) + if dlgOk: + nwItem.setName(newLabel) return @pyqtSlot(str, bool) @@ -893,16 +896,6 @@ class GuiProjectTree(QTreeView): # self.setCurrentItem(tItem.child(0)) return - def renameTreeItem(self, tHandle: str, name: str = "") -> None: - """Open a dialog to edit the label of an item.""" - # if nwItem := SHARED.project.tree[tHandle]: - # newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or nwItem.itemName) - # if dlgOk: - # nwItem.setName(newLabel) - # self.setTreeItemValues(nwItem) - # self._alertTreeChange(tHandle, flush=False) - return - # def saveTreeOrder(self) -> None: # """Build a list of the items in the project tree and send them # to the project class. This syncs up the two versions of the @@ -1848,7 +1841,7 @@ class _TreeContextMenu(QMenu): # Edit Item Settings action = self.addAction(self.tr("Rename")) - action.triggered.connect(qtLambda(self.projTree.renameTreeItem, self._handle)) + action.triggered.connect(qtLambda(self.projView.renameTreeItem, self._handle)) if isFile: self._itemHeader() self._itemActive(False) @@ -1911,7 +1904,7 @@ class _TreeContextMenu(QMenu): if hItem := SHARED.project.index.getItemHeading(self._handle, "T0001"): action = self.addAction(self.tr("Rename to Heading")) action.triggered.connect( - qtLambda(self.projTree.renameTreeItem, self._handle, hItem.title) + qtLambda(self.projView.renameTreeItem, self._handle, hItem.title) ) return diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 1bb744f6..fc7cd532 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -216,6 +216,10 @@ class GuiMain(QMainWindow): SHARED.indexScannedText.connect(self.itemDetails.updateViewBox) SHARED.indexScannedText.connect(self.projView.updateItemValues) SHARED.mainClockTick.connect(self._timeTick) + SHARED.projectItemChanged.connect(self.docEditor.updateDocInfo) + SHARED.projectItemChanged.connect(self.docViewer.updateDocInfo) + SHARED.projectItemChanged.connect(self.docViewerPanel.projectItemChanged) + SHARED.projectItemChanged.connect(self.itemDetails.updateViewBox) SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus) SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage) SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage) @@ -237,10 +241,6 @@ class GuiMain(QMainWindow): self.projView.rootFolderChanged.connect(self.outlineView.updateRootItem) self.projView.rootFolderChanged.connect(self.projView.updateRootItem) self.projView.selectedItemChanged.connect(self.itemDetails.updateViewBox) - self.projView.treeItemChanged.connect(self.docEditor.updateDocInfo) - self.projView.treeItemChanged.connect(self.docViewer.updateDocInfo) - self.projView.treeItemChanged.connect(self.docViewerPanel.projectItemChanged) - self.projView.treeItemChanged.connect(self.itemDetails.updateViewBox) self.projView.wordCountsChanged.connect(self._updateStatusWordCount) self.novelView.openDocumentRequest.connect(self._openDocument) diff --git a/novelwriter/shared.py b/novelwriter/shared.py index a42c0ffa..5e42fd1b 100644 --- a/novelwriter/shared.py +++ b/novelwriter/shared.py @@ -55,15 +55,16 @@ class SharedData(QObject): "_idleTime", "_idleRefTime", ) + focusModeChanged = pyqtSignal(bool) + indexAvailable = pyqtSignal() + indexChangedTags = pyqtSignal(list, list) + indexCleared = pyqtSignal() + indexScannedText = pyqtSignal(str) + mainClockTick = pyqtSignal() + projectItemChanged = pyqtSignal(str) projectStatusChanged = pyqtSignal(bool) projectStatusMessage = pyqtSignal(str) spellLanguageChanged = pyqtSignal(str, str) - focusModeChanged = pyqtSignal(bool) - indexScannedText = pyqtSignal(str) - indexChangedTags = pyqtSignal(list, list) - indexCleared = pyqtSignal() - indexAvailable = pyqtSignal() - mainClockTick = pyqtSignal() statusLabelsChanged = pyqtSignal(str) def __init__(self) -> None: @@ -320,12 +321,14 @@ class SharedData(QObject): self.indexAvailable.emit() return - def projectSingalProxy(self, data: dict) -> None: + def projectSignalProxy(self, data: dict) -> None: """Emit signals on project data change.""" event = data.get("event") logger.debug("Received '%s' event from project data", event) if event == "statusLabels": self.statusLabelsChanged.emit(data.get("kind", "")) + elif event == "projectItem": + self.projectItemChanged.emit(data.get("handle", "")) return ##