Simplify build settings dialog

This commit is contained in:
Veronica Berglyd Olsen
2023-05-22 16:25:33 +02:00
parent a212900554
commit 0a2355488e
4 changed files with 50 additions and 84 deletions
+6 -6
View File
@@ -205,13 +205,13 @@ class nwLabels:
class nwHeadingFormats: class nwHeadingFormats:
TITLE = "{Title}" TITLE = "{Title}"
CH_NUM = "{Chapter}" CH_NUM = "{Chapter}"
CH_WORD = "{Chapter:Word}" CH_WORD = "{Chapter:Word}"
CH_ROMU = "{Chapter:RomanU}" CH_ROMU = "{Chapter:URoman}"
CH_ROML = "{Chapter:RomanL}" CH_ROML = "{Chapter:LRoman}"
SC_NUM = "{Scene}" SC_NUM = "{Scene}"
SC_ABS = "{Scene:Abs}" SC_ABS = "{Scene:Abs}"
# END Class nwHeadingFormats # END Class nwHeadingFormats
+28 -25
View File
@@ -22,6 +22,7 @@ General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
from __future__ import annotations
import uuid import uuid
import logging import logging
@@ -59,7 +60,7 @@ SETTINGS_TEMPLATE = {
"text.includeBody": (bool, True), "text.includeBody": (bool, True),
"format.buildLang": (str, "en_GB"), "format.buildLang": (str, "en_GB"),
"format.textFont": (str, ""), "format.textFont": (str, ""),
"format.textSize": (str, ""), "format.textSize": (int, 12),
"format.lineHeight": (float, 1.15, 0.75, 3.0), "format.lineHeight": (float, 1.15, 0.75, 3.0),
"format.justifyText": (bool, False), "format.justifyText": (bool, False),
"format.stripUnicode": (bool, False), "format.stripUnicode": (bool, False),
@@ -119,7 +120,7 @@ class BuildSettings:
def __init__(self): def __init__(self):
self._name = "" self._name = ""
self._uuid = "" self._uuid = str(uuid.uuid4())
self._skipRoot = set() self._skipRoot = set()
self._excluded = set() self._excluded = set()
self._included = set() self._included = set()
@@ -132,15 +133,15 @@ class BuildSettings:
## ##
@property @property
def name(self): def name(self) -> str:
return self._name return self._name
@property @property
def buildID(self): def buildID(self) -> str:
return self._uuid return self._uuid
@property @property
def changed(self): def changed(self) -> bool:
return self._changed return self._changed
## ##
@@ -148,12 +149,12 @@ class BuildSettings:
## ##
@staticmethod @staticmethod
def getLabel(key): def getLabel(key: str) -> str:
"""Extract the label for a specific item. """Extract the label for a specific item.
""" """
return SETTINGS_LABELS.get(key, "ERROR") return SETTINGS_LABELS.get(key, "ERROR")
def getValue(self, key): def getValue(self, key: str) -> str | int | bool | float:
"""Get the value for a specific item, or return the default. """Get the value for a specific item, or return the default.
""" """
return self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None)[1])) return self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None)[1]))
@@ -162,13 +163,13 @@ class BuildSettings:
# Setters # Setters
## ##
def setName(self, name): def setName(self, name: str):
"""Set the build setting display name. """Set the build setting display name.
""" """
self._name = str(name) self._name = str(name)
return return
def setBuildID(self, value): def setBuildID(self, value: str | uuid.UUID):
"""Set a UUID build ID. """Set a UUID build ID.
""" """
value = checkUuid(value, "") value = checkUuid(value, "")
@@ -178,7 +179,7 @@ class BuildSettings:
self._uuid = value self._uuid = value
return return
def setFiltered(self, tHandle): def setFiltered(self, tHandle: str):
"""Set an item as filtered. """Set an item as filtered.
""" """
self._excluded.discard(tHandle) self._excluded.discard(tHandle)
@@ -186,7 +187,7 @@ class BuildSettings:
self._changed = True self._changed = True
return return
def setIncluded(self, tHandle): def setIncluded(self, tHandle: str):
"""Set an item as explicitly included. """Set an item as explicitly included.
""" """
self._excluded.discard(tHandle) self._excluded.discard(tHandle)
@@ -194,7 +195,7 @@ class BuildSettings:
self._changed = True self._changed = True
return return
def setExcluded(self, tHandle): def setExcluded(self, tHandle: str):
"""Set an item as explicitly excluded. """Set an item as explicitly excluded.
""" """
self._excluded.add(tHandle) self._excluded.add(tHandle)
@@ -202,7 +203,7 @@ class BuildSettings:
self._changed = True self._changed = True
return return
def setSkipRoot(self, tHandle, state): def setSkipRoot(self, tHandle: str, state: bool):
"""Set a specific root folder as skipped or not. """Set a specific root folder as skipped or not.
""" """
if state is True: if state is True:
@@ -213,7 +214,7 @@ class BuildSettings:
self._changed = True self._changed = True
return return
def setValue(self, key, value): def setValue(self, key: str, value: str | int | bool | float) -> bool:
"""Set a specific value for a build setting. """Set a specific value for a build setting.
""" """
if key not in SETTINGS_TEMPLATE: if key not in SETTINGS_TEMPLATE:
@@ -232,32 +233,34 @@ class BuildSettings:
# Methods # Methods
## ##
def isFiltered(self, tHandle): def isFiltered(self, tHandle: str) -> bool:
return tHandle not in self._included and tHandle not in self._excluded return tHandle not in self._included and tHandle not in self._excluded
def isIncluded(self, tHandle): def isIncluded(self, tHandle: str) -> bool:
return tHandle in self._included return tHandle in self._included
def isExcluded(self, tHandle): def isExcluded(self, tHandle: str) -> bool:
return tHandle in self._excluded return tHandle in self._excluded
def isRootAllowed(self, tHandle): def isRootAllowed(self, tHandle: str) -> bool:
return tHandle not in self._skipRoot return tHandle not in self._skipRoot
def buildItemFilter(self, project): def buildItemFilter(self, project: NWProject) -> dict:
"""Return a dictionary of item handles with filter decissions """Return a dictionary of item handles with filter decissions
applied. applied.
""" """
result = {} result: dict[str, tuple[bool, FilterMode]] = {}
if not isinstance(project, NWProject): if not isinstance(project, NWProject):
return result return result
incNovel = self.getValue("filter.includeNovel") or False incNovel = bool(self.getValue("filter.includeNovel"))
incNotes = self.getValue("filter.includeNotes") or False incNotes = bool(self.getValue("filter.includeNotes"))
incInactive = self.getValue("filter.includeInactive") or False incInactive = bool(self.getValue("filter.includeInactive"))
for item in project.tree: for item in project.tree:
tHandle = item.itemHandle tHandle = item.itemHandle
if not tHandle:
continue
if not isinstance(item, NWItem): if not isinstance(item, NWItem):
result[tHandle] = (False, FilterMode.UNKNOWN) result[tHandle] = (False, FilterMode.UNKNOWN)
continue continue
@@ -294,7 +297,7 @@ class BuildSettings:
self._changed = False self._changed = False
return return
def pack(self): def pack(self) -> dict:
"""Pack all content into a JSON compatible dictionary. """Pack all content into a JSON compatible dictionary.
""" """
logger.debug("Collecting build setting for '%s'", self._name) logger.debug("Collecting build setting for '%s'", self._name)
@@ -307,7 +310,7 @@ class BuildSettings:
"skipRoot": list(self._skipRoot), "skipRoot": list(self._skipRoot),
} }
def unpack(self, data): def unpack(self, data: dict):
"""Unpack a dictionary and populate the class. """Unpack a dictionary and populate the class.
""" """
included = data.get("included", []) included = data.get("included", [])
+4 -2
View File
@@ -35,6 +35,7 @@ from PyQt5.QtWidgets import (
) )
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.core.buildsettings import BuildSettings
from novelwriter.tools.manussettings import GuiBuildSettings from novelwriter.tools.manussettings import GuiBuildSettings
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -121,9 +122,10 @@ class GuiBuildManuscript(QDialog):
def _createNewBuild(self): def _createNewBuild(self):
"""Open the build settings dialog for a new build. """Open the build settings dialog for a new build.
""" """
data = {"name": self.tr("My Manuscript")} build = BuildSettings()
build.setName(self.tr("My Manuscript"))
dlgSettings = GuiBuildSettings(self.mainGui, data) dlgSettings = GuiBuildSettings(self.mainGui, build)
dlgSettings.setModal(False) dlgSettings.setModal(False)
dlgSettings.show() dlgSettings.show()
dlgSettings.raise_() dlgSettings.raise_()
+12 -51
View File
@@ -57,13 +57,11 @@ class GuiBuildSettings(QDialog):
OPT_HEADINGS = 2 OPT_HEADINGS = 2
OPT_FORMAT = 3 OPT_FORMAT = 3
OPT_CONTENT = 4 OPT_CONTENT = 4
BLD_HTML = 5 OPT_OUTPUT = 5
BLD_MARKDOWN = 6
BLD_ODT = 7
newSettingsReady = pyqtSignal(dict) newSettingsReady = pyqtSignal(dict)
def __init__(self, mainGui: GuiMain, buildData: dict): def __init__(self, mainGui: GuiMain, build: BuildSettings):
super().__init__(parent=mainGui) super().__init__(parent=mainGui)
logger.debug("Initialising GuiBuildSettings ...") logger.debug("Initialising GuiBuildSettings ...")
@@ -73,8 +71,7 @@ class GuiBuildSettings(QDialog):
self.mainTheme = mainGui.mainTheme self.mainTheme = mainGui.mainTheme
self.theProject = mainGui.theProject self.theProject = mainGui.theProject
self._build = BuildSettings() self._build = build
self._build.unpack(buildData)
self.setWindowTitle(self.tr("Manuscript Build Settings")) self.setWindowTitle(self.tr("Manuscript Build Settings"))
self.setMinimumWidth(CONFIG.pxInt(700)) self.setMinimumWidth(CONFIG.pxInt(700))
@@ -98,17 +95,12 @@ class GuiBuildSettings(QDialog):
self.optSideBar.setMaximumWidth(mPx) self.optSideBar.setMaximumWidth(mPx)
self.optSideBar.setLabelColor(self.mainTheme.helpText) self.optSideBar.setLabelColor(self.mainTheme.helpText)
self.optSideBar.addLabel(self.tr("Content")) self.optSideBar.addLabel(self.tr("Options"))
self.optSideBar.addButton(self.tr("Filters"), self.OPT_FILTERS) self.optSideBar.addButton(self.tr("Filters"), self.OPT_FILTERS)
self.optSideBar.addButton(self.tr("Headings"), self.OPT_HEADINGS) self.optSideBar.addButton(self.tr("Headings"), self.OPT_HEADINGS)
self.optSideBar.addButton(self.tr("Format"), self.OPT_FORMAT) self.optSideBar.addButton(self.tr("Format"), self.OPT_FORMAT)
self.optSideBar.addButton(self.tr("Content"), self.OPT_CONTENT) self.optSideBar.addButton(self.tr("Content"), self.OPT_CONTENT)
self.optSideBar.addSeparator() self.optSideBar.addButton(self.tr("Output"), self.OPT_OUTPUT)
self.optSideBar.addLabel(self.tr("Output"))
self.optSideBar.addButton(self.tr("HTML"), self.BLD_HTML)
self.optSideBar.addButton(self.tr("Markdown"), self.BLD_MARKDOWN)
self.optSideBar.addButton(self.tr("Open Document"), self.BLD_ODT)
self.optSideBar.buttonClicked.connect(self._stackPageSelected) self.optSideBar.buttonClicked.connect(self._stackPageSelected)
@@ -120,9 +112,7 @@ class GuiBuildSettings(QDialog):
self.optTabHeadings = GuiBuildHeadingsTab(self, self._build) self.optTabHeadings = GuiBuildHeadingsTab(self, self._build)
self.optTabFormat = GuiBuildFormatTab(self, self._build) self.optTabFormat = GuiBuildFormatTab(self, self._build)
self.optTabContent = GuiBuildContentTab(self, self._build) self.optTabContent = GuiBuildContentTab(self, self._build)
self.buildTabHTML = GuiBuildHTMLTab(self, self._build) self.optTabOutput = GuiBuildOutputTab(self, self._build)
self.buildTabMarkdown = GuiBuildMarkdownTab(self, self._build)
self.buildTabODT = GuiBuildODTTab(self, self._build)
# Add Tabs # Add Tabs
self.toolStack = QStackedWidget(self) self.toolStack = QStackedWidget(self)
@@ -130,9 +120,7 @@ class GuiBuildSettings(QDialog):
self.toolStack.addWidget(self.optTabHeadings) self.toolStack.addWidget(self.optTabHeadings)
self.toolStack.addWidget(self.optTabFormat) self.toolStack.addWidget(self.optTabFormat)
self.toolStack.addWidget(self.optTabContent) self.toolStack.addWidget(self.optTabContent)
self.toolStack.addWidget(self.buildTabHTML) self.toolStack.addWidget(self.optTabOutput)
self.toolStack.addWidget(self.buildTabMarkdown)
self.toolStack.addWidget(self.buildTabODT)
# Main Settings + Buttons # Main Settings + Buttons
# ======================= # =======================
@@ -195,12 +183,8 @@ class GuiBuildSettings(QDialog):
self.toolStack.setCurrentWidget(self.optTabFormat) self.toolStack.setCurrentWidget(self.optTabFormat)
elif pageId == self.OPT_CONTENT: elif pageId == self.OPT_CONTENT:
self.toolStack.setCurrentWidget(self.optTabContent) self.toolStack.setCurrentWidget(self.optTabContent)
elif pageId == self.BLD_HTML: elif pageId == self.OPT_OUTPUT:
self.toolStack.setCurrentWidget(self.buildTabHTML) self.toolStack.setCurrentWidget(self.optTabOutput)
elif pageId == self.BLD_MARKDOWN:
self.toolStack.setCurrentWidget(self.buildTabMarkdown)
elif pageId == self.BLD_ODT:
self.toolStack.setCurrentWidget(self.buildTabODT)
return return
@pyqtSlot("QAbstractButton*") @pyqtSlot("QAbstractButton*")
@@ -212,6 +196,7 @@ class GuiBuildSettings(QDialog):
self._build.setName(self.editBuildName.text()) self._build.setName(self.editBuildName.text())
self.newSettingsReady.emit(self._build.pack()) self.newSettingsReady.emit(self._build.pack())
self._saveSettings()
if role == QDialogButtonBox.AcceptRole: if role == QDialogButtonBox.AcceptRole:
self.accept() self.accept()
elif role == QDialogButtonBox.RejectRole: elif role == QDialogButtonBox.RejectRole:
@@ -849,7 +834,7 @@ class GuiBuildContentTab(QWidget):
# END Class GuiBuildContentTab # END Class GuiBuildContentTab
class GuiBuildHTMLTab(QWidget): class GuiBuildOutputTab(QWidget):
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings):
super().__init__(parent=buildMain) super().__init__(parent=buildMain)
@@ -858,31 +843,7 @@ class GuiBuildHTMLTab(QWidget):
return return
# END Class GuiBuildHTMLTab # END Class GuiBuildOutputTab
class GuiBuildMarkdownTab(QWidget):
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings):
super().__init__(parent=buildMain)
self._build = build
return
# END Class GuiBuildMarkdownTab
class GuiBuildODTTab(QWidget):
def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings):
super().__init__(parent=buildMain)
self._build = build
return
# END Class GuiBuildODTTab
class GuiHeadingSyntax(QSyntaxHighlighter): class GuiHeadingSyntax(QSyntaxHighlighter):