diff --git a/.github/workflows/syntax.yml b/.github/workflows/syntax.yml
index 567c40f6..01e4e8ea 100644
--- a/.github/workflows/syntax.yml
+++ b/.github/workflows/syntax.yml
@@ -1,4 +1,4 @@
-name: flake8
+name: Flake8
on:
push:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ac00b49..39b57f01 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,82 @@
# novelWriter Changelog
+## Version 2.2 Beta 1 [2023-11-11]
+
+### Release Notes
+
+This is a beta release of the next release version, and is intended for testing purposes. Please be
+careful when using this version on live writing projects, and make sure you take frequent backups.
+
+Please check the changelog for an overview of changes. The full release notes will be added to the
+final release.
+
+### Detailed Changelog
+
+**Features**
+
+* novelWriter has a new logo and icon. PR #1593.
+* The Document Editor is now a true plain text editor. This has a number of benefits and a couple
+ of drawbacks. The most important benefits is that the editor responds a lot faster, and can hold
+ much larger text documents. The big document limit has therefore been removed. It mostly affected
+ automatic spell checking. The syntax highlighter and spell checker are also more efficient, which
+ allows for needed improvements to these. The drawbacks are mainly that the editor now scrolls one
+ line at a time, instead of scrolling pixel by pixel like before. PRs #1521 and #1525.
+* Tags and References are now case insensitive. Their display name on the user interface remains
+ the same as the value set for the `@tag` entry. Issue #1313. PRs #1522 and #1578.
+* Keywords for Tags and References, and the References themselves, now have an auto-complete menu
+ that pops up in the editor on lines starting with the `@` character. It will first suggest what
+ keyword you want to use, and when it has been added, use that keyword to look up suggestions for
+ references to add. The suggestions improve as you type by looking for the characters you've
+ already typed in the tags you've previously defined. Issue #823. PR #1581.
+* You can now right-click an undefined tag, and a context menu option to create a Project Note for
+ that tag will appear in the menu. On selection, it will create a note in the first root folder of
+ the correct kind, and set the title and tag to match the undefined reference, making it instantly
+ defined. Issues #1580 and #823. PR #1582.
+* Shortcodes have been added to the Document Editor. Shorcodes are HTML-like syntax, but uses
+ square brackets instead of angular brackets. So `[b]text[/b]` will make the word "text" appear as
+ bold. Shortcodes currently support bold, italic, striketrough, underline, superscript and
+ subscript text. The first three are complimentary to the Markdown-like syntax that. The benefit
+ of the shortcode emphasis syntax, however, is that it does not care about word boundaries, and
+ can therefore be used any place in the text. Including in the middle of words. Issues #1337 and
+ #1444. PRs #1540 and #1583.
+* A show/hide toolbar has been added to the editor where toolbuttons for formatting options are
+ available. The toolbar is hidden by default, but can be activated from a three dots icon in the
+ top left corner of the editor. Issue #1585. PR #1584.
+* Build Definitions in the Manuscript Build tool can now be re-ordered, and the order is preserved
+ when the tool is closed and re-opened. Issue #1542. PR #1591.
+
+**Usability**
+
+* The Settings menu in the sidebar now always pops out to the right and upwards from the bottom of
+ the icon. The previous behaviour was not guaranteed to stay in the visible area of the screen.
+ PR #1520.
+* The right click action on a misspelled word now uses the actual spell checker data for lookup.
+ Previously, the spell checker would underline a word that was misspelled, but the right click
+ action actually had no way of reading where the error line was, so it had to guess again what
+ word the user was clicking. Since these two parts of the code used different logic, they
+ sometimes produced different results. The spell checker now saves the location of each spell
+ check error, and the right click action retrieves this data when generating suggestions, which
+ should eliminate the problem of picking the correct word boundaries. Issue #1532. PR #1525.
+* The language of a project is not set in the New Project Wizard and in Project Settings. It is no
+ longer defined in the Build Settings panel. Issue #1588. PR #1589.
+* The way switching focus and view in the main GUI has changed. Pressing `Ctrl+T` will now switch
+ focus to the Project or Novel Tree if focus is elsewhere, or if either have focus already, it
+ will switch view to the other tree. Pressing `Ctrl+E` will switch focus and view to the Document
+ Editor. Pressing `Ctrl+Shift+T` will do the same for the Outline View. The old Alt-based
+ shortcuts have been removed. Issues #1310 and #1291. PR #1590.
+
+**User Interface**
+
+* The labels under the sidebar buttons have been removed. The tool tips have the necessary
+ information. PR #1520.
+
+**Other Improvements**
+
+* Also the Tags and References keywords are now translated into the project language when these are
+ included in Manuscript builds. As long as the phrases have been translated. PR #1586.
+
+----
+
## Version 2.1.1 [2023-11-05]
### Release Notes
diff --git a/CREDITS.md b/CREDITS.md
index d792ce6f..68e673e9 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -52,6 +52,12 @@ Some of the assets bundled with novelWriter were adapted from the following sour
* [Owl](https://github.com/sdras/night-owl-vscode-theme) syntax themes by Sarah Drasner (MIT License)
* [Solarized](https://github.com/altercation/solarized) themes by Ethan Schoonover (MIT License)
+## Fonts
+
+The font used for the main novelWriter logo, mimetype and text banners is:
+
+* Pridi by Cadson Demak (Open Font License, Version 1.1)
+
## Special Mentions
Additional thanks to @johnblommers who was an early user and who has provided a lot of very useful
diff --git a/README.md b/README.md
index f9ea4bed..6a2022f9 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,12 @@
# novelWriter
-[](https://github.com/vkbo/novelWriter/releases)
[](https://github.com/vkbo/novelWriter/actions/workflows/test_linux.yml)
[](https://github.com/vkbo/novelWriter/actions/workflows/test_win.yml)
-[](https://github.com/vkbo/novelWriter/actions/workflows/test_mac.yml)
-[](https://github.com/vkbo/novelWriter/actions)
-[](https://codecov.io/gh/vkbo/novelWriter)
+[](https://github.com/vkbo/novelWriter/actions/workflows/test_mac.yml)
+[](https://github.com/vkbo/novelWriter/actions)
+[](https://codecov.io/gh/vkbo/novelWriter)
-
+
novelWriter is a plain text editor designed for writing novels assembled from many smaller text
documents. It uses a minimal formatting syntax inspired by Markdown, and adds a meta data syntax
diff --git a/docs/source/_static/novelwriter-dark.png b/docs/source/_static/novelwriter-dark.png
index 0ad6329d..1c7935aa 100644
Binary files a/docs/source/_static/novelwriter-dark.png and b/docs/source/_static/novelwriter-dark.png differ
diff --git a/docs/source/_static/novelwriter-light.png b/docs/source/_static/novelwriter-light.png
index 02bd281d..7b4723a7 100644
Binary files a/docs/source/_static/novelwriter-light.png and b/docs/source/_static/novelwriter-light.png differ
diff --git a/docs/source/_static/novelwriter-pdf.png b/docs/source/_static/novelwriter-pdf.png
index 6261b1ee..2b61485e 100644
Binary files a/docs/source/_static/novelwriter-pdf.png and b/docs/source/_static/novelwriter-pdf.png differ
diff --git a/docs/source/usage_shortcuts.rst b/docs/source/usage_shortcuts.rst
index 4e931351..db9382cb 100644
--- a/docs/source/usage_shortcuts.rst
+++ b/docs/source/usage_shortcuts.rst
@@ -25,19 +25,19 @@ Main Window Shortcuts
":kbd:`F8`", "Toggle :guilabel:`Focus Mode`"
":kbd:`F9`", "Re-build the project index"
":kbd:`F11`", "Toggle full screen mode"
- ":kbd:`Alt+1`", "Switch focus to the project tree (Windows :kbd:`Ctrl+Alt+1`)"
- ":kbd:`Alt+2`", "Switch focus to document editor (Windows :kbd:`Ctrl+Alt+2`)"
- ":kbd:`Alt+3`", "Switch focus to document viewer (Windows :kbd:`Ctrl+Alt+3`)"
- ":kbd:`Alt+4`", "Switch focus to outline view (Windows :kbd:`Ctrl+Alt+4`)"
":kbd:`Ctrl+,`", "Open the :guilabel:`Preferences` dialog"
+ ":kbd:`Ctrl+E`", "Switch focus to the document editor"
+ ":kbd:`Ctrl+T`", "Switch focus to the project/novel tree"
":kbd:`Ctrl+Q`", "Exit novelWriter"
":kbd:`Ctrl+Shift+,`", "Open the :guilabel:`Project Settings` dialog"
":kbd:`Ctrl+Shift+O`", "Open a project"
":kbd:`Ctrl+Shift+S`", "Save the current project"
+ ":kbd:`Ctrl+Shift+T`", "Switch focus to the outline view"
":kbd:`Ctrl+Shift+W`", "Close the current project"
":kbd:`Shift+F1`", "Open the local user manual (PDF) if it is available"
":kbd:`Shift+F6`", "Open the :guilabel:`Project Details` dialog"
+
.. _a_kb_tree:
Project Tree Shortcuts
@@ -46,21 +46,21 @@ Project Tree Shortcuts
.. csv-table::
:header: "Shortcut", "Description"
- ":kbd:`F2`", "Edit the label of the selected item"
- ":kbd:`Return`", "Open the selected document in the editor"
- ":kbd:`Alt+Up`", "Jump or go to the previous item at same level in the tree"
- ":kbd:`Alt+Down`", "Jump or go to the next item at same level in the tree"
- ":kbd:`Alt+Left`", "Jump to the parent item in the tree"
- ":kbd:`Alt+Right`", "Jump to the first child item in the project tree"
- ":kbd:`Ctrl+.`", "Open the context menu on the selected item"
- ":kbd:`Ctrl+L`", "Open the :guilabel:`Quick Links` menu"
- ":kbd:`Ctrl+N`", "Open the :guilabel:`Create New Item` menu"
- ":kbd:`Ctrl+O`", "Open selected document"
- ":kbd:`Ctrl+R`", "Open the selected document in the viewer"
- ":kbd:`Ctrl+Up`", "Move selected item one step up in the tree"
- ":kbd:`Ctrl+Down`", "Move selected item one step down in the tree"
- ":kbd:`Ctrl+Shift+Z`", "Undo the last move of a project item, if possible"
- ":kbd:`Ctrl+Shift+Del`", "Move the selected item to Trash"
+ ":kbd:`F2`", "Edit the label of the selected item"
+ ":kbd:`Return`", "Open the selected document in the editor"
+ ":kbd:`Alt+Up`", "Jump or go to the previous item at same level in the tree"
+ ":kbd:`Alt+Down`", "Jump or go to the next item at same level in the tree"
+ ":kbd:`Alt+Left`", "Jump to the parent item in the tree"
+ ":kbd:`Alt+Right`", "Jump to the first child item in the project tree"
+ ":kbd:`Ctrl+.`", "Open the context menu on the selected item"
+ ":kbd:`Ctrl+L`", "Open the :guilabel:`Quick Links` menu"
+ ":kbd:`Ctrl+N`", "Open the :guilabel:`Create New Item` menu"
+ ":kbd:`Ctrl+O`", "Open selected document"
+ ":kbd:`Ctrl+R`", "Open the selected document in the viewer"
+ ":kbd:`Ctrl+Up`", "Move selected item one step up in the tree"
+ ":kbd:`Ctrl+Down`", "Move selected item one step down in the tree"
+ ":kbd:`Ctrl+Del`", "Move the selected item to Trash"
+ ":kbd:`Ctrl+Shift+Z`", "Undo the last move of a project item, if possible"
.. _a_kb_editor:
@@ -134,6 +134,7 @@ Other Editor Shortcuts
":kbd:`Ctrl+Shift+A`", "Select all text in the current paragraph"
":kbd:`Ctrl+Shift+I`", "Import text to the current document from a text file"
+
.. _a_kb_ins:
Insert Shortcuts
diff --git a/novelwriter/__init__.py b/novelwriter/__init__.py
index b3b39028..07eebb28 100644
--- a/novelwriter/__init__.py
+++ b/novelwriter/__init__.py
@@ -33,26 +33,8 @@ from novelwriter.error import exceptionHandler, logException
from novelwriter.config import Config
from novelwriter.shared import SharedData
-##
-# Version Scheme
-# ================
-# Generally follows PEP 440
-# Hex Version:
-# - Digit 1,2 : Major Version (01-ff)
-# - Digit 3,4 : Minor Version (01-ff)
-# - Digit 5,6 : Patch Version (01-ff)
-# - Digit 7 : Release Type (a: alpha, b: beta, c: candidate, f: final)
-# - Digit 8 : Release Number (0-f)
-#
-# Example : Full Short Description
-# --------------------------------------------------------------------
-# 0x010200a0 : 1.2-alpha0 1.2a0 Use while developing next release
-# 0x010200a1 : 1.2-alpha1 1.2a1 First alpha release
-# 0x010200b1 : 1.2-beta1 1.2b1 First beta release
-# 0x010200c1 : 1.2-rc1 1.2rc1 First release candidate
-# 0x010200f0 : 1.2.0 1.2.0 Final release
-# 0x010201f0 : 1.2.1 1.2.1 Patch release
-##
+# Package Meta
+# ============
__package__ = "novelwriter"
__copyright__ = "Copyright 2018–2023, Veronica Berglyd Olsen"
@@ -60,9 +42,9 @@ __license__ = "GPLv3"
__author__ = "Veronica Berglyd Olsen"
__maintainer__ = "Veronica Berglyd Olsen"
__email__ = "code@vkbo.net"
-__version__ = "2.2-alpha1"
-__hexversion__ = "0x020200a1"
-__date__ = "2023-09-01"
+__version__ = "2.2-beta1"
+__hexversion__ = "0x020200b1"
+__date__ = "2023-11-12"
__status__ = "Stable"
__domain__ = "novelwriter.io"
diff --git a/novelwriter/assets/i18n/project_nn_NO.json b/novelwriter/assets/i18n/project_nn_NO.json
index 09b99a4e..aff847e2 100644
--- a/novelwriter/assets/i18n/project_nn_NO.json
+++ b/novelwriter/assets/i18n/project_nn_NO.json
@@ -2,6 +2,16 @@
"Synopsis": "Samandrag",
"Comment": "Kommentar",
"Notes": "Notat",
+ "Tag": "Knagg",
+ "Point of View": "Perspektiv",
+ "Focus": "Fokus",
+ "Characters": "Karakterar",
+ "Plot": "Plott",
+ "Timeline": "Tidslinje",
+ "Locations": "Lokasjonar",
+ "Objects": "Objekt",
+ "Entities": "Eining",
+ "Custom": "Anna",
"0": "null",
"1": "ein",
"2": "to",
diff --git a/novelwriter/assets/icons/novelwriter.ico b/novelwriter/assets/icons/novelwriter.ico
index 24de4e24..54301ffe 100644
Binary files a/novelwriter/assets/icons/novelwriter.ico and b/novelwriter/assets/icons/novelwriter.ico differ
diff --git a/novelwriter/assets/icons/novelwriter.svg b/novelwriter/assets/icons/novelwriter.svg
index 18be89c1..a161cd19 100644
--- a/novelwriter/assets/icons/novelwriter.svg
+++ b/novelwriter/assets/icons/novelwriter.svg
@@ -1,184 +1,9 @@
-
-
+
Fonts
+
+
The font used for the main novelWriter logo, mimetype and text banners is:
+
+ Pridi by Cadson Demak (Open Font License, Version 1.1)
+
+
Special Mentions
Additional thanks to @johnblommers who was an early user and who has provided a lot
diff --git a/novelwriter/assets/text/release_notes.htm b/novelwriter/assets/text/release_notes.htm
index c74a1574..69e1eaab 100644
--- a/novelwriter/assets/text/release_notes.htm
+++ b/novelwriter/assets/text/release_notes.htm
@@ -2,46 +2,16 @@
The primary focus of this release has been a complete redesign of the Build Tool, that is, the
-tool that assembles your project into a manuscript document. The new tool, called the "Manuscript
-Build Tool" allows you to define multiple build definitions for your project. The build definitions
-are edited in a new Manuscript Build Settings dialog, with a lot more options than the old tool.
-
The reason for this redesign is a long list of feature requests that could not easily be
-accommodated in the old, much simpler tool. Far from all the features have been added yet, but now
-that the new tool is in place, they will be gradually added in the coming releases.
-
The key feature added in this release is the extended control you now have for selecting exactly
-what part of your project is included in a given build definition. You have the same filters for
-selecting documents and notes, and turning on or off root folders as before, but you can now easily
-override on a per-document basis what is included or excluded in addition to the filter.
-
A second major improvement is a better tool to format your manuscript headings. You no longer
-have to look up formatting codes and add them manually. Instead, there is now a heading format
-editor in the Build Settings dialog for creating the header format, with syntax highlighting
-included.
-
-
Other Changes
-
Among other features is a new option to duplicate documents and folders in the project tree. The
-duplicate feature is available from the right-click menu. A proper light colour theme has also been
-added. In most cases it will be the same as the default theme, depending on your platform.
-
There are other, minor improvements as well, and a lot of code improvements under the hood. For
-a full list of changes, see the detailed changelogs.
+
This is a beta release of the next release version, and is intended for testing purposes. Please
+be careful when using this version on live writing projects, and make sure you take frequent
+backups.
+
Please check the changelog for an overview of changes. The full release notes will be added to
+the final release.
This is a patch release that fixes a layout issue and internationalisation issues with the new
-Manuscript Build tool. It also fixes a number of issues related to bugs in the underlying Qt
-framework that affects drag and drop functionality in the project tree. These issues were mostly
-only affecting Debian Linux package releases.
-
Other, minor issues related to updating the editor on colour theme change and project word list
-changes have been fixed as well. See the full changelog for more details.
-
diff --git a/novelwriter/config.py b/novelwriter/config.py
index ebd0d05f..bc8af368 100644
--- a/novelwriter/config.py
+++ b/novelwriter/config.py
@@ -148,6 +148,7 @@ class Config:
self.autoScroll = False # Typewriter-like scrolling
self.autoScrollPos = 30 # Start point for typewriter-like scrolling
+ self.scrollPastEnd = True # Scroll past end of document, and centre cursor
self.wordCountTimer = 5.0 # Interval for word count update in seconds
self.incNotesWCount = True # The status bar word count includes notes
@@ -577,6 +578,7 @@ class Config:
self.doReplaceDots = conf.rdBool(sec, "repdots", self.doReplaceDots)
self.autoScroll = conf.rdBool(sec, "autoscroll", self.autoScroll)
self.autoScrollPos = conf.rdInt(sec, "autoscrollpos", self.autoScrollPos)
+ self.scrollPastEnd = conf.rdBool(sec, "scrollpastend", self.scrollPastEnd)
self.fmtSQuoteOpen = conf.rdStr(sec, "fmtsquoteopen", self.fmtSQuoteOpen)
self.fmtSQuoteClose = conf.rdStr(sec, "fmtsquoteclose", self.fmtSQuoteClose)
self.fmtDQuoteOpen = conf.rdStr(sec, "fmtdquoteopen", self.fmtDQuoteOpen)
@@ -701,6 +703,7 @@ class Config:
"repdots": str(self.doReplaceDots),
"autoscroll": str(self.autoScroll),
"autoscrollpos": str(self.autoScrollPos),
+ "scrollpastend": str(self.scrollPastEnd),
"fmtsquoteopen": str(self.fmtSQuoteOpen),
"fmtsquoteclose": str(self.fmtSQuoteClose),
"fmtdquoteopen": str(self.fmtDQuoteOpen),
diff --git a/novelwriter/constants.py b/novelwriter/constants.py
index 5579e8a3..514ea9f2 100644
--- a/novelwriter/constants.py
+++ b/novelwriter/constants.py
@@ -327,8 +327,7 @@ class nwQuotes:
class nwUnicode:
- """Supported unicode character constants and their HTML equivalents.
- """
+ """Supported unicode character constants and their HTML equivalents."""
# Unicode Constants
# =================
diff --git a/novelwriter/core/buildsettings.py b/novelwriter/core/buildsettings.py
index 931525ea..84dd7ff2 100644
--- a/novelwriter/core/buildsettings.py
+++ b/novelwriter/core/buildsettings.py
@@ -64,7 +64,6 @@ SETTINGS_TEMPLATE = {
"text.includeKeywords": (bool, False),
"text.includeBodyText": (bool, True),
"text.addNoteHeadings": (bool, True),
- "format.buildLang": (str, "en_GB"),
"format.textFont": (str, CONFIG.textFont),
"format.textSize": (int, 12),
"format.lineHeight": (float, 1.15, 0.75, 3.0),
@@ -107,7 +106,6 @@ 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", "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"),
@@ -158,6 +156,7 @@ class BuildSettings:
self._uuid = str(uuid.uuid4())
self._path = Path.home()
self._build = ""
+ self._order = 0
self._format = nwBuildFmt.ODT
self._skipRoot = set()
self._excluded = set()
@@ -166,20 +165,32 @@ class BuildSettings:
self._changed = False
return
+ @classmethod
+ def fromDict(cls, data: dict) -> BuildSettings:
+ """Create a build settings object from a dict."""
+ cls = BuildSettings()
+ cls.unpack(data)
+ return cls
+
##
# Properties
##
@property
def name(self) -> str:
- """The build name."""
+ """Return the build name."""
return self._name
@property
def buildID(self) -> str:
- """The build ID as a UUID."""
+ """Return the build ID as a UUID."""
return self._uuid
+ @property
+ def order(self) -> int:
+ """Return the build order."""
+ return self._order
+
@property
def lastPath(self) -> Path:
"""The last used build path."""
@@ -253,6 +264,12 @@ class BuildSettings:
self._uuid = value
return
+ def setOrder(self, value: int) -> None:
+ """Set the build order."""
+ if isinstance(value, int):
+ self._order = value
+ return
+
def setLastPath(self, path: Path | str | None) -> None:
"""Set the last used build path."""
if isinstance(path, str):
@@ -400,6 +417,7 @@ class BuildSettings:
"uuid": self._uuid,
"path": str(self._path),
"build": self._build,
+ "order": self._order,
"format": self._format.name,
"settings": self._settings.copy(),
"content": {
@@ -411,14 +429,15 @@ class BuildSettings:
def unpack(self, data: dict) -> None:
"""Unpack a dictionary and populate the class."""
+ content = data.get("content", {})
settings = data.get("settings", {})
- content = data.get("content", {})
included = content.get("included", [])
excluded = content.get("excluded", [])
skipRoot = content.get("skipRoot", [])
self.setName(data.get("name", ""))
self.setBuildID(data.get("uuid", ""))
+ self.setOrder(data.get("order", 0))
self.setLastPath(data.get("path", None))
self.setLastBuildName(data.get("build", ""))
@@ -455,9 +474,9 @@ class BuildCollection:
def __init__(self, project: NWProject) -> None:
self._project = project
- self._builds = {}
self._lastBuild = ""
self._defaultBuild = ""
+ self._builds: dict[str, BuildSettings] = {}
self._loadCollection()
return
@@ -485,21 +504,19 @@ class BuildCollection:
def getBuild(self, buildID: str) -> BuildSettings | None:
"""Get a specific build settings object."""
- if buildID not in self._builds:
- return None
- build = BuildSettings()
- build.unpack(self._builds[buildID])
- return build
+ return self._builds.get(buildID, None)
##
# Setters
##
- def setLastBuild(self, buildID: str) -> None:
+ def setBuildsState(self, lastBuild: str, order: list[str]) -> None:
"""Set the last active build id."""
- if buildID != self._lastBuild:
- self._lastBuild = buildID
- self._saveCollection()
+ for i, key in enumerate(order):
+ if build := self._builds.get(key):
+ build.setOrder(i)
+ self._lastBuild = lastBuild
+ self._saveCollection()
return
def setDefaultBuild(self, buildID: str) -> None:
@@ -512,8 +529,7 @@ class BuildCollection:
def setBuild(self, build: BuildSettings) -> None:
"""Set build settings data in the collection."""
if isinstance(build, BuildSettings):
- buildID = build.buildID
- self._builds[buildID] = build.pack()
+ self._builds[build.buildID] = build
self._saveCollection()
return
@@ -522,15 +538,15 @@ class BuildCollection:
##
def removeBuild(self, buildID: str) -> None:
- """Remove the a build from the collection."""
+ """Remove a build from the collection."""
self._builds.pop(buildID, None)
self._saveCollection()
return
def builds(self) -> Iterable[tuple[str, str]]:
"""Iterate over all available builds."""
- for buildID in self._builds:
- yield buildID, self._builds[buildID].get("name", "")
+ for buildID, build in sorted(self._builds.items(), key=lambda x: x[1].order):
+ yield buildID, build.name
return
##
@@ -569,7 +585,7 @@ class BuildCollection:
elif key == "defaultBuild":
self._defaultBuild = str(entry)
elif isinstance(entry, dict):
- self._builds[key] = entry
+ self._builds[key] = BuildSettings.fromDict(entry)
return True
@@ -581,11 +597,11 @@ class BuildCollection:
logger.debug("Saving builds file")
try:
- data = {
+ data: dict[str, str | dict] = {
"lastBuild": self._lastBuild,
"defaultBuild": self._defaultBuild,
}
- data.update(self._builds)
+ data.update({k: b.pack() for k, b in self._builds.items()})
with open(buildsFile, mode="w+", encoding="utf-8") as outFile:
outFile.write(jsonEncode({"novelWriter.builds": data}, nmax=4))
except Exception:
diff --git a/novelwriter/core/coretools.py b/novelwriter/core/coretools.py
index 017ea082..81803576 100644
--- a/novelwriter/core/coretools.py
+++ b/novelwriter/core/coretools.py
@@ -353,11 +353,13 @@ class ProjectBuilder:
projName = data.get("projName", lblNewProject)
projTitle = data.get("projTitle", lblNewProject)
projAuthor = data.get("projAuthor", "")
+ projLang = data.get("projLang", "en_GB")
project.data.setUuid(None)
project.data.setName(projName)
project.data.setTitle(projTitle)
project.data.setAuthor(projAuthor)
+ project.data.setLanguage(projLang)
project.setDefaultStatusImport()
project.session.startSession()
diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py
index 8c4b4ca5..75906d9a 100644
--- a/novelwriter/core/docbuild.py
+++ b/novelwriter/core/docbuild.py
@@ -248,13 +248,9 @@ class NWBuildDocument:
def _setupBuild(self, bldObj: Tokenizer) -> dict:
"""Configure the build object."""
# Get Settings
- buildLang = self._build.getStr("format.buildLang")
textFont = self._build.getStr("format.textFont")
textSize = self._build.getInt("format.textSize")
- # The language lookup dict is reloaded if needed
- self._project.setProjectLang(buildLang)
-
fontFamily = textFont or CONFIG.textFont
bldFont = QFont(fontFamily, textSize)
fontInfo = QFontInfo(bldFont)
@@ -287,7 +283,7 @@ class NWBuildDocument:
if isinstance(bldObj, ToOdt):
bldObj.setColourHeaders(self._build.getBool("odt.addColours"))
- bldObj.setLanguage(buildLang)
+ bldObj.setLanguage(self._project.data.language)
scale = nwLabels.UNIT_SCALE.get(self._build.getStr("format.pageUnit"), 1.0)
pW, pH = nwLabels.PAPER_SIZE.get(self._build.getStr("format.pageSize"), (-1.0, -1.0))
diff --git a/novelwriter/core/projectdata.py b/novelwriter/core/projectdata.py
index 9b0cc36c..d248a7a1 100644
--- a/novelwriter/core/projectdata.py
+++ b/novelwriter/core/projectdata.py
@@ -152,14 +152,14 @@ class NWProjectData:
"""Return the initial count of words for novel and note
documents.
"""
- return tuple(self._initCounts)
+ return self._initCounts[0], self._initCounts[1]
@property
def currCounts(self) -> tuple[int, int]:
"""Return the current count of words for novel and note
documents.
"""
- return tuple(self._currCounts)
+ return self._currCounts[0], self._currCounts[1]
@property
def lastHandle(self) -> dict[str, str | None]:
diff --git a/novelwriter/core/tohtml.py b/novelwriter/core/tohtml.py
index 41201412..7443ed34 100644
--- a/novelwriter/core/tohtml.py
+++ b/novelwriter/core/tohtml.py
@@ -456,11 +456,10 @@ class ToHtml(Tokenizer):
def _formatSynopsis(self, text: str) -> str:
"""Apply HTML formatting to synopsis."""
+ sSynop = self._localLookup("Synopsis")
if self._genMode == self.M_PREVIEW:
- sSynop = self._trSynopsis
return f"