}
}
+ // Stretch the width of the first role so that the full visible view-width
+ // is used to show all roles.
+ const qreal availableWidth = size().width();
+
+ qreal usedWidth = 0;
+ QHashIterator<QByteArray, QSizeF> it(sizes);
+ while (it.hasNext()) {
+ it.next();
+ usedWidth += it.value().width();
+ }
+
+ if (usedWidth < availableWidth) {
+ const QByteArray role = visibleRoles().first();
+ QSizeF firstRoleSize = sizes.value(role);
+ firstRoleSize.rwidth() += availableWidth - usedWidth;
+ sizes.insert(role, firstRoleSize);
+ }
+
#ifdef KFILEITEMLISTVIEW_DEBUG
kDebug() << "[TIME] Calculated dynamic item size for " << itemCount << "items:" << timer.elapsed();
#endif
}
}
+bool KFileItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
+{
+ // Even if the icons have a different size they are always aligned within
+ // the area defined by KItemStyleOption.iconSize and hence result in no
+ // change of the item-size.
+ const bool containsIconName = changedRoles.contains("iconName");
+ const bool containsIconPixmap = changedRoles.contains("iconPixmap");
+ const int count = changedRoles.count();
+
+ const bool iconChanged = (containsIconName && containsIconPixmap && count == 2) ||
+ (containsIconName && count == 1) ||
+ (containsIconPixmap && count == 1);
+ return !iconChanged;
+}
+
void KFileItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous)
{
Q_UNUSED(previous);
{
KItemListView::resizeEvent(event);
triggerVisibleIndexRangeUpdate();
+ markVisibleRolesSizesAsDirty();
}
void KFileItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
protected:
virtual void initializeItemListWidget(KItemListWidget* item);
+ virtual bool itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const;
virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous);
virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
virtual void onItemSizeChanged(const QSizeF& current, const QSizeF& previous);
if (m_header) {
m_header->setVisibleRoles(roles);
m_header->setVisibleRolesWidths(headerRolesWidths());
+ m_useHeaderWidths = false;
}
}
Q_UNUSED(item);
}
+bool KItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
+{
+ Q_UNUSED(changedRoles);
+ return true;
+}
+
void KItemListView::onControllerChanged(KItemListController* current, KItemListController* previous)
{
Q_UNUSED(current);
updateHeaderWidth();
}
-void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
+bool KItemListView::markVisibleRolesSizesAsDirty()
{
- if (!m_useHeaderWidths) {
- markVisibleRolesSizesAsDirty();
+ const bool dirty = m_itemSize.isEmpty();
+ if (dirty && !m_useHeaderWidths) {
+ m_visibleRolesSizes.clear();
+ m_layouter->setItemSize(QSizeF());
}
+ return dirty;
+}
+
+void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
+{
+ markVisibleRolesSizesAsDirty();
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
{
- if (!m_useHeaderWidths) {
- markVisibleRolesSizesAsDirty();
- }
+ markVisibleRolesSizesAsDirty();
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges,
const QSet<QByteArray>& roles)
{
+ const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
+ if (updateSizeHints) {
+ markVisibleRolesSizesAsDirty();
+ }
+
foreach (const KItemRange& itemRange, itemRanges) {
const int index = itemRange.index;
const int count = itemRange.count;
- m_sizeHintResolver->itemsChanged(index, count, roles);
+ if (updateSizeHints) {
+ m_sizeHintResolver->itemsChanged(index, count, roles);
+ m_layouter->markAsDirty();
+ updateLayout();
+ }
+ // 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);
widget->setData(m_model->data(i), roles);
}
}
+
}
}
qreal previousWidth)
{
Q_UNUSED(previousWidth);
- Q_ASSERT(m_header);
m_useHeaderWidths = true;
}
}
-bool KItemListView::markVisibleRolesSizesAsDirty()
-{
- const bool dirty = m_itemSize.isEmpty();
- if (dirty) {
- m_visibleRolesSizes.clear();
- m_layouter->setItemSize(QSizeF());
- m_useHeaderWidths = false;
- }
- return dirty;
-}
-
void KItemListView::applyDynamicItemSize()
{
if (!m_itemSize.isEmpty()) {
int firstVisibleIndex() const;
int lastVisibleIndex() const;
+ /**
+ * @return Required size for the item with the index \p index.
+ * Per default KItemListView::itemSize() is returned.
+ * When reimplementing this method it is recommended to
+ * also reimplement KItemListView::itemSizeHintUpdateRequired().
+ */
virtual QSizeF itemSizeHint(int index) const;
/**
protected:
virtual void initializeItemListWidget(KItemListWidget* item);
+ /**
+ * @return True if at least one of the changed roles \p changedRoles might result
+ * in the need to update the item-size hint (see KItemListView::itemSizeHint()).
+ * Per default true is returned which means on each role-change of existing items
+ * the item-size hints are recalculated. For performance reasons it is recommended
+ * to return false in case if a role-change will not result in a changed
+ * item-size hint.
+ */
+ virtual bool itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const;
+
virtual void onControllerChanged(KItemListController* current, KItemListController* previous);
virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous);
QList<KItemListWidget*> visibleItemListWidgets() const;
+ /**
+ * Marks the visible roles as dirty so that they will get updated when doing the next
+ * layout. The visible roles will only get marked as dirty if an empty item-size is
+ * given and if the roles have not already been customized by the user by adjusting
+ * the view-header.
+ * @return True if the visible roles have been marked as dirty.
+ */
+ bool markVisibleRolesSizesAsDirty();
+
+ /** @reimp */
virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
protected slots:
*/
void setLayouterSize(const QSizeF& size, SizeType sizeType);
- /**
- * Marks the visible roles as dirty so that they will get updated when doing the next
- * layout. The visible roles will only get marked as dirty if an empty item-size is
- * given.
- * @return True if the visible roles have been marked as dirty.
- */
- bool markVisibleRolesSizesAsDirty();
-
/**
* Updates the m_visibleRoleSizes property and applies the dynamic
* size to the layouter.