Add Table of Contents to build dialog

This commit is contained in:
Veronica Berglyd Olsen
2023-06-05 21:49:30 +02:00
parent 18df119332
commit b0201c58e9
5 changed files with 79 additions and 57 deletions
-8
View File
@@ -72,9 +72,6 @@ SETTINGS_TEMPLATE = {
"format.replaceTabs": (bool, False), "format.replaceTabs": (bool, False),
"odt.addColours": (bool, True), "odt.addColours": (bool, True),
"html.addStyles": (bool, False), "html.addStyles": (bool, False),
"build.splitNovel": (bool, False),
"build.splitNotes": (bool, False),
"build.splitChapters": (bool, False),
} }
SETTINGS_LABELS = { SETTINGS_LABELS = {
@@ -115,11 +112,6 @@ SETTINGS_LABELS = {
"html": QT_TRANSLATE_NOOP("Builds", "HTML"), "html": QT_TRANSLATE_NOOP("Builds", "HTML"),
"html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"), "html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"),
"build": QT_TRANSLATE_NOOP("Builds", "Build Options"),
"build.splitNovel": QT_TRANSLATE_NOOP("Builds", "Split Novel Root Folders"),
"build.splitNotes": QT_TRANSLATE_NOOP("Builds", "Split Note Root Folders"),
"build.splitChapters": QT_TRANSLATE_NOOP("Builds", "Split By Chapter Document"),
} }
+1 -1
View File
@@ -64,7 +64,7 @@ VALID_MAP = {
"winWidth", "winHeight", "optsWidth", "viewWidth" "winWidth", "winHeight", "optsWidth", "viewWidth"
}, },
"GuiManuscriptBuild": { "GuiManuscriptBuild": {
"winWidth", "winHeight", "fmtWidth", "optsWidth" "winWidth", "winHeight", "fmtWidth", "sumWidth"
}, },
} }
+62 -33
View File
@@ -27,9 +27,9 @@ import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtCore import QSize, Qt, pyqtSlot
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAbstractButton, QDialog, QDialogButtonBox, QFrame, QGridLayout, QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QGridLayout,
QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem, QProgressBar, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem, QProgressBar,
QPushButton, QSplitter, QVBoxLayout, QWidget QPushButton, QSplitter, QVBoxLayout, QWidget
) )
@@ -37,8 +37,8 @@ from PyQt5.QtWidgets import (
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.common import makeFileNameSafe from novelwriter.common import makeFileNameSafe
from novelwriter.constants import nwLabels from novelwriter.constants import nwLabels
from novelwriter.core.item import NWItem
from novelwriter.core.buildsettings import BuildSettings from novelwriter.core.buildsettings import BuildSettings
from novelwriter.extensions.switchbox import NSwitchBox
if TYPE_CHECKING: if TYPE_CHECKING:
from novelwriter.guimain import GuiMain from novelwriter.guimain import GuiMain
@@ -70,8 +70,9 @@ class GuiManuscriptBuild(QDialog):
self.setWindowTitle(self.tr("Build Manuscript")) self.setWindowTitle(self.tr("Build Manuscript"))
self.setMinimumWidth(CONFIG.pxInt(500)) self.setMinimumWidth(CONFIG.pxInt(500))
self.setMinimumHeight(CONFIG.pxInt(250)) self.setMinimumHeight(CONFIG.pxInt(300))
iPx = self.mainTheme.baseIconSize
wWin = CONFIG.pxInt(660) wWin = CONFIG.pxInt(660)
hWin = CONFIG.pxInt(390) hWin = CONFIG.pxInt(390)
@@ -81,11 +82,12 @@ class GuiManuscriptBuild(QDialog):
CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "winHeight", hWin)) CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "winHeight", hWin))
) )
# Formats # Output Format
# ======= # =============
self.lblFormat = QLabel("<b>{0}</b>".format(self.tr("Build Format"))) self.lblFormat = QLabel(self.tr("Output Format"))
self.listFormats = QListWidget() self.listFormats = QListWidget()
self.listFormats.setIconSize(QSize(iPx, iPx))
current = None current = None
for key, (_, label) in nwLabels.BUILD_FORMATS.items(): for key, (_, label) in nwLabels.BUILD_FORMATS.items():
item = QListWidgetItem() item = QListWidgetItem()
@@ -106,28 +108,23 @@ class GuiManuscriptBuild(QDialog):
self.formatWidget.setLayout(self.formatBox) self.formatWidget.setLayout(self.formatBox)
self.formatWidget.setContentsMargins(0, 0, 0, 0) self.formatWidget.setContentsMargins(0, 0, 0, 0)
# Build Controls # Table of Contents
# ============== # =================
# Build Options self.lblContent = QLabel(self.tr("Table of Contents"))
self.swtOptions = NSwitchBox(self, self.mainTheme.baseIconSize)
self.swtOptions.switchToggled.connect(self._applyBuildOptions)
self.swtOptions.setFrameStyle(QFrame.NoFrame)
self.swtOptions.setInnerContentsMargins(0, 0, 0, 0)
self.swtOptions.addLabel(self._build.getLabel("build")) self.listContent = QListWidget(self)
self.swtOptions.addItem( self.listContent.setIconSize(QSize(iPx, iPx))
self.mainTheme.getIcon("cls_novel"), self._build.getLabel("build.splitNovel"), self.listContent.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
"build.splitNovel", default=self._build.getBool("build.splitNovel")
) self.contentBox = QVBoxLayout()
self.swtOptions.addItem( self.contentBox.addWidget(self.lblContent, 0)
self.mainTheme.getIcon("cls_custom"), self._build.getLabel("build.splitNotes"), self.contentBox.addWidget(self.listContent, 0)
"build.splitNotes", default=self._build.getBool("build.splitNotes") self.contentBox.setContentsMargins(0, 0, 0, 0)
)
self.swtOptions.addItem( self.contentWidget = QWidget()
self.mainTheme.getIcon("proj_chapter"), self._build.getLabel("build.splitChapters"), self.contentWidget.setLayout(self.contentBox)
"build.splitChapters", default=self._build.getBool("build.splitChapters") self.contentWidget.setContentsMargins(0, 0, 0, 0)
)
# Dialog Controls # Dialog Controls
# =============== # ===============
@@ -168,6 +165,7 @@ class GuiManuscriptBuild(QDialog):
# Build Progress # Build Progress
self.lblProgress = QLabel(self.tr("Build Progress")) self.lblProgress = QLabel(self.tr("Build Progress"))
self.buildProgress = QProgressBar() self.buildProgress = QProgressBar()
self.buildProgress.setValue(0)
# Dialog Buttons # Dialog Buttons
self.btnBuild = QPushButton(self.mainTheme.getIcon("export"), self.tr("&Build")) self.btnBuild = QPushButton(self.mainTheme.getIcon("export"), self.tr("&Build"))
@@ -180,13 +178,13 @@ class GuiManuscriptBuild(QDialog):
self.mainSplit = QSplitter() self.mainSplit = QSplitter()
self.mainSplit.addWidget(self.formatWidget) self.mainSplit.addWidget(self.formatWidget)
self.mainSplit.addWidget(self.swtOptions) self.mainSplit.addWidget(self.contentWidget)
self.mainSplit.setHandleWidth(CONFIG.pxInt(16)) self.mainSplit.setHandleWidth(CONFIG.pxInt(16))
self.mainSplit.setCollapsible(0, False) self.mainSplit.setCollapsible(0, False)
self.mainSplit.setCollapsible(1, False) self.mainSplit.setCollapsible(1, False)
self.mainSplit.setSizes([ self.mainSplit.setSizes([
CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "fmtWidth", int(0.45*wWin))), CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "fmtWidth", wWin//2)),
CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "optsWidth", int(0.55*wWin))), CONFIG.pxInt(pOptions.getInt("GuiManuscriptBuild", "sumWidth", wWin//2)),
]) ])
self.outerBox = QGridLayout() self.outerBox = QGridLayout()
@@ -200,6 +198,7 @@ class GuiManuscriptBuild(QDialog):
self.outerBox.addWidget(self.lblProgress, 5, 0, 1, 1) self.outerBox.addWidget(self.lblProgress, 5, 0, 1, 1)
self.outerBox.addWidget(self.buildProgress, 5, 1, 1, 1) self.outerBox.addWidget(self.buildProgress, 5, 1, 1, 1)
self.outerBox.addWidget(self.dlgButtons, 6, 0, 1, 2) self.outerBox.addWidget(self.dlgButtons, 6, 0, 1, 2)
self.outerBox.setRowStretch(2, 1)
self.setLayout(self.outerBox) self.setLayout(self.outerBox)
@@ -209,6 +208,7 @@ class GuiManuscriptBuild(QDialog):
self._doResetBuildName() self._doResetBuildName()
self.btnBuild.setFocus() self.btnBuild.setFocus()
self._populateContentList()
logger.debug("Ready: GuiManuscriptBuild") logger.debug("Ready: GuiManuscriptBuild")
@@ -294,16 +294,45 @@ class GuiManuscriptBuild(QDialog):
winHeight = CONFIG.rpxInt(self.height()) winHeight = CONFIG.rpxInt(self.height())
mainSplit = self.mainSplit.sizes() mainSplit = self.mainSplit.sizes()
fmtWidth = CONFIG.rpxInt(mainSplit[0]) fmtWidth = CONFIG.rpxInt(mainSplit[0])
optsWidth = CONFIG.rpxInt(mainSplit[1]) sumWidth = CONFIG.rpxInt(mainSplit[1])
pOptions = self.theProject.options pOptions = self.theProject.options
pOptions.setValue("GuiManuscriptBuild", "winWidth", winWidth) pOptions.setValue("GuiManuscriptBuild", "winWidth", winWidth)
pOptions.setValue("GuiManuscriptBuild", "winHeight", winHeight) pOptions.setValue("GuiManuscriptBuild", "winHeight", winHeight)
pOptions.setValue("GuiManuscriptBuild", "fmtWidth", fmtWidth) pOptions.setValue("GuiManuscriptBuild", "fmtWidth", fmtWidth)
pOptions.setValue("GuiManuscriptBuild", "optsWidth", optsWidth) pOptions.setValue("GuiManuscriptBuild", "sumWidth", sumWidth)
pOptions.saveSettings() pOptions.saveSettings()
return return
def _populateContentList(self):
"""Build the content list."""
rootMap = {}
filtered = self._build.buildItemFilter(self.theProject)
self.listContent.clear()
for nwItem in self.theProject.tree:
tHandle = nwItem.itemHandle
rHandle = nwItem.itemRoot
if tHandle is None or rHandle is None or not nwItem.isFileType():
continue
if filtered.get(tHandle, (False, 0))[0]:
if rHandle not in rootMap:
rItem = self.theProject.tree[rHandle]
if isinstance(rItem, NWItem):
rootMap[rHandle] = rItem.itemName
itemIcon = self.mainTheme.getItemIcon(
nwItem.itemType, nwItem.itemClass,
nwItem.itemLayout, nwItem.mainHeading
)
rootName = rootMap.get(rHandle, "??????")
item = QListWidgetItem(f"{rootName}: {nwItem.itemName}")
item.setIcon(itemIcon)
self.listContent.addItem(item)
return
# END Class GuiManuscriptBuild # END Class GuiManuscriptBuild
+9 -6
View File
@@ -144,9 +144,12 @@ class GuiManuscript(QDialog):
# ================ # ================
self.buildProgress = QProgressBar() self.buildProgress = QProgressBar()
self.buildProgress.setValue(0)
self.btnPreview = QPushButton(self.tr("Build Preview")) self.btnPreview = QPushButton(self.tr("Build Preview"))
self.btnPreview.clicked.connect(self._generatePreview) self.btnPreview.clicked.connect(self._generatePreview)
self.manPreview = _PreviewWidget(self.mainGui)
self.docPreview = _PreviewWidget(self.mainGui)
self.btnBuild = QPushButton(self.tr("Build")) self.btnBuild = QPushButton(self.tr("Build"))
self.btnBuild.clicked.connect(self._buildManuscript) self.btnBuild.clicked.connect(self._buildManuscript)
@@ -182,7 +185,7 @@ class GuiManuscript(QDialog):
self.mainSplit = QSplitter() self.mainSplit = QSplitter()
self.mainSplit.addWidget(self.optsWidget) self.mainSplit.addWidget(self.optsWidget)
self.mainSplit.addWidget(self.manPreview) self.mainSplit.addWidget(self.docPreview)
self.mainSplit.setSizes([ self.mainSplit.setSizes([
CONFIG.pxInt(pOptions.getInt("GuiManuscript", "optsWidth", wWin//3)), CONFIG.pxInt(pOptions.getInt("GuiManuscript", "optsWidth", wWin//3)),
CONFIG.pxInt(pOptions.getInt("GuiManuscript", "viewWidth", 2*wWin//3)), CONFIG.pxInt(pOptions.getInt("GuiManuscript", "viewWidth", 2*wWin//3)),
@@ -338,13 +341,13 @@ class GuiManuscript(QDialog):
def _updatePreview(self, data: dict, build: BuildSettings): def _updatePreview(self, data: dict, build: BuildSettings):
"""Update the preview widget and set relevant values.""" """Update the preview widget and set relevant values."""
self.manPreview.setContent(data) self.docPreview.setContent(data)
self.manPreview.setBuildName(build.name) self.docPreview.setBuildName(build.name)
self.manPreview.setTextFont( self.docPreview.setTextFont(
build.getStr("format.textFont"), build.getStr("format.textFont"),
build.getInt("format.textSize") build.getInt("format.textSize")
) )
self.manPreview.setJustify( self.docPreview.setJustify(
build.getBool("format.justifyText") build.getBool("format.justifyText")
) )
return return
+7 -9
View File
@@ -435,11 +435,15 @@ class _FilterTab(QWidget):
logger.debug("Building project tree") logger.debug("Building project tree")
self._treeMap = {} self._treeMap = {}
self.optTree.clear() self.optTree.clear()
for nwItem in self.theProject.getProjectItems(): for nwItem in self.theProject.tree:
tHandle = nwItem.itemHandle tHandle = nwItem.itemHandle
pHandle = nwItem.itemParent pHandle = nwItem.itemParent
rHandle = nwItem.itemRoot rHandle = nwItem.itemRoot
if tHandle is None or rHandle is None:
continue
isFile = nwItem.isFileType() isFile = nwItem.isFileType()
isActive = nwItem.isActive isActive = nwItem.isActive
@@ -465,16 +469,10 @@ class _FilterTab(QWidget):
trItem.setTextAlignment(self.C_NAME, Qt.AlignLeft) trItem.setTextAlignment(self.C_NAME, Qt.AlignLeft)
if pHandle is None: if pHandle is None and nwItem.isRootType():
if nwItem.isRootType(): self.optTree.addTopLevelItem(trItem)
self.optTree.addTopLevelItem(trItem)
else:
logger.debug("Skipping item '%s'", tHandle)
continue
elif pHandle in self._treeMap: elif pHandle in self._treeMap:
self._treeMap[pHandle].addChild(trItem) self._treeMap[pHandle].addChild(trItem)
else: else:
logger.debug("Skipping item '%s'", tHandle) logger.debug("Skipping item '%s'", tHandle)
continue continue