Exemple #1
0
    def insertItem(self, childItem, position=None, parentIndex=None):
        """ Inserts a childItem before row 'position' under the parent index.

            If position is None the child will be appended as the last child of the parent.
            Returns the index of the new inserted child.
        """
        if parentIndex is None:
            parentIndex = QtCore.QModelIndex()

        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)

        nChildren = parentItem.nChildren()
        if position is None:
            position = nChildren

        assert 0 <= position <= nChildren, \
            "position should be 0 < {} <= {}".format(position, nChildren)

        self.beginInsertRows(parentIndex, position, position)
        try:
            parentItem.insertChild(childItem, position)
        finally:
            self.endInsertRows()

        childIndex = self.index(position, 0, parentIndex)
        assert childIndex.isValid(
        ), "Sanity check failed: childIndex not valid"
        return childIndex
Exemple #2
0
    def indexTupleFromItem(self, treeItem):  # TODO: move to BaseTreeItem?
        """ Return (first column model index, last column model index) tuple for a configTreeItem
        """
        if not treeItem:
            return (QtCore.QModelIndex(), QtCore.QModelIndex())

        if not treeItem.parentItem:  # TODO: only necessary because of childNumber?
            return (QtCore.QModelIndex(), QtCore.QModelIndex())

        # Is there a bug in Qt in QStandardItemModel::indexFromItem?
        # It passes the parent in createIndex. TODO: investigate

        row = treeItem.childNumber()
        return (self.createIndex(row, 0, treeItem),
                self.createIndex(row,
                                 self.columnCount() - 1, treeItem))
Exemple #3
0
 def hasChildren(self, parentIndex=QtCore.QModelIndex()):
     """ Returns true if parent has any children; otherwise returns false.
         Use rowCount() on the parent to find out the number of children.
     """
     parentItem = self.getItem(parentIndex,
                               altItem=self.invisibleRootTreeItem)
     return parentItem.hasChildren()
Exemple #4
0
    def findItemAndIndexPath(self, path, startIndex=None):
        """ Searches all the model recursively (starting at startIndex) for an item where
            item.nodePath == path.

            Returns list of (item, itemIndex) tuples from the start index to that node.
            Raises IndexError if the item cannot be found.

            If startIndex is None, or path starts with a slash, searching begins at the (invisible)
            root item.
        """
        def _getIndexAndItemByName(nodeName, parentItem, parentIndex):
            """ Searches the parent for a direct child having the nodeName.
                Returns (item, itemIndex) tuple. Raises IndexError if the item cannot be found.
            """
            if self.canFetchMore(parentIndex):
                self.fetchMore(parentIndex)

            for rowNr, childItem in enumerate(parentItem.childItems):
                if childItem.nodeName == nodeName:
                    childIndex = self.index(rowNr, 0, parentIndex=parentIndex)
                    return (childItem, childIndex)
            raise IndexError("Item not found: {!r}".format(path))

        def _auxGetByPath(parts, item, index):
            "Aux function that does the actual recursive search"
            #logger.debug("_auxGetByPath item={}, parts={}".format(item, parts))

            if len(parts) == 0:
                return [(item, index)]

            head, tail = parts[0], parts[1:]
            if head == '':
                # Two consecutive slashes. Just go one level deeper.
                return _auxGetByPath(tail, item, index)
            else:
                childItem, childIndex = _getIndexAndItemByName(
                    head, item, index)
                return [(item, index)] + _auxGetByPath(tail, childItem,
                                                       childIndex)

        # The actual body of findItemAndIndexPath starts here

        check_is_a_string(path)
        if not path:
            raise IndexError("Item not found: {!r}".format(path))

        if startIndex is None or path.startswith('/'):
            startIndex = QtCore.QModelIndex()
            startItem = self.invisibleRootItem
        else:
            startItem = self.getItem(startIndex, None)

        if not startItem:
            raise IndexError(
                "Item not found: {!r}. No start item!".format(path))

        return _auxGetByPath(path.split('/'), startItem, startIndex)
Exemple #5
0
    def rowCount(self, parentIndex=QtCore.QModelIndex()):
        """ Returns the number of rows under the given parent. When the parent is valid it means
            that rowCount is returning the number of children of parent.

            Note: When implementing a table based model, rowCount() should return 0 when the parent
            is valid.
        """
        parentItem = self.getItem(parentIndex, altItem=self.invisibleRootItem)
        return parentItem.nChildren()
Exemple #6
0
 def insertItem(self, item, row):
     """ Insert an item in the store at a certain row.
     """
     check_class(item, self.store.ITEM_CLASS)
     logger.info("Inserting {!r} at row {}".format(item, row, self))
     self.beginInsertRows(QtCore.QModelIndex(), row, row)
     try:
         self.store.items.insert(row, item)
     finally:
         self.endInsertRows()
Exemple #7
0
 def popItemAtRow(self, row):
     """ Removes a store item from the store.
         Returns the item
     """
     self.beginRemoveRows(QtCore.QModelIndex(), row, row)
     try:
         item = self.store.items[row]
         del self.store.items[row]
         return item
     finally:
         self.endRemoveRows()
Exemple #8
0
 def indexFromItem(self, regItem, col=0):
     """ Gets the index (with column=0) for the row that contains the regItem
         If col is negative, it is counted from the end
     """
     if col < 0:
         col = len(self.attrNames) - col
     try:
         row = self.registry.items.index(regItem)
     except ValueError:
         return QtCore.QModelIndex()
     else:
         return self.index(row, col)
Exemple #9
0
    def parent(self, index):
        """ Returns the parent of the model item with the given index. If the item has no parent,
            an invalid QModelIndex is returned.

            A common convention used in models that expose tree data structures is that only items
            in the first column have children. For that case, when reimplementing this function in
            a subclass the column of the returned QModelIndex would be 0. (This is done here.)

            When reimplementing this function in a subclass, be careful to avoid calling QModelIndex
            member functions, such as QModelIndex.parent(), since indexes belonging to your model
            will simply call your implementation, leading to infinite recursion.
        """
        if not index.isValid():
            return QtCore.QModelIndex()

        childItem = self.getItem(index, altItem=self.invisibleRootItem)
        parentItem = childItem.parentItem

        if parentItem == self.invisibleRootItem:
            return QtCore.QModelIndex()

        return self.createIndex(parentItem.childNumber(), 0, parentItem)
Exemple #10
0
    def index(self, row, column, parentIndex=QtCore.QModelIndex()):
        """ Returns the index of the item in the model specified by the given row, column and parent
            index.

            Since each item contains information for an entire row of data, we create a model index
            to uniquely identify it by calling createIndex() it with the row and column numbers and
            a pointer to the item. (In the data() function, we will use the item pointer and column
            number to access the data associated with the model index; in this model, the row number
            is not needed to identify data.)

            When reimplementing this function in a subclass, call createIndex() to generate
            model indexes that other components can use to refer to items in your model.
        """
        #        logger.debug("  called index({}, {}, {}) {}"
        #                     .format(parentIndex.row(), parentIndex.column(), parentIndex.isValid(),
        #                             parentIndex.isValid() and parentIndex.column() != 0))

        parentItem = self.getItem(parentIndex,
                                  altItem=self.invisibleRootTreeItem)
        #logger.debug("    Getting row {} from parentItem: {}".format(row, parentItem))

        if not (0 <= row < parentItem.nChildren()):
            # Can happen when deleting the last child.
            #logger.warning("Index row {} invalid for parent item: {}".format(row, parentItem))
            return QtCore.QModelIndex()

        if not (0 <= column < self.columnCount()):
            #logger.warning("Index column {} invalid for parent item: {}".format(column, parentItem))
            return QtCore.QModelIndex()

        childItem = parentItem.child(row)
        if childItem:
            return self.createIndex(row, column, childItem)
        else:
            logger.warning(
                "No child item found at row {} for parent item: {}".format(
                    row, parentItem))
            return QtCore.QModelIndex()
Exemple #11
0
    def expandBranch(self, index=None, expanded=True):
        """ Expands or collapses the node at the index and all it's descendants.

            If expanded is True the nodes will be expanded, if False they will be collapsed.

            If parentIndex is None, the invisible root will be used (i.e. the complete forest will
            be expanded).
        """
        treeModel = self.model()
        if index is None:
            index = QtCore.QModelIndex()

        if index.isValid():
            self.setExpanded(index, expanded)

        for rowNr in range(treeModel.rowCount(index)):
            childIndex = treeModel.index(rowNr, 0, parentIndex=index)
            self.expandBranch(index=childIndex, expanded=expanded)
Exemple #12
0
 def loadFile(self,
              fileName,
              rtiClass=None,
              position=None,
              parentIndex=QtCore.QModelIndex()):
     """ Loads a file in the repository as a repo tree item of class rtiClass.
         Autodetects the RTI type if rtiClass is None.
         If position is None the child will be appended as the last child of the parent.
         Returns the index of the newly inserted RTI
     """
     logger.info("Loading data from: {!r}".format(fileName))
     if rtiClass is None:
         repoTreeItem = createRtiFromFileName(fileName)
     else:
         repoTreeItem = rtiClass.createFromFileName(fileName)
     assert repoTreeItem.parentItem is None, "repoTreeItem {!r}".format(
         repoTreeItem)
     return self.insertItem(repoTreeItem,
                            position=position,
                            parentIndex=parentIndex)
Exemple #13
0
    def expandBranch(self, index=None, expanded=None):
        """ Expands or collapses the node at the index and all it's descendants.
            If expanded is True the nodes will be expanded, if False they will be collapsed, and if
            expanded is None the expanded attribute of each item is used.
            If parentIndex is None, the invisible root will be used (i.e. the complete forest will
            be expanded).
        """
        configModel = self.model()
        if index is None:
            #index = configTreeModel.createIndex()
            index = QtCore.QModelIndex()

        if index.isValid():
            if expanded is None:
                item = configModel.getItem(index)
                self.setExpanded(index, item.expanded)
            else:
                self.setExpanded(index, expanded)

        for rowNr in range(configModel.rowCount(index)):
            childIndex = configModel.index(rowNr,
                                           configModel.COL_NODE_NAME,
                                           parentIndex=index)
            self.expandBranch(index=childIndex, expanded=expanded)
Exemple #14
0
 def columnCount(self, _parentIndex=QtCore.QModelIndex()):
     """ Returns the number of columns for the children of the given parent.
         In most subclasses, the number of columns is independent of the parent.
     """
     return len(self.horizontalHeaders)
Exemple #15
0
 def rootIndex(self):
     """ Returns an invalid index, which therefore will point to the root Item"""
     return QtCore.QModelIndex()