diff --git a/docs/FileFormatSpec-1.5.fodt b/docs/FileFormatSpec-1.5.fodt
index a57c8627..4e2d66ef 100644
--- a/docs/FileFormatSpec-1.5.fodt
+++ b/docs/FileFormatSpec-1.5.fodt
@@ -1,31 +1,30 @@
- Veronica Olsen2022-11-05T18:25:44.8874731592023-06-03T18:35:47.268848685Veronica OlsenPT4H19S53LibreOffice/7.4.5.1$Linux_X86_64 LibreOffice_project/40$Build-1
+ Veronica Olsen2022-11-05T18:25:44.8874731592024-01-26T22:59:54.491819741Veronica OlsenPT4H2M7S55LibreOffice/7.4.7.2$Linux_X86_64 LibreOffice_project/40$Build-2
- 0
+ 35971
0
- 35645
+ 26083
20394
true
false
view2
- 15145
- 7216
+ 4692
+ 47456
0
- 0
- 35643
- 20392
+ 35971
+ 26081
+ 56363
0
1
false
140
false
false
- false
false
@@ -91,7 +90,7 @@
true
true
- 805029
+ 917862
true
false
@@ -117,7 +116,7 @@
false
false
- true
+ false
false
false
false
@@ -159,7 +158,7 @@
-
+
@@ -180,7 +179,7 @@
-
+
@@ -480,15 +479,6 @@
-
-
-
-
-
-
-
-
-
@@ -1108,153 +1098,148 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1271,78 +1256,81 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
@@ -1420,17 +1408,20 @@
- novelWriter
- Project File Format 1.5 Specification
+ novelWriter
+ Project File Format 1.5 Specification
- This document covers the file format specification for the 1.5 file format for novelWriter project files. See the documentation1
- See: https://docs.novelwriter.io for a full description of the app’s functionality. The file format was intrioduced in Release 2.0.
- The target audience of this document is developers who intend to write a tool or script that generates valid novelWriter project files from data from other applications, or for templating purposes.
- Note that flags are generally written out as yes/no values, but also true/false and on/off are understood by the application. The None value that occasionally occurs in actual project files is the text representation of the Python None value, and indicates that there is no value set.
- Revisions
+ This document covers the file format specification for the 1.5 file format for novelWriter project files. See the documentation1
+ See: https://docs.novelwriter.io for a full description of the app’s functionality. The file format was intrioduced in Release 2.0.
+ The target audience of this document is developers who intend to write a tool or script that generates valid novelWriter project files from data from other applications, or for templating purposes.
+ Note that flags are generally written out as yes/no values, but also true/false and on/off are understood by the application. The None value that occasionally occurs in actual project files is the text representation of the Python None value, and indicates that there is no value set.
+ Revisions
- From Release 2.1 Beta 1: Removed the titleFormat node from settings.
+ From Release 2.1 Beta 1: Removed the titleFormat node from settings.
+
+
+ From Release 2.3 Beta 1: Removed the title node from project.
XML Root
@@ -1454,7 +1445,7 @@
- appVersion
+ appVersion
No
@@ -1465,7 +1456,7 @@
- hexVersion
+ hexVersion
No
@@ -1476,29 +1467,29 @@
- fileVersion
+ fileVersion
Yes
- The file format version used when writing the project file. This determines how the file is parsed, so it is important that it is set correctly. Valid values are “1.0”, “1.1”, “1.2”, “1.3”, “1.4”, and “1.5”.
+ The file format version used when writing the project file. This determines how the file is parsed, so it is important that it is set correctly. Valid values are “1.0”, “1.1”, “1.2”, “1.3”, “1.4”, and “1.5”.
- fileRevision
+ fileRevision
- No
+ No
- The revision of the file format used for non-breaking changes. This is an interger value.
+ The revision of the file format used for non-breaking changes. This is an interger value.
- timeStamp
+ timeStamp
No
@@ -1509,12 +1500,12 @@
Example
- <novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1"
- fileVersion="1.5" fileRevision="1"
- timeStamp="2022-11-05 17:46:51">
+ <novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1"
+ fileVersion="1.5" fileRevision="1"
+ timeStamp="2022-11-05 17:46:51">
Project Node
Tag: project
- The project section is a level one node under the root. It stores the primary settings for the project. The only required values are the id attribute and the name value. All other entries are set to default values during parsing if ommitted from the XML.
+ The project section is a level one node under the root. It stores the primary settings for the project. The only required values are the id attribute and the name value. All other entries are set to default values during parsing if ommitted from the XML.
Attributes
@@ -1533,18 +1524,18 @@
- id
+ id
- Yes
+ Yes
- A UUID that is unique for the project and does not change during the lifetime of the project. It is used by novelWriter to keep track of temporary files and to associate cross-project settings with specific projects without relying on the project name.
+ A UUID that is unique for the project and does not change during the lifetime of the project. It is used by novelWriter to keep track of temporary files and to associate cross-project settings with specific projects without relying on the project name.
- saveCount
+ saveCount
No
@@ -1555,7 +1546,7 @@
- autoCount
+ autoCount
No
@@ -1566,7 +1557,7 @@
- editTime
+ editTime
No
@@ -1594,49 +1585,37 @@
- name
+ name
- Yes
+ Yes
- The name the user has given to the project.
+ The name the user has given to the project.
- title
+ author
No
- The title the user has given to the project, which may differ from the project name. The value is used in some places in the user interface, and can be added to manuscript builds.
-
-
-
-
- author
-
-
- No
-
-
- The name of the novel author or authors. The value is used in some places in the user interface, and can be added to manuscript builds.
+ The name of the novel author or authors. The value is used in some places in the user interface, and can be added to manuscript builds.
Example
- <project id="e2be99af-f9bf-4403-857a-c3d1ac25abea"
- saveCount="5" autoCount="10" editTime="1000">
- <name>Sample Project</name>
- <title>Sample Project</title>
- <author>Jane Smith</author>
+ <project id="e2be99af-f9bf-4403-857a-c3d1ac25abea"
+ saveCount="5" autoCount="10" editTime="1000">
+ <name>Sample Project</name>
+ <author>Jane Smith</author>
</project>
-
- Settings Node
+
+ Settings Node
Tag: settings
- The settings section is a level one node under the root. It stores the various runtime values for the project, and the settings available from the Project Settings panel. None of these settings are required, and if missing, will be set to default values. The entire settings section can thus be ommitted.
+ The settings section is a level one node under the root. It stores the various runtime values for the project, and the settings available from the Project Settings panel. None of these settings are required, and if missing, will be set to default values. The entire settings section can thus be ommitted.
Attributes
None
Values
@@ -1657,18 +1636,18 @@
- doBackup
+ doBackup
- No
+ No
- User-controlled setting for whether or not to run backup when the project is closed.
+ User-controlled setting for whether or not to run backup when the project is closed.
- language
+ language
No
@@ -1679,7 +1658,7 @@
- spellChecking
+ spellChecking
No
@@ -1692,18 +1671,18 @@
- lastHandle
+ lastHandle
No
- An auto-generated list of the last documents open in the editor and viewer, and which novel root folder was last viewed in the Novel Tree and Outline View. These are saved as key/value pairs. See separate section for how they are stored as XML.
+ An auto-generated list of the last documents open in the editor and viewer, and which novel root folder was last viewed in the Novel Tree and Outline View. These are saved as key/value pairs. See separate section for how they are stored as XML.
- autoReplace
+ autoReplace
No
@@ -1714,50 +1693,50 @@
- titleFormat
+ titleFormat
No
- Removed in Revision 1.
+ Removed in Revision 1.
- status
+ status
No
- The status labels as defined by the user in Project Settings. These are saved as special key/value pars. See separate section for how they are stored as XML.
+ The status labels as defined by the user in Project Settings. These are saved as special key/value pars. See separate section for how they are stored as XML.
- importance
+ importance
No
- The importance labels as defined by the user in Project Settings. These are saved as special key/value pars. See separate section for how they are stored as XML.
+ The importance labels as defined by the user in Project Settings. These are saved as special key/value pars. See separate section for how they are stored as XML.
Example
- <settings>
- <doBackup>yes</doBackup>
- <language>en_GB</language>
- <spellChecking auto="yes">en_GB</spellChecking>
- <lastHandle />
- <autoReplace />
- <status />
- <importance />
- </settings>
-
- Key/Value Nodes
+ <settings>
+ <doBackup>yes</doBackup>
+ <language>en_GB</language>
+ <spellChecking auto="yes">en_GB</spellChecking>
+ <lastHandle />
+ <autoReplace />
+ <status />
+ <importance />
+ </settings>
+
+ Key/Value Nodes
The key/value nodes are used for lastHandle, autoReplace and titleFormat settings. The lookup key is stored as an attribute, and the value is the text of the node.
Attributes
@@ -1777,25 +1756,25 @@
- key
+ key
- Yes
+ Yes
- The lookup key.
+ The lookup key.
Example
- <lastHandle>
- <entry key="editor">636b6aa9b697b</entry>
- <entry key="viewer">636b6aa9b697b</entry>
- <entry key="novelTree">7031beac91f75</entry>
- <entry key="outline">7031beac91f75</entry>
- </lastHandle>
+ <lastHandle>
+ <entry key="editor">636b6aa9b697b</entry>
+ <entry key="viewer">636b6aa9b697b</entry>
+ <entry key="novelTree">7031beac91f75</entry>
+ <entry key="outline">7031beac91f75</entry>
+ </lastHandle>
Status/Importance Key/Value Nodes
- The status and importance settings are stored as key/value nodes with additional data attributes. The label of the status or importance setting is saved as the node text value.
+ The status and importance settings are stored as key/value nodes with additional data attributes. The label of the status or importance setting is saved as the node text value.
Attributes
@@ -1814,18 +1793,18 @@
- key
+ key
- Yes
+ Yes
- The lookup key. For status labels, it must consist of an “s” followed by six hexadecimal numbers. For importance labels it must consist of an “i” followed by six hexadecimal numbers. Each key string must be unique. Internally, they are random numbers, but also sequential values are valid.
+ The lookup key. For status labels, it must consist of an “s” followed by six hexadecimal numbers. For importance labels it must consist of an “i” followed by six hexadecimal numbers. Each key string must be unique. Internally, they are random numbers, but also sequential values are valid.
- count
+ count
No
@@ -1836,7 +1815,7 @@
- red
+ red
Yes
@@ -1847,48 +1826,48 @@
- green
+ green
Yes
- A number between 0 and 255 representing the green component of the label colour.
+ A number between 0 and 255 representing the green component of the label colour.
- blue
+ blue
Yes
- A number between 0 and 255 representing the blue component of the label colour.
+ A number between 0 and 255 representing the blue component of the label colour.
Example
- <status>
- <entry key="sf12341" count="4"
- red="100" green="100" blue="100">New</entry>
- <entry key="sd51c5b" count="0"
- red="193" green="129" blue="0">Draft</entry>
- <entry key="s78ea90" count="1"
- red="58" green="180" blue="58">Finished</entry>
- </status>
- <importance>
- <entry key="ia857f0" count="5"
- red="100" green="100" blue="100">None</entry>
- <entry key="icfb3a5" count="2"
- red="0" green="122" blue="188">Minor</entry>
- <entry key="i2d7a54" count="2"
- red="21" green="0" blue="180">Major</entry>
- </importance>
-
+ <status>
+ <entry key="sf12341" count="4"
+ red="100" green="100" blue="100">New</entry>
+ <entry key="sd51c5b" count="0"
+ red="193" green="129" blue="0">Draft</entry>
+ <entry key="s78ea90" count="1"
+ red="58" green="180" blue="58">Finished</entry>
+ </status>
+ <importance>
+ <entry key="ia857f0" count="5"
+ red="100" green="100" blue="100">None</entry>
+ <entry key="icfb3a5" count="2"
+ red="0" green="122" blue="188">Minor</entry>
+ <entry key="i2d7a54" count="2"
+ red="21" green="0" blue="180">Major</entry>
+ </importance>
+
Content Node
Tag: content
- The content section is a level one node under the root. It stores all the project items of the project. The items are stored in the order in which they appear in the project tree, so altering the order will affect the project structure. The attribute with the order number is not used when processing the data. It is written to the XML for debugging purposes.
+ The content section is a level one node under the root. It stores all the project items of the project. The items are stored in the order in which they appear in the project tree, so altering the order will affect the project structure. The attribute with the order number is not used when processing the data. It is written to the XML for debugging purposes.
Attributes
@@ -1907,35 +1886,35 @@
- items
+ items
No
- The number of project items in the content section.
+ The number of project items in the content section.
- novelWords
+ novelWords
No
- The number of words in total for all document nodes with layout DOCUMENT. The value defaults to 0, but this number forms the basis of computing writing statistics during a session, so the number should be properly set to ensure correct statistics.
+ The number of words in total for all document nodes with layout DOCUMENT. The value defaults to 0, but this number forms the basis of computing writing statistics during a session, so the number should be properly set to ensure correct statistics.
- notesWords
+ notesWords
No
- The number of words in total for all document nodes with layout NOTE. The value defaults to 0, but this number forms the basis of computing writing statistics during a session, so the number should be properly set to ensure correct statistics.
+ The number of words in total for all document nodes with layout NOTE. The value defaults to 0, but this number forms the basis of computing writing statistics during a session, so the number should be properly set to ensure correct statistics.
@@ -1957,31 +1936,31 @@
- item
+ item
- No
+ No
- A node representing a project item.
+ A node representing a project item.
Example
- <content items="27" novelWords="954" notesWords="409">
- <item handle="7031beac91f75" parent="None" root="7031beac91f75"
- order="0" type="ROOT" class="NOVEL">
- <meta expanded="yes"/>
- <name status="sc24b8f" import="ia857f0">Novel</name>
- </item>
- ...
- </content>
- Item Nodes
- The item nodes make up the actual project content of the project. Each node represents either a root folder, a regular folder, or a document. Each node has a type, class and layout setting that determine its category. Each item is given a handle that is a random hexadecimal string of length 13.
- For the items that are document files, the handle corresponds to its expected filename. It is therefore important that they match in generated projects. Each document node is expected to correspond to a file in the contents folder of the project named “content/7031beac91f75.nwd” for the item handle “7031beac91f75”. If there is no such file, the document item is assumed to contain no text, and a file is created when the user tries to save text to it.
- Each item node has a meta data node and a name node. The meta data node contains only collected information, and is thus not strictly required. However, an accurate word count and setting the correct icon in the project tree depend on these values. These values are set by the indexer class, so rebuilding the index should restore the data.
- The name node contains the primary user defined settings for an item, and is required for the entry to be valid.
-
+ <content items="27" novelWords="954" notesWords="409">
+ <item handle="7031beac91f75" parent="None" root="7031beac91f75"
+ order="0" type="ROOT" class="NOVEL">
+ <meta expanded="yes"/>
+ <name status="sc24b8f" import="ia857f0">Novel</name>
+ </item>
+ ...
+ </content>
+ Item Nodes
+ The item nodes make up the actual project content of the project. Each node represents either a root folder, a regular folder, or a document. Each node has a type, class and layout setting that determine its category. Each item is given a handle that is a random hexadecimal string of length 13.
+ For the items that are document files, the handle corresponds to its expected filename. It is therefore important that they match in generated projects. Each document node is expected to correspond to a file in the contents folder of the project named “content/7031beac91f75.nwd” for the item handle “7031beac91f75”. If there is no such file, the document item is assumed to contain no text, and a file is created when the user tries to save text to it.
+ Each item node has a meta data node and a name node. The meta data node contains only collected information, and is thus not strictly required. However, an accurate word count and setting the correct icon in the project tree depend on these values. These values are set by the indexer class, so rebuilding the index should restore the data.
+ The name node contains the primary user defined settings for an item, and is required for the entry to be valid.
+
Attributes
@@ -2000,79 +1979,79 @@
- handle
+ handle
- Yes
+ Yes
- The 13 value hexadecimal string that represents the item in the project. This is the primary identifier of a project item, and is required. It must be unique withing a project. Internally, it is generated as a random value, but it can also be sequential.
+ The 13 value hexadecimal string that represents the item in the project. This is the primary identifier of a project item, and is required. It must be unique withing a project. Internally, it is generated as a random value, but it can also be sequential.
- parent
+ parent
- Yes
+ Yes
- The handle of the parent item in the tree. This value should only be None for root folders. All other items must have a parent handle set. If the parent handle is None for an item that isn’t a root folder, the item will be treated as orphaned during project loading.
+ The handle of the parent item in the tree. This value should only be None for root folders. All other items must have a parent handle set. If the parent handle is None for an item that isn’t a root folder, the item will be treated as orphaned during project loading.
- root
+ root
- No
+ No
- The handle of the top of its hierarchy of parent items. That is, the root folder which it ultimately sits under. If the attribute is not set, it will be computed during loading. It is saved to the XML file for efficiency reasons.
+ The handle of the top of its hierarchy of parent items. That is, the root folder which it ultimately sits under. If the attribute is not set, it will be computed during loading. It is saved to the XML file for efficiency reasons.
- order
+ order
- No
+ No
- The numerical order of the item under its parent item. This value is not used during the loading process as the physical item order in the content node is used instead. It is primarily saved to the XML for debugging purposes.
+ The numerical order of the item under its parent item. This value is not used during the loading process as the physical item order in the content node is used instead. It is primarily saved to the XML for debugging purposes.
- type
+ type
- Yes
+ Yes
- The item type of the item node. Allowed values are ROOT, FOLDER and FILE.
+ The item type of the item node. Allowed values are ROOT, FOLDER and FILE.
- class
+ class
- Yes
+ Yes
- The item class of the item node. There are a number of item classes available in the app, all corresponding to a specific type of root folder. Each item in a root folder should have the same class set as the root folder itself. The attribute is not strictly required for items that aren’t root folders as it will be automatically set to match during loading. Allowed values are NOVEL, PLOT, CHARACTER, WORLD, TIMELINE, OBJECT, ENTITY, CUSTOM, ARCHIVE and TRASH.
+ The item class of the item node. There are a number of item classes available in the app, all corresponding to a specific type of root folder. Each item in a root folder should have the same class set as the root folder itself. The attribute is not strictly required for items that aren’t root folders as it will be automatically set to match during loading. Allowed values are NOVEL, PLOT, CHARACTER, WORLD, TIMELINE, OBJECT, ENTITY, CUSTOM, ARCHIVE and TRASH.
- layout
+ layout
- Yes
+ Yes
- The item layout of the item node. Allowed values are DOCUMENT and NOTE. This is the attribute that determines if a FILE type item is a Novel Document or a Project Note.
+ The item layout of the item node. Allowed values are DOCUMENT and NOTE. This is the attribute that determines if a FILE type item is a Novel Document or a Project Note.
@@ -2094,29 +2073,29 @@
- meta
+ meta
- No
+ No
- A node of meta data attributes for the item.
+ A node of meta data attributes for the item.
- name
+ name
- Yes
+ Yes
- A node of user settings for the item.
+ A node of user settings for the item.
- Meta Nodes
- The meta data collected for the current item. This data either represents the item’s last state in the app, or consists of data collected by the indexer. It can be restored by rebuilding the index, so the data is not essential.
+ Meta Nodes
+ The meta data collected for the current item. This data either represents the item’s last state in the app, or consists of data collected by the indexer. It can be restored by rebuilding the index, so the data is not essential.
Attributes
@@ -2135,73 +2114,73 @@
- expanded
+ expanded
- No
+ No
- Whether the tree node in the project tree was expanded or collapsed during the last session. Applies to all item types, but is ignored for items without child items.
+ Whether the tree node in the project tree was expanded or collapsed during the last session. Applies to all item types, but is ignored for items without child items.
- heading
+ heading
- No
+ No
- The heading level of the first heading of the text of the item. Only applies to FILE item types. Allowed values are H0, H1, H2, H3, and H4. Other values are reset to H0.
+ The heading level of the first heading of the text of the item. Only applies to FILE item types. Allowed values are H0, H1, H2, H3, and H4. Other values are reset to H0.
- charCount
+ charCount
- No
+ No
- The number of characters in the text of the item. Only applies to FILE item types.
+ The number of characters in the text of the item. Only applies to FILE item types.
- wordCount
+ wordCount
- No
+ No
- The number of words in the text of the item. Only applies to FILE item types.
+ The number of words in the text of the item. Only applies to FILE item types.
- paraCount
+ paraCount
- No
+ No
- The number of paragraphs in the text of the item. Only applies to FILE item types.
+ The number of paragraphs in the text of the item. Only applies to FILE item types.
- cursorPos
+ cursorPos
- No
+ No
- The last cursor position in the text of the item from the last editing session. Only applies to FILE item types. The value is used to restore the cursor position when the document is opened in the editor.
+ The last cursor position in the text of the item from the last editing session. Only applies to FILE item types. The value is used to restore the cursor position when the document is opened in the editor.
- Name Nodes
- The name node contains information about an item that is set by the user. Including its label, which is the text value of the node. This is the label that is displayed in the project tree.
+ Name Nodes
+ The name node contains information about an item that is set by the user. Including its label, which is the text value of the node. This is the label that is displayed in the project tree.
Attributes
@@ -2220,45 +2199,45 @@
- status
+ status
- No
+ No
- The ID of the status label that has been set for this item. Defaults to the first status item defined in the status section of the settings node.
+ The ID of the status label that has been set for this item. Defaults to the first status item defined in the status section of the settings node.
- import
+ import
- No
+ No
- The ID of the importance label that has been set for this item. Defaults to the first importance item defined in the importance section of the settings node.
+ The ID of the importance label that has been set for this item. Defaults to the first importance item defined in the importance section of the settings node.
- active
+ active
- No
+ No
- The active/inactive status of the document. Only applies to FILE item types.
+ The active/inactive status of the document. Only applies to FILE item types.
Example
- <item handle="53b69b83cdafc" parent="7031beac91f75" root="7031beac91f75"
- order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
- <meta expanded="no" heading="H1" charCount="93" wordCount="19"
- paraCount="2" cursorPos="119"/>
- <name status="sc24b8f" import="ia857f0" active="yes">Title Page</name>
- </item>
+ <item handle="53b69b83cdafc" parent="7031beac91f75" root="7031beac91f75"
+ order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
+ <meta expanded="no" heading="H1" charCount="93" wordCount="19"
+ paraCount="2" cursorPos="119"/>
+ <name status="sc24b8f" import="ia857f0" active="yes">Title Page</name>
+ </item>
\ No newline at end of file
diff --git a/docs/source/fileformatspec15.pdf b/docs/source/fileformatspec15.pdf
index 5115b5b1..58b5be9d 100644
Binary files a/docs/source/fileformatspec15.pdf and b/docs/source/fileformatspec15.pdf differ
diff --git a/novelwriter/core/coretools.py b/novelwriter/core/coretools.py
index 029bf22d..c88369e8 100644
--- a/novelwriter/core/coretools.py
+++ b/novelwriter/core/coretools.py
@@ -374,7 +374,6 @@ class ProjectBuilder:
project.data.setUuid(None)
project.data.setName(projName)
- project.data.setTitle(projName)
project.data.setAuthor(projAuthor)
project.data.setLanguage(projLang)
project.setDefaultStatusImport()
@@ -383,7 +382,7 @@ class ProjectBuilder:
# Add Root Folders
hNovelRoot = project.newRoot(nwItemClass.NOVEL)
hTitlePage = project.newFile(lblTitlePage, hNovelRoot)
- novelTitle = project.data.title if project.data.title else project.data.name
+ novelTitle = project.data.name
titlePage = f"#! {novelTitle}\n\n"
if project.data.author:
diff --git a/novelwriter/core/projectdata.py b/novelwriter/core/projectdata.py
index 4a6fcec1..07c16909 100644
--- a/novelwriter/core/projectdata.py
+++ b/novelwriter/core/projectdata.py
@@ -53,7 +53,6 @@ class NWProjectData:
# Project Meta
self._uuid = ""
self._name = ""
- self._title = ""
self._author = ""
self._saveCount = 0
self._autoCount = 0
@@ -102,11 +101,6 @@ class NWProjectData:
"""Return the project name."""
return self._name
- @property
- def title(self) -> str:
- """Return the project title."""
- return self._title
-
@property
def author(self) -> str:
"""Return the project author."""
@@ -228,16 +222,9 @@ class NWProjectData:
self._project.setProjectChanged(True)
return
- def setTitle(self, value: str | None) -> None:
- """Set a new novel title."""
- if value != self._title:
- self._title = simplified(str(value or ""))
- self._project.setProjectChanged(True)
- return
-
def setAuthor(self, value: str | None) -> None:
"""Set the author value."""
- if value != self._title:
+ if value != self._author:
self._author = simplified(str(value or ""))
self._project.setProjectChanged(True)
return
diff --git a/novelwriter/core/projectxml.py b/novelwriter/core/projectxml.py
index 71e2608c..1b6bef79 100644
--- a/novelwriter/core/projectxml.py
+++ b/novelwriter/core/projectxml.py
@@ -46,7 +46,7 @@ if TYPE_CHECKING: # pragma: no cover
logger = logging.getLogger(__name__)
FILE_VERSION = "1.5" # The current project file format version
-FILE_REVISION = "1" # The current project file format revision
+FILE_REVISION = "2" # The current project file format revision
HEX_VERSION = 0x0105
NUM_VERSION = {
@@ -106,7 +106,8 @@ class ProjectXMLReader:
the project or the content into their respective section nodes
as attributes. The id attribute was also added to the project.
- Rev 1: Drops the titleFormat section of settings.
+ Rev 1: Drops the titleFormat node from settings. 2.1 Beta 1.
+ Rev 2: Drops the title node from project. 2.3 Beta 1.
"""
def __init__(self, path: str | Path) -> None:
@@ -247,8 +248,6 @@ class ProjectXMLReader:
for xItem in xSection:
if xItem.tag == "name":
data.setName(xItem.text)
- elif xItem.tag == "title":
- data.setTitle(xItem.text)
elif xItem.tag == "author":
data.setAuthor(xItem.text)
else:
@@ -520,7 +519,6 @@ class ProjectXMLWriter:
xProject = ET.SubElement(xRoot, "project", attrib=projAttr)
self._packSingleValue(xProject, "name", data.name)
- self._packSingleValue(xProject, "title", data.title)
self._packSingleValue(xProject, "author", data.author)
# Save Project Settings
diff --git a/novelwriter/core/tohtml.py b/novelwriter/core/tohtml.py
index c509a547..5598ece7 100644
--- a/novelwriter/core/tohtml.py
+++ b/novelwriter/core/tohtml.py
@@ -338,7 +338,6 @@ class ToHtml(Tokenizer):
data = {
"meta": {
"projectName": self._project.data.name,
- "novelTitle": self._project.data.title,
"novelAuthor": self._project.data.author,
"buildTime": int(timeStamp),
"buildTimeStr": formatTimeStamp(timeStamp),
diff --git a/novelwriter/core/tokenizer.py b/novelwriter/core/tokenizer.py
index f1421db1..5b222e73 100644
--- a/novelwriter/core/tokenizer.py
+++ b/novelwriter/core/tokenizer.py
@@ -759,7 +759,6 @@ class Tokenizer(ABC):
data = {
"meta": {
"projectName": self._project.data.name,
- "novelTitle": self._project.data.title,
"novelAuthor": self._project.data.author,
"buildTime": int(timeStamp),
"buildTimeStr": formatTimeStamp(timeStamp),
diff --git a/novelwriter/core/toodt.py b/novelwriter/core/toodt.py
index b34a56bf..4409b595 100644
--- a/novelwriter/core/toodt.py
+++ b/novelwriter/core/toodt.py
@@ -283,9 +283,7 @@ class ToOdt(Tokenizer):
# ===============
if self._headerText == "":
- theTitle = self._project.data.title or self._project.data.name
- theAuth = self._project.data.author
- self._headerText = f"{theTitle} / {theAuth} /"
+ self._headerText = f"{self._project.data.name} / {self._project.data.author} /"
# Create Roots
# ============
@@ -373,7 +371,7 @@ class ToOdt(Tokenizer):
# Dublin Core Meta Data
xMeta = ET.SubElement(self._xMeta, _mkTag("dc", "title"))
- xMeta.text = self._project.data.title or self._project.data.name
+ xMeta.text = self._project.data.name
xMeta = ET.SubElement(self._xMeta, _mkTag("dc", "date"))
xMeta.text = timeStamp
diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx
index af18a5a6..8d02b22d 100644
--- a/sample/nwProject.nwx
+++ b/sample/nwProject.nwx
@@ -1,8 +1,7 @@
-
-
+
+
Sample Project
- Sample Project
Jane Smith
diff --git a/tests/files/nwProject-1.5.nwx b/tests/files/nwProject-1.5.nwx
index 1965de73..cc17f909 100644
--- a/tests/files/nwProject-1.5.nwx
+++ b/tests/files/nwProject-1.5.nwx
@@ -1,8 +1,7 @@
-
+
Sample Project
- Sample Project
Jane Smith
diff --git a/tests/reference/coreProject_NewFileFolder_nwProject.nwx b/tests/reference/coreProject_NewFileFolder_nwProject.nwx
index 6fd70fb2..99b5a57c 100644
--- a/tests/reference/coreProject_NewFileFolder_nwProject.nwx
+++ b/tests/reference/coreProject_NewFileFolder_nwProject.nwx
@@ -1,8 +1,7 @@
-
+
New Project
- New Novel
Jane Doe
diff --git a/tests/reference/coreProject_NewRoot_nwProject.nwx b/tests/reference/coreProject_NewRoot_nwProject.nwx
index 057e3742..028da14c 100644
--- a/tests/reference/coreProject_NewRoot_nwProject.nwx
+++ b/tests/reference/coreProject_NewRoot_nwProject.nwx
@@ -1,8 +1,7 @@
-
+
New Project
- New Novel
Jane Doe
diff --git a/tests/reference/coreTools_DocDuplicator_nwProject.nwx b/tests/reference/coreTools_DocDuplicator_nwProject.nwx
index 0ee99397..bab9a82d 100644
--- a/tests/reference/coreTools_DocDuplicator_nwProject.nwx
+++ b/tests/reference/coreTools_DocDuplicator_nwProject.nwx
@@ -1,8 +1,7 @@
-
+
New Project
- New Novel
Jane Doe
diff --git a/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx b/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx
index 02f11a29..ee5eeeea 100644
--- a/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx
+++ b/tests/reference/coreTools_ProjectBuilderA_nwProject.nwx
@@ -1,8 +1,7 @@
-
+
Test Project A
- Test Project A
Jane Doe
diff --git a/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx b/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx
index 0df054a8..209c7809 100644
--- a/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx
+++ b/tests/reference/coreTools_ProjectBuilderB_nwProject.nwx
@@ -1,8 +1,7 @@
-
+
Test Project B
- Test Project B
Jane Doe
diff --git a/tests/reference/guiEditor_Main_Final_nwProject.nwx b/tests/reference/guiEditor_Main_Final_nwProject.nwx
index c56d9782..c3ee941f 100644
--- a/tests/reference/guiEditor_Main_Final_nwProject.nwx
+++ b/tests/reference/guiEditor_Main_Final_nwProject.nwx
@@ -1,8 +1,7 @@
-
-
+
+
New Project
- New Novel
Jane Doe
diff --git a/tests/reference/guiEditor_Main_Initial_nwProject.nwx b/tests/reference/guiEditor_Main_Initial_nwProject.nwx
index e266f65f..aa9c3a74 100644
--- a/tests/reference/guiEditor_Main_Initial_nwProject.nwx
+++ b/tests/reference/guiEditor_Main_Initial_nwProject.nwx
@@ -1,8 +1,7 @@
-
+
New Project
- New Novel
Jane Doe
diff --git a/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.json b/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.json
index 429aff11..7c315e5a 100644
--- a/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.json
+++ b/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.json
@@ -1,10 +1,9 @@
{
"meta": {
"projectName": "Lorem Ipsum",
- "novelTitle": "Lorem Ipsum",
"novelAuthor": "lipsum.com",
- "buildTime": 1687620769,
- "buildTimeStr": "2023-06-24 17:32:49"
+ "buildTime": 1706306020,
+ "buildTimeStr": "2024-01-26 22:53:40"
},
"text": {
"css": [
diff --git a/tests/reference/mBuildDocBuild_NWD_Lorem_Ipsum.json b/tests/reference/mBuildDocBuild_NWD_Lorem_Ipsum.json
index 305b0006..06633aa2 100644
--- a/tests/reference/mBuildDocBuild_NWD_Lorem_Ipsum.json
+++ b/tests/reference/mBuildDocBuild_NWD_Lorem_Ipsum.json
@@ -1,10 +1,9 @@
{
"meta": {
"projectName": "Lorem Ipsum",
- "novelTitle": "Lorem Ipsum",
"novelAuthor": "lipsum.com",
- "buildTime": 1687621222,
- "buildTimeStr": "2023-06-24 17:40:22"
+ "buildTime": 1706306020,
+ "buildTimeStr": "2024-01-26 22:53:40"
},
"text": {
"nwd": [
diff --git a/tests/reference/projectXML_ReadLegacy10.nwx b/tests/reference/projectXML_ReadLegacy10.nwx
index 9d04ef44..5161eb5b 100644
--- a/tests/reference/projectXML_ReadLegacy10.nwx
+++ b/tests/reference/projectXML_ReadLegacy10.nwx
@@ -1,8 +1,7 @@
-
+
Sample Project
- Sample Project
Jay Doh
diff --git a/tests/reference/projectXML_ReadLegacy11.nwx b/tests/reference/projectXML_ReadLegacy11.nwx
index 50924c78..7624a057 100644
--- a/tests/reference/projectXML_ReadLegacy11.nwx
+++ b/tests/reference/projectXML_ReadLegacy11.nwx
@@ -1,8 +1,7 @@
-
+
Sample Project
- Sample Project
Jay Doh
diff --git a/tests/reference/projectXML_ReadLegacy12.nwx b/tests/reference/projectXML_ReadLegacy12.nwx
index 7d36e380..58b29061 100644
--- a/tests/reference/projectXML_ReadLegacy12.nwx
+++ b/tests/reference/projectXML_ReadLegacy12.nwx
@@ -1,8 +1,7 @@
-
+
Sample Project
- Sample Project
Jay Doh
diff --git a/tests/reference/projectXML_ReadLegacy13.nwx b/tests/reference/projectXML_ReadLegacy13.nwx
index c75aa97c..28e24c69 100644
--- a/tests/reference/projectXML_ReadLegacy13.nwx
+++ b/tests/reference/projectXML_ReadLegacy13.nwx
@@ -1,8 +1,7 @@
-
+
Sample Project
- Sample Project
Jay Doh
diff --git a/tests/reference/projectXML_ReadLegacy14.nwx b/tests/reference/projectXML_ReadLegacy14.nwx
index aef603dd..26e7413c 100644
--- a/tests/reference/projectXML_ReadLegacy14.nwx
+++ b/tests/reference/projectXML_ReadLegacy14.nwx
@@ -1,8 +1,7 @@
-
+
Sample Project
- Sample Project
Jay Doh
diff --git a/tests/test_core/test_core_docbuild.py b/tests/test_core/test_core_docbuild.py
index 8890e2a8..b70269a8 100644
--- a/tests/test_core/test_core_docbuild.py
+++ b/tests/test_core/test_core_docbuild.py
@@ -230,7 +230,7 @@ def testCoreDocBuild_HTML(monkeypatch, mockGUI, prjLipsum, fncPath, tstPaths):
assert error == []
copyfile(docFile, tstFile)
- assert cmpFiles(tstFile, cmpFile, ignoreLines=[6, 7])
+ assert cmpFiles(tstFile, cmpFile, ignoreLines=[5, 6])
# Check Error Handling
# ====================
@@ -370,7 +370,7 @@ def testCoreDocBuild_NWD(monkeypatch, mockGUI, prjLipsum, fncPath, tstPaths):
assert error == []
copyfile(docFile, tstFile)
- assert cmpFiles(tstFile, cmpFile, ignoreLines=[6, 7])
+ assert cmpFiles(tstFile, cmpFile, ignoreLines=[5, 6])
# Check Error Handling
# ====================
diff --git a/tests/test_core/test_core_project.py b/tests/test_core/test_core_project.py
index 538e179b..fdad6b77 100644
--- a/tests/test_core/test_core_project.py
+++ b/tests/test_core/test_core_project.py
@@ -482,10 +482,6 @@ def testCoreProject_Methods(monkeypatch, mockGUI, fncPath, mockRnd):
project.data.setName(" A Name ")
assert project.data.name == "A Name"
- # Project Title
- project.data.setTitle(" A Title ")
- assert project.data.title == "A Title"
-
# Project Author
project.data.setAuthor(" Jane\tDoe ")
assert project.data.author == "Jane Doe"
diff --git a/tests/test_core/test_core_projectxml.py b/tests/test_core/test_core_projectxml.py
index 06dad380..32458158 100644
--- a/tests/test_core/test_core_projectxml.py
+++ b/tests/test_core/test_core_projectxml.py
@@ -142,13 +142,12 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
assert xmlReader.state == XMLReadState.PARSED_OK
assert xmlReader.xmlRoot == "novelWriterXML"
assert xmlReader.xmlVersion == 0x0105
- assert xmlReader.xmlRevision == 1
+ assert xmlReader.xmlRevision == 2
assert xmlReader.appVersion == "2.0-rc1"
assert xmlReader.hexVersion == 0x020000c1
# Check loaded data
assert data.name == "Sample Project"
- assert data.title == "Sample Project"
assert data.author == "Jane Smith"
assert data.saveCount == 5
assert data.autoCount == 10
@@ -267,7 +266,6 @@ def testCoreProjectXML_ReadLegacy10(tstPaths, fncPath, mockRnd):
# Check loaded data
assert data.name == "Sample Project"
- assert data.title == "Sample Project"
assert data.author == "Jay Doh" # Only last author is preserved
assert data.saveCount == 0 # Doesn't exist in 1.0
assert data.autoCount == 0 # Doesn't exist in 1.0
@@ -402,7 +400,6 @@ def testCoreProjectXML_ReadLegacy11(tstPaths, fncPath, mockRnd):
# Check loaded data
assert data.name == "Sample Project"
- assert data.title == "Sample Project"
assert data.author == "Jay Doh" # Only last author is preserved
assert data.saveCount == 5
assert data.autoCount == 10
@@ -537,7 +534,6 @@ def testCoreProjectXML_ReadLegacy12(tstPaths, fncPath, mockRnd):
# Check loaded data
assert data.name == "Sample Project"
- assert data.title == "Sample Project"
assert data.author == "Jay Doh" # Only last author is preserved
assert data.saveCount == 5
assert data.autoCount == 10
@@ -675,7 +671,6 @@ def testCoreProjectXML_ReadLegacy13(tstPaths, fncPath, mockRnd):
# Check loaded data
assert data.name == "Sample Project"
- assert data.title == "Sample Project"
assert data.author == "Jay Doh" # Only last author is preserved
assert data.saveCount == 5
assert data.autoCount == 10
@@ -813,7 +808,6 @@ def testCoreProjectXML_ReadLegacy14(tstPaths, fncPath, mockRnd):
# Check loaded data
assert data.name == "Sample Project"
- assert data.title == "Sample Project"
assert data.author == "Jay Doh" # Only last author is preserved
assert data.saveCount == 5
assert data.autoCount == 10
diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py
index cb06a470..5c15ed4a 100644
--- a/tests/test_gui/test_gui_guimain.py
+++ b/tests/test_gui/test_gui_guimain.py
@@ -200,7 +200,6 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
assert len(SHARED.project.tree._roots) == 0
assert SHARED.project.tree.trashRoot is None
assert SHARED.project.data.name == ""
- assert SHARED.project.data.title == ""
assert SHARED.project.data.author == ""
assert SHARED.project.data.spellCheck is False
@@ -220,7 +219,6 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd):
assert len(SHARED.project.tree._roots) == 4
assert SHARED.project.tree.trashRoot is None
assert SHARED.project.data.name == "New Project"
- assert SHARED.project.data.title == "New Novel"
assert SHARED.project.data.author == "Jane Doe"
assert SHARED.project.data.spellCheck is False
diff --git a/tests/tools.py b/tests/tools.py
index 51cdcc19..2da23818 100644
--- a/tests/tools.py
+++ b/tests/tools.py
@@ -179,7 +179,6 @@ def buildTestProject(obj: object, projPath: Path) -> None:
project.data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")
project.data.setName("New Project")
- project.data.setTitle("New Novel")
project.data.setAuthor("Jane Doe")
# Creating a minimal project with a few root folders and a