]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistsizehintresolver.cpp
Output of licensedigger + manual cleanup afterwards.
[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));
33 }
34
35 void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges)
36 {
37 int insertedCount = 0;
38 foreach (const KItemRange& range, itemRanges) {
39 insertedCount += range.count;
40 }
41
42 const int currentCount = m_logicalHeightHintCache.count();
43 m_logicalHeightHintCache.reserve(currentCount + insertedCount);
44
45 // We build the new list from the end to the beginning to mimize the
46 // number of moves.
47 m_logicalHeightHintCache.insert(m_logicalHeightHintCache.end(), insertedCount, 0.0);
48
49 int sourceIndex = currentCount - 1;
50 int targetIndex = m_logicalHeightHintCache.count() - 1;
51 int itemsToInsertBeforeCurrentRange = insertedCount;
52
53 for (int rangeIndex = itemRanges.count() - 1; rangeIndex >= 0; --rangeIndex) {
54 const KItemRange& range = itemRanges.at(rangeIndex);
55 itemsToInsertBeforeCurrentRange -= range.count;
56
57 // First: move all existing items that must be put behind 'range'.
58 while (targetIndex >= itemsToInsertBeforeCurrentRange + range.index + range.count) {
59 m_logicalHeightHintCache[targetIndex] = m_logicalHeightHintCache[sourceIndex];
60 --sourceIndex;
61 --targetIndex;
62 }
63
64 // Then: insert QSizeF() for the items which are inserted into 'range'.
65 while (targetIndex >= itemsToInsertBeforeCurrentRange + range.index) {
66 m_logicalHeightHintCache[targetIndex] = 0.0;
67 --targetIndex;
68 }
69 }
70
71 m_needsResolving = true;
72
73 Q_ASSERT(m_logicalHeightHintCache.count() == m_itemListView->model()->count());
74 }
75
76 void KItemListSizeHintResolver::itemsRemoved(const KItemRangeList& itemRanges)
77 {
78 const QVector<qreal>::iterator begin = m_logicalHeightHintCache.begin();
79 const QVector<qreal>::iterator end = m_logicalHeightHintCache.end();
80
81 KItemRangeList::const_iterator rangeIt = itemRanges.constBegin();
82 const KItemRangeList::const_iterator rangeEnd = itemRanges.constEnd();
83
84 QVector<qreal>::iterator destIt = begin + rangeIt->index;
85 QVector<qreal>::iterator srcIt = destIt + rangeIt->count;
86
87 ++rangeIt;
88
89 while (srcIt != end) {
90 *destIt = *srcIt;
91 ++destIt;
92 ++srcIt;
93
94 if (rangeIt != rangeEnd && srcIt == begin + rangeIt->index) {
95 // Skip the items in the next removed range.
96 srcIt += rangeIt->count;
97 ++rangeIt;
98 }
99 }
100
101 m_logicalHeightHintCache.erase(destIt, end);
102
103 // Note that the cache size might temporarily not match the model size if
104 // this function is called from KItemListView::setModel() to empty the cache.
105 if (!m_logicalHeightHintCache.isEmpty() && m_itemListView->model()) {
106 Q_ASSERT(m_logicalHeightHintCache.count() == m_itemListView->model()->count());
107 }
108 }
109
110 void KItemListSizeHintResolver::itemsMoved(const KItemRange& range, const QList<int>& movedToIndexes)
111 {
112 QVector<qreal> newLogicalHeightHintCache(m_logicalHeightHintCache);
113
114 const int movedRangeEnd = range.index + range.count;
115 for (int i = range.index; i < movedRangeEnd; ++i) {
116 const int newIndex = movedToIndexes.at(i - range.index);
117 newLogicalHeightHintCache[newIndex] = m_logicalHeightHintCache.at(i);
118 }
119
120 m_logicalHeightHintCache = newLogicalHeightHintCache;
121 }
122
123 void KItemListSizeHintResolver::itemsChanged(int index, int count, const QSet<QByteArray>& roles)
124 {
125 Q_UNUSED(roles)
126 while (count) {
127 m_logicalHeightHintCache[index] = 0.0;
128 ++index;
129 --count;
130 }
131
132 m_needsResolving = true;
133 }
134
135 void KItemListSizeHintResolver::clearCache()
136 {
137 m_logicalHeightHintCache.fill(0.0);
138 m_needsResolving = true;
139 }
140
141 void KItemListSizeHintResolver::updateCache()
142 {
143 if (m_needsResolving) {
144 m_itemListView->calculateItemSizeHints(m_logicalHeightHintCache, m_logicalWidthHint);
145 m_needsResolving = false;
146 }
147 }