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):
nwItem = self.theProject.getItem(tHandle)
itemStatus = nwItem.itemStatus
if itemStatus < 0 or itemStatus >= len(self.theProject.statusLabels):
itemStatus = 0
nwItem = self.theProject.getItem(tHandle)
colTwo = [
nwItem.itemName,
self.theProject.statusLabels[itemStatus],
nwLabels.CLASS_NAME[nwItem.itemClass],
nwLabels.LAYOUT_NAME[nwItem.itemLayout],
]
if nwItem is None:
colTwo = [""]*4
else:
itemStatus = nwItem.itemStatus
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):
lblTwo = QLabel(colTwo[nRow])
+26 -6
View File
@@ -40,6 +40,7 @@ class GuiDocTree(QTreeWidget):
self.theParent = theParent
self.theProject = theProject
self.theMap = {}
self.orphRoot = None
self.setIconSize(QSize(13,13))
self.setExpandsOnDoubleClick(True)
@@ -152,6 +153,8 @@ class GuiDocTree(QTreeWidget):
def saveTreeOrder(self):
theList = []
for i in range(self.topLevelItemCount()):
if self.topLevelItem(i) == self.orphRoot:
continue
theList = self._scanChildren(theList, self.topLevelItem(i), i)
self.theProject.setTreeOrder(theList)
return True
@@ -200,7 +203,12 @@ class GuiDocTree(QTreeWidget):
self.theMap[tHandle] = newItem
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:
self.theMap[pHandle].addChild(newItem)
self.propagateCount(tHandle, nwItem.wordCount)
@@ -210,7 +218,6 @@ class GuiDocTree(QTreeWidget):
if nwItem.itemType == nwItemType.ROOT:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("drive-harddisk"))
self.theParent.mainMenu.setAvailableRoot()
elif nwItem.itemType == nwItemType.FOLDER:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("folder"))
elif nwItem.itemType == nwItemType.FILE:
@@ -218,6 +225,18 @@ class GuiDocTree(QTreeWidget):
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):
trItem = self.theMap[tHandle]
@@ -248,7 +267,7 @@ class GuiDocTree(QTreeWidget):
for i in range(pItem.childCount()):
pCount += int(pItem.child(i).text(self.C_COUNT))
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)
return
@@ -298,14 +317,15 @@ class GuiDocTree(QTreeWidget):
snItem = self.theProject.getItem(sHandle)
dnItem = self.theProject.getItem(dHandle)
isSame = snItem.itemClass == dnItem.itemClass and dnItem.itemType
isNone = snItem.itemClass == nwItemClass.NO_CLASS
isFile = dnItem.itemType == nwItemType.FILE
isRoot = snItem.itemType == nwItemType.ROOT
isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem
if isSame and not (isFile and isOnTop) and not isRoot:
logger.verbose("Drag'n'drop on item %s allowed" % sHandle)
if (isSame or isNone) and not (isFile and isOnTop) and not isRoot:
logger.verbose("Drag'n'drop of item %s accepted" % sHandle)
QTreeWidget.dropEvent(self, theEvent)
else:
logger.verbose("Drag'n'drop on item %s not allowed" % sHandle)
logger.verbose("Drag'n'drop of item %s not accepted" % sHandle)
return
+53 -1
View File
@@ -13,7 +13,7 @@
import logging
import nw
from os import path, mkdir
from os import path, mkdir, listdir
from lxml import etree
from hashlib import sha256
from datetime import datetime
@@ -167,6 +167,8 @@ class NWProject():
self._makeStatusIcons()
self.mainConf.setRecent(self.projPath)
self._scanProjectFolder()
return True
def saveProject(self):
@@ -287,6 +289,56 @@ class NWProject():
# 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):
theDepth = 0
nwItem = self.getItem(tHandle)
@@ -1,3 +1,3 @@
# 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
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'?>
<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>
<name>Sample Project</name>
<title>Sample Project</title>
<author>Jane Smith</author>
<author>Jay Doh</author>
</project>
<content count="9">
<content count="10">
<item handle="7031beac91f75" order="0" parent="None">
<name>Novel</name>
<type>ROOT</type>