X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/e30494323dc2f895026c14dd0f74742505ee3cda..b4e80645e8e39ef7fcc1545136bad06ab3dd5f3e:/src/kitemviews/kitemlistview.cpp diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index ce2d9737c..82325cb19 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -8,12 +8,16 @@ #include "kitemlistview.h" +#ifndef QT_NO_ACCESSIBILITY +#include "accessibility/kitemlistcontaineraccessible.h" +#include "accessibility/kitemlistdelegateaccessible.h" +#include "accessibility/kitemlistviewaccessible.h" +#endif #include "dolphindebug.h" #include "kitemlistcontainer.h" #include "kitemlistcontroller.h" #include "kitemlistheader.h" #include "kitemlistselectionmanager.h" -#include "kitemlistviewaccessible.h" #include "kstandarditemlistwidget.h" #include "private/kitemlistheaderwidget.h" @@ -21,6 +25,8 @@ #include "private/kitemlistsizehintresolver.h" #include "private/kitemlistviewlayouter.h" +#include + #include #include #include @@ -29,72 +35,80 @@ #include #include +namespace +{ +// Time in ms until reaching the autoscroll margin triggers +// an initial autoscrolling +const int InitialAutoScrollDelay = 700; -namespace { - // Time in ms until reaching the autoscroll margin triggers - // an initial autoscrolling - const int InitialAutoScrollDelay = 700; - - // Delay in ms for triggering the next autoscroll - const int RepeatingAutoScrollDelay = 1000 / 60; +// Delay in ms for triggering the next autoscroll +const int RepeatingAutoScrollDelay = 1000 / 60; - // Copied from the Kirigami.Units.shortDuration - const int RubberFadeSpeed = 150; +// Copied from the Kirigami.Units.shortDuration +const int RubberFadeSpeed = 150; - const char* RubberPropertyName = "_kitemviews_rubberBandPosition"; +const char *RubberPropertyName = "_kitemviews_rubberBandPosition"; } #ifndef QT_NO_ACCESSIBILITY -QAccessibleInterface* accessibleInterfaceFactory(const QString& key, QObject* object) +QAccessibleInterface *accessibleInterfaceFactory(const QString &key, QObject *object) { Q_UNUSED(key) - if (KItemListContainer* container = qobject_cast(object)) { + if (KItemListContainer *container = qobject_cast(object)) { + if (auto controller = container->controller(); controller) { + if (KItemListView *view = controller->view(); view && view->accessibleParent()) { + return view->accessibleParent(); + } + } return new KItemListContainerAccessible(container); - } else if (KItemListView* view = qobject_cast(object)) { - return new KItemListViewAccessible(view); + } else if (KItemListView *view = qobject_cast(object)) { + return new KItemListViewAccessible(view, view->accessibleParent()); } return nullptr; } #endif -KItemListView::KItemListView(QGraphicsWidget* parent) : - QGraphicsWidget(parent), - m_enabledSelectionToggles(false), - m_grouped(false), - m_supportsItemExpanding(false), - m_editingRole(false), - m_activeTransactions(0), - m_endTransactionAnimationHint(Animation), - m_itemSize(), - m_controller(nullptr), - m_model(nullptr), - m_visibleRoles(), - m_widgetCreator(nullptr), - m_groupHeaderCreator(nullptr), - m_styleOption(), - m_visibleItems(), - m_visibleGroups(), - m_visibleCells(), - m_sizeHintResolver(nullptr), - m_layouter(nullptr), - m_animation(nullptr), - m_layoutTimer(nullptr), - m_oldScrollOffset(0), - m_oldMaximumScrollOffset(0), - m_oldItemOffset(0), - m_oldMaximumItemOffset(0), - m_skipAutoScrollForRubberBand(false), - m_rubberBand(nullptr), - m_tapAndHoldIndicator(nullptr), - m_mousePos(), - m_autoScrollIncrement(0), - m_autoScrollTimer(nullptr), - m_header(nullptr), - m_headerWidget(nullptr), - m_indicatorAnimation(nullptr), - m_dropIndicator() +KItemListView::KItemListView(QGraphicsWidget *parent) + : QGraphicsWidget(parent) + , m_enabledSelectionToggles(false) + , m_grouped(false) + , m_highlightEntireRow(false) + , m_alternateBackgrounds(false) + , m_supportsItemExpanding(false) + , m_editingRole(false) + , m_activeTransactions(0) + , m_endTransactionAnimationHint(Animation) + , m_itemSize() + , m_controller(nullptr) + , m_model(nullptr) + , m_visibleRoles() + , m_widgetCreator(nullptr) + , m_groupHeaderCreator(nullptr) + , m_styleOption() + , m_visibleItems() + , m_visibleGroups() + , m_visibleCells() + , m_scrollBarExtent(0) + , m_layouter(nullptr) + , m_animation(nullptr) + , m_oldScrollOffset(0) + , m_oldMaximumScrollOffset(0) + , m_oldItemOffset(0) + , m_oldMaximumItemOffset(0) + , m_skipAutoScrollForRubberBand(false) + , m_rubberBand(nullptr) + , m_tapAndHoldIndicator(nullptr) + , m_mousePos() + , m_autoScrollIncrement(0) + , m_autoScrollTimer(nullptr) + , m_header(nullptr) + , m_headerWidget(nullptr) + , m_indicatorAnimation(nullptr) + , m_statusBarOffset(0) + , m_dropIndicator() + , m_sizeHintResolver(nullptr) { setAcceptHoverEvents(true); setAcceptTouchEvents(true); @@ -104,13 +118,7 @@ KItemListView::KItemListView(QGraphicsWidget* parent) : m_layouter = new KItemListViewLayouter(m_sizeHintResolver, this); m_animation = new KItemListViewAnimation(this); - connect(m_animation, &KItemListViewAnimation::finished, - this, &KItemListView::slotAnimationFinished); - - m_layoutTimer = new QTimer(this); - m_layoutTimer->setInterval(300); - m_layoutTimer->setSingleShot(true); - connect(m_layoutTimer, &QTimer::timeout, this, &KItemListView::slotLayoutTimerFinished); + connect(m_animation, &KItemListViewAnimation::finished, this, &KItemListView::slotAnimationFinished); m_rubberBand = new KItemListRubberBand(this); connect(m_rubberBand, &KItemListRubberBand::activationChanged, this, &KItemListView::slotRubberBandActivationChanged); @@ -140,7 +148,6 @@ KItemListView::KItemListView(QGraphicsWidget* parent) : #ifndef QT_NO_ACCESSIBILITY QAccessible::installFactory(accessibleInterfaceFactory); #endif - } KItemListView::~KItemListView() @@ -186,7 +193,7 @@ qreal KItemListView::scrollOffset() const qreal KItemListView::maximumScrollOffset() const { - return m_layouter->maximumScrollOffset(); + return m_layouter->maximumScrollOffset() + m_statusBarOffset; } void KItemListView::setItemOffset(qreal offset) @@ -221,7 +228,7 @@ int KItemListView::maximumVisibleItems() const return m_layouter->maximumVisibleItems(); } -void KItemListView::setVisibleRoles(const QList& roles) +void KItemListView::setVisibleRoles(const QList &roles) { const QList previousRoles = m_visibleRoles; m_visibleRoles = roles; @@ -236,7 +243,7 @@ void KItemListView::setVisibleRoles(const QList& roles) if (!m_headerWidget->automaticColumnResizing()) { // The column-width of new roles are still 0. Apply the preferred // column-width as default with. - for (const QByteArray& role : qAsConst(m_visibleRoles)) { + for (const QByteArray &role : std::as_const(m_visibleRoles)) { if (m_headerWidget->columnWidth(role) == 0) { const qreal width = m_headerWidget->preferredColumnWidth(role); m_headerWidget->setColumnWidth(role, width); @@ -247,14 +254,13 @@ void KItemListView::setVisibleRoles(const QList& roles) } } - const bool alternateBackgroundsChanged = m_itemSize.isEmpty() && - ((roles.count() > 1 && previousRoles.count() <= 1) || - (roles.count() <= 1 && previousRoles.count() > 1)); + const bool alternateBackgroundsChanged = + m_itemSize.isEmpty() && ((roles.count() > 1 && previousRoles.count() <= 1) || (roles.count() <= 1 && previousRoles.count() > 1)); - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); - KItemListWidget* widget = it.value(); + KItemListWidget *widget = it.value(); widget->setVisibleRoles(roles); if (alternateBackgroundsChanged) { updateAlternateBackgroundForWidget(widget); @@ -292,7 +298,7 @@ void KItemListView::setEnabledSelectionToggles(bool enabled) if (m_enabledSelectionToggles != enabled) { m_enabledSelectionToggles = enabled; - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); it.value()->setEnabledSelectionToggle(enabled); @@ -305,23 +311,23 @@ bool KItemListView::enabledSelectionToggles() const return m_enabledSelectionToggles; } -KItemListController* KItemListView::controller() const +KItemListController *KItemListView::controller() const { return m_controller; } -KItemModelBase* KItemListView::model() const +KItemModelBase *KItemListView::model() const { return m_model; } -void KItemListView::setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator) +void KItemListView::setWidgetCreator(KItemListWidgetCreatorBase *widgetCreator) { delete m_widgetCreator; m_widgetCreator = widgetCreator; } -KItemListWidgetCreatorBase* KItemListView::widgetCreator() const +KItemListWidgetCreatorBase *KItemListView::widgetCreator() const { if (!m_widgetCreator) { m_widgetCreator = defaultWidgetCreator(); @@ -329,13 +335,13 @@ KItemListWidgetCreatorBase* KItemListView::widgetCreator() const return m_widgetCreator; } -void KItemListView::setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator) +void KItemListView::setGroupHeaderCreator(KItemListGroupHeaderCreatorBase *groupHeaderCreator) { delete m_groupHeaderCreator; m_groupHeaderCreator = groupHeaderCreator; } -KItemListGroupHeaderCreatorBase* KItemListView::groupHeaderCreator() const +KItemListGroupHeaderCreatorBase *KItemListView::groupHeaderCreator() const { if (!m_groupHeaderCreator) { m_groupHeaderCreator = defaultGroupHeaderCreator(); @@ -343,17 +349,30 @@ KItemListGroupHeaderCreatorBase* KItemListView::groupHeaderCreator() const return m_groupHeaderCreator; } +#ifndef QT_NO_ACCESSIBILITY +void KItemListView::setAccessibleParentsObject(KItemListContainer *accessibleParentsObject) +{ + Q_ASSERT(!m_accessibleParent); + m_accessibleParent = new KItemListContainerAccessible(accessibleParentsObject); +} +KItemListContainerAccessible *KItemListView::accessibleParent() +{ + Q_CHECK_PTR(m_accessibleParent); // We always want the accessibility tree/hierarchy to be complete. + return m_accessibleParent; +} +#endif + QSizeF KItemListView::itemSize() const { return m_itemSize; } -const KItemListStyleOption& KItemListView::styleOption() const +const KItemListStyleOption &KItemListView::styleOption() const { return m_styleOption; } -void KItemListView::setGeometry(const QRectF& rect) +void KItemListView::setGeometry(const QRectF &rect) { QGraphicsWidget::setGeometry(rect); @@ -367,9 +386,8 @@ void KItemListView::setGeometry(const QRectF& rect) if (m_headerWidget->automaticColumnResizing()) { applyAutomaticColumnWidths(); } else { - const qreal requiredWidth = columnWidthsSum(); - const QSizeF dynamicItemSize(qMax(newSize.width(), requiredWidth), - m_itemSize.height()); + const qreal requiredWidth = m_headerWidget->leftPadding() + columnWidthsSum() + m_headerWidget->rightPadding(); + const QSizeF dynamicItemSize(qMax(newSize.width(), requiredWidth), m_itemSize.height()); m_layouter->setItemSize(dynamicItemSize); } } @@ -380,6 +398,12 @@ void KItemListView::setGeometry(const QRectF& rect) doLayout(NoAnimation); } +qreal KItemListView::scrollSingleStep() const +{ + const QFontMetrics metrics(font()); + return metrics.height(); +} + qreal KItemListView::verticalPageStep() const { qreal headerHeight = 0; @@ -389,29 +413,33 @@ qreal KItemListView::verticalPageStep() const return size().height() - headerHeight; } -int KItemListView::itemAt(const QPointF& pos) const +std::optional KItemListView::itemAt(const QPointF &pos) const { - QHashIterator it(m_visibleItems); + if (headerBoundaries().contains(pos)) { + return std::nullopt; + } + + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); - const KItemListWidget* widget = it.value(); + const KItemListWidget *widget = it.value(); const QPointF mappedPos = widget->mapFromItem(this, pos); if (widget->contains(mappedPos)) { return it.key(); } } - return -1; + return std::nullopt; } -bool KItemListView::isAboveSelectionToggle(int index, const QPointF& pos) const +bool KItemListView::isAboveSelectionToggle(int index, const QPointF &pos) const { if (!m_enabledSelectionToggles) { return false; } - const KItemListWidget* widget = m_visibleItems.value(index); + const KItemListWidget *widget = m_visibleItems.value(index); if (widget) { const QRectF selectionToggleRect = widget->selectionToggleRect(); if (!selectionToggleRect.isEmpty()) { @@ -422,9 +450,9 @@ bool KItemListView::isAboveSelectionToggle(int index, const QPointF& pos) const return false; } -bool KItemListView::isAboveExpansionToggle(int index, const QPointF& pos) const +bool KItemListView::isAboveExpansionToggle(int index, const QPointF &pos) const { - const KItemListWidget* widget = m_visibleItems.value(index); + const KItemListWidget *widget = m_visibleItems.value(index); if (widget) { const QRectF expansionToggleRect = widget->expansionToggleRect(); if (!expansionToggleRect.isEmpty()) { @@ -437,7 +465,7 @@ bool KItemListView::isAboveExpansionToggle(int index, const QPointF& pos) const bool KItemListView::isAboveText(int index, const QPointF &pos) const { - const KItemListWidget* widget = m_visibleItems.value(index); + const KItemListWidget *widget = m_visibleItems.value(index); if (widget) { const QRectF &textRect = widget->textRect(); if (!textRect.isEmpty()) { @@ -458,7 +486,7 @@ int KItemListView::lastVisibleIndex() const return m_layouter->lastVisibleIndex(); } -void KItemListView::calculateItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint) const +void KItemListView::calculateItemSizeHints(QVector> &logicalHeightHints, qreal &logicalWidthHint) const { widgetCreator()->calculateItemSizeHints(logicalHeightHints, logicalWidthHint, this); } @@ -477,6 +505,32 @@ bool KItemListView::supportsItemExpanding() const return m_supportsItemExpanding; } +void KItemListView::setHighlightEntireRow(bool highlightEntireRow) +{ + if (m_highlightEntireRow != highlightEntireRow) { + m_highlightEntireRow = highlightEntireRow; + onHighlightEntireRowChanged(highlightEntireRow); + } +} + +bool KItemListView::highlightEntireRow() const +{ + return m_highlightEntireRow; +} + +void KItemListView::setAlternateBackgrounds(bool alternate) +{ + if (m_alternateBackgrounds != alternate) { + m_alternateBackgrounds = alternate; + updateAlternateBackgrounds(); + } +} + +bool KItemListView::alternateBackgrounds() const +{ + return m_alternateBackgrounds; +} + QRectF KItemListView::itemRect(int index) const { return m_layouter->itemRect(index); @@ -486,48 +540,115 @@ QRectF KItemListView::itemContextRect(int index) const { QRectF contextRect; - const KItemListWidget* widget = m_visibleItems.value(index); + const KItemListWidget *widget = m_visibleItems.value(index); if (widget) { - contextRect = widget->iconRect() | widget->textRect(); + contextRect = widget->selectionRectCore(); contextRect.translate(itemRect(index).topLeft()); } return contextRect; } -void KItemListView::scrollToItem(int index) +bool KItemListView::isElided(int index) const +{ + return m_sizeHintResolver->isElided(index); +} + +void KItemListView::scrollToItem(int index, ViewItemPosition viewItemPosition) { QRectF viewGeometry = geometry(); if (m_headerWidget->isVisible()) { const qreal headerHeight = m_headerWidget->size().height(); viewGeometry.adjust(0, headerHeight, 0, 0); } + if (m_statusBarOffset != 0) { + viewGeometry.adjust(0, 0, 0, -m_statusBarOffset); + } QRectF currentRect = itemRect(index); - // Fix for Bug 311099 - View the underscore when using Ctrl + PagDown - currentRect.adjust(-m_styleOption.horizontalMargin, -m_styleOption.verticalMargin, - m_styleOption.horizontalMargin, m_styleOption.verticalMargin); + if (layoutDirection() == Qt::RightToLeft && scrollOrientation() == Qt::Horizontal) { + currentRect.moveLeft(m_layouter->size().width() - currentRect.right()); + } - if (!viewGeometry.contains(currentRect)) { - qreal newOffset = scrollOffset(); - if (scrollOrientation() == Qt::Vertical) { - if (currentRect.top() < viewGeometry.top()) { - newOffset += currentRect.top() - viewGeometry.top(); - } else if (currentRect.bottom() > viewGeometry.bottom()) { - newOffset += currentRect.bottom() - viewGeometry.bottom(); + // Fix for Bug 311099 - View the underscore when using Ctrl + PageDown + currentRect.adjust(-m_styleOption.horizontalMargin, -m_styleOption.verticalMargin, m_styleOption.horizontalMargin, m_styleOption.verticalMargin); + + qreal offset = 0; + switch (scrollOrientation()) { + case Qt::Vertical: + if (currentRect.top() < viewGeometry.top() || currentRect.bottom() > viewGeometry.bottom()) { + switch (viewItemPosition) { + case Beginning: + offset = currentRect.top() - viewGeometry.top(); + break; + case Middle: + offset = 0.5 * (currentRect.top() + currentRect.bottom() - (viewGeometry.top() + viewGeometry.bottom())); + break; + case End: + offset = currentRect.bottom() - viewGeometry.bottom(); + break; + case Nearest: + if (currentRect.top() < viewGeometry.top()) { + offset = currentRect.top() - viewGeometry.top(); + } + if (currentRect.bottom() > viewGeometry.bottom() + offset) { + offset += currentRect.bottom() - viewGeometry.bottom() - offset; + } + break; + default: + Q_UNREACHABLE(); } - } else { - if (currentRect.left() < viewGeometry.left()) { - newOffset += currentRect.left() - viewGeometry.left(); - } else if (currentRect.right() > viewGeometry.right()) { - newOffset += currentRect.right() - viewGeometry.right(); + } + break; + case Qt::Horizontal: + if (currentRect.left() < viewGeometry.left() || currentRect.right() > viewGeometry.right()) { + switch (viewItemPosition) { + case Beginning: + if (layoutDirection() == Qt::RightToLeft) { + offset = currentRect.right() - viewGeometry.right(); + } else { + offset = currentRect.left() - viewGeometry.left(); + } + break; + case Middle: + offset = 0.5 * (currentRect.left() + currentRect.right() - (viewGeometry.left() + viewGeometry.right())); + break; + case End: + if (layoutDirection() == Qt::RightToLeft) { + offset = currentRect.left() - viewGeometry.left(); + } else { + offset = currentRect.right() - viewGeometry.right(); + } + break; + case Nearest: + if (layoutDirection() == Qt::RightToLeft) { + if (currentRect.left() < viewGeometry.left()) { + offset = currentRect.left() - viewGeometry.left(); + } + if (currentRect.right() > viewGeometry.right() + offset) { + offset += currentRect.right() - viewGeometry.right() - offset; + } + } else { + if (currentRect.right() > viewGeometry.right()) { + offset = currentRect.right() - viewGeometry.right(); + } + if (currentRect.left() < viewGeometry.left() + offset) { + offset += currentRect.left() - viewGeometry.left() - offset; + } + } + break; + default: + Q_UNREACHABLE(); } } + break; + default: + Q_UNREACHABLE(); + } - if (newOffset != scrollOffset()) { - Q_EMIT scrollTo(newOffset); - return; - } + if (!qFuzzyIsNull(offset)) { + Q_EMIT scrollTo(scrollOffset() + offset); + return; } Q_EMIT scrollingStopped(); @@ -565,8 +686,7 @@ void KItemListView::setHeaderVisible(bool visible) { if (visible && !m_headerWidget->isVisible()) { QStyleOptionHeader option; - const QSize headerSize = style()->sizeFromContents(QStyle::CT_HeaderSection, - &option, QSize()); + const QSize headerSize = style()->sizeFromContents(QStyle::CT_HeaderSection, &option, QSize()); m_headerWidget->setPos(0, 0); m_headerWidget->resize(size().width(), headerSize.height()); @@ -574,26 +694,24 @@ void KItemListView::setHeaderVisible(bool visible) m_headerWidget->setColumns(m_visibleRoles); m_headerWidget->setZValue(1); - connect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged, - this, &KItemListView::slotHeaderColumnWidthChanged); - connect(m_headerWidget, &KItemListHeaderWidget::columnMoved, - this, &KItemListView::slotHeaderColumnMoved); - connect(m_headerWidget, &KItemListHeaderWidget::sortOrderChanged, - this, &KItemListView::sortOrderChanged); - connect(m_headerWidget, &KItemListHeaderWidget::sortRoleChanged, - this, &KItemListView::sortRoleChanged); + connect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged, this, &KItemListView::slotHeaderColumnWidthChanged); + connect(m_headerWidget, &KItemListHeaderWidget::sidePaddingChanged, this, &KItemListView::slotSidePaddingChanged); + connect(m_headerWidget, &KItemListHeaderWidget::columnMoved, this, &KItemListView::slotHeaderColumnMoved); + connect(m_headerWidget, &KItemListHeaderWidget::sortOrderChanged, this, &KItemListView::sortOrderChanged); + connect(m_headerWidget, &KItemListHeaderWidget::sortRoleChanged, this, &KItemListView::sortRoleChanged); + connect(m_headerWidget, &KItemListHeaderWidget::columnHovered, this, &KItemListView::columnHovered); + connect(m_headerWidget, &KItemListHeaderWidget::columnUnHovered, this, &KItemListView::columnUnHovered); m_layouter->setHeaderHeight(headerSize.height()); m_headerWidget->setVisible(true); } else if (!visible && m_headerWidget->isVisible()) { - disconnect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged, - this, &KItemListView::slotHeaderColumnWidthChanged); - disconnect(m_headerWidget, &KItemListHeaderWidget::columnMoved, - this, &KItemListView::slotHeaderColumnMoved); - disconnect(m_headerWidget, &KItemListHeaderWidget::sortOrderChanged, - this, &KItemListView::sortOrderChanged); - disconnect(m_headerWidget, &KItemListHeaderWidget::sortRoleChanged, - this, &KItemListView::sortRoleChanged); + disconnect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged, this, &KItemListView::slotHeaderColumnWidthChanged); + disconnect(m_headerWidget, &KItemListHeaderWidget::sidePaddingChanged, this, &KItemListView::slotSidePaddingChanged); + disconnect(m_headerWidget, &KItemListHeaderWidget::columnMoved, this, &KItemListView::slotHeaderColumnMoved); + disconnect(m_headerWidget, &KItemListHeaderWidget::sortOrderChanged, this, &KItemListView::sortOrderChanged); + disconnect(m_headerWidget, &KItemListHeaderWidget::sortRoleChanged, this, &KItemListView::sortRoleChanged); + disconnect(m_headerWidget, &KItemListHeaderWidget::columnHovered, this, &KItemListView::columnHovered); + disconnect(m_headerWidget, &KItemListHeaderWidget::columnUnHovered, this, &KItemListView::columnUnHovered); m_layouter->setHeaderHeight(0); m_headerWidget->setVisible(false); @@ -605,18 +723,18 @@ bool KItemListView::isHeaderVisible() const return m_headerWidget->isVisible(); } -KItemListHeader* KItemListView::header() const +KItemListHeader *KItemListView::header() const { return m_header; } -QPixmap KItemListView::createDragPixmap(const KItemSet& indexes) const +QPixmap KItemListView::createDragPixmap(const KItemSet &indexes) const { QPixmap pixmap; if (indexes.count() == 1) { - KItemListWidget* item = m_visibleItems.value(indexes.first()); - QGraphicsView* graphicsView = scene()->views()[0]; + KItemListWidget *item = m_visibleItems.value(indexes.first()); + QGraphicsView *graphicsView = scene()->views()[0]; if (item && graphicsView) { pixmap = item->createDragPixmap(nullptr, graphicsView); } @@ -629,30 +747,32 @@ QPixmap KItemListView::createDragPixmap(const KItemSet& indexes) const return pixmap; } -void KItemListView::editRole(int index, const QByteArray& role) +void KItemListView::editRole(int index, const QByteArray &role) { - KStandardItemListWidget* widget = qobject_cast(m_visibleItems.value(index)); - if (!widget || m_editingRole) { + KStandardItemListWidget *widget = qobject_cast(m_visibleItems.value(index)); + if (!widget) { + return; + } + if (m_editingRole || m_animation->isStarted(widget)) { + Q_EMIT widget->roleEditingCanceled(index, role, QVariant()); return; } m_editingRole = true; + m_controller->selectionManager()->setCurrentItem(index); widget->setEditedRole(role); - connect(widget, &KItemListWidget::roleEditingCanceled, - this, &KItemListView::slotRoleEditingCanceled); - connect(widget, &KItemListWidget::roleEditingFinished, - this, &KItemListView::slotRoleEditingFinished); + connect(widget, &KItemListWidget::roleEditingCanceled, this, &KItemListView::slotRoleEditingCanceled); + connect(widget, &KItemListWidget::roleEditingFinished, this, &KItemListView::slotRoleEditingFinished); - connect(this, &KItemListView::scrollOffsetChanged, - widget, &KStandardItemListWidget::finishRoleEditing); + connect(this, &KItemListView::scrollOffsetChanged, widget, &KStandardItemListWidget::finishRoleEditing); } -void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +void KItemListView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { QGraphicsWidget::paint(painter, option, widget); - for (auto animation : qAsConst(m_rubberBandAnimations)) { + for (auto animation : std::as_const(m_rubberBandAnimations)) { QRectF rubberBandRect = animation->property(RubberPropertyName).toRectF(); const QPointF topLeft = rubberBandRect.topLeft(); @@ -677,8 +797,7 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt } if (m_rubberBand->isActive()) { - QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(), - m_rubberBand->endPosition()).normalized(); + QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(), m_rubberBand->endPosition()).normalized(); const QPointF topLeft = rubberBandRect.topLeft(); if (scrollOrientation() == Qt::Vertical) { @@ -697,8 +816,8 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt if (m_tapAndHoldIndicator->isActive()) { const QPointF indicatorSize = m_tapAndHoldIndicator->endPosition(); - const QRectF rubberBandRect = QRectF(m_tapAndHoldIndicator->startPosition() - indicatorSize, - (m_tapAndHoldIndicator->startPosition()) + indicatorSize).normalized(); + const QRectF rubberBandRect = + QRectF(m_tapAndHoldIndicator->startPosition() - indicatorSize, (m_tapAndHoldIndicator->startPosition()) + indicatorSize).normalized(); QStyleOptionRubberBand opt; initStyleOption(&opt); opt.shape = QRubberBand::Rectangle; @@ -724,6 +843,16 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt } } +void KItemListView::setStatusBarOffset(int offset) +{ + if (m_statusBarOffset != offset) { + m_statusBarOffset = offset; + if (m_layouter) { + m_layouter->setStatusBarOffset(offset); + } + } +} + QVariant KItemListView::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemSceneHasChanged && scene()) { @@ -734,7 +863,7 @@ QVariant KItemListView::itemChange(GraphicsItemChange change, const QVariant &va return QGraphicsItem::itemChange(change, value); } -void KItemListView::setItemSize(const QSizeF& size) +void KItemListView::setItemSize(const QSizeF &size) { const QSizeF previousSize = m_itemSize; if (size == previousSize) { @@ -744,13 +873,9 @@ void KItemListView::setItemSize(const QSizeF& size) // Skip animations when the number of rows or columns // are changed in the grid layout. Although the animation // engine can handle this usecase, it looks obtrusive. - const bool animate = !changesItemGridLayout(m_layouter->size(), - size, - m_layouter->itemMargin()); + const bool animate = !changesItemGridLayout(m_layouter->size(), size, m_layouter->itemMargin()); - const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) && - (( m_itemSize.isEmpty() && !size.isEmpty()) || - (!m_itemSize.isEmpty() && size.isEmpty())); + const bool alternateBackgroundsChanged = m_alternateBackgrounds && ((m_itemSize.isEmpty() && !size.isEmpty()) || (!m_itemSize.isEmpty() && size.isEmpty())); m_itemSize = size; @@ -780,7 +905,7 @@ void KItemListView::setItemSize(const QSizeF& size) onItemSizeChanged(size, previousSize); } -void KItemListView::setStyleOption(const KItemListStyleOption& option) +void KItemListView::setStyleOption(const KItemListStyleOption &option) { if (m_styleOption == option) { return; @@ -795,9 +920,7 @@ void KItemListView::setStyleOption(const KItemListStyleOption& option) // Skip animations when the number of rows or columns // are changed in the grid layout. Although the animation // engine can handle this usecase, it looks obtrusive. - animate = !changesItemGridLayout(m_layouter->size(), - m_layouter->itemSize(), - margin); + animate = !changesItemGridLayout(m_layouter->size(), m_layouter->itemSize(), margin); m_layouter->setItemMargin(margin); } @@ -805,14 +928,13 @@ void KItemListView::setStyleOption(const KItemListStyleOption& option) updateGroupHeaderHeight(); } - if (animate && - (previousOption.maxTextLines != option.maxTextLines || previousOption.maxTextWidth != option.maxTextWidth)) { + if (animate && (previousOption.maxTextLines != option.maxTextLines || previousOption.maxTextWidth != option.maxTextWidth)) { // Animating a change of the maximum text size just results in expensive // temporary eliding and clipping operations and does not look good visually. animate = false; } - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); it.value()->setStyleOption(option); @@ -841,13 +963,12 @@ void KItemListView::setScrollOrientation(Qt::Orientation orientation) m_sizeHintResolver->clearCache(); if (m_grouped) { - QMutableHashIterator it (m_visibleGroups); + QMutableHashIterator it(m_visibleGroups); while (it.hasNext()) { it.next(); it.value()->setScrollOrientation(orientation); } updateGroupHeaderHeight(); - } doLayout(NoAnimation); @@ -861,34 +982,34 @@ Qt::Orientation KItemListView::scrollOrientation() const return m_layouter->scrollOrientation(); } -KItemListWidgetCreatorBase* KItemListView::defaultWidgetCreator() const +KItemListWidgetCreatorBase *KItemListView::defaultWidgetCreator() const { return nullptr; } -KItemListGroupHeaderCreatorBase* KItemListView::defaultGroupHeaderCreator() const +KItemListGroupHeaderCreatorBase *KItemListView::defaultGroupHeaderCreator() const { return nullptr; } -void KItemListView::initializeItemListWidget(KItemListWidget* item) +void KItemListView::initializeItemListWidget(KItemListWidget *item) { Q_UNUSED(item) } -bool KItemListView::itemSizeHintUpdateRequired(const QSet& changedRoles) const +bool KItemListView::itemSizeHintUpdateRequired(const QSet &changedRoles) const { Q_UNUSED(changedRoles) return true; } -void KItemListView::onControllerChanged(KItemListController* current, KItemListController* previous) +void KItemListView::onControllerChanged(KItemListController *current, KItemListController *previous) { Q_UNUSED(current) Q_UNUSED(previous) } -void KItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous) +void KItemListView::onModelChanged(KItemModelBase *current, KItemModelBase *previous) { Q_UNUSED(current) Q_UNUSED(previous) @@ -900,7 +1021,7 @@ void KItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orie Q_UNUSED(previous) } -void KItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& previous) +void KItemListView::onItemSizeChanged(const QSizeF ¤t, const QSizeF &previous) { Q_UNUSED(current) Q_UNUSED(previous) @@ -912,18 +1033,23 @@ void KItemListView::onScrollOffsetChanged(qreal current, qreal previous) Q_UNUSED(previous) } -void KItemListView::onVisibleRolesChanged(const QList& current, const QList& previous) +void KItemListView::onVisibleRolesChanged(const QList ¤t, const QList &previous) { Q_UNUSED(current) Q_UNUSED(previous) } -void KItemListView::onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous) +void KItemListView::onStyleOptionChanged(const KItemListStyleOption ¤t, const KItemListStyleOption &previous) { Q_UNUSED(current) Q_UNUSED(previous) } +void KItemListView::onHighlightEntireRowChanged(bool highlightEntireRow) +{ + Q_UNUSED(highlightEntireRow) +} + void KItemListView::onSupportsItemExpandingChanged(bool supportsExpanding) { Q_UNUSED(supportsExpanding) @@ -937,7 +1063,7 @@ void KItemListView::onTransactionEnd() { } -bool KItemListView::event(QEvent* event) +bool KItemListView::event(QEvent *event) { switch (event->type()) { case QEvent::PaletteChange: @@ -948,6 +1074,18 @@ bool KItemListView::event(QEvent* event) updateFont(); break; + case QEvent::FocusIn: + focusInEvent(static_cast(event)); + event->accept(); + return true; + break; + + case QEvent::FocusOut: + focusOutEvent(static_cast(event)); + event->accept(); + return true; + break; + default: // Forward all other events to the controller and handle them there if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) { @@ -959,13 +1097,13 @@ bool KItemListView::event(QEvent* event) return QGraphicsWidget::event(event); } -void KItemListView::mousePressEvent(QGraphicsSceneMouseEvent* event) +void KItemListView::mousePressEvent(QGraphicsSceneMouseEvent *event) { m_mousePos = transform().map(event->pos()); event->accept(); } -void KItemListView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +void KItemListView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QGraphicsWidget::mouseMoveEvent(event); @@ -975,13 +1113,13 @@ void KItemListView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) } } -void KItemListView::dragEnterEvent(QGraphicsSceneDragDropEvent* event) +void KItemListView::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { event->setAccepted(true); setAutoScroll(true); } -void KItemListView::dragMoveEvent(QGraphicsSceneDragDropEvent* event) +void KItemListView::dragMoveEvent(QGraphicsSceneDragDropEvent *event) { QGraphicsWidget::dragMoveEvent(event); @@ -991,19 +1129,19 @@ void KItemListView::dragMoveEvent(QGraphicsSceneDragDropEvent* event) } } -void KItemListView::dragLeaveEvent(QGraphicsSceneDragDropEvent* event) +void KItemListView::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) { QGraphicsWidget::dragLeaveEvent(event); setAutoScroll(false); } -void KItemListView::dropEvent(QGraphicsSceneDragDropEvent* event) +void KItemListView::dropEvent(QGraphicsSceneDragDropEvent *event) { QGraphicsWidget::dropEvent(event); setAutoScroll(false); } -QList KItemListView::visibleItemListWidgets() const +QList KItemListView::visibleItemListWidgets() const { return m_visibleItems.values(); } @@ -1021,15 +1159,12 @@ void KItemListView::updateFont() void KItemListView::updatePalette() { - if (scene() && !scene()->views().isEmpty()) { - KItemListStyleOption option = styleOption(); - option.palette = scene()->views().first()->palette(); - - setStyleOption(option); - } + KItemListStyleOption option = styleOption(); + option.palette = palette(); + setStyleOption(option); } -void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) +void KItemListView::slotItemsInserted(const KItemRangeList &itemRanges) { if (m_itemSize.isEmpty()) { updatePreferredColumnWidths(itemRanges); @@ -1045,7 +1180,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) m_sizeHintResolver->itemsInserted(itemRanges); int previouslyInsertedCount = 0; - for (const KItemRange& range : itemRanges) { + for (const KItemRange &range : itemRanges) { // range.index is related to the model before anything has been inserted. // As in each loop the current item-range gets inserted the index must // be increased by the already previously inserted items. @@ -1059,7 +1194,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) // Determine which visible items must be moved QList itemsToMove; - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); const int visibleItemIndex = it.key(); @@ -1073,7 +1208,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) // from the highest index to the lowest index to prevent overlaps when setting the new index. std::sort(itemsToMove.begin(), itemsToMove.end()); for (int i = itemsToMove.count() - 1; i >= 0; --i) { - KItemListWidget* widget = m_visibleItems.value(itemsToMove[i]); + KItemListWidget *widget = m_visibleItems.value(itemsToMove[i]); Q_ASSERT(widget); const int newIndex = widget->index() + count; if (hasMultipleRanges) { @@ -1089,8 +1224,8 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) // the size of the layouter will be decreased before calling doLayout(): This prevents // an unnecessary temporary animation due to the geometry change of the inserted scrollbar. const bool verticalScrollOrientation = (scrollOrientation() == Qt::Vertical); - const bool decreaseLayouterSize = ( verticalScrollOrientation && maximumScrollOffset() > size().height()) || - (!verticalScrollOrientation && maximumScrollOffset() > size().width()); + const bool decreaseLayouterSize = (verticalScrollOrientation && maximumScrollOffset() > size().height()) + || (!verticalScrollOrientation && maximumScrollOffset() > size().width()); if (decreaseLayouterSize) { const int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent); @@ -1138,7 +1273,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) } } -void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) +void KItemListView::slotItemsRemoved(const KItemRangeList &itemRanges) { if (m_itemSize.isEmpty()) { // Don't pass the item-range: The preferred column-widths of @@ -1156,7 +1291,7 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) m_sizeHintResolver->itemsRemoved(itemRanges); for (int i = itemRanges.count() - 1; i >= 0; --i) { - const KItemRange& range = itemRanges[i]; + const KItemRange &range = itemRanges[i]; const int index = range.index; const int count = range.count; if (index < 0 || count <= 0) { @@ -1174,7 +1309,7 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) // Iterate over a const copy because the container is mutated within the loop // directly and in `recycleWidget()` (https://bugs.kde.org/show_bug.cgi?id=428374) const auto visibleItems = m_visibleItems; - for (KItemListWidget* widget : visibleItems) { + for (KItemListWidget *widget : visibleItems) { const int i = widget->index(); if (i < firstRemovedIndex) { continue; @@ -1210,8 +1345,8 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) // after the deleted items. It is important to update them in ascending // order to prevent overlaps when setting the new index. std::sort(itemsToMove.begin(), itemsToMove.end()); - for (int i : qAsConst(itemsToMove)) { - KItemListWidget* widget = m_visibleItems.value(i); + for (int i : std::as_const(itemsToMove)) { + KItemListWidget *widget = m_visibleItems.value(i); Q_ASSERT(widget); const int newIndex = i - count; if (hasMultipleRanges) { @@ -1256,7 +1391,7 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) } } -void KItemListView::slotItemsMoved(const KItemRange& itemRange, const QList& movedToIndexes) +void KItemListView::slotItemsMoved(const KItemRange &itemRange, const QList &movedToIndexes) { m_sizeHintResolver->itemsMoved(itemRange, movedToIndexes); m_layouter->markAsDirty(); @@ -1268,9 +1403,20 @@ void KItemListView::slotItemsMoved(const KItemRange& itemRange, const QList const int firstVisibleMovedIndex = qMax(firstVisibleIndex(), itemRange.index); const int lastVisibleMovedIndex = qMin(lastVisibleIndex(), itemRange.index + itemRange.count - 1); + /// Represents an item that was moved while being edited. + struct MovedEditedItem { + int movedToIndex; + QByteArray editedRole; + }; + std::optional movedEditedItem; for (int index = firstVisibleMovedIndex; index <= lastVisibleMovedIndex; ++index) { - KItemListWidget* widget = m_visibleItems.value(index); + KItemListWidget *widget = m_visibleItems.value(index); if (widget) { + if (m_editingRole && !widget->editedRole().isEmpty()) { + movedEditedItem = {movedToIndexes[index - itemRange.index], widget->editedRole()}; + disconnectRoleEditingSignals(index); + m_editingRole = false; + } updateWidgetProperties(widget, index); initializeItemListWidget(widget); } @@ -1278,33 +1424,32 @@ void KItemListView::slotItemsMoved(const KItemRange& itemRange, const QList doLayout(NoAnimation); updateSiblingsInformation(); + + if (movedEditedItem) { + editRole(movedEditedItem->movedToIndex, movedEditedItem->editedRole); + } } -void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges, - const QSet& roles) +void KItemListView::slotItemsChanged(const KItemRangeList &itemRanges, const QSet &roles) { const bool updateSizeHints = itemSizeHintUpdateRequired(roles); if (updateSizeHints && m_itemSize.isEmpty()) { updatePreferredColumnWidths(itemRanges); } - for (const KItemRange& itemRange : itemRanges) { + for (const KItemRange &itemRange : itemRanges) { const int index = itemRange.index; const int count = itemRange.count; if (updateSizeHints) { m_sizeHintResolver->itemsChanged(index, count, roles); m_layouter->markAsDirty(); - - if (!m_layoutTimer->isActive()) { - m_layoutTimer->start(); - } } // Apply the changed roles to the visible item-widgets const int lastIndex = index + count - 1; for (int i = index; i <= lastIndex; ++i) { - KItemListWidget* widget = m_visibleItems.value(i); + KItemListWidget *widget = m_visibleItems.value(i); if (widget) { widget->setData(m_model->data(i), roles); } @@ -1316,12 +1461,8 @@ void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges, updateVisibleGroupHeaders(); doLayout(NoAnimation); } - - QAccessibleTableModelChangeEvent ev(this, QAccessibleTableModelChangeEvent::DataChanged); - ev.setFirstRow(itemRange.index); - ev.setLastRow(itemRange.index + itemRange.count); - QAccessible::updateAccessibility(&ev); } + doLayout(NoAnimation); } void KItemListView::slotGroupsChanged() @@ -1342,7 +1483,7 @@ void KItemListView::slotGroupedSortingChanged(bool current) // Clear all visible headers. Note that the QHashIterator takes a copy of // m_visibleGroups. Therefore, it remains valid even if items are removed // from m_visibleGroups in recycleGroupHeaderForWidget(). - QHashIterator it(m_visibleGroups); + QHashIterator it(m_visibleGroups); while (it.hasNext()) { it.next(); recycleGroupHeaderForWidget(it.key()); @@ -1370,7 +1511,7 @@ void KItemListView::slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder pr } } -void KItemListView::slotSortRoleChanged(const QByteArray& current, const QByteArray& previous) +void KItemListView::slotSortRoleChanged(const QByteArray ¤t, const QByteArray &previous) { Q_UNUSED(current) Q_UNUSED(previous) @@ -1380,50 +1521,82 @@ void KItemListView::slotSortRoleChanged(const QByteArray& current, const QByteAr } } -void KItemListView::slotCurrentChanged(int current, int previous) +void KItemListView::slotGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) +{ + Q_UNUSED(current) + Q_UNUSED(previous) + if (m_grouped) { + updateVisibleGroupHeaders(); + doLayout(NoAnimation); + } +} + +void KItemListView::slotGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous) { + Q_UNUSED(current) Q_UNUSED(previous) + if (m_grouped) { + updateVisibleGroupHeaders(); + doLayout(NoAnimation); + } +} +void KItemListView::slotCurrentChanged(int current, int previous) +{ // In SingleSelection mode (e.g., in the Places Panel), the current item is // always the selected item. It is not necessary to highlight the current item then. if (m_controller->selectionBehavior() != KItemListController::SingleSelection) { - KItemListWidget* previousWidget = m_visibleItems.value(previous, nullptr); + KItemListWidget *previousWidget = m_visibleItems.value(previous, nullptr); if (previousWidget) { previousWidget->setCurrent(false); } - KItemListWidget* currentWidget = m_visibleItems.value(current, nullptr); + KItemListWidget *currentWidget = m_visibleItems.value(current, nullptr); if (currentWidget) { currentWidget->setCurrent(true); } } - - QAccessibleEvent ev(this, QAccessible::Focus); - ev.setChild(current); - QAccessible::updateAccessibility(&ev); +#ifndef QT_NO_ACCESSIBILITY + if (current != previous && QAccessible::isActive()) { + static_cast(QAccessible::queryAccessibleInterface(this))->announceCurrentItem(); + } +#endif } -void KItemListView::slotSelectionChanged(const KItemSet& current, const KItemSet& previous) +void KItemListView::slotSelectionChanged(const KItemSet ¤t, const KItemSet &previous) { - Q_UNUSED(previous) - - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); const int index = it.key(); - KItemListWidget* widget = it.value(); - widget->setSelected(current.contains(index)); + KItemListWidget *widget = it.value(); + const bool isSelected(current.contains(index)); + widget->setSelected(isSelected); + +#ifndef QT_NO_ACCESSIBILITY + if (!QAccessible::isActive()) { + continue; + } + // Let the screen reader announce "selected" or "not selected" for the active item. + const bool wasSelected(previous.contains(index)); + if (isSelected != wasSelected) { + QAccessibleEvent accessibleSelectionChangedEvent(this, QAccessible::SelectionAdd); + accessibleSelectionChangedEvent.setChild(index); + QAccessible::updateAccessibility(&accessibleSelectionChangedEvent); + } + } +#else } + Q_UNUSED(previous) +#endif } -void KItemListView::slotAnimationFinished(QGraphicsWidget* widget, - KItemListViewAnimation::AnimationType type) +void KItemListView::slotAnimationFinished(QGraphicsWidget *widget, KItemListViewAnimation::AnimationType type) { - KItemListWidget* itemListWidget = qobject_cast(widget); + KItemListWidget *itemListWidget = qobject_cast(widget); Q_ASSERT(itemListWidget); - switch (type) { - case KItemListViewAnimation::DeleteAnimation: { + if (type == KItemListViewAnimation::DeleteAnimation) { // As we recycle the widget in this case it is important to assure that no // other animation has been started. This is a convention in KItemListView and // not a requirement defined by KItemListViewAnimation. @@ -1434,31 +1607,15 @@ void KItemListView::slotAnimationFinished(QGraphicsWidget* widget, // been finished. recycleGroupHeaderForWidget(itemListWidget); widgetCreator()->recycle(itemListWidget); - break; - } - - case KItemListViewAnimation::CreateAnimation: - case KItemListViewAnimation::MovingAnimation: - case KItemListViewAnimation::ResizeAnimation: { + } else { const int index = itemListWidget->index(); - const bool invisible = (index < m_layouter->firstVisibleIndex()) || - (index > m_layouter->lastVisibleIndex()); + const bool invisible = (index < m_layouter->firstVisibleIndex()) || (index > m_layouter->lastVisibleIndex()); if (invisible && !m_animation->isStarted(itemListWidget)) { recycleWidget(itemListWidget); } - break; - } - - default: break; } } -void KItemListView::slotLayoutTimerFinished() -{ - m_layouter->setSize(geometry().size()); - doLayout(Animation); -} - void KItemListView::slotRubberBandPosChanged() { update(); @@ -1471,8 +1628,7 @@ void KItemListView::slotRubberBandActivationChanged(bool active) connect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged); m_skipAutoScrollForRubberBand = true; } else { - QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(), - m_rubberBand->endPosition()).normalized(); + QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(), m_rubberBand->endPosition()).normalized(); auto animation = new QVariantAnimation(this); animation->setStartValue(1.0); @@ -1485,10 +1641,10 @@ void KItemListView::slotRubberBandActivationChanged(bool active) curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(1.0, 1.0), QPointF(1.0, 1.0)); animation->setEasingCurve(curve); - connect(animation, &QVariantAnimation::valueChanged, this, [=](const QVariant&) { + connect(animation, &QVariantAnimation::valueChanged, this, [=, this](const QVariant &) { update(); }); - connect(animation, &QVariantAnimation::finished, this, [=]() { + connect(animation, &QVariantAnimation::finished, this, [=, this]() { m_rubberBandAnimations.removeAll(animation); delete animation; }); @@ -1503,9 +1659,7 @@ void KItemListView::slotRubberBandActivationChanged(bool active) update(); } -void KItemListView::slotHeaderColumnWidthChanged(const QByteArray& role, - qreal currentWidth, - qreal previousWidth) +void KItemListView::slotHeaderColumnWidthChanged(const QByteArray &role, qreal currentWidth, qreal previousWidth) { Q_UNUSED(role) Q_UNUSED(currentWidth) @@ -1516,9 +1670,17 @@ void KItemListView::slotHeaderColumnWidthChanged(const QByteArray& role, doLayout(NoAnimation); } -void KItemListView::slotHeaderColumnMoved(const QByteArray& role, - int currentIndex, - int previousIndex) +void KItemListView::slotSidePaddingChanged(qreal width) +{ + Q_UNUSED(width) + if (m_headerWidget->automaticColumnResizing()) { + applyAutomaticColumnWidths(); + } + applyColumnWidthsFromHeader(); + doLayout(NoAnimation); +} + +void KItemListView::slotHeaderColumnMoved(const QByteArray &role, int currentIndex, int previousIndex) { Q_ASSERT(m_visibleRoles[previousIndex] == role); @@ -1568,9 +1730,8 @@ void KItemListView::triggerAutoScrolling() // an autoscrolling. const qreal minDiff = 4; // Ignore any autoscrolling if the rubberband is very small - const qreal diff = (scrollOrientation() == Qt::Vertical) - ? m_rubberBand->endPosition().y() - m_rubberBand->startPosition().y() - : m_rubberBand->endPosition().x() - m_rubberBand->startPosition().x(); + const qreal diff = (scrollOrientation() == Qt::Vertical) ? m_rubberBand->endPosition().y() - m_rubberBand->startPosition().y() + : m_rubberBand->endPosition().x() - m_rubberBand->startPosition().x(); if (qAbs(diff) < minDiff || (m_autoScrollIncrement < 0 && diff > 0) || (m_autoScrollIncrement > 0 && diff < 0)) { // The rubberband direction is different from the scroll direction (e.g. the rubberband has // been moved up although the autoscroll direction might be down) @@ -1594,14 +1755,14 @@ void KItemListView::triggerAutoScrolling() void KItemListView::slotGeometryOfGroupHeaderParentChanged() { - KItemListWidget* widget = qobject_cast(sender()); + KItemListWidget *widget = qobject_cast(sender()); Q_ASSERT(widget); - KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget); + KItemListGroupHeader *groupHeader = m_visibleGroups.value(widget); Q_ASSERT(groupHeader); updateGroupHeaderLayout(widget); } -void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value) +void KItemListView::slotRoleEditingCanceled(int index, const QByteArray &role, const QVariant &value) { disconnectRoleEditingSignals(index); @@ -1609,7 +1770,7 @@ void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, c Q_EMIT roleEditingCanceled(index, role, value); } -void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value) +void KItemListView::slotRoleEditingFinished(int index, const QByteArray &role, const QVariant &value) { disconnectRoleEditingSignals(index); @@ -1617,12 +1778,12 @@ void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, c Q_EMIT roleEditingFinished(index, role, value); } -void KItemListView::setController(KItemListController* controller) +void KItemListView::setController(KItemListController *controller) { if (m_controller != controller) { - KItemListController* previous = m_controller; + KItemListController *previous = m_controller; if (previous) { - KItemListSelectionManager* selectionManager = previous->selectionManager(); + KItemListSelectionManager *selectionManager = previous->selectionManager(); disconnect(selectionManager, &KItemListSelectionManager::currentChanged, this, &KItemListView::slotCurrentChanged); disconnect(selectionManager, &KItemListSelectionManager::selectionChanged, this, &KItemListView::slotSelectionChanged); } @@ -1630,7 +1791,7 @@ void KItemListView::setController(KItemListController* controller) m_controller = controller; if (controller) { - KItemListSelectionManager* selectionManager = controller->selectionManager(); + KItemListSelectionManager *selectionManager = controller->selectionManager(); connect(selectionManager, &KItemListSelectionManager::currentChanged, this, &KItemListView::slotCurrentChanged); connect(selectionManager, &KItemListSelectionManager::selectionChanged, this, &KItemListView::slotSelectionChanged); } @@ -1639,31 +1800,25 @@ void KItemListView::setController(KItemListController* controller) } } -void KItemListView::setModel(KItemModelBase* model) +void KItemListView::setModel(KItemModelBase *model) { if (m_model == model) { return; } - KItemModelBase* previous = m_model; + KItemModelBase *previous = m_model; if (m_model) { - disconnect(m_model, &KItemModelBase::itemsChanged, - this, &KItemListView::slotItemsChanged); - disconnect(m_model, &KItemModelBase::itemsInserted, - this, &KItemListView::slotItemsInserted); - disconnect(m_model, &KItemModelBase::itemsRemoved, - this, &KItemListView::slotItemsRemoved); - disconnect(m_model, &KItemModelBase::itemsMoved, - this, &KItemListView::slotItemsMoved); - disconnect(m_model, &KItemModelBase::groupsChanged, - this, &KItemListView::slotGroupsChanged); - disconnect(m_model, &KItemModelBase::groupedSortingChanged, - this, &KItemListView::slotGroupedSortingChanged); - disconnect(m_model, &KItemModelBase::sortOrderChanged, - this, &KItemListView::slotSortOrderChanged); - disconnect(m_model, &KItemModelBase::sortRoleChanged, - this, &KItemListView::slotSortRoleChanged); + disconnect(m_model, &KItemModelBase::itemsChanged, this, &KItemListView::slotItemsChanged); + disconnect(m_model, &KItemModelBase::itemsInserted, this, &KItemListView::slotItemsInserted); + disconnect(m_model, &KItemModelBase::itemsRemoved, this, &KItemListView::slotItemsRemoved); + disconnect(m_model, &KItemModelBase::itemsMoved, this, &KItemListView::slotItemsMoved); + disconnect(m_model, &KItemModelBase::groupsChanged, this, &KItemListView::slotGroupsChanged); + disconnect(m_model, &KItemModelBase::groupedSortingChanged, this, &KItemListView::slotGroupedSortingChanged); + disconnect(m_model, &KItemModelBase::sortOrderChanged, this, &KItemListView::slotSortOrderChanged); + disconnect(m_model, &KItemModelBase::sortRoleChanged, this, &KItemListView::slotSortRoleChanged); + disconnect(m_model, &KItemModelBase::groupOrderChanged, this, &KItemListView::slotGroupOrderChanged); + disconnect(m_model, &KItemModelBase::groupRoleChanged, this, &KItemListView::slotGroupRoleChanged); m_sizeHintResolver->itemsRemoved(KItemRangeList() << KItemRange(0, m_model->count())); } @@ -1673,22 +1828,14 @@ void KItemListView::setModel(KItemModelBase* model) m_grouped = model->groupedSorting(); if (m_model) { - connect(m_model, &KItemModelBase::itemsChanged, - this, &KItemListView::slotItemsChanged); - connect(m_model, &KItemModelBase::itemsInserted, - this, &KItemListView::slotItemsInserted); - connect(m_model, &KItemModelBase::itemsRemoved, - this, &KItemListView::slotItemsRemoved); - connect(m_model, &KItemModelBase::itemsMoved, - this, &KItemListView::slotItemsMoved); - connect(m_model, &KItemModelBase::groupsChanged, - this, &KItemListView::slotGroupsChanged); - connect(m_model, &KItemModelBase::groupedSortingChanged, - this, &KItemListView::slotGroupedSortingChanged); - connect(m_model, &KItemModelBase::sortOrderChanged, - this, &KItemListView::slotSortOrderChanged); - connect(m_model, &KItemModelBase::sortRoleChanged, - this, &KItemListView::slotSortRoleChanged); + connect(m_model, &KItemModelBase::itemsChanged, this, &KItemListView::slotItemsChanged); + connect(m_model, &KItemModelBase::itemsInserted, this, &KItemListView::slotItemsInserted); + connect(m_model, &KItemModelBase::itemsRemoved, this, &KItemListView::slotItemsRemoved); + connect(m_model, &KItemModelBase::itemsMoved, this, &KItemListView::slotItemsMoved); + connect(m_model, &KItemModelBase::groupsChanged, this, &KItemListView::slotGroupsChanged); + connect(m_model, &KItemModelBase::groupedSortingChanged, this, &KItemListView::slotGroupedSortingChanged); + connect(m_model, &KItemModelBase::sortOrderChanged, this, &KItemListView::slotSortOrderChanged); + connect(m_model, &KItemModelBase::sortRoleChanged, this, &KItemListView::slotSortRoleChanged); const int itemCount = m_model->count(); if (itemCount > 0) { @@ -1699,17 +1846,13 @@ void KItemListView::setModel(KItemModelBase* model) onModelChanged(model, previous); } -KItemListRubberBand* KItemListView::rubberBand() const +KItemListRubberBand *KItemListView::rubberBand() const { return m_rubberBand; } void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int changedCount) { - if (m_layoutTimer->isActive()) { - m_layoutTimer->stop(); - } - if (m_activeTransactions > 0) { if (hint == NoAnimation) { // As soon as at least one property change should be done without animation, @@ -1756,7 +1899,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const QRectF itemBounds = m_layouter->itemRect(i); const QPointF newPos = itemBounds.topLeft(); - KItemListWidget* widget = m_visibleItems.value(i); + KItemListWidget *widget = m_visibleItems.value(i); if (!widget) { if (!reusableItems.isEmpty()) { // Reuse a KItemListWidget instance from an invisible item @@ -1780,8 +1923,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const int previousIndex = i - changedCount; const QRectF itemRect = m_layouter->itemRect(previousIndex); if (itemRect.isEmpty()) { - const QPointF invisibleOldPos = (scrollOrientation() == Qt::Vertical) - ? QPointF(0, size().height()) : QPointF(size().width(), 0); + const QPointF invisibleOldPos = (scrollOrientation() == Qt::Vertical) ? QPointF(0, size().height()) : QPointF(size().width(), 0); widget->setPos(invisibleOldPos); } else { widget->setPos(itemRect.topLeft()); @@ -1800,7 +1942,10 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha if (animate) { if (m_animation->isStarted(widget, KItemListViewAnimation::MovingAnimation)) { - m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); + if (m_editingRole) { + Q_EMIT widget->roleEditingCanceled(widget->index(), QByteArray(), QVariant()); + } + m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); applyNewPos = false; } @@ -1836,6 +1981,8 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha Q_ASSERT(widget->index() == i); widget->setVisible(true); + bool animateIconResizing = animate; + if (widget->size() != itemBounds.size()) { // Resize the widget for the item to the changed size. if (animate) { @@ -1852,6 +1999,17 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha } else { widget->resize(itemBounds.size()); } + } else { + animateIconResizing = false; + } + + const int newIconSize = widget->styleOption().iconSize; + if (widget->iconSize() != newIconSize) { + if (animateIconResizing) { + m_animation->start(widget, KItemListViewAnimation::IconResizeAnimation, newIconSize); + } else { + widget->setIconSize(newIconSize); + } } // Updating the cell-information must be done as last step: The decision whether the @@ -1861,7 +2019,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha } // Delete invisible KItemListWidget instances that have not been reused - for (int index : qAsConst(reusableItems)) { + for (int index : std::as_const(reusableItems)) { recycleWidget(m_visibleItems.value(index)); } @@ -1872,7 +2030,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha if (m_grouped) { // Update the layout of all visible group headers - QHashIterator it(m_visibleGroups); + QHashIterator it(m_visibleGroups); while (it.hasNext()) { it.next(); updateGroupHeaderLayout(it.key()); @@ -1882,9 +2040,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha emitOffsetChanges(); } -QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, - int lastVisibleIndex, - LayoutAnimationHint hint) +QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, int lastVisibleIndex, LayoutAnimationHint hint) { // Determine all items that are completely invisible and might be // reused for items that just got (at least partly) visible. If the @@ -1894,11 +2050,11 @@ QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, QList items; - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); - KItemListWidget* widget = it.value(); + KItemListWidget *widget = it.value(); const int index = widget->index(); const bool invisible = (index < firstVisibleIndex) || (index > lastVisibleIndex); @@ -1923,7 +2079,7 @@ QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, return items; } -bool KItemListView::moveWidget(KItemListWidget* widget,const QPointF& newPos) +bool KItemListView::moveWidget(KItemListWidget *widget, const QPointF &newPos) { if (widget->pos() == newPos) { return false; @@ -1987,9 +2143,9 @@ void KItemListView::emitOffsetChanges() } } -KItemListWidget* KItemListView::createWidget(int index) +KItemListWidget *KItemListView::createWidget(int index) { - KItemListWidget* widget = widgetCreator()->create(this); + KItemListWidget *widget = widgetCreator()->create(this); widget->setFlag(QGraphicsItem::ItemStacksBehindParent); m_visibleItems.insert(index, widget); @@ -1999,7 +2155,7 @@ KItemListWidget* KItemListView::createWidget(int index) return widget; } -void KItemListView::recycleWidget(KItemListWidget* widget) +void KItemListView::recycleWidget(KItemListWidget *widget) { if (m_grouped) { recycleGroupHeaderForWidget(widget); @@ -2012,7 +2168,7 @@ void KItemListView::recycleWidget(KItemListWidget* widget) widgetCreator()->recycle(widget); } -void KItemListView::setWidgetIndex(KItemListWidget* widget, int index) +void KItemListView::setWidgetIndex(KItemListWidget *widget, int index) { const int oldIndex = widget->index(); m_visibleItems.remove(oldIndex); @@ -2024,7 +2180,7 @@ void KItemListView::setWidgetIndex(KItemListWidget* widget, int index) widget->setIndex(index); } -void KItemListView::moveWidgetToIndex(KItemListWidget* widget, int index) +void KItemListView::moveWidgetToIndex(KItemListWidget *widget, int index) { const int oldIndex = widget->index(); const Cell oldCell = m_visibleCells.value(oldIndex); @@ -2033,29 +2189,33 @@ void KItemListView::moveWidgetToIndex(KItemListWidget* widget, int index) const Cell newCell(m_layouter->itemColumn(index), m_layouter->itemRow(index)); const bool vertical = (scrollOrientation() == Qt::Vertical); - const bool updateCell = (vertical && oldCell.row == newCell.row) || - (!vertical && oldCell.column == newCell.column); + const bool updateCell = (vertical && oldCell.row == newCell.row) || (!vertical && oldCell.column == newCell.column); if (updateCell) { m_visibleCells.insert(index, newCell); } } -void KItemListView::setLayouterSize(const QSizeF& size, SizeType sizeType) +void KItemListView::setLayouterSize(const QSizeF &size, SizeType sizeType) { switch (sizeType) { - case LayouterSize: m_layouter->setSize(size); break; - case ItemSize: m_layouter->setItemSize(size); break; - default: break; + case LayouterSize: + m_layouter->setSize(size); + break; + case ItemSize: + m_layouter->setItemSize(size); + break; + default: + break; } } -void KItemListView::updateWidgetProperties(KItemListWidget* widget, int index) +void KItemListView::updateWidgetProperties(KItemListWidget *widget, int index) { widget->setVisibleRoles(m_visibleRoles); updateWidgetColumnWidths(widget); widget->setStyleOption(m_styleOption); - const KItemListSelectionManager* selectionManager = m_controller->selectionManager(); + const KItemListSelectionManager *selectionManager = m_controller->selectionManager(); // In SingleSelection mode (e.g., in the Places Panel), the current item is // always the selected item. It is not necessary to highlight the current item then. @@ -2075,7 +2235,7 @@ void KItemListView::updateWidgetProperties(KItemListWidget* widget, int index) } } -void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget) +void KItemListView::updateGroupHeaderForWidget(KItemListWidget *widget) { Q_ASSERT(m_grouped); @@ -2087,12 +2247,12 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget) return; } - const QList > groups = model()->groups(); + const QList> groups = model()->groups(); if (groups.isEmpty() || !groupHeaderCreator()) { return; } - KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget); + KItemListGroupHeader *groupHeader = m_visibleGroups.value(widget); if (!groupHeader) { groupHeader = groupHeaderCreator()->create(this); groupHeader->setParentItem(widget); @@ -2104,7 +2264,7 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget) const int groupIndex = groupIndexForItem(index); Q_ASSERT(groupIndex >= 0); groupHeader->setData(groups.at(groupIndex).second); - groupHeader->setRole(model()->sortRole()); + groupHeader->setRole(model()->groupRole()); groupHeader->setStyleOption(m_styleOption); groupHeader->setScrollOrientation(scrollOrientation()); groupHeader->setItemIndex(index); @@ -2112,9 +2272,9 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget) groupHeader->show(); } -void KItemListView::updateGroupHeaderLayout(KItemListWidget* widget) +void KItemListView::updateGroupHeaderLayout(KItemListWidget *widget) { - KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget); + KItemListGroupHeader *groupHeader = m_visibleGroups.value(widget); Q_ASSERT(groupHeader); const int index = widget->index(); @@ -2137,9 +2297,9 @@ void KItemListView::updateGroupHeaderLayout(KItemListWidget* widget) } } -void KItemListView::recycleGroupHeaderForWidget(KItemListWidget* widget) +void KItemListView::recycleGroupHeaderForWidget(KItemListWidget *widget) { - KItemListGroupHeader* header = m_visibleGroups.value(widget); + KItemListGroupHeader *header = m_visibleGroups.value(widget); if (header) { header->setParentItem(nullptr); groupHeaderCreator()->recycle(header); @@ -2153,7 +2313,7 @@ void KItemListView::updateVisibleGroupHeaders() Q_ASSERT(m_grouped); m_layouter->markAsDirty(); - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); updateGroupHeaderForWidget(it.value()); @@ -2164,7 +2324,7 @@ int KItemListView::groupIndexForItem(int index) const { Q_ASSERT(m_grouped); - const QList > groups = model()->groups(); + const QList> groups = model()->groups(); if (groups.isEmpty()) { return -1; } @@ -2192,14 +2352,14 @@ int KItemListView::groupIndexForItem(int index) const void KItemListView::updateAlternateBackgrounds() { - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); updateAlternateBackgroundForWidget(it.value()); } } -void KItemListView::updateAlternateBackgroundForWidget(KItemListWidget* widget) +void KItemListView::updateAlternateBackgroundForWidget(KItemListWidget *widget) { bool enabled = useAlternateBackgrounds(); if (enabled) { @@ -2208,7 +2368,7 @@ void KItemListView::updateAlternateBackgroundForWidget(KItemListWidget* widget) if (m_grouped) { const int groupIndex = groupIndexForItem(index); if (groupIndex >= 0) { - const QList > groups = model()->groups(); + const QList> groups = model()->groups(); const int indexOfFirstGroupItem = groups[groupIndex].first; const int relativeIndex = index - indexOfFirstGroupItem; enabled = (relativeIndex & 0x1) > 0; @@ -2220,10 +2380,10 @@ void KItemListView::updateAlternateBackgroundForWidget(KItemListWidget* widget) bool KItemListView::useAlternateBackgrounds() const { - return m_itemSize.isEmpty() && m_visibleRoles.count() > 1; + return m_alternateBackgrounds && m_itemSize.isEmpty(); } -QHash KItemListView::preferredColumnWidths(const KItemRangeList& itemRanges) const +QHash KItemListView::preferredColumnWidths(const KItemRangeList &itemRanges) const { QElapsedTimer timer; timer.start(); @@ -2233,25 +2393,25 @@ QHash KItemListView::preferredColumnWidths(const KItemRangeLi // Calculate the minimum width for each column that is required // to show the headline unclipped. const QFontMetricsF fontMetrics(m_headerWidget->font()); - const int gripMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderGripMargin); + const int gripMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderGripMargin); const int headerMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderMargin); - for (const QByteArray& visibleRole : qAsConst(m_visibleRoles)) { + for (const QByteArray &visibleRole : std::as_const(m_visibleRoles)) { const QString headerText = m_model->roleDescription(visibleRole); const qreal headerWidth = fontMetrics.horizontalAdvance(headerText) + gripMargin + headerMargin * 2; widths.insert(visibleRole, headerWidth); } - // Calculate the preferred column withs for each item and ignore values + // Calculate the preferred column widths for each item and ignore values // smaller than the width for showing the headline unclipped. - const KItemListWidgetCreatorBase* creator = widgetCreator(); + const KItemListWidgetCreatorBase *creator = widgetCreator(); int calculatedItemCount = 0; bool maxTimeExceeded = false; - for (const KItemRange& itemRange : itemRanges) { + for (const KItemRange &itemRange : itemRanges) { const int startIndex = itemRange.index; const int endIndex = startIndex + itemRange.count - 1; for (int i = startIndex; i <= endIndex; ++i) { - for (const QByteArray& visibleRole : qAsConst(m_visibleRoles)) { + for (const QByteArray &visibleRole : std::as_const(m_visibleRoles)) { qreal maxWidth = widths.value(visibleRole, 0); const qreal width = creator->preferredRoleColumnWidth(visibleRole, i, this); maxWidth = qMax(width, maxWidth); @@ -2278,38 +2438,38 @@ QHash KItemListView::preferredColumnWidths(const KItemRangeLi void KItemListView::applyColumnWidthsFromHeader() { // Apply the new size to the layouter - const qreal requiredWidth = columnWidthsSum(); - const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth), - m_itemSize.height()); + const qreal requiredWidth = m_headerWidget->leftPadding() + columnWidthsSum() + m_headerWidget->rightPadding(); + const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth), m_itemSize.height()); m_layouter->setItemSize(dynamicItemSize); // Update the role sizes for all visible widgets - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); updateWidgetColumnWidths(it.value()); } } -void KItemListView::updateWidgetColumnWidths(KItemListWidget* widget) +void KItemListView::updateWidgetColumnWidths(KItemListWidget *widget) { - for (const QByteArray& role : qAsConst(m_visibleRoles)) { + for (const QByteArray &role : std::as_const(m_visibleRoles)) { widget->setColumnWidth(role, m_headerWidget->columnWidth(role)); } + widget->setSidePadding(m_headerWidget->leftPadding(), m_headerWidget->rightPadding()); } -void KItemListView::updatePreferredColumnWidths(const KItemRangeList& itemRanges) +void KItemListView::updatePreferredColumnWidths(const KItemRangeList &itemRanges) { Q_ASSERT(m_itemSize.isEmpty()); const int itemCount = m_model->count(); int rangesItemCount = 0; - for (const KItemRange& range : itemRanges) { + for (const KItemRange &range : itemRanges) { rangesItemCount += range.count; } if (itemCount == rangesItemCount) { const QHash preferredWidths = preferredColumnWidths(itemRanges); - for (const QByteArray& role : qAsConst(m_visibleRoles)) { + for (const QByteArray &role : std::as_const(m_visibleRoles)) { m_headerWidget->setPreferredColumnWidth(role, preferredWidths.value(role)); } } else { @@ -2323,7 +2483,7 @@ void KItemListView::updatePreferredColumnWidths(const KItemRangeList& itemRanges QHashIterator it(updatedWidths); while (it.hasNext()) { it.next(); - const QByteArray& role = it.key(); + const QByteArray &role = it.key(); const qreal updatedWidth = it.value(); const qreal currentWidth = m_headerWidget->preferredColumnWidth(role); if (updatedWidth > currentWidth) { @@ -2364,7 +2524,7 @@ void KItemListView::applyAutomaticColumnWidths() // size does not use the available view-size the size of the // first role will get stretched. - for (const QByteArray& role : qAsConst(m_visibleRoles)) { + for (const QByteArray &role : std::as_const(m_visibleRoles)) { const qreal preferredWidth = m_headerWidget->preferredColumnWidth(role); m_headerWidget->setColumnWidth(role, preferredWidth); } @@ -2373,7 +2533,9 @@ void KItemListView::applyAutomaticColumnWidths() qreal firstColumnWidth = m_headerWidget->columnWidth(firstRole); QSizeF dynamicItemSize = m_itemSize; - qreal requiredWidth = columnWidthsSum(); + qreal requiredWidth = m_headerWidget->leftPadding() + columnWidthsSum() + m_headerWidget->rightPadding(); + // By default we want the same padding symmetrically on both sides of the view. This improves UX, looks better and increases the chances of users figuring + // out that the padding area can be used for deselecting and dropping files. const qreal availableWidth = size().width(); if (requiredWidth < availableWidth) { // Stretch the first column to use the whole remaining width @@ -2401,7 +2563,7 @@ void KItemListView::applyAutomaticColumnWidths() m_layouter->setItemSize(dynamicItemSize); // Update the role sizes for all visible widgets - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); updateWidgetColumnWidths(it.value()); @@ -2411,7 +2573,7 @@ void KItemListView::applyAutomaticColumnWidths() qreal KItemListView::columnWidthsSum() const { qreal widthsSum = 0; - for (const QByteArray& role : qAsConst(m_visibleRoles)) { + for (const QByteArray &role : std::as_const(m_visibleRoles)) { widthsSum += m_headerWidget->columnWidth(role); } return widthsSum; @@ -2422,9 +2584,7 @@ QRectF KItemListView::headerBoundaries() const return m_headerWidget->isVisible() ? m_headerWidget->geometry() : QRectF(); } -bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize, - const QSizeF& newItemSize, - const QSizeF& newItemMargin) const +bool KItemListView::changesItemGridLayout(const QSizeF &newGridSize, const QSizeF &newItemSize, const QSizeF &newItemMargin) const { if (newItemSize.isEmpty() || newGridSize.isEmpty()) { return false; @@ -2433,26 +2593,18 @@ bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize, if (m_layouter->scrollOrientation() == Qt::Vertical) { const qreal itemWidth = m_layouter->itemSize().width(); if (itemWidth > 0) { - const int newColumnCount = itemsPerSize(newGridSize.width(), - newItemSize.width(), - newItemMargin.width()); + const int newColumnCount = itemsPerSize(newGridSize.width(), newItemSize.width(), newItemMargin.width()); if (m_model->count() > newColumnCount) { - const int oldColumnCount = itemsPerSize(m_layouter->size().width(), - itemWidth, - m_layouter->itemMargin().width()); + const int oldColumnCount = itemsPerSize(m_layouter->size().width(), itemWidth, m_layouter->itemMargin().width()); return oldColumnCount != newColumnCount; } } } else { const qreal itemHeight = m_layouter->itemSize().height(); if (itemHeight > 0) { - const int newRowCount = itemsPerSize(newGridSize.height(), - newItemSize.height(), - newItemMargin.height()); + const int newRowCount = itemsPerSize(newGridSize.height(), newItemSize.height(), newItemMargin.height()); if (m_model->count() > newRowCount) { - const int oldRowCount = itemsPerSize(m_layouter->size().height(), - itemHeight, - m_layouter->itemMargin().height()); + const int oldRowCount = itemsPerSize(m_layouter->size().height(), itemHeight, m_layouter->itemMargin().height()); return oldRowCount != newRowCount; } } @@ -2473,15 +2625,13 @@ bool KItemListView::animateChangedItemCount(int changedItemCount) const return false; } - const int maximum = (scrollOrientation() == Qt::Vertical) - ? m_layouter->size().width() / m_layouter->itemSize().width() - : m_layouter->size().height() / m_layouter->itemSize().height(); + const int maximum = (scrollOrientation() == Qt::Vertical) ? m_layouter->size().width() / m_layouter->itemSize().width() + : m_layouter->size().height() / m_layouter->itemSize().height(); // Only animate if up to 2/3 of a row or column are inserted or removed return changedItemCount <= maximum * 2 / 3; } - -bool KItemListView::scrollBarRequired(const QSizeF& size) const +bool KItemListView::scrollBarRequired(const QSizeF &size) const { const QSizeF oldSize = m_layouter->size(); @@ -2489,16 +2639,15 @@ bool KItemListView::scrollBarRequired(const QSizeF& size) const const qreal maxOffset = m_layouter->maximumScrollOffset(); m_layouter->setSize(oldSize); - return m_layouter->scrollOrientation() == Qt::Vertical ? maxOffset > size.height() - : maxOffset > size.width(); + return m_layouter->scrollOrientation() == Qt::Vertical ? maxOffset > size.height() : maxOffset > size.width(); } -int KItemListView::showDropIndicator(const QPointF& pos) +int KItemListView::showDropIndicator(const QPointF &pos) { - QHashIterator it(m_visibleItems); + QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); - const KItemListWidget* widget = it.value(); + const KItemListWidget *widget = it.value(); const QPointF mappedPos = widget->mapFromItem(this, pos); const QRectF rect = itemRect(widget->index()); @@ -2511,7 +2660,7 @@ int KItemListView::showDropIndicator(const QPointF& pos) } } - const bool isAboveItem = (mappedPos.y () < rect.height() / 2); + const bool isAboveItem = (mappedPos.y() < rect.height() / 2); const qreal y = isAboveItem ? rect.top() : rect.bottom(); const QRectF draggingInsertIndicator(rect.left(), y, rect.width(), 1); @@ -2551,7 +2700,7 @@ void KItemListView::updateGroupHeaderHeight() // from m_styleOption. groupHeaderHeight += 2 * m_styleOption.horizontalMargin; groupHeaderMargin = m_styleOption.horizontalMargin; - } else if (m_itemSize.isEmpty()){ + } else if (m_itemSize.isEmpty()) { groupHeaderHeight += 4 * m_styleOption.padding; groupHeaderMargin = m_styleOption.iconSize / 2; } else { @@ -2572,10 +2721,9 @@ void KItemListView::updateSiblingsInformation(int firstIndex, int lastIndex) if (firstIndex < 0 || lastIndex < 0) { firstIndex = m_layouter->firstVisibleIndex(); - lastIndex = m_layouter->lastVisibleIndex(); + lastIndex = m_layouter->lastVisibleIndex(); } else { - const bool isRangeVisible = (firstIndex <= m_layouter->lastVisibleIndex() && - lastIndex >= m_layouter->firstVisibleIndex()); + const bool isRangeVisible = (firstIndex <= m_layouter->lastVisibleIndex() && lastIndex >= m_layouter->firstVisibleIndex()); if (!isRangeVisible) { return; } @@ -2591,7 +2739,7 @@ void KItemListView::updateSiblingsInformation(int firstIndex, int lastIndex) // contain a siblings information which can be used as base. int rootIndex = firstIndex; - KItemListWidget* widget = m_visibleItems.value(firstIndex - 1); + KItemListWidget *widget = m_visibleItems.value(firstIndex - 1); if (!widget) { // There is no visible widget before the range, check whether there // is one after the range: @@ -2644,7 +2792,7 @@ void KItemListView::updateSiblingsInformation(int firstIndex, int lastIndex) if (i >= firstIndex) { // The index represents a visible item. Apply the parent-siblings // and update the sibling of the current item. - KItemListWidget* widget = m_visibleItems.value(i); + KItemListWidget *widget = m_visibleItems.value(i); if (!widget) { continue; } @@ -2693,7 +2841,7 @@ bool KItemListView::hasSiblingSuccessor(int index) const void KItemListView::disconnectRoleEditingSignals(int index) { - KStandardItemListWidget* widget = qobject_cast(m_visibleItems.value(index)); + KStandardItemListWidget *widget = qobject_cast(m_visibleItems.value(index)); if (!widget) { return; } @@ -2736,20 +2884,18 @@ int KItemListView::itemsPerSize(qreal size, qreal itemSize, qreal itemMargin) return count; } - - KItemListCreatorBase::~KItemListCreatorBase() { qDeleteAll(m_recycleableWidgets); qDeleteAll(m_createdWidgets); } -void KItemListCreatorBase::addCreatedWidget(QGraphicsWidget* widget) +void KItemListCreatorBase::addCreatedWidget(QGraphicsWidget *widget) { m_createdWidgets.insert(widget); } -void KItemListCreatorBase::pushRecycleableWidget(QGraphicsWidget* widget) +void KItemListCreatorBase::pushRecycleableWidget(QGraphicsWidget *widget) { Q_ASSERT(m_createdWidgets.contains(widget)); m_createdWidgets.remove(widget); @@ -2762,13 +2908,13 @@ void KItemListCreatorBase::pushRecycleableWidget(QGraphicsWidget* widget) } } -QGraphicsWidget* KItemListCreatorBase::popRecycleableWidget() +QGraphicsWidget *KItemListCreatorBase::popRecycleableWidget() { if (m_recycleableWidgets.isEmpty()) { return nullptr; } - QGraphicsWidget* widget = m_recycleableWidgets.takeLast(); + QGraphicsWidget *widget = m_recycleableWidgets.takeLast(); m_createdWidgets.insert(widget); return widget; } @@ -2777,7 +2923,7 @@ KItemListWidgetCreatorBase::~KItemListWidgetCreatorBase() { } -void KItemListWidgetCreatorBase::recycle(KItemListWidget* widget) +void KItemListWidgetCreatorBase::recycle(KItemListWidget *widget) { widget->setParentItem(nullptr); widget->setOpacity(1.0); @@ -2788,9 +2934,10 @@ KItemListGroupHeaderCreatorBase::~KItemListGroupHeaderCreatorBase() { } -void KItemListGroupHeaderCreatorBase::recycle(KItemListGroupHeader* header) +void KItemListGroupHeaderCreatorBase::recycle(KItemListGroupHeader *header) { header->setOpacity(1.0); pushRecycleableWidget(header); } +#include "moc_kitemlistview.cpp"