Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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