Merge pull request #415 from vkbo/outtakes

Outtakes (Archive) Feature
This commit is contained in:
Veronica K. Berglyd Olsen
2020-08-16 18:29:29 +02:00
committed by GitHub
18 changed files with 184 additions and 26 deletions
+21
View File
@@ -43,6 +43,27 @@ currently selected item. This panel also includes the latest paragraph and chara
addition to the word count. addition to the word count.
.. _a_ui_tree_dnd:
Project Tree Drag and Drop
--------------------------
The project tree allows dragging and drop to a certain extent, but it does not allow bulk actions.
This is deliberate to avoid accidentally messing up your project. The project tree has no undo
function.
Document files and their folders can be rearranged freely within their root folders. Novel files
cannot be moved out of the :guilabel:`Novel` folder, except to :guilabel:`Trash` and the
:guilabel:`Outtakes` folder. Note files can be moved freely anywhere.
Folders cannot be moved at all outside their root tree. Neither can a folder containing files be
deleted. You must first delete the files.
Root folders in the project tree cannot be dragged and dropped. However, if you want to reorder
them, you can move them up or down with respect to eachother from the :guilabel:`Tools` menu, or by
pressing :kbd:`Ctrl`:kbd:`Shift` and the :kbd:`Up` or :kbd:`Down` key.
.. _a_ui_edit: .. _a_ui_edit:
Editing and Viewing Documents Editing and Viewing Documents
+17 -1
View File
@@ -87,7 +87,7 @@ Deleted Documents
Deleted document files will be moved into a special :guilabel:`Trash` root folder. Files in the Deleted document files will be moved into a special :guilabel:`Trash` root folder. Files in the
trash folder can then be deleted permanently, either individually, or by emptying the trash from the trash folder can then be deleted permanently, either individually, or by emptying the trash from the
menu. menu. Files in this folder are removed from the project index and cannot be referenced.
Folders and root folders can only be deleted when they are empty. Recursive deletion is not Folders and root folders can only be deleted when they are empty. Recursive deletion is not
supported. supported.
@@ -96,6 +96,22 @@ A document file or a folder can be deleted from the :guilabel:`project` menu, or
:kbd:`Ctrl`:kbd:`Del`. :kbd:`Ctrl`:kbd:`Del`.
.. _a_proj_roots_out:
Archived Documents (Outtakes)
-----------------------------
If you don't want to delete a file, or put it in the :guilabel:`Trash` folder where it may be
deleted, but still want it out of your main project tree, you can create an :guilabel:`Outtakes`
root folder from the :guilabel:`project` menu. This folder is similar to the :guilabel:`Trash`
folder in that it doesn't allow subfolders and creating new files.
You can drag any file to this folder and preserve its settings. The file will always be excluded
from the :guilabel:`Build Novel Project` builds, even with the setting to ignore the excluded files
option. The file is also removed from the project index, so the tags and references defined in it
will not show up anywhere else.
.. _a_proj_roots_orph: .. _a_proj_roots_orph:
Orphaned Documents Orphaned Documents
@@ -25,6 +25,7 @@ cls_timeline = calendar.svg
cls_object = key.svg cls_object = key.svg
cls_entity = flag.svg cls_entity = flag.svg
cls_custom = star.svg cls_custom = star.svg
cls_archive = delete.svg
cls_trash = trash.svg cls_trash = trash.svg
proj_document = document-text.svg proj_document = document-text.svg
proj_folder = folder.svg proj_folder = folder.svg
@@ -25,6 +25,7 @@ cls_timeline = calendar.svg
cls_object = key.svg cls_object = key.svg
cls_entity = flag.svg cls_entity = flag.svg
cls_custom = star.svg cls_custom = star.svg
cls_archive = delete.svg
cls_trash = trash.svg cls_trash = trash.svg
proj_document = document-text.svg proj_document = document-text.svg
proj_folder = folder.svg proj_folder = folder.svg
@@ -25,6 +25,7 @@ cls_timeline = calendar.svg
cls_object = key.svg cls_object = key.svg
cls_entity = flag.svg cls_entity = flag.svg
cls_custom = star.svg cls_custom = star.svg
cls_archive = delete.svg
cls_trash = trash.svg cls_trash = trash.svg
proj_document = document-text.svg proj_document = document-text.svg
proj_folder = folder.svg proj_folder = folder.svg
@@ -25,6 +25,7 @@ cls_timeline = calendar.svg
cls_object = key.svg cls_object = key.svg
cls_entity = flag.svg cls_entity = flag.svg
cls_custom = star.svg cls_custom = star.svg
cls_archive = delete.svg
cls_trash = trash.svg cls_trash = trash.svg
proj_document = document-text.svg proj_document = document-text.svg
proj_folder = folder.svg proj_folder = folder.svg
+3
View File
@@ -84,6 +84,7 @@ class nwLabels():
nwItemClass.OBJECT : "Objects", nwItemClass.OBJECT : "Objects",
nwItemClass.ENTITY : "Entity", nwItemClass.ENTITY : "Entity",
nwItemClass.CUSTOM : "Custom", nwItemClass.CUSTOM : "Custom",
nwItemClass.ARCHIVE : "Outtakes",
nwItemClass.TRASH : "Trash", nwItemClass.TRASH : "Trash",
} }
CLASS_FLAG = { CLASS_FLAG = {
@@ -96,6 +97,7 @@ class nwLabels():
nwItemClass.OBJECT : "O", nwItemClass.OBJECT : "O",
nwItemClass.ENTITY : "E", nwItemClass.ENTITY : "E",
nwItemClass.CUSTOM : "X", nwItemClass.CUSTOM : "X",
nwItemClass.ARCHIVE : "U",
nwItemClass.TRASH : "R", nwItemClass.TRASH : "R",
} }
CLASS_ICON = { CLASS_ICON = {
@@ -108,6 +110,7 @@ class nwLabels():
nwItemClass.OBJECT : "cls_object", nwItemClass.OBJECT : "cls_object",
nwItemClass.ENTITY : "cls_entity", nwItemClass.ENTITY : "cls_entity",
nwItemClass.CUSTOM : "cls_custom", nwItemClass.CUSTOM : "cls_custom",
nwItemClass.ARCHIVE : "cls_archive",
nwItemClass.TRASH : "cls_trash", nwItemClass.TRASH : "cls_trash",
} }
LAYOUT_NAME = { LAYOUT_NAME = {
+2 -1
View File
@@ -48,7 +48,8 @@ class nwItemClass(Enum):
OBJECT = 6 OBJECT = 6
ENTITY = 7 ENTITY = 7
CUSTOM = 8 CUSTOM = 8
TRASH = 9 ARCHIVE = 9
TRASH = 10
# END Enum nwItemClass # END Enum nwItemClass
+34
View File
@@ -34,6 +34,7 @@ from time import time
from nw.constants import ( from nw.constants import (
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert
) )
from nw.core.document import NWDoc
from nw.core.tools import countWords from nw.core.tools import countWords
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -106,6 +107,8 @@ class NWIndex():
def deleteHandle(self, tHandle): def deleteHandle(self, tHandle):
"""Delete all entries of a given document handle. """Delete all entries of a given document handle.
""" """
logger.debug("Removing item %s from the index" % tHandle)
delTags = [] delTags = []
for tTag in self.tagIndex: for tTag in self.tagIndex:
if self.tagIndex[tTag][1] == tHandle: if self.tagIndex[tTag][1] == tHandle:
@@ -121,6 +124,26 @@ class NWIndex():
return return
def reIndexHandle(self, tHandle):
"""Put a file back into the index. This is used when files are
moved from the archive or trash folders back into the active
project.
"""
logger.debug("Re-indexing item %s" % tHandle)
tItem = self.theProject.projTree[tHandle]
if tItem is None:
return False
if tItem.itemType != nwItemType.FILE:
return False
theDoc = NWDoc(self.theProject, self.theParent)
theText = theDoc.openDocument(tHandle, showStatus=False)
if theText:
self.scanText(tHandle, theText)
return True
## ##
# Load and Save Index to/from File # Load and Save Index to/from File
## ##
@@ -244,13 +267,24 @@ class NWIndex():
files before we save them, unless we're rebuilding the index. files before we save them, unless we're rebuilding the index.
""" """
theItem = self.theProject.projTree[tHandle] theItem = self.theProject.projTree[tHandle]
theRoot = self.theProject.projTree.getRootItem(tHandle)
if theItem is None: if theItem is None:
logger.error("Not indexing unknown item %s" % tHandle)
return False return False
if theItem.itemType != nwItemType.FILE: if theItem.itemType != nwItemType.FILE:
logger.error("Not indexing non-file item %s" % tHandle)
return False return False
if theItem.parHandle == self.theProject.projTree.trashRoot(): if theItem.parHandle == self.theProject.projTree.trashRoot():
logger.error("Not indexing trash item %s" % tHandle)
return False return False
if theItem.itemLayout == nwItemLayout.NO_LAYOUT: if theItem.itemLayout == nwItemLayout.NO_LAYOUT:
logger.error("Not indexing no-layout item %s" % tHandle)
return False
if theRoot is None:
logger.error("Not indexing homeless item %s" % tHandle)
return False
if theRoot.itemClass == nwItemClass.ARCHIVE:
logger.error("Not indexing archived item %s" % tHandle)
return False return False
itemClass = theItem.itemClass itemClass = theItem.itemClass
+19 -4
View File
@@ -67,6 +67,7 @@ class NWTree():
self._treeOrder = [] self._treeOrder = []
self._treeRoots = [] self._treeRoots = []
self._trashRoot = None self._trashRoot = None
self._archRoot = None
self._theLength = 0 self._theLength = 0
self._theIndex = 0 self._theIndex = 0
self._treeChanged = False self._treeChanged = False
@@ -96,6 +97,9 @@ class NWTree():
if nwItem.itemType == nwItemType.ROOT: if nwItem.itemType == nwItemType.ROOT:
logger.verbose("Entry %s is a root item" % str(tHandle)) logger.verbose("Entry %s is a root item" % str(tHandle))
self._treeRoots.append(tHandle) self._treeRoots.append(tHandle)
if nwItem.itemClass == nwItemClass.ARCHIVE:
logger.verbose("Entry %s is the archive folder" % str(tHandle))
self._archRoot = tHandle
if nwItem.itemType == nwItemType.TRASH: if nwItem.itemType == nwItemType.TRASH:
if self._trashRoot is None: if self._trashRoot is None:
@@ -211,6 +215,14 @@ class NWTree():
return self._trashRoot return self._trashRoot
return None return None
def archiveRoot(self):
"""Returns the handle of the archive folder, or None if there
isn't one.
"""
if self._archRoot:
return self._archRoot
return None
def findRoot(self, theClass): def findRoot(self, theClass):
"""Find the root item for a given class. """Find the root item for a given class.
Note: This returns the first item for class CUSTOM. Note: This returns the first item for class CUSTOM.
@@ -245,12 +257,10 @@ class NWTree():
if tItem is not None: if tItem is not None:
for i in range(200): for i in range(200):
if tItem.parHandle is None: if tItem.parHandle is None:
return tHandle return tItem
else: else:
tHandle = tItem.parHandle tHandle = tItem.parHandle
tItem = self.__getitem__(tHandle) tItem = self.__getitem__(tHandle)
if tItem is None:
return tHandle
return None return None
def getItemPath(self, tHandle): def getItemPath(self, tHandle):
@@ -391,7 +401,12 @@ class NWTree():
return False return False
self._treeOrder.remove(tHandle) self._treeOrder.remove(tHandle)
self._theLength = len(self._treeOrder) self._theLength = len(self._treeOrder)
if tHandle in self._treeRoots:
self._treeRoots.remove(tHandle)
self._setTreeChanged(True) self._setTreeChanged(True)
return True return True
def __contains__(self, tHandle): def __contains__(self, tHandle):
+2 -1
View File
@@ -478,6 +478,7 @@ class GuiBuildNovel(QDialog):
noteRoot = noteFiles noteRoot = noteFiles
noteRoot &= tItem.itemType == nwItemType.ROOT noteRoot &= tItem.itemType == nwItemType.ROOT
noteRoot &= tItem.itemClass != nwItemClass.NOVEL noteRoot &= tItem.itemClass != nwItemClass.NOVEL
noteRoot &= tItem.itemClass != nwItemClass.ARCHIVE
try: try:
if noteRoot: if noteRoot:
@@ -539,7 +540,6 @@ class GuiBuildNovel(QDialog):
* Items that appear in the TRASH folder or have parent set to * Items that appear in the TRASH folder or have parent set to
None (orphaned files). None (orphaned files).
""" """
if theItem is None: if theItem is None:
return False return False
@@ -551,6 +551,7 @@ class GuiBuildNovel(QDialog):
isNone |= theItem.itemClass == nwItemClass.NO_CLASS isNone |= theItem.itemClass == nwItemClass.NO_CLASS
isNone |= theItem.itemClass == nwItemClass.TRASH isNone |= theItem.itemClass == nwItemClass.TRASH
isNone |= theItem.parHandle == self.theProject.projTree.trashRoot() isNone |= theItem.parHandle == self.theProject.projTree.trashRoot()
isNone |= theItem.parHandle == self.theProject.projTree.archiveRoot()
isNone |= theItem.parHandle is None isNone |= theItem.parHandle is None
isNote = theItem.itemLayout == nwItemLayout.NOTE isNote = theItem.itemLayout == nwItemLayout.NOTE
isNovel = not isNone and not isNote isNovel = not isNone and not isNote
+4
View File
@@ -75,6 +75,9 @@ class GuiMainMenu(QMenuBar):
## ##
def setAvailableRoot(self): def setAvailableRoot(self):
"""Update the list of available root folders and set the ones
that are active.
"""
for itemClass in nwItemClass: for itemClass in nwItemClass:
if itemClass == nwItemClass.NO_CLASS: if itemClass == nwItemClass.NO_CLASS:
continue continue
@@ -245,6 +248,7 @@ class GuiMainMenu(QMenuBar):
self.rootItems[nwItemClass.OBJECT] = QAction("Object Root", self.rootMenu) self.rootItems[nwItemClass.OBJECT] = QAction("Object Root", self.rootMenu)
self.rootItems[nwItemClass.ENTITY] = QAction("Entity Root", self.rootMenu) self.rootItems[nwItemClass.ENTITY] = QAction("Entity Root", self.rootMenu)
self.rootItems[nwItemClass.CUSTOM] = QAction("Custom Root", self.rootMenu) self.rootItems[nwItemClass.CUSTOM] = QAction("Custom Root", self.rootMenu)
self.rootItems[nwItemClass.ARCHIVE] = QAction("Outtakes Root", self.rootMenu)
nCount = 0 nCount = 0
for itemClass in self.rootItems.keys(): for itemClass in self.rootItems.keys():
nCount += 1 # This forces the lambdas to be unique nCount += 1 # This forces the lambdas to be unique
+34 -5
View File
@@ -201,7 +201,17 @@ class GuiProjectTree(QTreeWidget):
if pHandle == self.theProject.projTree.trashRoot(): if pHandle == self.theProject.projTree.trashRoot():
self.makeAlert( self.makeAlert(
"Cannot add new files or folders to the trash folder.", nwAlert.ERROR "Cannot add new files or folders to the %s folder." % (
nwLabels.CLASS_NAME[nwItemClass.TRASH]
), nwAlert.ERROR
)
return False
if pItem.itemClass == nwItemClass.ARCHIVE:
self.makeAlert(
"Cannot add new files or folders to the %s folder." % (
nwLabels.CLASS_NAME[nwItemClass.ARCHIVE]
), nwAlert.ERROR
) )
return False return False
@@ -459,6 +469,7 @@ class GuiProjectTree(QTreeWidget):
tIndex = self.indexOfTopLevelItem(trItemS) tIndex = self.indexOfTopLevelItem(trItemS)
if trItemS.childCount() == 0: if trItemS.childCount() == 0:
self.takeTopLevelItem(tIndex) self.takeTopLevelItem(tIndex)
del self.theProject.projTree[tHandle]
self.theParent.mainMenu.setAvailableRoot() self.theParent.mainMenu.setAvailableRoot()
self._setTreeChanged(True) self._setTreeChanged(True)
else: else:
@@ -669,17 +680,25 @@ class GuiProjectTree(QTreeWidget):
isNote = snItem.itemLayout == nwItemLayout.NOTE isNote = snItem.itemLayout == nwItemLayout.NOTE
onFile = dnItem.itemType == nwItemType.FILE onFile = dnItem.itemType == nwItemType.FILE
isRoot = snItem.itemType == nwItemType.ROOT isRoot = snItem.itemType == nwItemType.ROOT
onFree = dnItem.itemClass == nwItemClass.ARCHIVE
onFree |= dnItem.itemClass == nwItemClass.TRASH
onFree &= snItem.itemType == nwItemType.FILE
isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem
if (isSame or isNone or isNote) and not (onFile and isOnTop) and not isRoot: if (isSame or isNone or isNote or onFree) and not (onFile and isOnTop) and not isRoot:
logger.debug("Drag'n'drop of item %s accepted" % sHandle) logger.debug("Drag'n'drop of item %s accepted" % sHandle)
self.propagateCount(sHandle, 0) self.propagateCount(sHandle, 0)
QTreeWidget.dropEvent(self, theEvent) QTreeWidget.dropEvent(self, theEvent)
# Handle orphaned files differently than tracked files
if isNone: if isNone:
self._moveOrphanedItem(sHandle, dHandle) self._moveOrphanedItem(sHandle, dHandle)
self._cleanOrphanedRoot() self._cleanOrphanedRoot()
else: else:
self._updateItemParent(sHandle) self._updateItemParent(sHandle)
if not isSame:
# If the item does not have the same class as the target,
# and the target is not a free root folder, update its class
if not isSame and not onFree:
logger.debug("Item %s class has been changed from %s to %s" % ( logger.debug("Item %s class has been changed from %s to %s" % (
sHandle, sHandle,
snItem.itemClass.name, snItem.itemClass.name,
@@ -687,7 +706,16 @@ class GuiProjectTree(QTreeWidget):
)) ))
snItem.setClass(dnItem.itemClass) snItem.setClass(dnItem.itemClass)
self.setTreeItemValues(sHandle) self.setTreeItemValues(sHandle)
self.propagateCount(sHandle, wCount) self.propagateCount(sHandle, wCount)
# The items dropped into archive or trash should be removed
# from the project index
if onFree:
self.theParent.theIndex.deleteHandle(sHandle)
else:
self.theParent.theIndex.reIndexHandle(sHandle)
else: else:
logger.debug("Drag'n'drop of item %s not accepted" % sHandle) logger.debug("Drag'n'drop of item %s not accepted" % sHandle)
self.makeAlert("The item cannot be moved to that location.", nwAlert.ERROR) self.makeAlert("The item cannot be moved to that location.", nwAlert.ERROR)
@@ -928,14 +956,15 @@ class GuiProjectTreeMenu(QMenu):
inTrash = theItem.parHandle == trashHandle inTrash = theItem.parHandle == trashHandle
isTrash = theItem.itemHandle == trashHandle isTrash = theItem.itemHandle == trashHandle
isFile = theItem.itemType == nwItemType.FILE isFile = theItem.itemType == nwItemType.FILE
isArch = theItem.itemClass == nwItemClass.ARCHIVE
isOrph = isFile and theItem.parHandle is None isOrph = isFile and theItem.parHandle is None
showOpen = isFile showOpen = isFile
showView = isFile showView = isFile
showEdit = not isTrash and not isOrph showEdit = not isTrash and not isOrph
showExport = isFile and not inTrash and not isOrph showExport = isFile and not inTrash and not isOrph
showNewFile = not isTrash and not inTrash and not isOrph showNewFile = not isTrash and not inTrash and not isOrph and not isArch
showNewFolder = not isTrash and not inTrash and not isOrph showNewFolder = not isTrash and not inTrash and not isOrph and not isArch
showDelete = not isTrash showDelete = not isTrash
showEmpty = isTrash showEmpty = isTrash
+1
View File
@@ -514,6 +514,7 @@ class GuiIcons:
"cls_object" : (QStyle.SP_DriveHDIcon, "drive-harddisk"), "cls_object" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"cls_entity" : (QStyle.SP_DriveHDIcon, "drive-harddisk"), "cls_entity" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"cls_custom" : (QStyle.SP_DriveHDIcon, "drive-harddisk"), "cls_custom" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"cls_archive" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"cls_trash" : (QStyle.SP_DriveHDIcon, "drive-harddisk"), "cls_trash" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
"proj_document" : (QStyle.SP_FileIcon, "x-office-document"), "proj_document" : (QStyle.SP_FileIcon, "x-office-document"),
"proj_folder" : (QStyle.SP_DirIcon, "folder"), "proj_folder" : (QStyle.SP_DirIcon, "folder"),
+5
View File
@@ -29,6 +29,11 @@
"NOVEL", "NOVEL",
"Chapter Two" "Chapter Two"
], ],
[
"content/8a5deb88c0e97.nwd",
"NOVEL",
"Old File"
],
[ [
"content/96b68994dfa3d.nwd", "content/96b68994dfa3d.nwd",
"NOVEL", "NOVEL",
+1
View File
@@ -10,6 +10,7 @@
content/636b6aa9b697b.nwd NOVEL Making a Scene content/636b6aa9b697b.nwd NOVEL Making a Scene
content/6a2d6d5f4f401.nwd NOVEL Chapter One content/6a2d6d5f4f401.nwd NOVEL Chapter One
content/88706ddc78b1b.nwd NOVEL Chapter Two content/88706ddc78b1b.nwd NOVEL Chapter Two
content/8a5deb88c0e97.nwd NOVEL Old File
content/96b68994dfa3d.nwd NOVEL A Note on Structure content/96b68994dfa3d.nwd NOVEL A Note on Structure
content/974e400180a99.nwd NOVEL Page content/974e400180a99.nwd NOVEL Page
content/ae7339df26ded.nwd NOVEL We Found John! content/ae7339df26ded.nwd NOVEL We Found John!
+4
View File
@@ -0,0 +1,4 @@
%%~ 8a5deb88c0e97:6827118336ac1:NOVEL:SCENE:Old File
### Discarded Scene
If you have files you no longer want in your main project, you can move them to the “Outtakes” folder. This is equivalent to turning off the “Include when building project” switch, just that you also put the file away, although the switch can be ignored when building the project, this folder cannot.
+33 -14
View File
@@ -1,13 +1,13 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.12.1" hexVersion="0x001201f0" fileVersion="1.2" timeStamp="2020-08-16 11:37:18"> <novelWriterXML appVersion="0.12.1" hexVersion="0x001201f0" fileVersion="1.2" timeStamp="2020-08-16 17:50:53">
<project> <project>
<name>Sample Project</name> <name>Sample Project</name>
<title>Sample Project</title> <title>Sample Project</title>
<author>Jane Smith</author> <author>Jane Smith</author>
<author>Jay Doh</author> <author>Jay Doh</author>
<saveCount>684</saveCount> <saveCount>713</saveCount>
<autoCount>125</autoCount> <autoCount>138</autoCount>
<editTime>33351</editTime> <editTime>35134</editTime>
</project> </project>
<settings> <settings>
<doBackup>False</doBackup> <doBackup>False</doBackup>
@@ -15,8 +15,8 @@
<autoOutline>True</autoOutline> <autoOutline>True</autoOutline>
<lastEdited>636b6aa9b697b</lastEdited> <lastEdited>636b6aa9b697b</lastEdited>
<lastViewed>636b6aa9b697b</lastViewed> <lastViewed>636b6aa9b697b</lastViewed>
<lastWordCount>1022</lastWordCount> <lastWordCount>1071</lastWordCount>
<novelWordCount>646</novelWordCount> <novelWordCount>695</novelWordCount>
<notesWordCount>376</notesWordCount> <notesWordCount>376</notesWordCount>
<autoReplace> <autoReplace>
<entry key="A">B</entry> <entry key="A">B</entry>
@@ -46,7 +46,7 @@
<entry blue="175" green="0" red="117">Main</entry> <entry blue="175" green="0" red="117">Main</entry>
</importance> </importance>
</settings> </settings>
<content count="22"> <content count="24">
<item handle="7031beac91f75" order="0" parent="None"> <item handle="7031beac91f75" order="0" parent="None">
<name>Novel</name> <name>Novel</name>
<type>ROOT</type> <type>ROOT</type>
@@ -119,7 +119,7 @@
<charCount>1811</charCount> <charCount>1811</charCount>
<wordCount>318</wordCount> <wordCount>318</wordCount>
<paraCount>8</paraCount> <paraCount>8</paraCount>
<cursorPos>1880</cursorPos> <cursorPos>1364</cursorPos>
</item> </item>
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a"> <item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">
<name>Another Scene</name> <name>Another Scene</name>
@@ -137,13 +137,13 @@
<name>Interlude</name> <name>Interlude</name>
<type>FILE</type> <type>FILE</type>
<class>NOVEL</class> <class>NOVEL</class>
<status>Finished</status> <status>New</status>
<exported>True</exported> <exported>True</exported>
<layout>UNNUMBERED</layout> <layout>UNNUMBERED</layout>
<charCount>633</charCount> <charCount>633</charCount>
<wordCount>101</wordCount> <wordCount>101</wordCount>
<paraCount>3</paraCount> <paraCount>3</paraCount>
<cursorPos>1238</cursorPos> <cursorPos>0</cursorPos>
</item> </item>
<item handle="96b68994dfa3d" order="4" parent="e7ded148d6e4a"> <item handle="96b68994dfa3d" order="4" parent="e7ded148d6e4a">
<name>A Note on Structure</name> <name>A Note on Structure</name>
@@ -262,7 +262,26 @@
<paraCount>1</paraCount> <paraCount>1</paraCount>
<cursorPos>45</cursorPos> <cursorPos>45</cursorPos>
</item> </item>
<item handle="98acd8c76c93a" order="3" parent="None"> <item handle="6827118336ac1" order="3" parent="None">
<name>Outtakes</name>
<type>ROOT</type>
<class>ARCHIVE</class>
<status>None</status>
<expanded>True</expanded>
</item>
<item handle="8a5deb88c0e97" order="0" parent="6827118336ac1">
<name>Old File</name>
<type>FILE</type>
<class>NOVEL</class>
<status>1st Draft</status>
<exported>True</exported>
<layout>SCENE</layout>
<charCount>315</charCount>
<wordCount>55</wordCount>
<paraCount>1</paraCount>
<cursorPos>322</cursorPos>
</item>
<item handle="98acd8c76c93a" order="4" parent="None">
<name>Trash</name> <name>Trash</name>
<type>TRASH</type> <type>TRASH</type>
<class>TRASH</class> <class>TRASH</class>
@@ -276,9 +295,9 @@
<status>New</status> <status>New</status>
<exported>True</exported> <exported>True</exported>
<layout>SCENE</layout> <layout>SCENE</layout>
<charCount>30</charCount> <charCount>0</charCount>
<wordCount>6</wordCount> <wordCount>0</wordCount>
<paraCount>1</paraCount> <paraCount>0</paraCount>
<cursorPos>36</cursorPos> <cursorPos>36</cursorPos>
</item> </item>
</content> </content>