Added item status, and added icons and flags to the main treeview

This commit is contained in:
Veronica K. B. Olsen
2019-04-24 22:42:57 +02:00
parent b180971548
commit 2f0f39b53e
8 changed files with 198 additions and 18 deletions
+1
View File
@@ -43,6 +43,7 @@ class nwItemLayout(Enum):
PARTITION = 3 PARTITION = 3
CHAPTER = 4 CHAPTER = 4
SCENE = 5 SCENE = 5
NOTE = 6
# END Enum nwItemLayout # END Enum nwItemLayout
+86
View File
@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI Document Details
novelWriter GUI Document Details
====================================
Class holding the left side document details panel
File History:
Created: 2019-04-24 [0.0.1]
"""
import logging
import nw
from os import path
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel
from nw.enum import nwItemType, nwItemClass, nwItemLayout
from nw.project.item import NWItem
logger = logging.getLogger(__name__)
class GuiDocDetails(QFrame):
C_NAME = 0
C_COUNT = 1
C_FLAGS = 2
C_HANDLE = 3
def __init__(self, theProject):
QFrame.__init__(self)
logger.debug("Initialising DocDetails ...")
self.mainConf = nw.CONFIG
self.debugGUI = self.mainConf.debugGUI
self.theProject = theProject
self.mainBox = QGridLayout(self)
self.mainBox.setVerticalSpacing(1)
self.mainBox.setHorizontalSpacing(15)
self.setLayout(self.mainBox)
self.fntOne = QFont()
self.fntOne.setPointSize(10)
self.fntOne.setBold(True)
self.fntTwo = QFont()
self.fntTwo.setPointSize(10)
colOne = ["Name","Status","Class","Layout"]
for nRow in range(4):
lblOne = QLabel(colOne[nRow])
lblOne.setFont(self.fntOne)
self.mainBox.addWidget(lblOne,nRow+1,0)
self.mainBox.setColumnStretch(0,0)
self.mainBox.setColumnStretch(1,1)
logger.debug("DocDetails initialisation complete")
return
def buildViewBox(self, tHandle):
nwItem = self.theProject.getItem(tHandle)
itemStatus = nwItem.itemStatus
if itemStatus < 0 or itemStatus >= len(self.theProject.statusLabels):
itemStatus = 0
colTwo = [
nwItem.itemName,
self.theProject.statusLabels[itemStatus],
NWItem.CLASS_NAME[nwItem.itemClass],
NWItem.LAYOUT_NAME[nwItem.itemLayout],
]
for nRow in range(4):
lblTwo = QLabel(colTwo[nRow])
lblTwo.setFont(self.fntTwo)
self.mainBox.addWidget(lblTwo,nRow+1,1)
return
# END Class GuiDocDetails
+35 -10
View File
@@ -14,8 +14,8 @@ import logging
import nw import nw
from os import path from os import path
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QSize from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QIcon, QFont, QColor
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, QInputDialog, QLineEdit from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, QInputDialog, QLineEdit
from nw.enum import nwItemType, nwItemClass from nw.enum import nwItemType, nwItemClass
@@ -43,10 +43,13 @@ class GuiDocTree(QTreeWidget):
self.setExpandsOnDoubleClick(True) self.setExpandsOnDoubleClick(True)
self.setIndentation(13) self.setIndentation(13)
self.setColumnCount(4) self.setColumnCount(4)
self.setHeaderLabels(["Name","S","#","Handle"]) self.setHeaderLabels(["Name","Count","Flags","Handle"])
if not self.debugGUI: if not self.debugGUI:
self.hideColumn(self.C_HANDLE) self.hideColumn(self.C_HANDLE)
treeHead = self.headerItem()
treeHead.setTextAlignment(self.C_COUNT,Qt.AlignRight)
# Allow Move by Drag & Drop # Allow Move by Drag & Drop
self.setDragEnabled(True) self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove) self.setDragDropMode(QAbstractItemView.InternalMove)
@@ -54,6 +57,9 @@ class GuiDocTree(QTreeWidget):
for colN in range(len(self.mainConf.treeColWidth)): for colN in range(len(self.mainConf.treeColWidth)):
self.setColumnWidth(colN,self.mainConf.treeColWidth[colN]) self.setColumnWidth(colN,self.mainConf.treeColWidth[colN])
self.fontFlags = QFont("Monospace",10)
self.fontCount = QFont("Monospace",10)
logger.debug("DocTree initialisation complete") logger.debug("DocTree initialisation complete")
return return
@@ -139,34 +145,53 @@ class GuiDocTree(QTreeWidget):
return theItem, theCount+1 return theItem, theCount+1
def _addTreeItem(self, nwItem): def _addTreeItem(self, nwItem):
tName = nwItem.itemName tName = nwItem.itemName
tHandle = nwItem.itemHandle tHandle = nwItem.itemHandle
pHandle = nwItem.parHandle pHandle = nwItem.parHandle
tStatus = 0 tStatus = NWItem.CLASS_FLAG[nwItem.itemClass]
if nwItem.itemType == nwItemType.FILE:
tStatus += "."+NWItem.LAYOUT_FLAG[nwItem.itemLayout]
nStatus = nwItem.itemStatus
if nStatus < 0 or nStatus >= len(self.theProject.statusIcons):
nStatus = 0
newItem = QTreeWidgetItem([""]*4) newItem = QTreeWidgetItem([""]*4)
newItem.setText(self.C_NAME, tName)
newItem.setText(self.C_FLAGS, str(tStatus)) newItem.setText(self.C_NAME,tName)
newItem.setText(self.C_COUNT, "0")
newItem.setText(self.C_COUNT,"0")
# newItem.setFont(self.C_COUNT,self.fontCount)
newItem.setForeground(self.C_COUNT,QColor(0,105,135))
newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight)
newItem.setText(self.C_FLAGS,tStatus)
newItem.setIcon(self.C_FLAGS,self.theProject.statusIcons[nStatus])
newItem.setFont(self.C_FLAGS,self.fontFlags)
newItem.setText(self.C_HANDLE, tHandle) newItem.setText(self.C_HANDLE, tHandle)
self.theMap[tHandle] = newItem self.theMap[tHandle] = newItem
if pHandle is None: if pHandle is None:
self.addTopLevelItem(newItem) self.addTopLevelItem(newItem)
else: else:
self.theMap[pHandle].addChild(newItem) self.theMap[pHandle].addChild(newItem)
self.propagateCount(tHandle, nwItem.wordCount) self.propagateCount(tHandle, nwItem.wordCount)
newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight)
newItem.setExpanded(nwItem.isExpanded) newItem.setExpanded(nwItem.isExpanded)
if nwItem.itemType == nwItemType.ROOT: if nwItem.itemType == nwItemType.ROOT:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("drive-harddisk")) newItem.setIcon(self.C_NAME, QIcon.fromTheme("drive-harddisk"))
elif nwItem.itemType == nwItemType.FOLDER: elif nwItem.itemType == nwItemType.FOLDER:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("folder")) newItem.setIcon(self.C_NAME, QIcon.fromTheme("folder"))
elif nwItem.itemType == nwItemType.FILE: elif nwItem.itemType == nwItemType.FILE:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("x-office-document")) newItem.setIcon(self.C_NAME, QIcon.fromTheme("x-office-document"))
return True return True
def propagateCount(self, tHandle, theCount, nDepth=0): def propagateCount(self, tHandle, theCount, nDepth=0):
tItem = self.theMap[tHandle] tItem = self.theMap[tHandle]
tItem.setText(self.C_COUNT,str(theCount)) tItem.setText(self.C_COUNT,"{:n}".format(theCount))
pItem = tItem.parent() pItem = tItem.parent()
if pItem is not None: if pItem is not None:
pCount = 0 pCount = 0
@@ -184,7 +209,7 @@ class GuiDocTree(QTreeWidget):
self._addTreeItem(nwItem) self._addTreeItem(nwItem)
return True return True
def _getSelectedHandle(self): def getSelectedHandle(self):
selItem = self.selectedItems() selItem = self.selectedItems()
if len(selItem) == 0: if len(selItem) == 0:
return None return None
@@ -210,7 +235,7 @@ class GuiDocTree(QTreeWidget):
"""Overload the drop of dragged item event to check whether the drop is allowed """Overload the drop of dragged item event to check whether the drop is allowed
or not. Disallowed drops are cancelled. or not. Disallowed drops are cancelled.
""" """
sHandle = self._getSelectedHandle() sHandle = self.getSelectedHandle()
if sHandle is None: if sHandle is None:
return return
+1 -1
View File
@@ -192,7 +192,7 @@ class GuiDocTreeCtx(QMenu):
return return
def _buildSubMenuAddRoot(self, itemClass): def _buildSubMenuAddRoot(self, itemClass):
mnuSub = QAction("Add "+NWItem.CLASS_NAME[itemClass], self) mnuSub = QAction("Add %s Root" % NWItem.CLASS_NAME[itemClass], self)
mnuSub.triggered.connect(lambda: self._ctxSignal( mnuSub.triggered.connect(lambda: self._ctxSignal(
nwItemAction.ADD_ROOT, nwItemAction.ADD_ROOT,
itemClass, itemClass,
+18 -3
View File
@@ -21,6 +21,7 @@ from PyQt5.QtGui import QIcon
from nw.gui.doctree import GuiDocTree from nw.gui.doctree import GuiDocTree
from nw.gui.doctreectx import GuiDocTreeCtx from nw.gui.doctreectx import GuiDocTreeCtx
from nw.gui.doceditor import GuiDocEditor from nw.gui.doceditor import GuiDocEditor
from nw.gui.docdetails import GuiDocDetails
from nw.gui.projecteditor import GuiProjectEditor from nw.gui.projecteditor import GuiProjectEditor
from nw.gui.statusbar import GuiMainStatus from nw.gui.statusbar import GuiMainStatus
from nw.project.project import NWProject from nw.project.project import NWProject
@@ -44,8 +45,9 @@ class GuiMain(QMainWindow):
self.setWindowIcon(QIcon(path.join(self.mainConf.appPath,"..","novelWriter.svg"))) self.setWindowIcon(QIcon(path.join(self.mainConf.appPath,"..","novelWriter.svg")))
# Main GUI Elements # Main GUI Elements
self.docEditor = GuiDocEditor(self) self.docEditor = GuiDocEditor(self)
self.treeView = GuiDocTree(self.theProject) self.docDetails = GuiDocDetails(self.theProject)
self.treeView = GuiDocTree(self.theProject)
# Assemble Main Window # Assemble Main Window
self.stackPane = QStackedWidget() self.stackPane = QStackedWidget()
@@ -53,8 +55,14 @@ class GuiMain(QMainWindow):
self.stackDoc = self.stackPane.addWidget(self.docEditor) self.stackDoc = self.stackPane.addWidget(self.docEditor)
self.stackPane.setCurrentIndex(self.stackNone) self.stackPane.setCurrentIndex(self.stackNone)
self.treePane = QFrame()
self.treeBox = QVBoxLayout()
self.treeBox.addWidget(self.treeView)
self.treeBox.addWidget(self.docDetails)
self.treePane.setLayout(self.treeBox)
self.splitMain = QSplitter(Qt.Horizontal) self.splitMain = QSplitter(Qt.Horizontal)
self.splitMain.addWidget(self.treeView) self.splitMain.addWidget(self.treePane)
self.splitMain.addWidget(self.stackPane) self.splitMain.addWidget(self.stackPane)
self.splitMain.setSizes(self.mainConf.mainPanePos) self.splitMain.setSizes(self.mainConf.mainPanePos)
self.splitMain.splitterMoved.connect(self._splitMainMove) self.splitMain.splitterMoved.connect(self._splitMainMove)
@@ -65,6 +73,7 @@ class GuiMain(QMainWindow):
self._buildMenu() self._buildMenu()
self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeView.customContextMenuRequested.connect(self._openDocTreeContextMenu) self.treeView.customContextMenuRequested.connect(self._openDocTreeContextMenu)
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
self.treeView.itemDoubleClicked.connect(self._treeDoubleClick) self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
self.treeView.buildTree() self.treeView.buildTree()
@@ -159,6 +168,12 @@ class GuiMain(QMainWindow):
# Internal Functions # Internal Functions
## ##
def _treeSingleClick(self):
sHandle = self.treeView.getSelectedHandle()
if sHandle is not None:
self.docDetails.buildViewBox(sHandle)
return
def _treeDoubleClick(self, tItem, colNo): def _treeDoubleClick(self, tItem, colNo):
tHandle = tItem.text(3) tHandle = tItem.text(3)
logger.verbose("User double clicked tree item with handle %s" % tHandle) logger.verbose("User double clicked tree item with handle %s" % tHandle)
+20 -3
View File
@@ -25,7 +25,7 @@ class NWItem():
MAX_DEPTH = 8 MAX_DEPTH = 8
CLASS_NAME = { CLASS_NAME = {
nwItemClass.NO_CLASS : "Folder", nwItemClass.NO_CLASS : "Custom",
nwItemClass.NOVEL : "Novel", nwItemClass.NOVEL : "Novel",
nwItemClass.PLOT : "Plot", nwItemClass.PLOT : "Plot",
nwItemClass.CHARACTER : "Characters", nwItemClass.CHARACTER : "Characters",
@@ -42,6 +42,15 @@ class NWItem():
nwItemClass.TIMELINE : "T", nwItemClass.TIMELINE : "T",
nwItemClass.OBJECT : "O", nwItemClass.OBJECT : "O",
} }
LAYOUT_NAME = {
nwItemLayout.NO_LAYOUT : "None",
nwItemLayout.TITLE_PAGE : "Title Page",
nwItemLayout.SIMPLE_PAGE : "Simple Page",
nwItemLayout.PARTITION : "Partition",
nwItemLayout.CHAPTER : "Chapter",
nwItemLayout.SCENE : "Scene",
nwItemLayout.NOTE : "Note",
}
LAYOUT_FLAG = { LAYOUT_FLAG = {
nwItemLayout.NO_LAYOUT : "Xo", nwItemLayout.NO_LAYOUT : "Xo",
nwItemLayout.TITLE_PAGE : "Tt", nwItemLayout.TITLE_PAGE : "Tt",
@@ -49,6 +58,7 @@ class NWItem():
nwItemLayout.PARTITION : "Pt", nwItemLayout.PARTITION : "Pt",
nwItemLayout.CHAPTER : "Ch", nwItemLayout.CHAPTER : "Ch",
nwItemLayout.SCENE : "Sc", nwItemLayout.SCENE : "Sc",
nwItemLayout.NOTE : "Nt",
} }
def __init__(self): def __init__(self):
@@ -60,6 +70,7 @@ class NWItem():
self.itemType = nwItemType.NO_TYPE self.itemType = nwItemType.NO_TYPE
self.itemClass = nwItemClass.NO_CLASS self.itemClass = nwItemClass.NO_CLASS
self.itemLayout = nwItemLayout.NO_LAYOUT self.itemLayout = nwItemLayout.NO_LAYOUT
self.itemStatus = 0
self.itemDepth = None self.itemDepth = None
self.hasChildren = False self.hasChildren = False
self.isExpanded = False self.isExpanded = False
@@ -83,12 +94,12 @@ class NWItem():
xSub = self._subPack(xPack,"name", text=str(self.itemName)) xSub = self._subPack(xPack,"name", text=str(self.itemName))
xSub = self._subPack(xPack,"type", text=str(self.itemType.name)) xSub = self._subPack(xPack,"type", text=str(self.itemType.name))
xSub = self._subPack(xPack,"class", text=str(self.itemClass.name)) xSub = self._subPack(xPack,"class", text=str(self.itemClass.name))
xSub = self._subPack(xPack,"status", text=str(self.itemStatus))
xSub = self._subPack(xPack,"depth", text=str(self.itemDepth)) xSub = self._subPack(xPack,"depth", text=str(self.itemDepth))
xSub = self._subPack(xPack,"children", text=str(self.hasChildren)) xSub = self._subPack(xPack,"children", text=str(self.hasChildren))
xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded)) xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded))
if self.itemClass == nwItemClass.NOVEL and self.itemLayout is not nwItemLayout.NO_LAYOUT:
xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name))
if self.itemType == nwItemType.FILE: if self.itemType == nwItemType.FILE:
xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name))
xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False) xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False)
xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False) xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False)
xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False) xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False)
@@ -113,6 +124,7 @@ class NWItem():
elif tagName == "type": self.setType(tagValue) elif tagName == "type": self.setType(tagValue)
elif tagName == "class": self.setClass(tagValue) elif tagName == "class": self.setClass(tagValue)
elif tagName == "layout": self.setLayout(tagValue) elif tagName == "layout": self.setLayout(tagValue)
elif tagName == "status": self.setStatus(tagValue)
elif tagName == "depth": self.setDepth(tagValue) elif tagName == "depth": self.setDepth(tagValue)
elif tagName == "children": self.setChildren(tagValue) elif tagName == "children": self.setChildren(tagValue)
elif tagName == "expanded": self.setExpanded(tagValue) elif tagName == "expanded": self.setExpanded(tagValue)
@@ -182,6 +194,11 @@ class NWItem():
self.itemLayout = nwItemLayout.NO_LAYOUT self.itemLayout = nwItemLayout.NO_LAYOUT
return return
def setStatus(self, theStatus):
theStatus = self._checkInt(theStatus,0)
self.itemStatus = theStatus
return
def setDepth(self, theDepth): def setDepth(self, theDepth):
theDepth = self._checkInt(theDepth,-1) theDepth = self._checkInt(theDepth,-1)
if theDepth >= 0 and theDepth <= self.MAX_DEPTH: if theDepth >= 0 and theDepth <= self.MAX_DEPTH:
+24
View File
@@ -19,6 +19,8 @@ from hashlib import sha256
from datetime import datetime from datetime import datetime
from time import time from time import time
from PyQt5.QtGui import QIcon, QPixmap, QColor
from nw.enum import nwItemType, nwItemClass, nwItemAction from nw.enum import nwItemType, nwItemClass, nwItemAction
from nw.project.item import NWItem from nw.project.item import NWItem
@@ -41,6 +43,16 @@ class NWProject():
self.bookTitle = "" self.bookTitle = ""
self.bookAuthors = [] self.bookAuthors = []
self.statusCols = [
("New", 100,100,100),
("Note", 200, 50, 0),
("Draft", 200,150, 0),
("Finished", 50,200, 0),
]
self.statusIcons = []
self.statusLabels = []
self._makeStatusIcons()
return return
## ##
@@ -79,6 +91,7 @@ class NWProject():
self.projName = "" self.projName = ""
self.bookTitle = "" self.bookTitle = ""
self.bookAuthors = [] self.bookAuthors = []
self._makeStatusIcons()
hNovel = self.newRoot("Novel", nwItemClass.NOVEL) hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
hChars = self.newRoot("Characters", nwItemClass.CHARACTER) hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
hWorld = self.newRoot("World", nwItemClass.WORLD) hWorld = self.newRoot("World", nwItemClass.WORLD)
@@ -147,6 +160,7 @@ class NWProject():
nwItem.setFromTag(xValue.tag,xValue.text) nwItem.setFromTag(xValue.tag,xValue.text)
self._appendItem(tHandle,pHandle,nwItem) self._appendItem(tHandle,pHandle,nwItem)
self._makeStatusIcons()
self.mainConf.setRecent(self.projPath) self.mainConf.setRecent(self.projPath)
return True return True
@@ -365,6 +379,16 @@ class NWProject():
return return
def _makeStatusIcons(self):
self.statusIcons = []
self.statusLabels = []
for sLabel, sR, sG, sB in self.statusCols:
theIcon = QPixmap(32,32)
theIcon.fill(QColor(sR,sG,sB))
self.statusIcons.append(QIcon(theIcon))
self.statusLabels.append(sLabel)
return
def _makeHandle(self, addSeed=""): def _makeHandle(self, addSeed=""):
newSeed = str(time()) + addSeed newSeed = str(time()) + addSeed
logger.verbose("Generating handle with seed '%s'" % newSeed) logger.verbose("Generating handle with seed '%s'" % newSeed)
+13 -1
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-24 18:07:47"> <novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-24 22:34:36">
<project> <project>
<name>Sample Project</name> <name>Sample Project</name>
<title>Sample Project</title> <title>Sample Project</title>
@@ -11,6 +11,7 @@
<name>Novel</name> <name>Novel</name>
<type>ROOT</type> <type>ROOT</type>
<class>NOVEL</class> <class>NOVEL</class>
<status>0</status>
<depth>0</depth> <depth>0</depth>
<children>True</children> <children>True</children>
<expanded>True</expanded> <expanded>True</expanded>
@@ -19,6 +20,7 @@
<name>New Chapter</name> <name>New Chapter</name>
<type>FOLDER</type> <type>FOLDER</type>
<class>NOVEL</class> <class>NOVEL</class>
<status>1</status>
<depth>1</depth> <depth>1</depth>
<children>True</children> <children>True</children>
<expanded>True</expanded> <expanded>True</expanded>
@@ -27,9 +29,11 @@
<name>New Scene</name> <name>New Scene</name>
<type>FILE</type> <type>FILE</type>
<class>NOVEL</class> <class>NOVEL</class>
<status>2</status>
<depth>2</depth> <depth>2</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<layout>SCENE</layout>
<charCount>2575</charCount> <charCount>2575</charCount>
<wordCount>377</wordCount> <wordCount>377</wordCount>
<paraCount>5</paraCount> <paraCount>5</paraCount>
@@ -38,9 +42,11 @@
<name>Test File</name> <name>Test File</name>
<type>FILE</type> <type>FILE</type>
<class>NOVEL</class> <class>NOVEL</class>
<status>1</status>
<depth>2</depth> <depth>2</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<layout>SCENE</layout>
<charCount>125</charCount> <charCount>125</charCount>
<wordCount>24</wordCount> <wordCount>24</wordCount>
<paraCount>2</paraCount> <paraCount>2</paraCount>
@@ -49,6 +55,7 @@
<name>Characters</name> <name>Characters</name>
<type>ROOT</type> <type>ROOT</type>
<class>CHARACTER</class> <class>CHARACTER</class>
<status>0</status>
<depth>0</depth> <depth>0</depth>
<children>True</children> <children>True</children>
<expanded>True</expanded> <expanded>True</expanded>
@@ -57,9 +64,11 @@
<name>Jon Smith</name> <name>Jon Smith</name>
<type>FILE</type> <type>FILE</type>
<class>CHARACTER</class> <class>CHARACTER</class>
<status>0</status>
<depth>1</depth> <depth>1</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<layout>NOTE</layout>
<charCount>0</charCount> <charCount>0</charCount>
<wordCount>0</wordCount> <wordCount>0</wordCount>
<paraCount>0</paraCount> <paraCount>0</paraCount>
@@ -68,9 +77,11 @@
<name>Jane Smith</name> <name>Jane Smith</name>
<type>FILE</type> <type>FILE</type>
<class>CHARACTER</class> <class>CHARACTER</class>
<status>0</status>
<depth>1</depth> <depth>1</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<layout>NOTE</layout>
<charCount>0</charCount> <charCount>0</charCount>
<wordCount>0</wordCount> <wordCount>0</wordCount>
<paraCount>0</paraCount> <paraCount>0</paraCount>
@@ -79,6 +90,7 @@
<name>World</name> <name>World</name>
<type>ROOT</type> <type>ROOT</type>
<class>WORLD</class> <class>WORLD</class>
<status>0</status>
<depth>0</depth> <depth>0</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>