Keep project tree and outline tree in sync

This commit is contained in:
Veronica K. B. Olsen
2021-01-02 17:33:53 +01:00
parent 4d7f925c5a
commit 21d91193a2
3 changed files with 59 additions and 9 deletions
+5 -5
View File
@@ -165,7 +165,7 @@ class GuiOutline(QTreeWidget):
return
def refreshTree(self, overRide=False):
def refreshTree(self, overRide=False, novelChanged=False):
"""Called whenever the Outline tab is activated and controls
what data to load, and if necessary, force a rebuild of the
tree.
@@ -177,10 +177,10 @@ class GuiOutline(QTreeWidget):
self.firstView = False
return
# If the novel index has changed since the tree was last built,
# we rebuild the tree from the updated index.
idxChanged = self.theParent.theIndex.novelChangedSince(self.lastBuild)
doBuild = idxChanged and self.theProject.autoOutline
# If the novel index or novel tree has changed since the tree
# was last built, we rebuild the tree from the updated index.
indexChanged = self.theIndex.novelChangedSince(self.lastBuild)
doBuild = (novelChanged or indexChanged) and self.theProject.autoOutline
if doBuild or overRide:
logger.debug("Rebuilding Project Outline")
self._populateTree()
+27 -2
View File
@@ -31,7 +31,7 @@ import logging
from time import time
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtCore import Qt, QSize, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
qApp, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMenu, QAction
@@ -51,6 +51,9 @@ class GuiProjectTree(QTreeWidget):
C_EXPORT = 2
C_FLAGS = 3
novelItemChanged = pyqtSignal()
noteItemChanged = pyqtSignal()
def __init__(self, theParent):
QTreeWidget.__init__(self, theParent)
@@ -285,8 +288,11 @@ class GuiProjectTree(QTreeWidget):
pHandle = nwItem.itemParent
if pHandle is not None and pHandle in self._treeMap:
self._treeMap[pHandle].setExpanded(True)
self._emitItemChange(tHandle)
self.clearSelection()
trItem.setSelected(True)
return True
def moveTreeItem(self, nStep):
@@ -327,6 +333,7 @@ class GuiProjectTree(QTreeWidget):
self.clearSelection()
cItem.setSelected(True)
self._setTreeChanged(True)
self._emitItemChange(tHandle)
return True
@@ -788,6 +795,10 @@ class GuiProjectTree(QTreeWidget):
else:
self.theIndex.reIndexHandle(sHandle)
# Trigger dependent updates
self._setTreeChanged(True)
self._emitItemChange(sHandle)
else:
theEvent.ignore()
logger.debug("Drag'n'drop of item %s not accepted" % sHandle)
@@ -915,7 +926,6 @@ class GuiProjectTree(QTreeWidget):
pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
nwItemS.setParent(pHandle)
self.setTreeItemValues(tHandle)
self._setTreeChanged(True)
logger.debug("The parent of item %s has been changed to %s" % (tHandle, pHandle))
@@ -930,6 +940,21 @@ class GuiProjectTree(QTreeWidget):
self.theProject.setProjectChanged(True)
return
def _emitItemChange(self, tHandle):
"""Emit an item change signal for a given handle.
"""
nwItem = self.theProject.projTree[tHandle]
if nwItem is None:
return
if nwItem.itemType == nwItemType.FILE:
if nwItem.itemClass == nwItemClass.NOVEL:
self.novelItemChanged.emit()
else:
self.noteItemChanged.emit()
return
# END Class GuiProjectTree
class GuiProjectTreeMenu(QMenu):
+27 -2
View File
@@ -32,7 +32,7 @@ import os
from datetime import datetime
from time import time
from PyQt5.QtCore import Qt, QTimer, QThreadPool
from PyQt5.QtCore import Qt, QTimer, QThreadPool, pyqtSlot
from PyQt5.QtGui import QIcon, QPixmap, QColor, QKeySequence, QCursor
from PyQt5.QtWidgets import (
qApp, QMainWindow, QVBoxLayout, QWidget, QSplitter, QFileDialog, QShortcut,
@@ -193,6 +193,7 @@ class GuiMain(QMainWindow):
# Initialise the Project Tree
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
self.treeView.novelItemChanged.connect(self._treeNovelItemChanged)
self.rebuildTrees()
# Set Main Window Elements
@@ -1319,9 +1320,10 @@ class GuiMain(QMainWindow):
return
##
# Signal Handlers
# Slots
##
@pyqtSlot()
def _treeSingleClick(self):
"""Single click on a project tree item just updates the details
panel below the tree.
@@ -1331,12 +1333,14 @@ class GuiMain(QMainWindow):
self.treeMeta.updateViewBox(sHandle)
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 do nothing.
"""
tHandle = tItem.data(self.treeView.C_NAME, Qt.UserRole)
logger.verbose("User double clicked tree item with handle %s" % tHandle)
nwItem = self.theProject.projTree[tHandle]
if nwItem is not None:
if nwItem.itemType == nwItemType.FILE:
@@ -1347,6 +1351,20 @@ class GuiMain(QMainWindow):
return
@pyqtSlot()
def _treeNovelItemChanged(self):
"""Triggered when there is a change to a novel item in the
project tree.
"""
if self.mainTabs.currentIndex() == self.idxTabProj:
logger.verbose("Novel tree changed while Outline tab active")
if self.hasProject:
self.treeView.flushTreeOrder()
self.projView.refreshTree(novelChanged=True)
return
@pyqtSlot()
def _treeKeyPressReturn(self):
"""The user pressed return on an item in the tree. If it is a
file, we open it. Otherwise, we do nothing. Pressing return does
@@ -1354,6 +1372,7 @@ class GuiMain(QMainWindow):
"""
tHandle = self.treeView.getSelectedHandle()
logger.verbose("User pressed return on tree item with handle %s" % tHandle)
nwItem = self.theProject.projTree[tHandle]
if nwItem is not None:
if nwItem.itemType == nwItemType.FILE:
@@ -1361,8 +1380,10 @@ class GuiMain(QMainWindow):
self.openDocument(tHandle, changeFocus=False, doScroll=False)
else:
logger.verbose("Requested item %s is a folder" % tHandle)
return
@pyqtSlot()
def _keyPressEscape(self):
"""When the escape key is pressed somewhere in the main window,
do the following, in order:
@@ -1371,8 +1392,10 @@ class GuiMain(QMainWindow):
self.docEditor.closeSearch()
elif self.isFocusMode:
self.toggleFocusMode()
return
@pyqtSlot(int)
def _mainTabChanged(self, tabIndex):
"""Activated when the main window tab is changed.
"""
@@ -1382,8 +1405,10 @@ class GuiMain(QMainWindow):
logger.verbose("Project outline tab activated")
if self.hasProject:
self.projView.refreshTree()
return
@pyqtSlot(int)
def _projTabsChanged(self, tabIndex):
"""Activated when the project view tab is changed.
"""