Merge pull request #760 from vkbo/doc_class

Non-Reusable Document Class
This commit is contained in:
Veronica Berglyd Olsen
2021-05-02 19:53:20 +02:00
committed by GitHub
47 changed files with 1310 additions and 1151 deletions
+150 -138
View File
@@ -793,22 +793,22 @@
<context> <context>
<name>GuiDocEditFooter</name> <name>GuiDocEditFooter</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2475"/> <location filename="../nw/gui/doceditor.py" line="2489"/>
<source>Status</source> <source>Status</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2616"/> <location filename="../nw/gui/doceditor.py" line="2630"/>
<source>Line: {0} ({1})</source> <source>Line: {0} ({1})</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2632"/> <location filename="../nw/gui/doceditor.py" line="2646"/>
<source>Words: {0} ({1})</source> <source>Words: {0} ({1})</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2637"/> <location filename="../nw/gui/doceditor.py" line="2651"/>
<source>Document size is {0} bytes</source> <source>Document size is {0} bytes</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -816,22 +816,22 @@
<context> <context>
<name>GuiDocEditHeader</name> <name>GuiDocEditHeader</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2267"/> <location filename="../nw/gui/doceditor.py" line="2281"/>
<source>Edit document meta</source> <source>Edit document meta</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2278"/> <location filename="../nw/gui/doceditor.py" line="2292"/>
<source>Search document</source> <source>Search document</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2289"/> <location filename="../nw/gui/doceditor.py" line="2303"/>
<source>Toggle Focus Mode</source> <source>Toggle Focus Mode</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2300"/> <location filename="../nw/gui/doceditor.py" line="2314"/>
<source>Close the document</source> <source>Close the document</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -839,97 +839,97 @@
<context> <context>
<name>GuiDocEditSearch</name> <name>GuiDocEditSearch</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1895"/> <location filename="../nw/gui/doceditor.py" line="1909"/>
<source>Search</source> <source>Search</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1886"/> <location filename="../nw/gui/doceditor.py" line="1900"/>
<source>Replace</source> <source>Replace</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1899"/> <location filename="../nw/gui/doceditor.py" line="1913"/>
<source>Case Sensitive</source> <source>Case Sensitive</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1900"/> <location filename="../nw/gui/doceditor.py" line="1914"/>
<source>Match case</source> <source>Match case</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1907"/> <location filename="../nw/gui/doceditor.py" line="1921"/>
<source>Whole Words Only</source> <source>Whole Words Only</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1908"/> <location filename="../nw/gui/doceditor.py" line="1922"/>
<source>Match whole words</source> <source>Match whole words</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1915"/> <location filename="../nw/gui/doceditor.py" line="1929"/>
<source>RegEx Mode</source> <source>RegEx Mode</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1916"/> <location filename="../nw/gui/doceditor.py" line="1930"/>
<source>Search using regular expressions</source> <source>Search using regular expressions</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1923"/> <location filename="../nw/gui/doceditor.py" line="1937"/>
<source>Loop Search</source> <source>Loop Search</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1924"/> <location filename="../nw/gui/doceditor.py" line="1938"/>
<source>Loop the search when reaching the end</source> <source>Loop the search when reaching the end</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1931"/> <location filename="../nw/gui/doceditor.py" line="1945"/>
<source>Search Next File</source> <source>Search Next File</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1932"/> <location filename="../nw/gui/doceditor.py" line="1946"/>
<source>Continue searching in the next file</source> <source>Continue searching in the next file</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1941"/> <location filename="../nw/gui/doceditor.py" line="1955"/>
<source>Preserve Case</source> <source>Preserve Case</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1942"/> <location filename="../nw/gui/doceditor.py" line="1956"/>
<source>Preserve case on replace</source> <source>Preserve case on replace</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1951"/> <location filename="../nw/gui/doceditor.py" line="1965"/>
<source>Close Search</source> <source>Close Search</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1952"/> <location filename="../nw/gui/doceditor.py" line="1966"/>
<source>Close the search box [{0}]</source> <source>Close the search box [{0}]</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1964"/> <location filename="../nw/gui/doceditor.py" line="1978"/>
<source>Show/hide the replace text box</source> <source>Show/hide the replace text box</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1970"/> <location filename="../nw/gui/doceditor.py" line="1984"/>
<source>Find in current document</source> <source>Find in current document</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1975"/> <location filename="../nw/gui/doceditor.py" line="1989"/>
<source>Find and replace in current document</source> <source>Find and replace in current document</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -937,99 +937,104 @@
<context> <context>
<name>GuiDocEditor</name> <name>GuiDocEditor</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="308"/> <location filename="../nw/gui/doceditor.py" line="313"/>
<source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="407"/> <location filename="../nw/gui/doceditor.py" line="411"/>
<source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="680"/> <location filename="../nw/gui/doceditor.py" line="694"/>
<source>Spell check complete</source> <source>Spell check complete</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>File Location</source> <source>File Location</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>The currently open file is saved in:</source> <source>The currently open file is saved in:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="964"/> <location filename="../nw/gui/doceditor.py" line="978"/>
<source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source> <source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1002"/> <location filename="../nw/gui/doceditor.py" line="1016"/>
<source>Follow Tag</source> <source>Follow Tag</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1008"/> <location filename="../nw/gui/doceditor.py" line="1022"/>
<source>Cut</source> <source>Cut</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1012"/> <location filename="../nw/gui/doceditor.py" line="1026"/>
<source>Copy</source> <source>Copy</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1016"/> <location filename="../nw/gui/doceditor.py" line="1030"/>
<source>Paste</source> <source>Paste</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1025"/> <location filename="../nw/gui/doceditor.py" line="1039"/>
<source>Select All</source> <source>Select All</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1029"/> <location filename="../nw/gui/doceditor.py" line="1043"/>
<source>Select Word</source> <source>Select Word</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1035"/> <location filename="../nw/gui/doceditor.py" line="1049"/>
<source>Select Paragraph</source> <source>Select Paragraph</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1061"/> <location filename="../nw/gui/doceditor.py" line="1075"/>
<source>Spelling Suggestion(s)</source> <source>Spelling Suggestion(s)</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1073"/> <location filename="../nw/gui/doceditor.py" line="1087"/>
<source>No Suggestions</source> <source>No Suggestions</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1079"/> <location filename="../nw/gui/doceditor.py" line="1093"/>
<source>Add Word to Dictionary</source> <source>Add Word to Dictionary</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1507"/> <location filename="../nw/gui/doceditor.py" line="1521"/>
<source>Please select some text before calling replace quotes.</source> <source>Please select some text before calling replace quotes.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="382"/> <location filename="../nw/gui/doceditor.py" line="386"/>
<source>Opened Document: {0}</source> <source>Opened Document: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="467"/> <location filename="../nw/gui/doceditor.py" line="482"/>
<source>Saved Document: {0}</source> <source>Saved Document: {0}</source>
<translation type="unfinished"></translation> <translation></translation>
</message>
<message>
<location filename="../nw/gui/doceditor.py" line="458"/>
<source>Could not save document.</source>
<translation></translation>
</message> </message>
</context> </context>
<context> <context>
@@ -1055,25 +1060,35 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="118"/> <location filename="../nw/dialogs/docmerge.py" line="123"/>
<source>No source document selected. Nothing to do.</source> <source>No source document selected. Nothing to do.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="125"/> <location filename="../nw/dialogs/docmerge.py" line="130"/>
<source>Could not parse source document.</source> <source>Could not parse source document.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="168"/> <location filename="../nw/dialogs/docmerge.py" line="177"/>
<source>Element selected in the project tree must be a folder.</source> <source>Element selected in the project tree must be a folder.</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="116"/>
<source>Failed to open document file.</source>
<translation></translation>
</message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="141"/>
<source>Could not save document.</source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocSplit</name> <name>GuiDocSplit</name>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Split Document</source> <source>Split Document</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -1118,30 +1133,40 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="153"/> <location filename="../nw/dialogs/docsplit.py" line="160"/>
<source>No headers found. Nothing to do.</source> <source>No headers found. Nothing to do.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="161"/> <location filename="../nw/dialogs/docsplit.py" line="168"/>
<source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source> <source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source> <source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Continue with the splitting process?</source> <source>Continue with the splitting process?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="256"/> <location filename="../nw/dialogs/docsplit.py" line="267"/>
<source>Element selected in the project tree must be a file.</source> <source>Element selected in the project tree must be a file.</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="135"/>
<source>Failed to open document file.</source>
<translation></translation>
</message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="230"/>
<source>Could not save document.</source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocViewFooter</name> <name>GuiDocViewFooter</name>
@@ -3965,7 +3990,7 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Delete File</source> <source>Delete File</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -3975,80 +4000,85 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Move file &apos;{0}&apos; to Trash?</source> <source>Move file &apos;{0}&apos; to Trash?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="572"/> <location filename="../nw/gui/projtree.py" line="577"/>
<source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="588"/> <location filename="../nw/gui/projtree.py" line="593"/>
<source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="875"/> <location filename="../nw/gui/projtree.py" line="880"/>
<source>The item cannot be moved to that location.</source> <source>The item cannot be moved to that location.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="972"/> <location filename="../nw/gui/projtree.py" line="977"/>
<source>There is nowhere to add item with name &apos;{0}&apos;.</source> <source>There is nowhere to add item with name &apos;{0}&apos;.</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../nw/gui/projtree.py" line="532"/>
<source>Could not delete document file.</source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>GuiProjectTreeMenu</name> <name>GuiProjectTreeMenu</name>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1094"/> <location filename="../nw/gui/projtree.py" line="1099"/>
<source>Edit Project Item</source> <source>Edit Project Item</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1098"/> <location filename="../nw/gui/projtree.py" line="1103"/>
<source>Open Document</source> <source>Open Document</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1102"/> <location filename="../nw/gui/projtree.py" line="1107"/>
<source>View Document</source> <source>View Document</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1106"/> <location filename="../nw/gui/projtree.py" line="1111"/>
<source>Toggle Included Flag</source> <source>Toggle Included Flag</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1110"/> <location filename="../nw/gui/projtree.py" line="1115"/>
<source>New File</source> <source>New File</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1114"/> <location filename="../nw/gui/projtree.py" line="1119"/>
<source>New Folder</source> <source>New Folder</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1118"/> <location filename="../nw/gui/projtree.py" line="1123"/>
<source>Delete Item</source> <source>Delete Item</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1122"/> <location filename="../nw/gui/projtree.py" line="1127"/>
<source>Empty Trash</source> <source>Empty Trash</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1126"/> <location filename="../nw/gui/projtree.py" line="1131"/>
<source>Move Item Up</source> <source>Move Item Up</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1130"/> <location filename="../nw/gui/projtree.py" line="1135"/>
<source>Move Item Down</source> <source>Move Item Down</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -4237,24 +4267,6 @@
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>NWDoc</name>
<message>
<location filename="../nw/core/document.py" line="118"/>
<source>Failed to open document file.</source>
<translation></translation>
</message>
<message>
<location filename="../nw/core/document.py" line="162"/>
<source>Could not save document.</source>
<translation></translation>
</message>
<message>
<location filename="../nw/core/document.py" line="192"/>
<source>Could not delete document file.</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>NWProject</name> <name>NWProject</name>
<message> <message>
@@ -4313,242 +4325,242 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="305"/> <location filename="../nw/core/project.py" line="299"/>
<source>Novel</source> <source>Novel</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="276"/> <location filename="../nw/core/project.py" line="273"/>
<source>Plot</source> <source>Plot</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="277"/> <location filename="../nw/core/project.py" line="274"/>
<source>Characters</source> <source>Characters</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="278"/> <location filename="../nw/core/project.py" line="275"/>
<source>World</source> <source>World</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="311"/> <location filename="../nw/core/project.py" line="305"/>
<source>Title Page</source> <source>Title Page</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="292"/> <location filename="../nw/core/project.py" line="288"/>
<source>New Chapter</source> <source>New Chapter</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="296"/> <location filename="../nw/core/project.py" line="291"/>
<source>New Scene</source> <source>New Scene</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="326"/> <location filename="../nw/core/project.py" line="319"/>
<source>Chapter {0}</source> <source>Chapter {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="351"/> <location filename="../nw/core/project.py" line="342"/>
<source>Scene {0}</source> <source>Scene {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="375"/> <location filename="../nw/core/project.py" line="365"/>
<source>File not found: {0}</source> <source>File not found: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="435"/> <location filename="../nw/core/project.py" line="425"/>
<source>Failed to parse project xml.</source> <source>Failed to parse project xml.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="429"/> <location filename="../nw/core/project.py" line="419"/>
<source>Attempting to open backup project file instead.</source> <source>Attempting to open backup project file instead.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="449"/> <location filename="../nw/core/project.py" line="439"/>
<source>Unknown</source> <source>Unknown</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="458"/> <location filename="../nw/core/project.py" line="448"/>
<source>Project file does not appear to be a novelWriterXML file.</source> <source>Project file does not appear to be a novelWriterXML file.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="478"/> <location filename="../nw/core/project.py" line="468"/>
<source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source> <source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>Version Conflict</source> <source>Version Conflict</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source> <source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="592"/> <location filename="../nw/core/project.py" line="582"/>
<source>Opened Project: {0}</source> <source>Opened Project: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="613"/> <location filename="../nw/core/project.py" line="603"/>
<source>Project path not set, cannot save project.</source> <source>Project path not set, cannot save project.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="694"/> <location filename="../nw/core/project.py" line="684"/>
<source>Failed to save project.</source> <source>Failed to save project.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="713"/> <location filename="../nw/core/project.py" line="703"/>
<source>Saved Project: {0}</source> <source>Saved Project: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="765"/> <location filename="../nw/core/project.py" line="755"/>
<source>Backing up project ...</source> <source>Backing up project ...</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="768"/> <location filename="../nw/core/project.py" line="758"/>
<source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="777"/> <location filename="../nw/core/project.py" line="767"/>
<source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source> <source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="786"/> <location filename="../nw/core/project.py" line="776"/>
<source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="801"/> <location filename="../nw/core/project.py" line="791"/>
<source>Could not create backup folder.</source> <source>Could not create backup folder.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="808"/> <location filename="../nw/core/project.py" line="798"/>
<source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="817"/> <location filename="../nw/core/project.py" line="807"/>
<source>Backup from {0}</source> <source>Backup from {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="826"/> <location filename="../nw/core/project.py" line="816"/>
<source>Backup archive file written to: {0}</source> <source>Backup archive file written to: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="835"/> <location filename="../nw/core/project.py" line="825"/>
<source>Could not write backup archive.</source> <source>Could not write backup archive.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="841"/> <location filename="../nw/core/project.py" line="831"/>
<source>Project backed up to &apos;{0}&apos;</source> <source>Project backed up to &apos;{0}&apos;</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="889"/> <location filename="../nw/core/project.py" line="879"/>
<source>Failed to create a new example project.</source> <source>Failed to create a new example project.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="894"/> <location filename="../nw/core/project.py" line="884"/>
<source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source> <source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="929"/> <location filename="../nw/core/project.py" line="919"/>
<source>Could not create new project folder.</source> <source>Could not create new project folder.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="936"/> <location filename="../nw/core/project.py" line="926"/>
<source>New project folder is not empty. Each project requires a dedicated project folder.</source> <source>New project folder is not empty. Each project requires a dedicated project folder.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="988"/> <location filename="../nw/core/project.py" line="978"/>
<source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source> <source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="997"/> <location filename="../nw/core/project.py" line="987"/>
<source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source> <source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1141"/> <location filename="../nw/core/project.py" line="1131"/>
<source>and</source> <source>and</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1387"/> <location filename="../nw/core/project.py" line="1377"/>
<source>Found {0} orphaned file(s) in project folder.</source> <source>Found {0} orphaned file(s) in project folder.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1399"/> <location filename="../nw/core/project.py" line="1388"/>
<source>Recovered</source> <source>Recovered</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1411"/> <location filename="../nw/core/project.py" line="1402"/>
<source>[{0}] {1}</source> <source>[{0}] {1}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1416"/> <location filename="../nw/core/project.py" line="1407"/>
<source>Recovered File {0}</source> <source>Recovered File {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1443"/> <location filename="../nw/core/project.py" line="1434"/>
<source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source> <source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1504"/> <location filename="../nw/core/project.py" line="1495"/>
<source>Not a folder: {0}</source> <source>Not a folder: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1527"/> <location filename="../nw/core/project.py" line="1518"/>
<source>Could not move: {0}</source> <source>Could not move: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1551"/> <location filename="../nw/core/project.py" line="1542"/>
<source>Could not delete: {0}</source> <source>Could not delete: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1563"/> <location filename="../nw/core/project.py" line="1554"/>
<source>Could not make folder: {0}</source> <source>Could not make folder: {0}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1574"/> <location filename="../nw/core/project.py" line="1565"/>
<source>Could not move item {0} to {1}.</source> <source>Could not move item {0} to {1}.</source>
<translation></translation> <translation></translation>
</message> </message>
+149 -137
View File
@@ -793,22 +793,22 @@
<context> <context>
<name>GuiDocEditFooter</name> <name>GuiDocEditFooter</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2475"/> <location filename="../nw/gui/doceditor.py" line="2489"/>
<source>Status</source> <source>Status</source>
<translation>État</translation> <translation>État</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2616"/> <location filename="../nw/gui/doceditor.py" line="2630"/>
<source>Line: {0} ({1})</source> <source>Line: {0} ({1})</source>
<translation>Ligne: {0} ({1})</translation> <translation>Ligne: {0} ({1})</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2632"/> <location filename="../nw/gui/doceditor.py" line="2646"/>
<source>Words: {0} ({1})</source> <source>Words: {0} ({1})</source>
<translation>Mots: {0} ({1})</translation> <translation>Mots: {0} ({1})</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2637"/> <location filename="../nw/gui/doceditor.py" line="2651"/>
<source>Document size is {0} bytes</source> <source>Document size is {0} bytes</source>
<translation>La taille du document est de {0} octets</translation> <translation>La taille du document est de {0} octets</translation>
</message> </message>
@@ -816,22 +816,22 @@
<context> <context>
<name>GuiDocEditHeader</name> <name>GuiDocEditHeader</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2267"/> <location filename="../nw/gui/doceditor.py" line="2281"/>
<source>Edit document meta</source> <source>Edit document meta</source>
<translation>Modifier les métadonnées du document</translation> <translation>Modifier les métadonnées du document</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2278"/> <location filename="../nw/gui/doceditor.py" line="2292"/>
<source>Search document</source> <source>Search document</source>
<translation>Chercher dans le document</translation> <translation>Chercher dans le document</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2289"/> <location filename="../nw/gui/doceditor.py" line="2303"/>
<source>Toggle Focus Mode</source> <source>Toggle Focus Mode</source>
<translation>Basculer le mode focus</translation> <translation>Basculer le mode focus</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2300"/> <location filename="../nw/gui/doceditor.py" line="2314"/>
<source>Close the document</source> <source>Close the document</source>
<translation>Fermer le document</translation> <translation>Fermer le document</translation>
</message> </message>
@@ -839,97 +839,97 @@
<context> <context>
<name>GuiDocEditSearch</name> <name>GuiDocEditSearch</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1895"/> <location filename="../nw/gui/doceditor.py" line="1909"/>
<source>Search</source> <source>Search</source>
<translation>Chercher</translation> <translation>Chercher</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1886"/> <location filename="../nw/gui/doceditor.py" line="1900"/>
<source>Replace</source> <source>Replace</source>
<translation>Remplacer</translation> <translation>Remplacer</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1899"/> <location filename="../nw/gui/doceditor.py" line="1913"/>
<source>Case Sensitive</source> <source>Case Sensitive</source>
<translation>Sensible à la casse</translation> <translation>Sensible à la casse</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1900"/> <location filename="../nw/gui/doceditor.py" line="1914"/>
<source>Match case</source> <source>Match case</source>
<translation>Respecter la casse</translation> <translation>Respecter la casse</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1907"/> <location filename="../nw/gui/doceditor.py" line="1921"/>
<source>Whole Words Only</source> <source>Whole Words Only</source>
<translation>Mots entiers uniquement</translation> <translation>Mots entiers uniquement</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1908"/> <location filename="../nw/gui/doceditor.py" line="1922"/>
<source>Match whole words</source> <source>Match whole words</source>
<translation>Ne vérifier la correspondance que sur des mots entiers</translation> <translation>Ne vérifier la correspondance que sur des mots entiers</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1915"/> <location filename="../nw/gui/doceditor.py" line="1929"/>
<source>RegEx Mode</source> <source>RegEx Mode</source>
<translation>Expressions régulières</translation> <translation>Expressions régulières</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1916"/> <location filename="../nw/gui/doceditor.py" line="1930"/>
<source>Search using regular expressions</source> <source>Search using regular expressions</source>
<translation>Chercher en utilisant des expressions régulières</translation> <translation>Chercher en utilisant des expressions régulières</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1923"/> <location filename="../nw/gui/doceditor.py" line="1937"/>
<source>Loop Search</source> <source>Loop Search</source>
<translation>Recherche en boucle</translation> <translation>Recherche en boucle</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1924"/> <location filename="../nw/gui/doceditor.py" line="1938"/>
<source>Loop the search when reaching the end</source> <source>Loop the search when reaching the end</source>
<translation>Reprendre la recherche au début du texte lorsque la fin est atteinte</translation> <translation>Reprendre la recherche au début du texte lorsque la fin est atteinte</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1931"/> <location filename="../nw/gui/doceditor.py" line="1945"/>
<source>Search Next File</source> <source>Search Next File</source>
<translation>Chercher dans le fichier suivant</translation> <translation>Chercher dans le fichier suivant</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1932"/> <location filename="../nw/gui/doceditor.py" line="1946"/>
<source>Continue searching in the next file</source> <source>Continue searching in the next file</source>
<translation>Continuer la recherche dans le fichier suivant</translation> <translation>Continuer la recherche dans le fichier suivant</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1941"/> <location filename="../nw/gui/doceditor.py" line="1955"/>
<source>Preserve Case</source> <source>Preserve Case</source>
<translation>Conserver la casse</translation> <translation>Conserver la casse</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1942"/> <location filename="../nw/gui/doceditor.py" line="1956"/>
<source>Preserve case on replace</source> <source>Preserve case on replace</source>
<translation>Conserver la casse lors d&apos;un remplacement</translation> <translation>Conserver la casse lors d&apos;un remplacement</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1951"/> <location filename="../nw/gui/doceditor.py" line="1965"/>
<source>Close Search</source> <source>Close Search</source>
<translation>Terminer la recherche</translation> <translation>Terminer la recherche</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1952"/> <location filename="../nw/gui/doceditor.py" line="1966"/>
<source>Close the search box [{0}]</source> <source>Close the search box [{0}]</source>
<translation>Fermer la boîte de recherche [{0}]</translation> <translation>Fermer la boîte de recherche [{0}]</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1964"/> <location filename="../nw/gui/doceditor.py" line="1978"/>
<source>Show/hide the replace text box</source> <source>Show/hide the replace text box</source>
<translation>Montrer/cacher le texte de remplacement</translation> <translation>Montrer/cacher le texte de remplacement</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1970"/> <location filename="../nw/gui/doceditor.py" line="1984"/>
<source>Find in current document</source> <source>Find in current document</source>
<translation>Chercher dans le document actuel</translation> <translation>Chercher dans le document actuel</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1975"/> <location filename="../nw/gui/doceditor.py" line="1989"/>
<source>Find and replace in current document</source> <source>Find and replace in current document</source>
<translation>Chercher et remplacer dans le document actuel</translation> <translation>Chercher et remplacer dans le document actuel</translation>
</message> </message>
@@ -937,100 +937,105 @@
<context> <context>
<name>GuiDocEditor</name> <name>GuiDocEditor</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="308"/> <location filename="../nw/gui/doceditor.py" line="313"/>
<source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation>Le document que vous essayez d&apos;ouvrir est trop grand. La taille du document est de {0} MB alors que la taille maximale est de {1} MB.</translation> <translation>Le document que vous essayez d&apos;ouvrir est trop grand. La taille du document est de {0} MB alors que la taille maximale est de {1} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="407"/> <location filename="../nw/gui/doceditor.py" line="411"/>
<source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation>Le texte que vous voulez ajouter est trop grand. La taille du texte est de {0} MB alors que la taille maximale est de {1} MB.</translation> <translation>Le texte que vous voulez ajouter est trop grand. La taille du texte est de {0} MB alors que la taille maximale est de {1} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="680"/> <location filename="../nw/gui/doceditor.py" line="694"/>
<source>Spell check complete</source> <source>Spell check complete</source>
<translation>La vérification orthographique est terminée</translation> <translation>La vérification orthographique est terminée</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>File Location</source> <source>File Location</source>
<translation>Emplacement du fichier</translation> <translation>Emplacement du fichier</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>The currently open file is saved in:</source> <source>The currently open file is saved in:</source>
<translation>Le fichier actuellement ouvert est enregistré dans :</translation> <translation>Le fichier actuellement ouvert est enregistré dans :</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="964"/> <location filename="../nw/gui/doceditor.py" line="978"/>
<source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source> <source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source>
<translation>Le document est devenu trop grand et vous ne pouvez plus lui ajouter de texte. La taille maximale d&apos;un fichier novelWriter est de {0} MB.</translation> <translation>Le document est devenu trop grand et vous ne pouvez plus lui ajouter de texte. La taille maximale d&apos;un fichier novelWriter est de {0} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1002"/> <location filename="../nw/gui/doceditor.py" line="1016"/>
<source>Follow Tag</source> <source>Follow Tag</source>
<translation>Suivre cette étiquette</translation> <translation>Suivre cette étiquette</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1008"/> <location filename="../nw/gui/doceditor.py" line="1022"/>
<source>Cut</source> <source>Cut</source>
<translation>Couper</translation> <translation>Couper</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1012"/> <location filename="../nw/gui/doceditor.py" line="1026"/>
<source>Copy</source> <source>Copy</source>
<translation>Copier</translation> <translation>Copier</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1016"/> <location filename="../nw/gui/doceditor.py" line="1030"/>
<source>Paste</source> <source>Paste</source>
<translation>Coller</translation> <translation>Coller</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1025"/> <location filename="../nw/gui/doceditor.py" line="1039"/>
<source>Select All</source> <source>Select All</source>
<translation>Sélectionner tout</translation> <translation>Sélectionner tout</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1029"/> <location filename="../nw/gui/doceditor.py" line="1043"/>
<source>Select Word</source> <source>Select Word</source>
<translation>Sélectionner le mot</translation> <translation>Sélectionner le mot</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1035"/> <location filename="../nw/gui/doceditor.py" line="1049"/>
<source>Select Paragraph</source> <source>Select Paragraph</source>
<translation>Sélectionner le paragraphe</translation> <translation>Sélectionner le paragraphe</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1061"/> <location filename="../nw/gui/doceditor.py" line="1075"/>
<source>Spelling Suggestion(s)</source> <source>Spelling Suggestion(s)</source>
<translation>Orthographe suggérée</translation> <translation>Orthographe suggérée</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1073"/> <location filename="../nw/gui/doceditor.py" line="1087"/>
<source>No Suggestions</source> <source>No Suggestions</source>
<translation>Pas de suggestion</translation> <translation>Pas de suggestion</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1079"/> <location filename="../nw/gui/doceditor.py" line="1093"/>
<source>Add Word to Dictionary</source> <source>Add Word to Dictionary</source>
<translation>Ajouter ce mot au dictionnaire</translation> <translation>Ajouter ce mot au dictionnaire</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1507"/> <location filename="../nw/gui/doceditor.py" line="1521"/>
<source>Please select some text before calling replace quotes.</source> <source>Please select some text before calling replace quotes.</source>
<translation>Veuillez sélectionner du texte avant de demander le remplacement des guillemets.</translation> <translation>Veuillez sélectionner du texte avant de demander le remplacement des guillemets.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="382"/> <location filename="../nw/gui/doceditor.py" line="386"/>
<source>Opened Document: {0}</source> <source>Opened Document: {0}</source>
<translation>Document ouvert : {0}</translation> <translation>Document ouvert : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="467"/> <location filename="../nw/gui/doceditor.py" line="482"/>
<source>Saved Document: {0}</source> <source>Saved Document: {0}</source>
<translation>Document enregistré : {0}</translation> <translation>Document enregistré : {0}</translation>
</message> </message>
<message>
<location filename="../nw/gui/doceditor.py" line="458"/>
<source>Could not save document.</source>
<translation>Impossible d&apos;enregistrer le document.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocMerge</name> <name>GuiDocMerge</name>
@@ -1055,25 +1060,35 @@
<translation>Pas de document source trouvé. Aucune action.</translation> <translation>Pas de document source trouvé. Aucune action.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="118"/> <location filename="../nw/dialogs/docmerge.py" line="123"/>
<source>No source document selected. Nothing to do.</source> <source>No source document selected. Nothing to do.</source>
<translation>Pas de document source sélectionné. Aucune action.</translation> <translation>Pas de document source sélectionné. Aucune action.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="125"/> <location filename="../nw/dialogs/docmerge.py" line="130"/>
<source>Could not parse source document.</source> <source>Could not parse source document.</source>
<translation>Impossible d&apos;interpréter le nom du document source.</translation> <translation>Impossible d&apos;interpréter le nom du document source.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="168"/> <location filename="../nw/dialogs/docmerge.py" line="177"/>
<source>Element selected in the project tree must be a folder.</source> <source>Element selected in the project tree must be a folder.</source>
<translation>L&apos;élement selectionné dans l&apos;arborescence doit être un dossier.</translation> <translation>L&apos;élement selectionné dans l&apos;arborescence doit être un dossier.</translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="116"/>
<source>Failed to open document file.</source>
<translation>Impossible d&apos;ouvrir le document.</translation>
</message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="141"/>
<source>Could not save document.</source>
<translation>Impossible d&apos;enregistrer le document.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocSplit</name> <name>GuiDocSplit</name>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Split Document</source> <source>Split Document</source>
<translation>Découper un document</translation> <translation>Découper un document</translation>
</message> </message>
@@ -1118,30 +1133,40 @@
<translation>Impossible d&apos;interpréter le nom du document source.</translation> <translation>Impossible d&apos;interpréter le nom du document source.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="153"/> <location filename="../nw/dialogs/docsplit.py" line="160"/>
<source>No headers found. Nothing to do.</source> <source>No headers found. Nothing to do.</source>
<translation>Pas d&apos;en-tête trouvé. Aucune action.</translation> <translation>Pas d&apos;en-tête trouvé. Aucune action.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="161"/> <location filename="../nw/dialogs/docsplit.py" line="168"/>
<source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source> <source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source>
<translation>Impossible d&apos;ajouter un nouveau dossier lors du découpage. Le nombre maximum de dossiers a é atteint. Veuillez placer ce fichier à un autre niveau dans l&apos;arborescence.</translation> <translation>Impossible d&apos;ajouter un nouveau dossier lors du découpage. Le nombre maximum de dossiers a é atteint. Veuillez placer ce fichier à un autre niveau dans l&apos;arborescence.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source> <source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source>
<translation>Ce document va être découpé en {0} fichier(s) dans un nouveau dossier. Le document d&apos;origine restera intact.</translation> <translation>Ce document va être découpé en {0} fichier(s) dans un nouveau dossier. Le document d&apos;origine restera intact.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Continue with the splitting process?</source> <source>Continue with the splitting process?</source>
<translation>Continuer le découpage ?</translation> <translation>Continuer le découpage ?</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="256"/> <location filename="../nw/dialogs/docsplit.py" line="267"/>
<source>Element selected in the project tree must be a file.</source> <source>Element selected in the project tree must be a file.</source>
<translation>L&apos;élément sélectionné dans l&apos;arborescence doit être un fichier.</translation> <translation>L&apos;élément sélectionné dans l&apos;arborescence doit être un fichier.</translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="135"/>
<source>Failed to open document file.</source>
<translation>Impossible d&apos;ouvrir le document.</translation>
</message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="230"/>
<source>Could not save document.</source>
<translation>Impossible d&apos;enregistrer le document.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocViewFooter</name> <name>GuiDocViewFooter</name>
@@ -3965,7 +3990,7 @@
<translation>Effacer définitivement {0} fichier(s) dans la Corbeille ?</translation> <translation>Effacer définitivement {0} fichier(s) dans la Corbeille ?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Delete File</source> <source>Delete File</source>
<translation>Effacer un fichier</translation> <translation>Effacer un fichier</translation>
</message> </message>
@@ -3975,80 +4000,85 @@
<translation>Effacer définitivement le fichier &apos;{0}&apos; ?</translation> <translation>Effacer définitivement le fichier &apos;{0}&apos; ?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Move file &apos;{0}&apos; to Trash?</source> <source>Move file &apos;{0}&apos; to Trash?</source>
<translation>Mettre le fichier &apos;{0}&apos; dans la Corbeille ?</translation> <translation>Mettre le fichier &apos;{0}&apos; dans la Corbeille ?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="572"/> <location filename="../nw/gui/projtree.py" line="577"/>
<source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation>Impossible d&apos;effacer le dossier car il n&apos;est pas vide. Les effacements récursifs n&apos;étant pas permis vous devez d&apos;abord effacer le contenu.</translation> <translation>Impossible d&apos;effacer le dossier car il n&apos;est pas vide. Les effacements récursifs n&apos;étant pas permis vous devez d&apos;abord effacer le contenu.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="588"/> <location filename="../nw/gui/projtree.py" line="593"/>
<source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation>Impossible d&apos;effacer le dossier racine car il n&apos;est pas vide. Les effacements récursifs n&apos;étant pas permis vous devez d&apos;abord effacer le contenu.</translation> <translation>Impossible d&apos;effacer le dossier racine car il n&apos;est pas vide. Les effacements récursifs n&apos;étant pas permis vous devez d&apos;abord effacer le contenu.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="875"/> <location filename="../nw/gui/projtree.py" line="880"/>
<source>The item cannot be moved to that location.</source> <source>The item cannot be moved to that location.</source>
<translation>Impossible de déplacer cet item vers cet emplacement.</translation> <translation>Impossible de déplacer cet item vers cet emplacement.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="972"/> <location filename="../nw/gui/projtree.py" line="977"/>
<source>There is nowhere to add item with name &apos;{0}&apos;.</source> <source>There is nowhere to add item with name &apos;{0}&apos;.</source>
<translation>Il n&apos;y a pas d&apos;emplacement pour ajouter l&apos;item nommé &apos;{0}&apos;.</translation> <translation>Il n&apos;y a pas d&apos;emplacement pour ajouter l&apos;item nommé &apos;{0}&apos;.</translation>
</message> </message>
<message>
<location filename="../nw/gui/projtree.py" line="532"/>
<source>Could not delete document file.</source>
<translation>Impossible d&apos;effacer le document.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiProjectTreeMenu</name> <name>GuiProjectTreeMenu</name>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1094"/> <location filename="../nw/gui/projtree.py" line="1099"/>
<source>Edit Project Item</source> <source>Edit Project Item</source>
<translation>Éditer les caractéristiques</translation> <translation>Éditer les caractéristiques</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1098"/> <location filename="../nw/gui/projtree.py" line="1103"/>
<source>Open Document</source> <source>Open Document</source>
<translation>Ouvrir ce document</translation> <translation>Ouvrir ce document</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1102"/> <location filename="../nw/gui/projtree.py" line="1107"/>
<source>View Document</source> <source>View Document</source>
<translation>Afficher ce document</translation> <translation>Afficher ce document</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1106"/> <location filename="../nw/gui/projtree.py" line="1111"/>
<source>Toggle Included Flag</source> <source>Toggle Included Flag</source>
<translation>Basculer le marqueur d&apos;inclusion</translation> <translation>Basculer le marqueur d&apos;inclusion</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1110"/> <location filename="../nw/gui/projtree.py" line="1115"/>
<source>New File</source> <source>New File</source>
<translation>Nouveau fichier</translation> <translation>Nouveau fichier</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1114"/> <location filename="../nw/gui/projtree.py" line="1119"/>
<source>New Folder</source> <source>New Folder</source>
<translation>Nouveau dossier</translation> <translation>Nouveau dossier</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1118"/> <location filename="../nw/gui/projtree.py" line="1123"/>
<source>Delete Item</source> <source>Delete Item</source>
<translation>Supprimer ce composant</translation> <translation>Supprimer ce composant</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1122"/> <location filename="../nw/gui/projtree.py" line="1127"/>
<source>Empty Trash</source> <source>Empty Trash</source>
<translation>Vider la corbeille</translation> <translation>Vider la corbeille</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1126"/> <location filename="../nw/gui/projtree.py" line="1131"/>
<source>Move Item Up</source> <source>Move Item Up</source>
<translation>Faire monter ce composant</translation> <translation>Faire monter ce composant</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1130"/> <location filename="../nw/gui/projtree.py" line="1135"/>
<source>Move Item Down</source> <source>Move Item Down</source>
<translation>Faire descendre ce composant</translation> <translation>Faire descendre ce composant</translation>
</message> </message>
@@ -4237,24 +4267,6 @@
<translation>Impossible de lire le fichier log de la session.</translation> <translation>Impossible de lire le fichier log de la session.</translation>
</message> </message>
</context> </context>
<context>
<name>NWDoc</name>
<message>
<location filename="../nw/core/document.py" line="118"/>
<source>Failed to open document file.</source>
<translation>Impossible d&apos;ouvrir le document.</translation>
</message>
<message>
<location filename="../nw/core/document.py" line="162"/>
<source>Could not save document.</source>
<translation>Impossible d&apos;enregistrer le document.</translation>
</message>
<message>
<location filename="../nw/core/document.py" line="192"/>
<source>Could not delete document file.</source>
<translation>Impossible d&apos;effacer le document.</translation>
</message>
</context>
<context> <context>
<name>NWProject</name> <name>NWProject</name>
<message> <message>
@@ -4313,242 +4325,242 @@
<translation>Par</translation> <translation>Par</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="305"/> <location filename="../nw/core/project.py" line="299"/>
<source>Novel</source> <source>Novel</source>
<translation>Roman</translation> <translation>Roman</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="276"/> <location filename="../nw/core/project.py" line="273"/>
<source>Plot</source> <source>Plot</source>
<translation>Intrigue</translation> <translation>Intrigue</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="277"/> <location filename="../nw/core/project.py" line="274"/>
<source>Characters</source> <source>Characters</source>
<translation>Personnages</translation> <translation>Personnages</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="278"/> <location filename="../nw/core/project.py" line="275"/>
<source>World</source> <source>World</source>
<translation>Monde</translation> <translation>Monde</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="311"/> <location filename="../nw/core/project.py" line="305"/>
<source>Title Page</source> <source>Title Page</source>
<translation>Page de titre</translation> <translation>Page de titre</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="292"/> <location filename="../nw/core/project.py" line="288"/>
<source>New Chapter</source> <source>New Chapter</source>
<translation>Nouveau chapitre</translation> <translation>Nouveau chapitre</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="296"/> <location filename="../nw/core/project.py" line="291"/>
<source>New Scene</source> <source>New Scene</source>
<translation>Nouvelle scène</translation> <translation>Nouvelle scène</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="326"/> <location filename="../nw/core/project.py" line="319"/>
<source>Chapter {0}</source> <source>Chapter {0}</source>
<translation>Chapitre{0}</translation> <translation>Chapitre{0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="351"/> <location filename="../nw/core/project.py" line="342"/>
<source>Scene {0}</source> <source>Scene {0}</source>
<translation>Scène {0}</translation> <translation>Scène {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="375"/> <location filename="../nw/core/project.py" line="365"/>
<source>File not found: {0}</source> <source>File not found: {0}</source>
<translation>Fichier introuvable : {0}</translation> <translation>Fichier introuvable : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="435"/> <location filename="../nw/core/project.py" line="425"/>
<source>Failed to parse project xml.</source> <source>Failed to parse project xml.</source>
<translation>Impossible de décoder le xml du projet.</translation> <translation>Impossible de décoder le xml du projet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="429"/> <location filename="../nw/core/project.py" line="419"/>
<source>Attempting to open backup project file instead.</source> <source>Attempting to open backup project file instead.</source>
<translation>Essai d&apos;ouverture depuis le fichier de sauvegarde du projet.</translation> <translation>Essai d&apos;ouverture depuis le fichier de sauvegarde du projet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="449"/> <location filename="../nw/core/project.py" line="439"/>
<source>Unknown</source> <source>Unknown</source>
<translation>Inconnu</translation> <translation>Inconnu</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="458"/> <location filename="../nw/core/project.py" line="448"/>
<source>Project file does not appear to be a novelWriterXML file.</source> <source>Project file does not appear to be a novelWriterXML file.</source>
<translation>Ce fichier projet ne semble pas être un fichier novelWriterXML.</translation> <translation>Ce fichier projet ne semble pas être un fichier novelWriterXML.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="478"/> <location filename="../nw/core/project.py" line="468"/>
<source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source> <source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source>
<translation>Format de projet novelWriter inconnu ou non supporté. Ce projet ne peut pas être ouvert avec cette version de novelWriter, il a é enregistré avec novelWriter version {0}.</translation> <translation>Format de projet novelWriter inconnu ou non supporté. Ce projet ne peut pas être ouvert avec cette version de novelWriter, il a é enregistré avec novelWriter version {0}.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>Version Conflict</source> <source>Version Conflict</source>
<translation>Conflit de version</translation> <translation>Conflit de version</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source> <source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source>
<translation>Ce projet a é enregistré par une version plus récente de novelWriter, la version {0}. Ceci est la version {1}. Si vous ouvrez quand même ce projet, certaines propriétés ou certains réglages risquent d&apos;être perdus, toutefois le projet dans son ensemble devrait être intact. Voulez-vous quand même ouvrir ce projet ?</translation> <translation>Ce projet a é enregistré par une version plus récente de novelWriter, la version {0}. Ceci est la version {1}. Si vous ouvrez quand même ce projet, certaines propriétés ou certains réglages risquent d&apos;être perdus, toutefois le projet dans son ensemble devrait être intact. Voulez-vous quand même ouvrir ce projet ?</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="592"/> <location filename="../nw/core/project.py" line="582"/>
<source>Opened Project: {0}</source> <source>Opened Project: {0}</source>
<translation>Projet ouvert : {0}</translation> <translation>Projet ouvert : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="613"/> <location filename="../nw/core/project.py" line="603"/>
<source>Project path not set, cannot save project.</source> <source>Project path not set, cannot save project.</source>
<translation>L&apos;emplacement du projet n&apos;est pas défini, il est impossible de l&apos;enregistrer.</translation> <translation>L&apos;emplacement du projet n&apos;est pas défini, il est impossible de l&apos;enregistrer.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="694"/> <location filename="../nw/core/project.py" line="684"/>
<source>Failed to save project.</source> <source>Failed to save project.</source>
<translation>Impossible d&apos;enregistrer le projet.</translation> <translation>Impossible d&apos;enregistrer le projet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="713"/> <location filename="../nw/core/project.py" line="703"/>
<source>Saved Project: {0}</source> <source>Saved Project: {0}</source>
<translation>Projet enregistré : {0}</translation> <translation>Projet enregistré : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="765"/> <location filename="../nw/core/project.py" line="755"/>
<source>Backing up project ...</source> <source>Backing up project ...</source>
<translation>Sauvegarde du projet en cours ...</translation> <translation>Sauvegarde du projet en cours ...</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="768"/> <location filename="../nw/core/project.py" line="758"/>
<source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation>Il est impossible de sauvegarder le projet car aucun emplacement de sauvegarde n&apos;a é défini. Veuillez en définir un dans Outils &gt; Préférences.</translation> <translation>Il est impossible de sauvegarder le projet car aucun emplacement de sauvegarde n&apos;a é défini. Veuillez en définir un dans Outils &gt; Préférences.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="777"/> <location filename="../nw/core/project.py" line="767"/>
<source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source> <source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source>
<translation>Il est impossible de sauvegarder le projet car il n&apos;a pas reçu de nom. Veuillez définir un titre de travail dans Projet &gt; Caractéristiques du projet.</translation> <translation>Il est impossible de sauvegarder le projet car il n&apos;a pas reçu de nom. Veuillez définir un titre de travail dans Projet &gt; Caractéristiques du projet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="786"/> <location filename="../nw/core/project.py" line="776"/>
<source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation>Il est impossible de sauvegarder le projet car l&apos;emplacement de sauvegarde défini n&apos;existe pas. Veuillez définir un emplacement correct dans Outils &gt; Préférences.</translation> <translation>Il est impossible de sauvegarder le projet car l&apos;emplacement de sauvegarde défini n&apos;existe pas. Veuillez définir un emplacement correct dans Outils &gt; Préférences.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="801"/> <location filename="../nw/core/project.py" line="791"/>
<source>Could not create backup folder.</source> <source>Could not create backup folder.</source>
<translation>Il n&apos;a pas é possible de créer le répertoire de sauvegarde.</translation> <translation>Il n&apos;a pas é possible de créer le répertoire de sauvegarde.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="808"/> <location filename="../nw/core/project.py" line="798"/>
<source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source>
<translation>La sauvegarde du projet est impossible car l&apos;emplacement défini est situé dans le dossier à sauvegarder. Veuillez définir un autre répertoire de sauvegarde dans Outils &gt; Préférences.</translation> <translation>La sauvegarde du projet est impossible car l&apos;emplacement défini est situé dans le dossier à sauvegarder. Veuillez définir un autre répertoire de sauvegarde dans Outils &gt; Préférences.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="817"/> <location filename="../nw/core/project.py" line="807"/>
<source>Backup from {0}</source> <source>Backup from {0}</source>
<translation>Sauvegarde depuis {0}</translation> <translation>Sauvegarde depuis {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="826"/> <location filename="../nw/core/project.py" line="816"/>
<source>Backup archive file written to: {0}</source> <source>Backup archive file written to: {0}</source>
<translation>Archivage du fichier de sauvegarde effectué en : {0}</translation> <translation>Archivage du fichier de sauvegarde effectué en : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="835"/> <location filename="../nw/core/project.py" line="825"/>
<source>Could not write backup archive.</source> <source>Could not write backup archive.</source>
<translation>Il n&apos;a pas é possible d&apos;écrire l&apos;archive de sauvegarde.</translation> <translation>Il n&apos;a pas é possible d&apos;écrire l&apos;archive de sauvegarde.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="841"/> <location filename="../nw/core/project.py" line="831"/>
<source>Project backed up to &apos;{0}&apos;</source> <source>Project backed up to &apos;{0}&apos;</source>
<translation>Projet sauvegardé en &apos;{0}&apos;</translation> <translation>Projet sauvegardé en &apos;{0}&apos;</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="889"/> <location filename="../nw/core/project.py" line="879"/>
<source>Failed to create a new example project.</source> <source>Failed to create a new example project.</source>
<translation>Il n&apos;a pas é possible de créer un nouveau projet exemple.</translation> <translation>Il n&apos;a pas é possible de créer un nouveau projet exemple.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="894"/> <location filename="../nw/core/project.py" line="884"/>
<source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source> <source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source>
<translation>Il n&apos;a pas é possible de créer un nouveau projet exemple. Il semble que les fichiers nécessaires soient manquants dans cette installation.</translation> <translation>Il n&apos;a pas é possible de créer un nouveau projet exemple. Il semble que les fichiers nécessaires soient manquants dans cette installation.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="929"/> <location filename="../nw/core/project.py" line="919"/>
<source>Could not create new project folder.</source> <source>Could not create new project folder.</source>
<translation>Il n&apos;a pas é possible de créer un nouveau dossier de projet.</translation> <translation>Il n&apos;a pas é possible de créer un nouveau dossier de projet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="936"/> <location filename="../nw/core/project.py" line="926"/>
<source>New project folder is not empty. Each project requires a dedicated project folder.</source> <source>New project folder is not empty. Each project requires a dedicated project folder.</source>
<translation>Le dossier pour le nouveau projet n&apos;est pas vide. Chaque projet doit résider dans un dossier spécifique.</translation> <translation>Le dossier pour le nouveau projet n&apos;est pas vide. Chaque projet doit résider dans un dossier spécifique.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="988"/> <location filename="../nw/core/project.py" line="978"/>
<source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source> <source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source>
<translation>Vous devez spécifier un répertoire de sauvegarde valide dans les préférences du projet avant d&apos;utiliser la fonction de sauvegarde automatique.</translation> <translation>Vous devez spécifier un répertoire de sauvegarde valide dans les préférences du projet avant d&apos;utiliser la fonction de sauvegarde automatique.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="997"/> <location filename="../nw/core/project.py" line="987"/>
<source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source> <source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source>
<translation>Vous devez spécifier un titre de travail valide dans les préférences du projet avant d&apos;utiliser la fonction de sauvegarde automatique.</translation> <translation>Vous devez spécifier un titre de travail valide dans les préférences du projet avant d&apos;utiliser la fonction de sauvegarde automatique.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1141"/> <location filename="../nw/core/project.py" line="1131"/>
<source>and</source> <source>and</source>
<translation>et</translation> <translation>et</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1387"/> <location filename="../nw/core/project.py" line="1377"/>
<source>Found {0} orphaned file(s) in project folder.</source> <source>Found {0} orphaned file(s) in project folder.</source>
<translation>Trouvé {0} fichier(s) orphelin(s) dans le dossier du projet.</translation> <translation>Trouvé {0} fichier(s) orphelin(s) dans le dossier du projet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1399"/> <location filename="../nw/core/project.py" line="1388"/>
<source>Recovered</source> <source>Recovered</source>
<translation>Récupéré</translation> <translation>Récupéré</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1411"/> <location filename="../nw/core/project.py" line="1402"/>
<source>[{0}] {1}</source> <source>[{0}] {1}</source>
<translation>[{0}] {1}</translation> <translation>[{0}] {1}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1416"/> <location filename="../nw/core/project.py" line="1407"/>
<source>Recovered File {0}</source> <source>Recovered File {0}</source>
<translation>Fichier récupéré {0}</translation> <translation>Fichier récupéré {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1443"/> <location filename="../nw/core/project.py" line="1434"/>
<source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source> <source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source>
<translation>Un ou plusieurs fichiers orphelins n&apos;ont pas pu être repris dans le projet. Vérifiez qu&apos;il y a au moins un dossier racine Roman.</translation> <translation>Un ou plusieurs fichiers orphelins n&apos;ont pas pu être repris dans le projet. Vérifiez qu&apos;il y a au moins un dossier racine Roman.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1504"/> <location filename="../nw/core/project.py" line="1495"/>
<source>Not a folder: {0}</source> <source>Not a folder: {0}</source>
<translation>Pas un dossier : {0}</translation> <translation>Pas un dossier : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1527"/> <location filename="../nw/core/project.py" line="1518"/>
<source>Could not move: {0}</source> <source>Could not move: {0}</source>
<translation>Pas pu déplacer : {0}</translation> <translation>Pas pu déplacer : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1551"/> <location filename="../nw/core/project.py" line="1542"/>
<source>Could not delete: {0}</source> <source>Could not delete: {0}</source>
<translation>Pas pu effacer : {0}</translation> <translation>Pas pu effacer : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1563"/> <location filename="../nw/core/project.py" line="1554"/>
<source>Could not make folder: {0}</source> <source>Could not make folder: {0}</source>
<translation>Pas pu crér le dossier : {0}</translation> <translation>Pas pu crér le dossier : {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1574"/> <location filename="../nw/core/project.py" line="1565"/>
<source>Could not move item {0} to {1}.</source> <source>Could not move item {0} to {1}.</source>
<translation>Pas pu déplacer l&apos;item {0} vers {1}.</translation> <translation>Pas pu déplacer l&apos;item {0} vers {1}.</translation>
</message> </message>
+149 -137
View File
@@ -793,22 +793,22 @@
<context> <context>
<name>GuiDocEditFooter</name> <name>GuiDocEditFooter</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2475"/> <location filename="../nw/gui/doceditor.py" line="2489"/>
<source>Status</source> <source>Status</source>
<translation>Status</translation> <translation>Status</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2616"/> <location filename="../nw/gui/doceditor.py" line="2630"/>
<source>Line: {0} ({1})</source> <source>Line: {0} ({1})</source>
<translation>Linje: {0} ({1})</translation> <translation>Linje: {0} ({1})</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2632"/> <location filename="../nw/gui/doceditor.py" line="2646"/>
<source>Words: {0} ({1})</source> <source>Words: {0} ({1})</source>
<translation>Ord: {0} ({1})</translation> <translation>Ord: {0} ({1})</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2637"/> <location filename="../nw/gui/doceditor.py" line="2651"/>
<source>Document size is {0} bytes</source> <source>Document size is {0} bytes</source>
<translation>Dokumentet er {0} byte</translation> <translation>Dokumentet er {0} byte</translation>
</message> </message>
@@ -816,22 +816,22 @@
<context> <context>
<name>GuiDocEditHeader</name> <name>GuiDocEditHeader</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2267"/> <location filename="../nw/gui/doceditor.py" line="2281"/>
<source>Edit document meta</source> <source>Edit document meta</source>
<translation>Rediger dokumentinstillinger</translation> <translation>Rediger dokumentinstillinger</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2278"/> <location filename="../nw/gui/doceditor.py" line="2292"/>
<source>Search document</source> <source>Search document</source>
<translation>Søk i dokumentet</translation> <translation>Søk i dokumentet</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2289"/> <location filename="../nw/gui/doceditor.py" line="2303"/>
<source>Toggle Focus Mode</source> <source>Toggle Focus Mode</source>
<translation>Slå av/ &quot;Fokus-modus&quot;</translation> <translation>Slå av/ &quot;Fokus-modus&quot;</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2300"/> <location filename="../nw/gui/doceditor.py" line="2314"/>
<source>Close the document</source> <source>Close the document</source>
<translation>Lukk dokumentet</translation> <translation>Lukk dokumentet</translation>
</message> </message>
@@ -839,97 +839,97 @@
<context> <context>
<name>GuiDocEditSearch</name> <name>GuiDocEditSearch</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1895"/> <location filename="../nw/gui/doceditor.py" line="1909"/>
<source>Search</source> <source>Search</source>
<translation>Søk</translation> <translation>Søk</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1886"/> <location filename="../nw/gui/doceditor.py" line="1900"/>
<source>Replace</source> <source>Replace</source>
<translation>Erstatt</translation> <translation>Erstatt</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1899"/> <location filename="../nw/gui/doceditor.py" line="1913"/>
<source>Case Sensitive</source> <source>Case Sensitive</source>
<translation>Skill store/små bokstaver</translation> <translation>Skill store/små bokstaver</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1900"/> <location filename="../nw/gui/doceditor.py" line="1914"/>
<source>Match case</source> <source>Match case</source>
<translation>Søket skiller mellom store og små bokstaver</translation> <translation>Søket skiller mellom store og små bokstaver</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1907"/> <location filename="../nw/gui/doceditor.py" line="1921"/>
<source>Whole Words Only</source> <source>Whole Words Only</source>
<translation>Kun hele ord</translation> <translation>Kun hele ord</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1908"/> <location filename="../nw/gui/doceditor.py" line="1922"/>
<source>Match whole words</source> <source>Match whole words</source>
<translation>Søk kun etter hele ord</translation> <translation>Søk kun etter hele ord</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1915"/> <location filename="../nw/gui/doceditor.py" line="1929"/>
<source>RegEx Mode</source> <source>RegEx Mode</source>
<translation>RegEx-modus</translation> <translation>RegEx-modus</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1916"/> <location filename="../nw/gui/doceditor.py" line="1930"/>
<source>Search using regular expressions</source> <source>Search using regular expressions</source>
<translation>Søk ved hjelp av &quot;regular expressions&quot;</translation> <translation>Søk ved hjelp av &quot;regular expressions&quot;</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1923"/> <location filename="../nw/gui/doceditor.py" line="1937"/>
<source>Loop Search</source> <source>Loop Search</source>
<translation>Søk rundt</translation> <translation>Søk rundt</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1924"/> <location filename="../nw/gui/doceditor.py" line="1938"/>
<source>Loop the search when reaching the end</source> <source>Loop the search when reaching the end</source>
<translation>Begynn søket nytt når enden er nådd</translation> <translation>Begynn søket nytt når enden er nådd</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1931"/> <location filename="../nw/gui/doceditor.py" line="1945"/>
<source>Search Next File</source> <source>Search Next File</source>
<translation>Søk i neste file</translation> <translation>Søk i neste file</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1932"/> <location filename="../nw/gui/doceditor.py" line="1946"/>
<source>Continue searching in the next file</source> <source>Continue searching in the next file</source>
<translation>Fortsett søket i neste fil</translation> <translation>Fortsett søket i neste fil</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1941"/> <location filename="../nw/gui/doceditor.py" line="1955"/>
<source>Preserve Case</source> <source>Preserve Case</source>
<translation>Behold store/små bokstaver</translation> <translation>Behold store/små bokstaver</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1942"/> <location filename="../nw/gui/doceditor.py" line="1956"/>
<source>Preserve case on replace</source> <source>Preserve case on replace</source>
<translation>Behold store og små bokstaver samme sted ved erstatt</translation> <translation>Behold store og små bokstaver samme sted ved erstatt</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1951"/> <location filename="../nw/gui/doceditor.py" line="1965"/>
<source>Close Search</source> <source>Close Search</source>
<translation>Lukk søk</translation> <translation>Lukk søk</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1952"/> <location filename="../nw/gui/doceditor.py" line="1966"/>
<source>Close the search box [{0}]</source> <source>Close the search box [{0}]</source>
<translation>Lukk søkeboksen [{0}]</translation> <translation>Lukk søkeboksen [{0}]</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1964"/> <location filename="../nw/gui/doceditor.py" line="1978"/>
<source>Show/hide the replace text box</source> <source>Show/hide the replace text box</source>
<translation>Vis/skjul erstatt-boksen</translation> <translation>Vis/skjul erstatt-boksen</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1970"/> <location filename="../nw/gui/doceditor.py" line="1984"/>
<source>Find in current document</source> <source>Find in current document</source>
<translation>Søk i det åpne dokumentet</translation> <translation>Søk i det åpne dokumentet</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1975"/> <location filename="../nw/gui/doceditor.py" line="1989"/>
<source>Find and replace in current document</source> <source>Find and replace in current document</source>
<translation>Søk og erstatt i det åpne dokumentet</translation> <translation>Søk og erstatt i det åpne dokumentet</translation>
</message> </message>
@@ -937,100 +937,105 @@
<context> <context>
<name>GuiDocEditor</name> <name>GuiDocEditor</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="308"/> <location filename="../nw/gui/doceditor.py" line="313"/>
<source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation>Dokumentet du prøver å åpne er for stort. Dokumenter er {0} MB. Den maksimale størrelsen tillat er {1} MB.</translation> <translation>Dokumentet du prøver å åpne er for stort. Dokumenter er {0} MB. Den maksimale størrelsen tillat er {1} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="407"/> <location filename="../nw/gui/doceditor.py" line="411"/>
<source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation>Teksten du forsøker å legge til er for stor. Teksten er {0} MB. Den maksimale tillatte størrelsen er {1} MB.</translation> <translation>Teksten du forsøker å legge til er for stor. Teksten er {0} MB. Den maksimale tillatte størrelsen er {1} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="680"/> <location filename="../nw/gui/doceditor.py" line="694"/>
<source>Spell check complete</source> <source>Spell check complete</source>
<translation>Stavekontrollen er ferdig</translation> <translation>Stavekontrollen er ferdig</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>File Location</source> <source>File Location</source>
<translation>Filens plassering</translation> <translation>Filens plassering</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>The currently open file is saved in:</source> <source>The currently open file is saved in:</source>
<translation>Det åpne dokumentet er lagret følgende sted:</translation> <translation>Det åpne dokumentet er lagret følgende sted:</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="964"/> <location filename="../nw/gui/doceditor.py" line="978"/>
<source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source> <source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source>
<translation>Dokumentet har blitt for stort og du kan ikke legge til mer tekst. Den maksimale tillatte størrelsen for et novelWriter-dokument er {0} MB.</translation> <translation>Dokumentet har blitt for stort og du kan ikke legge til mer tekst. Den maksimale tillatte størrelsen for et novelWriter-dokument er {0} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1002"/> <location filename="../nw/gui/doceditor.py" line="1016"/>
<source>Follow Tag</source> <source>Follow Tag</source>
<translation>Følg knagg</translation> <translation>Følg knagg</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1008"/> <location filename="../nw/gui/doceditor.py" line="1022"/>
<source>Cut</source> <source>Cut</source>
<translation>Klipp</translation> <translation>Klipp</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1012"/> <location filename="../nw/gui/doceditor.py" line="1026"/>
<source>Copy</source> <source>Copy</source>
<translation>Kopier</translation> <translation>Kopier</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1016"/> <location filename="../nw/gui/doceditor.py" line="1030"/>
<source>Paste</source> <source>Paste</source>
<translation>Lim inn</translation> <translation>Lim inn</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1025"/> <location filename="../nw/gui/doceditor.py" line="1039"/>
<source>Select All</source> <source>Select All</source>
<translation>Velg hele teksten</translation> <translation>Velg hele teksten</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1029"/> <location filename="../nw/gui/doceditor.py" line="1043"/>
<source>Select Word</source> <source>Select Word</source>
<translation>Velg hele ordet</translation> <translation>Velg hele ordet</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1035"/> <location filename="../nw/gui/doceditor.py" line="1049"/>
<source>Select Paragraph</source> <source>Select Paragraph</source>
<translation>Velg hele avsnittet</translation> <translation>Velg hele avsnittet</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1061"/> <location filename="../nw/gui/doceditor.py" line="1075"/>
<source>Spelling Suggestion(s)</source> <source>Spelling Suggestion(s)</source>
<translation>Forslag fra stavekontrollen</translation> <translation>Forslag fra stavekontrollen</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1073"/> <location filename="../nw/gui/doceditor.py" line="1087"/>
<source>No Suggestions</source> <source>No Suggestions</source>
<translation>Ingen forslag</translation> <translation>Ingen forslag</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1079"/> <location filename="../nw/gui/doceditor.py" line="1093"/>
<source>Add Word to Dictionary</source> <source>Add Word to Dictionary</source>
<translation>Legg til ord i ordbok</translation> <translation>Legg til ord i ordbok</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1507"/> <location filename="../nw/gui/doceditor.py" line="1521"/>
<source>Please select some text before calling replace quotes.</source> <source>Please select some text before calling replace quotes.</source>
<translation>Venligst velg en del av teksten før du velger å erstatte sitattegn.</translation> <translation>Venligst velg en del av teksten før du velger å erstatte sitattegn.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="382"/> <location filename="../nw/gui/doceditor.py" line="386"/>
<source>Opened Document: {0}</source> <source>Opened Document: {0}</source>
<translation>Åpnet dokument: {0}</translation> <translation>Åpnet dokument: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="467"/> <location filename="../nw/gui/doceditor.py" line="482"/>
<source>Saved Document: {0}</source> <source>Saved Document: {0}</source>
<translation>Lagret dokument: {0}</translation> <translation>Lagret dokument: {0}</translation>
</message> </message>
<message>
<location filename="../nw/gui/doceditor.py" line="458"/>
<source>Could not save document.</source>
<translation>Kunne ikke lagre dokumentet.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocMerge</name> <name>GuiDocMerge</name>
@@ -1055,25 +1060,35 @@
<translation>Ingen kilde-dokument funnet. Det er ingenting å gjøre.</translation> <translation>Ingen kilde-dokument funnet. Det er ingenting å gjøre.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="118"/> <location filename="../nw/dialogs/docmerge.py" line="123"/>
<source>No source document selected. Nothing to do.</source> <source>No source document selected. Nothing to do.</source>
<translation>Ingen kilde-dokument er valgt. Det er ingenting å gjøre.</translation> <translation>Ingen kilde-dokument er valgt. Det er ingenting å gjøre.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="125"/> <location filename="../nw/dialogs/docmerge.py" line="130"/>
<source>Could not parse source document.</source> <source>Could not parse source document.</source>
<translation>Klarte ikke å lese kilde-dokumentet.</translation> <translation>Klarte ikke å lese kilde-dokumentet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="168"/> <location filename="../nw/dialogs/docmerge.py" line="177"/>
<source>Element selected in the project tree must be a folder.</source> <source>Element selected in the project tree must be a folder.</source>
<translation>Elementet som er valgt i prosjekttreet være en mappe.</translation> <translation>Elementet som er valgt i prosjekttreet være en mappe.</translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="116"/>
<source>Failed to open document file.</source>
<translation>Kunne ikke åpne dokumentets fil.</translation>
</message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="141"/>
<source>Could not save document.</source>
<translation>Kunne ikke lagre dokumentet.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocSplit</name> <name>GuiDocSplit</name>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Split Document</source> <source>Split Document</source>
<translation>Del opp dokument</translation> <translation>Del opp dokument</translation>
</message> </message>
@@ -1118,30 +1133,40 @@
<translation>Klarte ikke å lese kilde-dokumentet.</translation> <translation>Klarte ikke å lese kilde-dokumentet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="153"/> <location filename="../nw/dialogs/docsplit.py" line="160"/>
<source>No headers found. Nothing to do.</source> <source>No headers found. Nothing to do.</source>
<translation>Ingen overskrifter ble funnet i dokumentet. Det er ikke noe å gjøre.</translation> <translation>Ingen overskrifter ble funnet i dokumentet. Det er ikke noe å gjøre.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="161"/> <location filename="../nw/dialogs/docsplit.py" line="168"/>
<source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source> <source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source>
<translation>Kan ikke legge til ny mappe for å dele opp dokumentet. Dokumentet har allerede maksimal dybde i prosjekttreet. Flytt dokumentet til et annet nivå først.</translation> <translation>Kan ikke legge til ny mappe for å dele opp dokumentet. Dokumentet har allerede maksimal dybde i prosjekttreet. Flytt dokumentet til et annet nivå først.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source> <source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source>
<translation>Dokumentet vil bli delt opp i {0} nye filer i en ny mappe. Det originale dokumentet vil ikke bli endret eller fjernet.</translation> <translation>Dokumentet vil bli delt opp i {0} nye filer i en ny mappe. Det originale dokumentet vil ikke bli endret eller fjernet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Continue with the splitting process?</source> <source>Continue with the splitting process?</source>
<translation>Fortsette med oppdelingen?</translation> <translation>Fortsette med oppdelingen?</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="256"/> <location filename="../nw/dialogs/docsplit.py" line="267"/>
<source>Element selected in the project tree must be a file.</source> <source>Element selected in the project tree must be a file.</source>
<translation>Elementet som er valgt i prosjekttreet være et dokument.</translation> <translation>Elementet som er valgt i prosjekttreet være et dokument.</translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="135"/>
<source>Failed to open document file.</source>
<translation>Kunne ikke åpne dokumentets fil.</translation>
</message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="230"/>
<source>Could not save document.</source>
<translation>Kunne ikke lagre dokumentet.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocViewFooter</name> <name>GuiDocViewFooter</name>
@@ -3960,7 +3985,7 @@
<translation>Vil du slette {0} filer i søppel-mappen for godt?</translation> <translation>Vil du slette {0} filer i søppel-mappen for godt?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Delete File</source> <source>Delete File</source>
<translation>Slett fil</translation> <translation>Slett fil</translation>
</message> </message>
@@ -3970,22 +3995,22 @@
<translation>Slette filen &apos;{0}&apos; for godt?</translation> <translation>Slette filen &apos;{0}&apos; for godt?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Move file &apos;{0}&apos; to Trash?</source> <source>Move file &apos;{0}&apos; to Trash?</source>
<translation>Vil du flytte filen &apos;{0}&apos; til søpla?</translation> <translation>Vil du flytte filen &apos;{0}&apos; til søpla?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="572"/> <location filename="../nw/gui/projtree.py" line="577"/>
<source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation>Kan ikke slette mappen da den ikke er tom. Rekursiv sletting er ikke støttet. Du slette innholdet først.</translation> <translation>Kan ikke slette mappen da den ikke er tom. Rekursiv sletting er ikke støttet. Du slette innholdet først.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="588"/> <location filename="../nw/gui/projtree.py" line="593"/>
<source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation>Kan ikke slette hovedmappen da den ikke er tom. Rekursiv sletting er ikke støttet. Du slette innholdet først.</translation> <translation>Kan ikke slette hovedmappen da den ikke er tom. Rekursiv sletting er ikke støttet. Du slette innholdet først.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="875"/> <location filename="../nw/gui/projtree.py" line="880"/>
<source>The item cannot be moved to that location.</source> <source>The item cannot be moved to that location.</source>
<translation>Denne enheten kan ikke flyttes til denne lokasjonen.</translation> <translation>Denne enheten kan ikke flyttes til denne lokasjonen.</translation>
</message> </message>
@@ -3995,60 +4020,65 @@
<translation>Kan ikke legge til nye filer eller mapper til søppel-mappen.</translation> <translation>Kan ikke legge til nye filer eller mapper til søppel-mappen.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="972"/> <location filename="../nw/gui/projtree.py" line="977"/>
<source>There is nowhere to add item with name &apos;{0}&apos;.</source> <source>There is nowhere to add item with name &apos;{0}&apos;.</source>
<translation>Fant ikke noe sted å legge til enheten med navn &apos;{0}&apos;.</translation> <translation>Fant ikke noe sted å legge til enheten med navn &apos;{0}&apos;.</translation>
</message> </message>
<message>
<location filename="../nw/gui/projtree.py" line="532"/>
<source>Could not delete document file.</source>
<translation>Kunne ikke slette dokumentets fil.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiProjectTreeMenu</name> <name>GuiProjectTreeMenu</name>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1094"/> <location filename="../nw/gui/projtree.py" line="1099"/>
<source>Edit Project Item</source> <source>Edit Project Item</source>
<translation>Endre enhet</translation> <translation>Endre enhet</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1098"/> <location filename="../nw/gui/projtree.py" line="1103"/>
<source>Open Document</source> <source>Open Document</source>
<translation>Åpne dokument</translation> <translation>Åpne dokument</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1102"/> <location filename="../nw/gui/projtree.py" line="1107"/>
<source>View Document</source> <source>View Document</source>
<translation>Vis dokument</translation> <translation>Vis dokument</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1106"/> <location filename="../nw/gui/projtree.py" line="1111"/>
<source>Toggle Included Flag</source> <source>Toggle Included Flag</source>
<translation>Slå av/ inkludering</translation> <translation>Slå av/ inkludering</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1110"/> <location filename="../nw/gui/projtree.py" line="1115"/>
<source>New File</source> <source>New File</source>
<translation>Ny fil</translation> <translation>Ny fil</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1114"/> <location filename="../nw/gui/projtree.py" line="1119"/>
<source>New Folder</source> <source>New Folder</source>
<translation>Ny mappe</translation> <translation>Ny mappe</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1118"/> <location filename="../nw/gui/projtree.py" line="1123"/>
<source>Delete Item</source> <source>Delete Item</source>
<translation>Slett enhet</translation> <translation>Slett enhet</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1122"/> <location filename="../nw/gui/projtree.py" line="1127"/>
<source>Empty Trash</source> <source>Empty Trash</source>
<translation>Tøm søppel</translation> <translation>Tøm søppel</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1126"/> <location filename="../nw/gui/projtree.py" line="1131"/>
<source>Move Item Up</source> <source>Move Item Up</source>
<translation>Flytt enhet opp</translation> <translation>Flytt enhet opp</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1130"/> <location filename="../nw/gui/projtree.py" line="1135"/>
<source>Move Item Down</source> <source>Move Item Down</source>
<translation>Flytt enhet ned</translation> <translation>Flytt enhet ned</translation>
</message> </message>
@@ -4237,24 +4267,6 @@
<translation>Lagre data som</translation> <translation>Lagre data som</translation>
</message> </message>
</context> </context>
<context>
<name>NWDoc</name>
<message>
<location filename="../nw/core/document.py" line="118"/>
<source>Failed to open document file.</source>
<translation>Kunne ikke åpne dokumentets fil.</translation>
</message>
<message>
<location filename="../nw/core/document.py" line="162"/>
<source>Could not save document.</source>
<translation>Kunne ikke lagre dokumentet.</translation>
</message>
<message>
<location filename="../nw/core/document.py" line="192"/>
<source>Could not delete document file.</source>
<translation>Kunne ikke slette dokumentets fil.</translation>
</message>
</context>
<context> <context>
<name>NWProject</name> <name>NWProject</name>
<message> <message>
@@ -4308,237 +4320,237 @@
<translation>Av</translation> <translation>Av</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="305"/> <location filename="../nw/core/project.py" line="299"/>
<source>Novel</source> <source>Novel</source>
<translation>Roman</translation> <translation>Roman</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="276"/> <location filename="../nw/core/project.py" line="273"/>
<source>Plot</source> <source>Plot</source>
<translation>Plott</translation> <translation>Plott</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="277"/> <location filename="../nw/core/project.py" line="274"/>
<source>Characters</source> <source>Characters</source>
<translation>Karakterer</translation> <translation>Karakterer</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="278"/> <location filename="../nw/core/project.py" line="275"/>
<source>World</source> <source>World</source>
<translation>Verden</translation> <translation>Verden</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="311"/> <location filename="../nw/core/project.py" line="305"/>
<source>Title Page</source> <source>Title Page</source>
<translation>Tittelside</translation> <translation>Tittelside</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="292"/> <location filename="../nw/core/project.py" line="288"/>
<source>New Chapter</source> <source>New Chapter</source>
<translation>Nytt kapittel</translation> <translation>Nytt kapittel</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="296"/> <location filename="../nw/core/project.py" line="291"/>
<source>New Scene</source> <source>New Scene</source>
<translation>Ny scene</translation> <translation>Ny scene</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="326"/> <location filename="../nw/core/project.py" line="319"/>
<source>Chapter {0}</source> <source>Chapter {0}</source>
<translation>Kapittel {0}</translation> <translation>Kapittel {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="351"/> <location filename="../nw/core/project.py" line="342"/>
<source>Scene {0}</source> <source>Scene {0}</source>
<translation>Scene {0}</translation> <translation>Scene {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="375"/> <location filename="../nw/core/project.py" line="365"/>
<source>File not found: {0}</source> <source>File not found: {0}</source>
<translation>Fant ikke filen: {0}</translation> <translation>Fant ikke filen: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="435"/> <location filename="../nw/core/project.py" line="425"/>
<source>Failed to parse project xml.</source> <source>Failed to parse project xml.</source>
<translation>Kunne ikke lese prosjektets xml-data.</translation> <translation>Kunne ikke lese prosjektets xml-data.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="429"/> <location filename="../nw/core/project.py" line="419"/>
<source>Attempting to open backup project file instead.</source> <source>Attempting to open backup project file instead.</source>
<translation>Forsøker å åpne prosjektets sekundære prosjektfil istedet.</translation> <translation>Forsøker å åpne prosjektets sekundære prosjektfil istedet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="449"/> <location filename="../nw/core/project.py" line="439"/>
<source>Unknown</source> <source>Unknown</source>
<translation>Ukjent</translation> <translation>Ukjent</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="458"/> <location filename="../nw/core/project.py" line="448"/>
<source>Project file does not appear to be a novelWriterXML file.</source> <source>Project file does not appear to be a novelWriterXML file.</source>
<translation>Prosjektfilen later ikke til å være en novelWriterXML-fil.</translation> <translation>Prosjektfilen later ikke til å være en novelWriterXML-fil.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="478"/> <location filename="../nw/core/project.py" line="468"/>
<source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source> <source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source>
<translation>Prosjektfilen har et ukjent eller ikke støttet format, og kan ikke åpnes med denne versjonen av novelWriter. Prosjektet ble lagret av novelWriter versjon {0}.</translation> <translation>Prosjektfilen har et ukjent eller ikke støttet format, og kan ikke åpnes med denne versjonen av novelWriter. Prosjektet ble lagret av novelWriter versjon {0}.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>Version Conflict</source> <source>Version Conflict</source>
<translation>Versjonskonflikt</translation> <translation>Versjonskonflikt</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="592"/> <location filename="../nw/core/project.py" line="582"/>
<source>Opened Project: {0}</source> <source>Opened Project: {0}</source>
<translation>Åpnet prosjekt: {0}</translation> <translation>Åpnet prosjekt: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="613"/> <location filename="../nw/core/project.py" line="603"/>
<source>Project path not set, cannot save project.</source> <source>Project path not set, cannot save project.</source>
<translation>Prosjektet mangler filbane, og kan ikke lagres.</translation> <translation>Prosjektet mangler filbane, og kan ikke lagres.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="694"/> <location filename="../nw/core/project.py" line="684"/>
<source>Failed to save project.</source> <source>Failed to save project.</source>
<translation>Kunne ikke lagre prosjektet.</translation> <translation>Kunne ikke lagre prosjektet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="713"/> <location filename="../nw/core/project.py" line="703"/>
<source>Saved Project: {0}</source> <source>Saved Project: {0}</source>
<translation>Lagret prosjekt: {0}</translation> <translation>Lagret prosjekt: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="765"/> <location filename="../nw/core/project.py" line="755"/>
<source>Backing up project ...</source> <source>Backing up project ...</source>
<translation>Lager sikkerhetskopi ...</translation> <translation>Lager sikkerhetskopi ...</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="768"/> <location filename="../nw/core/project.py" line="758"/>
<source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation>Kan ikke ta sikkerhetskopi av prosjektet da ingen filbane er satt. Du først sette en filbane i Verktøy &gt; Innstillinger.</translation> <translation>Kan ikke ta sikkerhetskopi av prosjektet da ingen filbane er satt. Du først sette en filbane i Verktøy &gt; Innstillinger.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="777"/> <location filename="../nw/core/project.py" line="767"/>
<source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source> <source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source>
<translation>Kan ikke ta sikkerhetskopi av prosjektet da ingen arbeidstittel er satt. Du først sette en arbeidstittel i Prosjekt &gt; Prosjektinnstillinger.</translation> <translation>Kan ikke ta sikkerhetskopi av prosjektet da ingen arbeidstittel er satt. Du først sette en arbeidstittel i Prosjekt &gt; Prosjektinnstillinger.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="786"/> <location filename="../nw/core/project.py" line="776"/>
<source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation>Kan ikke ta sikkerhetskopi av prosjektet da filbane ikke finnes. Du sette en ny filbane i Verktøy &gt; Innstillinger.</translation> <translation>Kan ikke ta sikkerhetskopi av prosjektet da filbane ikke finnes. Du sette en ny filbane i Verktøy &gt; Innstillinger.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="801"/> <location filename="../nw/core/project.py" line="791"/>
<source>Could not create backup folder.</source> <source>Could not create backup folder.</source>
<translation>Kunne ikke lage mappe til sikkerhetskopi.</translation> <translation>Kunne ikke lage mappe til sikkerhetskopi.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="808"/> <location filename="../nw/core/project.py" line="798"/>
<source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source>
<translation>Kan ikke ta sikkerhetskopi av prosjektet da filbanen er inne i prosjektmappen. Du sette en ny filbane i Verktøy &gt; Innstillinger.</translation> <translation>Kan ikke ta sikkerhetskopi av prosjektet da filbanen er inne i prosjektmappen. Du sette en ny filbane i Verktøy &gt; Innstillinger.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="817"/> <location filename="../nw/core/project.py" line="807"/>
<source>Backup from {0}</source> <source>Backup from {0}</source>
<translation>Sikkerhetskopi fra {0}</translation> <translation>Sikkerhetskopi fra {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="826"/> <location filename="../nw/core/project.py" line="816"/>
<source>Backup archive file written to: {0}</source> <source>Backup archive file written to: {0}</source>
<translation>Sikkerhetskopi skrevet til: {0}</translation> <translation>Sikkerhetskopi skrevet til: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="835"/> <location filename="../nw/core/project.py" line="825"/>
<source>Could not write backup archive.</source> <source>Could not write backup archive.</source>
<translation>Kunne ikke lage sikkerhetskopi.</translation> <translation>Kunne ikke lage sikkerhetskopi.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="841"/> <location filename="../nw/core/project.py" line="831"/>
<source>Project backed up to &apos;{0}&apos;</source> <source>Project backed up to &apos;{0}&apos;</source>
<translation>Sikkerhetskopi skrevet til &apos;{0}&apos;</translation> <translation>Sikkerhetskopi skrevet til &apos;{0}&apos;</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="889"/> <location filename="../nw/core/project.py" line="879"/>
<source>Failed to create a new example project.</source> <source>Failed to create a new example project.</source>
<translation>Kunne ikke lage nytt eksempel-prosjekt.</translation> <translation>Kunne ikke lage nytt eksempel-prosjekt.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="894"/> <location filename="../nw/core/project.py" line="884"/>
<source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source> <source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source>
<translation>Kunne ikke lage nytt eksempel-prosjekt. Kunne ikke finne de nødvendige filene. De ser ut til å mangle i denne installasjonen.</translation> <translation>Kunne ikke lage nytt eksempel-prosjekt. Kunne ikke finne de nødvendige filene. De ser ut til å mangle i denne installasjonen.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="929"/> <location filename="../nw/core/project.py" line="919"/>
<source>Could not create new project folder.</source> <source>Could not create new project folder.</source>
<translation>Kunne ikke lage ny prosjekt-mappe.</translation> <translation>Kunne ikke lage ny prosjekt-mappe.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="936"/> <location filename="../nw/core/project.py" line="926"/>
<source>New project folder is not empty. Each project requires a dedicated project folder.</source> <source>New project folder is not empty. Each project requires a dedicated project folder.</source>
<translation>Ny prosjektmappe er ikke tom. Hvert prosjekt trenger sin egen mappe.</translation> <translation>Ny prosjektmappe er ikke tom. Hvert prosjekt trenger sin egen mappe.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="988"/> <location filename="../nw/core/project.py" line="978"/>
<source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source> <source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source>
<translation>Du sette en gyldig filbane i innstillingene for å kunne bruke automatisk sikkerhetskopi.</translation> <translation>Du sette en gyldig filbane i innstillingene for å kunne bruke automatisk sikkerhetskopi.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="997"/> <location filename="../nw/core/project.py" line="987"/>
<source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source> <source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source>
<translation>Du sette en gyldig arbeidstittel i prosjektinnstillingene for å kunne bruke automatisk sikkerhetskopi.</translation> <translation>Du sette en gyldig arbeidstittel i prosjektinnstillingene for å kunne bruke automatisk sikkerhetskopi.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1141"/> <location filename="../nw/core/project.py" line="1131"/>
<source>and</source> <source>and</source>
<translation>og</translation> <translation>og</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1387"/> <location filename="../nw/core/project.py" line="1377"/>
<source>Found {0} orphaned file(s) in project folder.</source> <source>Found {0} orphaned file(s) in project folder.</source>
<translation>Fant {0} tapte filer i prosjektmappen.</translation> <translation>Fant {0} tapte filer i prosjektmappen.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1399"/> <location filename="../nw/core/project.py" line="1388"/>
<source>Recovered</source> <source>Recovered</source>
<translation>Gjennopprettet</translation> <translation>Gjennopprettet</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1411"/> <location filename="../nw/core/project.py" line="1402"/>
<source>[{0}] {1}</source> <source>[{0}] {1}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1416"/> <location filename="../nw/core/project.py" line="1407"/>
<source>Recovered File {0}</source> <source>Recovered File {0}</source>
<translation>Gjennopprettet fil {0}</translation> <translation>Gjennopprettet fil {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1443"/> <location filename="../nw/core/project.py" line="1434"/>
<source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source> <source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source>
<translation>Én eller flere gjennopprettede filer kunne ikke bli lagt til i posjektet. Pass at &quot;Roman&quot;-mappen i det minste eksisterer.</translation> <translation>Én eller flere gjennopprettede filer kunne ikke bli lagt til i posjektet. Pass at &quot;Roman&quot;-mappen i det minste eksisterer.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1504"/> <location filename="../nw/core/project.py" line="1495"/>
<source>Not a folder: {0}</source> <source>Not a folder: {0}</source>
<translation>Ikke en mappe: {0}</translation> <translation>Ikke en mappe: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1527"/> <location filename="../nw/core/project.py" line="1518"/>
<source>Could not move: {0}</source> <source>Could not move: {0}</source>
<translation>Kunne ikke flytte: {0}</translation> <translation>Kunne ikke flytte: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1551"/> <location filename="../nw/core/project.py" line="1542"/>
<source>Could not delete: {0}</source> <source>Could not delete: {0}</source>
<translation>Kunne ikke slette: {0}</translation> <translation>Kunne ikke slette: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1563"/> <location filename="../nw/core/project.py" line="1554"/>
<source>Could not make folder: {0}</source> <source>Could not make folder: {0}</source>
<translation>Kunne ikke lage mappe: {0}</translation> <translation>Kunne ikke lage mappe: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1574"/> <location filename="../nw/core/project.py" line="1565"/>
<source>Could not move item {0} to {1}.</source> <source>Could not move item {0} to {1}.</source>
<translation>Kunne ikke flytte {0} til {1}.</translation> <translation>Kunne ikke flytte {0} til {1}.</translation>
</message> </message>
@@ -4548,7 +4560,7 @@
<translation>Kapittel</translation> <translation>Kapittel</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source> <source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source>
<translation>Dette prosjektet ble lagret av en nyere versjon av novelWriter, versjon {0}. Dette er versjon {1}. Hvis du ønsker å fortsette med å åpne prosjektet, kan noen av innstillingene bli borte, men selve prosjektet vil være i orden. Vil du fortsatt åpne prosjektet?</translation> <translation>Dette prosjektet ble lagret av en nyere versjon av novelWriter, versjon {0}. Dette er versjon {1}. Hvis du ønsker å fortsette med å åpne prosjektet, kan noen av innstillingene bli borte, men selve prosjektet vil være i orden. Vil du fortsatt åpne prosjektet?</translation>
</message> </message>
+149 -137
View File
@@ -793,22 +793,22 @@
<context> <context>
<name>GuiDocEditFooter</name> <name>GuiDocEditFooter</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2616"/> <location filename="../nw/gui/doceditor.py" line="2630"/>
<source>Line: {0} ({1})</source> <source>Line: {0} ({1})</source>
<translation>Linha: {0} ({1})</translation> <translation>Linha: {0} ({1})</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2632"/> <location filename="../nw/gui/doceditor.py" line="2646"/>
<source>Words: {0} ({1})</source> <source>Words: {0} ({1})</source>
<translation>Palavras: {0} ({1})</translation> <translation>Palavras: {0} ({1})</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2475"/> <location filename="../nw/gui/doceditor.py" line="2489"/>
<source>Status</source> <source>Status</source>
<translation>Estado</translation> <translation>Estado</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2637"/> <location filename="../nw/gui/doceditor.py" line="2651"/>
<source>Document size is {0} bytes</source> <source>Document size is {0} bytes</source>
<translation>O tamanho do documento é {0} bytes</translation> <translation>O tamanho do documento é {0} bytes</translation>
</message> </message>
@@ -816,22 +816,22 @@
<context> <context>
<name>GuiDocEditHeader</name> <name>GuiDocEditHeader</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2267"/> <location filename="../nw/gui/doceditor.py" line="2281"/>
<source>Edit document meta</source> <source>Edit document meta</source>
<translation>Editar os meta-dados do documento</translation> <translation>Editar os meta-dados do documento</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2278"/> <location filename="../nw/gui/doceditor.py" line="2292"/>
<source>Search document</source> <source>Search document</source>
<translation>Procurar no documento</translation> <translation>Procurar no documento</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2289"/> <location filename="../nw/gui/doceditor.py" line="2303"/>
<source>Toggle Focus Mode</source> <source>Toggle Focus Mode</source>
<translation>Alternar o &quot;Modo Foco&quot;</translation> <translation>Alternar o &quot;Modo Foco&quot;</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="2300"/> <location filename="../nw/gui/doceditor.py" line="2314"/>
<source>Close the document</source> <source>Close the document</source>
<translation>Fechar o documento</translation> <translation>Fechar o documento</translation>
</message> </message>
@@ -839,97 +839,97 @@
<context> <context>
<name>GuiDocEditSearch</name> <name>GuiDocEditSearch</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1895"/> <location filename="../nw/gui/doceditor.py" line="1909"/>
<source>Search</source> <source>Search</source>
<translation>Pesquisa</translation> <translation>Pesquisa</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1886"/> <location filename="../nw/gui/doceditor.py" line="1900"/>
<source>Replace</source> <source>Replace</source>
<translation>Substituir</translation> <translation>Substituir</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1899"/> <location filename="../nw/gui/doceditor.py" line="1913"/>
<source>Case Sensitive</source> <source>Case Sensitive</source>
<translation>Diferenciar Maiúsculas e Minúsculas</translation> <translation>Diferenciar Maiúsculas e Minúsculas</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1900"/> <location filename="../nw/gui/doceditor.py" line="1914"/>
<source>Match case</source> <source>Match case</source>
<translation>Diferencia Maiúsculas e Minúsculas</translation> <translation>Diferencia Maiúsculas e Minúsculas</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1907"/> <location filename="../nw/gui/doceditor.py" line="1921"/>
<source>Whole Words Only</source> <source>Whole Words Only</source>
<translation>Apenas Palavras Inteiras</translation> <translation>Apenas Palavras Inteiras</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1908"/> <location filename="../nw/gui/doceditor.py" line="1922"/>
<source>Match whole words</source> <source>Match whole words</source>
<translation>Encontra apenas palavras inteiras</translation> <translation>Encontra apenas palavras inteiras</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1915"/> <location filename="../nw/gui/doceditor.py" line="1929"/>
<source>RegEx Mode</source> <source>RegEx Mode</source>
<translation>Expressão Regular</translation> <translation>Expressão Regular</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1923"/> <location filename="../nw/gui/doceditor.py" line="1937"/>
<source>Loop Search</source> <source>Loop Search</source>
<translation>Pesquisa do Início</translation> <translation>Pesquisa do Início</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1924"/> <location filename="../nw/gui/doceditor.py" line="1938"/>
<source>Loop the search when reaching the end</source> <source>Loop the search when reaching the end</source>
<translation>Pesquisa do início quando chega no final do documento</translation> <translation>Pesquisa do início quando chega no final do documento</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1931"/> <location filename="../nw/gui/doceditor.py" line="1945"/>
<source>Search Next File</source> <source>Search Next File</source>
<translation>Busca no Próximo Arquivo</translation> <translation>Busca no Próximo Arquivo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1932"/> <location filename="../nw/gui/doceditor.py" line="1946"/>
<source>Continue searching in the next file</source> <source>Continue searching in the next file</source>
<translation>Continua a busca no próximo arquivo</translation> <translation>Continua a busca no próximo arquivo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1941"/> <location filename="../nw/gui/doceditor.py" line="1955"/>
<source>Preserve Case</source> <source>Preserve Case</source>
<translation>Preserva Maiúsculas e Minúsculas</translation> <translation>Preserva Maiúsculas e Minúsculas</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1942"/> <location filename="../nw/gui/doceditor.py" line="1956"/>
<source>Preserve case on replace</source> <source>Preserve case on replace</source>
<translation>Preserva maiúsculas e minúsculas ao substituir</translation> <translation>Preserva maiúsculas e minúsculas ao substituir</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1951"/> <location filename="../nw/gui/doceditor.py" line="1965"/>
<source>Close Search</source> <source>Close Search</source>
<translation>Fechar a Busca</translation> <translation>Fechar a Busca</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1964"/> <location filename="../nw/gui/doceditor.py" line="1978"/>
<source>Show/hide the replace text box</source> <source>Show/hide the replace text box</source>
<translation>Mostrar/Ocultar a caixa substituição</translation> <translation>Mostrar/Ocultar a caixa substituição</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1970"/> <location filename="../nw/gui/doceditor.py" line="1984"/>
<source>Find in current document</source> <source>Find in current document</source>
<translation>Encontrar no documento atual</translation> <translation>Encontrar no documento atual</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1975"/> <location filename="../nw/gui/doceditor.py" line="1989"/>
<source>Find and replace in current document</source> <source>Find and replace in current document</source>
<translation>Encontrar e substituir no documento atual</translation> <translation>Encontrar e substituir no documento atual</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1952"/> <location filename="../nw/gui/doceditor.py" line="1966"/>
<source>Close the search box [{0}]</source> <source>Close the search box [{0}]</source>
<translation>Fechar a caixa de busca [{0}]</translation> <translation>Fechar a caixa de busca [{0}]</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1916"/> <location filename="../nw/gui/doceditor.py" line="1930"/>
<source>Search using regular expressions</source> <source>Search using regular expressions</source>
<translation>Busca usando expressões regulares</translation> <translation>Busca usando expressões regulares</translation>
</message> </message>
@@ -937,100 +937,105 @@
<context> <context>
<name>GuiDocEditor</name> <name>GuiDocEditor</name>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="680"/> <location filename="../nw/gui/doceditor.py" line="694"/>
<source>Spell check complete</source> <source>Spell check complete</source>
<translation>Verificação ortográfica completa</translation> <translation>Verificação ortográfica completa</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1073"/> <location filename="../nw/gui/doceditor.py" line="1087"/>
<source>No Suggestions</source> <source>No Suggestions</source>
<translation>Sem Sugestões</translation> <translation>Sem Sugestões</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="308"/> <location filename="../nw/gui/doceditor.py" line="313"/>
<source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The document you are trying to open is too big. The document size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation>O documento que você está tentando abrir é muito grande. O tamanho do documento é {0} MB. O tamanho máximo permitido é {1} MB.</translation> <translation>O documento que você está tentando abrir é muito grande. O tamanho do documento é {0} MB. O tamanho máximo permitido é {1} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="407"/> <location filename="../nw/gui/doceditor.py" line="411"/>
<source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source> <source>The text you are trying to add is too big. The text size is {0} MB. The maximum size allowed is {1} MB.</source>
<translation>O texto que você está tentando adicionar é muito grande. O tamanho do texto é {0} MB. O tamanho máximo permitido é {1} MB.</translation> <translation>O texto que você está tentando adicionar é muito grande. O tamanho do texto é {0} MB. O tamanho máximo permitido é {1} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>File Location</source> <source>File Location</source>
<translation>Localização do Arquivo</translation> <translation>Localização do Arquivo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1002"/> <location filename="../nw/gui/doceditor.py" line="1016"/>
<source>Follow Tag</source> <source>Follow Tag</source>
<translation>Seguir Etiqueta</translation> <translation>Seguir Etiqueta</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1008"/> <location filename="../nw/gui/doceditor.py" line="1022"/>
<source>Cut</source> <source>Cut</source>
<translation>Recortar</translation> <translation>Recortar</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1012"/> <location filename="../nw/gui/doceditor.py" line="1026"/>
<source>Copy</source> <source>Copy</source>
<translation>Copiar</translation> <translation>Copiar</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1016"/> <location filename="../nw/gui/doceditor.py" line="1030"/>
<source>Paste</source> <source>Paste</source>
<translation>Colar</translation> <translation>Colar</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1025"/> <location filename="../nw/gui/doceditor.py" line="1039"/>
<source>Select All</source> <source>Select All</source>
<translation>Selecionar Tudo</translation> <translation>Selecionar Tudo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1029"/> <location filename="../nw/gui/doceditor.py" line="1043"/>
<source>Select Word</source> <source>Select Word</source>
<translation>Selecionar Palavra</translation> <translation>Selecionar Palavra</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1035"/> <location filename="../nw/gui/doceditor.py" line="1049"/>
<source>Select Paragraph</source> <source>Select Paragraph</source>
<translation>Selecionar Parágrafo</translation> <translation>Selecionar Parágrafo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1061"/> <location filename="../nw/gui/doceditor.py" line="1075"/>
<source>Spelling Suggestion(s)</source> <source>Spelling Suggestion(s)</source>
<translation>Sugestão de Ortografia</translation> <translation>Sugestão de Ortografia</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1079"/> <location filename="../nw/gui/doceditor.py" line="1093"/>
<source>Add Word to Dictionary</source> <source>Add Word to Dictionary</source>
<translation>Adicionar Palavra ao Dicionário</translation> <translation>Adicionar Palavra ao Dicionário</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="1507"/> <location filename="../nw/gui/doceditor.py" line="1521"/>
<source>Please select some text before calling replace quotes.</source> <source>Please select some text before calling replace quotes.</source>
<translation>Por favor, selecione algum texto antes de invocar a substituição de aspas.</translation> <translation>Por favor, selecione algum texto antes de invocar a substituição de aspas.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="774"/> <location filename="../nw/gui/doceditor.py" line="788"/>
<source>The currently open file is saved in:</source> <source>The currently open file is saved in:</source>
<translation>O arquivo aberto atualmente está salvo em:</translation> <translation>O arquivo aberto atualmente está salvo em:</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="964"/> <location filename="../nw/gui/doceditor.py" line="978"/>
<source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source> <source>The document has grown too big and you cannot add more text to it. The maximum size of a single novelWriter document is {0} MB.</source>
<translation>O tamanho do documento aumentou muito e você não pode adicionar mais texto nele. O tamanho máximo de um único documento do novelWriter é {0} MB.</translation> <translation>O tamanho do documento aumentou muito e você não pode adicionar mais texto nele. O tamanho máximo de um único documento do novelWriter é {0} MB.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="382"/> <location filename="../nw/gui/doceditor.py" line="386"/>
<source>Opened Document: {0}</source> <source>Opened Document: {0}</source>
<translation>Documento Aberto: {0}</translation> <translation>Documento Aberto: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/doceditor.py" line="467"/> <location filename="../nw/gui/doceditor.py" line="482"/>
<source>Saved Document: {0}</source> <source>Saved Document: {0}</source>
<translation>Documento Salvo: {0}</translation> <translation>Documento Salvo: {0}</translation>
</message> </message>
<message>
<location filename="../nw/gui/doceditor.py" line="458"/>
<source>Could not save document.</source>
<translation>Não foi possível salvar o documento.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocMerge</name> <name>GuiDocMerge</name>
@@ -1055,20 +1060,30 @@
<translation>Nenhum documento-fonte foi encontrado. Nada para fazer.</translation> <translation>Nenhum documento-fonte foi encontrado. Nada para fazer.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="118"/> <location filename="../nw/dialogs/docmerge.py" line="123"/>
<source>No source document selected. Nothing to do.</source> <source>No source document selected. Nothing to do.</source>
<translation>Nenhum documento de origem selecionado. Nada a ser feito.</translation> <translation>Nenhum documento de origem selecionado. Nada a ser feito.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="125"/> <location filename="../nw/dialogs/docmerge.py" line="130"/>
<source>Could not parse source document.</source> <source>Could not parse source document.</source>
<translation>Não foi possível interpretar o documento.</translation> <translation>Não foi possível interpretar o documento.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docmerge.py" line="168"/> <location filename="../nw/dialogs/docmerge.py" line="177"/>
<source>Element selected in the project tree must be a folder.</source> <source>Element selected in the project tree must be a folder.</source>
<translation>O elemento selecionado na árvore do projeto deve ser um diretório.</translation> <translation>O elemento selecionado na árvore do projeto deve ser um diretório.</translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="116"/>
<source>Failed to open document file.</source>
<translation>Houve uma falha ao abrir o arquivo do documento.</translation>
</message>
<message>
<location filename="../nw/dialogs/docmerge.py" line="141"/>
<source>Could not save document.</source>
<translation>Não foi possível salvar o documento.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocSplit</name> <name>GuiDocSplit</name>
@@ -1103,7 +1118,7 @@
<translation>Dividir até os cabeçalhos de nível 4 (Seção)</translation> <translation>Dividir até os cabeçalhos de nível 4 (Seção)</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Split Document</source> <source>Split Document</source>
<translation>Divisão de Documento</translation> <translation>Divisão de Documento</translation>
</message> </message>
@@ -1118,30 +1133,40 @@
<translation>Não foi possível interpretar o documento.</translation> <translation>Não foi possível interpretar o documento.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="153"/> <location filename="../nw/dialogs/docsplit.py" line="160"/>
<source>No headers found. Nothing to do.</source> <source>No headers found. Nothing to do.</source>
<translation>Nenhum cabeçalho foi encontrado. Nada para fazer.</translation> <translation>Nenhum cabeçalho foi encontrado. Nada para fazer.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="161"/> <location filename="../nw/dialogs/docsplit.py" line="168"/>
<source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source> <source>Cannot add new folder for the document split. Maximum folder depth has been reached. Please move the file to another level in the project tree.</source>
<translation>Não é possível adicionar um novo diretório para a divisão do documento. A profundidade máxima dos diretórios foi alcançada. Por favor mova o arquivo para outro nível na árvore do projeto.</translation> <translation>Não é possível adicionar um novo diretório para a divisão do documento. A profundidade máxima dos diretórios foi alcançada. Por favor mova o arquivo para outro nível na árvore do projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>Continue with the splitting process?</source> <source>Continue with the splitting process?</source>
<translation>Continuar com o processo de divisão?</translation> <translation>Continuar com o processo de divisão?</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="256"/> <location filename="../nw/dialogs/docsplit.py" line="267"/>
<source>Element selected in the project tree must be a file.</source> <source>Element selected in the project tree must be a file.</source>
<translation>O elemento selecionado na árvore do projeto deve ser um arquivo.</translation> <translation>O elemento selecionado na árvore do projeto deve ser um arquivo.</translation>
</message> </message>
<message> <message>
<location filename="../nw/dialogs/docsplit.py" line="170"/> <location filename="../nw/dialogs/docsplit.py" line="177"/>
<source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source> <source>The document will be split into {0} file(s) in a new folder. The original document will remain intact.</source>
<translation>O documento será dividio em {0} arquivo(s) em um novo diretório. O documento original será mantido intacto.</translation> <translation>O documento será dividio em {0} arquivo(s) em um novo diretório. O documento original será mantido intacto.</translation>
</message> </message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="135"/>
<source>Failed to open document file.</source>
<translation>Houve uma falha ao abrir o arquivo do documento.</translation>
</message>
<message>
<location filename="../nw/dialogs/docsplit.py" line="230"/>
<source>Could not save document.</source>
<translation>Não foi possível salvar o documento.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiDocViewFooter</name> <name>GuiDocViewFooter</name>
@@ -3905,12 +3930,12 @@
<translation>Esvaziar a Lixeira</translation> <translation>Esvaziar a Lixeira</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Delete File</source> <source>Delete File</source>
<translation>Remover Arquivo</translation> <translation>Remover Arquivo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="875"/> <location filename="../nw/gui/projtree.py" line="880"/>
<source>The item cannot be moved to that location.</source> <source>The item cannot be moved to that location.</source>
<translation>O item não pode ser movido para este local.</translation> <translation>O item não pode ser movido para este local.</translation>
</message> </message>
@@ -3975,17 +4000,17 @@
<translation>Permanentemente remover o arquivo &apos;{0}&apos;?</translation> <translation>Permanentemente remover o arquivo &apos;{0}&apos;?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="539"/> <location filename="../nw/gui/projtree.py" line="544"/>
<source>Move file &apos;{0}&apos; to Trash?</source> <source>Move file &apos;{0}&apos; to Trash?</source>
<translation>Mover o arquivo &apos;{0}&apos; para a Lixeira?</translation> <translation>Mover o arquivo &apos;{0}&apos; para a Lixeira?</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="572"/> <location filename="../nw/gui/projtree.py" line="577"/>
<source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation>Não foi possível remover o diretório. O diretório não está vazio. Exclusão recursiva não é suportada. Por favor remova todo o conteúdo primeiro.</translation> <translation>Não foi possível remover o diretório. O diretório não está vazio. Exclusão recursiva não é suportada. Por favor remova todo o conteúdo primeiro.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="588"/> <location filename="../nw/gui/projtree.py" line="593"/>
<source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source> <source>Cannot delete root folder. It is not empty. Recursive deletion is not supported. Please delete the content first.</source>
<translation>Não foi possível remover o diretório-raiz. O diretório não está vazio. Exclusão recursiva não é suportada. Por favor remova todo o conteúdo primeiro.</translation> <translation>Não foi possível remover o diretório-raiz. O diretório não está vazio. Exclusão recursiva não é suportada. Por favor remova todo o conteúdo primeiro.</translation>
</message> </message>
@@ -3995,60 +4020,65 @@
<translation>Não foi possível adicionar novos arquivos ou diretórios à Lixeira.</translation> <translation>Não foi possível adicionar novos arquivos ou diretórios à Lixeira.</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="972"/> <location filename="../nw/gui/projtree.py" line="977"/>
<source>There is nowhere to add item with name &apos;{0}&apos;.</source> <source>There is nowhere to add item with name &apos;{0}&apos;.</source>
<translation>Não lugar para adicionar o item com o nome &apos;{0}&apos;.</translation> <translation>Não lugar para adicionar o item com o nome &apos;{0}&apos;.</translation>
</message> </message>
<message>
<location filename="../nw/gui/projtree.py" line="532"/>
<source>Could not delete document file.</source>
<translation>Não foi possível remover o arquivo do documento.</translation>
</message>
</context> </context>
<context> <context>
<name>GuiProjectTreeMenu</name> <name>GuiProjectTreeMenu</name>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1094"/> <location filename="../nw/gui/projtree.py" line="1099"/>
<source>Edit Project Item</source> <source>Edit Project Item</source>
<translation>Editar Item do Projeto</translation> <translation>Editar Item do Projeto</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1098"/> <location filename="../nw/gui/projtree.py" line="1103"/>
<source>Open Document</source> <source>Open Document</source>
<translation>Abrir Documento</translation> <translation>Abrir Documento</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1102"/> <location filename="../nw/gui/projtree.py" line="1107"/>
<source>View Document</source> <source>View Document</source>
<translation>Ver Documento</translation> <translation>Ver Documento</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1106"/> <location filename="../nw/gui/projtree.py" line="1111"/>
<source>Toggle Included Flag</source> <source>Toggle Included Flag</source>
<translation>Alternar Opção de Inclusão</translation> <translation>Alternar Opção de Inclusão</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1110"/> <location filename="../nw/gui/projtree.py" line="1115"/>
<source>New File</source> <source>New File</source>
<translation>Novo Arquivo</translation> <translation>Novo Arquivo</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1114"/> <location filename="../nw/gui/projtree.py" line="1119"/>
<source>New Folder</source> <source>New Folder</source>
<translation>Novo Diretório</translation> <translation>Novo Diretório</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1118"/> <location filename="../nw/gui/projtree.py" line="1123"/>
<source>Delete Item</source> <source>Delete Item</source>
<translation>Remover Item</translation> <translation>Remover Item</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1122"/> <location filename="../nw/gui/projtree.py" line="1127"/>
<source>Empty Trash</source> <source>Empty Trash</source>
<translation>Esvaziar a Lixeira</translation> <translation>Esvaziar a Lixeira</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1126"/> <location filename="../nw/gui/projtree.py" line="1131"/>
<source>Move Item Up</source> <source>Move Item Up</source>
<translation>Mover Item Acima</translation> <translation>Mover Item Acima</translation>
</message> </message>
<message> <message>
<location filename="../nw/gui/projtree.py" line="1130"/> <location filename="../nw/gui/projtree.py" line="1135"/>
<source>Move Item Down</source> <source>Move Item Down</source>
<translation>Mover Item Abaixo</translation> <translation>Mover Item Abaixo</translation>
</message> </message>
@@ -4237,24 +4267,6 @@
<translation>Salvar Dados Como</translation> <translation>Salvar Dados Como</translation>
</message> </message>
</context> </context>
<context>
<name>NWDoc</name>
<message>
<location filename="../nw/core/document.py" line="118"/>
<source>Failed to open document file.</source>
<translation>Houve uma falha ao abrir o arquivo do documento.</translation>
</message>
<message>
<location filename="../nw/core/document.py" line="162"/>
<source>Could not save document.</source>
<translation>Não foi possível salvar o documento.</translation>
</message>
<message>
<location filename="../nw/core/document.py" line="192"/>
<source>Could not delete document file.</source>
<translation>Não foi possível remover o arquivo do documento.</translation>
</message>
</context>
<context> <context>
<name>NWProject</name> <name>NWProject</name>
<message> <message>
@@ -4303,232 +4315,232 @@
<translation>Novo Projeto</translation> <translation>Novo Projeto</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="305"/> <location filename="../nw/core/project.py" line="299"/>
<source>Novel</source> <source>Novel</source>
<translation>Livro</translation> <translation>Livro</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="276"/> <location filename="../nw/core/project.py" line="273"/>
<source>Plot</source> <source>Plot</source>
<translation>Enredo</translation> <translation>Enredo</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="277"/> <location filename="../nw/core/project.py" line="274"/>
<source>Characters</source> <source>Characters</source>
<translation>Personagens</translation> <translation>Personagens</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="278"/> <location filename="../nw/core/project.py" line="275"/>
<source>World</source> <source>World</source>
<translation>Mundo</translation> <translation>Mundo</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="311"/> <location filename="../nw/core/project.py" line="305"/>
<source>Title Page</source> <source>Title Page</source>
<translation>Página de Título</translation> <translation>Página de Título</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="292"/> <location filename="../nw/core/project.py" line="288"/>
<source>New Chapter</source> <source>New Chapter</source>
<translation>Novo Capítulo</translation> <translation>Novo Capítulo</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="296"/> <location filename="../nw/core/project.py" line="291"/>
<source>New Scene</source> <source>New Scene</source>
<translation>Nova Cena</translation> <translation>Nova Cena</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="435"/> <location filename="../nw/core/project.py" line="425"/>
<source>Failed to parse project xml.</source> <source>Failed to parse project xml.</source>
<translation>Houve uma falha ao interpretar o conteúdo XML do projeto.</translation> <translation>Houve uma falha ao interpretar o conteúdo XML do projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="429"/> <location filename="../nw/core/project.py" line="419"/>
<source>Attempting to open backup project file instead.</source> <source>Attempting to open backup project file instead.</source>
<translation>Tentando abrir a cópia de segurança do projeto.</translation> <translation>Tentando abrir a cópia de segurança do projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="449"/> <location filename="../nw/core/project.py" line="439"/>
<source>Unknown</source> <source>Unknown</source>
<translation>Desconhecido</translation> <translation>Desconhecido</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="458"/> <location filename="../nw/core/project.py" line="448"/>
<source>Project file does not appear to be a novelWriterXML file.</source> <source>Project file does not appear to be a novelWriterXML file.</source>
<translation>O arquivo do projeto não parece ser um arquivo XML do novelWriter.</translation> <translation>O arquivo do projeto não parece ser um arquivo XML do novelWriter.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>Version Conflict</source> <source>Version Conflict</source>
<translation>Conflito de Versão</translation> <translation>Conflito de Versão</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="592"/> <location filename="../nw/core/project.py" line="582"/>
<source>Opened Project: {0}</source> <source>Opened Project: {0}</source>
<translation>Projeto Aberto: {0}</translation> <translation>Projeto Aberto: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="613"/> <location filename="../nw/core/project.py" line="603"/>
<source>Project path not set, cannot save project.</source> <source>Project path not set, cannot save project.</source>
<translation>O caminho do projeto não foi definido, não é possível salvar o projeto.</translation> <translation>O caminho do projeto não foi definido, não é possível salvar o projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="694"/> <location filename="../nw/core/project.py" line="684"/>
<source>Failed to save project.</source> <source>Failed to save project.</source>
<translation>Houve uma falha ao salvar o projeto.</translation> <translation>Houve uma falha ao salvar o projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="713"/> <location filename="../nw/core/project.py" line="703"/>
<source>Saved Project: {0}</source> <source>Saved Project: {0}</source>
<translation>Projeto Salvo: {0}</translation> <translation>Projeto Salvo: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="765"/> <location filename="../nw/core/project.py" line="755"/>
<source>Backing up project ...</source> <source>Backing up project ...</source>
<translation>Realizando uma cópia de segurança do projeto...</translation> <translation>Realizando uma cópia de segurança do projeto...</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="768"/> <location filename="../nw/core/project.py" line="758"/>
<source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because no backup path is set. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation>Não foi possível realizar uma cópia de segurança do projeto porquê o caminho das cópias de segurança não foi definido. Por favor, defina um caminho válido para as cópias de segurança em Ferramentas &gt; Preferências.</translation> <translation>Não foi possível realizar uma cópia de segurança do projeto porquê o caminho das cópias de segurança não foi definido. Por favor, defina um caminho válido para as cópias de segurança em Ferramentas &gt; Preferências.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="777"/> <location filename="../nw/core/project.py" line="767"/>
<source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source> <source>Cannot backup project because no project name is set. Please set a Working Title in Project &gt; Project Settings.</source>
<translation>Não foi possível realizar a cópia de segurança do projeto porque o nome do projeto não está definido. Por favor defina o Nome do Projeto em Projeto &gt; Configurações do Projeto.</translation> <translation>Não foi possível realizar a cópia de segurança do projeto porque o nome do projeto não está definido. Por favor defina o Nome do Projeto em Projeto &gt; Configurações do Projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="786"/> <location filename="../nw/core/project.py" line="776"/>
<source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools &gt; Preferences.</source>
<translation>Não foi possível realizar a cópia de segurança do projeto porque o caminho das cópias de segurança não exite. Por favor, defina um cainho válido para as cópias de segurança em Ferramentas &gt; Preferências.</translation> <translation>Não foi possível realizar a cópia de segurança do projeto porque o caminho das cópias de segurança não exite. Por favor, defina um cainho válido para as cópias de segurança em Ferramentas &gt; Preferências.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="801"/> <location filename="../nw/core/project.py" line="791"/>
<source>Could not create backup folder.</source> <source>Could not create backup folder.</source>
<translation>Não foi possível ler o diretório de cópias de segurança.</translation> <translation>Não foi possível ler o diretório de cópias de segurança.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="808"/> <location filename="../nw/core/project.py" line="798"/>
<source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source> <source>Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools &gt; Preferences.</source>
<translation>Não foi possível realizar a cópia de segurança do projeto porque o caminho das cópias de segurança está em um caminho dentro do diretório do projeto. Por favor, escolha um caminho diferente para as cópias de segurança em Ferramentas&gt; Preferências.</translation> <translation>Não foi possível realizar a cópia de segurança do projeto porque o caminho das cópias de segurança está em um caminho dentro do diretório do projeto. Por favor, escolha um caminho diferente para as cópias de segurança em Ferramentas&gt; Preferências.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="835"/> <location filename="../nw/core/project.py" line="825"/>
<source>Could not write backup archive.</source> <source>Could not write backup archive.</source>
<translation>Não foi possível escrever o arquivo da cópia de segurança.</translation> <translation>Não foi possível escrever o arquivo da cópia de segurança.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="889"/> <location filename="../nw/core/project.py" line="879"/>
<source>Failed to create a new example project.</source> <source>Failed to create a new example project.</source>
<translation>Houve uma falha ao criar um novo projeto de exemplo.</translation> <translation>Houve uma falha ao criar um novo projeto de exemplo.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="894"/> <location filename="../nw/core/project.py" line="884"/>
<source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source> <source>Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation.</source>
<translation>Houve uma falha ao criar um novo projeto de exemplo. Não foi possível encontrar os arquivos necessários. Eles parecem estar faltando nesta instalação.</translation> <translation>Houve uma falha ao criar um novo projeto de exemplo. Não foi possível encontrar os arquivos necessários. Eles parecem estar faltando nesta instalação.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="929"/> <location filename="../nw/core/project.py" line="919"/>
<source>Could not create new project folder.</source> <source>Could not create new project folder.</source>
<translation>Não foi possível criar o diretório do novo projeto.</translation> <translation>Não foi possível criar o diretório do novo projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="936"/> <location filename="../nw/core/project.py" line="926"/>
<source>New project folder is not empty. Each project requires a dedicated project folder.</source> <source>New project folder is not empty. Each project requires a dedicated project folder.</source>
<translation>O diretório do novo projeto não está vazio. Cada projeto requer um diretório dedicado.</translation> <translation>O diretório do novo projeto não está vazio. Cada projeto requer um diretório dedicado.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="988"/> <location filename="../nw/core/project.py" line="978"/>
<source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source> <source>You must set a valid backup path in Preferences to use the automatic project backup feature.</source>
<translation>Deve ser definido um caminho válido para as cópias de segurança nas preferências para usar a funcionalidade de cópias de segurança automáticas.</translation> <translation>Deve ser definido um caminho válido para as cópias de segurança nas preferências para usar a funcionalidade de cópias de segurança automáticas.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="997"/> <location filename="../nw/core/project.py" line="987"/>
<source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source> <source>You must set a valid project name in Project Settings to use the automatic project backup feature.</source>
<translation>Deve ser definido um nome de projeto válido nas preferências do projeto para usar a funcionalidade de cópias de segurança automáticas.</translation> <translation>Deve ser definido um nome de projeto válido nas preferências do projeto para usar a funcionalidade de cópias de segurança automáticas.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1399"/> <location filename="../nw/core/project.py" line="1388"/>
<source>Recovered</source> <source>Recovered</source>
<translation>Recuperado</translation> <translation>Recuperado</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1443"/> <location filename="../nw/core/project.py" line="1434"/>
<source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source> <source>One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists.</source>
<translation>Um ou mais arquivos-órfãos não puderam ser readicionados ao projeto. Verifique que pelo menos um diretório-raiz de Livro exista.</translation> <translation>Um ou mais arquivos-órfãos não puderam ser readicionados ao projeto. Verifique que pelo menos um diretório-raiz de Livro exista.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1527"/> <location filename="../nw/core/project.py" line="1518"/>
<source>Could not move: {0}</source> <source>Could not move: {0}</source>
<translation>Não foi possível mover: {0}</translation> <translation>Não foi possível mover: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1551"/> <location filename="../nw/core/project.py" line="1542"/>
<source>Could not delete: {0}</source> <source>Could not delete: {0}</source>
<translation>Não foi possível remover: {0}</translation> <translation>Não foi possível remover: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1563"/> <location filename="../nw/core/project.py" line="1554"/>
<source>Could not make folder: {0}</source> <source>Could not make folder: {0}</source>
<translation>Não foi possível criar o diretório: {0}</translation> <translation>Não foi possível criar o diretório: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="326"/> <location filename="../nw/core/project.py" line="319"/>
<source>Chapter {0}</source> <source>Chapter {0}</source>
<translation>Capítulo {0}</translation> <translation>Capítulo {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="351"/> <location filename="../nw/core/project.py" line="342"/>
<source>Scene {0}</source> <source>Scene {0}</source>
<translation>Cena {0}</translation> <translation>Cena {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="375"/> <location filename="../nw/core/project.py" line="365"/>
<source>File not found: {0}</source> <source>File not found: {0}</source>
<translation>Arquivo não encontrado: {0}</translation> <translation>Arquivo não encontrado: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="817"/> <location filename="../nw/core/project.py" line="807"/>
<source>Backup from {0}</source> <source>Backup from {0}</source>
<translation>Cópia de segurança de {0}</translation> <translation>Cópia de segurança de {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="826"/> <location filename="../nw/core/project.py" line="816"/>
<source>Backup archive file written to: {0}</source> <source>Backup archive file written to: {0}</source>
<translation>Arquivo da cópia de segurança escrito em: {0}</translation> <translation>Arquivo da cópia de segurança escrito em: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="841"/> <location filename="../nw/core/project.py" line="831"/>
<source>Project backed up to &apos;{0}&apos;</source> <source>Project backed up to &apos;{0}&apos;</source>
<translation>Cópia de segurança realizada para &apos;{0}&apos;</translation> <translation>Cópia de segurança realizada para &apos;{0}&apos;</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1387"/> <location filename="../nw/core/project.py" line="1377"/>
<source>Found {0} orphaned file(s) in project folder.</source> <source>Found {0} orphaned file(s) in project folder.</source>
<translation>Foram encontrados {0} arquivos-órfãos no diretório do projeto.</translation> <translation>Foram encontrados {0} arquivos-órfãos no diretório do projeto.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1416"/> <location filename="../nw/core/project.py" line="1407"/>
<source>Recovered File {0}</source> <source>Recovered File {0}</source>
<translation>Arquivo Recuperado {0}</translation> <translation>Arquivo Recuperado {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1504"/> <location filename="../nw/core/project.py" line="1495"/>
<source>Not a folder: {0}</source> <source>Not a folder: {0}</source>
<translation>Não é um diretório: {0}</translation> <translation>Não é um diretório: {0}</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="478"/> <location filename="../nw/core/project.py" line="468"/>
<source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source> <source>Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}.</source>
<translation>Format de arquivo de projeto do novelWriter desconhecido ou não-suportado. O projeto não pode ser aberto por essa versão do novelWriter. O arquivo foi salvo com a versão {0} do novelWriter.</translation> <translation>Format de arquivo de projeto do novelWriter desconhecido ou não-suportado. O projeto não pode ser aberto por essa versão do novelWriter. O arquivo foi salvo com a versão {0} do novelWriter.</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1411"/> <location filename="../nw/core/project.py" line="1402"/>
<source>[{0}] {1}</source> <source>[{0}] {1}</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1574"/> <location filename="../nw/core/project.py" line="1565"/>
<source>Could not move item {0} to {1}.</source> <source>Could not move item {0} to {1}.</source>
<translation>Não foi possível mover o item {0} para {1}.</translation> <translation>Não foi possível mover o item {0} para {1}.</translation>
</message> </message>
@@ -4538,7 +4550,7 @@
<translation>Por</translation> <translation>Por</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="1141"/> <location filename="../nw/core/project.py" line="1131"/>
<source>and</source> <source>and</source>
<translation>e</translation> <translation>e</translation>
</message> </message>
@@ -4548,7 +4560,7 @@
<translation>Capítulo</translation> <translation>Capítulo</translation>
</message> </message>
<message> <message>
<location filename="../nw/core/project.py" line="492"/> <location filename="../nw/core/project.py" line="482"/>
<source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source> <source>This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project?</source>
<translation>O projeto foi salvo por uma versão mais nova do novelWriter, versão {0}. Esta é a versão {1}. Caso deseje continuar a abrir o projeto, alguns atributos e configurações podem não ser preservados, mas o projeto deve funcionar corretamente. Continuar a abrir o projeto?</translation> <translation>O projeto foi salvo por uma versão mais nova do novelWriter, versão {0}. Esta é a versão {1}. Caso deseje continuar a abrir o projeto, alguns atributos e configurações podem não ser preservados, mas o projeto deve funcionar corretamente. Continuar a abrir o projeto?</translation>
</message> </message>
-1
View File
@@ -1,6 +1,5 @@
SOURCES += \ SOURCES += \
i18n/qtbase.py \ i18n/qtbase.py \
nw/core/document.py \
nw/core/project.py \ nw/core/project.py \
nw/core/tokenizer.py \ nw/core/tokenizer.py \
nw/dialogs/about.py \ nw/dialogs/about.py \
+32 -46
View File
@@ -27,31 +27,29 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging import logging
import os import os
from functools import partial from nw.enum import nwItemLayout, nwItemClass
from PyQt5.QtCore import QCoreApplication
from nw.enum import nwAlert, nwItemLayout, nwItemClass
from nw.common import isHandle from nw.common import isHandle
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class NWDoc(): class NWDoc():
def __init__(self, theProject): def __init__(self, theProject, theHandle):
self.theProject = theProject self.theProject = theProject
self.theParent = theProject.theParent
# Internal Variables # Internal Variables
self._theItem = None # The currently open item self._theItem = None # The currently open item
self._docHandle = None # The handle of the currently open item self._docHandle = None # The handle of the currently open item
self._fileLoc = None # The file location of the currently open item self._fileLoc = None # The file location of the currently open item
self._docMeta = {} # The meta data of the currently open item self._docMeta = {} # The meta data of the currently open item
self._docError = "" # The latest encountered IO error
# Internal Mapping if isHandle(theHandle):
self.makeAlert = self.theParent.makeAlert self._docHandle = theHandle
self.tr = partial(QCoreApplication.translate, "NWDoc")
if self._docHandle is not None:
self._theItem = self.theProject.projTree[theHandle]
return return
@@ -59,35 +57,19 @@ class NWDoc():
# Class Methods # Class Methods
## ##
def clearDocument(self): def readDocument(self, isOrphan=False):
"""Clear the document contents. """Read a document from set handle, capturing potential file
""" system errors and parse meta data. If the document doesn't exist
self._theItem = None on disk, return an empty string. If something went wrong, return
self._docHandle = None
self._fileLoc = None
self._docMeta = {}
return
def readDocument(self, tHandle, isOrphan=False):
"""Read a document from handle, capturing potential file system
errors and parse meta data. If the document doesn't exist on
disk, return an empty string. If something went wrong, return
None. None.
""" """
if not isHandle(tHandle): self._docError = ""
if self._docHandle is None:
logger.error("No document handle set")
return None return None
# Always clear first, since the object will often be reused.
self.clearDocument()
self._docHandle = tHandle
if not isOrphan:
self._theItem = self.theProject.projTree[tHandle]
else:
self._theItem = None
if self._theItem is None and not isOrphan: if self._theItem is None and not isOrphan:
self.clearDocument() logger.error("Unknown novelWriter document")
return None return None
docFile = self._docHandle+".nwd" docFile = self._docHandle+".nwd"
@@ -115,12 +97,9 @@ class NWDoc():
theText += inFile.read() theText += inFile.read()
except Exception as e: except Exception as e:
self.makeAlert([self.tr("Failed to open document file."), str(e)], nwAlert.ERROR) self._docError = str(e)
# Note: Document must be cleared in case of an io error,
# or else the auto-save or save will try to overwrite it
# with an empty file. Return None to alert the caller.
self.clearDocument()
return None return None
else: else:
# The document file does not exist, so we assume it's a new # The document file does not exist, so we assume it's a new
# document and initialise an empty text string. # document and initialise an empty text string.
@@ -133,7 +112,9 @@ class NWDoc():
"""Write the document. The file is saved via a temp file in case """Write the document. The file is saved via a temp file in case
of save failure. Returns True if successful, False if not. of save failure. Returns True if successful, False if not.
""" """
self._docError = ""
if self._docHandle is None: if self._docHandle is None:
logger.error("No document handle set")
return False return False
self.theProject.ensureFolderStructure() self.theProject.ensureFolderStructure()
@@ -159,7 +140,7 @@ class NWDoc():
outFile.write(docMeta) outFile.write(docMeta)
outFile.write(docText) outFile.write(docText)
except Exception as e: except Exception as e:
self.makeAlert([self.tr("Could not save document."), str(e)], nwAlert.ERROR) self._docError = str(e)
return False return False
# If we're here, the file was successfully saved, so we can # If we're here, the file was successfully saved, so we can
@@ -170,14 +151,16 @@ class NWDoc():
return True return True
def deleteDocument(self, tHandle): def deleteDocument(self):
"""Permanently delete a document source file and related files """Permanently delete a document source file and related files
from the project data folder. from the project data folder.
""" """
if not isHandle(tHandle): self._docError = ""
if self._docHandle is None:
logger.error("No document handle set")
return False return False
docFile = tHandle+".nwd" docFile = self._docHandle+".nwd"
chkList = [] chkList = []
chkList.append(os.path.join(self.theProject.projContent, docFile)) chkList.append(os.path.join(self.theProject.projContent, docFile))
@@ -189,9 +172,7 @@ class NWDoc():
os.unlink(chkFile) os.unlink(chkFile)
logger.debug("Deleted: %s" % chkFile) logger.debug("Deleted: %s" % chkFile)
except Exception as e: except Exception as e:
self.makeAlert( self._docError = str(e)
[self.tr("Could not delete document file."), str(e)], nwAlert.ERROR
)
return False return False
return True return True
@@ -221,6 +202,11 @@ class NWDoc():
return theName, theParent, theClass, theLayout return theName, theParent, theClass, theLayout
def getError(self):
"""Return the last recorded exception.
"""
return self._docError
## ##
# Internal Functions # Internal Functions
## ##
+3 -3
View File
@@ -115,8 +115,8 @@ class NWIndex():
if tItem.itemType != nwItemType.FILE: if tItem.itemType != nwItemType.FILE:
return False return False
theDoc = NWDoc(self.theProject) theDoc = NWDoc(self.theProject, tHandle)
theText = theDoc.readDocument(tHandle) theText = theDoc.readDocument()
if theText: if theText:
self.scanText(tHandle, theText) self.scanText(tHandle, theText)
@@ -269,7 +269,7 @@ class NWIndex():
logger.debug("Indexing item with handle %s" % tHandle) logger.debug("Indexing item with handle %s" % tHandle)
# Check file type, and reset its old index # Check file type, and reset its old index
# Also add a dummy entry T000000 in case the file has no title # Also add a default entry T000000 in case the file has no title
self._refIndex[tHandle] = {} self._refIndex[tHandle] = {}
self._refIndex[tHandle]["T000000"] = { self._refIndex[tHandle]["T000000"] = {
"tags" : [], "tags" : [],
+10 -19
View File
@@ -265,9 +265,6 @@ class NWProject():
if self.bookAuthors: if self.bookAuthors:
titlePage = "%s%s %s\n" % (titlePage, self.tr("By"), self.getAuthors()) titlePage = "%s%s %s\n" % (titlePage, self.tr("By"), self.getAuthors())
# Document object for writing files
aDoc = NWDoc(self)
if popMinimal: if popMinimal:
# Creating a minimal project with a few root folders and a # Creating a minimal project with a few root folders and a
# single chapter folder with a single file. # single chapter folder with a single file.
@@ -284,17 +281,14 @@ class NWProject():
self.projTree.setFileItemLayout(xHandle[5], nwItemLayout.TITLE) self.projTree.setFileItemLayout(xHandle[5], nwItemLayout.TITLE)
self.projTree.setFileItemLayout(xHandle[7], nwItemLayout.CHAPTER) self.projTree.setFileItemLayout(xHandle[7], nwItemLayout.CHAPTER)
aDoc.readDocument(xHandle[5]) aDoc = NWDoc(self, xHandle[5])
aDoc.writeDocument(titlePage) aDoc.writeDocument(titlePage)
aDoc.clearDocument()
aDoc.readDocument(xHandle[7]) aDoc = NWDoc(self, xHandle[7])
aDoc.writeDocument("## %s\n\n" % self.tr("New Chapter")) aDoc.writeDocument("## %s\n\n" % self.tr("New Chapter"))
aDoc.clearDocument()
aDoc.readDocument(xHandle[8]) aDoc = NWDoc(self, xHandle[8])
aDoc.writeDocument("### %s\n\n" % self.tr("New Scene")) aDoc.writeDocument("### %s\n\n" % self.tr("New Scene"))
aDoc.clearDocument()
elif popCustom: elif popCustom:
# Create a project structure based on selected root folders # Create a project structure based on selected root folders
@@ -311,9 +305,8 @@ class NWProject():
tHandle = self.newFile(self.tr("Title Page"), nwItemClass.NOVEL, nHandle) tHandle = self.newFile(self.tr("Title Page"), nwItemClass.NOVEL, nHandle)
self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE) self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE)
aDoc.readDocument(tHandle) aDoc = NWDoc(self, tHandle)
aDoc.writeDocument(titlePage) aDoc.writeDocument(titlePage)
aDoc.clearDocument()
# Create chapters and scenes # Create chapters and scenes
numChapters = projData.get("numChapters", 0) numChapters = projData.get("numChapters", 0)
@@ -331,9 +324,8 @@ class NWProject():
cHandle = self.newFile(chTitle, nwItemClass.NOVEL, pHandle) cHandle = self.newFile(chTitle, nwItemClass.NOVEL, pHandle)
self.projTree.setFileItemLayout(cHandle, nwItemLayout.CHAPTER) self.projTree.setFileItemLayout(cHandle, nwItemLayout.CHAPTER)
aDoc.readDocument(cHandle) aDoc = NWDoc(self, cHandle)
aDoc.writeDocument("## %s\n\n" % chTitle) aDoc.writeDocument("## %s\n\n" % chTitle)
aDoc.clearDocument()
# Create chapter scenes # Create chapter scenes
if numScenes > 0: if numScenes > 0:
@@ -341,9 +333,8 @@ class NWProject():
scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}") scTitle = self.tr("Scene {0}").format(f"{ch+1:d}.{sc+1:d}")
sHandle = self.newFile(scTitle, nwItemClass.NOVEL, pHandle) sHandle = self.newFile(scTitle, nwItemClass.NOVEL, pHandle)
aDoc.readDocument(sHandle) aDoc = NWDoc(self, sHandle)
aDoc.writeDocument("### %s\n\n" % scTitle) aDoc.writeDocument("### %s\n\n" % scTitle)
aDoc.clearDocument()
# Create scenes (no chapters) # Create scenes (no chapters)
elif numScenes > 0: elif numScenes > 0:
@@ -351,9 +342,8 @@ class NWProject():
scTitle = self.tr("Scene {0}").format(f"{sc+1:d}") scTitle = self.tr("Scene {0}").format(f"{sc+1:d}")
sHandle = self.newFile(scTitle, nwItemClass.NOVEL, nHandle) sHandle = self.newFile(scTitle, nwItemClass.NOVEL, nHandle)
aDoc.readDocument(sHandle) aDoc = NWDoc(self, sHandle)
aDoc.writeDocument("### %s\n\n" % scTitle) aDoc.writeDocument("### %s\n\n" % scTitle)
aDoc.clearDocument()
# Finalise # Finalise
if popCustom or popMinimal: if popCustom or popMinimal:
@@ -1393,7 +1383,6 @@ class NWProject():
return return
# Handle orphans # Handle orphans
aDoc = NWDoc(self)
nOrph = 0 nOrph = 0
noWhere = False noWhere = False
oPrefix = self.tr("Recovered") oPrefix = self.tr("Recovered")
@@ -1404,7 +1393,9 @@ class NWProject():
oParent = None oParent = None
oClass = None oClass = None
oLayout = None oLayout = None
if aDoc.readDocument(oHandle, isOrphan=True) is not None:
aDoc = NWDoc(self, oHandle)
if aDoc.readDocument(isOrphan=True) is not None:
oName, oParent, oClass, oLayout = aDoc.getMeta() oName, oParent, oClass, oLayout = aDoc.getMeta()
if oName: if oName:
+6 -6
View File
@@ -47,17 +47,17 @@ class NWSpellCheck():
return return
def setLanguage(self, theLang, projectDict=None): def setLanguage(self, theLang, projectDict=None):
"""Dummy function. """Default function.
""" """
return return
def checkWord(self, theWord): def checkWord(self, theWord):
"""Dummy function. """Default function.
""" """
return True return True
def suggestWords(self, theWord): def suggestWords(self, theWord):
"""Dummy function. """Default function.
""" """
return [] return []
@@ -78,12 +78,12 @@ class NWSpellCheck():
return False return False
def listDictionaries(self): def listDictionaries(self):
"""Dummy function. """Default function.
""" """
return [] return []
def describeDict(self): def describeDict(self):
"""Dummy function. """Default function.
""" """
return "", "" return "", ""
@@ -136,7 +136,7 @@ class NWSpellEnchant(NWSpellCheck):
def setLanguage(self, theLang, projectDict=None): def setLanguage(self, theLang, projectDict=None):
"""Load a dictionary for the language specified in the config. """Load a dictionary for the language specified in the config.
If that fails, we load a dummy dictionary so that lookups don't If that fails, we load a mock dictionary so that lookups don't
crash. crash.
""" """
try: try:
+2 -2
View File
@@ -284,8 +284,8 @@ class Tokenizer():
self.theText = theText self.theText = theText
else: else:
# Otherwise, load it from file # Otherwise, load it from file
theDoc = NWDoc(self.theProject) theDoc = NWDoc(self.theProject, theHandle)
theText = theDoc.readDocument(theHandle) theText = theDoc.readDocument()
if theText: if theText:
self.theText = theText self.theText = theText
+1 -1
View File
@@ -563,7 +563,7 @@ class ToOdt(Tokenizer):
## ##
if len(theText) != len(theFmt): if len(theText) != len(theFmt):
# Generate dummy format if there isn't any or it doesn't match # Generate an empty format if there isn't any or it doesn't match
theFmt = " "*len(theText) theFmt = " "*len(theText)
# XML functions # XML functions
+26 -17
View File
@@ -105,40 +105,48 @@ class GuiDocMerge(QDialog):
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("No source documents found. Nothing to do."), nwAlert.ERROR self.tr("No source documents found. Nothing to do."), nwAlert.ERROR
) )
return return False
theDoc = NWDoc(self.theProject)
theText = "" theText = ""
for tHandle in finalOrder: for tHandle in finalOrder:
docText = theDoc.readDocument(tHandle).rstrip("\n") inDoc = NWDoc(self.theProject, tHandle)
docText = inDoc.readDocument()
docErr = inDoc.getError()
if docText is None and docErr:
self.theParent.makeAlert(
[self.tr("Failed to open document file."), docErr], nwAlert.ERROR
)
if docText: if docText:
theText += docText+"\n\n" theText += docText.rstrip("\n")+"\n\n"
if self.sourceItem is None: if self.sourceItem is None:
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("No source document selected. Nothing to do."), nwAlert.ERROR self.tr("No source folder selected. Nothing to do."), nwAlert.ERROR
) )
return return False
srcItem = self.theProject.projTree[self.sourceItem] srcItem = self.theProject.projTree[self.sourceItem]
if srcItem is None: if srcItem is None:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr("Internal error."), nwAlert.ERROR)
self.tr("Could not parse source document."), nwAlert.ERROR return False
)
return
nHandle = self.theProject.newFile(srcItem.itemName, srcItem.itemClass, srcItem.itemParent) nHandle = self.theProject.newFile(srcItem.itemName, srcItem.itemClass, srcItem.itemParent)
newItem = self.theProject.projTree[nHandle] newItem = self.theProject.projTree[nHandle]
newItem.setStatus(srcItem.itemStatus) newItem.setStatus(srcItem.itemStatus)
theDoc.readDocument(nHandle) outDoc = NWDoc(self.theProject, nHandle)
theDoc.writeDocument(theText) if not outDoc.writeDocument(theText):
self.theParent.makeAlert(
[self.tr("Could not save document."), outDoc.getError()], nwAlert.ERROR
)
return False
self.theParent.treeView.revealNewTreeItem(nHandle) self.theParent.treeView.revealNewTreeItem(nHandle)
self.theParent.openDocument(nHandle, doScroll=True) self.theParent.openDocument(nHandle, doScroll=True)
self._doClose() self._doClose()
return return True
def _doClose(self): def _doClose(self):
"""Close the dialog window without doing anything. """Close the dialog window without doing anything.
@@ -159,16 +167,17 @@ class GuiDocMerge(QDialog):
tHandle = self.theParent.treeView.getSelectedHandle() tHandle = self.theParent.treeView.getSelectedHandle()
self.sourceItem = tHandle self.sourceItem = tHandle
if tHandle is None: if tHandle is None:
return return False
nwItem = self.theProject.projTree[tHandle] nwItem = self.theProject.projTree[tHandle]
if nwItem is None: if nwItem is None:
return return False
if nwItem.itemType is not nwItemType.FOLDER: if nwItem.itemType is not nwItemType.FOLDER:
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("Element selected in the project tree must be a folder."), nwAlert.ERROR self.tr("Element selected in the project tree must be a folder."), nwAlert.ERROR
) )
return return False
for sHandle in self.theParent.treeView.getTreeFromHandle(tHandle): for sHandle in self.theParent.treeView.getTreeFromHandle(tHandle):
newItem = QListWidgetItem() newItem = QListWidgetItem()
@@ -179,6 +188,6 @@ class GuiDocMerge(QDialog):
newItem.setData(Qt.UserRole, sHandle) newItem.setData(Qt.UserRole, sHandle)
self.listBox.addItem(newItem) self.listBox.addItem(newItem)
return return True
# END Class GuiDocMerge # END Class GuiDocMerge
+32 -18
View File
@@ -118,17 +118,24 @@ class GuiDocSplit(QDialog):
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("No source document selected. Nothing to do."), nwAlert.ERROR self.tr("No source document selected. Nothing to do."), nwAlert.ERROR
) )
return return False
srcItem = self.theProject.projTree[self.sourceItem] srcItem = self.theProject.projTree[self.sourceItem]
if srcItem is None: if srcItem is None:
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("Could not parse source document."), nwAlert.ERROR self.tr("Could not parse source document."), nwAlert.ERROR
) )
return return False
inDoc = NWDoc(self.theProject, self.sourceItem)
theText = inDoc.readDocument()
docErr = inDoc.getError()
if theText is None and docErr:
self.theParent.makeAlert(
[self.tr("Failed to open document file."), docErr], nwAlert.ERROR
)
theDoc = NWDoc(self.theProject)
theText = theDoc.readDocument(self.sourceItem)
if theText is None: if theText is None:
theText = "" theText = ""
@@ -153,7 +160,7 @@ class GuiDocSplit(QDialog):
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("No headers found. Nothing to do."), nwAlert.ERROR self.tr("No headers found. Nothing to do."), nwAlert.ERROR
) )
return return False
# Check that another folder can be created # Check that another folder can be created
parTree = self.theProject.projTree.getItemPath(srcItem.itemParent) parTree = self.theProject.projTree.getItemPath(srcItem.itemParent)
@@ -165,7 +172,7 @@ class GuiDocSplit(QDialog):
"Please move the file to another level in the project tree." "Please move the file to another level in the project tree."
), nwAlert.ERROR ), nwAlert.ERROR
) )
return return False
msgYes = self.theParent.askQuestion( msgYes = self.theParent.askQuestion(
self.tr("Split Document"), self.tr("Split Document"),
@@ -179,7 +186,7 @@ class GuiDocSplit(QDialog):
) )
) )
if not msgYes: if not msgYes:
return return False
# Create the folder # Create the folder
fHandle = self.theProject.newFolder( fHandle = self.theProject.newFolder(
@@ -217,14 +224,19 @@ class GuiDocSplit(QDialog):
theText = "\n".join(theLines[iStart:iEnd]) theText = "\n".join(theLines[iStart:iEnd])
theText = theText.rstrip("\n") + "\n\n" theText = theText.rstrip("\n") + "\n\n"
theDoc.readDocument(nHandle)
theDoc.writeDocument(theText) outDoc = NWDoc(self.theProject, nHandle)
theDoc.clearDocument() if not outDoc.writeDocument(theText):
self.theParent.makeAlert(
[self.tr("Could not save document."), outDoc.getError()], nwAlert.ERROR
)
return False
self.theParent.treeView.revealNewTreeItem(nHandle) self.theParent.treeView.revealNewTreeItem(nHandle)
self._doClose() self._doClose()
return return True
def _doClose(self): def _doClose(self):
"""Close the dialog window without doing anything. """Close the dialog window without doing anything.
@@ -243,26 +255,28 @@ class GuiDocSplit(QDialog):
are then added to the list view in order. The list itself can be are then added to the list view in order. The list itself can be
reordered by the user. reordered by the user.
""" """
self.listBox.clear()
if self.sourceItem is None: if self.sourceItem is None:
self.sourceItem = self.theParent.treeView.getSelectedHandle() self.sourceItem = self.theParent.treeView.getSelectedHandle()
if self.sourceItem is None: if self.sourceItem is None:
return return False
nwItem = self.theProject.projTree[self.sourceItem] nwItem = self.theProject.projTree[self.sourceItem]
if nwItem is None: if nwItem is None:
return return False
if nwItem.itemType is not nwItemType.FILE: if nwItem.itemType is not nwItemType.FILE:
self.theParent.makeAlert( self.theParent.makeAlert(
self.tr("Element selected in the project tree must be a file."), nwAlert.ERROR self.tr("Element selected in the project tree must be a file."), nwAlert.ERROR
) )
return return False
self.listBox.clear() inDoc = NWDoc(self.theProject, self.sourceItem)
theDoc = NWDoc(self.theProject) theText = inDoc.readDocument()
theText = theDoc.readDocument(self.sourceItem)
if theText is None: if theText is None:
theText = "" theText = ""
return False
spLevel = self.splitLevel.currentData() spLevel = self.splitLevel.currentData()
self.optState.setValue("GuiDocSplit", "spLevel", spLevel) self.optState.setValue("GuiDocSplit", "spLevel", spLevel)
@@ -291,6 +305,6 @@ class GuiDocSplit(QDialog):
newItem.setData(Qt.UserRole, onLine) newItem.setData(Qt.UserRole, onLine)
self.listBox.addItem(newItem) self.listBox.addItem(newItem)
return return True
# END Class GuiDocSplit # END Class GuiDocSplit
+40 -26
View File
@@ -75,7 +75,9 @@ class GuiDocEditor(QTextEdit):
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theIndex = theParent.theIndex self.theIndex = theParent.theIndex
self.theProject = theParent.theProject self.theProject = theParent.theProject
self.nwDocument = NWDoc(self.theProject)
self.nwDocument = None
self.nwItem = None
self.docChanged = False # Flag for changed status of document self.docChanged = False # Flag for changed status of document
self.spellCheck = False # Flag for spell checking enabled self.spellCheck = False # Flag for spell checking enabled
@@ -165,7 +167,7 @@ class GuiDocEditor(QTextEdit):
"""Clear the current document and reset all document related """Clear the current document and reset all document related
flags and counters. flags and counters.
""" """
self.nwDocument.clearDocument() self.nwDocument = None
self.setReadOnly(True) self.setReadOnly(True)
self.clear() self.clear()
self.wcTimer.stop() self.wcTimer.stop()
@@ -297,7 +299,10 @@ class GuiDocEditor(QTextEdit):
document is new (empty string), we set up the editor for editing document is new (empty string), we set up the editor for editing
the file. the file.
""" """
theDoc = self.nwDocument.readDocument(tHandle) self.nwDocument = NWDoc(self.theProject, tHandle)
self.nwItem = self.nwDocument.getCurrentItem()
theDoc = self.nwDocument.readDocument()
if theDoc is None: if theDoc is None:
# There was an io error # There was an io error
self.clearEditor() self.clearEditor()
@@ -350,16 +355,15 @@ class GuiDocEditor(QTextEdit):
self.updateDocMargins() self.updateDocMargins()
self.hLight.spellCheck = spTemp self.hLight.spellCheck = spTemp
theItem = self.nwDocument.getCurrentItem() if tLine is None and self.nwItem is not None:
if tLine is None and theItem is not None:
# For large documents we queue the repositioning until the # For large documents we queue the repositioning until the
# document layout has grown past the point we want to move # document layout has grown past the point we want to move
# the cursor to. This makes the loading significantly # the cursor to. This makes the loading significantly
# faster. # faster.
if docSize > 50000: if docSize > 50000:
self.queuePos = theItem.cursorPos self.queuePos = self.nwItem.cursorPos
else: else:
self.setCursorPosition(theItem.cursorPos) self.setCursorPosition(self.nwItem.cursorPos)
else: else:
self.setCursorLine(tLine) self.setCursorLine(tLine)
@@ -378,9 +382,9 @@ class GuiDocEditor(QTextEdit):
self.setCursorPosition(0) self.setCursorPosition(0)
# Update the status bar # Update the status bar
if theItem is not None: if self.nwItem is not None:
self.theParent.setStatus( self.theParent.setStatus(
self.tr("Opened Document: {0}").format(theItem.itemName) self.tr("Opened Document: {0}").format(self.nwItem.itemName)
) )
return True return True
@@ -429,22 +433,33 @@ class GuiDocEditor(QTextEdit):
"""Save the text currently in the editor to the NWDoc object, """Save the text currently in the editor to the NWDoc object,
and update the NWItem meta data. and update the NWItem meta data.
""" """
theItem = self.nwDocument.getCurrentItem() if self.nwItem is None or self.nwDocument is None:
if theItem is None: logger.error("Cannot save text as no document is open")
return False
tHandle = self.nwItem.itemHandle
if self.theHandle != tHandle:
logger.error("Editor handle %s and item handle %s do not match" % (
self.theHandle, tHandle
))
return False return False
docText = self.getText() docText = self.getText()
tHandle = theItem.itemHandle
cC, wC, pC = countWords(docText) cC, wC, pC = countWords(docText)
self._updateCounts(cC, wC, pC) self._updateCounts(cC, wC, pC)
theItem.setCharCount(self.charCount) self.nwItem.setCharCount(self.charCount)
theItem.setWordCount(self.wordCount) self.nwItem.setWordCount(self.wordCount)
theItem.setParaCount(self.paraCount) self.nwItem.setParaCount(self.paraCount)
self.saveCursorPosition() self.saveCursorPosition()
self.nwDocument.writeDocument(docText) if not self.nwDocument.writeDocument(docText):
self.theParent.makeAlert([
self.tr("Could not save document."), self.nwDocument.getError()
], nwAlert.ERROR)
return False
self.setDocumentChanged(False) self.setDocumentChanged(False)
self.theIndex.scanText(tHandle, docText) self.theIndex.scanText(tHandle, docText)
@@ -465,7 +480,7 @@ class GuiDocEditor(QTextEdit):
# Update the status bar # Update the status bar
self.theParent.setStatus( self.theParent.setStatus(
self.tr("Saved Document: {0}").format(theItem.itemName) self.tr("Saved Document: {0}").format(self.nwItem.itemName)
) )
return True return True
@@ -592,10 +607,9 @@ class GuiDocEditor(QTextEdit):
def saveCursorPosition(self): def saveCursorPosition(self):
"""Save the cursor position to the current project item object. """Save the cursor position to the current project item object.
""" """
theItem = self.nwDocument.getCurrentItem() if self.nwItem is not None:
if theItem is not None:
cursPos = self.getCursorPosition() cursPos = self.getCursorPosition()
theItem.setCursorPos(cursPos) self.nwItem.setCursorPos(cursPos)
return return
def setCursorLine(self, theLine): def setCursorLine(self, theLine):
@@ -766,7 +780,7 @@ class GuiDocEditor(QTextEdit):
"""Tell the user where on the file system the file in the editor """Tell the user where on the file system the file in the editor
is saved. is saved.
""" """
if self.theHandle is None: if self.nwDocument is None:
logger.error("No document open") logger.error("No document open")
return False return False
@@ -1133,8 +1147,7 @@ class GuiDocEditor(QTextEdit):
def _updateCounts(self, cCount, wCount, pCount): def _updateCounts(self, cCount, wCount, pCount):
"""Slot for the word counter's finished signal """Slot for the word counter's finished signal
""" """
theItem = self.nwDocument.getCurrentItem() if self.theHandle is None or self.nwItem is None:
if self.theHandle is None or theItem is None:
return return
logger.verbose("Updating word count") logger.verbose("Updating word count")
@@ -1142,9 +1155,10 @@ class GuiDocEditor(QTextEdit):
self.charCount = cCount self.charCount = cCount
self.wordCount = wCount self.wordCount = wCount
self.paraCount = pCount self.paraCount = pCount
theItem.setCharCount(cCount)
theItem.setWordCount(wCount) self.nwItem.setCharCount(cCount)
theItem.setParaCount(pCount) self.nwItem.setWordCount(wCount)
self.nwItem.setParaCount(pCount)
self.theParent.treeView.propagateCount(self.theHandle, wCount) self.theParent.treeView.propagateCount(self.theHandle, wCount)
self.theParent.treeView.projectWordCount() self.theParent.treeView.projectWordCount()
-1
View File
@@ -185,7 +185,6 @@ class GuiDocViewer(QTextBrowser):
logger.error("Failed to generate preview for document with handle '%s'" % tHandle) logger.error("Failed to generate preview for document with handle '%s'" % tHandle)
nw.logException() nw.logException()
self.setText(self.tr("An error occurred while generating the preview.")) self.setText(self.tr("An error occurred while generating the preview."))
return False
# Refresh the tab stops # Refresh the tab stops
if self.mainConf.verQtValue >= 51000: if self.mainConf.verQtValue >= 51000:
+9 -4
View File
@@ -286,8 +286,8 @@ class GuiProjectTree(QTreeWidget):
return True return True
# This is a new files, so let's add some content # This is a new files, so let's add some content
newDoc = NWDoc(self.theProject) newDoc = NWDoc(self.theProject, tHandle)
curTxt = newDoc.readDocument(tHandle) curTxt = newDoc.readDocument()
if curTxt is None: if curTxt is None:
curTxt = "" curTxt = ""
@@ -527,8 +527,13 @@ class GuiProjectTree(QTreeWidget):
if self.theParent.docEditor.theHandle == tHandle: if self.theParent.docEditor.theHandle == tHandle:
self.theParent.closeDocument() self.theParent.closeDocument()
theDoc = NWDoc(self.theProject) delDoc = NWDoc(self.theProject, tHandle)
theDoc.deleteDocument(tHandle) if not delDoc.deleteDocument():
self.makeAlert([
self.tr("Could not delete document file."), delDoc.getError()
], nwAlert.ERROR)
return False
self.theIndex.deleteHandle(tHandle) self.theIndex.deleteHandle(tHandle)
self._deleteTreeItem(tHandle) self._deleteTreeItem(tHandle)
self._setTreeChanged(True) self._setTreeChanged(True)
+2 -2
View File
@@ -173,7 +173,7 @@ class GuiBuildNovel(QDialog):
if langIdx != -1: if langIdx != -1:
self.buildLang.setCurrentIndex(langIdx) self.buildLang.setCurrentIndex(langIdx)
# Dummy boxes due to QGridView and QLineEdit expand bug # Wrapper boxes due to QGridView and QLineEdit expand bug
self.boxTitle = QHBoxLayout() self.boxTitle = QHBoxLayout()
self.boxTitle.addWidget(self.fmtTitle) self.boxTitle.addWidget(self.fmtTitle)
self.boxChapter = QHBoxLayout() self.boxChapter = QHBoxLayout()
@@ -245,7 +245,7 @@ class GuiBuildNovel(QDialog):
self.optState.getFloat("GuiBuildNovel", "lineHeight", 1.15) self.optState.getFloat("GuiBuildNovel", "lineHeight", 1.15)
) )
# Dummy box due to QGridView and QLineEdit expand bug # Wrapper box due to QGridView and QLineEdit expand bug
self.boxFont = QHBoxLayout() self.boxFont = QHBoxLayout()
self.boxFont.addWidget(self.textFont) self.boxFont.addWidget(self.textFont)
+6 -6
View File
@@ -25,7 +25,7 @@ import pytest
import shutil import shutil
import os import os
from dummy import DummyMain from mock import MockGuiMain
from tools import cleanProject from tools import cleanProject
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))
@@ -136,12 +136,12 @@ def fncConf(fncDir):
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def dummyGUI(monkeypatch, tmpConf): def dummyGUI(monkeypatch, tmpConf):
"""Create a dummy instance of novelWriter's main GUI class. """Create a mock instance of novelWriter's main GUI class.
""" """
monkeypatch.setattr("nw.CONFIG", tmpConf) monkeypatch.setattr("nw.CONFIG", tmpConf)
theDummy = DummyMain() theGui = MockGuiMain()
theDummy.mainConf = tmpConf theGui.mainConf = tmpConf
return theDummy return theGui
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def nwGUI(qtbot, monkeypatch, fncDir, fncConf): def nwGUI(qtbot, monkeypatch, fncDir, fncConf):
@@ -191,7 +191,7 @@ def nwMinimal(tmpDir):
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def nwLipsum(tmpDir): def nwLipsum(tmpDir):
"""A medium sized novelWriter example project with a lot of Lorem """A medium sized novelWriter example project with a lot of Lorem
Ipsum dummy text. Ipsum text.
""" """
tstDir = os.path.dirname(__file__) tstDir = os.path.dirname(__file__)
srcDir = os.path.join(tstDir, "lipsum") srcDir = os.path.join(tstDir, "lipsum")
+12 -12
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
novelWriter Test Suite Dummy Classes novelWriter Test Suite Mocked Classes
====================================== =======================================
This file is a part of novelWriter This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen Copyright 20182021, Veronica Berglyd Olsen
@@ -24,14 +24,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
# Mock GUI # Mock GUI
# =========================================================================== # # =========================================================================== #
class DummyMain(): class MockGuiMain():
def __init__(self): def __init__(self):
self.mainConf = None self.mainConf = None
self.hasProject = True self.hasProject = True
self.theIndex = None self.theIndex = None
self.theProject = None self.theProject = None
self.statusBar = DummyStatusBar() self.statusBar = MockStatusBar()
# Test Variables # Test Variables
self.askResponse = True self.askResponse = True
@@ -79,9 +79,9 @@ class DummyMain():
self.lastAlert = "" self.lastAlert = ""
return return
# END Class DummyMain # END Class MockGuiMain
class DummyStatusBar(): class MockStatusBar():
def __init__(self): def __init__(self):
return return
@@ -89,9 +89,9 @@ class DummyStatusBar():
def setStatus(self, theText): def setStatus(self, theText):
return return
# END Class DummyStatusBar # END Class MockStatusBar
class DummyApp: class MockApp:
def __init__(self): def __init__(self):
return return
@@ -99,15 +99,15 @@ class DummyApp:
def installTranslator(self, theLang): def installTranslator(self, theLang):
return return
# END Class DummyApp # END Class MockApp
# =========================================================================== # # =========================================================================== #
# Error Functions # Error Functions
# Dummy functions that will raise errors instead. # Mock functions that will raise errors instead.
# =========================================================================== # # =========================================================================== #
def causeOSError(*args, **kwargs): def causeOSError(*args, **kwargs):
raise OSError raise OSError("OSError")
def causeException(*args, **kwargs): def causeException(*args, **kwargs):
raise Exception raise Exception("Exception")
@@ -19,9 +19,9 @@
@char: Jane @char: Jane
This is a paragraph of dummy text. This is a paragraph of nonsense text.
This is another paragraph of much longer dummy text. It is in fact 1 very very DUMB dummy text! We can also try replacing “quotes”, even single quotes are replaced. Isnt that nice? We can hyphen-ate, make dashes and even longer dashes — if we want. Ellipsis? Not a problem either … How about three hyphens — for long dash? It works too. This is another paragraph of much longer nonsense text. It is in fact 1 very very NONSENSICAL nonsense text! We can also try replacing “quotes”, even single quotes are replaced. Isnt that nice? We can hyphen-ate, make dashes and even longer dashes — if we want. Ellipsis? Not a problem either … How about three hyphens — for long dash? It works too.
“Full line double quoted text.” “Full line double quoted text.”
@@ -85,10 +85,10 @@
<status>New</status> <status>New</status>
<exported>True</exported> <exported>True</exported>
<layout>BOOK</layout> <layout>BOOK</layout>
<charCount>466</charCount> <charCount>482</charCount>
<wordCount>83</wordCount> <wordCount>83</wordCount>
<paraCount>4</paraCount> <paraCount>4</paraCount>
<cursorPos>604</cursorPos> <cursorPos>620</cursorPos>
</item> </item>
<item handle="44cb730c42048" order="1" parent="None"> <item handle="44cb730c42048" order="1" parent="None">
<name>Plot</name> <name>Plot</name>
@@ -1,53 +0,0 @@
%%~name: Chapter One
%%~path: b3643d0f92e32/73475cb40a568
%%~kind: NOVEL/SCENE
## Chapter One
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam. Praesent magna nunc, lacinia sit amet quam eget, aliquet ultrices justo. Morbi ornare enim et lorem rutrum finibus ut eu dolor. Aliquam a orci odio. Ut ultrices sem quis massa placerat, eget mollis nisl cursus. Cras vel sagittis justo. Ut non ultricies leo. Maecenas rutrum velit in est varius, et egestas massa pulvinar.
### Scene One
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur.
Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur. Donec quis ante nunc. Mauris ut leo ipsum. Vestibulum est neque, hendrerit nec neque a, ullamcorper lobortis tellus. Fusce sollicitudin purus quis congue bibendum. Aliquam condimentum ipsum tristique blandit tristique. Donec pulvinar neque ac suscipit malesuada.
Aliquam ut nisl arcu. Ut ultricies, lorem dignissim rutrum convallis, risus orci tempus lectus, congue feugiat sem lectus vitae odio. Duis sit amet justo finibus, hendrerit nulla at, ullamcorper enim. Praesent vel tellus sit amet tellus vulputate bibendum. Morbi eleifend sagittis sem, ac volutpat ante congue non. In hac habitasse platea dictumst. Morbi lobortis fermentum elit, dignissim sagittis ligula volutpat lacinia. Vestibulum eu interdum odio. Integer ac purus commodo metus congue tempor non at urna. Sed eget tortor vel quam viverra egestas. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec non convallis mauris, ac feugiat ex.
#### Scene One, Section Two
Integer vel libero ipsum. Donec varius aliquam libero, sit amet commodo urna hendrerit non. Nullam quis erat mollis nunc viverra volutpat tincidunt in odio. Nam vitae quam sem. Aliquam suscipit nulla non lorem pharetra semper. Ut suscipit erat eu ligula accumsan ultrices. Phasellus nisl tellus, placerat sed laoreet id, consectetur nec dolor. Sed fringilla ipsum id dapibus posuere. Aenean finibus pharetra tincidunt. Ut molestie malesuada nulla, id posuere lorem tincidunt eu. Aliquam tempor eros a est vulputate, scelerisque pulvinar ipsum fermentum. In hac habitasse platea dictumst.
Curabitur congue, justo quis interdum fermentum, tellus nulla imperdiet sapien, eu interdum enim tellus condimentum metus. Vivamus nunc velit, dignissim ut ultrices sit amet, ultricies quis enim. Donec ut vestibulum neque. Vivamus semper neque id ex ullamcorper varius. Fusce mattis nibh viverra lorem sagittis, et tempor arcu congue. Suspendisse sit amet felis sed urna facilisis mattis eget vitae arcu. Proin eu magna hendrerit, tristique sem maximus, placerat diam. Nulla tristique sed velit sit amet varius. Etiam vel ornare magna, in vulputate arcu. Cras velit orci, tincidunt sed volutpat cursus, bibendum vel sem. Nunc vulputate pharetra tortor, ac consectetur neque tincidunt sit amet. Nulla ornare mi sed mi dignissim ultricies. Ut tincidunt bibendum mauris, sed elementum ex vulputate vel. Mauris fermentum, felis nec vehicula congue, felis lorem facilisis erat, a dictum dolor augue vitae quam. Maecenas rutrum tortor nec consequat eleifend.
### Scene Two
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci. Vestibulum facilisis bibendum aliquam. Aliquam posuere, turpis ac bibendum varius, sem tellus venenatis risus, in elementum massa enim ac lorem. Integer in sem ac diam blandit ultricies ut in nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam sit amet erat est. Curabitur vitae cursus justo, sit amet placerat dolor. Vivamus eu felis hendrerit, tincidunt massa rutrum, maximus arcu. Pellentesque commodo justo odio, vel rutrum nulla tincidunt eu. Integer non neque condimentum, convallis diam non, varius ligula. Aliquam eget sapien mauris. Aenean pharetra nunc nisi, vel maximus ante tristique sit amet. Aliquam risus metus, interdum non odio eu, consectetur lacinia sapien.
Proin vitae gravida nisl. Integer viverra orci turpis, sit amet pretium ligula facilisis consequat. Nulla interdum commodo metus, mollis consequat dui tincidunt et. Proin consequat bibendum justo id commodo. Fusce fermentum nunc turpis, eu vestibulum risus feugiat ut. Sed scelerisque vel ligula ut interdum. Suspendisse ac blandit ligula, sagittis fringilla dolor. In tincidunt convallis diam et ornare. Aenean id dignissim est, ut rhoncus quam. Donec vitae nisl velit. In convallis nibh ut augue dignissim, eu elementum quam cursus. Phasellus in lectus lorem. Curabitur in pellentesque nisi, at gravida sapien. Sed cursus justo volutpat lacus placerat, sit amet dignissim turpis commodo. Aliquam vitae orci eget nulla posuere condimentum in ut felis.
Nulla accumsan ante in pulvinar efficitur. Nulla non velit quis urna hendrerit bibendum. Suspendisse ultrices ante eu justo malesuada, sed fermentum enim rutrum. Nunc fermentum pharetra felis, vitae sollicitudin quam rutrum porta. Aliquam fringilla velit a mi laoreet, et luctus est rutrum. In gravida non ipsum sit amet tempus. Curabitur et eleifend purus. Nulla facilisi.
#### Scene Two, Section Two
Suspendisse potenti. Fusce tempus lorem nec laoreet suscipit. Fusce vulputate nisl ac diam tincidunt, nec malesuada quam pellentesque. Maecenas congue, tellus quis commodo rutrum, magna leo egestas arcu, quis suscipit ex risus id ligula. Suspendisse potenti. Morbi blandit lacus vitae laoreet vulputate. Donec vitae tellus eleifend, lobortis eros eu, tincidunt enim. Nullam et ullamcorper nisi. Vivamus tellus ex, lobortis quis rutrum ut, dapibus sit amet turpis. Phasellus pellentesque metus diam, commodo tristique ante commodo ac. Ut mollis ipsum nec diam blandit sollicitudin. Duis bibendum lacus nec commodo dapibus. Sed condimentum luctus ante, id ultricies urna varius nec. Nam convallis magna nec bibendum ultrices. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed auctor pharetra quam, vitae porta ex bibendum eu.
Vivamus ut venenatis lectus. Phasellus nec elit id sem dictum ornare. Quisque feugiat, diam eget sagittis ultricies, orci turpis efficitur nisi, et fringilla justo odio nec nibh. In hac habitasse platea dictumst. Sed tempus bibendum feugiat. Etiam luctus mauris arcu, non interdum ipsum ultrices id. Vivamus blandit urna sit amet scelerisque vulputate. Quisque in metus eget massa rutrum dictum sit amet sed nulla. Vivamus vel efficitur dolor.
Ut et consequat enim, quis ornare nibh. In lectus neque, mollis et suscipit et, vestibulum vitae augue. Praesent id ante sit amet odio venenatis placerat a at erat. Sed sed metus sed nisi dictum varius. Integer tincidunt fermentum purus ac porta. Fusce porttitor non risus eget tristique. Donec augue nunc, maximus at fermentum vel, varius et neque. Ut sed consectetur mauris. Quisque ipsum enim, porttitor vitae imperdiet sit amet, tempor et mauris. Aliquam malesuada tincidunt lectus quis blandit. Sed commodo orci felis, quis ultrices tellus facilisis sed. Nunc vel varius est. Duis ullamcorper eu metus in pulvinar. Morbi at sapien dictum, rutrum mauris eget, interdum tellus.
@@ -1,15 +0,0 @@
%%~name: Scene One
%%~path: 0e17daca5f3e1/031b4af5197ec
%%~kind: NOVEL/SCENE
### Scene One
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur.
Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur. Donec quis ante nunc. Mauris ut leo ipsum. Vestibulum est neque, hendrerit nec neque a, ullamcorper lobortis tellus. Fusce sollicitudin purus quis congue bibendum. Aliquam condimentum ipsum tristique blandit tristique. Donec pulvinar neque ac suscipit malesuada.
Aliquam ut nisl arcu. Ut ultricies, lorem dignissim rutrum convallis, risus orci tempus lectus, congue feugiat sem lectus vitae odio. Duis sit amet justo finibus, hendrerit nulla at, ullamcorper enim. Praesent vel tellus sit amet tellus vulputate bibendum. Morbi eleifend sagittis sem, ac volutpat ante congue non. In hac habitasse platea dictumst. Morbi lobortis fermentum elit, dignissim sagittis ligula volutpat lacinia. Vestibulum eu interdum odio. Integer ac purus commodo metus congue tempor non at urna. Sed eget tortor vel quam viverra egestas. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec non convallis mauris, ac feugiat ex.
@@ -1,13 +0,0 @@
%%~name: Chapter One
%%~path: 811786ad1ae74/25fc0e7096fc6
%%~kind: NOVEL/CHAPTER
## Chapter One
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam. Praesent magna nunc, lacinia sit amet quam eget, aliquet ultrices justo. Morbi ornare enim et lorem rutrum finibus ut eu dolor. Aliquam a orci odio. Ut ultrices sem quis massa placerat, eget mollis nisl cursus. Cras vel sagittis justo. Ut non ultricies leo. Maecenas rutrum velit in est varius, et egestas massa pulvinar.
@@ -1,17 +0,0 @@
%%~name: Scene Two
%%~path: 0e17daca5f3e1/2858dcd1057d3
%%~kind: NOVEL/SCENE
### Scene Two
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci. Vestibulum facilisis bibendum aliquam. Aliquam posuere, turpis ac bibendum varius, sem tellus venenatis risus, in elementum massa enim ac lorem. Integer in sem ac diam blandit ultricies ut in nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam sit amet erat est. Curabitur vitae cursus justo, sit amet placerat dolor. Vivamus eu felis hendrerit, tincidunt massa rutrum, maximus arcu. Pellentesque commodo justo odio, vel rutrum nulla tincidunt eu. Integer non neque condimentum, convallis diam non, varius ligula. Aliquam eget sapien mauris. Aenean pharetra nunc nisi, vel maximus ante tristique sit amet. Aliquam risus metus, interdum non odio eu, consectetur lacinia sapien.
Proin vitae gravida nisl. Integer viverra orci turpis, sit amet pretium ligula facilisis consequat. Nulla interdum commodo metus, mollis consequat dui tincidunt et. Proin consequat bibendum justo id commodo. Fusce fermentum nunc turpis, eu vestibulum risus feugiat ut. Sed scelerisque vel ligula ut interdum. Suspendisse ac blandit ligula, sagittis fringilla dolor. In tincidunt convallis diam et ornare. Aenean id dignissim est, ut rhoncus quam. Donec vitae nisl velit. In convallis nibh ut augue dignissim, eu elementum quam cursus. Phasellus in lectus lorem. Curabitur in pellentesque nisi, at gravida sapien. Sed cursus justo volutpat lacus placerat, sit amet dignissim turpis commodo. Aliquam vitae orci eget nulla posuere condimentum in ut felis.
Nulla accumsan ante in pulvinar efficitur. Nulla non velit quis urna hendrerit bibendum. Suspendisse ultrices ante eu justo malesuada, sed fermentum enim rutrum. Nunc fermentum pharetra felis, vitae sollicitudin quam rutrum porta. Aliquam fringilla velit a mi laoreet, et luctus est rutrum. In gravida non ipsum sit amet tempus. Curabitur et eleifend purus. Nulla facilisi.
@@ -1,11 +0,0 @@
%%~name: Scene Two, Section Two
%%~path: 0e17daca5f3e1/2fca346db6561
%%~kind: NOVEL/SCENE
#### Scene Two, Section Two
Suspendisse potenti. Fusce tempus lorem nec laoreet suscipit. Fusce vulputate nisl ac diam tincidunt, nec malesuada quam pellentesque. Maecenas congue, tellus quis commodo rutrum, magna leo egestas arcu, quis suscipit ex risus id ligula. Suspendisse potenti. Morbi blandit lacus vitae laoreet vulputate. Donec vitae tellus eleifend, lobortis eros eu, tincidunt enim. Nullam et ullamcorper nisi. Vivamus tellus ex, lobortis quis rutrum ut, dapibus sit amet turpis. Phasellus pellentesque metus diam, commodo tristique ante commodo ac. Ut mollis ipsum nec diam blandit sollicitudin. Duis bibendum lacus nec commodo dapibus. Sed condimentum luctus ante, id ultricies urna varius nec. Nam convallis magna nec bibendum ultrices. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed auctor pharetra quam, vitae porta ex bibendum eu.
Vivamus ut venenatis lectus. Phasellus nec elit id sem dictum ornare. Quisque feugiat, diam eget sagittis ultricies, orci turpis efficitur nisi, et fringilla justo odio nec nibh. In hac habitasse platea dictumst. Sed tempus bibendum feugiat. Etiam luctus mauris arcu, non interdum ipsum ultrices id. Vivamus blandit urna sit amet scelerisque vulputate. Quisque in metus eget massa rutrum dictum sit amet sed nulla. Vivamus vel efficitur dolor.
Ut et consequat enim, quis ornare nibh. In lectus neque, mollis et suscipit et, vestibulum vitae augue. Praesent id ante sit amet odio venenatis placerat a at erat. Sed sed metus sed nisi dictum varius. Integer tincidunt fermentum purus ac porta. Fusce porttitor non risus eget tristique. Donec augue nunc, maximus at fermentum vel, varius et neque. Ut sed consectetur mauris. Quisque ipsum enim, porttitor vitae imperdiet sit amet, tempor et mauris. Aliquam malesuada tincidunt lectus quis blandit. Sed commodo orci felis, quis ultrices tellus facilisis sed. Nunc vel varius est. Duis ullamcorper eu metus in pulvinar. Morbi at sapien dictum, rutrum mauris eget, interdum tellus.
@@ -1,21 +0,0 @@
%%~name: Scene One
%%~path: 811786ad1ae74/31489056e0916
%%~kind: NOVEL/SCENE
### Scene One
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur.
Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur. Donec quis ante nunc. Mauris ut leo ipsum. Vestibulum est neque, hendrerit nec neque a, ullamcorper lobortis tellus. Fusce sollicitudin purus quis congue bibendum. Aliquam condimentum ipsum tristique blandit tristique. Donec pulvinar neque ac suscipit malesuada.
Aliquam ut nisl arcu. Ut ultricies, lorem dignissim rutrum convallis, risus orci tempus lectus, congue feugiat sem lectus vitae odio. Duis sit amet justo finibus, hendrerit nulla at, ullamcorper enim. Praesent vel tellus sit amet tellus vulputate bibendum. Morbi eleifend sagittis sem, ac volutpat ante congue non. In hac habitasse platea dictumst. Morbi lobortis fermentum elit, dignissim sagittis ligula volutpat lacinia. Vestibulum eu interdum odio. Integer ac purus commodo metus congue tempor non at urna. Sed eget tortor vel quam viverra egestas. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec non convallis mauris, ac feugiat ex.
#### Scene One, Section Two
Integer vel libero ipsum. Donec varius aliquam libero, sit amet commodo urna hendrerit non. Nullam quis erat mollis nunc viverra volutpat tincidunt in odio. Nam vitae quam sem. Aliquam suscipit nulla non lorem pharetra semper. Ut suscipit erat eu ligula accumsan ultrices. Phasellus nisl tellus, placerat sed laoreet id, consectetur nec dolor. Sed fringilla ipsum id dapibus posuere. Aenean finibus pharetra tincidunt. Ut molestie malesuada nulla, id posuere lorem tincidunt eu. Aliquam tempor eros a est vulputate, scelerisque pulvinar ipsum fermentum. In hac habitasse platea dictumst.
Curabitur congue, justo quis interdum fermentum, tellus nulla imperdiet sapien, eu interdum enim tellus condimentum metus. Vivamus nunc velit, dignissim ut ultrices sit amet, ultricies quis enim. Donec ut vestibulum neque. Vivamus semper neque id ex ullamcorper varius. Fusce mattis nibh viverra lorem sagittis, et tempor arcu congue. Suspendisse sit amet felis sed urna facilisis mattis eget vitae arcu. Proin eu magna hendrerit, tristique sem maximus, placerat diam. Nulla tristique sed velit sit amet varius. Etiam vel ornare magna, in vulputate arcu. Cras velit orci, tincidunt sed volutpat cursus, bibendum vel sem. Nunc vulputate pharetra tortor, ac consectetur neque tincidunt sit amet. Nulla ornare mi sed mi dignissim ultricies. Ut tincidunt bibendum mauris, sed elementum ex vulputate vel. Mauris fermentum, felis nec vehicula congue, felis lorem facilisis erat, a dictum dolor augue vitae quam. Maecenas rutrum tortor nec consequat eleifend.
@@ -1,9 +0,0 @@
%%~name: Scene One, Section Two
%%~path: 0e17daca5f3e1/41cfc0d1f2d12
%%~kind: NOVEL/SCENE
#### Scene One, Section Two
Integer vel libero ipsum. Donec varius aliquam libero, sit amet commodo urna hendrerit non. Nullam quis erat mollis nunc viverra volutpat tincidunt in odio. Nam vitae quam sem. Aliquam suscipit nulla non lorem pharetra semper. Ut suscipit erat eu ligula accumsan ultrices. Phasellus nisl tellus, placerat sed laoreet id, consectetur nec dolor. Sed fringilla ipsum id dapibus posuere. Aenean finibus pharetra tincidunt. Ut molestie malesuada nulla, id posuere lorem tincidunt eu. Aliquam tempor eros a est vulputate, scelerisque pulvinar ipsum fermentum. In hac habitasse platea dictumst.
Curabitur congue, justo quis interdum fermentum, tellus nulla imperdiet sapien, eu interdum enim tellus condimentum metus. Vivamus nunc velit, dignissim ut ultrices sit amet, ultricies quis enim. Donec ut vestibulum neque. Vivamus semper neque id ex ullamcorper varius. Fusce mattis nibh viverra lorem sagittis, et tempor arcu congue. Suspendisse sit amet felis sed urna facilisis mattis eget vitae arcu. Proin eu magna hendrerit, tristique sem maximus, placerat diam. Nulla tristique sed velit sit amet varius. Etiam vel ornare magna, in vulputate arcu. Cras velit orci, tincidunt sed volutpat cursus, bibendum vel sem. Nunc vulputate pharetra tortor, ac consectetur neque tincidunt sit amet. Nulla ornare mi sed mi dignissim ultricies. Ut tincidunt bibendum mauris, sed elementum ex vulputate vel. Mauris fermentum, felis nec vehicula congue, felis lorem facilisis erat, a dictum dolor augue vitae quam. Maecenas rutrum tortor nec consequat eleifend.
@@ -1,25 +0,0 @@
%%~name: Scene Two
%%~path: 811786ad1ae74/98010bd9270f9
%%~kind: NOVEL/SCENE
### Scene Two
@pov: Bod
@plot: Main
@location: Europe
% Synopsis: Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci. Vestibulum facilisis bibendum aliquam. Aliquam posuere, turpis ac bibendum varius, sem tellus venenatis risus, in elementum massa enim ac lorem. Integer in sem ac diam blandit ultricies ut in nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam sit amet erat est. Curabitur vitae cursus justo, sit amet placerat dolor. Vivamus eu felis hendrerit, tincidunt massa rutrum, maximus arcu. Pellentesque commodo justo odio, vel rutrum nulla tincidunt eu. Integer non neque condimentum, convallis diam non, varius ligula. Aliquam eget sapien mauris. Aenean pharetra nunc nisi, vel maximus ante tristique sit amet. Aliquam risus metus, interdum non odio eu, consectetur lacinia sapien.
Proin vitae gravida nisl. Integer viverra orci turpis, sit amet pretium ligula facilisis consequat. Nulla interdum commodo metus, mollis consequat dui tincidunt et. Proin consequat bibendum justo id commodo. Fusce fermentum nunc turpis, eu vestibulum risus feugiat ut. Sed scelerisque vel ligula ut interdum. Suspendisse ac blandit ligula, sagittis fringilla dolor. In tincidunt convallis diam et ornare. Aenean id dignissim est, ut rhoncus quam. Donec vitae nisl velit. In convallis nibh ut augue dignissim, eu elementum quam cursus. Phasellus in lectus lorem. Curabitur in pellentesque nisi, at gravida sapien. Sed cursus justo volutpat lacus placerat, sit amet dignissim turpis commodo. Aliquam vitae orci eget nulla posuere condimentum in ut felis.
Nulla accumsan ante in pulvinar efficitur. Nulla non velit quis urna hendrerit bibendum. Suspendisse ultrices ante eu justo malesuada, sed fermentum enim rutrum. Nunc fermentum pharetra felis, vitae sollicitudin quam rutrum porta. Aliquam fringilla velit a mi laoreet, et luctus est rutrum. In gravida non ipsum sit amet tempus. Curabitur et eleifend purus. Nulla facilisi.
#### Scene Two, Section Two
Suspendisse potenti. Fusce tempus lorem nec laoreet suscipit. Fusce vulputate nisl ac diam tincidunt, nec malesuada quam pellentesque. Maecenas congue, tellus quis commodo rutrum, magna leo egestas arcu, quis suscipit ex risus id ligula. Suspendisse potenti. Morbi blandit lacus vitae laoreet vulputate. Donec vitae tellus eleifend, lobortis eros eu, tincidunt enim. Nullam et ullamcorper nisi. Vivamus tellus ex, lobortis quis rutrum ut, dapibus sit amet turpis. Phasellus pellentesque metus diam, commodo tristique ante commodo ac. Ut mollis ipsum nec diam blandit sollicitudin. Duis bibendum lacus nec commodo dapibus. Sed condimentum luctus ante, id ultricies urna varius nec. Nam convallis magna nec bibendum ultrices. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed auctor pharetra quam, vitae porta ex bibendum eu.
Vivamus ut venenatis lectus. Phasellus nec elit id sem dictum ornare. Quisque feugiat, diam eget sagittis ultricies, orci turpis efficitur nisi, et fringilla justo odio nec nibh. In hac habitasse platea dictumst. Sed tempus bibendum feugiat. Etiam luctus mauris arcu, non interdum ipsum ultrices id. Vivamus blandit urna sit amet scelerisque vulputate. Quisque in metus eget massa rutrum dictum sit amet sed nulla. Vivamus vel efficitur dolor.
Ut et consequat enim, quis ornare nibh. In lectus neque, mollis et suscipit et, vestibulum vitae augue. Praesent id ante sit amet odio venenatis placerat a at erat. Sed sed metus sed nisi dictum varius. Integer tincidunt fermentum purus ac porta. Fusce porttitor non risus eget tristique. Donec augue nunc, maximus at fermentum vel, varius et neque. Ut sed consectetur mauris. Quisque ipsum enim, porttitor vitae imperdiet sit amet, tempor et mauris. Aliquam malesuada tincidunt lectus quis blandit. Sed commodo orci felis, quis ultrices tellus facilisis sed. Nunc vel varius est. Duis ullamcorper eu metus in pulvinar. Morbi at sapien dictum, rutrum mauris eget, interdum tellus.
+6 -6
View File
@@ -27,7 +27,7 @@ import configparser
from shutil import copyfile from shutil import copyfile
from dummy import causeOSError, DummyApp from mock import causeOSError, MockApp
from tools import cmpFiles, writeFile from tools import cmpFiles, writeFile
from nw.config import Config from nw.config import Config
@@ -195,7 +195,7 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
writeFile(os.path.join(i18nDir, "nw_en_GB.ts"), "") writeFile(os.path.join(i18nDir, "nw_en_GB.ts"), "")
writeFile(os.path.join(i18nDir, "nw_abcd.qm"), "") writeFile(os.path.join(i18nDir, "nw_abcd.qm"), "")
tstApp = DummyApp() tstApp = MockApp()
tstConf.initLocalisation(tstApp) tstConf.initLocalisation(tstApp)
theList = tstConf.listLanguages(tstConf.LANG_NW) theList = tstConf.listLanguages(tstConf.LANG_NW)
assert theList == [("en_GB", "British English")] assert theList == [("en_GB", "British English")]
@@ -252,7 +252,7 @@ def testBaseConfig_RecentCache(monkeypatch, tmpConf, tmpDir, fncDir):
} }
# Remove Non-Existent Entry # Remove Non-Existent Entry
assert not tmpConf.removeFromRecentCache("dummy") assert not tmpConf.removeFromRecentCache("stuff")
assert tmpConf.recentProj == { assert tmpConf.recentProj == {
pathOne: {"time": 1600002000, "title": "Proj One", "words": 100}, pathOne: {"time": 1600002000, "title": "Proj One", "words": 100},
pathTwo: {"time": 1600005600, "title": "Proj Two", "words": 200}, pathTwo: {"time": 1600005600, "title": "Proj Two", "words": 200},
@@ -490,7 +490,7 @@ def testBaseConfig_Internal(monkeypatch, tmpConf):
cnfParse = configparser.ConfigParser() cnfParse = configparser.ConfigParser()
cnfParse.read_string( cnfParse.read_string(
"[Main]\n" "[Main]\n"
"val_string = dummy\n" "val_string = stuff\n"
"val_int = 123\n" "val_int = 123\n"
"val_bool = True\n" "val_bool = True\n"
"val_list_string = A, B, C\n" "val_list_string = A, B, C\n"
@@ -499,7 +499,7 @@ def testBaseConfig_Internal(monkeypatch, tmpConf):
assert tmpConf._parseLine( assert tmpConf._parseLine(
cnfParse, "Main", "val_string", tmpConf.CNF_STR, "default" cnfParse, "Main", "val_string", tmpConf.CNF_STR, "default"
) == "dummy" ) == "stuff"
assert tmpConf._parseLine( assert tmpConf._parseLine(
cnfParse, "Main", "nope", tmpConf.CNF_STR, "default" cnfParse, "Main", "nope", tmpConf.CNF_STR, "default"
) == "default" ) == "default"
@@ -554,7 +554,7 @@ def testBaseConfig_Internal(monkeypatch, tmpConf):
assert tmpConf.hasEnchant is False assert tmpConf.hasEnchant is False
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setattr("shutil.which", lambda *args: "dummy") mp.setattr("shutil.which", lambda *args: "stuff")
tmpConf._checkOptionalPackages() tmpConf._checkOptionalPackages()
assert tmpConf.hasAssistant is True assert tmpConf.hasAssistant is True
+1 -1
View File
@@ -25,7 +25,7 @@ import pytest
from PyQt5.QtWidgets import qApp from PyQt5.QtWidgets import qApp
from dummy import causeException from mock import causeException
from nw.error import NWErrorMessage, exceptionHandler from nw.error import NWErrorMessage, exceptionHandler
+6 -6
View File
@@ -25,19 +25,19 @@ import pytest
import logging import logging
import sys import sys
from dummy import DummyMain from mock import MockGuiMain
@pytest.mark.base @pytest.mark.base
def testBaseInit_Launch(caplog, monkeypatch, tmpDir): def testBaseInit_Launch(caplog, monkeypatch, tmpDir):
"""Check launching the main GUI. """Check launching the main GUI.
""" """
monkeypatch.setattr("nw.guimain.GuiMain", DummyMain) monkeypatch.setattr("nw.guimain.GuiMain", MockGuiMain)
# Testmode launch # Testmode launch
nwGUI = nw.main( nwGUI = nw.main(
["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir]
) )
assert isinstance(nwGUI, DummyMain) assert isinstance(nwGUI, MockGuiMain)
# Darwin launch # Darwin launch
monkeypatch.setitem(sys.modules, "Foundation", None) monkeypatch.setitem(sys.modules, "Foundation", None)
@@ -46,7 +46,7 @@ def testBaseInit_Launch(caplog, monkeypatch, tmpDir):
nwGUI = nw.main( nwGUI = nw.main(
["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir]
) )
assert isinstance(nwGUI, DummyMain) assert isinstance(nwGUI, MockGuiMain)
assert "Foundation" in caplog.messages[1] assert "Foundation" in caplog.messages[1]
nw.CONFIG.osDarwin = osDarwin nw.CONFIG.osDarwin = osDarwin
@@ -68,7 +68,7 @@ def testBaseInit_Launch(caplog, monkeypatch, tmpDir):
def testBaseInit_Options(monkeypatch, tmpDir): def testBaseInit_Options(monkeypatch, tmpDir):
"""Test command line options for logging level. """Test command line options for logging level.
""" """
monkeypatch.setattr("nw.guimain.GuiMain", DummyMain) monkeypatch.setattr("nw.guimain.GuiMain", MockGuiMain)
monkeypatch.setattr(sys, "argv", [ monkeypatch.setattr(sys, "argv", [
"novelWriter.py", "--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir "novelWriter.py", "--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir
]) ])
@@ -140,7 +140,7 @@ def testBaseInit_Options(monkeypatch, tmpDir):
def testBaseInit_Imports(caplog, monkeypatch, tmpDir): def testBaseInit_Imports(caplog, monkeypatch, tmpDir):
"""Check import error handling. """Check import error handling.
""" """
monkeypatch.setattr("nw.guimain.GuiMain", DummyMain) monkeypatch.setattr("nw.guimain.GuiMain", MockGuiMain)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *args: None) monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *args: None)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *args: 0) monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *args: 0)
monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.__init__", lambda *args: None) monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.__init__", lambda *args: None)
+26 -24
View File
@@ -23,10 +23,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import os import os
import pytest import pytest
from dummy import causeOSError from mock import causeOSError
from nw.core import NWProject, NWDoc from nw.core import NWProject, NWDoc
from nw.core.item import NWItem
from nw.enum import nwItemClass, nwItemLayout from nw.enum import nwItemClass, nwItemLayout
@pytest.mark.core @pytest.mark.core
@@ -37,39 +36,37 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal):
assert theProject.openProject(nwMinimal) assert theProject.openProject(nwMinimal)
assert theProject.projPath == nwMinimal assert theProject.projPath == nwMinimal
theDoc = NWDoc(theProject)
sHandle = "8c659a11cd429" sHandle = "8c659a11cd429"
# Not a valid handle # Not a valid handle
assert theDoc.readDocument("dummy") is None theDoc = NWDoc(theProject, "stuff")
assert theDoc.readDocument() is None
# Non-existent handle # Non-existent handle
assert theDoc.readDocument("0000000000000") is None theDoc = NWDoc(theProject, "0000000000000")
assert theDoc.readDocument() is None
# Cause open() to fail while loading # Cause open() to fail while loading
def dummyOpen(*args, **kwargs):
raise OSError
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setattr("builtins.open", dummyOpen) mp.setattr("builtins.open", causeOSError)
assert theDoc.readDocument(sHandle) is None theDoc = NWDoc(theProject, sHandle)
assert theDoc.readDocument() is None
assert theDoc.getError() == "OSError"
# Load the text # Load the text
assert theDoc.readDocument(sHandle) == "### New Scene\n\n" theDoc = NWDoc(theProject, sHandle)
assert theDoc.readDocument() == "### New Scene\n\n"
# Try to open a new (non-existent) file # Try to open a new (non-existent) file
nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL) nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL)
assert nHandle is not None assert nHandle is not None
xHandle = theProject.newFile("New File", nwItemClass.NOVEL, nHandle) xHandle = theProject.newFile("New File", nwItemClass.NOVEL, nHandle)
assert theDoc.readDocument(xHandle) == "" theDoc = NWDoc(theProject, xHandle)
assert theDoc.readDocument() == ""
# Check cached item
assert isinstance(theDoc._theItem, NWItem)
assert theDoc.readDocument(xHandle, isOrphan=True) == ""
assert theDoc._theItem is None
# Set handle and save again # Set handle and save again
theText = "### Test File\n\nText ...\n\n" theText = "### Test File\n\nText ...\n\n"
theDoc = NWDoc(theProject, xHandle)
assert theDoc.readDocument(xHandle) == "" assert theDoc.readDocument(xHandle) == ""
assert theDoc.writeDocument(theText) assert theDoc.writeDocument(theText)
@@ -98,22 +95,27 @@ def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal):
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setattr("builtins.open", causeOSError) mp.setattr("builtins.open", causeOSError)
assert not theDoc.writeDocument(theText) assert not theDoc.writeDocument(theText)
assert theDoc.getError() == "OSError"
# Saving with no handle # Saving with no handle
theDoc.clearDocument() theDoc._docHandle = None
assert not theDoc.writeDocument(theText) assert not theDoc.writeDocument(theText)
# Delete the last document # Delete the last document
assert not theDoc.deleteDocument("dummy") theDoc = NWDoc(theProject, "stuff")
assert not theDoc.deleteDocument()
assert os.path.isfile(docPath) assert os.path.isfile(docPath)
# Cause the delete to fail # Cause the delete to fail
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setattr("os.unlink", causeOSError) mp.setattr("os.unlink", causeOSError)
assert not theDoc.deleteDocument(xHandle) theDoc = NWDoc(theProject, xHandle)
assert not theDoc.deleteDocument()
assert theDoc.getError() == "OSError"
# Make the delete pass # Make the delete pass
assert theDoc.deleteDocument(xHandle) theDoc = NWDoc(theProject, xHandle)
assert theDoc.deleteDocument()
assert not os.path.isfile(docPath) assert not os.path.isfile(docPath)
# END Test testCoreDocument_Load # END Test testCoreDocument_Load
@@ -126,11 +128,11 @@ def testCoreDocument_Methods(monkeypatch, dummyGUI, nwMinimal):
assert theProject.openProject(nwMinimal) assert theProject.openProject(nwMinimal)
assert theProject.projPath == nwMinimal assert theProject.projPath == nwMinimal
theDoc = NWDoc(theProject)
sHandle = "8c659a11cd429" sHandle = "8c659a11cd429"
theDoc = NWDoc(theProject, sHandle)
docPath = os.path.join(nwMinimal, "content", sHandle+".nwd") docPath = os.path.join(nwMinimal, "content", sHandle+".nwd")
assert theDoc.readDocument(sHandle) == "### New Scene\n\n" assert theDoc.readDocument() == "### New Scene\n\n"
# Check location # Check location
assert theDoc.getFileLocation() == docPath assert theDoc.getFileLocation() == docPath
@@ -158,6 +160,6 @@ def testCoreDocument_Methods(monkeypatch, dummyGUI, nwMinimal):
"Text ...\n\n" "Text ...\n\n"
) )
assert theDoc.readDocument(sHandle) == "### Test File\n\nText ...\n\n" assert theDoc.readDocument() == "### Test File\n\nText ...\n\n"
# END Test testCoreDocument_Methods # END Test testCoreDocument_Methods
+1 -1
View File
@@ -26,7 +26,7 @@ import json
from shutil import copyfile from shutil import copyfile
from dummy import causeException from mock import causeException
from tools import cmpFiles from tools import cmpFiles
from nw.core.project import NWProject from nw.core.project import NWProject
+1 -1
View File
@@ -24,7 +24,7 @@ import os
import json import json
import pytest import pytest
from dummy import causeOSError from mock import causeOSError
from nw.core import NWProject from nw.core import NWProject
from nw.core.options import OptionState from nw.core.options import OptionState
+18 -18
View File
@@ -28,7 +28,7 @@ from zipfile import ZipFile
from lxml import etree from lxml import etree
from tools import cmpFiles, writeFile, readFile from tools import cmpFiles, writeFile, readFile
from dummy import causeOSError from mock import causeOSError
from nw.core.project import NWProject from nw.core.project import NWProject
from nw.enum import nwItemClass, nwItemType, nwItemLayout from nw.enum import nwItemClass, nwItemType, nwItemLayout
@@ -354,11 +354,11 @@ def testCoreProject_Open(monkeypatch, nwMinimal, dummyGUI):
oName = os.path.join(nwMinimal, nwFiles.PROJ_FILE[:-3]+"orig") oName = os.path.join(nwMinimal, nwFiles.PROJ_FILE[:-3]+"orig")
bName = os.path.join(nwMinimal, nwFiles.PROJ_FILE[:-3]+"bak") bName = os.path.join(nwMinimal, nwFiles.PROJ_FILE[:-3]+"bak")
os.rename(rName, oName) os.rename(rName, oName)
writeFile(rName, "dummy") writeFile(rName, "stuff")
assert theProject.openProject(nwMinimal) is False assert theProject.openProject(nwMinimal) is False
# Also write a jun XML backup file # Also write a jun XML backup file
writeFile(bName, "dummy") writeFile(bName, "stuff")
assert theProject.openProject(nwMinimal) is False assert theProject.openProject(nwMinimal) is False
# Wrong root item # Wrong root item
@@ -426,9 +426,9 @@ def testCoreProject_Open(monkeypatch, nwMinimal, dummyGUI):
os.rename(oName, rName) os.rename(oName, rName)
# Add some legacy stuff that cannot be removed # Add some legacy stuff that cannot be removed
writeFile(os.path.join(nwMinimal, "junk"), "dummy") writeFile(os.path.join(nwMinimal, "junk"), "stuff")
os.mkdir(os.path.join(nwMinimal, "data_0")) os.mkdir(os.path.join(nwMinimal, "data_0"))
writeFile(os.path.join(nwMinimal, "data_0", "junk"), "dummy") writeFile(os.path.join(nwMinimal, "data_0", "junk"), "stuff")
dummyGUI.clear() dummyGUI.clear()
assert theProject.openProject(nwMinimal) is True assert theProject.openProject(nwMinimal) is True
assert "data_0" in dummyGUI.lastAlert assert "data_0" in dummyGUI.lastAlert
@@ -559,19 +559,19 @@ def testCoreProject_Helpers(monkeypatch, fncDir, dummyGUI):
# Create a file to block meta folder # Create a file to block meta folder
metaDir = os.path.join(fncDir, "meta") metaDir = os.path.join(fncDir, "meta")
writeFile(metaDir, "dummy") writeFile(metaDir, "stuff")
assert theProject.ensureFolderStructure() is False assert theProject.ensureFolderStructure() is False
os.unlink(metaDir) os.unlink(metaDir)
# Create a file to block cache folder # Create a file to block cache folder
cacheDir = os.path.join(fncDir, "cache") cacheDir = os.path.join(fncDir, "cache")
writeFile(cacheDir, "dummy") writeFile(cacheDir, "stuff")
assert theProject.ensureFolderStructure() is False assert theProject.ensureFolderStructure() is False
os.unlink(cacheDir) os.unlink(cacheDir)
# Create a file to block content folder # Create a file to block content folder
contentDir = os.path.join(fncDir, "content") contentDir = os.path.join(fncDir, "content")
writeFile(contentDir, "dummy") writeFile(contentDir, "stuff")
assert theProject.ensureFolderStructure() is False assert theProject.ensureFolderStructure() is False
os.unlink(contentDir) os.unlink(contentDir)
@@ -977,7 +977,7 @@ def testCoreProject_OldFormat(dummyGUI, nwOldProj):
""" """
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
# Create dummy files for known legacy files # Create mock files for known legacy files
deleteFiles = [ deleteFiles = [
os.path.join(nwOldProj, "cache", "nwProject.nwx.0"), os.path.join(nwOldProj, "cache", "nwProject.nwx.0"),
os.path.join(nwOldProj, "cache", "nwProject.nwx.1"), os.path.join(nwOldProj, "cache", "nwProject.nwx.1"),
@@ -1005,7 +1005,7 @@ def testCoreProject_OldFormat(dummyGUI, nwOldProj):
os.mkdir(os.path.join(nwOldProj, "stuff")) os.mkdir(os.path.join(nwOldProj, "stuff"))
os.mkdir(os.path.join(nwOldProj, "data_1", "stuff")) os.mkdir(os.path.join(nwOldProj, "data_1", "stuff"))
# Create dummy files # Create mock files
os.mkdir(os.path.join(nwOldProj, "cache")) os.mkdir(os.path.join(nwOldProj, "cache"))
for aFile in deleteFiles: for aFile in deleteFiles:
writeFile(aFile, "Hi") writeFile(aFile, "Hi")
@@ -1071,7 +1071,7 @@ def testCoreProject_LegacyData(monkeypatch, dummyGUI, fncDir):
# Check behaviour of deprecated files function on OSError # Check behaviour of deprecated files function on OSError
tstFile = os.path.join(fncDir, "ToC.json") tstFile = os.path.join(fncDir, "ToC.json")
writeFile(tstFile, "dummy") writeFile(tstFile, "stuff")
assert os.path.isfile(tstFile) assert os.path.isfile(tstFile)
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
@@ -1083,7 +1083,7 @@ def testCoreProject_LegacyData(monkeypatch, dummyGUI, fncDir):
# Check processing non-folders # Check processing non-folders
tstFile = os.path.join(fncDir, "data_0") tstFile = os.path.join(fncDir, "data_0")
writeFile(tstFile, "dummy") writeFile(tstFile, "stuff")
assert os.path.isfile(tstFile) assert os.path.isfile(tstFile)
errList = [] errList = []
@@ -1128,12 +1128,12 @@ def testCoreProject_LegacyData(monkeypatch, dummyGUI, fncDir):
tstDoc3b = os.path.join(tstData, "tooshort003_main.bak") tstDoc3b = os.path.join(tstData, "tooshort003_main.bak")
os.mkdir(tstData) os.mkdir(tstData)
writeFile(tstDoc1m, "dummy") writeFile(tstDoc1m, "stuff")
writeFile(tstDoc1b, "dummy") writeFile(tstDoc1b, "stuff")
writeFile(tstDoc2m, "dummy") writeFile(tstDoc2m, "stuff")
writeFile(tstDoc2b, "dummy") writeFile(tstDoc2b, "stuff")
writeFile(tstDoc3m, "dummy") writeFile(tstDoc3m, "stuff")
writeFile(tstDoc3b, "dummy") writeFile(tstDoc3b, "stuff")
# Make the above fail # Make the above fail
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
+4 -4
View File
@@ -24,7 +24,7 @@ import os
import sys import sys
import pytest import pytest
from dummy import causeOSError from mock import causeOSError
from tools import readFile, writeFile from tools import readFile, writeFile
from nw.core.spellcheck import NWSpellCheck, NWSpellEnchant, NWSpellSimple from nw.core.spellcheck import NWSpellCheck, NWSpellEnchant, NWSpellSimple
@@ -38,7 +38,7 @@ def testCoreSpell_Super(monkeypatch, tmpDir):
spChk = NWSpellCheck() spChk = NWSpellCheck()
# Check that dummy functions return results that reflects that spell # Check that default functions return results that reflects that spell
# checking is effectively disabled # checking is effectively disabled
assert spChk.setLanguage("", "") is None assert spChk.setLanguage("", "") is None
assert spChk.checkWord("") assert spChk.checkWord("")
@@ -47,7 +47,7 @@ def testCoreSpell_Super(monkeypatch, tmpDir):
assert spChk.describeDict() == ("", "") assert spChk.describeDict() == ("", "")
# Add a word to the user's dictionary # Add a word to the user's dictionary
assert spChk._readProjectDictionary("dummy") is False assert spChk._readProjectDictionary("stuff") is False
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setattr("builtins.open", causeOSError) mp.setattr("builtins.open", causeOSError)
assert spChk._readProjectDictionary(wList) is False assert spChk._readProjectDictionary(wList) is False
@@ -77,7 +77,7 @@ def testCoreSpell_Enchant(monkeypatch, tmpDir):
wList = os.path.join(tmpDir, "wordlist.txt") wList = os.path.join(tmpDir, "wordlist.txt")
writeFile(wList, "a_word\nb_word\nc_word\n") writeFile(wList, "a_word\nb_word\nc_word\n")
# Block the enchant package (and trigger the dummy class) # Block the enchant package (and trigger the default class)
with monkeypatch.context() as mp: with monkeypatch.context() as mp:
mp.setitem(sys.modules, "enchant", None) mp.setitem(sys.modules, "enchant", None)
spChk = NWSpellEnchant() spChk = NWSpellEnchant()
+1 -1
View File
@@ -49,7 +49,7 @@ def testCoreStatus_Entries():
# Lookups # Lookups
assert theStatus.lookupEntry(None) is None assert theStatus.lookupEntry(None) is None
assert theStatus.lookupEntry("dummy") is None assert theStatus.lookupEntry("stuff") is None
assert theStatus.lookupEntry("Main") == 3 assert theStatus.lookupEntry("Main") == 3
# Checks # Checks
+4 -6
View File
@@ -137,23 +137,21 @@ def testCoreToken_TextOps(monkeypatch, nwMinimal, dummyGUI):
) )
docTextR = docText.replace("<A>", "this").replace("<B>", "that") docTextR = docText.replace("<A>", "this").replace("<B>", "that")
nDoc = NWDoc(theProject) nDoc = NWDoc(theProject, sHandle)
nDoc.readDocument(sHandle) assert nDoc.writeDocument(docText)
nDoc.writeDocument(docText)
nDoc.clearDocument()
theProject.setAutoReplace({"A": "this", "B": "that"}) theProject.setAutoReplace({"A": "this", "B": "that"})
assert theProject.saveProject() assert theProject.saveProject()
# Root heading # Root heading
assert theToken.addRootHeading("dummy") is False assert theToken.addRootHeading("stuff") is False
assert theToken.addRootHeading(sHandle) is False assert theToken.addRootHeading(sHandle) is False
assert theToken.addRootHeading("7695ce551d265") is True assert theToken.addRootHeading("7695ce551d265") is True
assert theToken.theMarkdown[-1] == "# Notes: Plot\n\n" assert theToken.theMarkdown[-1] == "# Notes: Plot\n\n"
# Set text # Set text
assert theToken.setText("dummy") is False assert theToken.setText("stuff") is False
assert theToken.setText(sHandle) is True assert theToken.setText(sHandle) is True
assert theToken.theText == docText assert theToken.theText == docText
+11 -11
View File
@@ -31,7 +31,7 @@ from nw.constants import nwFiles
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def dummyItems(dummyGUI): def dummyItems(dummyGUI):
"""Create a list of dummy items. """Create a list of mock items.
""" """
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
@@ -176,7 +176,7 @@ def testCoreTree_BuildTree(dummyGUI, dummyItems):
assert len(theTree) == len(dummyItems) + 1 assert len(theTree) == len(dummyItems) + 1
# Delete a non-existing item # Delete a non-existing item
del theTree["dummy"] del theTree["stuff"]
assert len(theTree) == len(dummyItems) + 1 assert len(theTree) == len(dummyItems) + 1
# Delete the last item # Delete the last item
@@ -214,7 +214,7 @@ def testCoreTree_Methods(dummyGUI, dummyItems):
assert len(theTree) == len(dummyItems) assert len(theTree) == len(dummyItems)
# Root item lookup # Root item lookup
theTree._treeRoots.append("dummy") theTree._treeRoots.append("stuff")
assert theTree.findRoot(nwItemClass.WORLD) is None assert theTree.findRoot(nwItemClass.WORLD) is None
assert theTree.findRoot(nwItemClass.NOVEL) == "a000000000001" assert theTree.findRoot(nwItemClass.NOVEL) == "a000000000001"
assert theTree.findRoot(nwItemClass.CHARACTER) == "a000000000004" assert theTree.findRoot(nwItemClass.CHARACTER) == "a000000000004"
@@ -229,16 +229,16 @@ def testCoreTree_Methods(dummyGUI, dummyItems):
assert theTree.getRootItem("b000000000001").itemHandle == "a000000000001" assert theTree.getRootItem("b000000000001").itemHandle == "a000000000001"
assert theTree.getRootItem("c000000000001").itemHandle == "a000000000001" assert theTree.getRootItem("c000000000001").itemHandle == "a000000000001"
assert theTree.getRootItem("c000000000002").itemHandle == "a000000000001" assert theTree.getRootItem("c000000000002").itemHandle == "a000000000001"
assert theTree.getRootItem("dummy") is None assert theTree.getRootItem("stuff") is None
# Get item path # Get item path
assert theTree.getItemPath("dummy") == [] assert theTree.getItemPath("stuff") == []
assert theTree.getItemPath("c000000000001") == [ assert theTree.getItemPath("c000000000001") == [
"c000000000001", "b000000000001", "a000000000001" "c000000000001", "b000000000001", "a000000000001"
] ]
# Break the folder parent handle # Break the folder parent handle
theTree["b000000000001"].itemParent = "dummy" theTree["b000000000001"].itemParent = "stuff"
assert theTree.getItemPath("c000000000001") == [ assert theTree.getItemPath("c000000000001") == [
"c000000000001", "b000000000001" "c000000000001", "b000000000001"
] ]
@@ -249,7 +249,7 @@ def testCoreTree_Methods(dummyGUI, dummyItems):
] ]
# Change file layout # Change file layout
assert not theTree.setFileItemLayout("dummy", nwItemLayout.UNNUMBERED) assert not theTree.setFileItemLayout("stuff", nwItemLayout.UNNUMBERED)
assert not theTree.setFileItemLayout("b000000000001", nwItemLayout.UNNUMBERED) assert not theTree.setFileItemLayout("b000000000001", nwItemLayout.UNNUMBERED)
assert not theTree.setFileItemLayout("c000000000001", "stuff") assert not theTree.setFileItemLayout("c000000000001", "stuff")
assert theTree.setFileItemLayout("c000000000001", nwItemLayout.UNNUMBERED) assert theTree.setFileItemLayout("c000000000001", nwItemLayout.UNNUMBERED)
@@ -424,7 +424,7 @@ def testCoreTree_Stats(dummyGUI, dummyItems):
theTree.append(tHandle, pHandle, nwItem) theTree.append(tHandle, pHandle, nwItem)
assert len(theTree) == len(dummyItems) assert len(theTree) == len(dummyItems)
theTree._treeOrder.append("dummy") theTree._treeOrder.append("stuff")
# Count Words # Count Words
novelWords, noteWords = theTree.sumWords() novelWords, noteWords = theTree.sumWords()
@@ -461,10 +461,10 @@ def testCoreTree_Reorder(dummyGUI, dummyItems):
theTree.setOrder(bHandle) theTree.setOrder(bHandle)
assert theTree.handles() == bHandle assert theTree.handles() == bHandle
theTree.setOrder(bHandle + ["dummy"]) theTree.setOrder(bHandle + ["stuff"])
assert theTree.handles() == bHandle assert theTree.handles() == bHandle
theTree._treeOrder.append("dummy") theTree._treeOrder.append("stuff")
theTree.setOrder(bHandle) theTree.setOrder(bHandle)
assert theTree.handles() == bHandle assert theTree.handles() == bHandle
@@ -536,7 +536,7 @@ def testCoreTree_ToCFile(monkeypatch, dummyGUI, dummyItems, tmpDir):
theTree.append(tHandle, pHandle, nwItem) theTree.append(tHandle, pHandle, nwItem)
assert len(theTree) == len(dummyItems) assert len(theTree) == len(dummyItems)
theTree._treeOrder.append("dummy") theTree._treeOrder.append("stuff")
def dummyIsFile(fileName): def dummyIsFile(fileName):
"""Return True for items that are files in novelWriter and """Return True for items that are files in novelWriter and
+182
View File
@@ -0,0 +1,182 @@
# -*- coding: utf-8 -*-
"""
novelWriter Merge and Split Dialog Classes Tester
===================================================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import pytest
import os
from tools import getGuiItem, readFile, writeFile
from mock import causeOSError
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog
from nw.dialogs import GuiDocMerge, GuiItemEditor
from nw.enum import nwItemType, nwWidget
from nw.core.tree import NWTree
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncDir, fncProj):
"""Test the merge documents tool.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
# Create a new project
nwGUI.theProject.projTree.setSeed(42)
assert nwGUI.newProject({"projPath": fncProj})
# Handles for new objects
hChapterDir = "31489056e0916"
hChapterOne = "98010bd9270f9"
hSceneOne = "0e17daca5f3e1"
hSceneTwo = "1a6562590ef19"
hSceneThree = "031b4af5197ec"
hSceneFour = "41cfc0d1f2d12"
hMergedDoc = "2858dcd1057d3"
# Add Project Content
monkeypatch.setattr(GuiItemEditor, "exec_", lambda *a: QDialog.Accepted)
nwGUI.switchFocus(nwWidget.TREE)
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
assert nwGUI.saveProject() is True
assert nwGUI.closeProject() is True
tChapterOne = "## Chapter One\n\n% Chapter one comment\n"
tSceneOne = "### Scene One\n\nThere once was a man from Nantucket"
tSceneTwo = "### Scene Two\n\nWho kept all his cash in a bucket."
tSceneThree = "### Scene Three\n\n\tBut his daughter, named Nan, \n\tRan away with a man"
tSceneFour = "### Scene Four\n\nAnd as for the bucket, Nantucket."
contentDir = os.path.join(fncProj, "content")
writeFile(os.path.join(contentDir, hChapterOne+".nwd"), tChapterOne)
writeFile(os.path.join(contentDir, hSceneOne+".nwd"), tSceneOne)
writeFile(os.path.join(contentDir, hSceneTwo+".nwd"), tSceneTwo)
writeFile(os.path.join(contentDir, hSceneThree+".nwd"), tSceneThree)
writeFile(os.path.join(contentDir, hSceneFour+".nwd"), tSceneFour)
assert nwGUI.openProject(fncProj) is True
# Open the Merge tool
nwGUI.switchFocus(nwWidget.TREE)
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
monkeypatch.setattr(GuiDocMerge, "exec_", lambda *a: None)
nwGUI.mainMenu.aMergeDocs.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiDocMerge") is not None, timeout=1000)
nwMerge = getGuiItem("GuiDocMerge")
assert isinstance(nwMerge, GuiDocMerge)
nwMerge.show()
qtbot.wait(stepDelay)
# Populate List
# =============
nwMerge.listBox.clear()
assert nwMerge.listBox.count() == 0
# No item selected
nwGUI.treeView.clearSelection()
assert nwMerge._populateList() is False
assert nwMerge.listBox.count() == 0
# Non-existing item
with monkeypatch.context() as mp:
mp.setattr(NWTree, "__getitem__", lambda *a: None)
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
assert nwMerge._populateList() is False
assert nwMerge.listBox.count() == 0
# Select a non-folder
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hChapterOne).setSelected(True)
assert nwMerge._populateList() is False
assert nwMerge.listBox.count() == 0
# Select the chapter folder
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
assert nwMerge._populateList() is True
assert nwMerge.listBox.count() == 5
# Merge Documents
# ===============
# First, a successful merge
with monkeypatch.context() as mp:
mp.setattr(GuiDocMerge, "_doClose", lambda *a: None)
assert nwMerge._doMerge() is True
assert nwGUI.saveProject() is True
mergedFile = os.path.join(contentDir, hMergedDoc+".nwd")
assert os.path.isfile(mergedFile)
assert readFile(mergedFile) == (
"%%%%~name: New Chapter\n"
"%%%%~path: 73475cb40a568/2858dcd1057d3\n"
"%%%%~kind: NOVEL/SCENE\n"
"%s\n\n"
"%s\n\n"
"%s\n\n"
"%s\n\n"
"%s\n\n"
) % (
tChapterOne.strip(),
tSceneOne.strip(),
tSceneTwo.strip(),
tSceneThree.strip(),
tSceneFour.strip(),
)
# OS error
with monkeypatch.context() as mp:
mp.setattr("builtins.open", causeOSError)
assert nwMerge._doMerge() is False
# Can't find the source item
with monkeypatch.context() as mp:
mp.setattr(NWTree, "__getitem__", lambda *a: None)
assert nwMerge._doMerge() is False
# No source handle set
nwMerge.sourceItem = None
assert nwMerge._doMerge() is False
# No documents to merge
nwMerge.listBox.clear()
assert nwMerge._doMerge() is False
# Close up
nwMerge._doClose()
# qtbot.stopForInteraction()
# END Test testDlgMerge_Main
-185
View File
@@ -1,185 +0,0 @@
# -*- coding: utf-8 -*-
"""
novelWriter Merge and Split Dialog Classes Tester
===================================================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import pytest
import os
from shutil import copyfile
from tools import cmpFiles, getGuiItem
from PyQt5.QtWidgets import QAction, QMessageBox
from nw.dialogs import GuiDocMerge, GuiDocSplit
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testDlgMergeSplit_Tools(qtbot, monkeypatch, nwGUI, nwLipsum, refDir, outDir):
"""Test the full merge and split tools.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes)
nwGUI.theProject.projTree.setSeed(42)
assert nwGUI.openProject(nwLipsum)
qtbot.wait(stepDelay)
assert nwGUI.treeView.setSelectedHandle("45e6b01ca35c1")
qtbot.wait(stepDelay)
monkeypatch.setattr(GuiDocMerge, "exec_", lambda *args: None)
nwGUI.mainMenu.aMergeDocs.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiDocMerge") is not None, timeout=1000)
nwMerge = getGuiItem("GuiDocMerge")
assert isinstance(nwMerge, GuiDocMerge)
nwMerge.show()
qtbot.wait(stepDelay)
nwMerge._doMerge()
qtbot.wait(stepDelay)
assert nwGUI.theProject.projTree["73475cb40a568"] is not None
projFile = os.path.join(nwLipsum, "content", "73475cb40a568.nwd")
testFile = os.path.join(outDir, "guiMerge_73475cb40a568.nwd")
compFile = os.path.join(refDir, "guiMerge_73475cb40a568.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# Split By Chapter
assert nwGUI.treeView.setSelectedHandle("73475cb40a568")
qtbot.wait(stepDelay)
monkeypatch.setattr(GuiDocSplit, "exec_", lambda *args: None)
nwGUI.mainMenu.aSplitDoc.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiDocSplit") is not None, timeout=1000)
nwSplit = getGuiItem("GuiDocSplit")
assert isinstance(nwSplit, GuiDocSplit)
nwSplit.show()
qtbot.wait(stepDelay)
nwSplit.splitLevel.setCurrentIndex(1)
qtbot.wait(stepDelay)
nwSplit._doSplit()
assert nwGUI.theProject.projTree["71ee45a3c0db9"] is not None
# This should give us back the file as it was before
projFile = os.path.join(nwLipsum, "content", "71ee45a3c0db9.nwd")
testFile = os.path.join(outDir, "guiMerge_71ee45a3c0db9.nwd")
compFile = os.path.join(refDir, "guiMerge_73475cb40a568.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile, [1, 2, 3])
# Split By Scene
assert nwGUI.treeView.setSelectedHandle("73475cb40a568")
qtbot.wait(stepDelay)
nwGUI.mainMenu.aSplitDoc.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiDocSplit") is not None, timeout=1000)
nwSplit = getGuiItem("GuiDocSplit")
assert isinstance(nwSplit, GuiDocSplit)
qtbot.wait(stepDelay)
nwSplit.splitLevel.setCurrentIndex(2)
qtbot.wait(stepDelay)
nwSplit._doSplit()
assert nwGUI.theProject.projTree["25fc0e7096fc6"] is not None
assert nwGUI.theProject.projTree["31489056e0916"] is not None
assert nwGUI.theProject.projTree["98010bd9270f9"] is not None
projFile = os.path.join(nwLipsum, "content", "25fc0e7096fc6.nwd")
testFile = os.path.join(outDir, "guiSplit_25fc0e7096fc6.nwd")
compFile = os.path.join(refDir, "guiSplit_25fc0e7096fc6.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "content", "31489056e0916.nwd")
testFile = os.path.join(outDir, "guiSplit_31489056e0916.nwd")
compFile = os.path.join(refDir, "guiSplit_31489056e0916.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "content", "98010bd9270f9.nwd")
testFile = os.path.join(outDir, "guiSplit_98010bd9270f9.nwd")
compFile = os.path.join(refDir, "guiSplit_98010bd9270f9.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# Split By Section
assert nwGUI.treeView.setSelectedHandle("73475cb40a568")
qtbot.wait(stepDelay)
nwGUI.mainMenu.aSplitDoc.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiDocSplit") is not None, timeout=1000)
nwSplit = getGuiItem("GuiDocSplit")
assert isinstance(nwSplit, GuiDocSplit)
qtbot.wait(stepDelay)
nwSplit.splitLevel.setCurrentIndex(3)
qtbot.wait(stepDelay)
nwSplit._doSplit()
assert nwGUI.theProject.projTree["1a6562590ef19"] is not None
assert nwGUI.theProject.projTree["031b4af5197ec"] is not None
assert nwGUI.theProject.projTree["41cfc0d1f2d12"] is not None
assert nwGUI.theProject.projTree["2858dcd1057d3"] is not None
assert nwGUI.theProject.projTree["2fca346db6561"] is not None
projFile = os.path.join(nwLipsum, "content", "1a6562590ef19.nwd")
testFile = os.path.join(outDir, "guiSplit_1a6562590ef19.nwd")
compFile = os.path.join(refDir, "guiSplit_25fc0e7096fc6.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile, [1, 2, 3])
projFile = os.path.join(nwLipsum, "content", "031b4af5197ec.nwd")
testFile = os.path.join(outDir, "guiSplit_031b4af5197ec.nwd")
compFile = os.path.join(refDir, "guiSplit_031b4af5197ec.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "content", "41cfc0d1f2d12.nwd")
testFile = os.path.join(outDir, "guiSplit_41cfc0d1f2d12.nwd")
compFile = os.path.join(refDir, "guiSplit_41cfc0d1f2d12.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "content", "2858dcd1057d3.nwd")
testFile = os.path.join(outDir, "guiSplit_2858dcd1057d3.nwd")
compFile = os.path.join(refDir, "guiSplit_2858dcd1057d3.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
projFile = os.path.join(nwLipsum, "content", "2fca346db6561.nwd")
testFile = os.path.join(outDir, "guiSplit_2fca346db6561.nwd")
compFile = os.path.join(refDir, "guiSplit_2fca346db6561.nwd")
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile)
# qtbot.stopForInteraction()
# END Test testDlgMergeSplit_Tools
+261
View File
@@ -0,0 +1,261 @@
# -*- coding: utf-8 -*-
"""
novelWriter Merge and Split Dialog Classes Tester
===================================================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import pytest
import os
from tools import getGuiItem, readFile, writeFile
from mock import causeOSError
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog
from nw.dialogs import GuiDocSplit, GuiItemEditor
from nw.enum import nwItemType, nwWidget
from nw.core.document import NWDoc
from nw.core.tree import NWTree
keyDelay = 2
typeDelay = 1
stepDelay = 20
@pytest.mark.gui
def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncDir, fncProj):
"""Test the split document tool.
"""
# Block message box
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
# Create a new project
nwGUI.theProject.projTree.setSeed(42)
assert nwGUI.newProject({"projPath": fncProj}) is True
# Handles for new objects
hNovelRoot = "73475cb40a568"
hChapterDir = "31489056e0916"
hToSplit = "1a6562590ef19"
hPartition = "41cfc0d1f2d12"
hChapterOne = "2858dcd1057d3"
hSceneOne = "2fca346db6561"
hSceneTwo = "02d20bbd7e394"
hSceneThree = "7688b6ef52555"
hSceneFour = "c837649cce43f"
hSceneFive = "6208ef0f7750c"
# Add Project Content
monkeypatch.setattr(GuiItemEditor, "exec_", lambda *a: QDialog.Accepted)
nwGUI.switchFocus(nwWidget.TREE)
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hNovelRoot).setSelected(True)
nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
assert nwGUI.saveProject() is True
assert nwGUI.closeProject() is True
tPartition = "# Nantucket"
tChapterOne = "## Chapter One\n\n% Chapter one comment"
tSceneOne = "### Scene One\n\nThere once was a man from Nantucket"
tSceneTwo = "### Scene Two\n\nWho kept all his cash in a bucket."
tSceneThree = "### Scene Three\n\n\tBut his daughter, named Nan, \n\tRan away with a man"
tSceneFour = "### Scene Four\n\nAnd as for the bucket, Nantucket."
tSceneFive = "#### The End\n\nend"
tToSplit = (
f"{tPartition}\n\n{tChapterOne}\n\n"
f"{tSceneOne}\n\n{tSceneTwo}\n\n"
f"{tSceneThree}\n\n{tSceneFour}\n\n"
f"{tSceneFive}\n\n"
)
contentDir = os.path.join(fncProj, "content")
writeFile(os.path.join(contentDir, hToSplit+".nwd"), tToSplit)
assert nwGUI.openProject(fncProj) is True
# Open the Split tool
nwGUI.switchFocus(nwWidget.TREE)
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hToSplit).setSelected(True)
monkeypatch.setattr(GuiDocSplit, "exec_", lambda *a: None)
nwGUI.mainMenu.aSplitDoc.activate(QAction.Trigger)
qtbot.waitUntil(lambda: getGuiItem("GuiDocSplit") is not None, timeout=1000)
nwSplit = getGuiItem("GuiDocSplit")
assert isinstance(nwSplit, GuiDocSplit)
nwSplit.show()
qtbot.wait(stepDelay)
# Populate List
# =============
nwSplit.listBox.clear()
assert nwSplit.listBox.count() == 0
# No item selected
nwSplit.sourceItem = None
nwGUI.treeView.clearSelection()
assert nwSplit._populateList() is False
assert nwSplit.listBox.count() == 0
# Non-existing item
with monkeypatch.context() as mp:
mp.setattr(NWTree, "__getitem__", lambda *a: None)
nwSplit.sourceItem = None
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hToSplit).setSelected(True)
assert nwSplit._populateList() is False
assert nwSplit.listBox.count() == 0
# Select a non-file
nwSplit.sourceItem = None
nwGUI.treeView.clearSelection()
nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
assert nwSplit._populateList() is False
assert nwSplit.listBox.count() == 0
# Error when reading documents
with monkeypatch.context() as mp:
mp.setattr(NWDoc, "readDocument", lambda *a: None)
nwSplit.sourceItem = hToSplit
assert nwSplit._populateList() is False
assert nwSplit.listBox.count() == 0
# Read properly, and check split levels
# Level 1
nwSplit.splitLevel.setCurrentIndex(0)
nwSplit.sourceItem = hToSplit
assert nwSplit._populateList() is True
assert nwSplit.listBox.count() == 1
# Level 2
nwSplit.splitLevel.setCurrentIndex(1)
nwSplit.sourceItem = hToSplit
assert nwSplit._populateList() is True
assert nwSplit.listBox.count() == 2
# Level 3
nwSplit.splitLevel.setCurrentIndex(2)
nwSplit.sourceItem = hToSplit
assert nwSplit._populateList() is True
assert nwSplit.listBox.count() == 6
# Level 4
nwSplit.splitLevel.setCurrentIndex(3)
nwSplit.sourceItem = hToSplit
assert nwSplit._populateList() is True
assert nwSplit.listBox.count() == 7
# Split Document
# ==============
# Test a proper split first
with monkeypatch.context() as mp:
mp.setattr(GuiDocSplit, "_doClose", lambda *a: None)
assert nwSplit._doSplit() is True
assert nwGUI.saveProject()
assert readFile(os.path.join(contentDir, hPartition+".nwd")) == (
"%%%%~name: Nantucket\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/PARTITION\n"
"%s\n\n"
) % (hPartition, tPartition)
assert readFile(os.path.join(contentDir, hChapterOne+".nwd")) == (
"%%%%~name: Chapter One\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/CHAPTER\n"
"%s\n\n"
) % (hChapterOne, tChapterOne)
assert readFile(os.path.join(contentDir, hSceneOne+".nwd")) == (
"%%%%~name: Scene One\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/SCENE\n"
"%s\n\n"
) % (hSceneOne, tSceneOne)
assert readFile(os.path.join(contentDir, hSceneTwo+".nwd")) == (
"%%%%~name: Scene Two\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/SCENE\n"
"%s\n\n"
) % (hSceneTwo, tSceneTwo)
assert readFile(os.path.join(contentDir, hSceneThree+".nwd")) == (
"%%%%~name: Scene Three\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/SCENE\n"
"%s\n\n"
) % (hSceneThree, tSceneThree)
assert readFile(os.path.join(contentDir, hSceneFour+".nwd")) == (
"%%%%~name: Scene Four\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/SCENE\n"
"%s\n\n"
) % (hSceneFour, tSceneFour)
assert readFile(os.path.join(contentDir, hSceneFive+".nwd")) == (
"%%%%~name: The End\n"
"%%%%~path: 031b4af5197ec/%s\n"
"%%%%~kind: NOVEL/SCENE\n"
"%s\n\n"
) % (hSceneFive, tSceneFive)
# OS error
with monkeypatch.context() as mp:
mp.setattr("builtins.open", causeOSError)
assert nwSplit._doSplit() is False
# Select to not split
with monkeypatch.context() as mp:
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
assert nwSplit._doSplit() is False
# Block folder creation by returning that the folder has a depth
# of 50 items in the tree
with monkeypatch.context() as mp:
mp.setattr(NWTree, "getItemPath", lambda *a: [""]*50)
assert nwSplit._doSplit() is False
# Clear the list
nwSplit.listBox.clear()
assert nwSplit._doSplit() is False
# Can't find sourcv item
with monkeypatch.context() as mp:
mp.setattr(NWTree, "__getitem__", lambda *a: None)
assert nwSplit._doSplit() is False
# No source item set
nwSplit.sourceItem = None
assert nwSplit._doSplit() is False
# Close up
nwSplit._doClose()
# qtbot.stopForInteraction()
# END Test testDlgSplit_Main
+1 -1
View File
@@ -26,7 +26,7 @@ from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog, QMessageBox, QAction from PyQt5.QtWidgets import QDialog, QMessageBox, QAction
from tools import writeFile, readFile, getGuiItem from tools import writeFile, readFile, getGuiItem
from dummy import causeOSError from mock import causeOSError
from nw.dialogs import GuiWordList from nw.dialogs import GuiWordList
from nw.constants import nwFiles from nw.constants import nwFiles
+3 -3
View File
@@ -249,14 +249,14 @@ def testGuiEditor_Main(qtbot, monkeypatch, nwGUI, fncDir, fncProj, refDir, outDi
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay) qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay) qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
for c in "This is a paragraph of dummy text.": for c in "This is a paragraph of nonsense text.":
qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay) qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay) qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay) qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
for c in ( for c in (
"This is another paragraph of much longer dummy text. " "This is another paragraph of much longer nonsense text. "
"It is in fact 1 very very DUMB dummy text! " "It is in fact 1 very very NONSENSICAL nonsense text! "
): ):
qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay) qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
for c in "We can also try replacing \"quotes\", even single 'quotes' are replaced. ": for c in "We can also try replacing \"quotes\", even single 'quotes' are replaced. ":
+1 -1
View File
@@ -165,7 +165,7 @@ def testGuiTheme_Main(qtbot, monkeypatch, nwMinimal, tmpDir):
assert isinstance(anIcon, QIcon) assert isinstance(anIcon, QIcon)
assert not anIcon.isNull() assert not anIcon.isNull()
# Add dummy icons and test alternative load paths # Add test icons and test alternative load paths
theIcons.ICON_MAP["testicon1"] = (QStyle.SP_DriveHDIcon, None) theIcons.ICON_MAP["testicon1"] = (QStyle.SP_DriveHDIcon, None)
anIcon = theIcons.getIcon("testicon1") anIcon = theIcons.getIcon("testicon1")
assert isinstance(anIcon, QIcon) assert isinstance(anIcon, QIcon)
+1 -1
View File
@@ -25,7 +25,7 @@ import json
import os import os
from tools import getGuiItem, writeFile from tools import getGuiItem, writeFile
from dummy import causeOSError from mock import causeOSError
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox