***************************************************************************/
#include "kitemlistselectionmanager.h"
-
#include "kitemmodelbase.h"
#include <KDebug>
return selectedItems;
}
+bool KItemListSelectionManager::isSelected(int index) const
+{
+ if (m_selectedItems.contains(index)) {
+ return true;
+ }
+
+ if (m_isAnchoredSelectionActive && m_anchorItem != m_currentItem) {
+ Q_ASSERT(m_anchorItem >= 0);
+ Q_ASSERT(m_currentItem >= 0);
+ const int from = qMin(m_anchorItem, m_currentItem);
+ const int to = qMax(m_anchorItem, m_currentItem);
+
+ if (from <= index && index <= to) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool KItemListSelectionManager::hasSelection() const
{
return !m_selectedItems.isEmpty() || (m_isAnchoredSelectionActive && m_anchorItem != m_currentItem);
m_isAnchoredSelectionActive = false;
}
-int KItemListSelectionManager::anchorItem() const
-{
- return m_anchorItem;
-}
-
bool KItemListSelectionManager::isAnchoredSelectionActive() const
{
return m_isAnchoredSelectionActive;
if (!m_selectedItems.isEmpty()) {
const QSet<int> previous = m_selectedItems;
m_selectedItems.clear();
+ m_selectedItems.reserve(previous.count());
QSetIterator<int> it(previous);
while (it.hasNext()) {
const int index = it.next();
// 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) {
- break;
- }
- if (currentItem >= itemRange.index + itemRange.count) {
- currentItem -= itemRange.count;
- } else if (currentItem >= m_model->count()) {
- currentItem = m_model->count() - 1;
- }
- }
- // Calling setCurrentItem would trigger the selectionChanged signal, but we want to
+ // 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);
+ m_currentItem = indexAfterRangesRemoving(m_currentItem, itemRanges);
+ if (m_currentItem != previousCurrent) {
+ emit currentChanged(m_currentItem, previousCurrent);
+ }
+
+ if (m_currentItem < 0) {
+ // The current item has been removed.
+ m_currentItem = qMin(previousCurrent, m_model->count() - 1);
+ emit currentChanged(m_currentItem, -1);
+ }
}
// Update the anchor item
if (m_anchorItem >= 0) {
- int anchorItem = m_anchorItem;
- foreach (const KItemRange& itemRange, itemRanges) {
- if (anchorItem < itemRange.index) {
- break;
- }
- if (anchorItem >= itemRange.index + itemRange.count) {
- anchorItem -= itemRange.count;
- } else if (anchorItem >= m_model->count()) {
- anchorItem = m_model->count() - 1;
- }
- }
- m_anchorItem = anchorItem;
+ m_anchorItem = indexAfterRangesRemoving(m_anchorItem, itemRanges);
if (m_anchorItem < 0) {
m_isAnchoredSelectionActive = false;
}
}
- // Update the selections
+ // Update the selections and the anchor item
if (!m_selectedItems.isEmpty()) {
const QSet<int> previous = m_selectedItems;
m_selectedItems.clear();
+ m_selectedItems.reserve(previous.count());
QSetIterator<int> it(previous);
while (it.hasNext()) {
- int index = it.next();
- int dec = 0;
- foreach (const KItemRange& itemRange, itemRanges) {
- if (index < itemRange.index) {
- break;
- }
+ const int index = indexAfterRangesRemoving(it.next(), itemRanges);
+ if (index >= 0) {
+ m_selectedItems.insert(index);
+ }
+ }
+ }
- if (index < itemRange.index + itemRange.count) {
- // The selection is part of the removed range
- // and will get deleted
- index = -1;
- break;
- }
+ const QSet<int> selection = selectedItems();
+ if (selection != previousSelection) {
+ emit selectionChanged(selection, previousSelection);
+ }
+
+ Q_ASSERT(m_currentItem < m_model->count());
+ Q_ASSERT(m_anchorItem < m_model->count());
+}
+
+void KItemListSelectionManager::itemsMoved(const KItemRange& itemRange, const QList<int>& movedToIndexes)
+{
+ // Store the current selection (needed in the selectionChanged() signal)
+ const QSet<int> previousSelection = selectedItems();
- dec += itemRange.count;
+ // Update the current item
+ if (m_currentItem >= itemRange.index && m_currentItem < itemRange.index + itemRange.count) {
+ const int previousCurrentItem = m_currentItem;
+ const int newCurrentItem = movedToIndexes.at(previousCurrentItem - itemRange.index);
+
+ // 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 = newCurrentItem;
+ emit currentChanged(newCurrentItem, previousCurrentItem);
+ }
+
+ // Update the anchor item
+ if (m_anchorItem >= itemRange.index && m_anchorItem < itemRange.index + itemRange.count) {
+ m_anchorItem = movedToIndexes.at(m_anchorItem - itemRange.index);
+ }
+
+ // Update the selections
+ if (!m_selectedItems.isEmpty()) {
+ const QSet<int> previous = m_selectedItems;
+ m_selectedItems.clear();
+ m_selectedItems.reserve(previous.count());
+ QSetIterator<int> it(previous);
+ while (it.hasNext()) {
+ const int index = it.next();
+ if (index >= itemRange.index && index < itemRange.index + itemRange.count) {
+ m_selectedItems.insert(movedToIndexes.at(index - itemRange.index));
}
- index -= dec;
- if (index >= 0) {
+ else {
m_selectedItems.insert(index);
}
}
}
}
+int KItemListSelectionManager::indexAfterRangesRemoving(int index, const KItemRangeList& itemRanges) const
+{
+ int dec = 0;
+ foreach (const KItemRange& itemRange, itemRanges) {
+ if (index < itemRange.index) {
+ break;
+ }
+
+ if (index < itemRange.index + itemRange.count) {
+ // The index is part of the removed range
+ return -1;
+ }
+
+ dec += itemRange.count;
+ }
+ return index - dec;
+}
#include "kitemlistselectionmanager.moc"