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