Handle actions in the project tree internally in the class
This commit is contained in:
+64
-34
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user