From 45095452142b15678e6a3cf40b9f45ad9281e2b7 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Mon, 21 Dec 2020 11:03:47 +0100 Subject: [PATCH] Some minor cleanup and fixes --- nw/core/project.py | 17 ++++++++++- nw/core/tree.py | 2 +- nw/gui/projtree.py | 76 ++++++++++++++++++++++------------------------ 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/nw/core/project.py b/nw/core/project.py index f1af6d5c..1af00534 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -1317,10 +1317,12 @@ class NWProject(): # Handle orphans aDoc = NWDoc(self, self.theParent) nOrph = 0 + noWhere = False for oHandle in orphanFiles: # Look for meta data oName = "" + oParent = None oClass = None oLayout = None if aDoc.openDocument(oHandle, showStatus=False, isOrphan=True) is not None: @@ -1332,16 +1334,23 @@ class NWProject(): nOrph += 1 oName = "Recovered File %d" % nOrph + # Recover file meta data if oClass is None: oClass = nwItemClass.NOVEL + if oLayout is None: oLayout = nwItemLayout.NOTE - if oParent is None or not self.projTree.isValid(oParent): + if oParent is None or not self.projTree.handleExists(oParent): oParent = self.projTree.findRoot(oClass) if oParent is None: oParent = self.projTree.findRoot(nwItemClass.NOVEL) + # If the file still has no parent item, skip it + if oParent is None: + noWhere = True + continue + orphItem = NWItem(self) orphItem.setName(oName) orphItem.setType(nwItemType.FILE) @@ -1349,6 +1358,12 @@ class NWProject(): orphItem.setLayout(oLayout) self.projTree.append(oHandle, oParent, orphItem) + if noWhere: + self.makeAlert(( + "One or more orphaned files could not be added back into the " + "project. Make sure at least a Novel root folder exists." + ), nwAlert.WARN) + return True def _appendSessionStats(self): diff --git a/nw/core/tree.py b/nw/core/tree.py index 6e103ec1..0c59fd7f 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -294,7 +294,7 @@ class NWTree(): tTree.append(tHandle) return tTree - def isValid(self, tHandle): + def handleExists(self, tHandle): """Check if a handle exists in the project. """ return tHandle in self._treeOrder diff --git a/nw/gui/projtree.py b/nw/gui/projtree.py index 28af1b0c..c3fe8c1d 100644 --- a/nw/gui/projtree.py +++ b/nw/gui/projtree.py @@ -61,7 +61,7 @@ class GuiProjectTree(QTreeWidget): self.theIndex = theParent.theIndex # Tree Settings - self.theMap = None + self.theMap = {} self.treeChanged = False self.ctxMenu = GuiProjectTreeMenu(self) @@ -144,10 +144,11 @@ class GuiProjectTree(QTreeWidget): ## def clearTree(self): - """Clear the GUI content and the related maps. + """Clear the GUI content and the related map. """ self.clear() self.theMap = {} + self.treeChanged = False return def newTreeItem(self, itemType, itemClass): @@ -390,14 +391,12 @@ class GuiProjectTree(QTreeWidget): return False msgYes = self.theParent.askQuestion( - "Empty Trash", "Permanently delete %d file%s from Trash?" % ( - nTrash, "s" if nTrash > 1 else "" - ) + "Empty Trash", "Permanently delete %d file(s) from Trash?" % nTrash ) if not msgYes: return False - logger.verbose("Deleting %d files from Trash" % nTrash) + logger.verbose("Deleting %d file(s) from Trash" % nTrash) for tHandle in self.getTreeFromHandle(trashHandle): if tHandle == trashHandle: continue @@ -637,11 +636,7 @@ class GuiProjectTree(QTreeWidget): selected, return the first. """ selItem = self.selectedItems() - - if len(selItem) == 0: - return None - - if isinstance(selItem[0], QTreeWidgetItem): + if selItem: return selItem[0].data(self.C_NAME, Qt.UserRole) return None @@ -660,18 +655,21 @@ class GuiProjectTree(QTreeWidget): def setSelectedHandle(self, tHandle, doScroll=False): """Set a specific handle as the selected item. """ - if tHandle in self.theMap: - self.clearSelection() - self.theMap[tHandle].setSelected(True) + if tHandle not in self.theMap: + return False - selItems = self.selectedIndexes() - if selItems and doScroll: - self.scrollTo( - selItems[0], QAbstractItemView.PositionAtCenter - ) - return True + tItem = self._getTreeItem(tHandle) + if tItem is None: + return False - return False + self.clearSelection() + self.theMap[tHandle].setSelected(True) + + selItems = self.selectedIndexes() + if selItems and doScroll: + self.scrollTo(selItems[0], QAbstractItemView.PositionAtCenter) + + return True ## # Slots @@ -684,14 +682,12 @@ class GuiProjectTree(QTreeWidget): selItem = self.itemAt(clickPos) if isinstance(selItem, QTreeWidgetItem): tHandle = selItem.data(self.C_NAME, Qt.UserRole) - if tHandle is None: - return - self.setSelectedHandle(tHandle) # Just to be safe tItem = self.theProject.projTree[tHandle] - if self.ctxMenu.filterActions(tItem): - # Only open menu if any actions remain after filter - self.ctxMenu.exec_(self.viewport().mapToGlobal(clickPos)) + if tItem is not None: + if self.ctxMenu.filterActions(tItem): + # Only open menu if any actions remain after filter + self.ctxMenu.exec_(self.viewport().mapToGlobal(clickPos)) return @@ -770,7 +766,7 @@ class GuiProjectTree(QTreeWidget): # If the item does not have the same class as the target, # and the target is not a free root folder, update its class - if not isSame and not onFree: + if not (isSame or onFree): logger.debug("Item %s class has been changed from %s to %s" % ( sHandle, snItem.itemClass.name, @@ -803,9 +799,7 @@ class GuiProjectTree(QTreeWidget): def _getTreeItem(self, tHandle): """Returns the QTreeWidgetItem of a given item handle. """ - if tHandle in self.theMap.keys(): - return self.theMap[tHandle] - return None + return self.theMap.get(tHandle, None) def _scanChildren(self, theList, theItem, theIndex): """This is a recursive function returning all items in a tree @@ -829,19 +823,20 @@ class GuiProjectTree(QTreeWidget): tClass = nwItem.itemClass newItem = QTreeWidgetItem([""]*4) - newItem.setText(self.C_NAME, "") - newItem.setText(self.C_COUNT, "0") + newItem.setText(self.C_NAME, "") + newItem.setText(self.C_COUNT, "0") newItem.setText(self.C_EXPORT, "") - newItem.setText(self.C_FLAGS, "") + newItem.setText(self.C_FLAGS, "") - newItem.setTextAlignment(self.C_NAME, Qt.AlignLeft | Qt.AlignVCenter) - newItem.setTextAlignment(self.C_COUNT, Qt.AlignRight | Qt.AlignVCenter) - newItem.setTextAlignment(self.C_EXPORT, Qt.AlignLeft | Qt.AlignVCenter) - newItem.setTextAlignment(self.C_FLAGS, Qt.AlignLeft | Qt.AlignVCenter) + newItem.setTextAlignment(self.C_NAME, Qt.AlignLeft) + newItem.setTextAlignment(self.C_COUNT, Qt.AlignRight) + newItem.setTextAlignment(self.C_EXPORT, Qt.AlignLeft) + newItem.setTextAlignment(self.C_FLAGS, Qt.AlignLeft) newItem.setData(self.C_NAME, Qt.UserRole, tHandle) newItem.setData(self.C_COUNT, Qt.UserRole, 0) + self.theMap[tHandle] = newItem if pHandle is None: if nwItem.itemType == nwItemType.ROOT: self.addTopLevelItem(newItem) @@ -850,9 +845,11 @@ class GuiProjectTree(QTreeWidget): self.addTopLevelItem(newItem) else: self.makeAlert( - "There is nowhere to add file with name '%s'" % nwItem.itemName, nwAlert.ERROR + "There is nowhere to add item with name '%s'" % nwItem.itemName, nwAlert.ERROR ) + del self.theMap[tHandle] return None + else: byIndex = -1 if nHandle is not None and nHandle in self.theMap: @@ -866,7 +863,6 @@ class GuiProjectTree(QTreeWidget): self.theMap[pHandle].addChild(newItem) self.propagateCount(tHandle, nwItem.wordCount) - self.theMap[tHandle] = newItem self.setTreeItemValues(tHandle) newItem.setExpanded(nwItem.isExpanded)