summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews
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
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')
-rw-r--r--src/widgets/itemviews/qlistview.cpp46
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp41
2 files changed, 45 insertions, 42 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);
}
/*!
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 7e360f9be8..2a0a1d683f 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1875,45 +1875,8 @@ bool QListWidget::dropMimeData(int index, const QMimeData *data, Qt::DropAction
}
/*! \reimp */
-void QListWidget::dropEvent(QDropEvent *event) {
- Q_D(QListWidget);
- if (event->source() == this && d->movement != Static) {
- QListView::dropEvent(event);
- return;
- }
-
- if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
- dragDropMode() == QAbstractItemView::InternalMove)) {
- QModelIndex topIndex;
- int col = -1;
- int row = -1;
- if (d->dropOn(event, &row, &col, &topIndex)) {
- QList<QModelIndex> selIndexes = selectedIndexes();
- QList<QPersistentModelIndex> persIndexes;
- const int selIndexesCount = selIndexes.count();
- persIndexes.reserve(selIndexesCount);
- for (int i = 0; i < selIndexesCount; i++)
- persIndexes.append(selIndexes.at(i));
-
- if (persIndexes.contains(topIndex))
- return;
- 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 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row);
- for (int i = 0; i < persIndexes.count(); ++i) {
- const QPersistentModelIndex &pIndex = persIndexes.at(i);
- d->listModel()->move(pIndex.row(), 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);
- }
- }
-
+void QListWidget::dropEvent(QDropEvent *event)
+{
QListView::dropEvent(event);
}