diff options
Diffstat (limited to 'src/widgets/itemviews/qlistview.cpp')
-rw-r--r-- | src/widgets/itemviews/qlistview.cpp | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index d34965fe07..5a88f1b1ef 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -572,6 +572,8 @@ void QListView::scrollTo(const QModelIndex &index, ScrollHint hint) return; const QRect rect = visualRect(index); + if (!rect.isValid()) + return; if (hint == EnsureVisible && d->viewport->rect().contains(rect)) { d->viewport->update(rect); return; @@ -932,7 +934,7 @@ void QListView::dropEvent(QDropEvent *event) } } - if (!topIndexDropped) { + if (!topIndexDropped && !topIndex.isValid()) { std::sort(persIndexes.begin(), persIndexes.end()); // The dropped items will remain in the same visual order. QPersistentModelIndex dropRow = model()->index(row, col, topIndex); @@ -940,19 +942,29 @@ void QListView::dropEvent(QDropEvent *event) 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); + if (r != pIndex.row()) { + // try to move (preserves selection) + d->dropEventMoved |= model()->moveRow(QModelIndex(), pIndex.row(), QModelIndex(), r); + if (!d->dropEventMoved) // can't move - abort and let QAbstractItemView handle this + break; + } else { + // move onto itself is blocked, don't delete anything + d->dropEventMoved = true; + } 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->dropEventMoved) + event->accept(); // data moved, nothing to be done in QAbstractItemView::dropEvent } } } - if (!d->commonListView->filterDropEvent(event)) + if (!d->commonListView->filterDropEvent(event) || !d->dropEventMoved) { + // icon view didn't move the data, and moveRows not implemented, so fall back to default + if (!d->dropEventMoved) + event->ignore(); QAbstractItemView::dropEvent(event); + } } /*! @@ -1529,12 +1541,14 @@ void QListView::doItemsLayout() setState(ExpandingState); if (d->model->columnCount(d->root) > 0) { // no columns means no contents d->resetBatchStartRow(); - if (layoutMode() == SinglePass) + if (layoutMode() == SinglePass) { d->doItemsLayout(d->model->rowCount(d->root)); // layout everything - else if (!d->batchLayoutTimer.isActive()) { + } else if (!d->batchLayoutTimer.isActive()) { if (!d->doItemsLayout(d->batchSize)) // layout is done d->batchLayoutTimer.start(0, this); // do a new batch as fast as possible } + } else { // clear the QBspTree generated by the last layout + d->clear(); } QAbstractItemView::doItemsLayout(); setState(oldState); // restoring the oldState @@ -2879,12 +2893,13 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) drag->setMimeData(dd->model->mimeData(indexes)); drag->setPixmap(pixmap); drag->setHotSpot(dd->pressedPosition - rect.topLeft()); + dd->dropEventMoved = false; 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) + // delete item, unless it has already been moved internally (see filterDropEvent) + if (action == Qt::MoveAction && !dd->dropEventMoved) dd->clearOrRemove(); + dd->dropEventMoved = false; } return true; } @@ -2920,7 +2935,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e) draggedItems.clear(); dd->emitIndexesMoved(indexes); // do not delete item on internal move, see filterStartDrag() - e->setDropAction(Qt::CopyAction); + dd->dropEventMoved = true; e->accept(); // we have handled the event // if the size has not grown, we need to check if it has shrinked if (contentsSize != contents) { |