How to override parent in QSortFilterProxyModel?

201 views Asked by At

I have an ObjectTreeModel class that inherits from QAbstractItemModel. The model stores ObjectTreeItem elements that have the _placement property, which is the uuid of another ObjectTreeItem element. I want that if an element has this property, then the ObjectTreeModel::parent() function returns the placement element, not the actual parent of the element and the tree structure changes accordingly. To do this, I redefined parent() in the SortFilterProxyTreeModel proxy model (inherited from QSortFilterProxyModel) of ObjectTreeModel, but as a result, the tree structure does not change. How can I redefine parent()correctly to get the desired result?

Source ObjectTreeModel::parent() function:

QModelIndex ObjectTreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    ObjectTreeItem *childItem = getItem(index);
    ObjectTreeItem *parentItem = childItem ? childItem->parent() : nullptr;

    if (parentItem == rootItem || !parentItem)
        return QModelIndex();

    return createIndex(parentItem->childNumber(), 0, parentItem);
}

Overridden parent in SortFilterProxyTreeModel:

QModelIndex SortFilterProxyTreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();
    
    // get original model
    ObjectTreeModel* treeModel = static_cast< ObjectTreeModel* >( sourceModel() );
    
    // convert the index from SortFilterProxyTreeModel to ObjectTreeModel
    QModelIndex sourceIndex = mapToSource( index );
    ObjectTreeItem *item = treeModel->getItem(sourceIndex);
    QModelIndex parentIndex;
    // if the uuid placement property exists, then we get its index, otherwise — the real parent.
    // the isPlacementParent variable is needed for optional behavior, by default it is true.
    const QUuid placementUuid = item->payload->_placement.value();
    if( isPlacementParent && !placementUuid.isNull() ) {
        ObjectTreeItem* placementItem = treeModel->items().value( placementUuid );
        parentIndex = treeModel->createThisIndex(placementItem->childNumber(), 0, placementItem);
        
    } else {
        ObjectTreeItem *parentItem = item ? item->parent() : nullptr;
        
        if (parentItem == treeModel->rootItem || !parentItem)
            return QModelIndex();
        
        parentIndex = treeModel->createThisIndex(parentItem->childNumber(), 0, parentItem);
    }
    // convert parentIndex from ObjectTreeModel to SortFilterProxyTreeModel
    return mapFromSource( parentIndex );
}
0

There are 0 answers