[SOLVED] supportedDropActions() in QAbstractItemModel
-
I've got class based on QAbstractItemModel and need realize drag'n'drop using it. Model is based on a 2-level tree structure. 2-level elements can be draged and dropped inside its parent and from one parent to another. I done almost all and stacked in supportedDropActions(). I need to move items by default and copy them if Ctrl key is pressed when dropping. But I can't return right flag to do this. Looking for examples or anything that can help.
-
-
All that I've got is : DropMImeData function:
@
bool GroupsModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int col, const QModelIndex & parent )
{
QByteArray encodedData = data->data("text/plain");
QDataStream stream(&encodedData, QIODevice::ReadOnly);int takedGpIndex, takedSubIndex;
while (!stream.atEnd()) {
stream >> takedGpIndex >> takedSubIndex;if(takedGpIndex == -1 || takedSubIndex == -1)
continue;// *********************************take item calculations ***********************//
// get place in structure
Group * takedGp = m_groups.getGroupByIndex(takedGpIndex);if(takedGp == NULL)
continue;GroupSubscriber * sub = takedGp->getSubscriberByIndex(takedSubIndex);
if(sub == NULL)
continue;// ********************************* drop place calculations ***********************//
// get place in structure
int putGpNdx = -1;
if(parent.isValid())
if(parent.internalId() != -1)
putGpNdx = parent.row();
else
putGpNdx = row;if(putGpNdx == -1)
continue;Group * putGp = m_groups.getGroupByIndex(putGpNdx);
if(putGp == NULL)
continue;// put data
QModelIndex putParent = index(putGpNdx,eID,m_null);
if(takedGp == putGp)
{
if(row == -1)
continue;if(row >= putGp->count())
{
int pRow = putGp->count();
beginInsertRows(putParent,pRow,pRow);
GroupSubscriber * newSub = new GroupSubscriber(*sub);
putGp->addSubscriber(newSub);
endInsertRows();
}
else
{
beginInsertRows(putParent,row,row);
takedGp->copySubscriber(takedSubIndex,row);
endInsertRows();if(takedSubIndex>row) takedSubIndex++;
}
}
else
{
if(row == -1)
{
int pRow = putGp->count();
beginInsertRows(putParent,pRow,pRow);
GroupSubscriber * newSub = new GroupSubscriber(*sub);
putGp->addSubscriber(newSub);
endInsertRows();
}
else
{
beginInsertRows(putParent,row,row);
GroupSubscriber * newSub = new GroupSubscriber(*sub);
putGp->insertSubscriber(newSub,row);
endInsertRows();
}
}m_bChanged = true;
if(action == Qt::MoveAction)
{
QModelIndex takeParent = index(takedGpIndex,eID,m_null);
// if non-copy event need to delete old item and structure data//remove data from structure
beginRemoveRows(takeParent,takedSubIndex,takedSubIndex);
takedGp->removeSubscriber(takedSubIndex);
endRemoveRows();
}}
return true;
}@
MimeData :
@QMimeData * GroupsModel::mimeData( const QModelIndexList & indexes ) const
{
QMimeData * mimeData = new QMimeData();
QByteArray encodedData;QDataStream stream(&encodedData, QIODevice::WriteOnly);
foreach (QModelIndex index, indexes) {
if (index.isValid() == false)
continue;if(index.column() != eID)
continue;int gpNdx = -1;
int subNdx = -1;if(index.parent().isValid())
{
// this is subscriber
gpNdx = index.parent().row();
subNdx = index.row();
}stream << gpNdx << subNdx;
}mimeData->setData("text/plain", encodedData);
return mimeData;
}@
MimeTypes:
@
QStringList GroupsModel::mimeTypes() const
{
QStringList types;
types << "text/plain";
return types;
}@
And supportedDropActions. I made standart treeView in *.ui file and set this model to it. So what I need to do to support copy in my model? -
Eureka ! Only one thing that I need to do just change dragDropMode in QTreeView from InternalMove to DragDrop. And Modified version of dropMimeData now looks like this :
@bool GroupsModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int col, const QModelIndex & parent )
{
QByteArray encodedData = data->data("text/plain");
QDataStream stream(&encodedData, QIODevice::ReadOnly);int takedGpIndex, takedSubIndex;
QModelIndexList deleteList;
while (!stream.atEnd()) {
stream >> takedGpIndex >> takedSubIndex;if (takedGpIndex < 0 || takedSubIndex < 0)
continue;// ********************************* take item calculations ***********************//
// get place in structure
Group * takedGp = m_groups.getGroupByIndex(takedGpIndex);
if (takedGp == NULL)
continue;GroupSubscriber * sub = takedGp->getSubscriberByIndex(takedSubIndex);
if(sub == NULL)
continue;// ********************************* drop place calculations ***********************//
// get place in structure
int putGpNdx = -1;
if (parent.isValid() && parent.internalId() <= 0)
putGpNdx = parent.row();
else
putGpNdx = row;Group * putGp = m_groups.getGroupByIndex(putGpNdx);
if(putGp == NULL)
continue;// put data
QModelIndex putParent = index(putGpNdx,eID,m_null);
if(takedGp == putGp)
{
if(row == -1)
continue;if(row >= putGp->count())
{
int pRow = putGp->count();
beginInsertRows(putParent,pRow,pRow);
GroupSubscriber * newSub = new GroupSubscriber(*sub);
putGp->addSubscriber(newSub);
endInsertRows();
}
else
{
beginInsertRows(putParent,row,row);
takedGp->copySubscriber(takedSubIndex,row);
endInsertRows();if(takedSubIndex>row) takedSubIndex++;
}
}
else
{
if(row == -1)
{
int pRow = putGp->count();
beginInsertRows(putParent,pRow,pRow);
GroupSubscriber * newSub = new GroupSubscriber(*sub);
putGp->addSubscriber(newSub);
endInsertRows();
}
else
{
beginInsertRows(putParent,row,row);
GroupSubscriber * newSub = new GroupSubscriber(*sub);
putGp->insertSubscriber(newSub,row);
endInsertRows();
}
}m_bChanged = true;
QModelIndex takeParent = index(takedGpIndex,eID,m_null);
deleteList.append(takeParent.child(takedSubIndex,eID));}
if(action == Qt::MoveAction)
removeItems(deleteList,false);
return true;
}@