┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kitemviews/kitemlistview.cpp4
-rw-r--r--src/kitemviews/kitemlistview.h12
-rw-r--r--src/kitemviews/kitemlistwidget.h2
-rw-r--r--src/kitemviews/kstandarditemlistwidget.cpp180
-rw-r--r--src/kitemviews/kstandarditemlistwidget.h6
-rw-r--r--src/kitemviews/private/kitemlistsizehintresolver.cpp26
-rw-r--r--src/kitemviews/private/kitemlistsizehintresolver.h4
-rw-r--r--src/kitemviews/private/kitemlistviewlayouter.cpp2
-rw-r--r--src/kitemviews/private/kitemlistviewlayouter.h4
9 files changed, 149 insertions, 91 deletions
diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp
index 7f497210c..38ce63af0 100644
--- a/src/kitemviews/kitemlistview.cpp
+++ b/src/kitemviews/kitemlistview.cpp
@@ -460,9 +460,9 @@ int KItemListView::lastVisibleIndex() const
return m_layouter->lastVisibleIndex();
}
-QSizeF KItemListView::itemSizeHint(int index) const
+void KItemListView::calculateItemSizeHints(QVector<QSizeF>& sizeHints) const
{
- return widgetCreator()->itemSizeHint(index, this);
+ widgetCreator()->calculateItemSizeHints(sizeHints, this);
}
void KItemListView::setSupportsItemExpanding(bool supportsExpanding)
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index dbe923086..f39e73a97 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -194,12 +194,12 @@ public:
int lastVisibleIndex() const;
/**
- * @return Required size for the item with the index \p index.
+ * @return Required size for all items in the model.
* The returned value might be larger than KItemListView::itemSize().
* In this case the layout grid will be stretched to assure an
* unclipped item.
*/
- QSizeF itemSizeHint(int index) const;
+ void calculateItemSizeHints(QVector<QSizeF>& sizeHints) const;
/**
* If set to true, items having child-items can be expanded to show the child-items as
@@ -802,7 +802,7 @@ public:
virtual void recycle(KItemListWidget* widget);
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const = 0;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
@@ -821,7 +821,7 @@ public:
virtual KItemListWidget* create(KItemListView* view);
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
@@ -854,9 +854,9 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
}
template<class T>
-QSizeF KItemListWidgetCreator<T>::itemSizeHint(int index, const KItemListView* view) const
+void KItemListWidgetCreator<T>::calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
{
- return m_informant->itemSizeHint(index, view);
+ return m_informant->calculateItemSizeHints(sizeHints, view);
}
template<class T>
diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h
index 55181faa8..954629ddd 100644
--- a/src/kitemviews/kitemlistwidget.h
+++ b/src/kitemviews/kitemlistwidget.h
@@ -49,7 +49,7 @@ public:
KItemListWidgetInformant();
virtual ~KItemListWidgetInformant();
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const = 0;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp
index acdf839ac..9a9a734ed 100644
--- a/src/kitemviews/kstandarditemlistwidget.cpp
+++ b/src/kitemviews/kstandarditemlistwidget.cpp
@@ -55,84 +55,25 @@ KStandardItemListWidgetInformant::~KStandardItemListWidgetInformant()
{
}
-QSizeF KStandardItemListWidgetInformant::itemSizeHint(int index, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
{
- const KItemListStyleOption& option = view->styleOption();
- const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
-
switch (static_cast<const KStandardItemListView*>(view)->itemLayout()) {
- case KStandardItemListWidget::IconsLayout: {
- const QString text = KStringHandler::preProcessWrap(itemText(index, view));
-
- const qreal itemWidth = view->itemSize().width();
- const qreal maxWidth = itemWidth - 2 * option.padding;
- QTextLine line;
-
- // Calculate the number of lines required for wrapping the name
- QTextOption textOption(Qt::AlignHCenter);
- textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
-
- qreal textHeight = 0;
- QTextLayout layout(text, option.font);
- layout.setTextOption(textOption);
- layout.beginLayout();
- while ((line = layout.createLine()).isValid()) {
- line.setLineWidth(maxWidth);
- line.naturalTextWidth();
- textHeight += line.height();
- }
- layout.endLayout();
-
- // Add one line for each additional information
- textHeight += additionalRolesCount * option.fontMetrics.lineSpacing();
-
- const qreal maxTextHeight = option.maxTextSize.height();
- if (maxTextHeight > 0 && textHeight > maxTextHeight) {
- textHeight = maxTextHeight;
- }
-
- return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3);
- }
-
- case KStandardItemListWidget::CompactLayout: {
- // For each row exactly one role is shown. Calculate the maximum required width that is necessary
- // to show all roles without horizontal clipping.
- qreal maximumRequiredWidth = 0.0;
-
- const QList<QByteArray>& visibleRoles = view->visibleRoles();
- const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
-
- if (showOnlyTextRole) {
- maximumRequiredWidth = option.fontMetrics.width(itemText(index, view));
- } else {
- const QHash<QByteArray, QVariant> values = view->model()->data(index);
- foreach (const QByteArray& role, view->visibleRoles()) {
- const QString text = roleText(role, values);
- const qreal requiredWidth = option.fontMetrics.width(text);
- maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
- }
- }
+ case KStandardItemListWidget::IconsLayout:
+ calculateIconsLayoutItemSizeHints(sizeHints, view);
+ break;
- qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
- const qreal maxWidth = option.maxTextSize.width();
- if (maxWidth > 0 && width > maxWidth) {
- width = maxWidth;
- }
- const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
- return QSizeF(width, height);
- }
+ case KStandardItemListWidget::CompactLayout:
+ calculateCompactLayoutItemSizeHints(sizeHints, view);
+ break;
- case KStandardItemListWidget::DetailsLayout: {
- const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
- return QSizeF(-1, height);
- }
+ case KStandardItemListWidget::DetailsLayout:
+ calculateDetailsLayoutItemSizeHints(sizeHints, view);
+ break;
default:
Q_ASSERT(false);
break;
}
-
- return QSize();
}
qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArray& role,
@@ -181,6 +122,107 @@ QString KStandardItemListWidgetInformant::roleText(const QByteArray& role,
return values.value(role).toString();
}
+void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const QFont& font = option.font;
+ const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+ const qreal itemWidth = view->itemSize().width();
+ const qreal maxWidth = itemWidth - 2 * option.padding;
+ const qreal maxTextHeight = option.maxTextSize.height();
+ const qreal additionalRolesSpacing = additionalRolesCount * option.fontMetrics.lineSpacing();
+ const qreal spacingAndIconHeight = option.iconSize + option.padding * 3;
+
+ QTextOption textOption(Qt::AlignHCenter);
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+
+ for (int index = 0; index < sizeHints.count(); ++index) {
+ if (!sizeHints.at(index).isEmpty()) {
+ continue;
+ }
+
+ const QString& text = KStringHandler::preProcessWrap(itemText(index, view));
+
+ // Calculate the number of lines required for wrapping the name
+ qreal textHeight = 0;
+ QTextLayout layout(text, font);
+ layout.setTextOption(textOption);
+ layout.beginLayout();
+ QTextLine line;
+ while ((line = layout.createLine()).isValid()) {
+ line.setLineWidth(maxWidth);
+ line.naturalTextWidth();
+ textHeight += line.height();
+ }
+ layout.endLayout();
+
+ // Add one line for each additional information
+ textHeight += additionalRolesSpacing;
+
+ if (maxTextHeight > 0 && textHeight > maxTextHeight) {
+ textHeight = maxTextHeight;
+ }
+
+ sizeHints[index] = QSizeF(itemWidth, textHeight + spacingAndIconHeight);
+ }
+}
+
+void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const QFontMetrics& fontMetrics = option.fontMetrics;
+ const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+ const QList<QByteArray>& visibleRoles = view->visibleRoles();
+ const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
+ const qreal maxWidth = option.maxTextSize.width();
+ const qreal paddingAndIconWidth = option.padding * 4 + option.iconSize;
+ const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
+
+ for (int index = 0; index < sizeHints.count(); ++index) {
+ if (!sizeHints.at(index).isEmpty()) {
+ continue;
+ }
+
+ // For each row exactly one role is shown. Calculate the maximum required width that is necessary
+ // to show all roles without horizontal clipping.
+ qreal maximumRequiredWidth = 0.0;
+
+ if (showOnlyTextRole) {
+ maximumRequiredWidth = fontMetrics.width(itemText(index, view));
+ } else {
+ const QHash<QByteArray, QVariant>& values = view->model()->data(index);
+ foreach (const QByteArray& role, visibleRoles) {
+ const QString& text = roleText(role, values);
+ const qreal requiredWidth = fontMetrics.width(text);
+ maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
+ }
+ }
+
+ qreal width = paddingAndIconWidth + maximumRequiredWidth;
+ if (maxWidth > 0 && width > maxWidth) {
+ width = maxWidth;
+ }
+
+ sizeHints[index] = QSizeF(width, height);
+ }
+}
+
+void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
+
+ for (int index = 0; index < sizeHints.count(); ++index) {
+ if (!sizeHints.at(index).isEmpty()) {
+ continue;
+ }
+
+ sizeHints[index] = QSizeF(-1, height);
+ }
+}
+
KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
KItemListWidget(informant, parent),
m_isCut(false),
diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h
index 7dd93b2b8..ca198c36b 100644
--- a/src/kitemviews/kstandarditemlistwidget.h
+++ b/src/kitemviews/kstandarditemlistwidget.h
@@ -38,7 +38,7 @@ public:
KStandardItemListWidgetInformant();
virtual ~KStandardItemListWidgetInformant();
- virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
+ virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
@@ -61,6 +61,10 @@ protected:
virtual QString roleText(const QByteArray& role,
const QHash<QByteArray, QVariant>& values) const;
+ void calculateIconsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
+ void calculateCompactLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
+ void calculateDetailsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const;
+
friend class KStandardItemListWidget; // Accesses roleText()
};
diff --git a/src/kitemviews/private/kitemlistsizehintresolver.cpp b/src/kitemviews/private/kitemlistsizehintresolver.cpp
index 0e2286b45..029beddf9 100644
--- a/src/kitemviews/private/kitemlistsizehintresolver.cpp
+++ b/src/kitemviews/private/kitemlistsizehintresolver.cpp
@@ -23,7 +23,8 @@
KItemListSizeHintResolver::KItemListSizeHintResolver(const KItemListView* itemListView) :
m_itemListView(itemListView),
- m_sizeHintCache()
+ m_sizeHintCache(),
+ m_needsResolving(false)
{
}
@@ -31,14 +32,10 @@ KItemListSizeHintResolver::~KItemListSizeHintResolver()
{
}
-QSizeF KItemListSizeHintResolver::sizeHint(int index) const
+QSizeF KItemListSizeHintResolver::sizeHint(int index)
{
- QSizeF size = m_sizeHintCache.at(index);
- if (size.isEmpty()) {
- size = m_itemListView->itemSizeHint(index);
- m_sizeHintCache[index] = size;
- }
- return size;
+ updateCache();
+ return m_sizeHintCache.at(index);
}
void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges)
@@ -77,6 +74,8 @@ void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges)
}
}
+ m_needsResolving = true;
+
Q_ASSERT(m_sizeHintCache.count() == m_itemListView->model()->count());
}
@@ -135,9 +134,20 @@ void KItemListSizeHintResolver::itemsChanged(int index, int count, const QSet<QB
++index;
--count;
}
+
+ m_needsResolving = true;
}
void KItemListSizeHintResolver::clearCache()
{
m_sizeHintCache.fill(QSizeF());
+ m_needsResolving = true;
+}
+
+void KItemListSizeHintResolver::updateCache()
+{
+ if (m_needsResolving) {
+ m_itemListView->calculateItemSizeHints(m_sizeHintCache);
+ m_needsResolving = false;
+ }
}
diff --git a/src/kitemviews/private/kitemlistsizehintresolver.h b/src/kitemviews/private/kitemlistsizehintresolver.h
index 486f9b631..86580bf7b 100644
--- a/src/kitemviews/private/kitemlistsizehintresolver.h
+++ b/src/kitemviews/private/kitemlistsizehintresolver.h
@@ -36,7 +36,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListSizeHintResolver
public:
KItemListSizeHintResolver(const KItemListView* itemListView);
virtual ~KItemListSizeHintResolver();
- QSizeF sizeHint(int index) const;
+ QSizeF sizeHint(int index);
void itemsInserted(const KItemRangeList& itemRanges);
void itemsRemoved(const KItemRangeList& itemRanges);
@@ -44,10 +44,12 @@ public:
void itemsChanged(int index, int count, const QSet<QByteArray>& roles);
void clearCache();
+ void updateCache();
private:
const KItemListView* m_itemListView;
mutable QVector<QSizeF> m_sizeHintCache;
+ bool m_needsResolving;
};
#endif
diff --git a/src/kitemviews/private/kitemlistviewlayouter.cpp b/src/kitemviews/private/kitemlistviewlayouter.cpp
index 90e8a6d0f..73f3d6182 100644
--- a/src/kitemviews/private/kitemlistviewlayouter.cpp
+++ b/src/kitemviews/private/kitemlistviewlayouter.cpp
@@ -209,7 +209,7 @@ const KItemModelBase* KItemListViewLayouter::model() const
return m_model;
}
-void KItemListViewLayouter::setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver)
+void KItemListViewLayouter::setSizeHintResolver(KItemListSizeHintResolver* sizeHintResolver)
{
if (m_sizeHintResolver != sizeHintResolver) {
m_sizeHintResolver = sizeHintResolver;
diff --git a/src/kitemviews/private/kitemlistviewlayouter.h b/src/kitemviews/private/kitemlistviewlayouter.h
index 19b14796d..5ae472411 100644
--- a/src/kitemviews/private/kitemlistviewlayouter.h
+++ b/src/kitemviews/private/kitemlistviewlayouter.h
@@ -103,7 +103,7 @@ public:
void setModel(const KItemModelBase* model);
const KItemModelBase* model() const;
- void setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver);
+ void setSizeHintResolver(KItemListSizeHintResolver* sizeHintResolver);
const KItemListSizeHintResolver* sizeHintResolver() const;
/**
@@ -205,7 +205,7 @@ private:
QSizeF m_itemMargin;
qreal m_headerHeight;
const KItemModelBase* m_model;
- const KItemListSizeHintResolver* m_sizeHintResolver;
+ KItemListSizeHintResolver* m_sizeHintResolver;
qreal m_scrollOffset;
qreal m_maximumScrollOffset;