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),
34 m_anchoredSelectionMode(KItemListSelectionManager::Select
),
39 KItemListSelectionManager::~KItemListSelectionManager()
43 void KItemListSelectionManager::setCurrentItem(int current
)
45 const int previous
= m_currentItem
;
46 if (m_model
&& current
>= 0 && current
< m_model
->count()) {
47 m_currentItem
= current
;
52 if (m_currentItem
!= previous
) {
53 emit
currentChanged(m_currentItem
, previous
);
57 int KItemListSelectionManager::currentItem() const
62 void KItemListSelectionManager::setSelectedItems(const QSet
<int>& items
)
64 if (m_selectedItems
!= items
) {
65 const QSet
<int> previous
= m_selectedItems
;
66 m_selectedItems
= items
;
67 emit
selectionChanged(m_selectedItems
, previous
);
71 QSet
<int> KItemListSelectionManager::selectedItems() const
73 QSet
<int> selectedItems
= m_selectedItems
;
75 if (m_isAnchoredSelectionActive
) {
76 const int from
= qMin(m_anchorItem
, m_currentItem
);
77 const int to
= qMax(m_anchorItem
, m_currentItem
);
79 for (int index
= from
; index
<= to
; index
++) {
80 switch (m_anchoredSelectionMode
) {
82 selectedItems
.insert(index
);
85 selectedItems
.remove(index
);
88 if (selectedItems
.contains(index
)) {
89 selectedItems
.remove(index
);
91 selectedItems
.insert(index
);
101 bool KItemListSelectionManager::hasSelection() const
103 return !m_selectedItems
.isEmpty() || (m_isAnchoredSelectionActive
&& m_anchoredSelectionMode
== KItemListSelectionManager::Select
);
106 void KItemListSelectionManager::setSelected(int index
, int count
, SelectionMode mode
)
108 if (index
< 0 || count
< 1 || !m_model
|| index
>= m_model
->count()) {
112 const QSet
<int> previous
= m_selectedItems
;
114 count
= qMin(count
, m_model
->count() - index
);
116 const int endIndex
= index
+ count
-1;
119 for (int i
= index
; i
<= endIndex
; ++i
) {
120 m_selectedItems
.insert(i
);
125 for (int i
= index
; i
<= endIndex
; ++i
) {
126 m_selectedItems
.remove(i
);
131 for (int i
= index
; i
<= endIndex
; ++i
) {
132 if (m_selectedItems
.contains(i
)) {
133 m_selectedItems
.remove(i
);
135 m_selectedItems
.insert(i
);
145 if (m_selectedItems
!= previous
) {
146 emit
selectionChanged(m_selectedItems
, previous
);
150 void KItemListSelectionManager::clearSelection()
152 if (!m_selectedItems
.isEmpty()) {
153 const QSet
<int> previous
= m_selectedItems
;
154 m_selectedItems
.clear();
155 m_isAnchoredSelectionActive
= false;
156 emit
selectionChanged(m_selectedItems
, previous
);
158 else if (m_isAnchoredSelectionActive
) {
159 m_isAnchoredSelectionActive
= false;
160 // TODO: the 'previous' parameter of the signal has to be set correctly, but do we actually need it?
161 emit
selectionChanged(m_selectedItems
, m_selectedItems
);
165 void KItemListSelectionManager::beginAnchoredSelection(int anchor
, SelectionMode mode
)
171 void KItemListSelectionManager::endAnchoredSelection()
175 void KItemListSelectionManager::setAnchorItem(int anchor
)
177 const int previous
= m_anchorItem
;
178 if (m_model
&& anchor
< m_model
->count()) {
179 m_anchorItem
= anchor
;
184 if (m_anchorItem
!= previous
) {
185 emit
anchorChanged(m_anchorItem
, previous
);
189 int KItemListSelectionManager::anchorItem() const
194 bool KItemListSelectionManager::isAnchoredSelectionActive() const
196 return m_isAnchoredSelectionActive
;
199 void KItemListSelectionManager::setAnchoredSelectionActive(bool active
)
201 m_isAnchoredSelectionActive
= active
;
204 KItemListSelectionManager::SelectionMode
KItemListSelectionManager::anchoredSelectionMode() const
206 return m_anchoredSelectionMode
;
209 void KItemListSelectionManager::setAnchoredSelectionMode(KItemListSelectionManager::SelectionMode mode
)
211 m_anchoredSelectionMode
= mode
;
214 KItemModelBase
* KItemListSelectionManager::model() const
219 void KItemListSelectionManager::setModel(KItemModelBase
* model
)
222 if (model
&& model
->count() > 0) {
227 void KItemListSelectionManager::itemsInserted(const KItemRangeList
& itemRanges
)
229 // Update the current item
230 if (m_currentItem
< 0) {
234 foreach (const KItemRange
& itemRange
, itemRanges
) {
235 if (m_currentItem
< itemRange
.index
) {
238 inc
+= itemRange
.count
;
240 setCurrentItem(m_currentItem
+ inc
);
243 // Update the anchor item
244 if (m_anchorItem
< 0) {
248 foreach (const KItemRange
& itemRange
, itemRanges
) {
249 if (m_anchorItem
< itemRange
.index
) {
252 inc
+= itemRange
.count
;
254 setAnchorItem(m_anchorItem
+ inc
);
257 // Update the selections
258 if (!m_selectedItems
.isEmpty()) {
259 const QSet
<int> previous
= m_selectedItems
;
262 current
.reserve(m_selectedItems
.count());
263 QSetIterator
<int> it(m_selectedItems
);
264 while (it
.hasNext()) {
265 const int index
= it
.next();
267 foreach (const KItemRange
& itemRange
, itemRanges
) {
268 if (index
< itemRange
.index
) {
271 inc
+= itemRange
.count
;
273 current
.insert(index
+ inc
);
276 if (current
!= previous
) {
277 m_selectedItems
= current
;
278 emit
selectionChanged(current
, previous
);
283 void KItemListSelectionManager::itemsRemoved(const KItemRangeList
& itemRanges
)
285 // Update the current item
286 if (m_currentItem
>= 0) {
287 int currentItem
= m_currentItem
;
288 foreach (const KItemRange
& itemRange
, itemRanges
) {
289 if (currentItem
< itemRange
.index
) {
292 if (currentItem
>= itemRange
.index
+ itemRange
.count
) {
293 currentItem
-= itemRange
.count
;
294 } else if (currentItem
>= m_model
->count()) {
295 currentItem
= m_model
->count() - 1;
298 setCurrentItem(currentItem
);
301 // Update the anchor item
302 if (m_anchorItem
>= 0) {
303 int anchorItem
= m_anchorItem
;
304 foreach (const KItemRange
& itemRange
, itemRanges
) {
305 if (anchorItem
< itemRange
.index
) {
308 if (anchorItem
>= itemRange
.index
+ itemRange
.count
) {
309 anchorItem
-= itemRange
.count
;
310 } else if (anchorItem
>= m_model
->count()) {
311 anchorItem
= m_model
->count() - 1;
314 setAnchorItem(anchorItem
);
317 // Update the selections
318 if (!m_selectedItems
.isEmpty()) {
319 const QSet
<int> previous
= m_selectedItems
;
322 current
.reserve(m_selectedItems
.count());
323 QSetIterator
<int> it(m_selectedItems
);
324 while (it
.hasNext()) {
325 int index
= it
.next();
327 foreach (const KItemRange
& itemRange
, itemRanges
) {
328 if (index
< itemRange
.index
) {
332 if (index
< itemRange
.index
+ itemRange
.count
) {
333 // The selection is part of the removed range
334 // and will get deleted
339 dec
+= itemRange
.count
;
343 current
.insert(index
);
347 if (current
!= previous
) {
348 m_selectedItems
= current
;
349 emit
selectionChanged(current
, previous
);
354 #include "kitemlistselectionmanager.moc"