Added handling of orphaned documents.

This commit is contained in:
Veronica K. B. Olsen
2019-04-28 19:37:39 +02:00
parent 880b8905ee
commit 664efbc6d2
7 changed files with 100 additions and 21 deletions
+13 -10
View File
@@ -64,17 +64,20 @@ class GuiDocDetails(QFrame):
def buildViewBox(self, tHandle): def buildViewBox(self, tHandle):
nwItem = self.theProject.getItem(tHandle) nwItem = self.theProject.getItem(tHandle)
itemStatus = nwItem.itemStatus
if itemStatus < 0 or itemStatus >= len(self.theProject.statusLabels):
itemStatus = 0
colTwo = [ if nwItem is None:
nwItem.itemName, colTwo = [""]*4
self.theProject.statusLabels[itemStatus], else:
nwLabels.CLASS_NAME[nwItem.itemClass], itemStatus = nwItem.itemStatus
nwLabels.LAYOUT_NAME[nwItem.itemLayout], if itemStatus < 0 or itemStatus >= len(self.theProject.statusLabels):
] itemStatus = 0
colTwo = [
nwItem.itemName,
self.theProject.statusLabels[itemStatus],
nwLabels.CLASS_NAME[nwItem.itemClass],
nwLabels.LAYOUT_NAME[nwItem.itemLayout],
]
for nRow in range(4): for nRow in range(4):
lblTwo = QLabel(colTwo[nRow]) lblTwo = QLabel(colTwo[nRow])
+26 -6
View File
@@ -40,6 +40,7 @@ class GuiDocTree(QTreeWidget):
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theProject
self.theMap = {} self.theMap = {}
self.orphRoot = None
self.setIconSize(QSize(13,13)) self.setIconSize(QSize(13,13))
self.setExpandsOnDoubleClick(True) self.setExpandsOnDoubleClick(True)
@@ -152,6 +153,8 @@ class GuiDocTree(QTreeWidget):
def saveTreeOrder(self): def saveTreeOrder(self):
theList = [] theList = []
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
if self.topLevelItem(i) == self.orphRoot:
continue
theList = self._scanChildren(theList, self.topLevelItem(i), i) theList = self._scanChildren(theList, self.topLevelItem(i), i)
self.theProject.setTreeOrder(theList) self.theProject.setTreeOrder(theList)
return True return True
@@ -200,7 +203,12 @@ class GuiDocTree(QTreeWidget):
self.theMap[tHandle] = newItem self.theMap[tHandle] = newItem
if pHandle is None: if pHandle is None:
self.addTopLevelItem(newItem) if nwItem.itemType == nwItemType.ROOT:
self.addTopLevelItem(newItem)
self.theParent.mainMenu.setAvailableRoot()
else:
self._addOrphanedRoot()
self.orphRoot.addChild(newItem)
else: else:
self.theMap[pHandle].addChild(newItem) self.theMap[pHandle].addChild(newItem)
self.propagateCount(tHandle, nwItem.wordCount) self.propagateCount(tHandle, nwItem.wordCount)
@@ -210,7 +218,6 @@ class GuiDocTree(QTreeWidget):
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"))
self.theParent.mainMenu.setAvailableRoot()
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:
@@ -218,6 +225,18 @@ class GuiDocTree(QTreeWidget):
return newItem return newItem
def _addOrphanedRoot(self):
if self.orphRoot is None:
newItem = QTreeWidgetItem([""]*4)
newItem.setText(self.C_NAME, "Orphaned Files")
newItem.setText(self.C_COUNT, "")
newItem.setText(self.C_FLAGS, "")
newItem.setText(self.C_HANDLE, "")
self.addTopLevelItem(newItem)
self.orphRoot = newItem
newItem.setExpanded(True)
return
def setTreeItemValues(self, tHandle): def setTreeItemValues(self, tHandle):
trItem = self.theMap[tHandle] trItem = self.theMap[tHandle]
@@ -248,7 +267,7 @@ class GuiDocTree(QTreeWidget):
for i in range(pItem.childCount()): for i in range(pItem.childCount()):
pCount += int(pItem.child(i).text(self.C_COUNT)) pCount += int(pItem.child(i).text(self.C_COUNT))
pHandle = pItem.text(self.C_HANDLE) pHandle = pItem.text(self.C_HANDLE)
if not nDepth > NWItem.MAX_DEPTH: if not nDepth > NWItem.MAX_DEPTH and pHandle != "":
self.propagateCount(pHandle, pCount, nDepth+1) self.propagateCount(pHandle, pCount, nDepth+1)
return return
@@ -298,14 +317,15 @@ class GuiDocTree(QTreeWidget):
snItem = self.theProject.getItem(sHandle) snItem = self.theProject.getItem(sHandle)
dnItem = self.theProject.getItem(dHandle) dnItem = self.theProject.getItem(dHandle)
isSame = snItem.itemClass == dnItem.itemClass and dnItem.itemType isSame = snItem.itemClass == dnItem.itemClass and dnItem.itemType
isNone = snItem.itemClass == nwItemClass.NO_CLASS
isFile = dnItem.itemType == nwItemType.FILE isFile = dnItem.itemType == nwItemType.FILE
isRoot = snItem.itemType == nwItemType.ROOT isRoot = snItem.itemType == nwItemType.ROOT
isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem
if isSame and not (isFile and isOnTop) and not isRoot: if (isSame or isNone) and not (isFile and isOnTop) and not isRoot:
logger.verbose("Drag'n'drop on item %s allowed" % sHandle) logger.verbose("Drag'n'drop of item %s accepted" % sHandle)
QTreeWidget.dropEvent(self, theEvent) QTreeWidget.dropEvent(self, theEvent)
else: else:
logger.verbose("Drag'n'drop on item %s not allowed" % sHandle) logger.verbose("Drag'n'drop of item %s not accepted" % sHandle)
return return
+53 -1
View File
@@ -13,7 +13,7 @@
import logging import logging
import nw import nw
from os import path, mkdir from os import path, mkdir, listdir
from lxml import etree from lxml import etree
from hashlib import sha256 from hashlib import sha256
from datetime import datetime from datetime import datetime
@@ -167,6 +167,8 @@ class NWProject():
self._makeStatusIcons() self._makeStatusIcons()
self.mainConf.setRecent(self.projPath) self.mainConf.setRecent(self.projPath)
self._scanProjectFolder()
return True return True
def saveProject(self): def saveProject(self):
@@ -287,6 +289,56 @@ class NWProject():
# Internal Functions # Internal Functions
## ##
def _scanProjectFolder(self):
if self.projPath is None:
return
# First, scan the project data folders
itemList = []
for subItem in listdir(self.projPath):
if subItem[:5] != "data_":
continue
dataDir = path.join(self.projPath,subItem)
for subFile in listdir(dataDir):
if subFile[-4:] == ".nwd":
newItem = path.join(subItem,subFile)
itemList.append(newItem)
# Then check the valid files
orphanFiles = []
for fileItem in itemList:
if len(fileItem) != 28:
# Just to be safe, shouldn't happen
logger.warning("Skipping file %s" % fileItem)
continue
fHandle = fileItem[5]+fileItem[7:19]
if fHandle in self.treeOrder:
logger.verbose("Checking file %s, handle %s: OK" % (fileItem,fHandle))
else:
logger.verbose("Checking file %s, handle %s: Orphaned" % (fileItem,fHandle))
orphanFiles.append(fHandle)
# Report status
if len(orphanFiles) > 0:
logger.warning("Found %d orphaned file(s) in project folder!" % len(orphanFiles))
else:
logger.verbose("File check OK")
return
# Handle orphans
nOrph = 0
for oHandle in orphanFiles:
nOrph += 1
orItem = NWItem()
orItem.setName("Orphaned File %d" % nOrph)
orItem.setType(nwItemType.FILE)
orItem.setClass(nwItemClass.NO_CLASS)
orItem.setLayout(nwItemLayout.NO_LAYOUT)
self._appendItem(oHandle,None,orItem)
return
def _countItemDepth(self, tHandle): def _countItemDepth(self, tHandle):
theDepth = 0 theDepth = 0
nwItem = self.getItem(tHandle) nwItem = self.getItem(tHandle)
@@ -1,3 +1,3 @@
# John Smith # John Smith
Hes pretty cool. Nor Brad Pitt though. Hes pretty cool. Not Brad Pitt though.
@@ -0,0 +1,4 @@
# My Novel
**By Jane Doh**
@@ -1,3 +1,3 @@
# Earth # Earth
Third planet from the sun, fairly dense and with lots of people on it. Third planet from the sun, fairly dense, and with lots of people on it.
+2 -2
View File
@@ -1,12 +1,12 @@
<?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-28 13:15:28"> <novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-28 14:03:05">
<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>
</project> </project>
<content count="9"> <content count="10">
<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>