1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
4 * Based on the Itemviews NG project from Trolltech Labs: *
5 * http://qt.gitorious.org/qt-labs/itemviews-ng *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
21 ***************************************************************************/
23 #include "kitemlistselectionmanager.h"
25 #include "kitemmodelbase.h"
28 KItemListSelectionManager::KItemListSelectionManager(QObject
* parent
) :
33 m_isAnchoredSelectionActive(false),
38 KItemListSelectionManager::~KItemListSelectionManager()
42 void KItemListSelectionManager::setCurrentItem(int current
)
44 const int previous
= m_currentItem
;
45 if (m_model
&& current
>= 0 && current
< m_model
->count()) {
46 m_currentItem
= current
;
51 if (m_currentItem
!= previous
) {
52 emit
currentChanged(m_currentItem
, previous
);
56 int KItemListSelectionManager::currentItem() const
61 void KItemListSelectionManager::setSelectedItems(const QSet
<int>& items
)
63 if (m_selectedItems
!= items
) {
64 const QSet
<int> previous
= m_selectedItems
;
65 m_selectedItems
= items
;
66 emit
selectionChanged(m_selectedItems
, previous
);
70 QSet
<int> KItemListSelectionManager::selectedItems() const
72 QSet
<int> selectedItems
= m_selectedItems
;
74 if (m_isAnchoredSelectionActive
) {
75 const int from
= qMin(m_anchorItem
, m_currentItem
);
76 const int to
= qMax(m_anchorItem
, m_currentItem
);
78 for (int index
= from
; index
<= to
; index
++) {
79 selectedItems
.insert(index
);
86 bool KItemListSelectionManager::hasSelection() const
88 return !m_selectedItems
.isEmpty() || m_isAnchoredSelectionActive
;
91 void KItemListSelectionManager::setSelected(int index
, int count
, SelectionMode mode
)
93 if (index
< 0 || count
< 1 || !m_model
|| index
>= m_model
->count()) {
97 const QSet
<int> previous
= m_selectedItems
;
99 count
= qMin(count
, m_model
->count() - index
);
101 const int endIndex
= index
+ count
-1;
104 for (int i
= index
; i
<= endIndex
; ++i
) {
105 m_selectedItems
.insert(i
);
110 for (int i
= index
; i
<= endIndex
; ++i
) {
111 m_selectedItems
.remove(i
);
116 for (int i
= index
; i
<= endIndex
; ++i
) {
117 if (m_selectedItems
.contains(i
)) {
118 m_selectedItems
.remove(i
);
120 m_selectedItems
.insert(i
);
130 if (m_selectedItems
!= previous
) {
131 emit
selectionChanged(m_selectedItems
, previous
);
135 void KItemListSelectionManager::clearSelection()
137 if (!m_selectedItems
.isEmpty()) {
138 const QSet
<int> previous
= m_selectedItems
;
139 m_selectedItems
.clear();
140 m_isAnchoredSelectionActive
= false;
141 emit
selectionChanged(m_selectedItems
, previous
);
143 else if (m_isAnchoredSelectionActive
) {
144 m_isAnchoredSelectionActive
= false;
145 // TODO: the 'previous' parameter of the signal has to be set correctly, but do we actually need it?
146 emit
selectionChanged(m_selectedItems
, m_selectedItems
);
150 void KItemListSelectionManager::beginAnchoredSelection(int anchor
)
155 void KItemListSelectionManager::endAnchoredSelection()
159 void KItemListSelectionManager::setAnchorItem(int anchor
)
161 const int previous
= m_anchorItem
;
162 if (m_model
&& anchor
< m_model
->count()) {
163 m_anchorItem
= anchor
;
168 if (m_anchorItem
!= previous
) {
169 emit
anchorChanged(m_anchorItem
, previous
);
173 int KItemListSelectionManager::anchorItem() const
178 bool KItemListSelectionManager::isAnchoredSelectionActive() const
180 return m_isAnchoredSelectionActive
;
183 void KItemListSelectionManager::setAnchoredSelectionActive(bool active
)
185 m_isAnchoredSelectionActive
= active
;
188 KItemModelBase
* KItemListSelectionManager::model() const
193 void KItemListSelectionManager::setModel(KItemModelBase
* model
)
196 if (model
&& model
->count() > 0) {
201 void KItemListSelectionManager::itemsInserted(const KItemRangeList
& itemRanges
)
203 // Update the current item
204 if (m_currentItem
< 0) {
208 foreach (const KItemRange
& itemRange
, itemRanges
) {
209 if (m_currentItem
< itemRange
.index
) {
212 inc
+= itemRange
.count
;
214 setCurrentItem(m_currentItem
+ inc
);
217 // Update the anchor item
218 if (m_anchorItem
< 0) {
222 foreach (const KItemRange
& itemRange
, itemRanges
) {
223 if (m_anchorItem
< itemRange
.index
) {
226 inc
+= itemRange
.count
;
228 setAnchorItem(m_anchorItem
+ inc
);
231 // Update the selections
232 if (!m_selectedItems
.isEmpty()) {
233 const QSet
<int> previous
= m_selectedItems
;
236 current
.reserve(m_selectedItems
.count());
237 QSetIterator
<int> it(m_selectedItems
);
238 while (it
.hasNext()) {
239 const int index
= it
.next();
241 foreach (const KItemRange
& itemRange
, itemRanges
) {
242 if (index
< itemRange
.index
) {
245 inc
+= itemRange
.count
;
247 current
.insert(index
+ inc
);
250 if (current
!= previous
) {
251 m_selectedItems
= current
;
252 emit
selectionChanged(current
, previous
);
257 void KItemListSelectionManager::itemsRemoved(const KItemRangeList
& itemRanges
)
259 // Update the current item
260 if (m_currentItem
>= 0) {
261 int currentItem
= m_currentItem
;
262 foreach (const KItemRange
& itemRange
, itemRanges
) {
263 if (currentItem
< itemRange
.index
) {
266 if (currentItem
>= itemRange
.index
+ itemRange
.count
) {
267 currentItem
-= itemRange
.count
;
268 } else if (currentItem
>= m_model
->count()) {
269 currentItem
= m_model
->count() - 1;
272 setCurrentItem(currentItem
);
275 // Update the anchor item
276 if (m_anchorItem
>= 0) {
277 int anchorItem
= m_anchorItem
;
278 foreach (const KItemRange
& itemRange
, itemRanges
) {
279 if (anchorItem
< itemRange
.index
) {
282 if (anchorItem
>= itemRange
.index
+ itemRange
.count
) {
283 anchorItem
-= itemRange
.count
;
284 } else if (anchorItem
>= m_model
->count()) {
285 anchorItem
= m_model
->count() - 1;
288 setAnchorItem(anchorItem
);
291 // Update the selections
292 if (!m_selectedItems
.isEmpty()) {
293 const QSet
<int> previous
= m_selectedItems
;
296 current
.reserve(m_selectedItems
.count());
297 QSetIterator
<int> it(m_selectedItems
);
298 while (it
.hasNext()) {
299 int index
= it
.next();
301 foreach (const KItemRange
& itemRange
, itemRanges
) {
302 if (index
< itemRange
.index
) {
306 if (index
< itemRange
.index
+ itemRange
.count
) {
307 // The selection is part of the removed range
308 // and will get deleted
313 dec
+= itemRange
.count
;
317 current
.insert(index
);
321 if (current
!= previous
) {
322 m_selectedItems
= current
;
323 emit
selectionChanged(current
, previous
);
328 #include "kitemlistselectionmanager.moc"