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>
This commit is contained in:
parent
20cdf807b1
commit
fd894fd68e
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user