diff --git a/i18n/nw_base.ts b/i18n/nw_base.ts
index b4728c00..7360cfe3 100644
--- a/i18n/nw_base.ts
+++ b/i18n/nw_base.ts
@@ -1313,6 +1313,11 @@
novelWriter is ready ...
+
+
+ You are now running novelWriter version {0}.
+
+
Please check the {0}release notes{1} for further details.
@@ -4169,73 +4174,67 @@
-
+
+ Add {0} chapter documents
+
+
+
- Add
+ Add {0} scene documents (to each chapter)
-
- chapter documents
-
-
-
-
- scene documents (to each chapter)
-
-
-
-
+
Add a folder for plot notes
-
+
Add a folder for character notes
-
+
Add a folder for location notes
-
+
Add example notes to the above
-
+
Chapters and Scenes
-
+
Project Notes
-
+
Create New Project
-
+
Select Project Folder
-
+
Fresh Project
-
+
Example Project
-
+
Template: {0}
diff --git a/i18n/nw_de_DE.ts b/i18n/nw_de_DE.ts
index 3ab9c8f6..9c7f2b15 100644
--- a/i18n/nw_de_DE.ts
+++ b/i18n/nw_de_DE.ts
@@ -311,7 +311,7 @@
Characters
- Charaktere
+ Figuren
@@ -394,7 +394,7 @@
Novel Scene
- Roman Szene
+ Szene
@@ -1313,6 +1313,11 @@
novelWriter is ready ...
novelWriter ist bereit ...
+
+
+ You are now running novelWriter version {0}.
+ Sie verwenden jetzt die novelWriter-Version {0}.
+
Please check the {0}release notes{1} for further details.
@@ -2322,7 +2327,7 @@
Characters
- Charaktere
+ Zeichen
@@ -3175,37 +3180,37 @@
GuiWelcome
-
+
Welcome
Willkommen
-
+
List
Liste
-
+
New
Neu
-
+
Browse
Auswählen
-
+
Cancel
Abbrechen
-
+
Create
Erstellen
-
+
Open
Öffnen
@@ -4119,123 +4124,117 @@
_NewProjectForm
-
+
Required
Erforderlich
-
+
Optional
Optional
-
+
Create a fresh project
Neues Projekt erstellen
-
+
Create an example project
Beispielprojekt erstellen
-
+
Copy an existing project
Vorhandenes Projekt kopieren
-
+
Project Name
Projektname
-
+
Author
Autor
-
+
Project Path
Projektpfad
-
+
Prefill Project
Projekt vorbereiten
-
+
Set to 0 to only add scenes
Auf 0 setzen um nur Szenen hinzuzufügen
+
+
+ Add {0} chapter documents
+ {0} Kapiteldokumente hinzufügen
+
-
- Add
-
+ Add {0} scene documents (to each chapter)
+ {0} Szenendokumente hinzufügen (pro Kapitel)
-
- chapter documents
- Kapitel
-
-
-
- scene documents (to each chapter)
- Szenen (pro Kapitel)
-
-
-
+
Add a folder for plot notes
Ordner hinzufügen: Notizen für Handlungsstränge
-
+
Add a folder for character notes
Ordner hinzufügen: Notizen für Figuren
-
+
Add a folder for location notes
Ordner hinzufügen: Notizen für Schauplätze
-
+
Add example notes to the above
Beispielnotizen zur obigen Auswahl hinzufügen
-
+
Chapters and Scenes
Kapitel und Szenen
-
+
Project Notes
Projektnotizen
-
+
Create New Project
Neues Projekt erstellen
-
+
Select Project Folder
Speicherort wählen
-
+
Fresh Project
Neues Projekt
-
+
Example Project
Beispielprojekt
-
+
Template: {0}
Vorlage: {0}
@@ -4243,7 +4242,7 @@
_NewProjectPage
-
+
A project name is required.
Ein Projektname ist erforderlich.
@@ -4251,27 +4250,27 @@
_OpenProjectPage
-
+
The project path is not reachable.
Der Projektpfad ist nicht erreichbar.
-
+
Path
Pfad
-
+
Remove '{0}' from the recent projects list? The project files will not be deleted.
„{0}“ von der Liste der zuletzt geöffneten Projekte entfernen? Ihre Daten werden nicht gelöscht.
-
+
Open Project
Projekt öffnen
-
+
Remove Project
Projekt entfernen
@@ -4362,12 +4361,12 @@
_ProjectListModel
-
+
Word Count
Wörter
-
+
Last Opened
Zuletzt geöffnet
@@ -4382,7 +4381,7 @@
Keyword
- Schlagwort
+ Stichwort
diff --git a/i18n/nw_en_US.ts b/i18n/nw_en_US.ts
index 89d04722..597c1248 100644
--- a/i18n/nw_en_US.ts
+++ b/i18n/nw_en_US.ts
@@ -1313,6 +1313,11 @@
novelWriter is ready ...
novelWriter is ready ...
+
+
+ You are now running novelWriter version {0}.
+ You are now running novelWriter version {0}.
+
Please check the {0}release notes{1} for further details.
@@ -3175,37 +3180,37 @@
GuiWelcome
-
+
Welcome
Welcome
-
+
List
List
-
+
New
New
-
+
Browse
Browse
-
+
Cancel
Cancel
-
+
Create
Create
-
+
Open
Open
@@ -4119,123 +4124,117 @@
_NewProjectForm
-
+
Required
Required
-
+
Optional
Optional
-
+
Create a fresh project
Create a fresh project
-
+
Create an example project
Create an example project
-
+
Copy an existing project
Copy an existing project
-
+
Project Name
Project Name
-
+
Author
Author
-
+
Project Path
Project Path
-
+
Prefill Project
Prefill Project
-
+
Set to 0 to only add scenes
Set to 0 to only add scenes
+
+
+ Add {0} chapter documents
+ Add {0} chapter documents
+
-
- Add
- Add
+ Add {0} scene documents (to each chapter)
+ Add {0} scene documents (to each chapter)
-
- chapter documents
- chapter documents
-
-
-
- scene documents (to each chapter)
- scene documents (to each chapter)
-
-
-
+
Add a folder for plot notes
Add a folder for plot notes
-
+
Add a folder for character notes
Add a folder for character notes
-
+
Add a folder for location notes
Add a folder for location notes
-
+
Add example notes to the above
Add example notes to the above
-
+
Chapters and Scenes
Chapters and Scenes
-
+
Project Notes
Project Notes
-
+
Create New Project
Create New Project
-
+
Select Project Folder
Select Project Folder
-
+
Fresh Project
Fresh Project
-
+
Example Project
Example Project
-
+
Template: {0}
Template: {0}
@@ -4243,7 +4242,7 @@
_NewProjectPage
-
+
A project name is required.
A project name is required.
@@ -4251,27 +4250,27 @@
_OpenProjectPage
-
+
The project path is not reachable.
The project path is not reachable.
-
+
Path
Path
-
+
Remove '{0}' from the recent projects list? The project files will not be deleted.
Remove '{0}' from the recent projects list? The project files will not be deleted.
-
+
Open Project
Open Project
-
+
Remove Project
Remove Project
@@ -4362,12 +4361,12 @@
_ProjectListModel
-
+
Word Count
Word Count
-
+
Last Opened
Last Opened
diff --git a/i18n/nw_nb_NO.ts b/i18n/nw_nb_NO.ts
index dc025e97..c06d29da 100644
--- a/i18n/nw_nb_NO.ts
+++ b/i18n/nw_nb_NO.ts
@@ -1313,6 +1313,11 @@
novelWriter is ready ...
novelWriter er klar ...
+
+
+ You are now running novelWriter version {0}.
+ Du kjører nå novelWriter versjon {0}.
+
Please check the {0}release notes{1} for further details.
@@ -3175,37 +3180,37 @@
GuiWelcome
-
+
Welcome
Velkommen
-
+
List
Liste
-
+
New
Nytt
-
+
Browse
Bla gjennom
-
+
Cancel
Avbryt
-
+
Create
Opprett
-
+
Open
Åpne
@@ -4119,123 +4124,117 @@
_NewProjectForm
-
+
Required
Påkrevd
-
+
Optional
Valgfritt
-
+
Create a fresh project
Opprett et nytt prosjekt
-
+
Create an example project
Opprett et eksempelprosjekt
-
+
Copy an existing project
Kopier et eksisterende prosjekt
-
+
Project Name
Prosjektnavn
-
+
Author
Forfatter
-
+
Project Path
Filbane
-
+
Prefill Project
Forhåndsfyll prosjektet
-
+
Set to 0 to only add scenes
Satt til 0 for bare å legge til scener
+
+
+ Add {0} chapter documents
+ Legg til {0} kapitteldokumenter
+
-
- Add
- Legg til
+ Add {0} scene documents (to each chapter)
+ Legg til {0} scenedokumenter (til hvert kapittel)
-
- chapter documents
- kapittel-dokumenter
-
-
-
- scene documents (to each chapter)
- scene-dokumenter (i hvert kapittel)
-
-
-
+
Add a folder for plot notes
Legg til en mappe for plott-notater
-
+
Add a folder for character notes
Legg til en mappe for karakterer
-
+
Add a folder for location notes
Legg til en mappe for lokasjoner
-
+
Add example notes to the above
Lag eksempelfiler til ovennevnte
-
+
Chapters and Scenes
Kapittel og scener
-
+
Project Notes
Prosjektnotater
-
+
Create New Project
Opprett nytt prosjekt
-
+
Select Project Folder
Velg prosjektmappe
-
+
Fresh Project
Nytt prosjekt
-
+
Example Project
Eksempelprosjekt
-
+
Template: {0}
Mal: {0}
@@ -4243,7 +4242,7 @@
_NewProjectPage
-
+
A project name is required.
Vennligst oppgi et prosjektnavn.
@@ -4251,27 +4250,27 @@
_OpenProjectPage
-
+
The project path is not reachable.
Prosjektets bane er ikke tilgjengelig.
-
+
Path
Filbane
-
+
Remove '{0}' from the recent projects list? The project files will not be deleted.
Vil du fjerne {0} fra listen over tidligere åpnede prosjekter? Selve prosjektfilene blir ikke slettet.
-
+
Open Project
Åpne prosjekt
-
+
Remove Project
Fjern prosjekt
@@ -4362,12 +4361,12 @@
_ProjectListModel
-
+
Word Count
Antall ord
-
+
Last Opened
Sist åpnet
diff --git a/novelwriter/config.py b/novelwriter/config.py
index 568c0376..85786119 100644
--- a/novelwriter/config.py
+++ b/novelwriter/config.py
@@ -30,6 +30,7 @@ import logging
from time import time
from pathlib import Path
+from datetime import datetime
from PyQt5.QtGui import QFontDatabase
from PyQt5.QtCore import (
@@ -84,8 +85,11 @@ class Config:
self._nwLangPath = self._appPath / "assets" / "i18n"
self._qtLangPath = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
- wantedLocale = self._nwLangPath / f"nw_{QLocale.system().name()}.qm"
- self._qLocale = QLocale.system() if wantedLocale.exists() else QLocale("en_GB")
+ hasLocale = (self._nwLangPath / f"nw_{QLocale.system().name()}.qm").exists()
+ self._qLocale = QLocale.system() if hasLocale else QLocale("en_GB")
+ self._dLocale = QLocale.system()
+ self._dShortDate = self._dLocale.dateFormat(QLocale.FormatType.ShortFormat)
+ self._dShortDateTime = self._dLocale.dateTimeFormat(QLocale.FormatType.ShortFormat)
self._qtTrans = {}
# PDF Manual
@@ -414,6 +418,14 @@ class Config:
self._errData = []
return message
+ def localDate(self, value: datetime) -> str:
+ """Return a localised date format."""
+ return self._dLocale.toString(value, self._dShortDate)
+
+ def localDateTime(self, value: datetime) -> str:
+ """Return a localised datetime format."""
+ return self._dLocale.toString(value, self._dShortDateTime)
+
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).
@@ -496,6 +508,11 @@ class Config:
QLocale.setDefault(self._qLocale)
self._qtTrans = {}
+ hasLocale = (self._nwLangPath / f"nw_{self._qLocale.name()}.qm").exists()
+ self._dLocale = self._qLocale if hasLocale else QLocale.system()
+ self._dShortDate = self._dLocale.dateFormat(QLocale.FormatType.ShortFormat)
+ self._dShortDateTime = self._dLocale.dateTimeFormat(QLocale.FormatType.ShortFormat)
+
langList = [
(self._qtLangPath, "qtbase"), # Qt 5.x
(str(self._nwLangPath), "nw"), # novelWriter
diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py
index 690ad08e..142b837d 100644
--- a/novelwriter/dialogs/preferences.py
+++ b/novelwriter/dialogs/preferences.py
@@ -151,8 +151,7 @@ class GuiPreferences(QDialog):
self.guiLocale.setMinimumWidth(minWidth)
for lang, name in CONFIG.listLanguages(CONFIG.LANG_NW):
self.guiLocale.addItem(name, lang)
- if (idx := self.guiLocale.findData(CONFIG.guiLocale)) != -1:
- self.guiLocale.setCurrentIndex(idx)
+ self.guiLocale.setCurrentData(CONFIG.guiLocale, "en_GB")
self.mainForm.addRow(
self.tr("Display language"), self.guiLocale,
@@ -164,8 +163,7 @@ class GuiPreferences(QDialog):
self.guiTheme.setMinimumWidth(minWidth)
for theme, name in SHARED.theme.listThemes():
self.guiTheme.addItem(name, theme)
- if (idx := self.guiTheme.findData(CONFIG.guiTheme)) != -1:
- self.guiTheme.setCurrentIndex(idx)
+ self.guiTheme.setCurrentData(CONFIG.guiTheme, "default")
self.mainForm.addRow(
self.tr("Colour theme"), self.guiTheme,
@@ -226,8 +224,7 @@ class GuiPreferences(QDialog):
self.guiSyntax.setMinimumWidth(CONFIG.pxInt(200))
for syntax, name in SHARED.theme.listSyntax():
self.guiSyntax.addItem(name, syntax)
- if (idx := self.guiSyntax.findData(CONFIG.guiSyntax)) != -1:
- self.guiSyntax.setCurrentIndex(idx)
+ self.guiSyntax.setCurrentData(CONFIG.guiSyntax, "default_light")
self.mainForm.addRow(
self.tr("Document colour theme"), self.guiSyntax,
diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py
index aa168778..280caedc 100644
--- a/novelwriter/extensions/configlayout.py
+++ b/novelwriter/extensions/configlayout.py
@@ -7,6 +7,7 @@ Created: 2020-05-03 [0.4.5] NColourLabel
Created: 2024-01-08 [2.3b1] NScrollableForm
Created: 2024-01-26 [2.3b1] NScrollablePage
Created: 2024-01-26 [2.3b1] NFixedPage
+Created: 2024-03-12 [2.4b1] NWrappedWidgetBox
This file is a part of novelWriter
Copyright 2018–2024, Veronica Berglyd Olsen
@@ -269,3 +270,24 @@ class NColourLabel(QLabel):
return
# END Class NColourLabel
+
+
+class NWrappedWidgetBox(QHBoxLayout):
+ """Extension: A Text-Wrapped Widget Box
+
+ A custom layout box where a widget is wrapped in text labels on
+ either side within a layout box. The widget is inserted at the {0}
+ position so that it can be used for translation strings.
+ """
+
+ def __init__(self, text: str, widget: QWidget) -> None:
+ super().__init__()
+ before, _, after = text.partition(r"{0}")
+ if before:
+ self.addWidget(QLabel(before.rstrip()))
+ self.addWidget(widget)
+ if after:
+ self.addWidget(QLabel(after.lstrip()))
+ return
+
+# END Class NWrappedWidgetBox
diff --git a/novelwriter/extensions/modified.py b/novelwriter/extensions/modified.py
index cebb8b74..39416b23 100644
--- a/novelwriter/extensions/modified.py
+++ b/novelwriter/extensions/modified.py
@@ -44,6 +44,12 @@ class NComboBox(QComboBox):
event.ignore()
return
+ def setCurrentData(self, data: str, default: str) -> None:
+ """Set the current index from data, with a fallback."""
+ idx = self.findData(data)
+ self.setCurrentIndex(self.findData(default) if idx < 0 else idx)
+ return
+
# END Class NComboBox
diff --git a/novelwriter/extensions/versioninfo.py b/novelwriter/extensions/versioninfo.py
index 08cbc74e..6ac78794 100644
--- a/novelwriter/extensions/versioninfo.py
+++ b/novelwriter/extensions/versioninfo.py
@@ -57,7 +57,7 @@ class VersionInfoWidget(QWidget):
# Labels
self._lblInfo = QLabel("{0} {1} \u2013 {2} {3} \u2013 {4}".format(
self.tr("Version"), formatVersion(__version__),
- self.tr("Released on"), datetime.strptime(__date__, "%Y-%m-%d").strftime("%x"),
+ self.tr("Released on"), CONFIG.localDate(datetime.strptime(__date__, "%Y-%m-%d")),
"{0}".format(self.tr("Release Notes")),
), self)
self._lblInfo.linkActivated.connect(self._processLink)
diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py
index 9ca97ba7..f2a3e8ff 100644
--- a/novelwriter/guimain.py
+++ b/novelwriter/guimain.py
@@ -355,8 +355,8 @@ class GuiMain(QMainWindow):
if hexToInt(CONFIG.lastNotes) < hexToInt(__hexversion__):
CONFIG.lastNotes = __hexversion__
trVersion = self.tr(
- "You are now running novelWriter version {0}.".format(formatVersion(__version__))
- )
+ "You are now running novelWriter version {0}."
+ ).format(formatVersion(__version__))
trRelease = self.tr(
"Please check the {0}release notes{1} for further details."
).format(f"", "")
@@ -457,7 +457,7 @@ class GuiMain(QMainWindow):
"'{0}' ({1} {2}), last active on {3}."
).format(
lockStatus[0], lockStatus[1], lockStatus[2],
- datetime.fromtimestamp(int(lockStatus[3])).strftime("%x %X")
+ CONFIG.localDateTime(datetime.fromtimestamp(int(lockStatus[3])))
)
except Exception:
lockDetails = ""
diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py
index aa686d74..3f52e9c8 100644
--- a/novelwriter/tools/manuscript.py
+++ b/novelwriter/tools/manuscript.py
@@ -827,7 +827,7 @@ class _PreviewWidget(QTextBrowser):
"""Update the build time and the fuzzy age."""
if self._docTime > 0:
strBuildTime = "%s (%s)" % (
- datetime.fromtimestamp(self._docTime).strftime("%x %X"),
+ CONFIG.localDateTime(datetime.fromtimestamp(self._docTime)),
fuzzyTime(int(time()) - self._docTime)
)
else:
diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py
index 99d0c901..ec7869f5 100644
--- a/novelwriter/tools/welcome.py
+++ b/novelwriter/tools/welcome.py
@@ -45,6 +45,7 @@ from novelwriter.enum import nwItemClass
from novelwriter.common import formatInt, makeFileNameSafe
from novelwriter.constants import nwFiles
from novelwriter.core.coretools import ProjectBuilder
+from novelwriter.extensions.configlayout import NWrappedWidgetBox
from novelwriter.extensions.switch import NSwitch
from novelwriter.extensions.modified import NSpinBox
from novelwriter.extensions.versioninfo import VersionInfoWidget
@@ -455,7 +456,7 @@ class _ProjectListModel(QAbstractListModel):
opened = self.tr("Last Opened")
records = sorted(CONFIG.recentProjects.listEntries(), key=lambda x: x[3], reverse=True)
for path, title, count, time in records:
- when = datetime.fromtimestamp(time).strftime("%x")
+ when = CONFIG.localDate(datetime.fromtimestamp(time))
data.append((title, path, f"{opened}: {when}, {words}: {formatInt(count)}"))
self._data = data
return
@@ -630,20 +631,18 @@ class _NewProjectForm(QWidget):
self.numChapters.setValue(5)
self.numChapters.setToolTip(self.tr("Set to 0 to only add scenes"))
- self.chapterBox = QHBoxLayout()
- self.chapterBox.addWidget(QLabel(self.tr("Add")))
- self.chapterBox.addWidget(self.numChapters)
- self.chapterBox.addWidget(QLabel(self.tr("chapter documents")))
+ self.chapterBox = NWrappedWidgetBox(
+ self.tr("Add {0} chapter documents"), self.numChapters
+ )
self.chapterBox.addStretch(1)
self.numScenes = NSpinBox(self)
self.numScenes.setRange(0, 200)
self.numScenes.setValue(5)
- self.sceneBox = QHBoxLayout()
- self.sceneBox.addWidget(QLabel(self.tr("Add")))
- self.sceneBox.addWidget(self.numScenes)
- self.sceneBox.addWidget(QLabel(self.tr("scene documents (to each chapter)")))
+ self.sceneBox = NWrappedWidgetBox(
+ self.tr("Add {0} scene documents (to each chapter)"), self.numScenes
+ )
self.sceneBox.addStretch(1)
self.novelForm = QVBoxLayout()
diff --git a/tests/test_tools/test_tools_welcome.py b/tests/test_tools/test_tools_welcome.py
index 11d2e6c3..29900674 100644
--- a/tests/test_tools/test_tools_welcome.py
+++ b/tests/test_tools/test_tools_welcome.py
@@ -75,8 +75,8 @@ def testToolWelcome_Open(qtbot: QtBot, monkeypatch, nwGUI, fncPath):
CONFIG.recentProjects.update("/stuff/project_one", "Project One", 12345, 1690000000)
CONFIG.recentProjects.update("/stuff/project_two", "Project Two", 54321, 1700000000)
- dateOne = datetime.fromtimestamp(1700000000).strftime("%x")
- dateTwo = datetime.fromtimestamp(1690000000).strftime("%x")
+ dateOne = CONFIG.localDate(datetime.fromtimestamp(1700000000))
+ dateTwo = CONFIG.localDate(datetime.fromtimestamp(1690000000))
welcome = GuiWelcome(nwGUI)
with qtbot.waitExposed(welcome):