MyModel::dropMimeData() not working
-
Guys,
Maybe you can see something I'm missing. My goal is to drag data from one view to other, with custom mime type; but dropMimeData in the target model is never called. I'm pretty sure I've setup everything required.Well, fist views:
void MainWindow::setDragnDrop(QAbstractItemView *view, bool enable, QAbstractItemView::DragDropMode mode) { view->setDragEnabled(enable); view->setAcceptDrops(enable); view->viewport()->setAcceptDrops(enable);//I tried both view->setDropIndicatorShown(enable); view->setDragDropMode(mode); }
calling in MainWindow constructor:
setDragnDrop(ui->targetTreeView, true, QAbstractItemView::DragDrop); setDragnDrop(ui->sourceFilesList, true, QAbstractItemView::DragOnly);
so setting views for drag'n'drop - CHECK
Now the source model (descendant of QFileSystemModel) reimplementations:
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::DropActions supportedDragActions() const override; QStringList mimeTypes() const override; QMimeData* mimeData(const QModelIndexList &indexes) const override;
and bodies:
Qt::ItemFlags PackagesModel::flags(const QModelIndex &index) const { auto defaultFlags = QFileSystemModel::flags(index); if (index.isValid()) { return defaultFlags | Qt::ItemIsDragEnabled; } return defaultFlags; } Qt::DropActions PackagesModel::supportedDragActions() const { return Qt::CopyAction | Qt::LinkAction; } QStringList PackagesModel::mimeTypes() const { QStringList types; types.append(DragNDropData::mimeType); return types; } QMimeData* PackagesModel::mimeData(const QModelIndexList &indexes) const { QMimeData *data = new QMimeData; for (const QModelIndex &index : indexes) { //namespace DragNDropData { static const QString mimeType = "TerminalPackage"; } data->setData(DragNDropData::mimeType, fileInfo(index).absoluteFilePath().toUtf8()); } return data; }
required implementations in source model - CHECK
And last, target model (descendand of QFileSystemModel) have reimplemented:
Qt::DropActions supportedDropActions() const override; QStringList mimeTypes() const override; bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
bodies:
Qt::DropActions NavigationModel::supportedDropActions() const { return Qt::LinkAction | Qt::CopyAction; } QStringList NavigationModel::mimeTypes() const { QStringList types; types.append(DragNDropData::mimeType); return types; } #include <QDebug> bool NavigationModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const { if (data->hasFormat(DragNDropData::mimeType) && parent.isValid() && action & (Qt::LinkAction | Qt::CopyAction)) { qDebug() << "drop may be preformed";//this message shows up return true; } return false; } bool NavigationModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (!canDropMimeData(data, action, row, column, parent)) { return false; } QString path(data->data(DragNDropData::mimeType)); qDebug() << "drop detected - path: " << path << ", action: " << action << ", row: " << row << ", column: " << column << ", parent: " << parent; return true; }
required implementations in target model - CHECK
So dammit what else is needed to make it work??
-
Hah, after posting the thread, and taking a look at it I've spotted what was missing - target model requires flags() to be reimplemented:
Qt::ItemFlags NavigationModel::flags(const QModelIndex &index) const { auto defaultFlags = QFileSystemModel::flags(index); if (index.isValid()) { //pozwól na przeciąganie prawidłowych indeksów return defaultFlags | Qt::ItemIsDropEnabled; } return defaultFlags; }
with that change everything works like charm.