X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/82ea33762ffcc75cece3269fedb5380afc86b05d..fc9e06426746b5b33d31db68904d4d205537a080:/src/kitemviews/private/kitemlistviewlayouter.cpp diff --git a/src/kitemviews/private/kitemlistviewlayouter.cpp b/src/kitemviews/private/kitemlistviewlayouter.cpp index da569b3dc..3ed2343a8 100644 --- a/src/kitemviews/private/kitemlistviewlayouter.cpp +++ b/src/kitemviews/private/kitemlistviewlayouter.cpp @@ -1,56 +1,48 @@ -/*************************************************************************** - * Copyright (C) 2011 by Peter Penz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2011 Peter Penz + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "kitemlistviewlayouter.h" - -#include +#include "dolphindebug.h" #include "kitemlistsizehintresolver.h" +#include "kitemviews/kitemmodelbase.h" -#include +#include +#include // #define KITEMLISTVIEWLAYOUTER_DEBUG -KItemListViewLayouter::KItemListViewLayouter(QObject* parent) : - QObject(parent), - m_dirty(true), - m_visibleIndexesDirty(true), - m_scrollOrientation(Qt::Vertical), - m_size(), - m_itemSize(128, 128), - m_itemMargin(), - m_headerHeight(0), - m_model(0), - m_sizeHintResolver(0), - m_scrollOffset(0), - m_maximumScrollOffset(0), - m_itemOffset(0), - m_maximumItemOffset(0), - m_firstVisibleIndex(-1), - m_lastVisibleIndex(-1), - m_columnWidth(0), - m_xPosInc(0), - m_columnCount(0), - m_groupItemIndexes(), - m_groupHeaderHeight(0), - m_groupHeaderMargin(0), - m_itemInfos() -{ +KItemListViewLayouter::KItemListViewLayouter(KItemListSizeHintResolver *sizeHintResolver, QObject *parent) + : QObject(parent) + , m_dirty(true) + , m_visibleIndexesDirty(true) + , m_scrollOrientation(Qt::Vertical) + , m_size() + , m_itemSize(128, 128) + , m_itemMargin() + , m_headerHeight(0) + , m_model(nullptr) + , m_sizeHintResolver(sizeHintResolver) + , m_scrollOffset(0) + , m_maximumScrollOffset(0) + , m_itemOffset(0) + , m_maximumItemOffset(0) + , m_firstVisibleIndex(-1) + , m_lastVisibleIndex(-1) + , m_columnWidth(0) + , m_xPosInc(0) + , m_columnCount(0) + , m_rowOffsets() + , m_columnOffsets() + , m_groupItemIndexes() + , m_groupHeaderHeight(0) + , m_groupHeaderMargin(0) + , m_itemInfos() + , m_statusBarOffset(0) +{ + Q_ASSERT(m_sizeHintResolver); } KItemListViewLayouter::~KItemListViewLayouter() @@ -70,7 +62,7 @@ Qt::Orientation KItemListViewLayouter::scrollOrientation() const return m_scrollOrientation; } -void KItemListViewLayouter::setSize(const QSizeF& size) +void KItemListViewLayouter::setSize(const QSizeF &size) { if (m_size != size) { if (m_scrollOrientation == Qt::Vertical) { @@ -91,7 +83,7 @@ QSizeF KItemListViewLayouter::size() const return m_size; } -void KItemListViewLayouter::setItemSize(const QSizeF& size) +void KItemListViewLayouter::setItemSize(const QSizeF &size) { if (m_itemSize != size) { m_itemSize = size; @@ -104,7 +96,7 @@ QSizeF KItemListViewLayouter::itemSize() const return m_itemSize; } -void KItemListViewLayouter::setItemMargin(const QSizeF& margin) +void KItemListViewLayouter::setItemMargin(const QSizeF &margin) { if (m_itemMargin != margin) { m_itemMargin = margin; @@ -171,7 +163,7 @@ qreal KItemListViewLayouter::scrollOffset() const qreal KItemListViewLayouter::maximumScrollOffset() const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); return m_maximumScrollOffset; } @@ -190,11 +182,11 @@ qreal KItemListViewLayouter::itemOffset() const qreal KItemListViewLayouter::maximumItemOffset() const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); return m_maximumItemOffset; } -void KItemListViewLayouter::setModel(const KItemModelBase* model) +void KItemListViewLayouter::setModel(const KItemModelBase *model) { if (m_model != model) { m_model = model; @@ -202,62 +194,60 @@ void KItemListViewLayouter::setModel(const KItemModelBase* model) } } -const KItemModelBase* KItemListViewLayouter::model() const +const KItemModelBase *KItemListViewLayouter::model() const { return m_model; } -void KItemListViewLayouter::setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver) -{ - if (m_sizeHintResolver != sizeHintResolver) { - m_sizeHintResolver = sizeHintResolver; - m_dirty = true; - } -} - -const KItemListSizeHintResolver* KItemListViewLayouter::sizeHintResolver() const -{ - return m_sizeHintResolver; -} - int KItemListViewLayouter::firstVisibleIndex() const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); return m_firstVisibleIndex; } int KItemListViewLayouter::lastVisibleIndex() const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); return m_lastVisibleIndex; } QRectF KItemListViewLayouter::itemRect(int index) const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); if (index < 0 || index >= m_itemInfos.count()) { return QRectF(); } + QSizeF sizeHint = m_sizeHintResolver->sizeHint(index); + + const qreal x = m_columnOffsets.at(m_itemInfos.at(index).column); + const qreal y = m_rowOffsets.at(m_itemInfos.at(index).row); + if (m_scrollOrientation == Qt::Horizontal) { // Rotate the logical direction which is always vertical by 90° // to get the physical horizontal direction - const QRectF& b = m_itemInfos[index].rect; - QRectF bounds(b.y(), b.x(), b.height(), b.width()); - QPointF pos = bounds.topLeft(); - pos.rx() -= m_scrollOffset; - bounds.moveTo(pos); - return bounds; + QPointF pos(y, x); + sizeHint.transpose(); + if (QGuiApplication::isRightToLeft()) { + pos.rx() = m_size.width() - 1 + m_scrollOffset - pos.x() - sizeHint.width(); + } else { + pos.rx() -= m_scrollOffset; + } + return QRectF(pos, sizeHint); + } + + if (sizeHint.width() <= 0) { + // In Details View, a size hint with negative width is used internally. + sizeHint.rwidth() = m_itemSize.width(); } - QRectF bounds = m_itemInfos[index].rect; - bounds.moveTo(bounds.topLeft() - QPointF(m_itemOffset, m_scrollOffset)); - return bounds; + const QPointF pos(x - m_itemOffset, y - m_scrollOffset); + return QRectF(pos, sizeHint); } QRectF KItemListViewLayouter::groupHeaderRect(int index) const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); const QRectF firstItemRect = itemRect(index); QPointF pos = firstItemRect.topLeft(); @@ -271,61 +261,65 @@ QRectF KItemListViewLayouter::groupHeaderRect(int index) const pos.ry() -= m_groupHeaderHeight; size = QSizeF(m_size.width(), m_groupHeaderHeight); } else { - pos.rx() -= m_itemMargin.width(); pos.ry() = 0; - // Determine the maximum width used in the - // current column. As the scroll-direction is - // Qt::Horizontal and m_itemRects is accessed directly, - // the logical height represents the visual width. - qreal width = minimumGroupHeaderWidth(); - const qreal y = m_itemInfos[index].rect.y(); + // Determine the maximum width used in the current column. As the + // scroll-direction is Qt::Horizontal and m_itemRects is accessed + // directly, the logical height represents the visual width, and + // the logical row represents the column. + qreal headerWidth = minimumGroupHeaderWidth(); + const int row = m_itemInfos[index].row; const int maxIndex = m_itemInfos.count() - 1; while (index <= maxIndex) { - QRectF bounds = m_itemInfos[index].rect; - if (bounds.y() != y) { + if (m_itemInfos[index].row != row) { break; } - if (bounds.height() > width) { - width = bounds.height(); + const qreal itemWidth = + (m_scrollOrientation == Qt::Vertical) ? m_sizeHintResolver->sizeHint(index).width() : m_sizeHintResolver->sizeHint(index).height(); + + if (itemWidth > headerWidth) { + headerWidth = itemWidth; } ++index; } - size = QSizeF(width, m_size.height()); + size = QSizeF(headerWidth, m_size.height()); + + if (QGuiApplication::isRightToLeft()) { + pos.setX(firstItemRect.right() + m_itemMargin.width() - size.width()); + } else { + pos.rx() -= m_itemMargin.width(); + } } + return QRectF(pos, size); } int KItemListViewLayouter::itemColumn(int index) const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); if (index < 0 || index >= m_itemInfos.count()) { return -1; } - return (m_scrollOrientation == Qt::Vertical) - ? m_itemInfos[index].column - : m_itemInfos[index].row; + return (m_scrollOrientation == Qt::Vertical) ? m_itemInfos[index].column : m_itemInfos[index].row; } int KItemListViewLayouter::itemRow(int index) const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); if (index < 0 || index >= m_itemInfos.count()) { return -1; } - return (m_scrollOrientation == Qt::Vertical) - ? m_itemInfos[index].row - : m_itemInfos[index].column; + return (m_scrollOrientation == Qt::Vertical) ? m_itemInfos[index].row : m_itemInfos[index].column; } int KItemListViewLayouter::maximumVisibleItems() const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); const int height = static_cast(m_size.height()); const int rowHeight = static_cast(m_itemSize.height()); @@ -339,7 +333,7 @@ int KItemListViewLayouter::maximumVisibleItems() const bool KItemListViewLayouter::isFirstGroupItem(int itemIndex) const { - const_cast(this)->doLayout(); + const_cast(this)->doLayout(); return m_groupItemIndexes.contains(itemIndex); } @@ -348,194 +342,204 @@ void KItemListViewLayouter::markAsDirty() m_dirty = true; } +void KItemListViewLayouter::setStatusBarOffset(int offset) +{ + if (m_statusBarOffset != offset) { + m_statusBarOffset = offset; + } +} #ifndef QT_NO_DEBUG - bool KItemListViewLayouter::isDirty() - { - return m_dirty; - } +bool KItemListViewLayouter::isDirty() +{ + return m_dirty; +} #endif void KItemListViewLayouter::doLayout() { - if (m_dirty) { -#ifdef KITEMLISTVIEWLAYOUTER_DEBUG - QElapsedTimer timer; - timer.start(); -#endif - m_visibleIndexesDirty = true; + // we always want to update visible indexes after performing a layout + auto qsg = qScopeGuard([this] { + updateVisibleIndexes(); + }); - QSizeF itemSize = m_itemSize; - QSizeF itemMargin = m_itemMargin; - QSizeF size = m_size; - - const bool grouped = createGroupHeaders(); - - const bool horizontalScrolling = (m_scrollOrientation == Qt::Horizontal); - if (horizontalScrolling) { - // Flip everything so that the layout logically can work like having - // a vertical scrolling - itemSize.setWidth(m_itemSize.height()); - itemSize.setHeight(m_itemSize.width()); - itemMargin.setWidth(m_itemMargin.height()); - itemMargin.setHeight(m_itemMargin.width()); - size.setWidth(m_size.height()); - size.setHeight(m_size.width()); - - if (grouped) { - // In the horizontal scrolling case all groups are aligned - // at the top, which decreases the available height. For the - // flipped data this means that the width must be decreased. - size.rwidth() -= m_groupHeaderHeight; - } - } + if (!m_dirty) { + return; + } - m_columnWidth = itemSize.width() + itemMargin.width(); - const qreal widthForColumns = size.width() - itemMargin.width(); - m_columnCount = qMax(1, int(widthForColumns / m_columnWidth)); - m_xPosInc = itemMargin.width(); - - const int itemCount = m_model->count(); - if (itemCount > m_columnCount && m_columnWidth >= 32) { - // Apply the unused width equally to each column - const qreal unusedWidth = widthForColumns - m_columnCount * m_columnWidth; - if (unusedWidth > 0) { - const qreal columnInc = unusedWidth / (m_columnCount + 1); - m_columnWidth += columnInc; - m_xPosInc += columnInc; - } +#ifdef KITEMLISTVIEWLAYOUTER_DEBUG + QElapsedTimer timer; + timer.start(); +#endif + m_visibleIndexesDirty = true; + + QSizeF itemSize = m_itemSize; + QSizeF itemMargin = m_itemMargin; + QSizeF size = m_size; + + const bool grouped = createGroupHeaders(); + + const bool horizontalScrolling = m_scrollOrientation == Qt::Horizontal; + if (horizontalScrolling) { + // Flip everything so that the layout logically can work like having + // a vertical scrolling + itemSize.transpose(); + itemMargin.transpose(); + size.transpose(); + size.rwidth() -= m_statusBarOffset; + + if (grouped) { + // In the horizontal scrolling case all groups are aligned + // at the top, which decreases the available height. For the + // flipped data this means that the width must be decreased. + size.rwidth() -= m_groupHeaderHeight; } + } - int rowCount = itemCount / m_columnCount; - if (itemCount % m_columnCount != 0) { - ++rowCount; + const bool isRightToLeft = QGuiApplication::isRightToLeft(); + m_columnWidth = itemSize.width() + itemMargin.width(); + const qreal widthForColumns = std::max(size.width() - itemMargin.width(), m_columnWidth); + m_columnCount = qMax(1, int(widthForColumns / m_columnWidth)); + m_xPosInc = itemMargin.width(); + + const int itemCount = m_model->count(); + if (itemCount > m_columnCount && m_columnWidth >= 32) { + // Apply the unused width equally to each column + const qreal unusedWidth = widthForColumns - m_columnCount * m_columnWidth; + if (unusedWidth > 0) { + const qreal columnInc = unusedWidth / (m_columnCount + 1); + m_columnWidth += columnInc; + m_xPosInc += columnInc; } + } - m_itemInfos.reserve(itemCount); - - qreal y = m_headerHeight + itemMargin.height(); - int row = 0; + m_itemInfos.resize(itemCount); - int index = 0; - while (index < itemCount) { - qreal x = m_xPosInc; - qreal maxItemHeight = itemSize.height(); + // Calculate the offset of each column, i.e., the x-coordinate where the column starts. + m_columnOffsets.resize(m_columnCount); + qreal currentOffset = isRightToLeft && !horizontalScrolling ? widthForColumns : m_xPosInc; - if (grouped) { - if (horizontalScrolling) { - // All group headers will always be aligned on the top and not - // flipped like the other properties - x += m_groupHeaderHeight; - } + if (grouped && horizontalScrolling) { + // All group headers will always be aligned on the top and not + // flipped like the other properties. + currentOffset += m_groupHeaderHeight; + } - if (m_groupItemIndexes.contains(index)) { - // The item is the first item of a group. - // Increase the y-position to provide space - // for the group header. - if (index > 0) { - // Only add a margin if there has been added another - // group already before - y += m_groupHeaderMargin; - } else if (!horizontalScrolling) { - // The first group header should be aligned on top - y -= itemMargin.height(); - } - - if (!horizontalScrolling) { - y += m_groupHeaderHeight; - } - } + if (isRightToLeft) { + for (int column = 0; column < m_columnCount; ++column) { + if (horizontalScrolling) { + m_columnOffsets[column] = currentOffset + column * m_columnWidth; + } else { + currentOffset -= m_columnWidth; + m_columnOffsets[column] = currentOffset; } + } + } else { + for (int column = 0; column < m_columnCount; ++column) { + m_columnOffsets[column] = currentOffset; + currentOffset += m_columnWidth; + } + } - int column = 0; - while (index < itemCount && column < m_columnCount) { - qreal requiredItemHeight = itemSize.height(); - if (m_sizeHintResolver) { - const QSizeF sizeHint = m_sizeHintResolver->sizeHint(index); - const qreal sizeHintHeight = horizontalScrolling ? sizeHint.width() : sizeHint.height(); - if (sizeHintHeight > requiredItemHeight) { - requiredItemHeight = sizeHintHeight; - } + // Prepare the QVector which stores the y-coordinate for each new row. + int numberOfRows = (itemCount + m_columnCount - 1) / m_columnCount; + if (grouped && m_columnCount > 1) { + // In the worst case, a new row will be started for every group. + // We could calculate the exact number of rows now to prevent that we reserve + // too much memory, but the code required to do that might need much more + // memory than it would save in the average case. + numberOfRows += m_groupItemIndexes.count(); + } + m_rowOffsets.resize(numberOfRows); + + qreal y = m_headerHeight + itemMargin.height(); + int row = 0; + + int index = 0; + while (index < itemCount) { + qreal maxItemHeight = itemSize.height(); + + if (grouped) { + if (m_groupItemIndexes.contains(index)) { + // The item is the first item of a group. + // Increase the y-position to provide space + // for the group header. + if (index > 0) { + // Only add a margin if there has been added another + // group already before + y += m_groupHeaderMargin; + } else if (!horizontalScrolling) { + // The first group header should be aligned on top + y -= itemMargin.height(); } - const QRectF bounds(x, y, itemSize.width(), requiredItemHeight); - if (index < m_itemInfos.count()) { - m_itemInfos[index].rect = bounds; - m_itemInfos[index].column = column; - m_itemInfos[index].row = row; - } else { - ItemInfo itemInfo; - itemInfo.rect = bounds; - itemInfo.column = column; - itemInfo.row = row; - m_itemInfos.append(itemInfo); + if (!horizontalScrolling) { + y += m_groupHeaderHeight; } + } + } - if (grouped && horizontalScrolling) { - // When grouping is enabled in the horizontal mode, the header alignment - // looks like this: - // Header-1 Header-2 Header-3 - // Item 1 Item 4 Item 7 - // Item 2 Item 5 Item 8 - // Item 3 Item 6 Item 9 - // In this case 'requiredItemHeight' represents the column-width. We don't - // check the content of the header in the layouter to determine the required - // width, hence assure that at least a minimal width of 15 characters is given - // (in average a character requires the halve width of the font height). - // - // TODO: Let the group headers provide a minimum width and respect this width here - const qreal headerWidth = minimumGroupHeaderWidth(); - if (requiredItemHeight < headerWidth) { - requiredItemHeight = headerWidth; - } - } + m_rowOffsets[row] = y; - maxItemHeight = qMax(maxItemHeight, requiredItemHeight); - x += m_columnWidth; - ++index; - ++column; + int column = 0; + while (index < itemCount && column < m_columnCount) { + qreal requiredItemHeight = itemSize.height(); + const QSizeF sizeHint = m_sizeHintResolver->sizeHint(index); + const qreal sizeHintHeight = sizeHint.height(); + if (sizeHintHeight > requiredItemHeight) { + requiredItemHeight = sizeHintHeight; + } - if (grouped && m_groupItemIndexes.contains(index)) { - // The item represents the first index of a group - // and must aligned in the first column - break; + ItemInfo &itemInfo = m_itemInfos[index]; + itemInfo.column = column; + itemInfo.row = row; + + if (grouped && horizontalScrolling) { + // When grouping is enabled in the horizontal mode, the header alignment + // looks like this: + // Header-1 Header-2 Header-3 + // Item 1 Item 4 Item 7 + // Item 2 Item 5 Item 8 + // Item 3 Item 6 Item 9 + // In this case 'requiredItemHeight' represents the column-width. We don't + // check the content of the header in the layouter to determine the required + // width, hence assure that at least a minimal width of 15 characters is given + // (in average a character requires the halve width of the font height). + // + // TODO: Let the group headers provide a minimum width and respect this width here + const qreal headerWidth = minimumGroupHeaderWidth(); + if (requiredItemHeight < headerWidth) { + requiredItemHeight = headerWidth; } } - y += maxItemHeight + itemMargin.height(); - ++row; - } - if (m_itemInfos.count() > itemCount) { - m_itemInfos.erase(m_itemInfos.begin() + itemCount, - m_itemInfos.end()); - } - - if (itemCount > 0) { - // Calculate the maximum y-range of the last row for m_maximumScrollOffset - m_maximumScrollOffset = m_itemInfos.last().rect.bottom(); - const qreal rowY = m_itemInfos.last().rect.y(); + maxItemHeight = qMax(maxItemHeight, requiredItemHeight); + ++index; + ++column; - int index = m_itemInfos.count() - 2; - while (index >= 0 && m_itemInfos[index].rect.bottom() >= rowY) { - m_maximumScrollOffset = qMax(m_maximumScrollOffset, m_itemInfos[index].rect.bottom()); - --index; + if (grouped && m_groupItemIndexes.contains(index)) { + // The item represents the first index of a group + // and must aligned in the first column + break; } + } - m_maximumScrollOffset += itemMargin.height(); + y += maxItemHeight + itemMargin.height(); + ++row; + } - m_maximumItemOffset = m_columnCount * m_columnWidth; - } else { - m_maximumScrollOffset = 0; - m_maximumItemOffset = 0; - } + if (itemCount > 0) { + m_maximumScrollOffset = y; + m_maximumItemOffset = m_columnCount * m_columnWidth; + } else { + m_maximumScrollOffset = 0; + m_maximumItemOffset = 0; + } #ifdef KITEMLISTVIEWLAYOUTER_DEBUG - kDebug() << "[TIME] doLayout() for " << m_model->count() << "items:" << timer.elapsed(); + qCDebug(DolphinDebug) << "[TIME] doLayout() for " << m_model->count() << "items:" << timer.elapsed(); #endif - m_dirty = false; - } - - updateVisibleIndexes(); + m_dirty = false; } void KItemListViewLayouter::updateVisibleIndexes() @@ -561,7 +565,7 @@ void KItemListViewLayouter::updateVisibleIndexes() int mid = 0; do { mid = (min + max) / 2; - if (m_itemInfos[mid].rect.top() < m_scrollOffset) { + if (m_rowOffsets.at(m_itemInfos[mid].row) < m_scrollOffset) { min = mid + 1; } else { max = mid - 1; @@ -571,13 +575,13 @@ void KItemListViewLayouter::updateVisibleIndexes() if (mid > 0) { // Include the row before the first fully visible index, as it might // be partly visible - if (m_itemInfos[mid].rect.top() >= m_scrollOffset) { + if (m_rowOffsets.at(m_itemInfos[mid].row) >= m_scrollOffset) { --mid; - Q_ASSERT(m_itemInfos[mid].rect.top() < m_scrollOffset); + Q_ASSERT(m_rowOffsets.at(m_itemInfos[mid].row) < m_scrollOffset); } - const qreal rowTop = m_itemInfos[mid].rect.top(); - while (mid > 0 && m_itemInfos[mid - 1].rect.top() == rowTop) { + const int firstVisibleRow = m_itemInfos[mid].row; + while (mid > 0 && m_itemInfos[mid - 1].row == firstVisibleRow) { --mid; } } @@ -594,14 +598,14 @@ void KItemListViewLayouter::updateVisibleIndexes() max = maxIndex; do { mid = (min + max) / 2; - if (m_itemInfos[mid].rect.y() <= bottom) { + if (m_rowOffsets.at(m_itemInfos[mid].row) <= bottom) { min = mid + 1; } else { max = mid - 1; } } while (min <= max); - while (mid > 0 && m_itemInfos[mid].rect.y() > bottom) { + while (mid > 0 && m_rowOffsets.at(m_itemInfos[mid].row) > bottom) { --mid; } m_lastVisibleIndex = mid; @@ -617,7 +621,7 @@ bool KItemListViewLayouter::createGroupHeaders() m_groupItemIndexes.clear(); - const QList > groups = m_model->groups(); + const QList> groups = m_model->groups(); if (groups.isEmpty()) { return false; } @@ -635,4 +639,4 @@ qreal KItemListViewLayouter::minimumGroupHeaderWidth() const return 100; } -#include "kitemlistviewlayouter.moc" +#include "moc_kitemlistviewlayouter.cpp"