diff options
| author | Frank Reininghaus <[email protected]> | 2011-09-29 20:50:00 +0200 |
|---|---|---|
| committer | Frank Reininghaus <[email protected]> | 2011-09-29 20:50:00 +0200 |
| commit | 7424fcc3314a63d0716cb428a8b8de24b23e0279 (patch) | |
| tree | 3c51a6b755fa6eb27806e947dde63d93739b48d8 /src/kitemviews | |
| parent | e43f29576d4666a66cd4d236418baf403f176069 (diff) | |
Keep current item and selection when resorting, part 1
KFileItemModel now emits the itemsMoved signal when the model
is resorted, and KItemListSelectionManager has a new function
itemsMoved() which will be called indirectly when this signal
is emitted. Unit tests for the new functionality are included.
The following things are still needed to make the feature
work:
1. KFileItemMdel::resortAllItems() should not emit
itemsAdded/itemsRemoved any more.
2. KItemListView::itemsMoved() must update the view according
to the changes in the model, and it must call
KItemListSelectionManager::itemsMoved().
Diffstat (limited to 'src/kitemviews')
| -rw-r--r-- | src/kitemviews/kfileitemmodel.cpp | 20 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistselectionmanager.cpp | 46 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistselectionmanager.h | 1 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.cpp | 13 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.h | 1 | ||||
| -rw-r--r-- | src/kitemviews/kitemmodelbase.h | 17 |
6 files changed, 86 insertions, 12 deletions
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 7874d3025..0d6f60336 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -732,6 +732,8 @@ void KFileItemModel::resortAllItems() return; } + const KFileItemList oldSortedItems = m_sortedItems; + KFileItemList sortedItems = m_sortedItems; m_sortedItems.clear(); m_items.clear(); @@ -748,12 +750,28 @@ void KFileItemModel::resortAllItems() ++index; } + bool emitItemsMoved = false; + QList<int> movedToIndexes; + movedToIndexes.reserve(sortedItems.count()); + for (int i = 0; i < itemCount; i++) { + const int newIndex = m_items.value(oldSortedItems.at(i).url()); + movedToIndexes.append(newIndex); + if (!emitItemsMoved && newIndex != i) { + emitItemsMoved = true; + } + } + + if (emitItemsMoved) { + // TODO: + // * Implement KItemListView::slotItemsMoved() (which should call KItemListSelectionManager::itemsMoved()) + // * Do not emit itemsRemoved()/itemsInserted() here. + emit itemsMoved(KItemRange(0, itemCount), movedToIndexes); + } emit itemsInserted(KItemRangeList() << KItemRange(0, itemCount)); } void KFileItemModel::removeExpandedItems() { - KFileItemList expandedItems; const int maxIndex = m_data.count() - 1; diff --git a/src/kitemviews/kitemlistselectionmanager.cpp b/src/kitemviews/kitemlistselectionmanager.cpp index 63306a3f2..131ee46e6 100644 --- a/src/kitemviews/kitemlistselectionmanager.cpp +++ b/src/kitemviews/kitemlistselectionmanager.cpp @@ -239,6 +239,7 @@ void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges) 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(); @@ -307,6 +308,7 @@ void KItemListSelectionManager::itemsRemoved(const KItemRangeList& itemRanges) 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(); @@ -338,4 +340,48 @@ void KItemListSelectionManager::itemsRemoved(const KItemRangeList& itemRanges) } } +void KItemListSelectionManager::itemsMoved(const KItemRange& itemRange, const QList<int>& movedToIndexes) +{ + // Store the current selection (needed in the selectionChanged() signal) + const QSet<int> previousSelection = selectedItems(); + + // 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)); + } + else { + m_selectedItems.insert(index); + } + } + } + + const QSet<int> selection = selectedItems(); + if (selection != previousSelection) { + emit selectionChanged(selection, previousSelection); + } +} + #include "kitemlistselectionmanager.moc" diff --git a/src/kitemviews/kitemlistselectionmanager.h b/src/kitemviews/kitemlistselectionmanager.h index 8b3a121a6..a8ef5ca2d 100644 --- a/src/kitemviews/kitemlistselectionmanager.h +++ b/src/kitemviews/kitemlistselectionmanager.h @@ -73,6 +73,7 @@ private: void setModel(KItemModelBase* model); void itemsInserted(const KItemRangeList& itemRanges); void itemsRemoved(const KItemRangeList& itemRanges); + void itemsMoved(const KItemRange& itemRange, const QList<int>& movedToIndexes); private: int m_currentItem; diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 988a45d40..63315b665 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -762,6 +762,15 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) } } +void KItemListView::slotItemsMoved(const KItemRange& itemRange, const QList<int>& movedToIndexes) +{ + // TODO: + // * Implement KItemListView::slotItemsMoved() (which should call KItemListSelectionManager::itemsMoved()) + // * Do not emit itemsRemoved()/itemsInserted() in KFileItemModel::resortAllItems() + Q_UNUSED(itemRange); + Q_UNUSED(movedToIndexes); +} + void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges, const QSet<QByteArray>& roles) { @@ -1031,6 +1040,8 @@ void KItemListView::setModel(KItemModelBase* model) this, SLOT(slotItemsInserted(KItemRangeList))); disconnect(m_model, SIGNAL(itemsRemoved(KItemRangeList)), this, SLOT(slotItemsRemoved(KItemRangeList))); + disconnect(m_model, SIGNAL(itemsMoved(KItemRangeList,QList<int>)), + this, SLOT(slotItemsMoved(KItemRangeList,QList<int>))); } m_model = model; @@ -1044,6 +1055,8 @@ void KItemListView::setModel(KItemModelBase* model) this, SLOT(slotItemsInserted(KItemRangeList))); connect(m_model, SIGNAL(itemsRemoved(KItemRangeList)), this, SLOT(slotItemsRemoved(KItemRangeList))); + connect(m_model, SIGNAL(itemsMoved(KItemRangeList,QList<int>)), + this, SLOT(slotItemsMoved(KItemRangeList,QList<int>))); } onModelChanged(model, previous); diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 73b736bf7..e49dbe48d 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -246,6 +246,7 @@ protected: protected slots: virtual void slotItemsInserted(const KItemRangeList& itemRanges); virtual void slotItemsRemoved(const KItemRangeList& itemRanges); + virtual void slotItemsMoved(const KItemRange& itemRange, const QList<int>& movedToIndexes); virtual void slotItemsChanged(const KItemRangeList& itemRanges, const QSet<QByteArray>& roles); diff --git a/src/kitemviews/kitemmodelbase.h b/src/kitemviews/kitemmodelbase.h index 742bc2915..763a02efd 100644 --- a/src/kitemviews/kitemmodelbase.h +++ b/src/kitemviews/kitemmodelbase.h @@ -34,7 +34,7 @@ class QMimeData; struct KItemRange { - KItemRange(int index, int count); + KItemRange(int index = 0, int count = 0); int index; int count; @@ -180,20 +180,15 @@ signals: /** * Is emitted if one ore more items get moved. - * @param itemRanges Item-ranges that get moved to a new position. - * @param movedToIndexes New positions for each element of the item-ranges. + * @param itemRange Item-range that gets moved to a new position. + * @param movedToIndexes New positions for each element of the item-range. * * For example if the model has 10 items and the items 0 and 1 get exchanged * with the items 5 and 6 then the parameters look like this: - * - itemRanges: Contains two ranges. The first has the index 0 and a count of - * 2 and the second as the index 5 and a count of 2. - * - movedToIndexes: Contains the four values 5, 6, 0, 1 - * - * For the item-ranges it is assured that: - * - They don't overlap - * - The index of item-range n is smaller than the index of item-range n + 1. + * - itemRange: has the index 0 and a count of 7. + * - movedToIndexes: Contains the seven values 5, 6, 2, 3, 4, 0, 1 */ - void itemsMoved(const KItemRangeList& itemRanges, const QList<int> movedToIndexes); + void itemsMoved(const KItemRange& itemRange, const QList<int>& movedToIndexes); void itemsChanged(const KItemRangeList& itemRanges, const QSet<QByteArray>& roles); |
