Merge branch 'main' into dev
This commit is contained in:
+115
-124
@@ -3018,118 +3018,118 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>GuiProjectTree</name>
|
<name>GuiProjectTree</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="559" />
|
<location filename="../novelwriter/gui/projtree.py" line="513" />
|
||||||
<source>Active</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="560" />
|
|
||||||
<source>Inactive</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="647" />
|
|
||||||
<source>Did not find anywhere to add the file or folder!</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="656" />
|
|
||||||
<source>Cannot add new files or folders to the Trash folder.</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="666" />
|
|
||||||
<source>New Note</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="669" />
|
|
||||||
<source>New Chapter</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="672" />
|
|
||||||
<source>New Scene</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="675" />
|
|
||||||
<source>New Document</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="678" />
|
|
||||||
<source>New Folder</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="893" />
|
|
||||||
<source>There is currently no Trash folder in this project.</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="902" />
|
|
||||||
<source>The Trash folder is already empty.</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="906" />
|
|
||||||
<source>Permanently delete {0} file(s) from Trash?</source>
|
<source>Permanently delete {0} file(s) from Trash?</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="952" />
|
<location filename="../novelwriter/gui/projtree.py" line="514" />
|
||||||
|
<source>Active</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="515" />
|
||||||
|
<source>Inactive</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="648" />
|
||||||
|
<source>Did not find anywhere to add the file or folder!</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="657" />
|
||||||
|
<source>Cannot add new files or folders to the Trash folder.</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="667" />
|
||||||
|
<source>New Note</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="670" />
|
||||||
|
<source>New Chapter</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="673" />
|
||||||
|
<source>New Scene</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="676" />
|
||||||
|
<source>New Document</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="679" />
|
||||||
|
<source>New Folder</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="894" />
|
||||||
|
<source>There is currently no Trash folder in this project.</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="903" />
|
||||||
|
<source>The Trash folder is already empty.</source>
|
||||||
|
<translation type="unfinished" />
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="950" />
|
||||||
<source>Move '{0}' to Trash?</source>
|
<source>Move '{0}' to Trash?</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="984" />
|
<location filename="../novelwriter/gui/projtree.py" line="982" />
|
||||||
<source>Root folders can only be deleted when they are empty.</source>
|
<source>Root folders can only be deleted when they are empty.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1003" />
|
<location filename="../novelwriter/gui/projtree.py" line="1001" />
|
||||||
<source>Permanently delete '{0}'?</source>
|
<source>Permanently delete '{0}'?</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1298" />
|
<location filename="../novelwriter/gui/projtree.py" line="1292" />
|
||||||
<source>Drag and drop is only allowed for single items, non-root items, or multiple items with the same parent.</source>
|
<source>Drag and drop is only allowed for single items, non-root items, or multiple items with the same parent.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1430" />
|
<location filename="../novelwriter/gui/projtree.py" line="1424" />
|
||||||
<source>No documents selected for merging.</source>
|
<source>No documents selected for merging.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1438" />
|
<location filename="../novelwriter/gui/projtree.py" line="1432" />
|
||||||
<source>Merged</source>
|
<source>Merged</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1518" />
|
<location filename="../novelwriter/gui/projtree.py" line="1512" />
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1454" />
|
<location filename="../novelwriter/gui/projtree.py" line="1448" />
|
||||||
<source>Could not write document content.</source>
|
<source>Could not write document content.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1540" />
|
<location filename="../novelwriter/gui/projtree.py" line="1534" />
|
||||||
<source>Do you want to duplicate this document?</source>
|
<source>Do you want to duplicate this document?</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1542" />
|
<location filename="../novelwriter/gui/projtree.py" line="1536" />
|
||||||
<source>Do you want to duplicate this item and all child items?</source>
|
<source>Do you want to duplicate this item and all child items?</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1556" />
|
<location filename="../novelwriter/gui/projtree.py" line="1550" />
|
||||||
<source>Could not duplicate all items.</source>
|
<source>Could not duplicate all items.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1613" />
|
<location filename="../novelwriter/gui/projtree.py" line="1607" />
|
||||||
<source>There is nowhere to add item with name '{0}'.</source>
|
<source>There is nowhere to add item with name '{0}'.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
@@ -3474,73 +3474,73 @@
|
|||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="427" />
|
<location filename="../novelwriter/core/project.py" line="428" />
|
||||||
<source>Backing up project ...</source>
|
<source>Backing up project ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="430" />
|
<location filename="../novelwriter/core/project.py" line="431" />
|
||||||
<source>Cannot backup project because no project name is set. Please set a Project Name in Project Settings.</source>
|
<source>Cannot backup project because no project name is set. Please set a Project Name in Project Settings.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="442" />
|
<location filename="../novelwriter/core/project.py" line="443" />
|
||||||
<source>Could not create backup folder.</source>
|
<source>Could not create backup folder.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="451" />
|
<location filename="../novelwriter/core/project.py" line="452" />
|
||||||
<source>Created a backup of your project of size {0}B.</source>
|
<source>Created a backup of your project of size {0}B.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="452" />
|
<location filename="../novelwriter/core/project.py" line="453" />
|
||||||
<source>Path: {0}</source>
|
<source>Path: {0}</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="455" />
|
<location filename="../novelwriter/core/project.py" line="456" />
|
||||||
<source>Could not write backup archive.</source>
|
<source>Could not write backup archive.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="458" />
|
<location filename="../novelwriter/core/project.py" line="459" />
|
||||||
<source>Project backed up to '{0}'</source>
|
<source>Project backed up to '{0}'</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="472" />
|
<location filename="../novelwriter/core/project.py" line="473" />
|
||||||
<location filename="../novelwriter/core/project.py" line="468" />
|
<location filename="../novelwriter/core/project.py" line="469" />
|
||||||
<source>New</source>
|
<source>New</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="469" />
|
<location filename="../novelwriter/core/project.py" line="470" />
|
||||||
<source>Note</source>
|
<source>Note</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="470" />
|
<location filename="../novelwriter/core/project.py" line="471" />
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="471" />
|
<location filename="../novelwriter/core/project.py" line="472" />
|
||||||
<source>Finished</source>
|
<source>Finished</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="473" />
|
<location filename="../novelwriter/core/project.py" line="474" />
|
||||||
<source>Minor</source>
|
<source>Minor</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="474" />
|
<location filename="../novelwriter/core/project.py" line="475" />
|
||||||
<source>Major</source>
|
<source>Major</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/core/project.py" line="475" />
|
<location filename="../novelwriter/core/project.py" line="476" />
|
||||||
<source>Main</source>
|
<source>Main</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
@@ -4520,142 +4520,133 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>_TreeContextMenu</name>
|
<name>_TreeContextMenu</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1765" />
|
<location filename="../novelwriter/gui/projtree.py" line="1759" />
|
||||||
<source>Empty Trash</source>
|
<source>Empty Trash</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1785" />
|
<location filename="../novelwriter/gui/projtree.py" line="1779" />
|
||||||
<source>Rename</source>
|
<source>Rename</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1817" />
|
<location filename="../novelwriter/gui/projtree.py" line="1815" />
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1821" />
|
<location filename="../novelwriter/gui/projtree.py" line="1819" />
|
||||||
<source>View Document</source>
|
<source>View Document</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1829" />
|
<location filename="../novelwriter/gui/projtree.py" line="1827" />
|
||||||
<source>Create New ...</source>
|
<source>Create New ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1840" />
|
<location filename="../novelwriter/gui/projtree.py" line="1838" />
|
||||||
<source>Rename to Heading</source>
|
<source>Rename to Heading</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1849" />
|
<location filename="../novelwriter/gui/projtree.py" line="1847" />
|
||||||
<source>Set Active to ...</source>
|
<source>Set Active to ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1850" />
|
<location filename="../novelwriter/gui/projtree.py" line="1853" />
|
||||||
<source>Active</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1852" />
|
|
||||||
<source>Inactive</source>
|
|
||||||
<translation type="unfinished" />
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1855" />
|
|
||||||
<source>Toggle Active</source>
|
<source>Toggle Active</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1862" />
|
<location filename="../novelwriter/gui/projtree.py" line="1860" />
|
||||||
<source>Set Status to ...</source>
|
<source>Set Status to ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1891" />
|
<location filename="../novelwriter/gui/projtree.py" line="1889" />
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1874" />
|
<location filename="../novelwriter/gui/projtree.py" line="1872" />
|
||||||
<source>Manage Labels ...</source>
|
<source>Manage Labels ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1879" />
|
<location filename="../novelwriter/gui/projtree.py" line="1877" />
|
||||||
<source>Set Importance to ...</source>
|
<source>Set Importance to ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1899" />
|
<location filename="../novelwriter/gui/projtree.py" line="1897" />
|
||||||
<source>Transform ...</source>
|
<source>Transform ...</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1924" />
|
<location filename="../novelwriter/gui/projtree.py" line="1922" />
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1920" />
|
<location filename="../novelwriter/gui/projtree.py" line="1918" />
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1916" />
|
<location filename="../novelwriter/gui/projtree.py" line="1914" />
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1912" />
|
<location filename="../novelwriter/gui/projtree.py" line="1910" />
|
||||||
<source>Convert to {0}</source>
|
<source>Convert to {0}</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1928" />
|
<location filename="../novelwriter/gui/projtree.py" line="1926" />
|
||||||
<source>Merge Child Items into Self</source>
|
<source>Merge Child Items into Self</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1930" />
|
<location filename="../novelwriter/gui/projtree.py" line="1928" />
|
||||||
<source>Merge Child Items into New</source>
|
<source>Merge Child Items into New</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1934" />
|
<location filename="../novelwriter/gui/projtree.py" line="1932" />
|
||||||
<source>Merge Documents in Folder</source>
|
<source>Merge Documents in Folder</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1938" />
|
<location filename="../novelwriter/gui/projtree.py" line="1936" />
|
||||||
<source>Split Document by Headers</source>
|
<source>Split Document by Headers</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1948" />
|
<location filename="../novelwriter/gui/projtree.py" line="1946" />
|
||||||
<source>Expand All</source>
|
<source>Expand All</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1950" />
|
<location filename="../novelwriter/gui/projtree.py" line="1948" />
|
||||||
<source>Collapse All</source>
|
<source>Collapse All</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1952" />
|
<location filename="../novelwriter/gui/projtree.py" line="1950" />
|
||||||
<source>Duplicate from Here</source>
|
<source>Duplicate from Here</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1955" />
|
<location filename="../novelwriter/gui/projtree.py" line="1953" />
|
||||||
<source>Duplicate Document</source>
|
<source>Duplicate Document</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1959" />
|
<location filename="../novelwriter/gui/projtree.py" line="1969" />
|
||||||
|
<location filename="../novelwriter/gui/projtree.py" line="1957" />
|
||||||
<source>Delete Permanently</source>
|
<source>Delete Permanently</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1969" />
|
<location filename="../novelwriter/gui/projtree.py" line="1972" />
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1962" />
|
<location filename="../novelwriter/gui/projtree.py" line="1960" />
|
||||||
<source>Move to Trash</source>
|
<source>Move to Trash</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1981" />
|
<location filename="../novelwriter/gui/projtree.py" line="1983" />
|
||||||
<source>Move {0} items to Trash?</source>
|
<source>Move {0} items to Trash?</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="2060" />
|
<location filename="../novelwriter/gui/projtree.py" line="2068" />
|
||||||
<source>Do you want to convert the folder to a {0}? This action cannot be reversed.</source>
|
<source>Do you want to convert the folder to a {0}? This action cannot be reversed.</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
@@ -4663,7 +4654,7 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>_UpdatableMenu</name>
|
<name>_UpdatableMenu</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../novelwriter/gui/projtree.py" line="1681" />
|
<location filename="../novelwriter/gui/projtree.py" line="1675" />
|
||||||
<source>From Template</source>
|
<source>From Template</source>
|
||||||
<translation type="unfinished" />
|
<translation type="unfinished" />
|
||||||
</message>
|
</message>
|
||||||
|
|||||||
+53
-45
@@ -505,10 +505,15 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self.mainGui = projView.mainGui
|
self.mainGui = projView.mainGui
|
||||||
|
|
||||||
# Internal Variables
|
# Internal Variables
|
||||||
self._treeMap = {}
|
self._treeMap: dict[str, QTreeWidgetItem] = {}
|
||||||
self._timeChanged = 0.0
|
self._timeChanged = 0.0
|
||||||
self._popAlert = None
|
self._popAlert = None
|
||||||
|
|
||||||
|
# Cached Translations
|
||||||
|
self.trActive = self.tr("Active")
|
||||||
|
self.trInactive = self.tr("Inactive")
|
||||||
|
self.trPermDelete = self.tr("Permanently delete {0} file(s) from Trash?")
|
||||||
|
|
||||||
# Build GUI
|
# Build GUI
|
||||||
# =========
|
# =========
|
||||||
|
|
||||||
@@ -555,10 +560,6 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
trRoot = self.invisibleRootItem()
|
trRoot = self.invisibleRootItem()
|
||||||
trRoot.setFlags(trRoot.flags() ^ Qt.ItemFlag.ItemIsDropEnabled)
|
trRoot.setFlags(trRoot.flags() ^ Qt.ItemFlag.ItemIsDropEnabled)
|
||||||
|
|
||||||
# Cached values
|
|
||||||
self._lblActive = self.tr("Active")
|
|
||||||
self._lblInactive = self.tr("Inactive")
|
|
||||||
|
|
||||||
# Set selection options
|
# Set selection options
|
||||||
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||||
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
||||||
@@ -902,10 +903,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
SHARED.info(self.tr("The Trash folder is already empty."))
|
SHARED.info(self.tr("The Trash folder is already empty."))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
msgYes = SHARED.question(
|
if not SHARED.question(self.trPermDelete.format(nTrash)):
|
||||||
self.tr("Permanently delete {0} file(s) from Trash?").format(nTrash)
|
|
||||||
)
|
|
||||||
if not msgYes:
|
|
||||||
logger.info("Action cancelled by user")
|
logger.info("Action cancelled by user")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -1052,7 +1050,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
|
|
||||||
if nwItem.isFileType():
|
if nwItem.isFileType():
|
||||||
iconName = "checked" if nwItem.isActive else "unchecked"
|
iconName = "checked" if nwItem.isActive else "unchecked"
|
||||||
toolTip = self._lblActive if nwItem.isActive else self._lblInactive
|
toolTip = self.trActive if nwItem.isActive else self.trInactive
|
||||||
trItem.setToolTip(self.C_ACTIVE, toolTip)
|
trItem.setToolTip(self.C_ACTIVE, toolTip)
|
||||||
else:
|
else:
|
||||||
iconName = "noncheckable"
|
iconName = "noncheckable"
|
||||||
@@ -1129,9 +1127,8 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
"""Get the currently selected handle. If multiple items are
|
"""Get the currently selected handle. If multiple items are
|
||||||
selected, return the first.
|
selected, return the first.
|
||||||
"""
|
"""
|
||||||
selItem = self.selectedItems()
|
if items := self.selectedItems():
|
||||||
if selItem:
|
return items[0].data(self.C_DATA, self.D_HANDLE)
|
||||||
return selItem[0].data(self.C_DATA, self.D_HANDLE)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def setSelectedHandle(self, tHandle: str | None, doScroll: bool = False) -> bool:
|
def setSelectedHandle(self, tHandle: str | None, doScroll: bool = False) -> bool:
|
||||||
@@ -1143,9 +1140,8 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if tHandle in self._treeMap:
|
if tHandle in self._treeMap:
|
||||||
self.setCurrentItem(self._treeMap[tHandle])
|
self.setCurrentItem(self._treeMap[tHandle])
|
||||||
|
|
||||||
selIndex = self.selectedIndexes()
|
if (indexes := self.selectedIndexes()) and doScroll:
|
||||||
if selIndex and doScroll:
|
self.scrollTo(indexes[0], QAbstractItemView.ScrollHint.PositionAtCenter)
|
||||||
self.scrollTo(selIndex[0], QAbstractItemView.ScrollHint.PositionAtCenter)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -1160,10 +1156,8 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
|
|
||||||
def openContextOnSelected(self) -> bool:
|
def openContextOnSelected(self) -> bool:
|
||||||
"""Open the context menu on the current selected item."""
|
"""Open the context menu on the current selected item."""
|
||||||
selItem = self.selectedItems()
|
if items := self.selectedItems():
|
||||||
if selItem:
|
return self._openContextMenu(self.visualItemRect(items[0]).center())
|
||||||
pos = self.visualItemRect(selItem[0]).center()
|
|
||||||
return self._openContextMenu(pos)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def changedSince(self, checkTime: float) -> bool:
|
def changedSince(self, checkTime: float) -> bool:
|
||||||
@@ -1746,7 +1740,7 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
self._item = nwItem
|
self._item = nwItem
|
||||||
self._handle = nwItem.itemHandle
|
self._handle = nwItem.itemHandle
|
||||||
self._items: list[str] = []
|
self._items: list[NWItem] = []
|
||||||
|
|
||||||
logger.debug("Ready: _TreeContextMenu")
|
logger.debug("Ready: _TreeContextMenu")
|
||||||
|
|
||||||
@@ -1799,13 +1793,17 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def buildMultiSelectMenu(self, items: list[str]) -> None:
|
def buildMultiSelectMenu(self, handles: list[str]) -> None:
|
||||||
"""Build the multi-select menu."""
|
"""Build the multi-select menu."""
|
||||||
self._items = items
|
self._items = []
|
||||||
|
for tHandle in handles:
|
||||||
|
if (tItem := SHARED.project.tree[tHandle]):
|
||||||
|
self._items.append(tItem)
|
||||||
|
|
||||||
self._itemActive(True)
|
self._itemActive(True)
|
||||||
self._itemStatusImport(True)
|
self._itemStatusImport(True)
|
||||||
self.addSeparator()
|
self.addSeparator()
|
||||||
self._moveToTrash(True)
|
self._multiMoveToTrash()
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -1847,9 +1845,9 @@ class _TreeContextMenu(QMenu):
|
|||||||
"""Add Active/Inactive actions."""
|
"""Add Active/Inactive actions."""
|
||||||
if multi:
|
if multi:
|
||||||
mSub = self.addMenu(self.tr("Set Active to ..."))
|
mSub = self.addMenu(self.tr("Set Active to ..."))
|
||||||
aOne = mSub.addAction(SHARED.theme.getIcon("checked"), self.tr("Active"))
|
aOne = mSub.addAction(SHARED.theme.getIcon("checked"), self.projTree.trActive)
|
||||||
aOne.triggered.connect(lambda: self._iterItemActive(True))
|
aOne.triggered.connect(lambda: self._iterItemActive(True))
|
||||||
aTwo = mSub.addAction(SHARED.theme.getIcon("unchecked"), self.tr("Inactive"))
|
aTwo = mSub.addAction(SHARED.theme.getIcon("unchecked"), self.projTree.trInactive)
|
||||||
aTwo.triggered.connect(lambda: self._iterItemActive(False))
|
aTwo.triggered.connect(lambda: self._iterItemActive(False))
|
||||||
else:
|
else:
|
||||||
action = self.addAction(self.tr("Toggle Active"))
|
action = self.addAction(self.tr("Toggle Active"))
|
||||||
@@ -1964,10 +1962,14 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _moveToTrash(self, multi: bool) -> None:
|
def _multiMoveToTrash(self) -> None:
|
||||||
"""Add move to Trash action."""
|
"""Add move to Trash action."""
|
||||||
action = self.addAction(self.tr("Move to Trash"))
|
areTrash = [i.itemClass == nwItemClass.TRASH for i in self._items]
|
||||||
if multi:
|
if all(areTrash):
|
||||||
|
action = self.addAction(self.tr("Delete Permanently"))
|
||||||
|
action.triggered.connect(self._iterPermDelete)
|
||||||
|
elif not any(areTrash):
|
||||||
|
action = self.addAction(self.tr("Move to Trash"))
|
||||||
action.triggered.connect(self._iterMoveToTrash)
|
action.triggered.connect(self._iterMoveToTrash)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1979,10 +1981,19 @@ class _TreeContextMenu(QMenu):
|
|||||||
def _iterMoveToTrash(self) -> None:
|
def _iterMoveToTrash(self) -> None:
|
||||||
"""Iterate through files and move them to Trash."""
|
"""Iterate through files and move them to Trash."""
|
||||||
if SHARED.question(self.tr("Move {0} items to Trash?").format(len(self._items))):
|
if SHARED.question(self.tr("Move {0} items to Trash?").format(len(self._items))):
|
||||||
for tHandle in self._items:
|
for tItem in self._items:
|
||||||
tItem = SHARED.project.tree[tHandle]
|
if tItem.isFileType() and tItem.itemClass != nwItemClass.TRASH:
|
||||||
if tItem and tItem.isFileType():
|
self.projTree.moveItemToTrash(tItem.itemHandle, askFirst=False, flush=False)
|
||||||
self.projTree.moveItemToTrash(tHandle, askFirst=False, flush=False)
|
self.projTree.saveTreeOrder()
|
||||||
|
return
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def _iterPermDelete(self) -> None:
|
||||||
|
"""Iterate through files and delete them."""
|
||||||
|
if SHARED.question(self.projTree.trPermDelete.format(len(self._items))):
|
||||||
|
for tItem in self._items:
|
||||||
|
if tItem.isFileType() and tItem.itemClass == nwItemClass.TRASH:
|
||||||
|
self.projTree.permDeleteItem(tItem.itemHandle, askFirst=False, flush=False)
|
||||||
self.projTree.saveTreeOrder()
|
self.projTree.saveTreeOrder()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -2000,12 +2011,11 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
def _iterItemActive(self, isActive: bool) -> None:
|
def _iterItemActive(self, isActive: bool) -> None:
|
||||||
"""Set the active status of multiple items."""
|
"""Set the active status of multiple items."""
|
||||||
for tHandle in self._items:
|
for tItem in self._items:
|
||||||
tItem = SHARED.project.tree[tHandle]
|
|
||||||
if tItem and tItem.isFileType():
|
if tItem and tItem.isFileType():
|
||||||
tItem.setActive(isActive)
|
tItem.setActive(isActive)
|
||||||
self.projTree.setTreeItemValues(tHandle)
|
self.projTree.setTreeItemValues(tItem.itemHandle)
|
||||||
self.projTree._alertTreeChange(tHandle, flush=False)
|
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _changeItemStatus(self, key: str) -> None:
|
def _changeItemStatus(self, key: str) -> None:
|
||||||
@@ -2017,12 +2027,11 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
def _iterSetItemStatus(self, key: str) -> None:
|
def _iterSetItemStatus(self, key: str) -> None:
|
||||||
"""Change the status value for multiple items."""
|
"""Change the status value for multiple items."""
|
||||||
for tHandle in self._items:
|
for tItem in self._items:
|
||||||
tItem = SHARED.project.tree[tHandle]
|
|
||||||
if tItem and tItem.isNovelLike():
|
if tItem and tItem.isNovelLike():
|
||||||
tItem.setStatus(key)
|
tItem.setStatus(key)
|
||||||
self.projTree.setTreeItemValues(tHandle)
|
self.projTree.setTreeItemValues(tItem.itemHandle)
|
||||||
self.projTree._alertTreeChange(tHandle, flush=False)
|
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _changeItemImport(self, key: str) -> None:
|
def _changeItemImport(self, key: str) -> None:
|
||||||
@@ -2034,12 +2043,11 @@ class _TreeContextMenu(QMenu):
|
|||||||
|
|
||||||
def _iterSetItemImport(self, key: str) -> None:
|
def _iterSetItemImport(self, key: str) -> None:
|
||||||
"""Change the status value for multiple items."""
|
"""Change the status value for multiple items."""
|
||||||
for tHandle in self._items:
|
for tItem in self._items:
|
||||||
tItem = SHARED.project.tree[tHandle]
|
|
||||||
if tItem and not tItem.isNovelLike():
|
if tItem and not tItem.isNovelLike():
|
||||||
tItem.setImport(key)
|
tItem.setImport(key)
|
||||||
self.projTree.setTreeItemValues(tHandle)
|
self.projTree.setTreeItemValues(tItem.itemHandle)
|
||||||
self.projTree._alertTreeChange(tHandle, flush=False)
|
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _changeItemLayout(self, itemLayout: nwItemLayout) -> None:
|
def _changeItemLayout(self, itemLayout: nwItemLayout) -> None:
|
||||||
|
|||||||
@@ -1404,6 +1404,22 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
assert SHARED.project.tree[hNovelNote].itemRoot == hTrashRoot # type: ignore
|
assert SHARED.project.tree[hNovelNote].itemRoot == hTrashRoot # type: ignore
|
||||||
assert SHARED.project.tree[hSubNote].itemRoot == hTrashRoot # type: ignore
|
assert SHARED.project.tree[hSubNote].itemRoot == hTrashRoot # type: ignore
|
||||||
|
|
||||||
|
# Permanently Delete Menu
|
||||||
|
nwItem = SHARED.project.tree[hCharNote]
|
||||||
|
assert isinstance(nwItem, NWItem)
|
||||||
|
ctxMenu = _TreeContextMenu(projTree, nwItem)
|
||||||
|
ctxMenu.buildMultiSelectMenu([hCharNote, hNovelNote, hSubNote])
|
||||||
|
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||||
|
assert actions == [
|
||||||
|
"Set Active to ...", "Set Importance to ...", "Delete Permanently",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Permanently Delete
|
||||||
|
ctxMenu._iterPermDelete()
|
||||||
|
assert SHARED.project.tree[hCharNote] is None
|
||||||
|
assert SHARED.project.tree[hNovelNote] is None
|
||||||
|
assert SHARED.project.tree[hSubNote] is None
|
||||||
|
|
||||||
# qtbot.stop()
|
# qtbot.stop()
|
||||||
|
|
||||||
# END Test testGuiProjTree_ContextMenu
|
# END Test testGuiProjTree_ContextMenu
|
||||||
|
|||||||
Reference in New Issue
Block a user