return QSize();
}
-QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes() const
+QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes(const KItemRangeList& itemRanges) const
{
QElapsedTimer timer;
timer.start();
QHash<QByteArray, QSizeF> sizes;
- const int itemCount = model()->count();
- for (int i = 0; i < itemCount; ++i) {
- foreach (const QByteArray& visibleRole, visibleRoles()) {
- QSizeF maxSize = sizes.value(visibleRole, QSizeF(0, 0));
- const QSizeF itemSize = visibleRoleSizeHint(i, visibleRole);
- maxSize = maxSize.expandedTo(itemSize);
- sizes.insert(visibleRole, maxSize);
- }
+ int calculatedItemCount = 0;
+ bool maxTimeExceeded = false;
+ foreach (const KItemRange& itemRange, itemRanges) {
+ const int startIndex = itemRange.index;
+ const int endIndex = startIndex + itemRange.count - 1;
+
+ for (int i = startIndex; i <= endIndex; ++i) {
+ foreach (const QByteArray& visibleRole, visibleRoles()) {
+ QSizeF maxSize = sizes.value(visibleRole, QSizeF(0, 0));
+ const QSizeF itemSize = visibleRoleSizeHint(i, visibleRole);
+ maxSize = maxSize.expandedTo(itemSize);
+ sizes.insert(visibleRole, maxSize);
+ }
- if (i > 100 && timer.elapsed() > 200) {
- // When having several thousands of items calculating the sizes can get
- // very expensive. We accept a possibly too small role-size in favour
- // of having no blocking user interface.
- #ifdef KFILEITEMLISTVIEW_DEBUG
- kDebug() << "Timer exceeded, stopped after" << i << "items";
- #endif
+ if (calculatedItemCount > 100 && timer.elapsed() > 200) {
+ // When having several thousands of items calculating the sizes can get
+ // very expensive. We accept a possibly too small role-size in favour
+ // of having no blocking user interface.
+ #ifdef KFILEITEMLISTVIEW_DEBUG
+ kDebug() << "Timer exceeded, stopped after" << calculatedItemCount << "items";
+ #endif
+ maxTimeExceeded = true;
+ break;
+ }
+ }
+ if (maxTimeExceeded) {
break;
}
+ ++calculatedItemCount;
}
// Stretch the width of the first role so that the full visible view-width
}
#ifdef KFILEITEMLISTVIEW_DEBUG
- kDebug() << "[TIME] Calculated dynamic item size for " << itemCount << "items:" << timer.elapsed();
+ int rangesItemCount = 0;
+ foreach (const KItemRange& itemRange, itemRanges) {
+ rangesItemCount += itemRange.count;
+ }
+ kDebug() << "[TIME] Calculated dynamic item size for " << rangesItemCount << "items:" << timer.elapsed();
#endif
return sizes;
}
virtual QSizeF itemSizeHint(int index) const;
/** @reimp */
- virtual QHash<QByteArray, QSizeF> visibleRolesSizes() const;
+ virtual QHash<QByteArray, QSizeF> visibleRolesSizes(const KItemRangeList& itemRanges) const;
/** @reimp */
virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
return itemSize();
}
-QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes() const
+QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes(const KItemRangeList& itemRanges) const
{
+ Q_UNUSED(itemRanges);
return QHash<QByteArray, QSizeF>();
}
void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
{
- updateVisibleRoleSizes();
+ updateVisibleRoleSizes(itemRanges);
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
{
const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
if (updateSizeHints) {
- updateVisibleRoleSizes();
+ updateVisibleRoleSizes(itemRanges);
}
foreach (const KItemRange& itemRange, itemRanges) {
return rolesWidths;
}
-void KItemListView::updateVisibleRoleSizes()
+void KItemListView::updateVisibleRoleSizes(const KItemRangeList& itemRanges)
{
if (!m_itemSize.isEmpty() || m_useHeaderWidths) {
return;
}
- m_visibleRolesSizes = visibleRolesSizes();
+ const int itemCount = m_model->count();
+ int rangesItemCount = 0;
+ foreach (const KItemRange& range, itemRanges) {
+ rangesItemCount += range.count;
+ }
+
+ if (itemCount == rangesItemCount) {
+ // The sizes of all roles need to be determined
+ m_visibleRolesSizes = visibleRolesSizes(itemRanges);
+ } else {
+ // Only a sub range of the roles need to be determined.
+ // The chances are good that the sizes of the sub ranges
+ // already fit into the available sizes and hence no
+ // expensive update might be required.
+ bool updateRequired = false;
+
+ const QHash<QByteArray, QSizeF> updatedSizes = visibleRolesSizes(itemRanges);
+ QHashIterator<QByteArray, QSizeF> it(updatedSizes);
+ while (it.hasNext()) {
+ it.next();
+ const QByteArray& role = it.key();
+ const QSizeF& updatedSize = it.value();
+ const QSizeF currentSize = m_visibleRolesSizes.value(role);
+ if (updatedSize.width() > currentSize.width() || updatedSize.height() > currentSize.height()) {
+ m_visibleRolesSizes.insert(role, updatedSize);
+ updateRequired = true;
+ }
+ }
+
+ if (!updateRequired) {
+ // All the updated sizes are smaller than the current sizes and no change
+ // of the roles-widths is required
+ return;
+ }
+ }
+
if (m_header) {
m_header->setVisibleRolesWidths(headerRolesWidths());
}
}
}
+void KItemListView::updateVisibleRoleSizes()
+{
+ updateVisibleRoleSizes(KItemRangeList() << KItemRange(0, m_model->count()));
+}
+
int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
{
int inc = 0;
virtual QSizeF itemSizeHint(int index) const;
/**
+ * @param itemRanges Items that must be checked for getting the visible roles sizes.
* @return The size of each visible role in case if KItemListView::itemSize()
* is empty. This allows to have dynamic but equal role sizes between
* all items. Per default an empty hash is returned.
*/
- virtual QHash<QByteArray, QSizeF> visibleRolesSizes() const;
+ virtual QHash<QByteArray, QSizeF> visibleRolesSizes(const KItemRangeList& itemRanges) const;
/**
* @return The bounding rectangle of the item relative to the top/left of
* if the m_itemRect is empty and no custom header-widths are used
* (see m_useHeaderWidths).
*/
+ void updateVisibleRoleSizes(const KItemRangeList& itemRanges);
+
+ /**
+ * Convenience method for updateVisibleRoleSizes(KItemRangeList() << KItemRange(0, m_model->count()).
+ */
void updateVisibleRoleSizes();
/**