1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * Copyright (C) 2011 by Frank Reininghaus <frank78ac@googlemail.com> *
5 * Based on the Itemviews NG project from Trolltech Labs: *
6 * http://qt.gitorious.org/qt-labs/itemviews-ng *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
22 ***************************************************************************/
24 #include "kitemlistselectionmanager.h"
26 #include "kitemmodelbase.h"
29 KItemListSelectionManager::KItemListSelectionManager(QObject
* parent
) :
34 m_isAnchoredSelectionActive(false),
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 selectedItems
.insert(index
);
87 bool KItemListSelectionManager::hasSelection() const
89 return !m_selectedItems
.isEmpty() || m_isAnchoredSelectionActive
;
92 void KItemListSelectionManager::setSelected(int index
, int count
, SelectionMode mode
)
94 if (index
< 0 || count
< 1 || !m_model
|| index
>= m_model
->count()) {
98 const QSet
<int> previous
= m_selectedItems
;
100 count
= qMin(count
, m_model
->count() - index
);
102 const int endIndex
= index
+ count
-1;
105 for (int i
= index
; i
<= endIndex
; ++i
) {
106 m_selectedItems
.insert(i
);
111 for (int i
= index
; i
<= endIndex
; ++i
) {
112 m_selectedItems
.remove(i
);
117 for (int i
= index
; i
<= endIndex
; ++i
) {
118 if (m_selectedItems
.contains(i
)) {
119 m_selectedItems
.remove(i
);
121 m_selectedItems
.insert(i
);
131 if (m_selectedItems
!= previous
) {
132 emit
selectionChanged(m_selectedItems
, previous
);
136 void KItemListSelectionManager::clearSelection()
138 if (!m_selectedItems
.isEmpty()) {
139 const QSet
<int> previous
= m_selectedItems
;
140 m_selectedItems
.clear();
141 m_isAnchoredSelectionActive
= false;
142 emit
selectionChanged(m_selectedItems
, previous
);
144 else if (m_isAnchoredSelectionActive
) {
145 m_isAnchoredSelectionActive
= false;
146 // TODO: the 'previous' parameter of the signal has to be set correctly, but do we actually need it?
147 emit
selectionChanged(m_selectedItems
, m_selectedItems
);
151 void KItemListSelectionManager::beginAnchoredSelection(int anchor
)
153 m_isAnchoredSelectionActive
= true;
154 setAnchorItem(anchor
);
157 void KItemListSelectionManager::endAnchoredSelection()
159 if (m_isAnchoredSelectionActive
) {
160 const int from
= qMin(m_anchorItem
, m_currentItem
);
161 const int to
= qMax(m_anchorItem
, m_currentItem
);
163 for (int index
= from
; index
<= to
; index
++) {
164 m_selectedItems
.insert(index
);
167 m_isAnchoredSelectionActive
= false;
171 void KItemListSelectionManager::setAnchorItem(int anchor
)
173 const int previous
= m_anchorItem
;
174 if (m_model
&& anchor
< m_model
->count()) {
175 m_anchorItem
= anchor
;
180 if (m_anchorItem
!= previous
) {
181 emit
anchorChanged(m_anchorItem
, previous
);
185 int KItemListSelectionManager::anchorItem() const
190 bool KItemListSelectionManager::isAnchoredSelectionActive() const
192 return m_isAnchoredSelectionActive
;
195 void KItemListSelectionManager::setAnchoredSelectionActive(bool active
)
197 m_isAnchoredSelectionActive
= active
;
200 KItemModelBase
* KItemListSelectionManager::model() const
205 void KItemListSelectionManager::setModel(KItemModelBase
* model
)
208 if (model
&& model
->count() > 0) {
213 void KItemListSelectionManager::itemsInserted(const KItemRangeList
& itemRanges
)
215 // Update the current item
216 if (m_currentItem
< 0) {
220 foreach (const KItemRange
& itemRange
, itemRanges
) {
221 if (m_currentItem
< itemRange
.index
) {
224 inc
+= itemRange
.count
;
226 setCurrentItem(m_currentItem
+ inc
);
229 // Update the anchor item
230 if (m_anchorItem
< 0) {
234 foreach (const KItemRange
& itemRange
, itemRanges
) {
235 if (m_anchorItem
< itemRange
.index
) {
238 inc
+= itemRange
.count
;
240 setAnchorItem(m_anchorItem
+ inc
);
243 // Update the selections
244 if (!m_selectedItems
.isEmpty()) {
245 const QSet
<int> previous
= m_selectedItems
;
248 current
.reserve(m_selectedItems
.count());
249 QSetIterator
<int> it(m_selectedItems
);
250 while (it
.hasNext()) {
251 const int index
= it
.next();
253 foreach (const KItemRange
& itemRange
, itemRanges
) {
254 if (index
< itemRange
.index
) {
257 inc
+= itemRange
.count
;
259 current
.insert(index
+ inc
);
262 if (current
!= previous
) {
263 m_selectedItems
= current
;
264 emit
selectionChanged(current
, previous
);
269 void KItemListSelectionManager::itemsRemoved(const KItemRangeList
& itemRanges
)
271 // Update the current item
272 if (m_currentItem
>= 0) {
273 int currentItem
= m_currentItem
;
274 foreach (const KItemRange
& itemRange
, itemRanges
) {
275 if (currentItem
< itemRange
.index
) {
278 if (currentItem
>= itemRange
.index
+ itemRange
.count
) {
279 currentItem
-= itemRange
.count
;
280 } else if (currentItem
>= m_model
->count()) {
281 currentItem
= m_model
->count() - 1;
284 setCurrentItem(currentItem
);
287 // Update the anchor item
288 if (m_anchorItem
>= 0) {
289 int anchorItem
= m_anchorItem
;
290 foreach (const KItemRange
& itemRange
, itemRanges
) {
291 if (anchorItem
< itemRange
.index
) {
294 if (anchorItem
>= itemRange
.index
+ itemRange
.count
) {
295 anchorItem
-= itemRange
.count
;
296 } else if (anchorItem
>= m_model
->count()) {
297 anchorItem
= m_model
->count() - 1;
300 setAnchorItem(anchorItem
);
303 // Update the selections
304 if (!m_selectedItems
.isEmpty()) {
305 const QSet
<int> previous
= m_selectedItems
;
308 current
.reserve(m_selectedItems
.count());
309 QSetIterator
<int> it(m_selectedItems
);
310 while (it
.hasNext()) {
311 int index
= it
.next();
313 foreach (const KItemRange
& itemRange
, itemRanges
) {
314 if (index
< itemRange
.index
) {
318 if (index
< itemRange
.index
+ itemRange
.count
) {
319 // The selection is part of the removed range
320 // and will get deleted
325 dec
+= itemRange
.count
;
329 current
.insert(index
);
333 if (current
!= previous
) {
334 m_selectedItems
= current
;
335 emit
selectionChanged(current
, previous
);
340 #include "kitemlistselectionmanager.moc"