summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews/qlistview.cpp
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-04-22 18:55:13 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-04-24 17:40:01 +0200
commitfd894fd68edf3d67975cda8eb9dda43646887b0d (patch)
tree7e8e27cf95cde1906ff59d8e5ff379208c2dc018 /src/widgets/itemviews/qlistview.cpp
parent20cdf807b1b6db2189024736047350cdc7be4887 (diff)
QListWidget/View: Update the selection when moving items within the view
The code for doing that existed in the QListWidget::dropEvent override, and was only using standard itemview APIs to adjust the selection model. There is no reason why dropping items internally in a QListView should not do the exact same thing. As part of moving the code from QListWidget to QListView, replace QList with QVector, and other minor optimizations. [ChangeLog][QtWidgets][QListView] Moving selected items within a list view by drag'n'drop will maintain the selection of those items. Change-Id: Ie24bec38234839dcb2f0b0ee0302cc59ca101631 Fixes: QTBUG-83084 Pick-to: 5.15 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/widgets/itemviews/qlistview.cpp')
-rw-r--r--src/widgets/itemviews/qlistview.cpp46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 4cb9214ff4..ed8fd88996 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -909,10 +909,50 @@ void QListView::dragLeaveEvent(QDragLeaveEvent *e)
/*!
\reimp
*/
-void QListView::dropEvent(QDropEvent *e)
+void QListView::dropEvent(QDropEvent *event)
{
- if (!d_func()->commonListView->filterDropEvent(e))
- QAbstractItemView::dropEvent(e);
+ Q_D(QListView);
+
+ if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
+ dragDropMode() == QAbstractItemView::InternalMove)) {
+ QModelIndex topIndex;
+ bool topIndexDropped = false;
+ int col = -1;
+ int row = -1;
+ if (d->dropOn(event, &row, &col, &topIndex)) {
+ const QVector<QModelIndex> selIndexes = selectedIndexes();
+ QVector<QPersistentModelIndex> persIndexes;
+ persIndexes.reserve(selIndexes.count());
+
+ for (const auto &index : selIndexes) {
+ persIndexes.append(index);
+ if (index == topIndex) {
+ topIndexDropped = true;
+ break;
+ }
+ }
+
+ if (!topIndexDropped) {
+ std::sort(persIndexes.begin(), persIndexes.end()); // The dropped items will remain in the same visual order.
+
+ QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
+
+ int r = row == -1 ? model()->rowCount() : (dropRow.row() >= 0 ? dropRow.row() : row);
+ for (int i = 0; i < persIndexes.count(); ++i) {
+ const QPersistentModelIndex &pIndex = persIndexes.at(i);
+ model()->moveRow(QModelIndex(), pIndex.row(), QModelIndex(), r);
+ r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order.
+ }
+
+ event->accept();
+ // Don't want QAbstractItemView to delete it because it was "moved" we already did it
+ event->setDropAction(Qt::CopyAction);
+ }
+ }
+ }
+
+ if (!d->commonListView->filterDropEvent(event))
+ QAbstractItemView::dropEvent(event);
}
/*!