list in mimeData(const QModelIndexList& list) returns more items than selected in QTreeView



  • Hi fellow Qt programmers,

    I am using Qt 5.9.1 on Win10. The Tree I am implementing looks like this:

    • RootElement
      • Product 1
    • ++ Workpackage 1
    • +++ Workstep 1
    • +++ Workstep 2
    • ...
    • ++ Workpackage 2
    • +++ Workstep 1
    • +++ Workstep 2
      • Product 2
    • ....

    I reimplemented mimeTypes, mimeData, canDropMimeData and dropMimeData like this:

    QStringList ProductTreeModel::mimeTypes() const
    {
        QStringList mimeTypes;
    
        mimeTypes.append(Product::MIMETYPE_PRODUCT);
        mimeTypes.append(WorkStep::MIMETYPE_WORKSTEP);
        mimeTypes.append(WorkPackage::MIMETYPE_WORKPACKAGE);
    
        return mimeTypes;
    }
    
    QMimeData *ProductTreeModel::mimeData(const QModelIndexList &indexes) const
    {
        //TODO add support for tool, material, qualification, instruction
        QByteArray encodedData;
        AbstractTreeNode* node;
        QMimeData* mimeData = new QMimeData();
        QDataStream mdStream(&encodedData, QIODevice::WriteOnly);
    
        for(QModelIndexList::const_iterator i=indexes.begin(); i!=indexes.end(); ++i) {
            node = indexToNode(*i);
    
            switch(node->getType()) {
            case AbstractTreeNode::TYPE_PRODUCT:
                mdStream << QJsonDocument(dynamic_cast<ProductTreeNode*>(node)->toJsonObject()).toBinaryData();
                break;
    
            case AbstractTreeNode::TYPE_WORKSTEP:
                mdStream << QJsonDocument(dynamic_cast<WorkStepTreeNode*>(node)->toJsonObject()).toBinaryData();
                break;
    
            case AbstractTreeNode::TYPE_WORKPACKAGE:
                mdStream << QJsonDocument(dynamic_cast<WorkPackageTreeNode*>(node)->toJsonObject()).toBinaryData();
                break;
            }
        }
        switch(node->getType()) {
        case AbstractTreeNode::TYPE_PRODUCT:
            mimeData->setData(Product::MIMETYPE_PRODUCT, encodedData);
            break;
    
        case AbstractTreeNode::TYPE_WORKSTEP:
            mimeData->setData(WorkStep::MIMETYPE_WORKSTEP, encodedData);
            break;
    
        case AbstractTreeNode::TYPE_WORKPACKAGE:
            mimeData->setData(WorkPackage::MIMETYPE_WORKPACKAGE, encodedData);
            break;
        }
        return mimeData;
    }
    
    bool ProductTreeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
    {
        Q_UNUSED(row)
        Q_UNUSED(action)
        Q_UNUSED(column);
    
        if((getType(parent)==AbstractTreeNode::TYPE_PRODUCT) && (data->hasFormat(WorkPackage::MIMETYPE_WORKPACKAGE))) {
            return true;
        }
        if((getType(parent)==AbstractTreeNode::TYPE_WORKPACKAGE) && (data->hasFormat(WorkStep::MIMETYPE_WORKSTEP))) {
            return true;
        }
        return false;
    }
    
    bool ProductTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    {
        int i = 0;
        int insertRow;
        QByteArray encodedRow;
        QByteArray encodedData;
        QJsonDocument jsonRow;
        AbstractTreeNode* node;
    
        if(data->hasFormat(WorkPackage::MIMETYPE_WORKPACKAGE)) {
            encodedData = data->data(WorkPackage::MIMETYPE_WORKPACKAGE);
        }
        if(data->hasFormat(WorkStep::MIMETYPE_WORKSTEP)) {
            encodedData = data->data(WorkStep::MIMETYPE_WORKSTEP);
        }
        if(row<0) {
            insertRow = 0;
        }
        else {
            insertRow = row;
        }
        QDataStream mdStream(&encodedData, QIODevice::ReadOnly);
    
        if(!canDropMimeData(data, action, row, column, parent)) {
            return false;
        }
        if(action==Qt::IgnoreAction) {
            return true;
        }
        node = indexToNode(parent);
    
        while(!mdStream.atEnd()) {
            mdStream >> encodedRow;
            jsonRow = QJsonDocument::fromBinaryData(encodedRow);
    
            if(data->hasFormat(WorkPackage::MIMETYPE_WORKPACKAGE)) {
                insertWorkPackage(jsonRow.object(), insertRow+i, parent);
            }
            if(data->hasFormat(WorkStep::MIMETYPE_WORKSTEP)) {
                insertWorkStep(jsonRow.object(), insertRow+i, parent);
            }
            ++i;
        }
        return true;
    }
    

    Here is my problem: If I drag and drop Worksteps everythings works fine, but when I drag Workpackages indexes in mimeData() holds the very same index twice. And if I drag a Product, indexes even holds three times the index. I can't find any errors in the code. Is this behaviour intended by QTreeView?

    Regards
    Simonson



  • ok found the error. The problems was that the columnCount() funktion returned a number > 1 for the alle other items than worksteps. Thats why indexes in mimeData() had more than one entries.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.