Can now restore document label for orphaned files

This commit is contained in:
Veronica K. B. Olsen
2020-05-09 13:59:57 +02:00
parent d44dca6a21
commit 75adcdf679
4 changed files with 82 additions and 14 deletions
+17
View File
@@ -77,6 +77,20 @@ def checkBool(checkValue, defaultValue, allowNone=False):
return defaultValue
return defaultValue
def isHandle(theString):
"""Check if a string is a valid novelWriter handle.
Note: This is case sensitive. Must be lower case!
"""
if not isinstance(theString, str):
return False
if len(theString) != 13:
return False
invalidChar = False
for c in theString:
if c not in "0123456789abcdef":
invalidChar = True
return not invalidChar
def colRange(rgbStart, rgbEnd, nStep):
if len(rgbStart) != 3 and len(rgbEnd) != 3 and nStep < 1:
@@ -127,6 +141,9 @@ def formatInt(theInt):
return "%d" % theInt
def formatTimeStamp(theTime, fileSafe=False):
"""Take a number (on the format returned by time.time()) and convert
it to a timestamp string.
"""
if fileSafe:
return datetime.fromtimestamp(theTime).strftime(nwConst.fStampFmt)
else:
+52 -11
View File
@@ -31,6 +31,7 @@ import nw
from os import path, mkdir, rename, unlink
from nw.constants import nwAlert
from nw.common import isHandle
logger = logging.getLogger(__name__)
@@ -68,25 +69,29 @@ class NWDoc():
self.docMeta = ""
return
def openDocument(self, tHandle, showStatus=True):
def openDocument(self, tHandle, showStatus=True, isOrphan=False):
"""Open a document from handle, capturing potential file system
errors and parse meta data.
"""
self.docHandle = tHandle
self.theItem = self.theProject.projTree[tHandle]
if not isOrphan:
self.theItem = self.theProject.projTree[tHandle]
else:
self.theItem = None
if self.theItem is None:
if self.theItem is None and not isOrphan:
self.clearDocument()
return None
# By default, the document is editable.
# Except for files in the trash folder.
self.docEditable = True
if self.theItem.parHandle == self.theProject.projTree.trashRoot():
self.docEditable = False
if self.theItem is not None:
if self.theItem.parHandle == self.theProject.projTree.trashRoot():
self.docEditable = False
docDir, docFile = self.assemblePath(self.docHandle, self.FILE_MN)
docDir, docFile = self._assemblePath(self.docHandle, self.FILE_MN)
self.fileLoc = path.join(docDir,docFile)
logger.debug("Opening document %s" % self.fileLoc)
dataDir = path.join(self.theProject.projPath, docDir)
@@ -100,7 +105,7 @@ class NWDoc():
fstLine = inFile.readline()
if fstLine.startswith("%%~ "):
# This is the meta line
self.docMeta = fstLine.strip()
self.docMeta = fstLine[4:].strip()
else:
theText = fstLine
theText += inFile.read()
@@ -120,7 +125,7 @@ class NWDoc():
logger.verbose("DocMeta: '%s'" % self.docMeta)
if showStatus:
if showStatus and not isOrphan:
self.theParent.statusBar.setStatus("Opened Document: %s" % self.theItem.itemName)
return theText
@@ -133,7 +138,7 @@ class NWDoc():
if self.docHandle is None or not self.docEditable:
return False
docDir, docFile = self.assemblePath(self.docHandle, self.FILE_MN)
docDir, docFile = self._assemblePath(self.docHandle, self.FILE_MN)
logger.debug("Saving document %s" % path.join(docDir,docFile))
dataPath = path.join(self.theProject.projPath, docDir)
docPath = path.join(dataPath, docFile)
@@ -171,7 +176,7 @@ class NWDoc():
"""Permanently delete a document source file and its backups
from the project data folder.
"""
docDir, docFile = self.assemblePath(tHandle, self.FILE_MN)
docDir, docFile = self._assemblePath(tHandle, self.FILE_MN)
dataPath = path.join(self.theProject.projPath, docDir)
chkList = []
chkList.append(path.join(dataPath, docFile))
@@ -187,8 +192,44 @@ class NWDoc():
return False
return True
##
# Getters
##
def getMeta(self):
"""Parses the document meta tag and returns the path and name as
a list and a string.
"""
if len(self.docMeta) < 14:
# Not enough information
return "", []
theMeta = self.docMeta
# Scan for handles
thePath = []
for n in range(200):
if len(theMeta) < 14:
break
if theMeta[13] == ":":
theHandle = theMeta[:13]
if isHandle(theHandle):
thePath.append(theHandle)
theMeta = theMeta[14:]
else:
break
else:
break
return theMeta, thePath
##
# Internal Functions
##
@staticmethod
def assemblePath(tHandle, docExt):
def _assemblePath(tHandle, docExt):
if tHandle is None:
return None, None
docDir = "data_"+tHandle[0]
+12 -2
View File
@@ -41,6 +41,7 @@ from shutil import make_archive
from nw.gui.tools import OptionState
from nw.core.tools import projectMaintenance
from nw.core.document import NWDoc
from nw.common import checkString, checkBool, checkInt, formatTimeStamp
from nw.constants import (
nwFiles, nwConst, nwItemType, nwItemClass, nwItemLayout, nwAlert
@@ -913,11 +914,20 @@ class NWProject():
return
# Handle orphans
aDoc = NWDoc(self, self.theParent)
nOrph = 0
for oHandle in orphanFiles:
nOrph += 1
# Look for meta data
if aDoc.openDocument(oHandle, showStatus=False, isOrphan=True):
oName, oPath = aDoc.getMeta()
aDoc.clearDocument()
else:
nOrph += 1
oName = "Orphaned File %d" % nOrph
orphItem = NWItem(self)
orphItem.setName("Orphaned File %d" % nOrph)
orphItem.setName(oName)
orphItem.setType(nwItemType.FILE)
orphItem.setClass(nwItemClass.NO_CLASS)
orphItem.setLayout(nwItemLayout.NO_LAYOUT)
+1 -1
View File
@@ -404,7 +404,7 @@ class GuiMain(QMainWindow):
else:
return False
# project is loaded
# Project is loaded
self.hasProject = True
# Load the tag index