summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews/qlistview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/itemviews/qlistview.cpp')
-rw-r--r--src/widgets/itemviews/qlistview.cpp66
1 files changed, 59 insertions, 7 deletions
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index a7174a92e8..e5769940d4 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1631,6 +1631,32 @@ bool QListView::isSelectionRectVisible() const
}
/*!
+ \property QListView::itemAlignment
+ \brief the alignment of each item in its cell
+ \since 5.12
+
+ This is only supported in ListMode with TopToBottom flow
+ and with wrapping enabled.
+ The default alignment is 0, which means that an item fills
+ its cell entirely.
+*/
+void QListView::setItemAlignment(Qt::Alignment alignment)
+{
+ Q_D(QListView);
+ if (d->itemAlignment == alignment)
+ return;
+ d->itemAlignment = alignment;
+ if (viewMode() == ListMode && flow() == QListView::TopToBottom && isWrapping())
+ d->doDelayedItemsLayout();
+}
+
+Qt::Alignment QListView::itemAlignment() const
+{
+ Q_D(const QListView);
+ return d->itemAlignment;
+}
+
+/*!
\reimp
*/
bool QListView::event(QEvent *e)
@@ -1656,7 +1682,8 @@ QListViewPrivate::QListViewPrivate()
column(0),
uniformItemSizes(false),
batchSize(100),
- showElasticBand(false)
+ showElasticBand(false),
+ itemAlignment(Qt::Alignment())
{
}
@@ -2366,6 +2393,7 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
options.rect.setSize(contentsSize);
QSize size = (uniformItemSizes() && cachedItemSize().isValid())
? cachedItemSize() : itemSize(options, index);
+ QSize cellSize = size;
QPoint pos;
if (flow() == QListView::LeftToRight) {
@@ -2378,12 +2406,22 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
int right = (segment + 1 >= segmentPositions.count()
? contentsSize.width()
: segmentPositions.at(segment + 1));
- size.setWidth(right - pos.x());
+ cellSize.setWidth(right - pos.x());
} else { // make the items as wide as the viewport
- size.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing()));
+ cellSize.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing()));
}
}
+ if (dd->itemAlignment & Qt::AlignHorizontal_Mask) {
+ size.setWidth(qMin(size.width(), cellSize.width()));
+ if (dd->itemAlignment & Qt::AlignRight)
+ pos.setX(pos.x() + cellSize.width() - size.width());
+ if (dd->itemAlignment & Qt::AlignHCenter)
+ pos.setX(pos.x() + (cellSize.width() - size.width()) / 2);
+ } else {
+ size.setWidth(cellSize.width());
+ }
+
return QListViewItem(QRect(pos, size), index.row());
}
@@ -2562,8 +2600,18 @@ QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
if (isHidden(row))
continue;
QModelIndex index = modelIndex(row);
- if (index.isValid())
- ret += index;
+ if (index.isValid()) {
+ if (flow() == QListView::LeftToRight || dd->itemAlignment == Qt::Alignment()) {
+ ret += index;
+ } else {
+ const auto viewItem = indexToListViewItem(index);
+ const int iw = viewItem.width();
+ const int startPos = qMax(segStartPosition, segmentPositions.at(seg));
+ const int endPos = qMin(segmentPositions.at(seg + 1), segEndPosition);
+ if (endPos >= viewItem.x && startPos < viewItem.x + iw)
+ ret += index;
+ }
+ }
#if 0 // for debugging
else
qWarning("intersectingSet: row %d was invalid", row);
@@ -2603,7 +2651,7 @@ int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wr
positions = segmentPositions;
else if (!flowPositions.isEmpty()) {
positions.reserve(scrollValueMap.size());
- foreach (int itemShown, scrollValueMap)
+ for (int itemShown : scrollValueMap)
positions.append(flowPositions.at(itemShown));
}
if (positions.isEmpty() || bounds <= length)
@@ -2767,6 +2815,8 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
drag->setHotSpot(dd->pressedPosition - rect.topLeft());
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)
dd->clearOrRemove();
}
@@ -2784,7 +2834,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
if (qq->acceptDrops()) {
const Qt::ItemFlags dropableFlags = Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
const QVector<QModelIndex> &dropIndices = intersectingSet(QRect(end, QSize(1, 1)));
- foreach (const QModelIndex &index, dropIndices)
+ for (const QModelIndex &index : dropIndices)
if ((index.flags() & dropableFlags) == dropableFlags)
return false;
}
@@ -2803,6 +2853,8 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
dd->stopAutoScroll();
draggedItems.clear();
dd->emitIndexesMoved(indexes);
+ // do not delete item on internal move, see filterStartDrag()
+ e->setDropAction(Qt::CopyAction);
e->accept(); // we have handled the event
// if the size has not grown, we need to check if it has shrinked
if (contentsSize != contents) {