list in mimeData(const QModelIndexList& list) returns more items than selected in QTreeView
Solved
General and Desktop
-
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