From 7d065659e8b24d60f94f4fd53e3d16ae24529e7c Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:05:46 +0200 Subject: [PATCH 1/8] Bump version 2.1-beta1 --- novelwriter/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/novelwriter/__init__.py b/novelwriter/__init__.py index 8d1c68f7..bd8fa337 100644 --- a/novelwriter/__init__.py +++ b/novelwriter/__init__.py @@ -58,9 +58,9 @@ __license__ = "GPLv3" __author__ = "Veronica Berglyd Olsen" __maintainer__ = "Veronica Berglyd Olsen" __email__ = "code@vkbo.net" -__version__ = "2.0.7" -__hexversion__ = "0x020007f0" -__date__ = "2023-04-16" +__version__ = "2.1-beta1" +__hexversion__ = "0x020100b1" +__date__ = "2023-06-19" __status__ = "Stable" __domain__ = "novelwriter.io" From c123ef925882df041bec3f055a2fd46f56a6e20c Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:17:03 +0200 Subject: [PATCH 2/8] Add a separator style to ODT builds --- novelwriter/core/toodt.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/novelwriter/core/toodt.py b/novelwriter/core/toodt.py index 3bdb66b5..19d21694 100644 --- a/novelwriter/core/toodt.py +++ b/novelwriter/core/toodt.py @@ -454,10 +454,10 @@ class ToOdt(Tokenizer): self._addTextPar("Heading_20_4", oStyle, tHead, isHead=True, oLevel="4") elif tType == self.T_SEP: - self._addTextPar("Text_20_body", oStyle, tText) + self._addTextPar("Separator", oStyle, tText) elif tType == self.T_SKIP: - self._addTextPar("Text_20_body", oStyle, "") + self._addTextPar("Separator", oStyle, "") elif tType == self.T_TEXT: if parStyle is None: @@ -869,6 +869,25 @@ class ToOdt(Tokenizer): self._mainPara["Title"] = oStyle + # Add Separator Style + # =================== + + oStyle = ODTParagraphStyle() + oStyle.setDisplayName("Separator") + oStyle.setParentStyleName("Standard") + oStyle.setNextStyleName("Text_20_body") + oStyle.setClass("text") + oStyle.setTextAlign("center") + oStyle.setMarginTop(self._mTopText) + oStyle.setMarginBottom(self._mBotText) + oStyle.setLineHeight(self._fLineHeight) + oStyle.setFontName(self._textFont) + oStyle.setFontFamily(self._fontFamily) + oStyle.setFontSize(self._fSizeText) + oStyle.packXML(self._xStyl, "Separator") + + self._mainPara["Separator"] = oStyle + # Add Heading 1 Style # =================== From bebf48777696047e7d18183e43db6c4dcc512212 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:17:18 +0200 Subject: [PATCH 3/8] Update tests --- sample/nwProject.nwx | 4 +- .../coreToOdt_SaveFlat_document.fodt | 10 ++- tests/reference/coreToOdt_SaveFull_styles.xml | 4 + ...uildDocBuild_OpenDocument_Lorem_Ipsum.fodt | 14 +-- tests/test_core/test_core_toodt.py | 86 +++++++++---------- 5 files changed, 65 insertions(+), 53 deletions(-) diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index ee8d43ca..18efb9d6 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,6 +1,6 @@ - - + + Sample Project Sample Project Jane Smith diff --git a/tests/reference/coreToOdt_SaveFlat_document.fodt b/tests/reference/coreToOdt_SaveFlat_document.fodt index 0c2b658e..1f49def3 100644 --- a/tests/reference/coreToOdt_SaveFlat_document.fodt +++ b/tests/reference/coreToOdt_SaveFlat_document.fodt @@ -1,13 +1,13 @@ - 2023-05-29T22:10:15 - novelWriter/2.0.7 + 2023-07-19T18:05:15 + novelWriter/2.1-beta1 Jane Smith 1234 P42DT12H34M56S Test Project - 2023-05-29T22:10:15 + 2023-07-19T18:05:15 Jane Smith @@ -38,6 +38,10 @@ + + + + diff --git a/tests/reference/coreToOdt_SaveFull_styles.xml b/tests/reference/coreToOdt_SaveFull_styles.xml index 5f2d1db6..37dbceb9 100644 --- a/tests/reference/coreToOdt_SaveFull_styles.xml +++ b/tests/reference/coreToOdt_SaveFull_styles.xml @@ -28,6 +28,10 @@ + + + + diff --git a/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt b/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt index aba1a301..278a0632 100644 --- a/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt +++ b/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt @@ -1,13 +1,13 @@ - 2023-05-29T22:20:22 - novelWriter/2.0.7 + 2023-07-19T18:05:14 + novelWriter/2.1-beta1 lipsum.com - 40 - P0DT0H31M45S + 42 + P0DT0H31M53S Lorem Ipsum - 2023-05-29T22:20:22 + 2023-07-19T18:05:14 lipsum.com @@ -38,6 +38,10 @@ + + + + diff --git a/tests/test_core/test_core_toodt.py b/tests/test_core/test_core_toodt.py index 5ab6f276..359b0935 100644 --- a/tests/test_core/test_core_toodt.py +++ b/tests/test_core/test_core_toodt.py @@ -129,8 +129,8 @@ def testCoreToOdt_TextFormatting(mockGUI): assert theDoc._paraStyle("Text_20_body", oStyle) == "P1" assert list(theDoc._mainPara.keys()) == [ - "Text_20_body", "Text_20_Meta", "Title", "Heading_20_1", - "Heading_20_2", "Heading_20_3", "Heading_20_4", "Header" + "Text_20_body", "Text_20_Meta", "Title", "Separator", + "Heading_20_1", "Heading_20_2", "Heading_20_3", "Heading_20_4", "Header", ] theKey = "071d6b2e4764749f8c78d3c1ab9099fa04c07d2d53fd3de61eb1bdf1cb4845c3" @@ -145,9 +145,9 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc.initDocument() theDoc._addTextPar("Standard", oStyle, "") assert xmlToText(theDoc._xText) == ( - "" - "" - "" + '' + '' + '' ) # No Format @@ -155,9 +155,9 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, "Hello World") assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( - "" - "Hello World" - "" + '' + 'Hello World' + '' ) # Heading Level None @@ -165,9 +165,9 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, "Hello World", isHead=True) assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( - "" - "Hello World" - "" + '' + 'Hello World' + '' ) # Heading Level 1 @@ -175,9 +175,9 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, "Hello World", isHead=True, oLevel="1") assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( - "" - "Hello World" - "" + '' + 'Hello World' + '' ) # Formatted Text @@ -187,11 +187,11 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, theTxt, tFmt=theFmt) assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( - "" - "A few " - "words from our sponsor" - "" + '' + 'A few ' + 'words from ' + 'our sponsor' + '' ) # Incorrectly Formatted Text @@ -201,11 +201,11 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, theTxt, tFmt=theFmt) assert theDoc.errData == ["Unknown format tag encountered"] assert xmlToText(theDoc._xText) == ( - "" - "" - "A few words" - "" - "" + '' + '' + 'A few words' + '' + '' ) # Formatted Text @@ -215,9 +215,9 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, theTxt, tFmt=theFmt) assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( - "" - "HelloWorld" - "" + '' + 'HelloWorld' + '' ) # Test for issue #1412 @@ -230,10 +230,10 @@ def testCoreToOdt_TextFormatting(mockGUI): theDoc._addTextPar("Standard", oStyle, theTxt, tFmt=theFmt) assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( - "" - "Test text **" - "bold** and more." - "" + '' + 'Test text **' + 'bold** and more.' + '' ) # END Test testCoreToOdt_TextFormatting @@ -454,9 +454,9 @@ def testCoreToOdt_Convert(mockGUI): assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( '' - '* * *' + '* * *' 'Text' - '* * *' + '* * *' 'Text' '' ) @@ -472,9 +472,9 @@ def testCoreToOdt_Convert(mockGUI): assert theDoc.errData == [] assert xmlToText(theDoc._xText) == ( '' - '' + '' 'Text' - '' + '' 'Text' '' ) @@ -500,24 +500,24 @@ def testCoreToOdt_Convert(mockGUI): assert xmlToText(theDoc._xText) == ( '' 'Scene' - '' + '' 'Point of View: Jane' - '' + '' 'Characters: John' '' 'Plot: Main' - 'Right align' + 'Right align' 'Left Align' - 'Centered' + 'Centered' 'Left indent' 'Right indent' '' ) + assert getStyle("P3")._pAttr["margin-bottom"] == ["fo", "0.000cm"] assert getStyle("P4")._pAttr["margin-bottom"] == ["fo", "0.000cm"] - assert getStyle("P5")._pAttr["margin-bottom"] == ["fo", "0.000cm"] - assert getStyle("P5")._pAttr["margin-top"] == ["fo", "0.000cm"] - assert getStyle("P6")._pAttr["text-align"] == ["fo", "right"] - assert getStyle("P3")._pAttr["text-align"] == ["fo", "center"] + assert getStyle("P4")._pAttr["margin-top"] == ["fo", "0.000cm"] + assert getStyle("P5")._pAttr["text-align"] == ["fo", "right"] + assert getStyle("P6")._pAttr["text-align"] == ["fo", "center"] assert getStyle("P7")._pAttr["margin-left"] == ["fo", "1.693cm"] assert getStyle("P8")._pAttr["margin-right"] == ["fo", "1.693cm"] From ac92e5b1268c6a456d064585f83216513b50e409 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 19 Jul 2023 23:55:00 +0200 Subject: [PATCH 4/8] Add support for page layout settings in builds --- novelwriter/constants.py | 18 ++- novelwriter/core/buildsettings.py | 38 ++++- novelwriter/core/docbuild.py | 14 +- novelwriter/core/toodt.py | 30 +++- novelwriter/tools/manussettings.py | 234 ++++++++++++++++++++++++----- 5 files changed, 283 insertions(+), 51 deletions(-) diff --git a/novelwriter/constants.py b/novelwriter/constants.py index 2875a72b..6e974923 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -22,16 +22,16 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ +from __future__ import annotations from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP from novelwriter.enum import nwBuildFmt, nwItemClass, nwItemLayout, nwOutline -def trConst(tString): - """Wrapper function for locally translating constants. - """ - return QCoreApplication.translate("Constant", tString) +def trConst(text: str) -> str: + """Wrapper function for locally translating constants.""" + return QCoreApplication.translate("Constant", text) class nwConst: @@ -225,6 +225,16 @@ class nwLabels: nwBuildFmt.J_HTML: ".json", nwBuildFmt.J_NWD: ".json", } + UNIT_NAME = { + "mm": QT_TRANSLATE_NOOP("Constant", "Millimetres"), + "cm": QT_TRANSLATE_NOOP("Constant", "Centimetres"), + "in": QT_TRANSLATE_NOOP("Constant", "Inches"), + } + UNIT_SCALE = { + "mm": 1.0, + "cm": 10.0, + "in": 25.4, + } # END Class nwLabels diff --git a/novelwriter/core/buildsettings.py b/novelwriter/core/buildsettings.py index cafa637d..aa826022 100644 --- a/novelwriter/core/buildsettings.py +++ b/novelwriter/core/buildsettings.py @@ -71,6 +71,14 @@ SETTINGS_TEMPLATE = { "format.justifyText": (bool, False), "format.stripUnicode": (bool, False), "format.replaceTabs": (bool, False), + "format.pageUnit": (str, "cm"), + "format.pageSize": (str, "A4"), + "format.pageWidth": (float, 21.0), + "format.pageHeight": (float, 29.7), + "format.topMargin": (float, 2.0), + "format.bottomMargin": (float, 2.0), + "format.leftMargin": (float, 2.0), + "format.rightMargin": (float, 2.0), "odt.addColours": (bool, True), "html.addStyles": (bool, True), } @@ -99,7 +107,7 @@ SETTINGS_LABELS = { "text.addNoteHeadings": QT_TRANSLATE_NOOP("Builds", "Add Titles for Notes"), "format.grpFormat": QT_TRANSLATE_NOOP("Builds", "Text Format"), - "format.buildLang": QT_TRANSLATE_NOOP("Builds", "Document Language"), + "format.buildLang": QT_TRANSLATE_NOOP("Builds", "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"), @@ -107,6 +115,15 @@ SETTINGS_LABELS = { "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"), + "format.grpPage": QT_TRANSLATE_NOOP("Builds", "Page Layout"), + "format.pageUnit": QT_TRANSLATE_NOOP("Builds", "Unit"), + "format.pageSize": QT_TRANSLATE_NOOP("Builds", "Page Size"), + "format.pageWidth": QT_TRANSLATE_NOOP("Builds", "Page Width"), + "format.pageHeight": QT_TRANSLATE_NOOP("Builds", "Page Height"), + "format.topMargin": QT_TRANSLATE_NOOP("Builds", "Top Margin"), + "format.bottomMargin": QT_TRANSLATE_NOOP("Builds", "Bottom Margin"), + "format.leftMargin": QT_TRANSLATE_NOOP("Builds", "Left Margin"), + "format.rightMargin": QT_TRANSLATE_NOOP("Builds", "Right Margin"), "odt": QT_TRANSLATE_NOOP("Builds", "Open Document"), "odt.addColours": QT_TRANSLATE_NOOP("Builds", "Add Highlight Colours"), @@ -115,6 +132,15 @@ SETTINGS_LABELS = { "html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"), } +PAGE_SIZES = { + "A4": (210.0, 297.0), + "A5": (148.0, 210.0), + "A6": (105.0, 148.0), + "Legal": (215.9, 355.6), + "Letter": (215.9, 279.4), + "Custom": (-1.0, -1.0), +} + class FilterMode(Enum): """The decision reason for an item in a filtered project.""" @@ -160,7 +186,7 @@ class BuildSettings: @property def buildID(self) -> str: - """The build ID as an UUID.""" + """The build ID as a UUID.""" return self._uuid @property @@ -196,24 +222,24 @@ class BuildSettings: def getStr(self, key: str) -> str: """Type safe value access for strings.""" - value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None)[1])) + value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1]) return str(value) def getBool(self, key: str) -> bool: """Type safe value access for bools.""" - value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None)[1])) + value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1]) return bool(value) def getInt(self, key: str) -> int: """Type safe value access for integers.""" - value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None)[1])) + value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1]) if isinstance(value, (int, float)): return int(value) return 0 def getFloat(self, key: str) -> float: """Type safe value access for floats.""" - value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None)[1])) + value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1]) if isinstance(value, (int, float)): return float(value) return 0.0 diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py index 82753306..a43112c0 100644 --- a/novelwriter/core/docbuild.py +++ b/novelwriter/core/docbuild.py @@ -33,13 +33,14 @@ from PyQt5.QtGui import QFont, QFontInfo from novelwriter import CONFIG from novelwriter.enum import nwBuildFmt from novelwriter.error import formatException, logException +from novelwriter.constants import nwLabels from novelwriter.core.item import NWItem from novelwriter.core.tomd import ToMarkdown from novelwriter.core.toodt import ToOdt from novelwriter.core.tohtml import ToHtml from novelwriter.core.project import NWProject from novelwriter.core.tokenizer import Tokenizer -from novelwriter.core.buildsettings import BuildSettings +from novelwriter.core.buildsettings import PAGE_SIZES, BuildSettings logger = logging.getLogger(__name__) @@ -290,6 +291,17 @@ class NWBuildDocument: bldObj.setColourHeaders(self._build.getBool("odt.addColours")) bldObj.setLanguage(buildLang) + scale = nwLabels.UNIT_SCALE.get(self._build.getStr("format.pageUnit"), 1.0) + width, height = PAGE_SIZES.get(self._build.getStr("format.pageSize"), (-1.0, -1.0)) + bldObj.setPageLayout( + width if width > 0.0 else scale*self._build.getFloat("format.pageWidth"), + height if height > 0.0 else scale*self._build.getFloat("format.pageHeight"), + scale*self._build.getFloat("format.topMargin"), + scale*self._build.getFloat("format.bottomMargin"), + scale*self._build.getFloat("format.leftMargin"), + scale*self._build.getFloat("format.rightMargin"), + ) + filtered = self._build.buildItemFilter( self._project, withRoots=self._build.getBool("text.addNoteHeadings") ) diff --git a/novelwriter/core/toodt.py b/novelwriter/core/toodt.py index 19d21694..34d5a7d8 100644 --- a/novelwriter/core/toodt.py +++ b/novelwriter/core/toodt.py @@ -147,7 +147,7 @@ class ToOdt(Tokenizer): self._dLanguage = "en" self._dCountry = "GB" - # Text Margings in Units of em + # Text Margings self._mTopTitle = "0.423cm" self._mTopHead1 = "0.423cm" self._mTopHead2 = "0.353cm" @@ -166,11 +166,13 @@ class ToOdt(Tokenizer): self._mBotText = "0.247cm" self._mBotMeta = "0.106cm" - # Document Margins - self._mDocTop = "2.000cm" - self._mDocBtm = "2.000cm" - self._mDocLeft = "2.000cm" - self._mDocRight = "2.000cm" + # Document Size and Margins + self._mDocWidth = "21.0cm" + self._mDocHeight = "29.7cm" + self._mDocTop = "2.000cm" + self._mDocBtm = "2.000cm" + self._mDocLeft = "2.000cm" + self._mDocRight = "2.000cm" # Colour self._colHead12 = None @@ -200,6 +202,19 @@ class ToOdt(Tokenizer): self._colourHead = state return + def setPageLayout( + self, width: int | float, height: int | float, + top: int | float, bottom: int | float, left: int | float, right: int | float + ): + """Set the document page size and margins in millimetres.""" + self._mDocWidth = f"{width/10.0:.3f}cm" + self._mDocHeight = f"{height/10.0:.3f}cm" + self._mDocTop = f"{top/10.0:.3f}cm" + self._mDocBtm = f"{bottom/10.0:.3f}cm" + self._mDocLeft = f"{left/10.0:.3f}cm" + self._mDocRight = f"{right/10.0:.3f}cm" + return + ## # Class Methods ## @@ -721,10 +736,13 @@ class ToOdt(Tokenizer): xPage = ET.SubElement(self._xAut2, _mkTag("style", "page-layout"), attrib=tAttr) tAttr = {} + tAttr[_mkTag("fo", "page-width")] = self._mDocWidth + tAttr[_mkTag("fo", "page-height")] = self._mDocHeight tAttr[_mkTag("fo", "margin-top")] = self._mDocTop tAttr[_mkTag("fo", "margin-bottom")] = self._mDocBtm tAttr[_mkTag("fo", "margin-left")] = self._mDocLeft tAttr[_mkTag("fo", "margin-right")] = self._mDocRight + tAttr[_mkTag("fo", "print-orientation")] = "portrait" ET.SubElement(xPage, _mkTag("style", "page-layout-properties"), attrib=tAttr) xHead = ET.SubElement(xPage, _mkTag("style", "header-style")) diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 3e390c2c..6e6038c7 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -40,8 +40,8 @@ from PyQt5.QtWidgets import ( ) from novelwriter import CONFIG -from novelwriter.constants import nwHeadFmt -from novelwriter.core.buildsettings import BuildSettings, FilterMode +from novelwriter.constants import nwHeadFmt, nwLabels, trConst +from novelwriter.core.buildsettings import PAGE_SIZES, BuildSettings, FilterMode from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.extensions.configlayout import NConfigLayout, NSimpleLayout @@ -644,7 +644,7 @@ class _HeadingsTab(QWidget): 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 = NSwitch(self, width=2*iPx, height=iPx) self.swtScene.setToolTip(sceneHideTip) wrapScene = QHBoxLayout() @@ -671,7 +671,7 @@ class _HeadingsTab(QWidget): 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 = NSwitch(self, width=2*iPx, height=iPx) self.swtSection.setToolTip(sectionHideTip) wrapSection = QHBoxLayout() @@ -882,10 +882,10 @@ class _ContentTab(QWidget): 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.incSynopsis = NSwitch(self, width=2*iPx, height=iPx) + self.incComments = NSwitch(self, width=2*iPx, height=iPx) + self.incKeywords = NSwitch(self, width=2*iPx, height=iPx) + self.incBodyText = NSwitch(self, 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) @@ -898,7 +898,7 @@ class _ContentTab(QWidget): self.formRight = NSimpleLayout() self.formRight.addGroupLabel(self._build.getLabel("text.grpInsert")) - self.addNoteHead = NSwitch(width=2*iPx, height=iPx) + self.addNoteHead = NSwitch(self, width=2*iPx, height=iPx) self.formRight.addRow(self._build.getLabel("text.addNoteHeadings"), self.addNoteHead) @@ -945,33 +945,34 @@ class _FormatTab(QWidget): self.mainTheme = buildMain.mainGui.mainTheme self._build = build + self._unitScale = 1.0 iPx = self.mainTheme.baseIconSize + spW = 6*self.mainTheme.textNWidth + dbW = 8*self.mainTheme.textNWidth - # Form - # ==== + # Text Format Form + # ================ - self.mainForm = NConfigLayout() - self.mainForm.addGroupLabel(self._build.getLabel("format.grpFormat")) + self.formFormat = NConfigLayout() + self.formFormat.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) + self.formFormat.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.formFormat.addRow( self._build.getLabel("format.textFont"), self.textFont, button=self.btnTextFont ) @@ -980,39 +981,104 @@ class _FormatTab(QWidget): self.textSize.setMinimum(8) self.textSize.setMaximum(60) self.textSize.setSingleStep(1) - self.textSize.setMinimumWidth(CONFIG.pxInt(60)) - self.mainForm.addRow( + self.textSize.setMinimumWidth(spW) + self.formFormat.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.setFixedWidth(spW) 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.formFormat.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) + # Text Options Form + # ================= - 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.formOptions = NSimpleLayout() + self.formOptions.addGroupLabel(self._build.getLabel("format.grpOptions")) + self.formOptions.setContentsMargins(0, 0, 0, 0) - 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) + self.justifyText = NSwitch(self, width=2*iPx, height=iPx) + self.stripUnicode = NSwitch(self, width=2*iPx, height=iPx) + self.replaceTabs = NSwitch(self, width=2*iPx, height=iPx) + + self.formOptions.addRow(self._build.getLabel("format.justifyText"), self.justifyText) + self.formOptions.addRow(self._build.getLabel("format.stripUnicode"), self.stripUnicode) + self.formOptions.addRow(self._build.getLabel("format.replaceTabs"), self.replaceTabs) + + # Page Layout Form + # ================ + + self.formLayout = NSimpleLayout() + self.formLayout.addGroupLabel(self._build.getLabel("format.grpPage")) + self.formLayout.setContentsMargins(0, 0, 0, 0) + + self.pageUnit = QComboBox(self) + for key, name in nwLabels.UNIT_NAME.items(): + self.pageUnit.addItem(trConst(name), key) + + self.pageSize = QComboBox(self) + for key, size in PAGE_SIZES.items(): + self.pageSize.addItem(key, size) + + self.pageWidth = QDoubleSpinBox(self) + self.pageWidth.setFixedWidth(dbW) + self.pageWidth.setMaximum(500.0) + + self.pageHeight = QDoubleSpinBox(self) + self.pageHeight.setFixedWidth(dbW) + self.pageHeight.setMaximum(500.0) + + self.topMargin = QDoubleSpinBox(self) + self.topMargin.setFixedWidth(dbW) + + self.bottomMargin = QDoubleSpinBox(self) + self.bottomMargin.setFixedWidth(dbW) + + self.leftMargin = QDoubleSpinBox(self) + self.leftMargin.setFixedWidth(dbW) + + self.rightMargin = QDoubleSpinBox(self) + self.rightMargin.setFixedWidth(dbW) + + self.formLayout.addRow(self._build.getLabel("format.pageUnit"), self.pageUnit) + self.formLayout.addRow(self._build.getLabel("format.pageSize"), self.pageSize) + self.formLayout.addRow(self._build.getLabel("format.pageWidth"), self.pageWidth) + self.formLayout.addRow(self._build.getLabel("format.pageHeight"), self.pageHeight) + self.formLayout.addRow(self._build.getLabel("format.topMargin"), self.topMargin) + self.formLayout.addRow(self._build.getLabel("format.bottomMargin"), self.bottomMargin) + self.formLayout.addRow(self._build.getLabel("format.leftMargin"), self.leftMargin) + self.formLayout.addRow(self._build.getLabel("format.rightMargin"), self.rightMargin) # Assemble GUI # ============ - self.setLayout(self.mainForm) + self.formLeft = QVBoxLayout() + self.formLeft.addLayout(self.formFormat) + self.formLeft.addLayout(self.formOptions) + self.formLeft.addStretch(1) + self.formLeft.setContentsMargins(0, 0, 0, 0) + self.formLeft.setSpacing(CONFIG.pxInt(8)) + + self.formRight = QVBoxLayout() + self.formRight.addLayout(self.formLayout) + self.formRight.addStretch(1) + self.formRight.setContentsMargins(0, 0, 0, 0) + self.formRight.setSpacing(CONFIG.pxInt(8)) + + 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 @@ -1034,6 +1100,29 @@ class _FormatTab(QWidget): self.stripUnicode.setChecked(self._build.getBool("format.stripUnicode")) self.replaceTabs.setChecked(self._build.getBool("format.replaceTabs")) + pageUnit = self._build.getStr("format.pageUnit") + index = self.pageUnit.findData(pageUnit) + if index >= 0: + self.pageUnit.setCurrentIndex(index) + self._unitScale = nwLabels.UNIT_SCALE.get(pageUnit, 1.0) + self._changeUnit(index) + + self.pageWidth.setValue(self._build.getFloat("format.pageWidth")) + self.pageHeight.setValue(self._build.getFloat("format.pageHeight")) + self.topMargin.setValue(self._build.getFloat("format.topMargin")) + self.bottomMargin.setValue(self._build.getFloat("format.bottomMargin")) + self.leftMargin.setValue(self._build.getFloat("format.leftMargin")) + self.rightMargin.setValue(self._build.getFloat("format.rightMargin")) + + pageSize = self._build.getStr("format.pageSize") + index = self.pageSize.findText(pageSize) + if index >= 0: + self.pageSize.setCurrentIndex(index) + self._changePageSize(index) + + self.pageUnit.currentIndexChanged.connect(self._changeUnit) + self.pageSize.currentIndexChanged.connect(self._changePageSize) + return def saveContent(self): @@ -1045,6 +1134,14 @@ class _FormatTab(QWidget): self._build.setValue("format.justifyText", self.justifyText.isChecked()) self._build.setValue("format.stripUnicode", self.stripUnicode.isChecked()) self._build.setValue("format.replaceTabs", self.replaceTabs.isChecked()) + self._build.setValue("format.pageUnit", str(self.pageUnit.currentData())) + self._build.setValue("format.pageSize", str(self.pageSize.currentText())) + self._build.setValue("format.pageWidth", self.pageWidth.value()) + self._build.setValue("format.pageHeight", self.pageHeight.value()) + self._build.setValue("format.topMargin", self.topMargin.value()) + self._build.setValue("format.bottomMargin", self.bottomMargin.value()) + self._build.setValue("format.leftMargin", self.leftMargin.value()) + self._build.setValue("format.rightMargin", self.rightMargin.value()) return ## @@ -1063,6 +1160,75 @@ class _FormatTab(QWidget): self.textSize.setValue(theFont.pointSize()) return + @pyqtSlot(int) + def _changeUnit(self, index: int): + """The current unit change, so recalculate sizes.""" + newUnit = self.pageUnit.itemData(index) + newScale = nwLabels.UNIT_SCALE.get(newUnit, 1.0) + reScale = self._unitScale/newScale + + pageWidth = self.pageWidth.value() * reScale + pageHeight = self.pageHeight.value() * reScale + topMargin = self.topMargin.value() * reScale + bottomMargin = self.bottomMargin.value() * reScale + leftMargin = self.leftMargin.value() * reScale + rightMargin = self.rightMargin.value() * reScale + + isMM = newUnit == "mm" + nDec = 1 if isMM else 2 + nStep = 1.0 if isMM else 0.1 + pMax = 500.0 if isMM else 50.0 + mMax = 150.0 if isMM else 15.0 + + self.pageWidth.setDecimals(nDec) + self.pageWidth.setSingleStep(nStep) + self.pageWidth.setMaximum(pMax) + self.pageWidth.setValue(pageWidth) + + self.pageHeight.setDecimals(nDec) + self.pageHeight.setSingleStep(nStep) + self.pageHeight.setMaximum(pMax) + self.pageHeight.setValue(pageHeight) + + self.topMargin.setDecimals(nDec) + self.topMargin.setSingleStep(nStep) + self.topMargin.setMaximum(mMax) + self.topMargin.setValue(topMargin) + + self.bottomMargin.setDecimals(nDec) + self.bottomMargin.setSingleStep(nStep) + self.bottomMargin.setMaximum(mMax) + self.bottomMargin.setValue(bottomMargin) + + self.leftMargin.setDecimals(nDec) + self.leftMargin.setSingleStep(nStep) + self.leftMargin.setMaximum(mMax) + self.leftMargin.setValue(leftMargin) + + self.rightMargin.setDecimals(nDec) + self.rightMargin.setSingleStep(nStep) + self.rightMargin.setMaximum(mMax) + self.rightMargin.setValue(rightMargin) + + self._unitScale = newScale + + return + + @pyqtSlot(int) + def _changePageSize(self, index: int): + """The page size has changed.""" + self.pageWidth.setEnabled(True) + self.pageHeight.setEnabled(True) + + width, height = self.pageSize.itemData(index) if index >= 0 else (-1.0, -1.0) + if width > 0.0 and height > 0.0: + self.pageWidth.setEnabled(False) + self.pageHeight.setEnabled(False) + self.pageWidth.setValue(width/self._unitScale) + self.pageHeight.setValue(height/self._unitScale) + + return + # END Class _FormatTab @@ -1084,7 +1250,7 @@ class _OutputTab(QWidget): self.formLeft = NSimpleLayout() self.formLeft.addGroupLabel(self._build.getLabel("odt")) - self.odtAddColours = NSwitch(width=2*iPx, height=iPx) + self.odtAddColours = NSwitch(self, width=2*iPx, height=iPx) self.formLeft.addRow(self._build.getLabel("odt.addColours"), self.odtAddColours) @@ -1094,7 +1260,7 @@ class _OutputTab(QWidget): self.formRight = NSimpleLayout() self.formRight.addGroupLabel(self._build.getLabel("html")) - self.htmlAddStyles = NSwitch(width=2*iPx, height=iPx) + self.htmlAddStyles = NSwitch(self, width=2*iPx, height=iPx) self.formRight.addRow(self._build.getLabel("html.addStyles"), self.htmlAddStyles) From 3c535ab0efedc851bbfe639d50da0a74d72b58c4 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 19 Jul 2023 23:55:17 +0200 Subject: [PATCH 5/8] Make some improvements to the config layout class --- novelwriter/extensions/configlayout.py | 51 +++++++------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py index cada2efa..93d348be 100644 --- a/novelwriter/extensions/configlayout.py +++ b/novelwriter/extensions/configlayout.py @@ -58,8 +58,7 @@ class NConfigLayout(QGridLayout): ## def setHelpTextStyle(self, color: QColor | list | tuple, fontScale: float = FONT_SCALE): - """Set the text color for the help text. - """ + """Set the text color for the help text.""" if isinstance(color, QColor): self._helpCol = color else: @@ -68,8 +67,7 @@ class NConfigLayout(QGridLayout): return def setHelpText(self, row: int, text: str): - """Set the text for the help label. - """ + """Set the text for the help label.""" if row in self._itemMap: qHelp = self._itemMap[row][1] if isinstance(qHelp, NHelpLabel): @@ -77,8 +75,7 @@ class NConfigLayout(QGridLayout): return def setLabelText(self, row: int, text: str): - """Set the text for the main label. - """ + """Set the text for the main label.""" if row in self._itemMap: self._itemMap[row](0).setText(text) return @@ -88,8 +85,7 @@ class NConfigLayout(QGridLayout): ## def addGroupLabel(self, label: str): - """Adds a text label to separate groups of settings. - """ + """Add a text label to separate groups of settings.""" hM = CONFIG.pxInt(4) qLabel = QLabel("%s" % label) qLabel.setContentsMargins(0, hM, 0, hM) @@ -103,44 +99,35 @@ class NConfigLayout(QGridLayout): self, label: str, widget: QWidget, helpText: str | None = None, unit: str | None = None, button: QWidget | None = None ) -> int: - """Add a label and a widget as a new row of the grid. - """ - if isinstance(widget, QWidget): - qWidget = widget - else: - qWidget = None - raise ValueError("The widget must be a QWidget") - + """Add a label and a widget as a new row of the grid.""" wSp = CONFIG.pxInt(8) qLabel = QLabel(label) qLabel.setIndent(wSp) + qLabel.setBuddy(widget) qHelp = None if helpText is not None: qHelp = NHelpLabel(str(helpText), self._helpCol, self._fontScale) qHelp.setIndent(wSp) - labelBox = QVBoxLayout() labelBox.addWidget(qLabel) labelBox.addWidget(qHelp) labelBox.setSpacing(0) labelBox.addStretch(1) - self.addLayout(labelBox, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop) - else: self.addWidget(qLabel, self._nextRow, 0, 1, 1, Qt.AlignLeft | Qt.AlignTop) if isinstance(unit, str): controlBox = QHBoxLayout() - controlBox.addWidget(qWidget, 0, Qt.AlignVCenter) + controlBox.addWidget(widget, 0, Qt.AlignVCenter) controlBox.addWidget(QLabel(unit), 0, Qt.AlignVCenter) controlBox.setSpacing(wSp) self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) elif isinstance(button, QAbstractButton): controlBox = QHBoxLayout() - controlBox.addWidget(qWidget, 0, Qt.AlignVCenter) + controlBox.addWidget(widget, 0, Qt.AlignVCenter) controlBox.addWidget(button, 0, Qt.AlignVCenter) controlBox.setSpacing(wSp) self.addLayout(controlBox, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) @@ -151,14 +138,12 @@ class NConfigLayout(QGridLayout): qLayout.addWidget(widget) self.addLayout(qLayout, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) else: - self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) - - qLabel.setBuddy(qWidget) + self.addWidget(widget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) self.setRowStretch(self._nextRow, 0) self.setRowStretch(self._nextRow+1, 1) - self._itemMap[self._nextRow] = (qLabel, qHelp, qWidget) + self._itemMap[self._nextRow] = (qLabel, qHelp, widget) self._nextRow += 1 return self._nextRow - 1 @@ -187,8 +172,7 @@ class NSimpleLayout(QGridLayout): ## def addGroupLabel(self, label: str): - """Adds a text label to separate groups of settings. - """ + """Add a text label to separate groups of settings.""" hM = CONFIG.pxInt(4) qLabel = QLabel("%s" % label) qLabel.setContentsMargins(0, hM, 0, hM) @@ -199,14 +183,7 @@ class NSimpleLayout(QGridLayout): return def addRow(self, label: str, widget: QWidget): - """Add a label and a widget as a new row of the grid. - """ - if isinstance(widget, QWidget): - qWidget = widget - else: - qWidget = None - raise ValueError("The widget must be a QWidget") - + """Add a label and a widget as a new row of the grid.""" wSp = CONFIG.pxInt(8) qLabel = QLabel(label) qLabel.setIndent(wSp) @@ -217,9 +194,9 @@ class NSimpleLayout(QGridLayout): qLayout.addWidget(widget) self.addLayout(qLayout, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) else: - self.addWidget(qWidget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) + self.addWidget(widget, self._nextRow, 1, 1, 1, Qt.AlignRight | Qt.AlignTop) - qLabel.setBuddy(qWidget) + qLabel.setBuddy(widget) self.setRowStretch(self._nextRow, 0) self.setRowStretch(self._nextRow+1, 1) From e1ea28520197c9230eee0a327007dc499d7dc72d Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 19 Jul 2023 23:57:45 +0200 Subject: [PATCH 6/8] Update test reference files --- tests/reference/coreToOdt_SaveFlat_document.fodt | 6 +++--- tests/reference/coreToOdt_SaveFull_styles.xml | 2 +- .../reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/reference/coreToOdt_SaveFlat_document.fodt b/tests/reference/coreToOdt_SaveFlat_document.fodt index 1f49def3..70198aaa 100644 --- a/tests/reference/coreToOdt_SaveFlat_document.fodt +++ b/tests/reference/coreToOdt_SaveFlat_document.fodt @@ -1,13 +1,13 @@ - 2023-07-19T18:05:15 + 2023-07-19T23:55:29 novelWriter/2.1-beta1 Jane Smith 1234 P42DT12H34M56S Test Project - 2023-07-19T18:05:15 + 2023-07-19T23:55:29 Jane Smith @@ -64,7 +64,7 @@ - + diff --git a/tests/reference/coreToOdt_SaveFull_styles.xml b/tests/reference/coreToOdt_SaveFull_styles.xml index 37dbceb9..c52c6938 100644 --- a/tests/reference/coreToOdt_SaveFull_styles.xml +++ b/tests/reference/coreToOdt_SaveFull_styles.xml @@ -54,7 +54,7 @@ - + diff --git a/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt b/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt index 278a0632..1c5ccd36 100644 --- a/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt +++ b/tests/reference/mBuildDocBuild_OpenDocument_Lorem_Ipsum.fodt @@ -1,13 +1,13 @@ - 2023-07-19T18:05:14 + 2023-07-19T23:55:28 novelWriter/2.1-beta1 lipsum.com 42 P0DT0H31M53S Lorem Ipsum - 2023-07-19T18:05:14 + 2023-07-19T23:55:28 lipsum.com @@ -64,7 +64,7 @@ - + From dedb86b11d9c0468c3a0269e7fc202f553d6c9b3 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 20 Jul 2023 00:29:01 +0200 Subject: [PATCH 7/8] Make paper sizes translatable --- novelwriter/constants.py | 16 ++++++++++++++++ novelwriter/core/buildsettings.py | 9 --------- novelwriter/core/docbuild.py | 8 ++++---- novelwriter/tools/manussettings.py | 20 +++++++++++--------- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/novelwriter/constants.py b/novelwriter/constants.py index 6e974923..60ed8af3 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -235,6 +235,22 @@ class nwLabels: "cm": 10.0, "in": 25.4, } + PAPER_NAME = { + "A4": QT_TRANSLATE_NOOP("Constant", "A4"), + "A5": QT_TRANSLATE_NOOP("Constant", "A5"), + "A6": QT_TRANSLATE_NOOP("Constant", "A6"), + "Legal": QT_TRANSLATE_NOOP("Constant", "US Legal"), + "Letter": QT_TRANSLATE_NOOP("Constant", "US Letter"), + "Custom": QT_TRANSLATE_NOOP("Constant", "Custom"), + } + PAPER_SIZE = { + "A4": (210.0, 297.0), + "A5": (148.0, 210.0), + "A6": (105.0, 148.0), + "Legal": (215.9, 355.6), + "Letter": (215.9, 279.4), + "Custom": (-1.0, -1.0), + } # END Class nwLabels diff --git a/novelwriter/core/buildsettings.py b/novelwriter/core/buildsettings.py index aa826022..cba442e8 100644 --- a/novelwriter/core/buildsettings.py +++ b/novelwriter/core/buildsettings.py @@ -132,15 +132,6 @@ SETTINGS_LABELS = { "html.addStyles": QT_TRANSLATE_NOOP("Builds", "Add CSS Styles"), } -PAGE_SIZES = { - "A4": (210.0, 297.0), - "A5": (148.0, 210.0), - "A6": (105.0, 148.0), - "Legal": (215.9, 355.6), - "Letter": (215.9, 279.4), - "Custom": (-1.0, -1.0), -} - class FilterMode(Enum): """The decision reason for an item in a filtered project.""" diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py index a43112c0..e960debc 100644 --- a/novelwriter/core/docbuild.py +++ b/novelwriter/core/docbuild.py @@ -40,7 +40,7 @@ from novelwriter.core.toodt import ToOdt from novelwriter.core.tohtml import ToHtml from novelwriter.core.project import NWProject from novelwriter.core.tokenizer import Tokenizer -from novelwriter.core.buildsettings import PAGE_SIZES, BuildSettings +from novelwriter.core.buildsettings import BuildSettings logger = logging.getLogger(__name__) @@ -292,10 +292,10 @@ class NWBuildDocument: bldObj.setLanguage(buildLang) scale = nwLabels.UNIT_SCALE.get(self._build.getStr("format.pageUnit"), 1.0) - width, height = PAGE_SIZES.get(self._build.getStr("format.pageSize"), (-1.0, -1.0)) + pW, pH = nwLabels.PAPER_SIZE.get(self._build.getStr("format.pageSize"), (-1.0, -1.0)) bldObj.setPageLayout( - width if width > 0.0 else scale*self._build.getFloat("format.pageWidth"), - height if height > 0.0 else scale*self._build.getFloat("format.pageHeight"), + pW if pW > 0.0 else scale*self._build.getFloat("format.pageWidth"), + pH if pH > 0.0 else scale*self._build.getFloat("format.pageHeight"), scale*self._build.getFloat("format.topMargin"), scale*self._build.getFloat("format.bottomMargin"), scale*self._build.getFloat("format.leftMargin"), diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 6e6038c7..6a031bf0 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -41,7 +41,7 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG from novelwriter.constants import nwHeadFmt, nwLabels, trConst -from novelwriter.core.buildsettings import PAGE_SIZES, BuildSettings, FilterMode +from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.extensions.configlayout import NConfigLayout, NSimpleLayout @@ -1024,8 +1024,8 @@ class _FormatTab(QWidget): self.pageUnit.addItem(trConst(name), key) self.pageSize = QComboBox(self) - for key, size in PAGE_SIZES.items(): - self.pageSize.addItem(key, size) + for key, name in nwLabels.PAPER_NAME.items(): + self.pageSize.addItem(trConst(name), key) self.pageWidth = QDoubleSpinBox(self) self.pageWidth.setFixedWidth(dbW) @@ -1115,7 +1115,7 @@ class _FormatTab(QWidget): self.rightMargin.setValue(self._build.getFloat("format.rightMargin")) pageSize = self._build.getStr("format.pageSize") - index = self.pageSize.findText(pageSize) + index = self.pageSize.findData(pageSize) if index >= 0: self.pageSize.setCurrentIndex(index) self._changePageSize(index) @@ -1131,11 +1131,13 @@ class _FormatTab(QWidget): 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()) + self._build.setValue("format.pageUnit", str(self.pageUnit.currentData())) - self._build.setValue("format.pageSize", str(self.pageSize.currentText())) + self._build.setValue("format.pageSize", str(self.pageSize.currentData())) self._build.setValue("format.pageWidth", self.pageWidth.value()) self._build.setValue("format.pageHeight", self.pageHeight.value()) self._build.setValue("format.topMargin", self.topMargin.value()) @@ -1220,12 +1222,12 @@ class _FormatTab(QWidget): self.pageWidth.setEnabled(True) self.pageHeight.setEnabled(True) - width, height = self.pageSize.itemData(index) if index >= 0 else (-1.0, -1.0) - if width > 0.0 and height > 0.0: + w, h = nwLabels.PAPER_SIZE[self.pageSize.itemData(index)] if index >= 0 else (-1.0, -1.0) + if w > 0.0 and h > 0.0: self.pageWidth.setEnabled(False) self.pageHeight.setEnabled(False) - self.pageWidth.setValue(width/self._unitScale) - self.pageHeight.setValue(height/self._unitScale) + self.pageWidth.setValue(w/self._unitScale) + self.pageHeight.setValue(h/self._unitScale) return From 32a52b2bf1f5103d44057a8e6d068e0cc9ae83b5 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 20 Jul 2023 00:29:11 +0200 Subject: [PATCH 8/8] Update tests --- tests/test_tools/test_tools_manussettings.py | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/test_tools/test_tools_manussettings.py b/tests/test_tools/test_tools_manussettings.py index b4ae8e12..c455b623 100644 --- a/tests/test_tools/test_tools_manussettings.py +++ b/tests/test_tools/test_tools_manussettings.py @@ -519,10 +519,20 @@ def testBuildSettings_Format(monkeypatch, qtbot: QtBot, nwGUI: GuiMain): build.setValue("format.textFont", "") # Will fall back to config value build.setValue("format.textSize", 12) build.setValue("format.lineHeight", 1.2) + build.setValue("format.justifyText", False) build.setValue("format.stripUnicode", False) build.setValue("format.replaceTabs", False) + build.setValue("format.pageUnit", "mm") + build.setValue("format.pageSize", "Custom") + build.setValue("format.pageWidth", 180.0) + build.setValue("format.pageHeight", 250.0) + build.setValue("format.topMargin", 25.0) + build.setValue("format.bottomMargin", 25.0) + build.setValue("format.leftMargin", 15.0) + build.setValue("format.rightMargin", 15.0) + # Create the dialog and populate it bSettings = GuiBuildSettings(nwGUI, nwGUI, build) bSettings.show() @@ -537,19 +547,33 @@ def testBuildSettings_Format(monkeypatch, qtbot: QtBot, nwGUI: GuiMain): assert fmtTab.textFont.text() == textFont assert fmtTab.textSize.value() == 12 assert fmtTab.lineHeight.value() == 1.2 + assert fmtTab.justifyText.isChecked() is False assert fmtTab.stripUnicode.isChecked() is False assert fmtTab.replaceTabs.isChecked() is False + assert fmtTab.pageUnit.currentData() == "mm" + assert fmtTab.pageSize.currentData() == "Custom" + assert fmtTab.pageWidth.value() == 180.0 + assert fmtTab.pageHeight.value() == 250.0 + assert fmtTab.topMargin.value() == 25.0 + assert fmtTab.bottomMargin.value() == 25.0 + assert fmtTab.leftMargin.value() == 15.0 + assert fmtTab.rightMargin.value() == 15.0 + # Change values fmtTab.buildLang.setCurrentIndex(fmtTab.buildLang.findData("en_GB")) fmtTab.textFont.setText("Arial") fmtTab.textSize.setValue(11) fmtTab.lineHeight.setValue(1.15) + fmtTab.justifyText.setChecked(True) fmtTab.stripUnicode.setChecked(True) fmtTab.replaceTabs.setChecked(True) + fmtTab.pageUnit.setCurrentIndex(fmtTab.pageUnit.findData("cm")) + fmtTab.pageSize.setCurrentIndex(fmtTab.pageSize.findData("A4")) + # Save values fmtTab.saveContent() @@ -557,10 +581,20 @@ def testBuildSettings_Format(monkeypatch, qtbot: QtBot, nwGUI: GuiMain): assert build.getStr("format.textFont") == "Arial" assert build.getInt("format.textSize") == 11 assert build.getFloat("format.lineHeight") == 1.15 + assert build.getBool("format.justifyText") is True assert build.getBool("format.stripUnicode") is True assert build.getBool("format.replaceTabs") is True + assert fmtTab.pageUnit.currentData() == "cm" + assert fmtTab.pageSize.currentData() == "A4" + assert fmtTab.pageWidth.value() == 21.0 + assert fmtTab.pageHeight.value() == 29.7 + assert fmtTab.topMargin.value() == 2.5 + assert fmtTab.bottomMargin.value() == 2.5 + assert fmtTab.leftMargin.value() == 1.5 + assert fmtTab.rightMargin.value() == 1.5 + # Check that the font dialog doesn't fail with monkeypatch.context() as mp: font = QFont()