Improve the way the project tree is managed and elements deleted.
This commit is contained in:
@@ -82,6 +82,18 @@ def checkBool(checkValue, defaultValue, allowNone=False):
|
||||
return defaultValue
|
||||
return defaultValue
|
||||
|
||||
def checkHandle(checkValue, defaultValue, allowNone=False):
|
||||
"""Check if a value is a handle.
|
||||
"""
|
||||
if allowNone:
|
||||
if checkValue is None:
|
||||
return None
|
||||
if checkValue == "None":
|
||||
return None
|
||||
if isHandle(checkValue):
|
||||
return str(checkValue)
|
||||
return defaultValue
|
||||
|
||||
def isHandle(theString):
|
||||
"""Check if a string is a valid novelWriter handle.
|
||||
Note: This is case sensitive. Must be lower case!
|
||||
|
||||
+20
-21
@@ -34,7 +34,7 @@ from hashlib import sha256
|
||||
from time import time
|
||||
|
||||
from nw.core.item import NWItem
|
||||
from nw.common import checkString
|
||||
from nw.common import checkHandle
|
||||
from nw.constants import nwFiles, nwItemType, nwItemClass, nwItemLayout, nwConst
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -49,7 +49,6 @@ class NWTree():
|
||||
self._treeOrder = [] # The order of the tree items on the tree view
|
||||
self._treeRoots = [] # The root items of the tree
|
||||
self._trashRoot = None # The handle of the trash root folder
|
||||
self._theLength = 0 # Always the length of _treeOrder
|
||||
self._theIndex = 0 # The current iterator index
|
||||
self._treeChanged = False # True if tree structure has changed
|
||||
self._handleSeed = None # Used for generating handles for testing
|
||||
@@ -68,7 +67,6 @@ class NWTree():
|
||||
self._treeRoots = []
|
||||
self._trashRoot = None
|
||||
self._archRoot = None
|
||||
self._theLength = 0
|
||||
self._theIndex = 0
|
||||
self._treeChanged = False
|
||||
return
|
||||
@@ -81,8 +79,8 @@ class NWTree():
|
||||
def append(self, tHandle, pHandle, nwItem):
|
||||
"""Add a new item to the end of the tree.
|
||||
"""
|
||||
tHandle = checkString(tHandle, None, True)
|
||||
pHandle = checkString(pHandle, None, True)
|
||||
tHandle = checkHandle(tHandle, None, True)
|
||||
pHandle = checkHandle(pHandle, None, True)
|
||||
if tHandle is None:
|
||||
tHandle = self._makeHandle()
|
||||
|
||||
@@ -108,16 +106,16 @@ class NWTree():
|
||||
else:
|
||||
logger.error("Only one trash folder allowed")
|
||||
|
||||
self._theLength = len(self._treeOrder)
|
||||
self._setTreeChanged(True)
|
||||
|
||||
return
|
||||
|
||||
def packXML(self, xParent):
|
||||
"""Pack the content of the tree into an XML object.
|
||||
"""Pack the content of the tree into the provided XML object. In
|
||||
the order defined by the _treeOrder list.
|
||||
"""
|
||||
xContent = etree.SubElement(xParent, "content", attrib={
|
||||
"count": str(self._theLength)}
|
||||
"count": str(len(self._treeOrder))}
|
||||
)
|
||||
for tHandle in self._treeOrder:
|
||||
tItem = self.__getitem__(tHandle)
|
||||
@@ -309,7 +307,6 @@ class NWTree():
|
||||
|
||||
# Save the temp list
|
||||
self._treeOrder = tmpOrder
|
||||
self._theLength = len(self._treeOrder)
|
||||
self._setTreeChanged(True)
|
||||
logger.verbose("Project tree order updated")
|
||||
|
||||
@@ -330,7 +327,7 @@ class NWTree():
|
||||
if tItem is None:
|
||||
return False
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
logger.error("Item '%s' is not a file" % tHandle)
|
||||
logger.error("Item %s is not a file" % tHandle)
|
||||
return False
|
||||
if not isinstance(itemLayout, nwItemLayout):
|
||||
return False
|
||||
@@ -370,12 +367,12 @@ class NWTree():
|
||||
def __len__(self):
|
||||
"""Return the length counter. Does not check that it is correct!
|
||||
"""
|
||||
return self._theLength
|
||||
return len(self._treeOrder)
|
||||
|
||||
def __bool__(self):
|
||||
"""Returns True if the tree has any entries.
|
||||
"""
|
||||
return self._theLength > 0
|
||||
return len(self._treeOrder) > 0
|
||||
|
||||
##
|
||||
# Item Access Methods
|
||||
@@ -391,19 +388,21 @@ class NWTree():
|
||||
return None
|
||||
|
||||
def __delitem__(self, tHandle):
|
||||
"""This only removes the item from the order list, but not from
|
||||
the project tree.
|
||||
"""Remove an item from the internal lists and dictionaries.
|
||||
"""
|
||||
if tHandle not in self._treeOrder:
|
||||
logger.warning(
|
||||
"Could not remove item %s from project tree as it does not exist" % tHandle
|
||||
)
|
||||
if tHandle in self._treeOrder and tHandle in self._projTree:
|
||||
self._treeOrder.remove(tHandle)
|
||||
del self._projTree[tHandle]
|
||||
else:
|
||||
logger.warning("Failed to delete item %s: item not found" % tHandle)
|
||||
return False
|
||||
self._treeOrder.remove(tHandle)
|
||||
self._theLength = len(self._treeOrder)
|
||||
|
||||
if tHandle in self._treeRoots:
|
||||
self._treeRoots.remove(tHandle)
|
||||
if tHandle == self._trashRoot:
|
||||
self._trashRoot = None
|
||||
if tHandle == self._archRoot:
|
||||
self._archRoot = None
|
||||
|
||||
self._setTreeChanged(True)
|
||||
|
||||
@@ -427,7 +426,7 @@ class NWTree():
|
||||
def __next__(self):
|
||||
"""Returns the item from the next entry in the _treeOrder list.
|
||||
"""
|
||||
if self._theIndex < self._theLength:
|
||||
if self._theIndex < len(self._treeOrder):
|
||||
theItem = self.__getitem__(self._treeOrder[self._theIndex])
|
||||
self._theIndex += 1
|
||||
return theItem
|
||||
|
||||
+5
-5
@@ -378,11 +378,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
return True
|
||||
|
||||
def deleteItem(self, tHandle=None, alreadyAsked=False, askForTrash=False):
|
||||
"""Delete items from the tree. Note that this does not delete
|
||||
the item from the item tree in the project object. However,
|
||||
since this is only meta data, there isn't really a need to do
|
||||
that to save memory. Items not in the tree are not saved to the
|
||||
project file, so a loaded project will be clean anyway.
|
||||
"""Delete an item from the project tree. As a first step, files are
|
||||
moved to the Trash folder. Permanent deletion is a second step. This
|
||||
second step also deletes the item from the project object as well as
|
||||
delete the files on disk. Folders are deleted if they're empty only,
|
||||
and the deletion is always permanent.
|
||||
"""
|
||||
if tHandle is None:
|
||||
tHandle = self.getSelectedHandle()
|
||||
|
||||
+10
-1
@@ -5,7 +5,7 @@
|
||||
import pytest
|
||||
from nw.common import (
|
||||
checkString, checkBool, checkInt, colRange, formatInt, transferCase,
|
||||
fuzzyTime
|
||||
fuzzyTime, checkHandle
|
||||
)
|
||||
from nwtools import cmpList
|
||||
|
||||
@@ -42,6 +42,15 @@ def testCheckBool():
|
||||
assert checkBool(1.0, None, False) is None
|
||||
assert checkBool(2.0, None, False) is None
|
||||
|
||||
@pytest.mark.core
|
||||
def testCheckHandle():
|
||||
assert checkHandle("None", 1, True) is None
|
||||
assert checkHandle("None", 1, False) == 1
|
||||
assert checkHandle(None, 1, True) is None
|
||||
assert checkHandle(None, 1, False) == 1
|
||||
assert checkHandle("47666c91c7ccf", None, False) == "47666c91c7ccf"
|
||||
assert checkHandle("h7666c91c7ccf", None, False) is None
|
||||
|
||||
@pytest.mark.core
|
||||
def testColRange():
|
||||
assert colRange([0, 0], [0, 0], 0) is None
|
||||
|
||||
Reference in New Issue
Block a user