Add a quick links dropdown menu to the project tree (#1137)
This commit is contained in:
@@ -274,11 +274,13 @@ class NWTree:
|
||||
return rootClasses
|
||||
|
||||
def iterRoots(self, itemClass):
|
||||
"""Iterate over all items of a given class.
|
||||
"""Iterate over all root items of a given class in order.
|
||||
"""
|
||||
for tHandle, nwItem in self._treeRoots.items():
|
||||
if nwItem.itemClass == itemClass:
|
||||
yield tHandle, nwItem
|
||||
for tHandle in self._treeOrder:
|
||||
nwItem = self.__getitem__(tHandle)
|
||||
if nwItem is not None and nwItem.isRootType():
|
||||
if itemClass is None or nwItem.itemClass == itemClass:
|
||||
yield tHandle, nwItem
|
||||
return
|
||||
|
||||
def isRoot(self, tHandle):
|
||||
|
||||
+80
-12
@@ -121,18 +121,33 @@ class GuiProjectView(QWidget):
|
||||
##
|
||||
|
||||
def initSettings(self):
|
||||
"""Initialise GUI elements that depend on specific settings.
|
||||
"""
|
||||
self.projTree.initSettings()
|
||||
return
|
||||
|
||||
def clearProject(self):
|
||||
"""Clear project-related GUI content.
|
||||
"""
|
||||
self.projBar.clearContent()
|
||||
self.projTree.clearTree()
|
||||
return
|
||||
|
||||
def saveProjectTree(self):
|
||||
def openProjectTasks(self):
|
||||
"""Run open project tasks.
|
||||
"""
|
||||
self.projBar.buildQuickLinkMenu()
|
||||
return
|
||||
|
||||
def saveProjectTasks(self):
|
||||
"""Run save project tasks.
|
||||
"""
|
||||
self.projTree.saveTreeOrder()
|
||||
return
|
||||
|
||||
def populateTree(self):
|
||||
"""Build the tree structure from project data.
|
||||
"""
|
||||
self.projTree.buildTree()
|
||||
return
|
||||
|
||||
@@ -159,6 +174,13 @@ class GuiProjectView(QWidget):
|
||||
self.wordCountsChanged.emit()
|
||||
return
|
||||
|
||||
@pyqtSlot(str)
|
||||
def updateRootItem(self, tHandle):
|
||||
"""If any root item changes, rebuild the quick link root menu.
|
||||
"""
|
||||
self.projBar.buildQuickLinkMenu()
|
||||
return
|
||||
|
||||
# END Class GuiProjectView
|
||||
|
||||
|
||||
@@ -197,6 +219,18 @@ class GuiProjectToolBar(QWidget):
|
||||
self.viewLabel.setContentsMargins(0, 0, 0, 0)
|
||||
self.viewLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
|
||||
# Quick Links
|
||||
self.mQuick = QMenu()
|
||||
|
||||
self.tbQuick = QToolButton(self)
|
||||
self.tbQuick.setToolTip("%s [Ctrl+L]" % self.tr("Quick Links"))
|
||||
self.tbQuick.setShortcut("Ctrl+L")
|
||||
self.tbQuick.setIcon(self.mainTheme.getIcon("bookmark"))
|
||||
self.tbQuick.setIconSize(QSize(iPx, iPx))
|
||||
self.tbQuick.setStyleSheet(buttonStyle)
|
||||
self.tbQuick.setMenu(self.mQuick)
|
||||
self.tbQuick.setPopupMode(QToolButton.InstantPopup)
|
||||
|
||||
# Move Buttons
|
||||
self.tbMoveU = QToolButton(self)
|
||||
self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up"))
|
||||
@@ -292,6 +326,7 @@ class GuiProjectToolBar(QWidget):
|
||||
# Assemble
|
||||
self.outerBox = QHBoxLayout()
|
||||
self.outerBox.addWidget(self.viewLabel)
|
||||
self.outerBox.addWidget(self.tbQuick)
|
||||
self.outerBox.addWidget(self.tbMoveU)
|
||||
self.outerBox.addWidget(self.tbMoveD)
|
||||
self.outerBox.addWidget(self.tbAdd)
|
||||
@@ -305,6 +340,32 @@ class GuiProjectToolBar(QWidget):
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Methods
|
||||
##
|
||||
|
||||
def clearContent(self):
|
||||
"""Clear dynamic content on the tool bar.
|
||||
"""
|
||||
self.mQuick.clear()
|
||||
return
|
||||
|
||||
def buildQuickLinkMenu(self):
|
||||
"""Build the quick link menu.
|
||||
"""
|
||||
logger.verbose("Rebuilding quick links menu")
|
||||
|
||||
self.mQuick.clear()
|
||||
for n, (tHandle, nwItem) in enumerate(self.theProject.tree.iterRoots(None)):
|
||||
aRoot = self.mQuick.addAction(nwItem.itemName)
|
||||
aRoot.setData(tHandle)
|
||||
aRoot.setIcon(self.mainTheme.getIcon(nwLabels.CLASS_ICON[nwItem.itemClass]))
|
||||
aRoot.triggered.connect(
|
||||
lambda n, tHandle=tHandle: self.projView.setSelectedHandle(tHandle, doScroll=True)
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
@@ -545,8 +606,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
self._treeMap[pHandle].setExpanded(True)
|
||||
|
||||
self._alertTreeChange(tHandle, flush=True)
|
||||
self.clearSelection()
|
||||
trItem.setSelected(True)
|
||||
self.setCurrentItem(trItem)
|
||||
|
||||
return True
|
||||
|
||||
@@ -585,8 +645,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
self._recordLastMove(cItem, pItem, tIndex)
|
||||
|
||||
self._alertTreeChange(tHandle, flush=True)
|
||||
self.clearSelection()
|
||||
trItem.setSelected(True)
|
||||
self.setCurrentItem(trItem)
|
||||
trItem.setExpanded(isExp)
|
||||
|
||||
return True
|
||||
@@ -790,6 +849,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
self._treeMap.pop(tHandle, None)
|
||||
self._alertTreeChange(tHandle, flush=True)
|
||||
|
||||
# These are not emitted by the alert function because the
|
||||
# item has already been deleted
|
||||
self.projView.rootFolderChanged.emit(tHandle)
|
||||
self.projView.treeItemChanged.emit(tHandle)
|
||||
|
||||
else:
|
||||
if askFirst:
|
||||
msgYes = self.mainGui.askQuestion(
|
||||
@@ -817,6 +881,10 @@ class GuiProjectTree(QTreeWidget):
|
||||
self._alertTreeChange(tHandle, flush=flush)
|
||||
self.projView.wordCountsChanged.emit()
|
||||
|
||||
# This is not emitted by the alert function because the item
|
||||
# has already been deleted
|
||||
self.projView.treeItemChanged.emit(tHandle)
|
||||
|
||||
return True
|
||||
|
||||
def setTreeItemValues(self, tHandle):
|
||||
@@ -945,8 +1013,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
self._postItemMove(sHandle, wCount)
|
||||
self._alertTreeChange(sHandle, flush=True)
|
||||
|
||||
self.clearSelection()
|
||||
movItem.setSelected(True)
|
||||
self.setCurrentItem(movItem)
|
||||
self._lastMove = {}
|
||||
|
||||
return True
|
||||
@@ -968,12 +1035,13 @@ class GuiProjectTree(QTreeWidget):
|
||||
if tItem is None:
|
||||
return False
|
||||
|
||||
self.clearSelection()
|
||||
self._treeMap[tHandle].setSelected(True)
|
||||
self.setFocus()
|
||||
if tHandle in self._treeMap:
|
||||
self.setCurrentItem(self._treeMap[tHandle])
|
||||
|
||||
selItems = self.selectedIndexes()
|
||||
if selItems and doScroll:
|
||||
self.scrollTo(selItems[0], QAbstractItemView.PositionAtCenter)
|
||||
selIndex = self.selectedIndexes()
|
||||
if selIndex and doScroll:
|
||||
self.scrollTo(selIndex[0], QAbstractItemView.PositionAtCenter)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -206,6 +206,7 @@ class GuiMain(QMainWindow):
|
||||
self.projView.treeItemChanged.connect(self.itemDetails.updateViewBox)
|
||||
self.projView.rootFolderChanged.connect(self.outlineView.updateRootItem)
|
||||
self.projView.rootFolderChanged.connect(self.novelView.updateRootItem)
|
||||
self.projView.rootFolderChanged.connect(self.projView.updateRootItem)
|
||||
|
||||
self.novelView.selectedItemChanged.connect(self.itemDetails.updateViewBox)
|
||||
self.novelView.openDocumentRequest.connect(self._openDocument)
|
||||
@@ -370,6 +371,7 @@ class GuiMain(QMainWindow):
|
||||
self.saveProject()
|
||||
|
||||
self.docEditor.setDictionaries()
|
||||
self.projView.openProjectTasks()
|
||||
self.novelView.openProjectTasks()
|
||||
self.outlineView.openProjectTasks()
|
||||
self.rebuildIndex(beQuiet=True)
|
||||
@@ -522,6 +524,7 @@ class GuiMain(QMainWindow):
|
||||
self.docEditor.setDictionaries()
|
||||
self.docEditor.toggleSpellCheck(self.theProject.spellCheck)
|
||||
self.statusBar.setRefTime(self.theProject.projOpened)
|
||||
self.projView.openProjectTasks()
|
||||
self.novelView.openProjectTasks()
|
||||
self.outlineView.openProjectTasks()
|
||||
self._updateStatusWordCount()
|
||||
@@ -556,7 +559,7 @@ class GuiMain(QMainWindow):
|
||||
logger.error("No project open")
|
||||
return False
|
||||
|
||||
self.projView.saveProjectTree()
|
||||
self.projView.saveProjectTasks()
|
||||
if self.theProject.saveProject(autoSave=autoSave):
|
||||
self.theProject.index.saveIndex()
|
||||
|
||||
@@ -841,7 +844,7 @@ class GuiMain(QMainWindow):
|
||||
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
tStart = time()
|
||||
|
||||
self.projView.saveProjectTree()
|
||||
self.projView.saveProjectTasks()
|
||||
self.theProject.index.clearIndex()
|
||||
|
||||
for tItem in self.theProject.tree:
|
||||
|
||||
Reference in New Issue
Block a user