Added code to create trash folder when needed.
This commit is contained in:
@@ -23,6 +23,7 @@ class nwLabels():
|
|||||||
nwItemClass.TIMELINE : "Timeline",
|
nwItemClass.TIMELINE : "Timeline",
|
||||||
nwItemClass.OBJECT : "Objects",
|
nwItemClass.OBJECT : "Objects",
|
||||||
nwItemClass.CUSTOM : "Custom",
|
nwItemClass.CUSTOM : "Custom",
|
||||||
|
nwItemClass.TRASH : "Trash",
|
||||||
}
|
}
|
||||||
CLASS_FLAG = {
|
CLASS_FLAG = {
|
||||||
nwItemClass.NO_CLASS : "0",
|
nwItemClass.NO_CLASS : "0",
|
||||||
@@ -33,6 +34,7 @@ class nwLabels():
|
|||||||
nwItemClass.TIMELINE : "T",
|
nwItemClass.TIMELINE : "T",
|
||||||
nwItemClass.OBJECT : "O",
|
nwItemClass.OBJECT : "O",
|
||||||
nwItemClass.CUSTOM : "X",
|
nwItemClass.CUSTOM : "X",
|
||||||
|
nwItemClass.TRASH : "R",
|
||||||
}
|
}
|
||||||
LAYOUT_NAME = {
|
LAYOUT_NAME = {
|
||||||
nwItemLayout.NO_LAYOUT : "None",
|
nwItemLayout.NO_LAYOUT : "None",
|
||||||
|
|||||||
+2
-1
@@ -18,7 +18,7 @@ class nwItemType(Enum):
|
|||||||
ROOT = 1
|
ROOT = 1
|
||||||
FOLDER = 2
|
FOLDER = 2
|
||||||
FILE = 3
|
FILE = 3
|
||||||
TRASHFOLDER = 4
|
TRASH = 4
|
||||||
TRASHFILE = 5
|
TRASHFILE = 5
|
||||||
|
|
||||||
# END Enum nwItemType
|
# END Enum nwItemType
|
||||||
@@ -33,6 +33,7 @@ class nwItemClass(Enum):
|
|||||||
TIMELINE = 5
|
TIMELINE = 5
|
||||||
OBJECT = 6
|
OBJECT = 6
|
||||||
CUSTOM = 7
|
CUSTOM = 7
|
||||||
|
TRASH = 8
|
||||||
|
|
||||||
# END Enum nwItemClass
|
# END Enum nwItemClass
|
||||||
|
|
||||||
|
|||||||
+123
-113
@@ -76,6 +76,10 @@ class GuiDocTree(QTreeWidget):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
##
|
||||||
|
# Class Methods
|
||||||
|
##
|
||||||
|
|
||||||
def clearTree(self):
|
def clearTree(self):
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
@@ -164,18 +168,6 @@ class GuiDocTree(QTreeWidget):
|
|||||||
cItem.setSelected(True)
|
cItem.setSelected(True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def renameTreeItem(self, tHandle):
|
|
||||||
tItem = self.theMap[tHandle]
|
|
||||||
oldName = tItem.text(self.C_NAME)
|
|
||||||
newName, isOk = QInputDialog.getText(self, "Rename Item", "New Name", QLineEdit.Normal,oldName)
|
|
||||||
if isOk:
|
|
||||||
newName = newName.strip()
|
|
||||||
if newName == "":
|
|
||||||
newName = oldName
|
|
||||||
tItem.setText(self.C_NAME,newName)
|
|
||||||
self.theProject.setItemName(tHandle, newName)
|
|
||||||
return
|
|
||||||
|
|
||||||
def saveTreeOrder(self):
|
def saveTreeOrder(self):
|
||||||
theList = []
|
theList = []
|
||||||
for i in range(self.topLevelItemCount()):
|
for i in range(self.topLevelItemCount()):
|
||||||
@@ -193,107 +185,12 @@ class GuiDocTree(QTreeWidget):
|
|||||||
]
|
]
|
||||||
return retVals
|
return retVals
|
||||||
|
|
||||||
##
|
def deleteItem(self):
|
||||||
# Internal Functions
|
tHandle = self.getSelectedHandle()
|
||||||
##
|
nwItem = self.theProject.getItem(tHandle)
|
||||||
|
if nwItem.itemType == nwItemType.FILE:
|
||||||
def _scanChildren(self, theList, theItem, theIndex):
|
logger.debug("User requested item %s moved to trash" % tHandle)
|
||||||
tHandle = theItem.text(self.C_HANDLE)
|
self._addTrashRoot()
|
||||||
nwItem = self.theProject.projTree[tHandle]
|
|
||||||
nwItem.setExpanded(theItem.isExpanded())
|
|
||||||
nwItem.setOrder(theIndex)
|
|
||||||
theList.append(tHandle)
|
|
||||||
for i in range(theItem.childCount()):
|
|
||||||
self._scanChildren(theList, theItem.child(i), i)
|
|
||||||
return theList
|
|
||||||
|
|
||||||
def _scanParents(self, theItem, theCount=0):
|
|
||||||
if theItem.parent() is not None:
|
|
||||||
theItem, theCount = self._scanParents(theItem.parent(), theCount)
|
|
||||||
return theItem, theCount+1
|
|
||||||
|
|
||||||
def _addTreeItem(self, nwItem):
|
|
||||||
|
|
||||||
tHandle = nwItem.itemHandle
|
|
||||||
pHandle = nwItem.parHandle
|
|
||||||
newItem = QTreeWidgetItem([""]*4)
|
|
||||||
|
|
||||||
newItem.setText(self.C_NAME, "")
|
|
||||||
newItem.setText(self.C_COUNT, "0")
|
|
||||||
newItem.setText(self.C_FLAGS, "")
|
|
||||||
newItem.setText(self.C_HANDLE, tHandle)
|
|
||||||
|
|
||||||
newItem.setForeground(self.C_COUNT,QColor(0,105,135))
|
|
||||||
newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight)
|
|
||||||
newItem.setFont(self.C_FLAGS,self.fontFlags)
|
|
||||||
|
|
||||||
self.theMap[tHandle] = newItem
|
|
||||||
if pHandle is None:
|
|
||||||
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)
|
|
||||||
|
|
||||||
self.setTreeItemValues(tHandle)
|
|
||||||
newItem.setExpanded(nwItem.isExpanded)
|
|
||||||
|
|
||||||
if nwItem.itemType == nwItemType.ROOT:
|
|
||||||
newItem.setIcon(self.C_NAME, QIcon.fromTheme("drive-harddisk"))
|
|
||||||
elif nwItem.itemType == nwItemType.FOLDER:
|
|
||||||
newItem.setIcon(self.C_NAME, QIcon.fromTheme("folder"))
|
|
||||||
elif nwItem.itemType == nwItemType.FILE:
|
|
||||||
newItem.setIcon(self.C_NAME, QIcon.fromTheme("x-office-document"))
|
|
||||||
|
|
||||||
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 _cleanOrphanedRoot(self):
|
|
||||||
if self.orphRoot.childCount() == 0:
|
|
||||||
self.takeTopLevelItem(self.indexOfTopLevelItem(self.orphRoot))
|
|
||||||
self.orphRoot = None
|
|
||||||
return
|
|
||||||
|
|
||||||
def _updateItemParent(self, tHandle):
|
|
||||||
trItemS = self.theMap[tHandle]
|
|
||||||
nwItemS = self.theProject.getItem(tHandle)
|
|
||||||
trItemP = trItemS.parent()
|
|
||||||
if trItemP is None:
|
|
||||||
logger.error("Failed to find new parent item of %s" % tHandle)
|
|
||||||
return
|
|
||||||
pHandle = trItemP.text(self.C_HANDLE)
|
|
||||||
nwItemS.setParent(pHandle)
|
|
||||||
self.setTreeItemValues(tHandle)
|
|
||||||
return
|
|
||||||
|
|
||||||
def _moveOrphanedItem(self, tHandle, dHandle):
|
|
||||||
trItemS = self.theMap[tHandle]
|
|
||||||
nwItemS = self.theProject.getItem(tHandle)
|
|
||||||
nwItemD = self.theProject.getItem(dHandle)
|
|
||||||
trItemP = trItemS.parent()
|
|
||||||
nwItemS.setClass(nwItemD.itemClass)
|
|
||||||
if trItemP is None:
|
|
||||||
logger.error("Failed to find new parent item of %s" % tHandle)
|
|
||||||
return
|
|
||||||
pHandle = trItemP.text(self.C_HANDLE)
|
|
||||||
nwItemS.setParent(pHandle)
|
|
||||||
nwItemS.setDepth(self.theProject.countItemDepth(tHandle))
|
|
||||||
self.setTreeItemValues(tHandle)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def setTreeItemValues(self, tHandle):
|
def setTreeItemValues(self, tHandle):
|
||||||
@@ -345,6 +242,119 @@ class GuiDocTree(QTreeWidget):
|
|||||||
return selItem[0].text(self.C_HANDLE)
|
return selItem[0].text(self.C_HANDLE)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
##
|
||||||
|
# Internal Functions
|
||||||
|
##
|
||||||
|
|
||||||
|
def _scanChildren(self, theList, theItem, theIndex):
|
||||||
|
tHandle = theItem.text(self.C_HANDLE)
|
||||||
|
nwItem = self.theProject.projTree[tHandle]
|
||||||
|
nwItem.setExpanded(theItem.isExpanded())
|
||||||
|
nwItem.setOrder(theIndex)
|
||||||
|
theList.append(tHandle)
|
||||||
|
for i in range(theItem.childCount()):
|
||||||
|
self._scanChildren(theList, theItem.child(i), i)
|
||||||
|
return theList
|
||||||
|
|
||||||
|
def _scanParents(self, theItem, theCount=0):
|
||||||
|
if theItem.parent() is not None:
|
||||||
|
theItem, theCount = self._scanParents(theItem.parent(), theCount)
|
||||||
|
return theItem, theCount+1
|
||||||
|
|
||||||
|
def _addTreeItem(self, nwItem):
|
||||||
|
|
||||||
|
tHandle = nwItem.itemHandle
|
||||||
|
pHandle = nwItem.parHandle
|
||||||
|
newItem = QTreeWidgetItem([""]*4)
|
||||||
|
|
||||||
|
newItem.setText(self.C_NAME, "")
|
||||||
|
newItem.setText(self.C_COUNT, "0")
|
||||||
|
newItem.setText(self.C_FLAGS, "")
|
||||||
|
newItem.setText(self.C_HANDLE, tHandle)
|
||||||
|
|
||||||
|
newItem.setForeground(self.C_COUNT,QColor(0,105,135))
|
||||||
|
newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight)
|
||||||
|
newItem.setFont(self.C_FLAGS,self.fontFlags)
|
||||||
|
|
||||||
|
self.theMap[tHandle] = newItem
|
||||||
|
if pHandle is None:
|
||||||
|
if nwItem.itemType == nwItemType.ROOT:
|
||||||
|
self.addTopLevelItem(newItem)
|
||||||
|
self.theParent.mainMenu.setAvailableRoot()
|
||||||
|
elif nwItem.itemType == nwItemType.TRASH:
|
||||||
|
self.addTopLevelItem(newItem)
|
||||||
|
else:
|
||||||
|
self._addOrphanedRoot()
|
||||||
|
self.orphRoot.addChild(newItem)
|
||||||
|
else:
|
||||||
|
self.theMap[pHandle].addChild(newItem)
|
||||||
|
self.propagateCount(tHandle, nwItem.wordCount)
|
||||||
|
|
||||||
|
self.setTreeItemValues(tHandle)
|
||||||
|
newItem.setExpanded(nwItem.isExpanded)
|
||||||
|
|
||||||
|
if nwItem.itemType == nwItemType.ROOT:
|
||||||
|
newItem.setIcon(self.C_NAME, QIcon.fromTheme("drive-harddisk"))
|
||||||
|
elif nwItem.itemType == nwItemType.FOLDER:
|
||||||
|
newItem.setIcon(self.C_NAME, QIcon.fromTheme("folder"))
|
||||||
|
elif nwItem.itemType == nwItemType.FILE:
|
||||||
|
newItem.setIcon(self.C_NAME, QIcon.fromTheme("x-office-document"))
|
||||||
|
elif nwItem.itemType == nwItemType.TRASH:
|
||||||
|
newItem.setIcon(self.C_NAME, QIcon.fromTheme("user-trash"))
|
||||||
|
|
||||||
|
return newItem
|
||||||
|
|
||||||
|
def _addTrashRoot(self):
|
||||||
|
if self.theProject.trashRoot is None:
|
||||||
|
self.theProject.addTrash()
|
||||||
|
self._addTreeItem(self.theProject.getItem(self.theProject.trashRoot))
|
||||||
|
return
|
||||||
|
|
||||||
|
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 _cleanOrphanedRoot(self):
|
||||||
|
if self.orphRoot.childCount() == 0:
|
||||||
|
self.takeTopLevelItem(self.indexOfTopLevelItem(self.orphRoot))
|
||||||
|
self.orphRoot = None
|
||||||
|
return
|
||||||
|
|
||||||
|
def _updateItemParent(self, tHandle):
|
||||||
|
trItemS = self.theMap[tHandle]
|
||||||
|
nwItemS = self.theProject.getItem(tHandle)
|
||||||
|
trItemP = trItemS.parent()
|
||||||
|
if trItemP is None:
|
||||||
|
logger.error("Failed to find new parent item of %s" % tHandle)
|
||||||
|
return
|
||||||
|
pHandle = trItemP.text(self.C_HANDLE)
|
||||||
|
nwItemS.setParent(pHandle)
|
||||||
|
self.setTreeItemValues(tHandle)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _moveOrphanedItem(self, tHandle, dHandle):
|
||||||
|
trItemS = self.theMap[tHandle]
|
||||||
|
nwItemS = self.theProject.getItem(tHandle)
|
||||||
|
nwItemD = self.theProject.getItem(dHandle)
|
||||||
|
trItemP = trItemS.parent()
|
||||||
|
nwItemS.setClass(nwItemD.itemClass)
|
||||||
|
if trItemP is None:
|
||||||
|
logger.error("Failed to find new parent item of %s" % tHandle)
|
||||||
|
return
|
||||||
|
pHandle = trItemP.text(self.C_HANDLE)
|
||||||
|
nwItemS.setParent(pHandle)
|
||||||
|
nwItemS.setDepth(self.theProject.countItemDepth(tHandle))
|
||||||
|
self.setTreeItemValues(tHandle)
|
||||||
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Event Overloading
|
# Event Overloading
|
||||||
##
|
##
|
||||||
|
|||||||
+6
-4
@@ -54,10 +54,11 @@ class GuiMainMenu(QMenuBar):
|
|||||||
|
|
||||||
def setAvailableRoot(self):
|
def setAvailableRoot(self):
|
||||||
for itemClass in nwItemClass:
|
for itemClass in nwItemClass:
|
||||||
if itemClass != nwItemClass.NO_CLASS:
|
if itemClass == nwItemClass.NO_CLASS: continue
|
||||||
self.rootItems[itemClass].setEnabled(
|
if itemClass == nwItemClass.TRASH: continue
|
||||||
self.theProject.checkRootUnique(itemClass)
|
self.rootItems[itemClass].setEnabled(
|
||||||
)
|
self.theProject.checkRootUnique(itemClass)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def updateRecentProjects(self):
|
def updateRecentProjects(self):
|
||||||
@@ -186,6 +187,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
menuItem = QAction(QIcon.fromTheme("edit-delete"), "&Delete Item", self)
|
menuItem = QAction(QIcon.fromTheme("edit-delete"), "&Delete Item", self)
|
||||||
menuItem.setStatusTip("Delete Selected Item")
|
menuItem.setStatusTip("Delete Selected Item")
|
||||||
menuItem.setShortcut("Ctrl+Del")
|
menuItem.setShortcut("Ctrl+Del")
|
||||||
|
menuItem.triggered.connect(self.theParent.treeView.deleteItem)
|
||||||
self.projMenu.addAction(menuItem)
|
self.projMenu.addAction(menuItem)
|
||||||
|
|
||||||
# Project > Separator
|
# Project > Separator
|
||||||
|
|||||||
+22
-5
@@ -38,6 +38,7 @@ class NWProject():
|
|||||||
self.projTree = None
|
self.projTree = None
|
||||||
self.treeOrder = None
|
self.treeOrder = None
|
||||||
self.treeRoots = None
|
self.treeRoots = None
|
||||||
|
self.trashRoot = None
|
||||||
self.projPath = None
|
self.projPath = None
|
||||||
self.projFile = None
|
self.projFile = None
|
||||||
self.projName = None
|
self.projName = None
|
||||||
@@ -52,7 +53,7 @@ class NWProject():
|
|||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Add Entries
|
# Item Methods
|
||||||
##
|
##
|
||||||
|
|
||||||
def newRoot(self, rootName, rootClass):
|
def newRoot(self, rootName, rootClass):
|
||||||
@@ -83,6 +84,18 @@ class NWProject():
|
|||||||
self._appendItem(None,pHandle,newItem)
|
self._appendItem(None,pHandle,newItem)
|
||||||
return newItem.itemHandle
|
return newItem.itemHandle
|
||||||
|
|
||||||
|
def addTrash(self):
|
||||||
|
newItem = NWItem()
|
||||||
|
newItem.setName("Trash")
|
||||||
|
newItem.setType(nwItemType.TRASH)
|
||||||
|
newItem.setClass(nwItemClass.TRASH)
|
||||||
|
self._appendItem(None,None,newItem)
|
||||||
|
return newItem.itemHandle
|
||||||
|
|
||||||
|
##
|
||||||
|
# Project Methods
|
||||||
|
##
|
||||||
|
|
||||||
def newProject(self):
|
def newProject(self):
|
||||||
|
|
||||||
self.clearProject()
|
self.clearProject()
|
||||||
@@ -101,6 +114,7 @@ class NWProject():
|
|||||||
self.projTree = {}
|
self.projTree = {}
|
||||||
self.treeOrder = []
|
self.treeOrder = []
|
||||||
self.treeRoots = []
|
self.treeRoots = []
|
||||||
|
self.trashRoot = None
|
||||||
self.projPath = None
|
self.projPath = None
|
||||||
self.projFile = "nwProject.nwx"
|
self.projFile = "nwProject.nwx"
|
||||||
self.projName = ""
|
self.projName = ""
|
||||||
@@ -119,10 +133,6 @@ class NWProject():
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
|
||||||
# File I/O
|
|
||||||
##
|
|
||||||
|
|
||||||
def openProject(self, fileName):
|
def openProject(self, fileName):
|
||||||
|
|
||||||
if not path.isfile(fileName):
|
if not path.isfile(fileName):
|
||||||
@@ -390,6 +400,13 @@ class NWProject():
|
|||||||
logger.verbose("Entry %s is a root item" % str(tHandle))
|
logger.verbose("Entry %s is a root item" % str(tHandle))
|
||||||
self.treeRoots.append(tHandle)
|
self.treeRoots.append(tHandle)
|
||||||
|
|
||||||
|
if nwItem.itemType == nwItemType.TRASH:
|
||||||
|
if self.trashRoot is None:
|
||||||
|
logger.verbose("Entry %s is the trash folder" % str(tHandle))
|
||||||
|
self.trashRoot = tHandle
|
||||||
|
else:
|
||||||
|
logger.error("Only one trash folder allowed")
|
||||||
|
|
||||||
itemDepth = self.countItemDepth(tHandle)
|
itemDepth = self.countItemDepth(tHandle)
|
||||||
if itemDepth is None:
|
if itemDepth is None:
|
||||||
logger.error("The depth of entry %s could not be determined" % tHandle)
|
logger.error("The depth of entry %s could not be determined" % tHandle)
|
||||||
|
|||||||
Reference in New Issue
Block a user