diff options
author | Ian Walters <ian@walters.id.au> | 2010-04-28 10:59:54 +1000 |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dietrich-de@nokia.com> | 2010-06-02 15:25:25 +0200 |
commit | ad3d90572e2a5ed9ab63553ee3e5be3db5c957a3 (patch) | |
tree | 8f76f3727275267d888a46a82a33abc634933dae | |
parent | d20d5611aec3eb2c4be1808250f8eed47e0ebf19 (diff) | |
download | qt4-tools-ad3d90572e2a5ed9ab63553ee3e5be3db5c957a3.tar.gz |
Fix LeftToRight + setSpacing + setWrapping when drag-and-dropping
Quite a number of assumptions in qlistview assume either wrapping or spacing,
but not both. This fixes the Flow left to right case.
The TopToBottom case is not affected. TopToBottom + wrapping still works
TopToBottom + spacing still works, TopToBottom + spacing + wrapping is still
as broken as ever.
Drag move prior to this patch was correct, but also need the drop
to use the spacing when determining what index to apply to, not
just the drag move.
Reviewed-by: gabi
Merge-Request: 586
Task-number: QTBUG-8938
-rw-r--r-- | src/gui/itemviews/qabstractitemview_p.h | 2 | ||||
-rw-r--r-- | src/gui/itemviews/qlistview.cpp | 95 | ||||
-rw-r--r-- | src/gui/itemviews/qlistview_p.h | 2 |
3 files changed, 90 insertions, 9 deletions
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index fce74f3f54..b9408a544d 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -136,7 +136,7 @@ public: void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;} - bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index); + virtual bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index); bool droppingOnItself(QDropEvent *event, const QModelIndex &index); QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options); diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 186909377a..846d911757 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1833,6 +1833,14 @@ QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint else return QAbstractItemViewPrivate::position(pos, rect, idx); } + +bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex) +{ + if (viewMode == QListView::ListMode && flow == QListView::LeftToRight) + return static_cast<QListModeViewBase *>(commonListView)->dropOn(event, dropRow, dropCol, dropIndex); + else + return QAbstractItemViewPrivate::dropOn(event, dropRow, dropCol, dropIndex); +} #endif /* @@ -1960,7 +1968,13 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) // ignore by default event->ignore(); - QModelIndex index = qq->indexAt(event->pos()); + // can't use indexAt, doesn't account for spacing. + QPoint p = event->pos(); + QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1); + rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing()); + const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect); + QModelIndex index = intersectVector.count() > 0 + ? intersectVector.last() : QModelIndex(); dd->hover = index; if (!dd->droppingOnItself(event, index) && dd->canDecode(event)) { @@ -1968,10 +1982,11 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) if (index.isValid() && dd->showDropIndicator) { QRect rect = qq->visualRect(index); dd->dropIndicatorPosition = position(event->pos(), rect, index); + // if spacing, should try to draw between items, not just next to item. switch (dd->dropIndicatorPosition) { case QAbstractItemView::AboveItem: if (dd->isIndexDropEnabled(index.parent())) { - dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height()); + dd->dropIndicatorRect = QRect(rect.left()-dd->spacing(), rect.top(), 0, rect.height()); event->accept(); } else { dd->dropIndicatorRect = QRect(); @@ -1979,7 +1994,7 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) break; case QAbstractItemView::BelowItem: if (dd->isIndexDropEnabled(index.parent())) { - dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height()); + dd->dropIndicatorRect = QRect(rect.right()+dd->spacing(), rect.top(), 0, rect.height()); event->accept(); } else { dd->dropIndicatorRect = QRect(); @@ -2014,6 +2029,68 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) qq->startAutoScroll(); } +/*! + If the event hasn't already been accepted, determines the index to drop on. + + if (row == -1 && col == -1) + // append to this drop index + else + // place at row, col in drop index + + If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop. + \internal + */ +bool QListModeViewBase::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex) +{ + if (event->isAccepted()) + return false; + + QModelIndex index; + if (dd->viewport->rect().contains(event->pos())) { + // can't use indexAt, doesn't account for spacing. + QPoint p = event->pos(); + QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1); + rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing()); + const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect); + index = intersectVector.count() > 0 + ? intersectVector.last() : QModelIndex(); + if (!index.isValid()) + index = dd->root; + } + + // If we are allowed to do the drop + if (dd->model->supportedDropActions() & event->dropAction()) { + int row = -1; + int col = -1; + if (index != dd->root) { + dd->dropIndicatorPosition = position(event->pos(), qq->visualRect(index), index); + switch (dd->dropIndicatorPosition) { + case QAbstractItemView::AboveItem: + row = index.row(); + col = index.column(); + index = index.parent(); + break; + case QAbstractItemView::BelowItem: + row = index.row() + 1; + col = index.column(); + index = index.parent(); + break; + case QAbstractItemView::OnItem: + case QAbstractItemView::OnViewport: + break; + } + } else { + dd->dropIndicatorPosition = QAbstractItemView::OnViewport; + } + *dropIndex = index; + *dropRow = row; + *dropCol = col; + if (!dd->droppingOnItself(event, index)) + return true; + } + return false; +} + #endif //QT_NO_DRAGANDDROP void QListModeViewBase::updateVerticalScrollBar(const QSize &step) @@ -2107,7 +2184,7 @@ int QListModeViewBase::verticalOffset() const int value = verticalScrollBar()->value(); if (value >= segmentPositions.count()) return 0; - return segmentPositions.at(value); + return segmentPositions.at(value) - spacing(); } } else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) { int value = verticalScrollBar()->value(); @@ -2155,14 +2232,14 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) if (horizontal && flow() == QListView::TopToBottom && dx != 0) { int currentValue = qBound(0, horizontalValue, max); int previousValue = qBound(0, currentValue + dx, max); - int currentCoordinate = segmentPositions.at(currentValue); - int previousCoordinate = segmentPositions.at(previousValue); + int currentCoordinate = segmentPositions.at(currentValue) - spacing(); + int previousCoordinate = segmentPositions.at(previousValue) - spacing(); dx = previousCoordinate - currentCoordinate; } else if (vertical && flow() == QListView::LeftToRight && dy != 0) { int currentValue = qBound(0, verticalValue, max); int previousValue = qBound(0, currentValue + dy, max); - int currentCoordinate = segmentPositions.at(currentValue); - int previousCoordinate = segmentPositions.at(previousValue); + int currentCoordinate = segmentPositions.at(currentValue) - spacing(); + int previousCoordinate = segmentPositions.at(previousValue) - spacing(); dy = previousCoordinate - currentCoordinate; } } else { @@ -2330,6 +2407,8 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info) segmentExtents.append(flowPosition); flowPosition = info.spacing + segStartPosition; segPosition += deltaSegPosition; + if (info.wrap) + segPosition += info.spacing; segmentPositions.append(segPosition); segmentStartRows.append(row); deltaSegPosition = 0; diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index bf7657b3c0..9ae1f50a52 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -237,6 +237,7 @@ public: // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}. QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; void dragMoveEvent(QDragMoveEvent *e); + bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index); #endif private: @@ -364,6 +365,7 @@ public: #ifndef QT_NO_DRAGANDDROP virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; + bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index); #endif inline void setGridSize(const QSize &size) { grid = size; } |