Complete build initial tree and save tree logic

This commit is contained in:
Veronica Berglyd Olsen
2024-11-17 21:24:55 +01:00
parent cbe557507f
commit 27b3dde6f6
5 changed files with 121 additions and 34 deletions
+2
View File
@@ -256,6 +256,8 @@ class NWItem:
self._paraCount = 0
self._cursorPos = 0
self._initCount = self._wordCount
return True
@classmethod
+49 -12
View File
@@ -60,13 +60,17 @@ class ProjectNode:
def __init__(self, item: NWItem) -> None:
self._item = item
self._children = []
self._children: list[ProjectNode] = []
self._parent: ProjectNode | None = None
self._row = 0
self._cache: dict[int, str | QIcon | Qt.AlignmentFlag] = {}
self.refresh()
return
@property
def item(self) -> NWItem:
return self._item
def refresh(self) -> None:
cache: dict[int, str | QIcon | Qt.AlignmentFlag] = {}
@@ -132,17 +136,38 @@ class ProjectNode:
self.refresh()
return
def allChildren(self) -> list[ProjectNode]:
nodes: list[ProjectNode] = []
self._recursiveAppendChildren(nodes)
return nodes
##
# Internal Functions
##
def _recursiveAppendChildren(self, children: list[ProjectNode]) -> None:
for node in self._children:
children.append(node)
node._recursiveAppendChildren(children)
return
class ProjectModel(QAbstractItemModel):
__slots__ = ("_root", "_map")
def __init__(self, tree: NWTree) -> None:
super().__init__(None)
self._root = ProjectNode(NWItem(tree._project, ""))
return
def setRoot(self, root: ProjectNode) -> None:
self._root = root
return
@property
def root(self) -> ProjectNode:
return self._root
##
# Model Access
##
def rowCount(self, index: QModelIndex) -> int:
if index.isValid():
@@ -159,7 +184,7 @@ class ProjectModel(QAbstractItemModel):
return QModelIndex()
def index(self, row: int, column: int, parent: QModelIndex = QModelIndex()) -> QModelIndex:
if parent and parent.isValid():
if parent.isValid():
item = parent.internalPointer()
else:
item = self._root
@@ -178,10 +203,22 @@ class ProjectModel(QAbstractItemModel):
node = index.internalPointer()
return node.data(index.column(), role)
def addChild(self, node: ProjectNode, parent: QModelIndex) -> None:
if parent and parent.isValid():
item = parent.internalPointer()
else:
item = self._root
item.addChild(node)
return
# def addChild(self, node: ProjectNode, parent: QModelIndex) -> None:
# if parent.isValid():
# item = parent.internalPointer()
# else:
# item = self._root
# item.addChild(node)
# return
##
# Methods
##
def allExpanded(self) -> list[QModelIndex]:
"""Return a list of all expanded items."""
expanded = []
for node in self._root.allChildren():
if node._item.isExpanded:
expanded.append(self.createIndex(node.row(), 0, node))
return expanded
+58 -21
View File
@@ -63,7 +63,10 @@ class NWTree:
also used for file names.
"""
__slots__ = ("_project", "_tree", "_order", "_roots", "_model", "_nodes", "_trash", "_changed")
__slots__ = (
"_project", "_tree", "_order", "_roots",
"_model", "_items", "_nodes", "_trash", "_changed",
)
def __init__(self, project: NWProject) -> None:
@@ -74,6 +77,7 @@ class NWTree:
self._roots: dict[str, NWItem] = {} # The root items of the tree
self._model = ProjectModel(self)
self._items: dict[str, NWItem] = {}
self._nodes: dict[str, ProjectNode] = {}
self._trash = None # The handle of the trash root folder
@@ -103,6 +107,11 @@ class NWTree:
self._tree = {}
self._order = []
self._roots = {}
self._model = ProjectModel(self)
self._items = {}
self._nodes = {}
self._trash = None
self._changed = False
return
@@ -185,12 +194,20 @@ class NWTree:
"""Pack the content of the tree into a list of dictionaries of
items. In the order defined by the _treeOrder list.
"""
tree = []
for tHandle in self._order:
tItem = self.__getitem__(tHandle)
if tItem:
tree.append(tItem.pack())
return tree
nodes = self._model.root.allChildren()
if len(nodes) != len(self._nodes):
logger.warning(
"Model tree is inconsitent with nodes map, %d != %d",
len(nodes), len(self._nodes)
)
# tree = []
# for tHandle in self._order:
# tItem = self.__getitem__(tHandle)
# if tItem:
# tree.append(tItem.pack())
return [node.item.pack() for node in nodes]
def unpack(self, data: list[dict]) -> None:
"""Iterate through all items of a list and add them to the
@@ -200,31 +217,51 @@ class NWTree:
for item in data:
nwItem = NWItem(self._project, "") # Handle is set by unpack()
if nwItem.unpack(item):
self._items[nwItem.itemHandle] = nwItem
self.append(nwItem)
nwItem.saveInitialCount()
return
def buildModel(self) -> None:
""""""
root = ProjectNode(NWItem(self._project, ""))
for item in self._tree.values():
node = ProjectNode(item)
self._nodes[item.itemHandle] = node
if pHandle := item.itemParent:
if parent := self._nodes.get(pHandle):
parent.addChild(node)
else:
logger.error("Could not add item '%s'", item.itemHandle)
else:
root.addChild(node)
self._model.beginInsertRows(self._model.index(0, 0), 0, 0)
self._model.setRoot(root)
later: dict[str, NWItem] = self._items.copy()
for _ in range(999):
later = self._buildTree(later)
if len(later) == 0:
break
else:
logger.error("Not all items could be added to project tree")
for item in later.values():
item.setParent(None)
self._model.endInsertRows()
self._model.layoutChanged.emit()
return
def _buildTree(self, items: dict[str, NWItem]) -> dict[str, NWItem]:
""""""
remains: dict[str, NWItem] = {}
for handle, item in items.items():
if pHandle := item.itemParent:
if parent := self._nodes.get(pHandle):
node = ProjectNode(item)
parent.addChild(node)
self._nodes[handle] = node
elif pHandle in items:
remains[handle] = item
logger.warning("Item '%s' found before its parent", handle)
else:
item.setParent(None)
logger.error("Item '%s' has no parent in current tree", handle)
elif item.isRootType():
node = ProjectNode(item)
self._model.root.addChild(node)
self._nodes[handle] = node
return remains
def checkConsistency(self, prefix: str) -> tuple[int, int]:
"""Check the project tree consistency. Also check the content
folder and add back files that were discovered but were not
+5
View File
@@ -535,6 +535,11 @@ class GuiProjectTree2(QTreeView):
treeHeader.resizeSection(self.C_ACTIVE, iPx + cMg)
treeHeader.resizeSection(self.C_STATUS, iPx + cMg)
self.blockSignals(True)
for index in SHARED.project.tree.model.allExpanded():
self.setExpanded(index, True)
self.blockSignals(False)
return
+7 -1
View File
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
from PyQt5.QtGui import QPixmap
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QWidget
@@ -73,6 +73,12 @@ class MockTheme:
def getPixmap(self, *a):
return QPixmap()
def getIcon(self, *a) -> QIcon:
return QIcon()
def getItemIcon(self, *a, **k) -> QIcon:
return QIcon()
class MockApp: