From c302162d1f55251cf39f0692fe020605ce2b8d57 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Tue, 23 May 2023 16:39:43 +0200 Subject: [PATCH] Add build settings Content and Format tabs --- novelwriter/constants.py | 4 + novelwriter/core/buildsettings.py | 46 ++-- novelwriter/core/docbuild.py | 9 +- novelwriter/tools/manussettings.py | 329 +++++++++++++++++++++++------ 4 files changed, 294 insertions(+), 94 deletions(-) diff --git a/novelwriter/constants.py b/novelwriter/constants.py index da807c6d..717f3cdb 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -23,6 +23,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ +from PyQt5.QtGui import QFontDatabase from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP from novelwriter.enum import nwItemClass, nwItemLayout, nwOutline @@ -53,6 +54,9 @@ class nwConst: URL_HELP = "https://github.com/vkbo/novelWriter/discussions" URL_RELEASE = "https://github.com/vkbo/novelWriter/releases/latest" + # System Values + SYSTEM_FONT = QFontDatabase.systemFont(QFontDatabase.GeneralFont).family() + # END Class nwConst diff --git a/novelwriter/core/buildsettings.py b/novelwriter/core/buildsettings.py index 91f97ebf..5704fd75 100644 --- a/novelwriter/core/buildsettings.py +++ b/novelwriter/core/buildsettings.py @@ -36,7 +36,7 @@ from pathlib import Path from PyQt5.QtCore import QT_TRANSLATE_NOOP from novelwriter.common import checkUuid, isHandle, jsonEncode -from novelwriter.constants import nwFiles, nwHeadingFormats +from novelwriter.constants import nwConst, nwFiles, nwHeadingFormats from novelwriter.core.item import NWItem from novelwriter.core.project import NWProject from novelwriter.error import logException @@ -62,10 +62,10 @@ SETTINGS_TEMPLATE = { "text.includeSynopsis": (bool, False), "text.includeComments": (bool, False), "text.includeKeywords": (bool, False), - "text.includeBody": (bool, True), + "text.includeBodyText": (bool, True), "text.addNoteHeadings": (bool, True), "format.buildLang": (str, "en_GB"), - "format.textFont": (str, ""), + "format.textFont": (str, nwConst.SYSTEM_FONT), "format.textSize": (int, 12), "format.lineHeight": (float, 1.15, 0.75, 3.0), "format.justifyText": (bool, False), @@ -82,26 +82,28 @@ SETTINGS_LABELS = { "filter.includeInactive": QT_TRANSLATE_NOOP("Builds", "Inactive Documents"), "headings": QT_TRANSLATE_NOOP("Builds", "Headings"), - "headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Title Heading"), - "headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Heading"), - "headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Heading"), - "headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Heading"), - "headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Heading"), - "headings.hideScene": QT_TRANSLATE_NOOP("Builds", "Hide Scene"), - "headings.hideSection": QT_TRANSLATE_NOOP("Builds", "Hide Section"), + "headings.fmtTitle": QT_TRANSLATE_NOOP("Builds", "Title Headings"), + "headings.fmtChapter": QT_TRANSLATE_NOOP("Builds", "Chapter Headings"), + "headings.fmtUnnumbered": QT_TRANSLATE_NOOP("Builds", "Unnumbered Headings"), + "headings.fmtScene": QT_TRANSLATE_NOOP("Builds", "Scene Headings"), + "headings.fmtSection": QT_TRANSLATE_NOOP("Builds", "Section Headings"), + "headings.hideScene": QT_TRANSLATE_NOOP("Builds", "Hide Scene Headings"), + "headings.hideSection": QT_TRANSLATE_NOOP("Builds", "Hide Section Headings"), - "text": QT_TRANSLATE_NOOP("Builds", "Text Content"), - "text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Synopsis"), - "text.includeComments": QT_TRANSLATE_NOOP("Builds", "Comments"), - "text.includeKeywords": QT_TRANSLATE_NOOP("Builds", "Keywords"), - "text.includeBody": QT_TRANSLATE_NOOP("Builds", "Body Text"), + "text.grpContent": QT_TRANSLATE_NOOP("Builds", "Text Content"), + "text.includeSynopsis": QT_TRANSLATE_NOOP("Builds", "Include Synopsis"), + "text.includeComments": QT_TRANSLATE_NOOP("Builds", "Include Comments"), + "text.includeKeywords": QT_TRANSLATE_NOOP("Builds", "Include Keywords"), + "text.includeBodyText": QT_TRANSLATE_NOOP("Builds", "Include Body Text"), + "text.grpInsert": QT_TRANSLATE_NOOP("Builds", "Insert Content"), "text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"), - "format": QT_TRANSLATE_NOOP("Builds", "Text Format"), - "format.buildLang": QT_TRANSLATE_NOOP("Builds", "Build Language"), + "format.grpFormat": QT_TRANSLATE_NOOP("Builds", "Text Format"), + "format.buildLang": QT_TRANSLATE_NOOP("Builds", "Document Language"), "format.textFont": QT_TRANSLATE_NOOP("Builds", "Font Family"), "format.textSize": QT_TRANSLATE_NOOP("Builds", "Font Size"), "format.lineHeight": QT_TRANSLATE_NOOP("Builds", "Line Height"), + "format.grpOptions": QT_TRANSLATE_NOOP("Builds", "Text Options"), "format.justifyText": QT_TRANSLATE_NOOP("Builds", "Justify Text Margins"), "format.stripUnicode": QT_TRANSLATE_NOOP("Builds", "Replace Unicode Characters"), "format.replaceTabs": QT_TRANSLATE_NOOP("Builds", "Replace Tabs with Spaces"), @@ -382,7 +384,7 @@ class BuildCollection: return def getBuild(self, buildID: str) -> BuildSettings | None: - """ + """Get a specific build settings object. """ if buildID not in self._builds: return None @@ -391,7 +393,7 @@ class BuildCollection: return build def setBuild(self, build: BuildSettings) -> bool: - """ + """Set build settings data in the collection. """ if not isinstance(build, BuildSettings): return False @@ -400,14 +402,14 @@ class BuildCollection: return True def builds(self) -> Iterable[tuple[str, str]]: - """ + """Iterate over all avaiable builds. """ for buildID in self._builds: yield buildID, self._builds[buildID].get("name", "") return def loadCollection(self) -> bool: - """ + """Load build collections file. """ buildsFile = self._project.storage.getMetaFile(nwFiles.BUILDS_FILE) if not isinstance(buildsFile, Path): @@ -440,7 +442,7 @@ class BuildCollection: return True def saveCollection(self) -> bool: - """ + """Save build collections file. """ buildsFile = self._project.storage.getMetaFile(nwFiles.BUILDS_FILE) if not isinstance(buildsFile, Path): diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py index 63020838..d6a5b481 100644 --- a/novelwriter/core/docbuild.py +++ b/novelwriter/core/docbuild.py @@ -28,9 +28,10 @@ import logging from pathlib import Path from typing import Iterable -from PyQt5.QtGui import QFont, QFontDatabase, QFontInfo +from PyQt5.QtGui import QFont, QFontInfo from novelwriter import CONFIG +from novelwriter.constants import nwConst from novelwriter.core.tokenizer import Tokenizer from novelwriter.error import formatException from novelwriter.core.tomd import ToMarkdown @@ -174,7 +175,7 @@ class NWBuildDocument: incSynopsis = self._build.getBool("text.includeSynopsis") incComments = self._build.getBool("text.includeComments") incKeywords = self._build.getBool("text.includeKeywords") - includeBody = self._build.getBool("text.includeBody") + incBodyText = self._build.getBool("text.includeBodyText") buildLang = self._build.getStr("format.buildLang") textFont = self._build.getStr("format.textFont") @@ -193,7 +194,7 @@ class NWBuildDocument: if not textFont: textFont = str(CONFIG.textFont) if not textFont: - textFont = QFontDatabase.systemFont(QFontDatabase.GeneralFont).family() + textFont = nwConst.SYSTEM_FONT bldFont = QFont(family=textFont, pointSize=textSize) fontInfo = QFontInfo(bldFont) @@ -212,7 +213,7 @@ class NWBuildDocument: bldObj.setSynopsis(incSynopsis) bldObj.setComments(incComments) bldObj.setKeywords(incKeywords) - bldObj.setBodyText(includeBody) + bldObj.setBodyText(incBodyText) if isinstance(bldObj, ToHtml): bldObj.setStyles(htmlAddStyles) diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index a5200d33..70ab7b56 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -28,18 +28,22 @@ import logging from typing import TYPE_CHECKING -from PyQt5.QtGui import QColor, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument +from PyQt5.QtGui import ( + QColor, QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument +) from PyQt5.QtCore import QEvent, QSize, Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( - QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QGridLayout, - QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSplitter, + QAbstractButton, QAbstractItemView, QComboBox, QDialog, QDialogButtonBox, + QDoubleSpinBox, QFontDialog, QGridLayout, QHBoxLayout, QHeaderView, QLabel, + QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSpinBox, QSplitter, QStackedWidget, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) from novelwriter import CONFIG -from novelwriter.constants import nwHeadingFormats +from novelwriter.constants import nwConst, nwHeadingFormats from novelwriter.core.buildsettings import BuildSettings, FilterMode +from novelwriter.extensions.configlayout import NConfigLayout, NSimpleLayout from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.extensions.pagedsidebar import NPagedSideBar @@ -55,8 +59,8 @@ class GuiBuildSettings(QDialog): OPT_FILTERS = 1 OPT_HEADINGS = 2 - OPT_FORMAT = 3 - OPT_CONTENT = 4 + OPT_CONTENT = 3 + OPT_FORMAT = 4 OPT_OUTPUT = 5 newSettingsReady = pyqtSignal(BuildSettings) @@ -98,8 +102,8 @@ class GuiBuildSettings(QDialog): self.optSideBar.addLabel(self.tr("Options")) self.optSideBar.addButton(self.tr("Filters"), self.OPT_FILTERS) self.optSideBar.addButton(self.tr("Headings"), self.OPT_HEADINGS) - self.optSideBar.addButton(self.tr("Format"), self.OPT_FORMAT) self.optSideBar.addButton(self.tr("Content"), self.OPT_CONTENT) + self.optSideBar.addButton(self.tr("Format"), self.OPT_FORMAT) self.optSideBar.addButton(self.tr("Output"), self.OPT_OUTPUT) self.optSideBar.buttonClicked.connect(self._stackPageSelected) @@ -165,6 +169,8 @@ class GuiBuildSettings(QDialog): self.editBuildName.setText(self._build.name) self.optTabSelect.loadContent() self.optTabHeadings.loadContent() + self.optTabContent.loadContent() + self.optTabFormat.loadContent() return ## @@ -179,10 +185,10 @@ class GuiBuildSettings(QDialog): self.toolStack.setCurrentWidget(self.optTabSelect) elif pageId == self.OPT_HEADINGS: self.toolStack.setCurrentWidget(self.optTabHeadings) - elif pageId == self.OPT_FORMAT: - self.toolStack.setCurrentWidget(self.optTabFormat) elif pageId == self.OPT_CONTENT: self.toolStack.setCurrentWidget(self.optTabContent) + elif pageId == self.OPT_FORMAT: + self.toolStack.setCurrentWidget(self.optTabFormat) elif pageId == self.OPT_OUTPUT: self.toolStack.setCurrentWidget(self.optTabOutput) return @@ -194,6 +200,9 @@ class GuiBuildSettings(QDialog): role = self.dlgButtons.buttonRole(button) if role in (QDialogButtonBox.ApplyRole, QDialogButtonBox.AcceptRole): self._build.setName(self.editBuildName.text()) + self.optTabHeadings.saveContent() + self.optTabContent.saveContent() + self.optTabFormat.saveContent() self.newSettingsReady.emit(self._build) self._saveSettings() @@ -553,7 +562,7 @@ class GuiBuildHeadingsTab(QWidget): self.formatBox.setHorizontalSpacing(vSp) # Title Heading - self.lblTitle = QLabel(BuildSettings.getLabel("headings.fmtTitle")) + self.lblTitle = QLabel(self._build.getLabel("headings.fmtTitle")) self.fmtTitle = QLineEdit("") self.fmtTitle.setEnabled(False) self.btnTitle = QToolButton() @@ -569,7 +578,7 @@ class GuiBuildHeadingsTab(QWidget): self.formatBox.addLayout(wrapTitle, 0, 1, Qt.AlignLeft) # Chapter Heading - self.lblChapter = QLabel(BuildSettings.getLabel("headings.fmtChapter")) + self.lblChapter = QLabel(self._build.getLabel("headings.fmtChapter")) self.fmtChapter = QLineEdit("") self.fmtChapter.setEnabled(False) self.btnChapter = QToolButton() @@ -585,7 +594,7 @@ class GuiBuildHeadingsTab(QWidget): self.formatBox.addLayout(wrapChapter, 1, 1, Qt.AlignLeft) # Unnumbered Chapter Heading - self.lblUnnumbered = QLabel(BuildSettings.getLabel("headings.fmtUnnumbered")) + self.lblUnnumbered = QLabel(self._build.getLabel("headings.fmtUnnumbered")) self.fmtUnnumbered = QLineEdit("") self.fmtUnnumbered.setEnabled(False) self.btnUnnumbered = QToolButton() @@ -601,14 +610,17 @@ class GuiBuildHeadingsTab(QWidget): self.formatBox.addLayout(wrapUnnumbered, 2, 1, Qt.AlignLeft) # Scene Heading - self.lblScene = QLabel(BuildSettings.getLabel("headings.fmtScene")) + sceneHideTip = self._build.getLabel("headings.hideScene") + self.lblScene = QLabel(self._build.getLabel("headings.fmtScene")) self.fmtScene = QLineEdit("") self.fmtScene.setEnabled(False) self.btnScene = QToolButton() self.btnScene.setIcon(self.mainTheme.getIcon("edit")) self.btnScene.clicked.connect(lambda: self._editHeading(self.EDIT_SCENE)) + self.hdeScene = QLabel(self.tr("Hide")) + self.hdeScene.setToolTip(sceneHideTip) self.swtScene = NSwitch(width=2*iPx, height=iPx) - self.swtScene.toggled.connect(self._hideScene) + self.swtScene.setToolTip(sceneHideTip) wrapScene = QHBoxLayout() wrapScene.addWidget(self.fmtScene) @@ -616,7 +628,7 @@ class GuiBuildHeadingsTab(QWidget): wrapScene.setSpacing(bSp) wrapSceneHide = QHBoxLayout() - wrapSceneHide.addWidget(QLabel(self.tr("Hide"))) + wrapSceneHide.addWidget(self.hdeScene) wrapSceneHide.addWidget(self.swtScene) wrapSceneHide.setSpacing(bSp) @@ -625,14 +637,17 @@ class GuiBuildHeadingsTab(QWidget): self.formatBox.addLayout(wrapSceneHide, 3, 2, Qt.AlignLeft) # Section Heading - self.lblSection = QLabel(BuildSettings.getLabel("headings.fmtSection")) + sectionHideTip = self._build.getLabel("headings.hideSection") + self.lblSection = QLabel(self._build.getLabel("headings.fmtSection")) self.fmtSection = QLineEdit("") self.fmtSection.setEnabled(False) self.btnSection = QToolButton() self.btnSection.setIcon(self.mainTheme.getIcon("edit")) self.btnSection.clicked.connect(lambda: self._editHeading(self.EDIT_SECTION)) + self.hdeSection = QLabel(self.tr("Hide")) + self.hdeSection.setToolTip(sectionHideTip) self.swtSection = NSwitch(width=2*iPx, height=iPx) - self.swtSection.toggled.connect(self._hideSection) + self.swtSection.setToolTip(sectionHideTip) wrapSection = QHBoxLayout() wrapSection.addWidget(self.fmtSection) @@ -640,7 +655,7 @@ class GuiBuildHeadingsTab(QWidget): wrapSection.setSpacing(bSp) wrapSectionHide = QHBoxLayout() - wrapSectionHide.addWidget(QLabel(self.tr("Hide"))) + wrapSectionHide.addWidget(self.hdeSection) wrapSectionHide.addWidget(self.swtSection) wrapSectionHide.setSpacing(bSp) @@ -717,6 +732,13 @@ class GuiBuildHeadingsTab(QWidget): self.swtSection.setChecked(self._build.getBool("headings.hideSection")) return + def saveContent(self): + """Save choices back into build object. + """ + self._build.setValue("headings.hideScene", self.swtScene.isChecked()) + self._build.setValue("headings.hideSection", self.swtSection.isChecked()) + return + ## # Internal Functions ## @@ -793,59 +815,9 @@ class GuiBuildHeadingsTab(QWidget): return - @pyqtSlot(bool) - def _hideScene(self, status): - """Hide scene heading - """ - self._build.setValue("headings.hideScene", status) - return - - @pyqtSlot(bool) - def _hideSection(self, status): - """Hide section heading - """ - self._build.setValue("headings.hideSection", status) - return - # END Class GuiBuildHeadingsTab -class GuiBuildFormatTab(QWidget): - - def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): - super().__init__(parent=buildMain) - - self._build = build - - return - -# END Class GuiBuildFormatTab - - -class GuiBuildContentTab(QWidget): - - def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): - super().__init__(parent=buildMain) - - self._build = build - - return - -# END Class GuiBuildContentTab - - -class GuiBuildOutputTab(QWidget): - - def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): - super().__init__(parent=buildMain) - - self._build = build - - return - -# END Class GuiBuildOutputTab - - class GuiHeadingSyntax(QSyntaxHighlighter): def __init__(self, document: QTextDocument, mainTheme: GuiTheme): @@ -885,3 +857,224 @@ class GuiHeadingSyntax(QSyntaxHighlighter): return # END Class GuiHeadingSyntax + + +class GuiBuildContentTab(QWidget): + + def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): + super().__init__(parent=buildMain) + + self.mainGui = buildMain.mainGui + self.mainTheme = buildMain.mainGui.mainTheme + + self._build = build + + iPx = self.mainTheme.baseIconSize + + # Left Form + # ========= + + self.formLeft = NSimpleLayout() + self.formLeft.addGroupLabel(self._build.getLabel("text.grpContent")) + + self.incSynopsis = NSwitch(width=2*iPx, height=iPx) + self.incComments = NSwitch(width=2*iPx, height=iPx) + self.incKeywords = NSwitch(width=2*iPx, height=iPx) + self.incBodyText = NSwitch(width=2*iPx, height=iPx) + + self.formLeft.addRow(self._build.getLabel("text.includeSynopsis"), self.incSynopsis) + self.formLeft.addRow(self._build.getLabel("text.includeComments"), self.incComments) + self.formLeft.addRow(self._build.getLabel("text.includeKeywords"), self.incKeywords) + self.formLeft.addRow(self._build.getLabel("text.includeBodyText"), self.incBodyText) + + # Right Form + # ========== + + self.formRight = NSimpleLayout() + self.formRight.addGroupLabel(self._build.getLabel("text.grpInsert")) + + self.addNoteHead = NSwitch(width=2*iPx, height=iPx) + + self.formRight.addRow(self._build.getLabel("text.addNoteHeadings"), self.addNoteHead) + + # Assemble GUI + # ============ + + self.outerBox = QHBoxLayout() + self.outerBox.addLayout(self.formLeft, 1) + self.outerBox.addLayout(self.formRight, 1) + self.outerBox.setContentsMargins(0, 0, 0, 0) + self.outerBox.setSpacing(CONFIG.pxInt(16)) + + self.setLayout(self.outerBox) + + return + + def loadContent(self): + """Populate the widgets. + """ + self.incSynopsis.setChecked(self._build.getBool("text.includeSynopsis")) + self.incComments.setChecked(self._build.getBool("text.includeComments")) + self.incKeywords.setChecked(self._build.getBool("text.includeKeywords")) + self.incBodyText.setChecked(self._build.getBool("text.includeBodyText")) + self.addNoteHead.setChecked(self._build.getBool("text.addNoteHeadings")) + return + + def saveContent(self): + """Save choices back into build object. + """ + self._build.setValue("text.includeSynopsis", self.incSynopsis.isChecked()) + self._build.setValue("text.includeComments", self.incComments.isChecked()) + self._build.setValue("text.includeKeywords", self.incKeywords.isChecked()) + self._build.setValue("text.includeBodyText", self.incBodyText.isChecked()) + self._build.setValue("text.addNoteHeadings", self.addNoteHead.isChecked()) + return + +# END Class GuiBuildContentTab + + +class GuiBuildFormatTab(QWidget): + + def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): + super().__init__(parent=buildMain) + + self.mainGui = buildMain.mainGui + self.mainTheme = buildMain.mainGui.mainTheme + + self._build = build + + iPx = self.mainTheme.baseIconSize + + # Form + # ==== + + self.mainForm = NConfigLayout() + self.mainForm.addGroupLabel(self._build.getLabel("format.grpFormat")) + + # Build Language + self.buildLang = QComboBox() + self.buildLang.setMinimumWidth(CONFIG.pxInt(250)) + langauges = CONFIG.listLanguages(CONFIG.LANG_PROJ) + self.buildLang.addItem("[%s]" % self.tr("Not Set"), "None") + for langID, langName in langauges: + self.buildLang.addItem(langName, langID) + + self.mainForm.addRow(self._build.getLabel("format.buildLang"), self.buildLang) + + # Font Family + self.textFont = QLineEdit() + self.textFont.setReadOnly(True) + self.textFont.setMinimumWidth(CONFIG.pxInt(200)) + self.btnTextFont = QPushButton("...") + self.btnTextFont.setMaximumWidth(int(2.5*self.mainTheme.getTextWidth("..."))) + self.btnTextFont.clicked.connect(self._selectFont) + self.mainForm.addRow( + self._build.getLabel("format.textFont"), self.textFont, button=self.btnTextFont + ) + + # Font Size + self.textSize = QSpinBox(self) + self.textSize.setMinimum(8) + self.textSize.setMaximum(60) + self.textSize.setSingleStep(1) + self.textSize.setMinimumWidth(CONFIG.pxInt(60)) + self.mainForm.addRow( + self._build.getLabel("format.textSize"), self.textSize, unit="pt" + ) + + # Line Height + self.lineHeight = QDoubleSpinBox(self) + self.lineHeight.setFixedWidth(6*self.mainTheme.textNWidth) + self.lineHeight.setMinimum(0.75) + self.lineHeight.setMaximum(3.0) + self.lineHeight.setSingleStep(0.05) + self.lineHeight.setDecimals(2) + self.lineHeight.setMinimumWidth(CONFIG.pxInt(60)) + self.mainForm.addRow( + self._build.getLabel("format.lineHeight"), self.lineHeight, unit="em" + ) + + # Switches + self.mainForm.addGroupLabel(self._build.getLabel("format.grpOptions")) + self.mainForm.setContentsMargins(0, 0, 0, 0) + + self.justifyText = NSwitch(width=2*iPx, height=iPx) + self.stripUnicode = NSwitch(width=2*iPx, height=iPx) + self.replaceTabs = NSwitch(width=2*iPx, height=iPx) + + self.mainForm.addRow(self._build.getLabel("format.justifyText"), self.justifyText) + self.mainForm.addRow(self._build.getLabel("format.stripUnicode"), self.stripUnicode) + self.mainForm.addRow(self._build.getLabel("format.replaceTabs"), self.replaceTabs) + + # Assemble GUI + # ============ + + self.setLayout(self.mainForm) + + return + + def loadContent(self): + """Populate the widgets. + """ + langIdx = self.buildLang.findData(self._build.getStr("format.buildLang")) + if langIdx != -1: + self.buildLang.setCurrentIndex(langIdx) + + textFont = self._build.getStr("format.textFont") + if not textFont: + textFont = str(CONFIG.textFont) + if not textFont: + textFont = nwConst.SYSTEM_FONT + + self.textFont.setText(textFont) + self.textSize.setValue(self._build.getInt("format.textSize")) + self.lineHeight.setValue(self._build.getFloat("format.lineHeight")) + + self.justifyText.setChecked(self._build.getBool("format.justifyText")) + self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode")) + self.replaceTabs.setChecked(self._build.getBool("format.replaceTabs")) + + return + + def saveContent(self): + """Save choices back into build object. + """ + self._build.setValue("format.buildLang", str(self.buildLang.currentData())) + self._build.setValue("format.textFont", self.textFont.text()) + self._build.setValue("format.textSize", self.textSize.value()) + self._build.setValue("format.lineHeight", self.lineHeight.value()) + self._build.setValue("format.justifyText", self.justifyText.isChecked()) + self._build.setValue("format.stripUnicode", self.stripUnicode.isChecked()) + self._build.setValue("format.replaceTabs", self.replaceTabs.isChecked()) + return + + ## + # Private Slots + ## + + @pyqtSlot() + def _selectFont(self): + """Open the QFontDialog and set a font for the font style. + """ + currFont = QFont() + currFont.setFamily(self.textFont.text()) + currFont.setPointSize(self.textSize.value()) + theFont, theStatus = QFontDialog.getFont(currFont, self) + if theStatus: + self.textFont.setText(theFont.family()) + self.textSize.setValue(theFont.pointSize()) + return + +# END Class GuiBuildFormatTab + + +class GuiBuildOutputTab(QWidget): + + def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): + super().__init__(parent=buildMain) + + self._build = build + + return + +# END Class GuiBuildOutputTab