File indexing completed on 2024-04-14 03:59:14

0001 # -*- coding: utf-8 -*-
0002 """
0003 Copyright (C) 2008-2016 Wolfgang Rohdewald <wolfgang@rohdewald.de>
0004 
0005 partially based on C++ code from:
0006 Copyright (C) 2006 Mauricio Piacentini <mauricio@tabuleiro.com>
0007 
0008 SPDX-License-Identifier: GPL-2.0
0009 
0010 Here we define classes useful for tree views
0011 """
0012 
0013 from qt import QAbstractItemModel, QModelIndex
0014 
0015 class TreeItem:
0016 
0017     """generic class for items in a tree"""
0018 
0019     def __init__(self, content):
0020         self.rawContent = content
0021         self.parent = None
0022         self.children = []
0023 
0024     def insert(self, row, child):
0025         """add a new child to this tree node"""
0026         assert isinstance(child, TreeItem)
0027         child.parent = self
0028         self.children.insert(row, child)
0029         return child
0030 
0031     def remove(self):  # pylint: disable=no-self-use
0032         """remove this item from the model and the database.
0033         This is an abstract method."""
0034         raise Exception(
0035             'cannot remove this TreeItem. We should never get here.')
0036 
0037     def child(self, row):
0038         """return a specific child item"""
0039         return self.children[row]
0040 
0041     def childCount(self):
0042         """how many children does this item have?"""
0043         return len(self.children)
0044 
0045     def content(self, column):
0046         """content held by this item"""
0047         raise NotImplementedError("Virtual Method")
0048 
0049     def row(self):
0050         """the row of this item in parent"""
0051         if self.parent:
0052             return self.parent.children.index(self)
0053         return 0
0054 
0055 
0056 class RootItem(TreeItem):
0057 
0058     """an item for header data"""
0059 
0060     def __init__(self, content):
0061         TreeItem.__init__(self, content)
0062 
0063     def content(self, column):
0064         """content held by this item"""
0065         return self.rawContent[column]
0066 
0067     def columnCount(self):  # pylint: disable=no-self-use
0068         """Always return 1. is 1 always correct? No, inherit from RootItem"""
0069         return 1
0070 
0071 
0072 class TreeModel(QAbstractItemModel):
0073 
0074     """a basic class for Kajongg tree views"""
0075 
0076     def columnCount(self, parent):
0077         """how many columns does this node have?"""
0078         return self.itemForIndex(parent).columnCount()
0079 
0080     def rowCount(self, parent):
0081         """how many items?"""
0082         if parent.isValid() and parent.column():
0083             # all children have col=0 for parent
0084             return 0
0085         return self.itemForIndex(parent).childCount()
0086 
0087     def index(self, row, column, parent):
0088         """generate an index for this item"""
0089         if self.rootItem is None:
0090             return QModelIndex()
0091         if (row < 0
0092                 or column < 0
0093                 or row >= self.rowCount(parent)
0094                 or column >= self.columnCount(parent)):
0095             return QModelIndex()
0096         parentItem = self.itemForIndex(parent)
0097         assert parentItem
0098         item = parentItem.child(row)
0099         if item:
0100             return self.createIndex(row, column, item)
0101         return QModelIndex()
0102 
0103     def parent(self, index):
0104         """find the parent index"""
0105         if not index.isValid():
0106             return QModelIndex()
0107         childItem = self.itemForIndex(index)
0108         if childItem:
0109             parentItem = childItem.parent
0110             if parentItem:
0111                 if parentItem != self.rootItem:
0112                     grandParentItem = parentItem.parent
0113                     if grandParentItem:
0114                         row = grandParentItem.children.index(parentItem)
0115                         return self.createIndex(row, 0, parentItem)
0116         return QModelIndex()
0117 
0118     def itemForIndex(self, index):
0119         """return the item at index"""
0120         if index.isValid():
0121             item = index.internalPointer()
0122             if item:
0123                 return item
0124         return self.rootItem
0125 
0126     def insertRows(self, position, items, parent=QModelIndex()):
0127         """inserts items into the model"""
0128         parentItem = self.itemForIndex(parent)
0129         self.beginInsertRows(parent, position, position + len(items) - 1)
0130         for row, item in enumerate(items):
0131             parentItem.insert(position + row, item)
0132         self.endInsertRows()
0133         return True
0134 
0135     def removeRows(self, position, rows=1, parent=QModelIndex()):
0136         """reimplement QAbstractItemModel.removeRows"""
0137         self.beginRemoveRows(parent, position, position + rows - 1)
0138         parentItem = self.itemForIndex(parent)
0139         for row in parentItem.children[position:position + rows]:
0140             row.remove()
0141         parentItem.children = parentItem.children[
0142             :position] + parentItem.children[
0143                 position + rows:]
0144         self.endRemoveRows()
0145         return True