summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2018-04-07 08:59:06 +0200
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2018-06-22 20:05:11 +0000
commitc699daeceb4448c4545a67ffdba27bcb3b994114 (patch)
tree52d35b5a0db2164f2192e4d38e9f083aa7be7cfc
parent1acdcdaa4d9c4b6bf86b50ada8a7b194d86f1e4c (diff)
QListView: do not delete item on internal move
When an internal DnD occoures in IconMode, the item is moved to it's new place but the logic in filterStartDrag() has no clue about the fact that an internal move happend. Therefore the item gets deleted. Fix it by changing the event's drop action to Qt::CopyAction to avoid the deletion as it is done within QListWidget DnD code. [ChangeLog][QtWidgets][QListView] Do not delete item on internal move. Task-number: QTBUG-67440 Change-Id: I873d3c9fa76e107e108d9af0dcf8cecd1e18a18f Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
-rw-r--r--src/widgets/itemviews/qlistview.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp49
2 files changed, 53 insertions, 0 deletions
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 7fbbf39309..e5769940d4 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -2815,6 +2815,8 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
drag->setHotSpot(dd->pressedPosition - rect.topLeft());
Qt::DropAction action = drag->exec(supportedActions, dd->defaultDropAction);
draggedItems.clear();
+ // for internal moves the action was set to Qt::CopyAction in
+ // filterDropEvent() to avoid the deletion here
if (action == Qt::MoveAction)
dd->clearOrRemove();
}
@@ -2851,6 +2853,8 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
dd->stopAutoScroll();
draggedItems.clear();
dd->emitIndexesMoved(indexes);
+ // do not delete item on internal move, see filterStartDrag()
+ e->setDropAction(Qt::CopyAction);
e->accept(); // we have handled the event
// if the size has not grown, we need to check if it has shrinked
if (contentsSize != contents) {
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index b60e19c474..5227db64ec 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -150,6 +150,7 @@ private slots:
void taskQTBUG_51086_skippingIndexesInSelectedIndexes();
void taskQTBUG_47694_indexOutOfBoundBatchLayout();
void itemAlignment();
+ void internalDragDropMove();
};
// Testing get/set functions
@@ -2577,5 +2578,53 @@ void tst_QListView::itemAlignment()
QVERIFY(w.visualRect(item1->index()).width() < w.visualRect(item2->index()).width());
}
+void tst_QListView::internalDragDropMove()
+{
+ const QString platform(QGuiApplication::platformName().toLower());
+ if (platform != QLatin1String("xcb"))
+ QSKIP("Need a window system with proper DnD support via injected mouse events");
+
+ // on an internal move, the item was deleted which should not happen
+ // see QTBUG-67440
+ class QListViewWithPublicStartDrag : public QListView
+ {
+ public:
+ using QListView::startDrag;
+ };
+
+ QStandardItemModel data(0, 1);
+ QPixmap pixmap(32, 32);
+ for (int i = 0; i < 10; ++i) {
+ pixmap.fill(Qt::GlobalColor(i + 1));
+ data.appendRow(new QStandardItem(QIcon(pixmap), QString::number(i)));
+ }
+ QItemSelectionModel selections(&data);
+ QListViewWithPublicStartDrag list;
+ list.setWindowTitle(QTest::currentTestFunction());
+ list.setViewMode(QListView::IconMode);
+ list.setDefaultDropAction(Qt::MoveAction);
+ list.setModel(&data);
+ list.setSelectionModel(&selections);
+ list.resize(300, 300);
+ list.show();
+ selections.select(data.index(1, 0), QItemSelectionModel::Select);
+ QVERIFY(QTest::qWaitForWindowExposed(&list));
+
+ // execute as soon as the eventloop is running again
+ // which is the case inside list.startDrag()
+ QTimer::singleShot(0, [&list]()
+ {
+ const QPoint pos = list.rect().center();
+ QMouseEvent mouseMove(QEvent::MouseMove, pos, list.mapToGlobal(pos), Qt::NoButton, 0, 0);
+ QApplication::sendEvent(&list, &mouseMove);
+ QMouseEvent mouseRelease(QEvent::MouseButtonRelease, pos, list.mapToGlobal(pos), Qt::LeftButton, 0, 0);
+ QApplication::sendEvent(&list, &mouseRelease);
+ });
+ const int expectedCount = data.rowCount();
+ list.startDrag(Qt::MoveAction|Qt::CopyAction);
+ QCOMPARE(expectedCount, data.rowCount());
+}
+
+
QTEST_MAIN(tst_QListView)
#include "tst_qlistview.moc"