]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistsizehintresolver.cpp
GIT_SILENT Sync po/docbooks with svn
[dolphin.git] / src / kitemviews / private / kitemlistsizehintresolver.cpp
1 /*
2 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "kitemlistsizehintresolver.h"
8 #include "kitemviews/kitemlistview.h"
9
10 KItemListSizeHintResolver::KItemListSizeHintResolver(const KItemListView *itemListView)
11 : m_itemListView(itemListView)
12 , m_logicalHeightHintCache()
13 , m_logicalWidthHint(0.0)
14 , m_minHeightHint(0.0)
15 , m_needsResolving(false)
16 {
17 }
18
19 KItemListSizeHintResolver::~KItemListSizeHintResolver()
20 {
21 }
22
23 QSizeF KItemListSizeHintResolver::minSizeHint()
24 {
25 updateCache();
26 return QSizeF(m_logicalWidthHint, m_minHeightHint);
27 }
28
29 QSizeF KItemListSizeHintResolver::sizeHint(int index)
30 {
31 updateCache();
32 return QSizeF(m_logicalWidthHint, m_logicalHeightHintCache.at(index).first);
33 }
34
35 bool KItemListSizeHintResolver::isElided(int index)
36 {
37 return m_logicalHeightHintCache.at(index).second;
38 }
39
40 void KItemListSizeHintResolver::itemsInserted(const KItemRangeList &itemRanges)
41 {
42 int insertedCount = 0;
43 for (const KItemRange &range : itemRanges) {
44 insertedCount += range.count;
45 }
46
47 const int currentCount = m_logicalHeightHintCache.count();
48 m_logicalHeightHintCache.reserve(currentCount + insertedCount);
49
50 // We build the new list from the end to the beginning to mimize the
51 // number of moves.
52 m_logicalHeightHintCache.insert(m_logicalHeightHintCache.end(), insertedCount, std::make_pair(0.0, false));
53
54 int sourceIndex = currentCount - 1;
55 int targetIndex = m_logicalHeightHintCache.count() - 1;
56 int itemsToInsertBeforeCurrentRange = insertedCount;
57
58 for (int rangeIndex = itemRanges.count() - 1; rangeIndex >= 0; --rangeIndex) {
59 const KItemRange &range = itemRanges.at(rangeIndex);
60 itemsToInsertBeforeCurrentRange -= range.count;
61
62 // First: move all existing items that must be put behind 'range'.
63 while (targetIndex >= itemsToInsertBeforeCurrentRange + range.index + range.count) {
64 m_logicalHeightHintCache[targetIndex] = m_logicalHeightHintCache[sourceIndex];
65 --sourceIndex;
66 --targetIndex;
67 }
68
69 // Then: insert QSizeF() for the items which are inserted into 'range'.
70 while (targetIndex >= itemsToInsertBeforeCurrentRange + range.index) {
71 m_logicalHeightHintCache[targetIndex] = std::make_pair(0.0, false);
72 --targetIndex;
73 }
74 }
75
76 m_needsResolving = true;
77
78 Q_ASSERT(m_logicalHeightHintCache.count() == m_itemListView->model()->count());
79 }
80
81 void KItemListSizeHintResolver::itemsRemoved(const KItemRangeList &itemRanges)
82 {
83 const QVector<std::pair<qreal, bool>>::iterator begin = m_logicalHeightHintCache.begin();
84 const QVector<std::pair<qreal, bool>>::iterator end = m_logicalHeightHintCache.end();
85
86 KItemRangeList::const_iterator rangeIt = itemRanges.constBegin();
87 const KItemRangeList::const_iterator rangeEnd = itemRanges.constEnd();
88
89 QVector<std::pair<qreal, bool>>::iterator destIt = begin + rangeIt->index;
90 QVector<std::pair<qreal, bool>>::iterator srcIt = destIt + rangeIt->count;
91
92 ++rangeIt;
93
94 while (srcIt != end) {
95 *destIt = *srcIt;
96 ++destIt;
97 ++srcIt;
98
99 if (rangeIt != rangeEnd && srcIt == begin + rangeIt->index) {
100 // Skip the items in the next removed range.
101 srcIt += rangeIt->count;
102 ++rangeIt;
103 }
104 }
105
106 m_logicalHeightHintCache.erase(destIt, end);
107
108 // Note that the cache size might temporarily not match the model size if
109 // this function is called from KItemListView::setModel() to empty the cache.
110 if (!m_logicalHeightHintCache.isEmpty() && m_itemListView->model()) {
111 Q_ASSERT(m_logicalHeightHintCache.count() == m_itemListView->model()->count());
112 }
113 }
114
115 void KItemListSizeHintResolver::itemsMoved(const KItemRange &range, const QList<int> &movedToIndexes)
116 {
117 QVector<std::pair<qreal, bool>> newLogicalHeightHintCache(m_logicalHeightHintCache);
118
119 const int movedRangeEnd = range.index + range.count;
120 for (int i = range.index; i < movedRangeEnd; ++i) {
121 const int newIndex = movedToIndexes.at(i - range.index);
122 newLogicalHeightHintCache[newIndex] = m_logicalHeightHintCache.at(i);
123 }
124
125 m_logicalHeightHintCache = newLogicalHeightHintCache;
126 }
127
128 void KItemListSizeHintResolver::itemsChanged(int index, int count, const QSet<QByteArray> &roles)
129 {
130 Q_UNUSED(roles)
131 while (count) {
132 m_logicalHeightHintCache[index] = std::make_pair(0.0, false);
133 ++index;
134 --count;
135 }
136
137 m_needsResolving = true;
138 }
139
140 void KItemListSizeHintResolver::clearCache()
141 {
142 m_logicalHeightHintCache.fill(std::make_pair(0.0, false));
143 m_needsResolving = true;
144 }
145
146 void KItemListSizeHintResolver::updateCache()
147 {
148 if (m_needsResolving) {
149 m_itemListView->calculateItemSizeHints(m_logicalHeightHintCache, m_logicalWidthHint);
150 m_needsResolving = false;
151 }
152 }