Handle actions in the project tree internally in the class

This commit is contained in:
Veronica Berglyd Olsen
2022-06-06 13:46:54 +02:00
parent 3ff5dfce33
commit 669eabc7e8
2 changed files with 99 additions and 82 deletions
+64 -34
View File
@@ -27,6 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
import novelwriter
from enum import Enum
from time import time
from PyQt5.QtCore import Qt, QSize, pyqtSignal, pyqtSlot
@@ -37,7 +38,7 @@ from PyQt5.QtWidgets import (
)
from novelwriter.core import NWDoc
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout, nwAlert
from novelwriter.common import minmax
from novelwriter.dialogs.itemeditor import GuiItemEditor
@@ -51,11 +52,16 @@ class GuiProjectTree(QTreeWidget):
C_EXPORT = 2
C_STATUS = 3
# Signals triggered when the meta data values of items change
treeItemChanged = pyqtSignal(str)
novelItemChanged = pyqtSignal(str)
rootFolderChanged = pyqtSignal(str)
wordCountsChanged = pyqtSignal()
# Signals for user interaction with the project tree
selectedItemChanged = pyqtSignal(str)
openDocumentRequest = pyqtSignal(str, Enum)
def __init__(self, theParent):
QTreeWidget.__init__(self, theParent)
@@ -127,6 +133,10 @@ class GuiProjectTree(QTreeWidget):
# The last column should just auto-scale
self.resizeColumnToContents(self.C_STATUS)
# Connect signals
self.itemDoubleClicked.connect(self._treeDoubleClick)
self.itemSelectionChanged.connect(self._treeSelectionChange)
# Set custom settings
self.initTree()
@@ -223,9 +233,9 @@ class GuiProjectTree(QTreeWidget):
if tHandle is None: # pragma: no cover
return True
# Add the new item to the tree
# Add the new item to the tree and open the editor dialog
self.revealNewTreeItem(tHandle, nHandle)
self.theParent.editItem(tHandle)
self.editTreeItem(tHandle)
# Handle new file creation
nwItem = self.theProject.tree[tHandle]
@@ -249,10 +259,7 @@ class GuiProjectTree(QTreeWidget):
pIndex.scanText(tHandle, newText)
# Get Word Counts
cC, wC, pC = pIndex.getCounts(tHandle)
nwItem.setCharCount(cC)
nwItem.setWordCount(wC)
nwItem.setParaCount(pC)
_, wC, _ = pIndex.getCounts(tHandle)
self.propagateCount(tHandle, wC)
self.wordCountsChanged.emit()
@@ -280,8 +287,8 @@ class GuiProjectTree(QTreeWidget):
return True
def moveTreeItem(self, nStep):
"""Move an item up or down in the tree, but only if the treeView
has focus. This also applies when the menu is used.
"""Move an item up or down in the tree, but only if the project
tree has focus. This also applies when the menu is used.
"""
if not self.theParent.hasProject:
logger.error("No project open")
@@ -321,13 +328,9 @@ class GuiProjectTree(QTreeWidget):
return True
def editTreeItem(self, tHandle=None):
def editTreeItem(self, tHandle):
"""Open the edit item dialog.
"""
if tHandle is None:
logger.warning("No item selected")
return False
tItem = self.theProject.tree[tHandle]
if tItem is None:
return False
@@ -357,8 +360,8 @@ class GuiProjectTree(QTreeWidget):
return True
def getTreeFromHandle(self, tHandle):
"""Recursively return all the children items starting from a
given item handle.
"""Recursively return all the child items starting from a given
item handle.
"""
theList = []
theItem = self._getTreeItem(tHandle)
@@ -366,14 +369,6 @@ class GuiProjectTree(QTreeWidget):
theList = self._scanChildren(theList, theItem, 0)
return theList
def toggleExpanded(self, tHandle):
"""Expand an item based on its handle.
"""
trItem = self._getTreeItem(tHandle)
if trItem is not None:
trItem.setExpanded(not trItem.isExpanded())
return
def getColumnSizes(self):
"""Return the column widths for the tree columns.
"""
@@ -719,9 +714,52 @@ class GuiProjectTree(QTreeWidget):
return self._timeChanged > checkTime
##
# Slots
# Public Solts
##
@pyqtSlot(str, int, int, int)
def doUpdateCounts(self, tHandle, cCount, wCount, pCount):
"""Slot for updating the word count of a specific item.
"""
self.propagateCount(tHandle, wCount, countChildren=True)
self.wordCountsChanged.emit()
return
##
# Private Slots
##
@pyqtSlot()
def _treeSelectionChange(self):
"""The user changed which item is selected.
"""
tHandle = self.getSelectedHandle()
if tHandle is not None:
self.selectedItemChanged.emit(tHandle)
return
@pyqtSlot("QTreeWidgetItem*", int)
def _treeDoubleClick(self, tItem, colNo):
"""Capture a double-click event and either request the document
for editing if it is a file, or expand/close the node it is not.
"""
tHandle = self.getSelectedHandle()
if tHandle is None:
return
tItem = self.theProject.tree[tHandle]
if tItem is None:
return
if tItem.itemType == nwItemType.FILE:
self.openDocumentRequest.emit(tHandle, nwDocMode.EDIT)
else:
trItem = self._getTreeItem(tHandle)
if trItem is not None:
trItem.setExpanded(not trItem.isExpanded())
return
@pyqtSlot("QPoint")
def _rightClickMenu(self, clickPos):
"""The user right clicked an element in the project tree, so we
@@ -739,14 +777,6 @@ class GuiProjectTree(QTreeWidget):
return
@pyqtSlot(str, int, int, int)
def doUpdateCounts(self, tHandle, cCount, wCount, pCount):
"""Slot for updating the word count of a specific item.
"""
self.propagateCount(tHandle, wCount, countChildren=True)
self.wordCountsChanged.emit()
return
##
# Events
##
@@ -774,7 +804,7 @@ class GuiProjectTree(QTreeWidget):
return
if tItem.itemType == nwItemType.FILE:
self.theParent.viewDocument(tHandle)
self.openDocumentRequest.emit(tHandle, nwDocMode.VIEW)
return
+35 -48
View File
@@ -115,28 +115,6 @@ class GuiMain(QMainWindow):
self.mainMenu = GuiMainMenu(self)
self.viewsBar = GuiViewsBar(self)
# Connect Signals Between Main Elements
self.viewsBar.viewChangeRequested.connect(self._changeView)
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
self.treeView.novelItemChanged.connect(self._treeNovelItemChanged)
self.treeView.wordCountsChanged.connect(self._updateStatusWordCount)
self.treeView.treeItemChanged.connect(self.docEditor.updateDocInfo)
self.treeView.treeItemChanged.connect(self.docViewer.updateDocInfo)
self.treeView.treeItemChanged.connect(self.treeMeta.updateViewBox)
self.treeView.rootFolderChanged.connect(self.projView.updateRootItem)
self.docEditor.spellDictionaryChanged.connect(self.statusBar.setLanguage)
self.docEditor.docEditedStatusChanged.connect(self.statusBar.doUpdateDocumentStatus)
self.docEditor.docCountsChanged.connect(self.treeMeta.doUpdateCounts)
self.docEditor.docCountsChanged.connect(self.treeView.doUpdateCounts)
self.docEditor.loadDocumentTagRequest.connect(self._followTag)
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
self.projView.loadDocumentTagRequest.connect(self._followTag)
# Project Tree Stack
self.projStack = QStackedWidget()
self.projStack.addWidget(self.treeView)
@@ -214,6 +192,30 @@ class GuiMain(QMainWindow):
self.setStatusBar(self.statusBar)
self.addToolBar(Qt.LeftToolBarArea, self.viewsBar)
# Connect Signals
# ===============
self.viewsBar.viewChangeRequested.connect(self._changeView)
self.treeView.selectedItemChanged.connect(self.treeMeta.updateViewBox)
self.treeView.openDocumentRequest.connect(self._openDocument)
self.treeView.novelItemChanged.connect(self._treeNovelItemChanged)
self.treeView.wordCountsChanged.connect(self._updateStatusWordCount)
self.treeView.treeItemChanged.connect(self.docEditor.updateDocInfo)
self.treeView.treeItemChanged.connect(self.docViewer.updateDocInfo)
self.treeView.treeItemChanged.connect(self.treeMeta.updateViewBox)
self.treeView.rootFolderChanged.connect(self.projView.updateRootItem)
self.docEditor.spellDictionaryChanged.connect(self.statusBar.setLanguage)
self.docEditor.docEditedStatusChanged.connect(self.statusBar.doUpdateDocumentStatus)
self.docEditor.docCountsChanged.connect(self.treeMeta.doUpdateCounts)
self.docEditor.docCountsChanged.connect(self.treeView.doUpdateCounts)
self.docEditor.loadDocumentTagRequest.connect(self._followTag)
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
self.projView.loadDocumentTagRequest.connect(self._followTag)
# Finalise Initialisation
# =======================
@@ -1468,6 +1470,17 @@ class GuiMain(QMainWindow):
self.viewDocument(tHandle=tHandle, tAnchor=f"#{sTitle}")
return
@pyqtSlot(str, Enum)
def _openDocument(self, tHandle, tMode):
"""Handle an open document request.
"""
if tHandle is not None:
if tMode == nwDocMode.EDIT:
self.openDocument(tHandle, changeFocus=False)
elif tMode == nwDocMode.VIEW:
self.viewDocument(tHandle=tHandle)
return
@pyqtSlot(nwView)
def _changeView(self, view):
"""Handle the requested change of view from the GuiViewBar.
@@ -1531,32 +1544,6 @@ class GuiMain(QMainWindow):
return
@pyqtSlot()
def _treeSingleClick(self):
"""Single click on a project tree item just updates the details
panel below the tree.
"""
tHandle = self.treeView.getSelectedHandle()
if tHandle is not None:
self.treeMeta.updateViewBox(tHandle)
return
@pyqtSlot("QTreeWidgetItem*", int)
def _treeDoubleClick(self, tItem, colNo):
"""The user double-clicked an item in the tree. If it is a file,
we open it. Otherwise, we toggle the expanded status.
"""
tHandle = self.treeView.getSelectedHandle()
if tHandle is not None:
tItem = self.theProject.tree[tHandle]
if tItem is None:
return
if tItem.itemType == nwItemType.FILE:
self.openDocument(tHandle, changeFocus=False, doScroll=False)
else:
self.treeView.toggleExpanded(tHandle)
return
@pyqtSlot()
def _treeNovelItemChanged(self):
"""Triggered when there is a change to a novel item in the