diff --git a/novelwriter/config.py b/novelwriter/config.py index fb2ff9d3..9e010c55 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -252,6 +252,10 @@ class Config: def hasError(self) -> bool: return self._hasError + @property + def locale(self) -> QLocale: + return self._dLocale + @property def recentProjects(self) -> RecentProjects: return self._recentProjects @@ -469,10 +473,6 @@ class Config: """Return a localised datetime format.""" return self._dLocale.toString(value, self._dShortDateTime) - def localInt(self, value: int) -> str: - """Return a localised integer.""" - return self._dLocale.toString(value) - def listLanguages(self, lngSet: int) -> list[tuple[str, str]]: """List localisation files in the i18n folder. The default GUI language is British English (en_GB). diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py index ba3e469d..14b4ed16 100644 --- a/novelwriter/core/docbuild.py +++ b/novelwriter/core/docbuild.py @@ -224,7 +224,9 @@ class NWBuildDocument: # Get Settings textFont = QFont(CONFIG.textFont) textFont.fromString(self._build.getStr("format.textFont")) + bldObj.setFont(textFont) + bldObj.setLanguage(self._project.data.language) bldObj.setPartitionFormat( self._build.getStr("headings.fmtPart"), @@ -322,7 +324,6 @@ class NWBuildDocument: bldObj.setReplaceUnicode(self._build.getBool("format.stripUnicode")) if isinstance(bldObj, (ToOdt, ToDocX)): - bldObj.setLanguage(self._project.data.language) bldObj.setHeaderFormat( self._build.getStr("doc.pageHeader"), self._build.getInt("doc.pageCountOffset"), diff --git a/novelwriter/formats/todocx.py b/novelwriter/formats/todocx.py index 55cdca21..6461cfe9 100644 --- a/novelwriter/formats/todocx.py +++ b/novelwriter/formats/todocx.py @@ -36,7 +36,7 @@ from zipfile import ZIP_DEFLATED, ZipFile from PyQt5.QtCore import QMarginsF, QSizeF from PyQt5.QtGui import QColor -from novelwriter import CONFIG, __version__ +from novelwriter import __version__ from novelwriter.common import firstFloat, xmlSubElem from novelwriter.constants import nwHeadFmt, nwStyles from novelwriter.core.project import NWProject @@ -182,7 +182,6 @@ class ToDocX(Tokenizer): # Internal self._fontFamily = "Liberation Serif" self._fontSize = 12.0 - self._dLanguage = "en_GB" self._pageSize = QSizeF(210.0, 297.0) self._pageMargins = QMarginsF(20.0, 20.0, 20.0, 20.0) @@ -200,12 +199,6 @@ class ToDocX(Tokenizer): # Setters ## - def setLanguage(self, language: str | None) -> None: - """Set language for the document.""" - if language: - self._dLanguage = language.replace("_", "-") - return - def setPageLayout( self, width: float, height: float, top: float, bottom: float, left: float, right: float ) -> None: @@ -740,7 +733,7 @@ class ToDocX(Tokenizer): xmlSubElem(xRoot, _mkTag("dcterms", "modified"), timeStamp, attrib=tsAttr) xmlSubElem(xRoot, _mkTag("dc", "creator"), self._project.data.author) xmlSubElem(xRoot, _mkTag("dc", "title"), self._project.data.name) - xmlSubElem(xRoot, _mkTag("dc", "language"), self._dLanguage) + xmlSubElem(xRoot, _mkTag("dc", "language"), self._dLocale.name()) xmlSubElem(xRoot, _mkTag("cp", "revision"), str(self._project.data.saveCount)) xmlSubElem(xRoot, _mkTag("cp", "lastModifiedBy"), self._project.data.author) @@ -777,7 +770,7 @@ class ToDocX(Tokenizer): }) xmlSubElem(xRPr, _wTag("sz"), attrib={W_VAL: size}) xmlSubElem(xRPr, _wTag("szCs"), attrib={W_VAL: size}) - xmlSubElem(xRPr, _wTag("lang"), attrib={W_VAL: self._dLanguage}) + xmlSubElem(xRPr, _wTag("lang"), attrib={W_VAL: self._dLocale.name()}) xmlSubElem(xPPr, _wTag("spacing"), attrib={_wTag("line"): line}) # Paragraph Styles @@ -936,7 +929,7 @@ class ToDocX(Tokenizer): if self._usedFields and self._counts: for xField, field in self._usedFields: if (value := self._counts.get(field)) is not None: - xField.text = CONFIG.localInt(value) + xField.text = self._formatInt(value) # Write Paragraphs for par in pars: diff --git a/novelwriter/formats/tohtml.py b/novelwriter/formats/tohtml.py index ca89e3fe..15ce897a 100644 --- a/novelwriter/formats/tohtml.py +++ b/novelwriter/formats/tohtml.py @@ -29,7 +29,6 @@ import logging from pathlib import Path from time import time -from novelwriter import CONFIG from novelwriter.common import formatTimeStamp from novelwriter.constants import nwHtmlUnicode from novelwriter.core.project import NWProject @@ -259,7 +258,7 @@ class ToHtml(Tokenizer): for doc, field in self._usedFields: if doc >= 0 and doc < pages and (value := self._counts.get(field)) is not None: self._pages[doc] = self._pages[doc].replace( - f"{{{{{field}}}}}", CONFIG.localInt(value) + f"{{{{{field}}}}}", self._formatInt(value) ) # Add footnotes diff --git a/novelwriter/formats/tokenizer.py b/novelwriter/formats/tokenizer.py index 64017e7e..759185c7 100644 --- a/novelwriter/formats/tokenizer.py +++ b/novelwriter/formats/tokenizer.py @@ -31,6 +31,7 @@ from abc import ABC, abstractmethod from pathlib import Path from typing import NamedTuple +from PyQt5.QtCore import QLocale from PyQt5.QtGui import QColor, QFont from novelwriter import CONFIG @@ -104,6 +105,7 @@ class Tokenizer(ABC): self._outline: dict[str, str] = {} # User Settings + self._dLocale = CONFIG.locale # The document locale self._textFont = QFont("Serif", 11) # Output text font self._lineHeight = 1.15 # Line height in units of em self._colorHeads = True # Colourise headings @@ -226,6 +228,12 @@ class Tokenizer(ABC): # Setters ## + def setLanguage(self, language: str | None) -> None: + """Set language for the document.""" + if language: + self._dLocale = QLocale(language) + return + def setTheme(self, theme: TextDocumentTheme) -> None: """Set the document colour theme.""" self._theme = theme @@ -1033,6 +1041,10 @@ class Tokenizer(ABC): # Internal Functions ## + def _formatInt(self, value: int) -> str: + """Return a localised integer.""" + return self._dLocale.toString(value) + def _formatComment(self, style: ComStyle, key: str, text: str) -> tuple[str, T_Formats]: """Apply formatting to comments and notes.""" tTxt, tFmt = self._extractFormats(text) diff --git a/novelwriter/formats/tomarkdown.py b/novelwriter/formats/tomarkdown.py index d7981249..f2f1284d 100644 --- a/novelwriter/formats/tomarkdown.py +++ b/novelwriter/formats/tomarkdown.py @@ -27,7 +27,6 @@ import logging from pathlib import Path -from novelwriter import CONFIG from novelwriter.constants import nwUnicode from novelwriter.core.project import NWProject from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt @@ -159,7 +158,7 @@ class ToMarkdown(Tokenizer): for doc, field in self._usedFields: if doc >= 0 and doc < pages and (value := self._counts.get(field)) is not None: self._pages[doc] = self._pages[doc].replace( - f"{{{{{field}}}}}", CONFIG.localInt(value) + f"{{{{{field}}}}}", self._formatInt(value) ) # Add footnotes diff --git a/novelwriter/formats/toodt.py b/novelwriter/formats/toodt.py index 0845b14a..b3286170 100644 --- a/novelwriter/formats/toodt.py +++ b/novelwriter/formats/toodt.py @@ -223,14 +223,6 @@ class ToOdt(Tokenizer): # Setters ## - def setLanguage(self, language: str | None) -> None: - """Set language for the document.""" - if language: - lang, _, country = language.partition("_") - self._dLanguage = lang or self._dLanguage - self._dCountry = country or self._dCountry - return - def setPageLayout( self, width: float, height: float, top: float, bottom: float, left: float, right: float ) -> None: @@ -264,6 +256,10 @@ class ToOdt(Tokenizer): fontWeight = str(intWeight) fontBold = str(min(intWeight + 300, 900)) + lang, _, country = self._dLocale.name().partition("_") + self._dLanguage = lang or self._dLanguage + self._dCountry = country or self._dCountry + self._fontFamily = self._textFont.family() self._fontSize = self._textFont.pointSize() self._fontWeight = FONT_WEIGHT_MAP.get(fontWeight, fontWeight) diff --git a/novelwriter/formats/toqdoc.py b/novelwriter/formats/toqdoc.py index 0bb32d4f..de0a344c 100644 --- a/novelwriter/formats/toqdoc.py +++ b/novelwriter/formats/toqdoc.py @@ -34,7 +34,6 @@ from PyQt5.QtGui import ( ) from PyQt5.QtPrintSupport import QPrinter -from novelwriter import CONFIG from novelwriter.constants import nwStyles, nwUnicode from novelwriter.core.project import NWProject from novelwriter.formats.shared import BlockFmt, BlockTyp, T_Formats, TextFmt @@ -259,7 +258,7 @@ class ToQTextDocument(Tokenizer): if (value := self._counts.get(field)) is not None: cursor.setPosition(pos, QtMoveAnchor) cursor.setPosition(pos + 1, QtKeepAnchor) - cursor.insertText(CONFIG.localInt(value)) + cursor.insertText(self._formatInt(value)) # Add footnotes if self._usedNotes: diff --git a/tests/reference/fmtToDocX_SaveDocument_core.xml b/tests/reference/fmtToDocX_SaveDocument_core.xml index 1e503ab2..2d07ced8 100644 --- a/tests/reference/fmtToDocX_SaveDocument_core.xml +++ b/tests/reference/fmtToDocX_SaveDocument_core.xml @@ -1,10 +1,10 @@ - 2024-10-28T18:23:43 - 2024-10-28T18:23:43 + 2024-10-28T20:12:57 + 2024-10-28T20:12:57 lipsum.com Lorem Ipsum - en-GB + en_GB 50 lipsum.com diff --git a/tests/reference/fmtToDocX_SaveDocument_styles.xml b/tests/reference/fmtToDocX_SaveDocument_styles.xml index e2a654e1..f730b33a 100644 --- a/tests/reference/fmtToDocX_SaveDocument_styles.xml +++ b/tests/reference/fmtToDocX_SaveDocument_styles.xml @@ -6,7 +6,7 @@ - + diff --git a/tests/reference/fmtToOdt_SaveFlat_document.fodt b/tests/reference/fmtToOdt_SaveFlat_document.fodt index 3beacd02..508c8cd9 100644 --- a/tests/reference/fmtToOdt_SaveFlat_document.fodt +++ b/tests/reference/fmtToOdt_SaveFlat_document.fodt @@ -1,13 +1,13 @@ - 2024-10-22T14:19:48 - novelWriter/2.6a1 + 2024-10-28T20:17:34 + novelWriter/2.6a3 Jane Smith 1234 P42DT12H34M56S Test Project - 2024-10-22T14:19:48 + 2024-10-28T20:17:34 Jane Smith @@ -16,7 +16,7 @@ - + diff --git a/tests/test_formats/test_fmt_toodt.py b/tests/test_formats/test_fmt_toodt.py index a6ebf6b7..536c977e 100644 --- a/tests/test_formats/test_fmt_toodt.py +++ b/tests/test_formats/test_fmt_toodt.py @@ -780,11 +780,6 @@ def testFmtToOdt_SaveFlat(mockGUI, fncPath, tstPaths): odt = ToOdt(project, isFlat=True) odt._isNovel = True - odt._dLanguage = "" - odt.setLanguage(None) # type: ignore - assert odt._dLanguage == "" - odt.setLanguage("nb_NO") - assert odt._dLanguage == "nb" odt.setHeaderFormat(nwHeadFmt.DOC_AUTO, 1) assert odt._headerFormat == nwHeadFmt.DOC_AUTO odt.setFirstLineIndent(True, 1.4, False)