diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-04-22 18:55:13 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-04-24 17:40:01 +0200 |
commit | fd894fd68edf3d67975cda8eb9dda43646887b0d (patch) | |
tree | 7e8e27cf95cde1906ff59d8e5ff379208c2dc018 /src/widgets/itemviews | |
parent | 20cdf807b1b6db2189024736047350cdc7be4887 (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.cpp | 46 | ||||
-rw-r--r-- | src/widgets/itemviews/qlistwidget.cpp | 41 |
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); } |