+ // Calculate the maximum size of an item by considering the
+ // visible role sizes and apply them to the layouter. If the
+ // size does not use the available view-size the size of the
+ // first role will get stretched.
+
+ for (const QByteArray& role : qAsConst(m_visibleRoles)) {
+ const qreal preferredWidth = m_headerWidget->preferredColumnWidth(role);
+ m_headerWidget->setColumnWidth(role, preferredWidth);
+ }
+
+ const QByteArray firstRole = m_visibleRoles.first();
+ qreal firstColumnWidth = m_headerWidget->columnWidth(firstRole);
+ QSizeF dynamicItemSize = m_itemSize;
+
+ qreal requiredWidth = columnWidthsSum() + m_headerWidget->sidePadding()
+ + m_headerWidget->sidePadding(); // Adding the padding a second time so we have 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
+ firstColumnWidth += availableWidth - requiredWidth;
+ m_headerWidget->setColumnWidth(firstRole, firstColumnWidth);
+ } else if (requiredWidth > availableWidth && m_visibleRoles.count() > 1) {
+ // Shrink the first column to be able to show as much other
+ // columns as possible
+ qreal shrinkedFirstColumnWidth = firstColumnWidth - requiredWidth + availableWidth;
+
+ // TODO: A proper calculation of the minimum width depends on the implementation
+ // of KItemListWidget. Probably a kind of minimum size-hint should be introduced
+ // later.
+ const qreal minWidth = qMin(firstColumnWidth, qreal(m_styleOption.iconSize * 2 + 200));
+ if (shrinkedFirstColumnWidth < minWidth) {
+ shrinkedFirstColumnWidth = minWidth;
+ }
+
+ m_headerWidget->setColumnWidth(firstRole, shrinkedFirstColumnWidth);
+ requiredWidth -= firstColumnWidth - shrinkedFirstColumnWidth;
+ }
+
+ dynamicItemSize.rwidth() = qMax(requiredWidth, availableWidth);
+
+ m_layouter->setItemSize(dynamicItemSize);
+
+ // Update the role sizes for all visible widgets
+ QHashIterator<int, KItemListWidget*> it(m_visibleItems);
+ while (it.hasNext()) {
+ it.next();
+ updateWidgetColumnWidths(it.value());
+ }
+}
+
+qreal KItemListView::columnWidthsSum() const
+{
+ qreal widthsSum = 0;
+ for (const QByteArray& role : qAsConst(m_visibleRoles)) {
+ widthsSum += m_headerWidget->columnWidth(role);
+ }
+ return widthsSum;
+}
+
+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
+{
+ if (newItemSize.isEmpty() || newGridSize.isEmpty()) {
+ return false;
+ }
+
+ 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());
+ if (m_model->count() > newColumnCount) {
+ 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());
+ if (m_model->count() > newRowCount) {
+ const int oldRowCount = itemsPerSize(m_layouter->size().height(),
+ itemHeight,
+ m_layouter->itemMargin().height());
+ return oldRowCount != newRowCount;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool KItemListView::animateChangedItemCount(int changedItemCount) const
+{
+ if (m_itemSize.isEmpty()) {
+ // We have only columns or only rows, but no grid: An animation is usually
+ // welcome when inserting or removing items.
+ return !supportsItemExpanding();
+ }
+
+ if (m_layouter->size().isEmpty() || m_layouter->itemSize().isEmpty()) {
+ return false;
+ }
+
+ 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;