/***************************************************************************
* Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * Copyright (C) 2011 by Frank Reininghaus <frank78ac@googlemail.com> *
* *
* Based on the Itemviews NG project from Trolltech Labs: *
* http://qt.gitorious.org/qt-labs/itemviews-ng *
m_currentItem(-1),
m_anchorItem(-1),
m_selectedItems(),
+ m_isAnchoredSelectionActive(false),
m_model(0)
{
}
void KItemListSelectionManager::setCurrentItem(int current)
{
const int previous = m_currentItem;
+ const QSet<int> previousSelection = selectedItems();
+
if (m_model && current >= 0 && current < m_model->count()) {
m_currentItem = current;
} else {
if (m_currentItem != previous) {
emit currentChanged(m_currentItem, previous);
+
+ if (m_isAnchoredSelectionActive) {
+ const QSet<int> selection = selectedItems();
+ if (selection != previousSelection) {
+ emit selectionChanged(selection, previousSelection);
+ }
+ }
}
}
QSet<int> KItemListSelectionManager::selectedItems() const
{
- return m_selectedItems;
+ QSet<int> selectedItems = m_selectedItems;
+
+ if (m_isAnchoredSelectionActive) {
+ const int from = qMin(m_anchorItem, m_currentItem);
+ const int to = qMax(m_anchorItem, m_currentItem);
+
+ for (int index = from; index <= to; index++) {
+ selectedItems.insert(index);
+ }
+ }
+
+ return selectedItems;
}
bool KItemListSelectionManager::hasSelection() const
{
- return !m_selectedItems.isEmpty();
+ return !m_selectedItems.isEmpty() || m_isAnchoredSelectionActive;
}
void KItemListSelectionManager::setSelected(int index, int count, SelectionMode mode)
return;
}
- const QSet<int> previous = m_selectedItems;
+ const QSet<int> previous = selectedItems();
count = qMin(count, m_model->count() - index);
break;
}
- if (m_selectedItems != previous) {
- emit selectionChanged(m_selectedItems, previous);
+ const QSet<int> selection = selectedItems();
+ if (selection != previous) {
+ emit selectionChanged(selection, previous);
}
}
void KItemListSelectionManager::clearSelection()
{
- if (!m_selectedItems.isEmpty()) {
- const QSet<int> previous = m_selectedItems;
+ const QSet<int> previous = selectedItems();
+ if (!previous.isEmpty()) {
m_selectedItems.clear();
- emit selectionChanged(m_selectedItems, previous);
+ m_isAnchoredSelectionActive = false;
+ emit selectionChanged(QSet<int>(), previous);
}
}
-void KItemListSelectionManager::beginAnchoredSelection(int anchor, SelectionMode mode)
+void KItemListSelectionManager::beginAnchoredSelection(int anchor)
{
- Q_UNUSED(anchor);
- Q_UNUSED(mode);
+ m_isAnchoredSelectionActive = true;
+ setAnchorItem(anchor);
}
void KItemListSelectionManager::endAnchoredSelection()
{
+ if (m_isAnchoredSelectionActive) {
+ const int from = qMin(m_anchorItem, m_currentItem);
+ const int to = qMax(m_anchorItem, m_currentItem);
+
+ for (int index = from; index <= to; index++) {
+ m_selectedItems.insert(index);
+ }
+
+ m_isAnchoredSelectionActive = false;
+ }
}
void KItemListSelectionManager::setAnchorItem(int anchor)
return m_anchorItem;
}
+bool KItemListSelectionManager::isAnchoredSelectionActive() const
+{
+ return m_isAnchoredSelectionActive;
+}
+
+void KItemListSelectionManager::setAnchoredSelectionActive(bool active)
+{
+ m_isAnchoredSelectionActive = active;
+}
+
KItemModelBase* KItemListSelectionManager::model() const
{
return m_model;
void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges)
{
+ // Store the current selection (needed in the selectionChanged() signal)
+ const QSet<int> previousSelection = selectedItems();
+
// Update the current item
if (m_currentItem < 0) {
setCurrentItem(0);
} else {
+ const int previousCurrent = m_currentItem;
int inc = 0;
foreach (const KItemRange& itemRange, itemRanges) {
if (m_currentItem < itemRange.index) {
}
inc += itemRange.count;
}
- setCurrentItem(m_currentItem + inc);
+ // Calling setCurrentItem would trigger the selectionChanged signal, but we want to
+ // emit it only once in this function -> change the current item manually and emit currentChanged
+ m_currentItem += inc;
+ emit currentChanged(m_currentItem, previousCurrent);
}
// Update the anchor item
if (m_anchorItem < 0) {
setAnchorItem(0);
} else {
+ const int previousAnchor = m_anchorItem;
int inc = 0;
foreach (const KItemRange& itemRange, itemRanges) {
if (m_anchorItem < itemRange.index) {
}
inc += itemRange.count;
}
- setAnchorItem(m_anchorItem + inc);
+ m_anchorItem += inc;
+ emit anchorChanged(m_anchorItem, previousAnchor);
}
// Update the selections
if (!m_selectedItems.isEmpty()) {
const QSet<int> previous = m_selectedItems;
-
- QSet<int> current;
- current.reserve(m_selectedItems.count());
- QSetIterator<int> it(m_selectedItems);
+ m_selectedItems.clear();
+ QSetIterator<int> it(previous);
while (it.hasNext()) {
const int index = it.next();
int inc = 0;
}
inc += itemRange.count;
}
- current.insert(index + inc);
+ m_selectedItems.insert(index + inc);
}
+ }
- if (current != previous) {
- m_selectedItems = current;
- emit selectionChanged(current, previous);
- }
+ const QSet<int> selection = selectedItems();
+ if (selection != previousSelection) {
+ emit selectionChanged(selection, previousSelection);
}
}
void KItemListSelectionManager::itemsRemoved(const KItemRangeList& itemRanges)
{
+ // Store the current selection (needed in the selectionChanged() signal)
+ const QSet<int> previousSelection = selectedItems();
+
// Update the current item
if (m_currentItem >= 0) {
+ const int previousCurrent = m_currentItem;
int currentItem = m_currentItem;
foreach (const KItemRange& itemRange, itemRanges) {
if (currentItem < itemRange.index) {
currentItem = m_model->count() - 1;
}
}
- setCurrentItem(currentItem);
+ // Calling setCurrentItem would trigger the selectionChanged signal, but we want to
+ // emit it only once in this function -> change the current item manually and emit currentChanged
+ m_currentItem = currentItem;
+ emit currentChanged(m_currentItem, previousCurrent);
}
// Update the anchor item
if (m_anchorItem >= 0) {
+ const int previousAnchor = m_anchorItem;
int anchorItem = m_anchorItem;
foreach (const KItemRange& itemRange, itemRanges) {
if (anchorItem < itemRange.index) {
anchorItem = m_model->count() - 1;
}
}
- setAnchorItem(anchorItem);
+ m_anchorItem = anchorItem;
+ emit anchorChanged(m_anchorItem, previousAnchor);
}
// Update the selections
if (!m_selectedItems.isEmpty()) {
const QSet<int> previous = m_selectedItems;
-
- QSet<int> current;
- current.reserve(m_selectedItems.count());
- QSetIterator<int> it(m_selectedItems);
+ m_selectedItems.clear();
+ QSetIterator<int> it(previous);
while (it.hasNext()) {
int index = it.next();
int dec = 0;
}
index -= dec;
if (index >= 0) {
- current.insert(index);
+ m_selectedItems.insert(index);
}
}
+ }
- if (current != previous) {
- m_selectedItems = current;
- emit selectionChanged(current, previous);
- }
+ const QSet<int> selection = selectedItems();
+ if (selection != previousSelection) {
+ emit selectionChanged(selection, previousSelection);
}
}