Simplify build settings dialog
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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", [])
|
||||||
|
|||||||
@@ -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_()
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user