From 479478490e3e022ed745c7866c7dd1b89530b823 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Sat, 1 Oct 2022 22:02:00 +0200
Subject: [PATCH 1/2] Update the index to generate a ToC for a specific root
folder
---
novelwriter/core/index.py | 6 ++++--
tests/test_core/test_core_index.py | 12 ++++++------
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py
index 7ea713b6..e9491027 100644
--- a/novelwriter/core/index.py
+++ b/novelwriter/core/index.py
@@ -498,13 +498,15 @@ class NWIndex:
"""
return self._itemIndex.mainItemHeader(tHandle)
- def getTableOfContents(self, maxDepth, skipExcl=True):
+ def getTableOfContents(self, rootHandle, maxDepth, skipExcl=True):
"""Generate a table of contents up to a maximum depth.
"""
tOrder = []
tData = {}
pKey = None
- for tHandle, sTitle, hItem in self._itemIndex.iterNovelStructure(skipExcl=skipExcl):
+ for tHandle, sTitle, hItem in self._itemIndex.iterNovelStructure(
+ rootHandle=rootHandle, skipExcl=skipExcl
+ ):
tKey = f"{tHandle}:{sTitle}"
iLevel = nwHeaders.H_LEVEL.get(hItem.level, 0)
if iLevel > maxDepth:
diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py
index 8f126e56..14aaa9be 100644
--- a/tests/test_core/test_core_index.py
+++ b/tests/test_core/test_core_index.py
@@ -709,16 +709,16 @@ def testCoreIndex_ExtractData(mockGUI, fncDir, mockRnd):
assert theIndex.getNovelTitleCounts(skipExcl=True) == [0, 1, 2, 3, 0]
# Table of Contents
- assert theIndex.getTableOfContents(0, skipExcl=True) == []
- assert theIndex.getTableOfContents(1, skipExcl=True) == [
+ assert theIndex.getTableOfContents("0000000000010", 0, skipExcl=True) == []
+ assert theIndex.getTableOfContents("0000000000010", 1, skipExcl=True) == [
("0000000000014:T000001", 1, "New Novel", 15),
]
- assert theIndex.getTableOfContents(2, skipExcl=True) == [
+ assert theIndex.getTableOfContents("0000000000010", 2, skipExcl=True) == [
("0000000000014:T000001", 1, "New Novel", 5),
("0000000000016:T000001", 2, "New Chapter", 4),
("%s:T000001" % hHandle, 2, "Chapter One", 6),
]
- assert theIndex.getTableOfContents(3, skipExcl=True) == [
+ assert theIndex.getTableOfContents("0000000000010", 3, skipExcl=True) == [
("0000000000014:T000001", 1, "New Novel", 5),
("0000000000016:T000001", 2, "New Chapter", 2),
("0000000000017:T000001", 3, "New Scene", 2),
@@ -727,8 +727,8 @@ def testCoreIndex_ExtractData(mockGUI, fncDir, mockRnd):
("%s:T000001" % tHandle, 3, "Scene Two", 2),
]
- assert theIndex.getTableOfContents(0, skipExcl=False) == []
- assert theIndex.getTableOfContents(1, skipExcl=False) == [
+ assert theIndex.getTableOfContents("0000000000010", 0, skipExcl=False) == []
+ assert theIndex.getTableOfContents("0000000000010", 1, skipExcl=False) == [
("0000000000014:T000001", 1, "New Novel", 9),
("%s:T000001" % nHandle, 1, "Hello World!", 12),
("%s:T000011" % nHandle, 1, "Hello World!", 22),
From 534614d0371c5fe6205ff29f92f800503316dcc9 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Sat, 1 Oct 2022 22:02:24 +0200
Subject: [PATCH 2/2] Add a root folder combo box to the Project Details dialog
---
novelwriter/dialogs/projdetails.py | 66 +++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 10 deletions(-)
diff --git a/novelwriter/dialogs/projdetails.py b/novelwriter/dialogs/projdetails.py
index e83fc0a4..7b23498a 100644
--- a/novelwriter/dialogs/projdetails.py
+++ b/novelwriter/dialogs/projdetails.py
@@ -27,15 +27,17 @@ import math
import logging
import novelwriter
-from PyQt5.QtCore import Qt, QSize
+from PyQt5.QtCore import Qt, QSize, pyqtSlot
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import (
- QWidget, QDialogButtonBox, QVBoxLayout, QTreeWidget, QTreeWidgetItem,
- QLabel, QSpinBox, QGridLayout, QHBoxLayout, QLineEdit, QAbstractItemView
+ QAbstractItemView, QComboBox, QDialogButtonBox, QGridLayout, QHBoxLayout,
+ QLabel, QLineEdit, QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
+ QWidget
)
+from novelwriter.enum import nwItemClass
from novelwriter.common import numberToRoman
-from novelwriter.constants import nwUnicode
+from novelwriter.constants import nwLabels, nwUnicode
from novelwriter.gui.custom import PagedDialog, QSwitch
logger = logging.getLogger(__name__)
@@ -281,12 +283,26 @@ class GuiProjectDetailsContents(QWidget):
# Internal
self._theToC = []
+ self._currentRoot = None
iPx = self.mainTheme.baseIconSize
hPx = self.mainConf.pxInt(12)
vPx = self.mainConf.pxInt(4)
pOptions = self.theProject.options
+ # Header
+ # ======
+
+ self.tocLabel = QLabel("%s" % self.tr("Table of Contents"))
+
+ self.novelValue = QComboBox(self)
+ self.novelValue.setMinimumWidth(self.mainConf.pxInt(200))
+ self.novelValue.currentIndexChanged.connect(self._novelValueChanged)
+
+ self.headBox = QHBoxLayout()
+ self.headBox.addWidget(self.tocLabel)
+ self.headBox.addWidget(self.novelValue)
+
# Contents Tree
# =============
@@ -389,7 +405,7 @@ class GuiProjectDetailsContents(QWidget):
# ========
self.outerBox = QVBoxLayout()
- self.outerBox.addWidget(QLabel("%s" % self.tr("Table of Contents")))
+ self.outerBox.addLayout(self.headBox)
self.outerBox.addWidget(self.tocTree)
self.outerBox.addLayout(self.optionsBox)
@@ -412,19 +428,37 @@ class GuiProjectDetailsContents(QWidget):
def updateValues(self):
"""Populate the tree.
"""
- self._prepareData()
+ self._currentRoot = None
+ self._populateNovelList()
+
+ rootHandle = self.novelValue.currentData()
+ self._prepareData(rootHandle)
self._populateTree()
+
return
##
# Internal Functions
##
- def _prepareData(self):
- """Extract the data for the tree.
+ def _populateNovelList(self):
+ """Fill the novel combo box with a list of all novel folders.
"""
- self._theToC = []
- self._theToC = self.theProject.index.getTableOfContents(2)
+ self.novelValue.clear()
+
+ tIcon = self.mainTheme.getIcon(nwLabels.CLASS_ICON[nwItemClass.NOVEL])
+ for tHandle, nwItem in self.theProject.tree.iterRoots(nwItemClass.NOVEL):
+ self.novelValue.addItem(tIcon, nwItem.itemName, tHandle)
+
+ self.novelValue.setVisible(self.novelValue.count() > 1)
+
+ return
+
+ def _prepareData(self, rootHandle):
+ """Extract the information from the project index.
+ """
+ logger.debug("Populating ToC from handle '%s'", rootHandle)
+ self._theToC = self.theProject.index.getTableOfContents(rootHandle, 2)
self._theToC.append(("", 0, self.tr("END"), 0))
return
@@ -432,6 +466,18 @@ class GuiProjectDetailsContents(QWidget):
# Slots
##
+ @pyqtSlot()
+ def _novelValueChanged(self):
+ """Refresh the tree with another root item.
+ """
+ rootHandle = self.novelValue.currentData()
+ if rootHandle != self._currentRoot:
+ self._prepareData(rootHandle)
+ self._populateTree()
+ self._currentRoot = rootHandle
+ return
+
+ @pyqtSlot()
def _populateTree(self):
"""Set the content of the chapter/page tree.
"""