]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Store the selected items in a more efficient way
authorFrank Reininghaus <frank78ac@googlemail.com>
Wed, 30 Oct 2013 22:21:09 +0000 (23:21 +0100)
committerFrank Reininghaus <frank78ac@googlemail.com>
Wed, 30 Oct 2013 22:22:23 +0000 (23:22 +0100)
Since Dolphin 2.0, we have stored the selected items in a QSet<int>,
which is neither space-efficient nor particularly fast when inserting
many items which are in a consecutive range.

This commit replaces the QSet<int> by a new class "KItemSet", which
stores the items in a sorted list of ranges. For each range, we only
store the first index and the length of the range, so we need a lot
less memory for most common selection patterns, and we also save quite
a few CPU cycles in many situations, because adding an item to the
KItemSet will in many cases not need a memory allocation at all, and
it's particularly easy when inserting sorted items into the KItemSet in
a row.

KItemSet contains a minimal subset of QSet's API which makes it
suitable as a drop-in replacement for our needs. It also has iterators,
such that the items can be iterated through easily, also with foreach.
One advantage of KItemSet compared to QSet<int> is that the items are
always iterated through in ascending order.

REVIEW: 113488

26 files changed:
src/CMakeLists.txt
src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemlistview.h
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistcontroller.h
src/kitemviews/kitemlistselectionmanager.cpp
src/kitemviews/kitemlistselectionmanager.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h
src/kitemviews/kitemlistviewaccessible.cpp
src/kitemviews/kitemmodelbase.cpp
src/kitemviews/kitemmodelbase.h
src/kitemviews/kitemset.cpp [new file with mode: 0644]
src/kitemviews/kitemset.h [new file with mode: 0644]
src/kitemviews/kstandarditemmodel.cpp
src/kitemviews/kstandarditemmodel.h
src/panels/places/placesitemmodel.cpp
src/panels/places/placesitemmodel.h
src/tests/CMakeLists.txt
src/tests/kitemlistcontrollertest.cpp
src/tests/kitemlistselectionmanagertest.cpp
src/tests/kitemsettest.cpp [new file with mode: 0644]
src/views/dolphinview.cpp
src/views/dolphinview.h

index 48ea14c18e9696267c60917eb9f3cc0edf9edd98..7710ddf928854b831ebdf1c5f47530a056bc68c6 100644 (file)
@@ -53,6 +53,7 @@ set(dolphinprivate_LIB_SRCS
     kitemviews/kitemlistviewaccessible.cpp
     kitemviews/kitemlistwidget.cpp
     kitemviews/kitemmodelbase.cpp
+    kitemviews/kitemset.cpp
     kitemviews/kstandarditem.cpp
     kitemviews/kstandarditemlistgroupheader.cpp
     kitemviews/kstandarditemlistwidget.cpp
index 8950c9a1ee4f65ce364f07ff7d5d33bfce938f62..fd01f2c4c23565827f7ed6b1e4aaf0e3b99f141e 100644 (file)
@@ -119,7 +119,7 @@ QStringList KFileItemListView::enabledPlugins() const
     return m_modelRolesUpdater ? m_modelRolesUpdater->enabledPlugins() : QStringList();
 }
 
-QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
+QPixmap KFileItemListView::createDragPixmap(const KItemSet& indexes) const
 {
     if (!model()) {
         return QPixmap();
@@ -165,10 +165,8 @@ QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
     QPainter painter(&dragPixmap);
     int x = 0;
     int y = 0;
-    QSetIterator<int> it(indexes);
-    while (it.hasNext()) {
-        const int index = it.next();
 
+    foreach (int index, indexes) {
         QPixmap pixmap = model()->data(index).value("iconPixmap").value<QPixmap>();
         if (pixmap.isNull()) {
             KIcon icon(model()->data(index).value("iconName").toString());
index bdc63b01bdb21bd8d6c8105f76ff9c3f81743e2a..2fd21edbfdda12e0c5e7b045f3774eb510191731 100644 (file)
@@ -73,7 +73,7 @@ public:
     QStringList enabledPlugins() const;
 
     /** @reimp */
-    virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
+    virtual QPixmap createDragPixmap(const KItemSet& indexes) const;
 
 protected:
     virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
index e2d0413a26b00baa6ac277cf0c7c140df692411a..261b23046dbfdccb0910b86e96f19f321617978e 100644 (file)
@@ -237,7 +237,7 @@ bool KFileItemModel::showDirectoriesOnly() const
     return m_dirLister->dirOnlyMode();
 }
 
-QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
+QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
 {
     QMimeData* data = new QMimeData();
 
@@ -248,9 +248,7 @@ QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
     KUrl::List mostLocalUrls;
     bool canUseMostLocalUrls = true;
 
-    QSetIterator<int> it(indexes);
-    while (it.hasNext()) {
-        const int index = it.next();
+    foreach (int index, indexes) {
         const KFileItem item = fileItem(index);
         if (!item.isNull()) {
             urls << item.targetUrl();
index 4b50477d985cbac05e05c2cbc5d1b0c3214cd1f6..c57329fc85051b153f0430e327bc2cdc1dccfded 100644 (file)
@@ -27,6 +27,7 @@
 #include <kitemviews/private/kfileitemmodelfilter.h>
 
 #include <QHash>
+#include <QSet>
 
 class KFileItemModelDirLister;
 class QTimer;
@@ -99,7 +100,7 @@ public:
     bool showDirectoriesOnly() const;
 
     /** @reimp */
-    virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
+    virtual QMimeData* createMimeData(const KItemSet& indexes) const;
 
     /** @reimp */
     virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
index befb09713ec9fd2c53b0efc03e6c5cb025a10aa6..51a1f91b91c1a257c1658fe6d3ae6bdb32088d13 100644 (file)
@@ -364,11 +364,11 @@ bool KItemListController::keyPressEvent(QKeyEvent* event)
 
     case Qt::Key_Enter:
     case Qt::Key_Return: {
-        const QSet<int> selectedItems = m_selectionManager->selectedItems();
+        const KItemSet selectedItems = m_selectionManager->selectedItems();
         if (selectedItems.count() >= 2) {
             emit itemsActivated(selectedItems);
         } else if (selectedItems.count() == 1) {
-            emit itemActivated(selectedItems.toList().first());
+            emit itemActivated(selectedItems.first());
         } else {
             emit itemActivated(index);
         }
@@ -378,14 +378,14 @@ bool KItemListController::keyPressEvent(QKeyEvent* event)
     case Qt::Key_Menu: {
         // Emit the signal itemContextMenuRequested() in case if at least one
         // item is selected. Otherwise the signal viewContextMenuRequested() will be emitted.
-        const QSet<int> selectedItems = m_selectionManager->selectedItems();
+        const KItemSet selectedItems = m_selectionManager->selectedItems();
         int index = -1;
         if (selectedItems.count() >= 2) {
             const int currentItemIndex = m_selectionManager->currentItem();
             index = selectedItems.contains(currentItemIndex)
-                    ? currentItemIndex : selectedItems.toList().first();
+                    ? currentItemIndex : selectedItems.first();
         } else if (selectedItems.count() == 1) {
-            index = selectedItems.toList().first();
+            index = selectedItems.first();
         }
 
         if (index >= 0) {
@@ -1079,7 +1079,7 @@ void KItemListController::slotRubberBandChanged()
         }
     }
 
-    QSet<int> selectedItems;
+    KItemSet selectedItems;
 
     // Select all visible items that intersect with the rubberband
     foreach (const KItemListWidget* widget, m_view->visibleItemListWidgets()) {
@@ -1127,7 +1127,7 @@ void KItemListController::slotRubberBandChanged()
         // Therefore, the new selection contains:
         // 1. All previously selected items which are not inside the rubberband, and
         // 2. all items inside the rubberband which have not been selected previously.
-        m_selectionManager->setSelectedItems((m_oldSelection - selectedItems) + (selectedItems - m_oldSelection));
+        m_selectionManager->setSelectedItems(m_oldSelection ^ selectedItems);
     }
     else {
         m_selectionManager->setSelectedItems(selectedItems + m_oldSelection);
@@ -1140,7 +1140,7 @@ void KItemListController::startDragging()
         return;
     }
 
-    const QSet<int> selectedItems = m_selectionManager->selectedItems();
+    const KItemSet selectedItems = m_selectionManager->selectedItems();
     if (selectedItems.isEmpty()) {
         return;
     }
index bb72856e0c1e053c8dc1cdb8d5e432f101a4ed9e..e9b70cddaf7dfc46659b5b37434b68a1f02394bf 100644 (file)
 
 #include <libdolphin_export.h>
 
+#include "kitemset.h"
+
 #include <QObject>
 #include <QPixmap>
 #include <QPointF>
-#include <QSet>
 
 class KItemModelBase;
 class KItemListKeyboardSearchManager;
@@ -129,7 +130,7 @@ public:
 
     /**
      * If set to true, the signals itemActivated() and itemsActivated() are emitted
-     * after a single-click of the left mouse button. If set to false (the default), 
+     * after a single-click of the left mouse button. If set to false (the default),
      * the setting from KGlobalSettings::singleClick() is used.
      */
     void setSingleClickActivationEnforced(bool singleClick);
@@ -165,7 +166,7 @@ signals:
      * Is emitted if more than one item has been activated by pressing Return/Enter
      * when having a selection.
      */
-    void itemsActivated(const QSet<int>& indexes);
+    void itemsActivated(const KItemSet& indexes);
 
     void itemMiddleClicked(int index);
 
@@ -326,7 +327,7 @@ private:
      * the current selection it is remembered in m_oldSelection before the
      * rubberband gets activated.
      */
-    QSet<int> m_oldSelection;
+    KItemSet m_oldSelection;
 
     /**
      * Assuming a view is given with a vertical scroll-orientation, grouped items and
index 833f7aad07f6d0e985f6fe6dfa59f5a5c8c0daf9..ebff1a30ed4604db4759bd40e6d06cacabd450ba 100644 (file)
@@ -43,7 +43,7 @@ KItemListSelectionManager::~KItemListSelectionManager()
 void KItemListSelectionManager::setCurrentItem(int current)
 {
     const int previous = m_currentItem;
-    const QSet<int> previousSelection = selectedItems();
+    const KItemSet previousSelection = selectedItems();
 
     if (m_model && current >= 0 && current < m_model->count()) {
         m_currentItem = current;
@@ -55,7 +55,7 @@ void KItemListSelectionManager::setCurrentItem(int current)
         emit currentChanged(m_currentItem, previous);
 
         if (m_isAnchoredSelectionActive) {
-            const QSet<int> selection = selectedItems();
+            const KItemSet selection = selectedItems();
             if (selection != previousSelection) {
                 emit selectionChanged(selection, previousSelection);
             }
@@ -68,18 +68,18 @@ int KItemListSelectionManager::currentItem() const
     return m_currentItem;
 }
 
-void KItemListSelectionManager::setSelectedItems(const QSet<int>& items)
+void KItemListSelectionManager::setSelectedItems(const KItemSet& items)
 {
     if (m_selectedItems != items) {
-        const QSet<int> previous = m_selectedItems;
+        const KItemSet previous = m_selectedItems;
         m_selectedItems = items;
         emit selectionChanged(m_selectedItems, previous);
     }
 }
 
-QSet<int> KItemListSelectionManager::selectedItems() const
+KItemSet KItemListSelectionManager::selectedItems() const
 {
-    QSet<int> selectedItems = m_selectedItems;
+    KItemSet selectedItems = m_selectedItems;
 
     if (m_isAnchoredSelectionActive && m_anchorItem != m_currentItem) {
         Q_ASSERT(m_anchorItem >= 0);
@@ -127,7 +127,7 @@ void KItemListSelectionManager::setSelected(int index, int count, SelectionMode
     }
 
     endAnchoredSelection();
-    const QSet<int> previous = selectedItems();
+    const KItemSet previous = selectedItems();
 
     count = qMin(count, m_model->count() - index);
 
@@ -160,7 +160,7 @@ void KItemListSelectionManager::setSelected(int index, int count, SelectionMode
         break;
     }
 
-    const QSet<int> selection = selectedItems();
+    const KItemSet selection = selectedItems();
     if (selection != previous) {
         emit selectionChanged(selection, previous);
     }
@@ -168,11 +168,11 @@ void KItemListSelectionManager::setSelected(int index, int count, SelectionMode
 
 void KItemListSelectionManager::clearSelection()
 {
-    const QSet<int> previous = selectedItems();
+    const KItemSet previous = selectedItems();
     if (!previous.isEmpty()) {
         m_selectedItems.clear();
         m_isAnchoredSelectionActive = false;
-        emit selectionChanged(QSet<int>(), previous);
+        emit selectionChanged(KItemSet(), previous);
     }
 }
 
@@ -221,7 +221,7 @@ void KItemListSelectionManager::setModel(KItemModelBase* model)
 void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges)
 {
     // Store the current selection (needed in the selectionChanged() signal)
-    const QSet<int> previousSelection = selectedItems();
+    const KItemSet previousSelection = selectedItems();
 
     // Update the current item
     if (m_currentItem < 0) {
@@ -257,12 +257,10 @@ void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges)
 
     // Update the selections
     if (!m_selectedItems.isEmpty()) {
-        const QSet<int> previous = m_selectedItems;
+        const KItemSet previous = m_selectedItems;
         m_selectedItems.clear();
-        m_selectedItems.reserve(previous.count());
-        QSetIterator<int> it(previous);
-        while (it.hasNext()) {
-            const int index = it.next();
+
+        foreach (int index, previous) {
             int inc = 0;
             foreach (const KItemRange& itemRange, itemRanges) {
                 if (index < itemRange.index) {
@@ -274,7 +272,7 @@ void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges)
         }
     }
 
-    const QSet<int> selection = selectedItems();
+    const KItemSet selection = selectedItems();
     if (selection != previousSelection) {
         emit selectionChanged(selection, previousSelection);
     }
@@ -283,7 +281,7 @@ void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges)
 void KItemListSelectionManager::itemsRemoved(const KItemRangeList& itemRanges)
 {
     // Store the current selection (needed in the selectionChanged() signal)
-    const QSet<int> previousSelection = selectedItems();
+    const KItemSet previousSelection = selectedItems();
     const int previousCurrent = m_currentItem;
 
     // Update the current item
@@ -308,19 +306,18 @@ void KItemListSelectionManager::itemsRemoved(const KItemRangeList& itemRanges)
 
     // Update the selections and the anchor item
     if (!m_selectedItems.isEmpty()) {
-        const QSet<int> previous = m_selectedItems;
+        const KItemSet previous = m_selectedItems;
         m_selectedItems.clear();
-        m_selectedItems.reserve(previous.count());
-        QSetIterator<int> it(previous);
-        while (it.hasNext()) {
-            const int index = indexAfterRangesRemoving(it.next(), itemRanges, DiscardRemovedIndex);
+
+        foreach (int oldIndex, previous) {
+            const int index = indexAfterRangesRemoving(oldIndex, itemRanges, DiscardRemovedIndex);
             if (index >= 0)  {
                 m_selectedItems.insert(index);
             }
         }
     }
 
-    const QSet<int> selection = selectedItems();
+    const KItemSet selection = selectedItems();
     if (selection != previousSelection) {
         emit selectionChanged(selection, previousSelection);
     }
@@ -332,7 +329,7 @@ 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();
+    const KItemSet previousSelection = selectedItems();
 
     // Update the current item
     if (m_currentItem >= itemRange.index && m_currentItem < itemRange.index + itemRange.count) {
@@ -352,12 +349,10 @@ void KItemListSelectionManager::itemsMoved(const KItemRange& itemRange, const QL
 
     // Update the selections
     if (!m_selectedItems.isEmpty()) {
-        const QSet<int> previous = m_selectedItems;
+        const KItemSet previous = m_selectedItems;
         m_selectedItems.clear();
-        m_selectedItems.reserve(previous.count());
-        QSetIterator<int> it(previous);
-        while (it.hasNext()) {
-            const int index = it.next();
+
+        foreach (int index, previous) {
             if (index >= itemRange.index && index < itemRange.index + itemRange.count) {
                 m_selectedItems.insert(movedToIndexes.at(index - itemRange.index));
             }
@@ -367,7 +362,7 @@ void KItemListSelectionManager::itemsMoved(const KItemRange& itemRange, const QL
         }
     }
 
-    const QSet<int> selection = selectedItems();
+    const KItemSet selection = selectedItems();
     if (selection != previousSelection) {
         emit selectionChanged(selection, previousSelection);
     }
index c89b8a4b85916655e48a7853eb889849ec2c8e16..c4decd39eb3d07e49058d73b6b30259c843a77e2 100644 (file)
@@ -26,9 +26,9 @@
 #include <libdolphin_export.h>
 
 #include <kitemviews/kitemmodelbase.h>
+#include <kitemviews/kitemset.h>
 
 #include <QObject>
-#include <QSet>
 
 class KItemModelBase;
 
@@ -57,8 +57,8 @@ public:
     void setCurrentItem(int current);
     int currentItem() const;
 
-    void setSelectedItems(const QSet<int>& items);
-    QSet<int> selectedItems() const;
+    void setSelectedItems(const KItemSet& items);
+    KItemSet selectedItems() const;
     bool isSelected(int index) const;
     bool hasSelection() const;
 
@@ -73,7 +73,7 @@ public:
 
 signals:
     void currentChanged(int current, int previous);
-    void selectionChanged(const QSet<int>& current, const QSet<int>& previous);
+    void selectionChanged(const KItemSet& current, const KItemSet& previous);
 
 private:
     void setModel(KItemModelBase* model);
@@ -91,7 +91,7 @@ private:
 private:
     int m_currentItem;
     int m_anchorItem;
-    QSet<int> m_selectedItems;
+    KItemSet m_selectedItems;
     bool m_isAnchoredSelectionActive;
 
     KItemModelBase* m_model;
index b3d805a917ef2c07be519c49acd33a3ce5f6ff8c..7f497210cdd5eb5abc8603319c950f3f374ad9ef 100644 (file)
@@ -609,12 +609,12 @@ KItemListHeader* KItemListView::header() const
     return m_header;
 }
 
-QPixmap KItemListView::createDragPixmap(const QSet<int>& indexes) const
+QPixmap KItemListView::createDragPixmap(const KItemSet& indexes) const
 {
     QPixmap pixmap;
 
     if (indexes.count() == 1) {
-        KItemListWidget* item = m_visibleItems.value(indexes.toList().first());
+        KItemListWidget* item = m_visibleItems.value(indexes.first());
         QGraphicsView* graphicsView = scene()->views()[0];
         if (item && graphicsView) {
             pixmap = item->createDragPixmap(0, graphicsView);
@@ -1305,7 +1305,7 @@ void KItemListView::slotCurrentChanged(int current, int previous)
     QAccessible::updateAccessibility(this, current+1, QAccessible::Focus);
 }
 
-void KItemListView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
+void KItemListView::slotSelectionChanged(const KItemSet& current, const KItemSet& previous)
 {
     Q_UNUSED(previous);
 
@@ -1502,7 +1502,7 @@ void KItemListView::setController(KItemListController* controller)
         if (previous) {
             KItemListSelectionManager* selectionManager = previous->selectionManager();
             disconnect(selectionManager, SIGNAL(currentChanged(int,int)), this, SLOT(slotCurrentChanged(int,int)));
-            disconnect(selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)), this, SLOT(slotSelectionChanged(QSet<int>,QSet<int>)));
+            disconnect(selectionManager, SIGNAL(selectionChanged(KItemSet,KItemSet)), this, SLOT(slotSelectionChanged(KItemSet,KItemSet)));
         }
 
         m_controller = controller;
@@ -1510,7 +1510,7 @@ void KItemListView::setController(KItemListController* controller)
         if (controller) {
             KItemListSelectionManager* selectionManager = controller->selectionManager();
             connect(selectionManager, SIGNAL(currentChanged(int,int)), this, SLOT(slotCurrentChanged(int,int)));
-            connect(selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)), this, SLOT(slotSelectionChanged(QSet<int>,QSet<int>)));
+            connect(selectionManager, SIGNAL(selectionChanged(KItemSet,KItemSet)), this, SLOT(slotSelectionChanged(KItemSet,KItemSet)));
         }
 
         onControllerChanged(controller, previous);
index 14360b02bb2d9bae20ed1f0c43a76bf31f356fce..dbe9230867610975e17e0b9607cd3f9e27dc03ae 100644 (file)
@@ -271,7 +271,7 @@ public:
      * @return Pixmap that is used for a drag operation based on the
      *         items given by \a indexes.
      */
-    virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
+    virtual QPixmap createDragPixmap(const KItemSet& indexes) const;
 
     /**
      * Lets the user edit the role \a role for item with the index \a index.
@@ -400,7 +400,7 @@ protected slots:
     virtual void slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
     virtual void slotSortRoleChanged(const QByteArray& current, const QByteArray& previous);
     virtual void slotCurrentChanged(int current, int previous);
-    virtual void slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous);
+    virtual void slotSelectionChanged(const KItemSet& current, const KItemSet& previous);
 
 private slots:
     void slotAnimationFinished(QGraphicsWidget* widget,
index 565c2151ec17c59fb50f4db0fb17763de524486c..d9ddd58f84045b9831b56ee74a601013250220b4 100644 (file)
@@ -109,7 +109,7 @@ int KItemListViewAccessible::rowCount() const
 
 int KItemListViewAccessible::selectedCellCount() const
 {
-    return view()->controller()->selectionManager()->selectedItems().size();
+    return view()->controller()->selectionManager()->selectedItems().count();
 }
 
 int KItemListViewAccessible::selectedColumnCount() const
index edce95ece937a3846d4a6dcb5e105d069989be43..4312640e41f423dac936958f44ebc20d3caaa3f8 100644 (file)
@@ -123,7 +123,7 @@ int KItemModelBase::expandedParentsCount(int index) const
     return 0;
 }
 
-QMimeData* KItemModelBase::createMimeData(const QSet<int>& indexes) const
+QMimeData* KItemModelBase::createMimeData(const KItemSet& indexes) const
 {
     Q_UNUSED(indexes);
     return 0;
index c5b9a0ca5f9a2bc146221c83c486753fd0c65e91..283cfa5523b363fbe72996b27c40b8c7f4ec1538 100644 (file)
 #include <libdolphin_export.h>
 
 #include <kitemviews/kitemrange.h>
+#include <kitemviews/kitemset.h>
 
 #include <QHash>
 #include <QObject>
-#include <QSet>
 #include <QVariant>
 
 class QMimeData;
@@ -149,7 +149,7 @@ public:
      *         caller of this method. The method must be implemented if dragging of
      *         items should be possible.
      */
-    virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
+    virtual QMimeData* createMimeData(const KItemSet& indexes) const;
 
     /**
      * @return Reimplement this to return the index for the first item
diff --git a/src/kitemviews/kitemset.cpp b/src/kitemviews/kitemset.cpp
new file mode 100644 (file)
index 0000000..f855368
--- /dev/null
@@ -0,0 +1,348 @@
+/***************************************************************************
+ *   Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.com>    *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "kitemset.h"
+
+#include <QVector>
+
+#include <algorithm>
+
+KItemSet::iterator KItemSet::insert(int i)
+{
+    if (m_itemRanges.empty()) {
+        m_itemRanges.push_back(KItemRange(i, 1));
+        return iterator(m_itemRanges.begin(), 0);
+    }
+
+    KItemRangeList::iterator rangeBegin = m_itemRanges.begin();
+    if (i < rangeBegin->index) {
+        // The inserted index is smaller than all existing items.
+        if (i == rangeBegin->index - 1) {
+            // Move the beginning of the first range one item to the front.
+            --rangeBegin->index;
+            ++rangeBegin->count;
+        } else {
+            // Insert a new range at the beginning.
+            rangeBegin = m_itemRanges.insert(rangeBegin, KItemRange(i, 1));
+        }
+
+        return iterator(rangeBegin, 0);
+    }
+
+    KItemRangeList::iterator rangeEnd = m_itemRanges.end();
+    KItemRangeList::iterator lastRange = rangeEnd - 1;
+    if (i >= lastRange->index) {
+        // i either belongs to the last range, or it is larger than all existing items.
+        const int lastItemPlus1 = lastRange->index + lastRange->count;
+        if (i == lastItemPlus1) {
+            // Move the end of the last range one item to the back.
+            ++lastRange->count;
+        } else if (i > lastItemPlus1) {
+            // Append a new range.
+            lastRange = m_itemRanges.insert(rangeEnd, KItemRange(i, 1));
+        }
+
+        return iterator(lastRange, i - lastRange->index);
+    }
+
+    // We know that i is between the smallest existing item and the first item
+    // of the last range. Find the lowest range whose 'index' is smaller than i.
+    KItemRangeList::iterator low = rangeBegin;
+    KItemRangeList::iterator high = lastRange;
+
+    while (low + 1 != high) {
+        const int span = high - low;
+        Q_ASSERT(span >= 2);
+
+        KItemRangeList::iterator mid = low + span / 2;
+        if (mid->index > i) {
+            high = mid;
+        } else {
+            low = mid;
+        }
+    }
+
+    Q_ASSERT(low->index <= i && high->index > i);
+
+    if (i == low->index + low->count) {
+        // i is just one item behind the range low.
+        if (i == high->index - 1) {
+            // i closes the gap between low and high. Merge the two ranges.
+            const int newRangeCount = low->count + 1 + high->count;
+            KItemRangeList::iterator behindNewRange = m_itemRanges.erase(high);
+            KItemRangeList::iterator newRange = behindNewRange - 1;
+            newRange->count = newRangeCount;
+            return iterator(newRange, i - newRange->index);
+        } else {
+            // Extend low by one item.
+            ++low->count;
+            return iterator(low, low->count - 1);
+        }
+    } else if (i > low->index + low->count) {
+        if (i == high->index - 1) {
+            // Extend high by one item to the front.
+            --high->index;
+            ++high->count;
+            return iterator(high, 0);
+        } else {
+            // Insert a new range between low and high.
+            KItemRangeList::iterator newRange = m_itemRanges.insert(high, KItemRange(i, 1));
+            return iterator(newRange, 0);
+        }
+    } else {
+        // The range low already contains i.
+        return iterator(low, i - low->index);
+    }
+}
+
+KItemSet::iterator KItemSet::erase(iterator it)
+{
+    KItemRangeList::iterator rangeIt = it.m_rangeIt;
+
+    if (it.m_offset == 0) {
+        // Removed index is at the beginning of a range.
+        if (rangeIt->count > 1) {
+            ++rangeIt->index;
+            --rangeIt->count;
+        } else {
+            // The range only contains the removed index.
+            rangeIt = m_itemRanges.erase(rangeIt);
+        }
+        return iterator(rangeIt, 0);
+    } else if (it.m_offset == rangeIt->count - 1) {
+        // Removed index is at the end of a range.
+        --rangeIt->count;
+        ++rangeIt;
+        return iterator(rangeIt, 0);
+    } else {
+        // The removed index is in the middle of a range.
+        const int newRangeIndex = *it + 1;
+        const int newRangeCount = rangeIt->count - it.m_offset - 1;
+        const KItemRange newRange(newRangeIndex, newRangeCount);
+
+        rangeIt->count = it.m_offset;
+        ++rangeIt;
+        rangeIt = m_itemRanges.insert(rangeIt, newRange);
+
+        return iterator(rangeIt, 0);
+    }
+}
+
+KItemSet KItemSet::operator+(const KItemSet& other) const
+{
+    KItemSet sum;
+
+    KItemRangeList::const_iterator it1 = m_itemRanges.constBegin();
+    KItemRangeList::const_iterator it2 = other.m_itemRanges.constBegin();
+
+    const KItemRangeList::const_iterator end1 = m_itemRanges.constEnd();
+    const KItemRangeList::const_iterator end2 = other.m_itemRanges.constEnd();
+
+    while (it1 != end1 || it2 != end2) {
+        if (it1 == end1) {
+            // We are past the end of 'this' already. Append all remaining
+            // item ranges from 'other'.
+            while (it2 != end2) {
+                sum.m_itemRanges.append(*it2);
+                ++it2;
+            }
+        } else if (it2 == end2) {
+            // We are past the end of 'other' already. Append all remaining
+            // item ranges from 'this'.
+            while (it1 != end1) {
+                sum.m_itemRanges.append(*it1);
+                ++it1;
+            }
+        } else {
+            // Find the beginning of the next range.
+            int index = qMin(it1->index, it2->index);
+            int count = 0;
+
+            do {
+                if (it1 != end1 && it1->index <= index + count) {
+                    // The next range from 'this' overlaps with the current range in the sum.
+                    count = qMax(count, it1->index + it1->count - index);
+                    ++it1;
+                }
+
+                if (it2 != end2 && it2->index <= index + count) {
+                    // The next range from 'other' overlaps with the current range in the sum.
+                    count = qMax(count, it2->index + it2->count - index);
+                    ++it2;
+                }
+            } while ((it1 != end1 && it1->index <= index + count)
+                    || (it2 != end2 && it2->index <= index + count));
+
+            sum.m_itemRanges.append(KItemRange(index, count));
+        }
+    }
+
+    return sum;
+}
+
+KItemSet KItemSet::operator^(const KItemSet& other) const
+{
+    // We are looking for all ints which are either in *this or in other,
+    // but not in both.
+    KItemSet result;
+
+    // When we go through all integers from INT_MIN to INT_MAX and start
+    // in the state "do not add to result", every beginning/end of a range
+    // of *this and other toggles the "add/do not add to result" state.
+    // Therefore, we just have to put ints where any range starts/ends to
+    // a sorted array, and then we can calculate the result quite easily.
+    QVector<int> rangeBoundaries;
+    rangeBoundaries.resize(2 * (m_itemRanges.count() + other.m_itemRanges.count()));
+    const QVector<int>::iterator begin = rangeBoundaries.begin();
+    const QVector<int>::iterator end = rangeBoundaries.end();
+    QVector<int>::iterator it = begin;
+
+    foreach (const KItemRange& range, m_itemRanges) {
+        *it++ = range.index;
+        *it++ = range.index + range.count;
+    }
+
+    const QVector<int>::iterator middle = it;
+
+    foreach (const KItemRange& range, other.m_itemRanges) {
+        *it++ = range.index;
+        *it++ = range.index + range.count;
+    }
+    Q_ASSERT(it == end);
+
+    std::inplace_merge(begin, middle, end);
+
+    it = begin;
+    while (it != end) {
+        const int rangeBegin = *it;
+        ++it;
+
+        if (*it == rangeBegin) {
+            // It seems that ranges from both *this and other start at
+            // rangeBegin. Do not start a new range, but read the next int.
+            //
+            // Example: Consider the symmetric difference of the sets
+            // {1, 2, 3, 4} and {1, 2}. The sorted list of range boundaries is
+            // 1 1 3 5. Discarding the duplicate 1 yields the result
+            // rangeBegin = 3, rangeEnd = 5, which corresponds to the set {3, 4}.
+            ++it;
+        } else {
+            // The end of the current range is the next *single* int that we
+            // find. If an int appears twice in rangeBoundaries, the range does
+            // not end.
+            //
+            // Example: Consider the symmetric difference of the sets
+            // {1, 2, 3, 4, 8, 9, 10} and {5, 6, 7}. The sorted list of range
+            // boundaries is 1 5 5 8 8 11, and discarding all duplicates yields
+            // the result rangeBegin = 1, rangeEnd = 11, which corresponds to
+            // the set {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}.
+            bool foundEndOfRange = false;
+            int rangeEnd;
+            do {
+                rangeEnd = *it;
+                ++it;
+
+                if (it == end || *it != rangeEnd) {
+                    foundEndOfRange = true;
+                } else {
+                    ++it;
+                }
+            } while (!foundEndOfRange);
+
+            result.m_itemRanges.append(KItemRange(rangeBegin, rangeEnd - rangeBegin));
+        }
+    }
+
+    return result;
+}
+
+bool KItemSet::isValid() const
+{
+    const KItemRangeList::const_iterator begin = m_itemRanges.constBegin();
+    const KItemRangeList::const_iterator end = m_itemRanges.constEnd();
+
+    for (KItemRangeList::const_iterator it = begin; it != end; ++it) {
+        if (it->count <= 0) {
+            return false;
+        }
+
+        if (it != begin) {
+            const KItemRangeList::const_iterator previous = it - 1;
+            if (previous->index + previous->count >= it->index) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+KItemRangeList::iterator KItemSet::rangeForItem(int i)
+{
+    const KItemRangeList::iterator end = m_itemRanges.end();
+    KItemRangeList::iterator low = m_itemRanges.begin();
+    KItemRangeList::iterator high = end;
+
+    if (low == end || low->index > i) {
+        return end;
+    }
+
+    while (low != high && low + 1 != high) {
+        KItemRangeList::iterator mid = low + (high - low) / 2;
+        if (mid->index > i) {
+            high = mid;
+        } else {
+            low = mid;
+        }
+    }
+
+    Q_ASSERT(low->index <= i);
+    if (low->index + low->count > i) {
+        return low;
+    }
+
+    return end;
+}
+
+KItemRangeList::const_iterator KItemSet::constRangeForItem(int i) const
+{
+    const KItemRangeList::const_iterator end = m_itemRanges.constEnd();
+    KItemRangeList::const_iterator low = m_itemRanges.constBegin();
+    KItemRangeList::const_iterator high = end;
+
+    if (low == end || low->index > i) {
+        return end;
+    }
+
+    while (low != high && low + 1 != high) {
+        KItemRangeList::const_iterator mid = low + (high - low) / 2;
+        if (mid->index > i) {
+            high = mid;
+        } else {
+            low = mid;
+        }
+    }
+
+    Q_ASSERT(low->index <= i);
+    if (low->index + low->count > i) {
+        return low;
+    }
+
+    return end;
+}
diff --git a/src/kitemviews/kitemset.h b/src/kitemviews/kitemset.h
new file mode 100644 (file)
index 0000000..385010f
--- /dev/null
@@ -0,0 +1,413 @@
+/***************************************************************************
+ *   Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.com>    *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef KITEMSET_H
+#define KITEMSET_H
+
+#include <kitemviews/kitemrange.h>
+
+/**
+ * @brief Stores a set of integer numbers in a space-efficient way.
+ *
+ * This class is similar to QSet<int>, but it has the following advantages:
+ *
+ * 1. It uses less memory than a QSet<int> if many consecutive numbers are
+ *    stored. This is achieved by not storing each number separately, but
+ *    "ranges" of numbers.
+ *
+ *    Example: The set {1, 2, 3, 4, 5} is represented by a single range which
+ *    starts at 1 and has the length 5.
+ *
+ * 2. When iterating through a KItemSet using KItemSet::iterator or
+ *    KItemSet::const_iterator, the numbers are traversed in ascending order.
+ *
+ * The complexity of most operations depends on the number of ranges.
+ */
+
+class KItemSet
+{
+public:
+    KItemSet();
+    KItemSet(const KItemSet& other);
+
+    /**
+     * Returns the number of items in the set.
+     * Complexity: O(log(number of ranges)).
+     */
+    int count() const;
+
+    bool isEmpty() const;
+    void clear();
+
+    bool operator==(const KItemSet& other) const;
+    bool operator!=(const KItemSet& other) const;
+
+    class iterator
+    {
+        iterator(const KItemRangeList::iterator& rangeIt, int offset) :
+            m_rangeIt(rangeIt),
+            m_offset(offset)
+        {
+        }
+
+    public:
+        iterator(const iterator& other) :
+            m_rangeIt(other.m_rangeIt),
+            m_offset(other.m_offset)
+        {
+        }
+
+        iterator& operator=(const iterator& other)
+        {
+            m_rangeIt = other.m_rangeIt;
+            m_offset = other.m_offset;
+            return *this;
+        }
+
+        int operator*() const
+        {
+            return m_rangeIt->index + m_offset;
+        }
+
+        inline bool operator==(const iterator& other) const
+        {
+            return m_rangeIt == other.m_rangeIt && m_offset == other.m_offset;
+        }
+
+        inline bool operator!=(const iterator& other) const
+        {
+            return !(*this == other);
+        }
+
+        inline iterator& operator++()
+        {
+            ++m_offset;
+
+            if (m_offset == m_rangeIt->count) {
+                ++m_rangeIt;
+                m_offset = 0;
+            }
+
+            return *this;
+        }
+
+        inline iterator operator++(int)
+        {
+            iterator r = *this;
+            ++(*this);
+            return r;
+        }
+
+        inline iterator& operator--()
+        {
+            if (m_offset == 0) {
+                --m_rangeIt;
+                m_offset = m_rangeIt->count - 1;
+            } else {
+                --m_offset;
+            }
+
+            return *this;
+        }
+
+        inline iterator operator--(int)
+        {
+            iterator r = *this;
+            --(*this);
+            return r;
+        }
+
+    private:
+        KItemRangeList::iterator m_rangeIt;
+        int m_offset;
+
+        friend class const_iterator;
+        friend class KItemSet;
+    };
+
+
+    class const_iterator
+    {
+        const_iterator(KItemRangeList::const_iterator rangeIt, int offset) :
+            m_rangeIt(rangeIt),
+            m_offset(offset)
+        {
+        }
+
+    public:
+        const_iterator(const const_iterator& other) :
+            m_rangeIt(other.m_rangeIt),
+            m_offset(other.m_offset)
+        {
+        }
+
+        const_iterator(const iterator& other) :
+            m_rangeIt(other.m_rangeIt),
+            m_offset(other.m_offset)
+        {
+        }
+
+        const_iterator& operator=(const const_iterator& other)
+        {
+            m_rangeIt = other.m_rangeIt;
+            m_offset = other.m_offset;
+            return *this;
+        }
+
+        int operator*() const
+        {
+            return m_rangeIt->index + m_offset;
+        }
+
+        inline bool operator==(const const_iterator& other) const
+        {
+            return m_rangeIt == other.m_rangeIt && m_offset == other.m_offset;
+        }
+
+        inline bool operator!=(const const_iterator& other) const
+        {
+            return !(*this == other);
+        }
+
+        inline const_iterator& operator++()
+        {
+            ++m_offset;
+
+            if (m_offset == m_rangeIt->count) {
+                ++m_rangeIt;
+                m_offset = 0;
+            }
+
+            return *this;
+        }
+
+        inline const_iterator operator++(int)
+        {
+            const_iterator r = *this;
+            ++(*this);
+            return r;
+        }
+
+        inline const_iterator& operator--()
+        {
+            if (m_offset == 0) {
+                --m_rangeIt;
+                m_offset = m_rangeIt->count - 1;
+            } else {
+                --m_offset;
+            }
+
+            return *this;
+        }
+
+        inline const_iterator operator--(int)
+        {
+            const_iterator r = *this;
+            --(*this);
+            return r;
+        }
+
+    private:
+        KItemRangeList::const_iterator m_rangeIt;
+        int m_offset;
+
+        friend class KItemSet;
+    };
+
+    iterator begin();
+    const_iterator begin() const;
+    const_iterator constBegin() const;
+    iterator end();
+    const_iterator end() const;
+    const_iterator constEnd() const;
+
+    int first() const;
+    int last() const;
+
+    bool contains(int i) const;
+    iterator insert(int i);
+    iterator find(int i);
+    const_iterator constFind(int i) const;
+    bool remove(int i);
+    iterator erase(iterator it);
+
+    /**
+     * Returns a new set which contains all items that are contained in this
+     * KItemSet, in \a other, or in both.
+     */
+    KItemSet operator+(const KItemSet& other) const;
+
+    /**
+     * Returns a new set which contains all items that are contained either in
+     * this KItemSet, or in \a other, but not in both (the symmetric difference
+     * of both KItemSets).
+     */
+    KItemSet operator^(const KItemSet& other) const;
+
+    KItemSet& operator<<(int i);
+
+private:
+    /**
+     * Returns true if the KItemSet is valid, and false otherwise.
+     * A valid KItemSet must store the item ranges in ascending order, and
+     * the ranges must not overlap.
+     */
+    bool isValid() const;
+
+    /**
+     * This function returns an iterator that points to the KItemRange which
+     * contains i, or m_itemRanges.end() if no such range exists.
+     */
+    KItemRangeList::iterator rangeForItem(int i);
+
+    /**
+     * This function returns an iterator that points to the KItemRange which
+     * contains i, or m_itemRanges.constEnd() if no such range exists.
+     */
+    KItemRangeList::const_iterator constRangeForItem(int i) const;
+
+    KItemRangeList m_itemRanges;
+
+    friend class KItemSetTest;
+};
+
+inline KItemSet::KItemSet() :
+    m_itemRanges()
+{
+}
+
+inline KItemSet::KItemSet(const KItemSet& other) :
+    m_itemRanges(other.m_itemRanges)
+{
+}
+
+inline int KItemSet::count() const
+{
+    int result = 0;
+    foreach (const KItemRange& range, m_itemRanges) {
+        result += range.count;
+    }
+    return result;
+}
+
+inline bool KItemSet::isEmpty() const
+{
+    return m_itemRanges.isEmpty();
+}
+
+inline void KItemSet::clear()
+{
+    m_itemRanges.clear();
+}
+
+inline bool KItemSet::operator==(const KItemSet& other) const
+{
+    return m_itemRanges == other.m_itemRanges;
+}
+
+inline bool KItemSet::operator!=(const KItemSet& other) const
+{
+    return m_itemRanges != other.m_itemRanges;
+}
+
+inline bool KItemSet::contains(int i) const
+{
+    const KItemRangeList::const_iterator it = constRangeForItem(i);
+    return it != m_itemRanges.end();
+}
+
+inline KItemSet::iterator KItemSet::find(int i)
+{
+    const KItemRangeList::iterator it = rangeForItem(i);
+    if (it != m_itemRanges.end()) {
+        return iterator(it, i - it->index);
+    } else {
+        return end();
+    }
+}
+
+inline KItemSet::const_iterator KItemSet::constFind(int i) const
+{
+    const KItemRangeList::const_iterator it = constRangeForItem(i);
+    if (it != m_itemRanges.constEnd()) {
+        return const_iterator(it, i - it->index);
+    } else {
+        return constEnd();
+    }
+}
+
+inline bool KItemSet::remove(int i)
+{
+    iterator it = find(i);
+    if (it != end()) {
+        erase(it);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+inline KItemSet::iterator KItemSet::begin()
+{
+    return iterator(m_itemRanges.begin(), 0);
+}
+
+inline KItemSet::const_iterator KItemSet::begin() const
+{
+    return const_iterator(m_itemRanges.begin(), 0);
+}
+
+inline KItemSet::const_iterator KItemSet::constBegin() const
+{
+    return const_iterator(m_itemRanges.constBegin(), 0);
+}
+
+inline KItemSet::iterator KItemSet::end()
+{
+    return iterator(m_itemRanges.end(), 0);
+}
+
+inline KItemSet::const_iterator KItemSet::end() const
+{
+    return const_iterator(m_itemRanges.end(), 0);
+}
+
+inline KItemSet::const_iterator KItemSet::constEnd() const
+{
+    return const_iterator(m_itemRanges.constEnd(), 0);
+}
+
+inline int KItemSet::first() const
+{
+    return m_itemRanges.first().index;
+}
+
+inline int KItemSet::last() const
+{
+    const KItemRange& lastRange = m_itemRanges.last();
+    return lastRange.index + lastRange.count - 1;
+}
+
+inline KItemSet& KItemSet::operator<<(int i)
+{
+    insert(i);
+    return *this;
+}
+
+#endif
index 959d62cb8ad55a643f9263c25ea1c97570489d41..e8c1b6204293d65f01b478599ade9d13847ea940 100644 (file)
@@ -175,7 +175,7 @@ bool KStandardItemModel::setData(int index, const QHash<QByteArray, QVariant>& v
     return true;
 }
 
-QMimeData* KStandardItemModel::createMimeData(const QSet<int>& indexes) const
+QMimeData* KStandardItemModel::createMimeData(const KItemSet& indexes) const
 {
     Q_UNUSED(indexes);
     return 0;
index 0debd6a6fccc3e5c6a78b62f374fce3012e3ee7b..721e155299862f91a2c3e9bbd4999d92611401b8 100644 (file)
@@ -72,7 +72,7 @@ public:
     virtual int count() const;
     virtual QHash<QByteArray, QVariant> data(int index) const;
     virtual bool setData(int index, const QHash<QByteArray, QVariant>& values);
-    virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
+    virtual QMimeData* createMimeData(const KItemSet& indexes) const;
     virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
     virtual bool supportsDropping(int index) const;
     virtual QString roleDescription(const QByteArray& role) const;
index eae2095c994ff37fe78fb8dc9a82a1be2cdda644..681479dfbad0ea0ae43883f252a764ff95d4511b 100644 (file)
@@ -377,7 +377,7 @@ void PlacesItemModel::requestStorageSetup(int index)
     }
 }
 
-QMimeData* PlacesItemModel::createMimeData(const QSet<int>& indexes) const
+QMimeData* PlacesItemModel::createMimeData(const KItemSet& indexes) const
 {
     KUrl::List urls;
     QByteArray itemData;
index 693836033265e2978f6981d9a10b05d37ef117ff..cd37e7353583d288fcf602935144bc48394442de 100644 (file)
@@ -118,7 +118,7 @@ public:
     void requestStorageSetup(int index);
 
     /** @reimp */
-    virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
+    virtual QMimeData* createMimeData(const KItemSet& indexes) const;
 
     /** @reimp */
     virtual bool supportsDropping(int index) const;
index dd761fc90b0113f81359e30a2fd2531a146e314a..9b152ed07d4f3be36f80e59a38a3e93979e4e14a 100644 (file)
@@ -3,11 +3,21 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BUILD_DIR}/.
 
 # needed on windows to correctly use the files from dolphinprivate
 add_definitions(-DLIBDOLPHINPRIVATE_EXPORT=)
+
+# KItemSetTest
+set(kitemsettest_SRCS
+    kitemsettest.cpp
+    ../kitemviews/kitemset.cpp
+)
+kde4_add_unit_test(kitemsettest TEST ${kitemsettest_SRCS})
+target_link_libraries(kitemsettest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY})
+
 # KItemListSelectionManagerTest
 set(kitemlistselectionmanagertest_SRCS
     kitemlistselectionmanagertest.cpp
     ../kitemviews/kitemlistselectionmanager.cpp
     ../kitemviews/kitemmodelbase.cpp
+    ../kitemviews/kitemset.cpp
 )
 kde4_add_unit_test(kitemlistselectionmanagertest TEST ${kitemlistselectionmanagertest_SRCS})
 target_link_libraries(kitemlistselectionmanagertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY})
@@ -24,6 +34,7 @@ set(kitemlistcontrollertest_SRCS
     ../kitemviews/kitemlistcontainer.cpp
     ../kitemviews/kitemlistwidget.cpp
     ../kitemviews/kitemlistviewaccessible.cpp
+    ../kitemviews/kitemset.cpp
     ../kitemviews/kstandarditemlistview.cpp
     ../kitemviews/kstandarditemlistwidget.cpp
 )
@@ -41,6 +52,7 @@ set(kfileitemlistviewtest_SRCS
     ../kitemviews/kitemlistviewaccessible.cpp
     ../kitemviews/kitemlistcontainer.cpp
     ../kitemviews/kitemlistwidget.cpp
+    ../kitemviews/kitemset.cpp
     ../kitemviews/kstandarditemlistview.cpp
     ../kitemviews/kstandarditemlistwidget.cpp
 )
index 60e93e539abc9f87926ba7c9c0dcbf36440a4569..7dd37bf0a3d60f78e5e56ec888d43ffe0db59073 100644 (file)
@@ -41,7 +41,7 @@ namespace {
 Q_DECLARE_METATYPE(KFileItemListView::ItemLayout);
 Q_DECLARE_METATYPE(Qt::Orientation);
 Q_DECLARE_METATYPE(KItemListController::SelectionBehavior);
-Q_DECLARE_METATYPE(QSet<int>);
+Q_DECLARE_METATYPE(KItemSet);
 
 class KItemListControllerTest : public QObject
 {
@@ -81,7 +81,7 @@ private:
  */
 void KItemListControllerTest::initTestCase()
 {
-    qRegisterMetaType<QSet<int> >("QSet<int>");
+    qRegisterMetaType<KItemSet>("KItemSet");
 
     m_testDir = new TestDir();
     m_model = new KFileItemModel();
@@ -159,14 +159,14 @@ struct KeyPress {
  */
 struct ViewState {
 
-    ViewState(int current, const QSet<int> selection, bool activated = false) :
+    ViewState(int current, const KItemSet selection, bool activated = false) :
         m_current(current),
         m_selection(selection),
         m_activated(activated)
     {}
 
     int m_current;
-    QSet<int> m_selection;
+    KItemSet m_selection;
     bool m_activated;
 };
 
@@ -262,34 +262,34 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                     // First, key presses which should have the same effect
                     // for any layout and any number of columns.
                     testList
-                        << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet<int>() << 1))
-                        << qMakePair(KeyPress(Qt::Key_Return), ViewState(1, QSet<int>() << 1, true))
-                        << qMakePair(KeyPress(Qt::Key_Enter), ViewState(1, QSet<int>() << 1, true))
-                        << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet<int>() << 2))
-                        << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet<int>() << 2 << 3))
-                        << qMakePair(KeyPress(Qt::Key_Return), ViewState(3, QSet<int>() << 2 << 3, true))
-                        << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, QSet<int>() << 2))
-                        << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet<int>() << 2 << 3))
-                        << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet<int>() << 2 << 3))
-                        << qMakePair(KeyPress(Qt::Key_Return), ViewState(4, QSet<int>() << 2 << 3, true))
-                        << qMakePair(KeyPress(previousItemKey), ViewState(3, QSet<int>() << 3))
-                        << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, QSet<int>() << 0 << 1 << 2 << 3))
-                        << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, QSet<int>() << 0 << 1 << 2 << 3))
-                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet<int>() << 0 << 2 << 3))
-                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet<int>() << 0 << 1 << 2 << 3))
-                        << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet<int>() << 19))
-                        << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, QSet<int>() << 18 << 19))
-                        << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0))
-                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, QSet<int>()))
-                        << qMakePair(KeyPress(Qt::Key_Enter), ViewState(0, QSet<int>(), true))
-                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, QSet<int>() << 0))
-                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, QSet<int>()))
-                        << qMakePair(KeyPress(Qt::Key_Space), ViewState(0, QSet<int>() << 0))
-                        << qMakePair(KeyPress(Qt::Key_E), ViewState(13, QSet<int>() << 13))
-                        << qMakePair(KeyPress(Qt::Key_Space), ViewState(14, QSet<int>() << 14))
-                        << qMakePair(KeyPress(Qt::Key_3), ViewState(15, QSet<int>() << 15))
-                        << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0))
-                        << qMakePair(KeyPress(Qt::Key_Escape), ViewState(0, QSet<int>()));
+                        << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet() << 1))
+                        << qMakePair(KeyPress(Qt::Key_Return), ViewState(1, KItemSet() << 1, true))
+                        << qMakePair(KeyPress(Qt::Key_Enter), ViewState(1, KItemSet() << 1, true))
+                        << qMakePair(KeyPress(nextItemKey), ViewState(2, KItemSet() << 2))
+                        << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3))
+                        << qMakePair(KeyPress(Qt::Key_Return), ViewState(3, KItemSet() << 2 << 3, true))
+                        << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, KItemSet() << 2))
+                        << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3))
+                        << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, KItemSet() << 2 << 3))
+                        << qMakePair(KeyPress(Qt::Key_Return), ViewState(4, KItemSet() << 2 << 3, true))
+                        << qMakePair(KeyPress(previousItemKey), ViewState(3, KItemSet() << 3))
+                        << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, KItemSet() << 0 << 1 << 2 << 3))
+                        << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 1 << 2 << 3))
+                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 2 << 3))
+                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, KItemSet() << 0 << 1 << 2 << 3))
+                        << qMakePair(KeyPress(Qt::Key_End), ViewState(19, KItemSet() << 19))
+                        << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, KItemSet() << 18 << 19))
+                        << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0))
+                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet()))
+                        << qMakePair(KeyPress(Qt::Key_Enter), ViewState(0, KItemSet(), true))
+                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet() << 0))
+                        << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(0, KItemSet()))
+                        << qMakePair(KeyPress(Qt::Key_Space), ViewState(0, KItemSet() << 0))
+                        << qMakePair(KeyPress(Qt::Key_E), ViewState(13, KItemSet() << 13))
+                        << qMakePair(KeyPress(Qt::Key_Space), ViewState(14, KItemSet() << 14))
+                        << qMakePair(KeyPress(Qt::Key_3), ViewState(15, KItemSet() << 15))
+                        << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0))
+                        << qMakePair(KeyPress(Qt::Key_Escape), ViewState(0, KItemSet()));
 
                     // Next, we test combinations of key presses which only work for a
                     // particular number of columns and either enabled or disabled grouping.
@@ -297,12 +297,12 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                     // One column.
                     if (columnCount == 1) {
                         testList
-                            << qMakePair(KeyPress(nextRowKey), ViewState(1, QSet<int>() << 1))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(2, QSet<int>() << 1 << 2))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ControlModifier), ViewState(3, QSet<int>() << 1 << 2))
-                            << qMakePair(KeyPress(previousRowKey), ViewState(2, QSet<int>() << 2))
-                            << qMakePair(KeyPress(previousItemKey), ViewState(1, QSet<int>() << 1))
-                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0));
+                            << qMakePair(KeyPress(nextRowKey), ViewState(1, KItemSet() << 1))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(2, KItemSet() << 1 << 2))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ControlModifier), ViewState(3, KItemSet() << 1 << 2))
+                            << qMakePair(KeyPress(previousRowKey), ViewState(2, KItemSet() << 2))
+                            << qMakePair(KeyPress(previousItemKey), ViewState(1, KItemSet() << 1))
+                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
                     }
 
                     // Multiple columns: we test both 3 and 5 columns with grouping
@@ -321,26 +321,26 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                         // e3 e4 e5 | 15 16 17
                         // e6 e7    | 18 19
                         testList
-                            << qMakePair(KeyPress(nextRowKey), ViewState(3, QSet<int>() << 3))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet<int>() << 3))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(7, QSet<int>() << 7))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(8, QSet<int>() << 7 << 8))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(9, QSet<int>() << 7 << 8 << 9))
-                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(8, QSet<int>() << 7 << 8))
-                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(7, QSet<int>() << 7))
-                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(6, QSet<int>() << 6 << 7))
-                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(5, QSet<int>() << 5 << 6 << 7))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(6, QSet<int>() << 6 << 7))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(7, QSet<int>() << 7))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(10, QSet<int>() << 10))
-                            << qMakePair(KeyPress(nextItemKey), ViewState(11, QSet<int>() << 11))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(14, QSet<int>() << 14))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(17, QSet<int>() << 17))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet<int>() << 19))
-                            << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet<int>() << 17))
-                            << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet<int>() << 19))
-                            << qMakePair(KeyPress(previousRowKey), ViewState(16, QSet<int>() << 16))
-                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0));
+                            << qMakePair(KeyPress(nextRowKey), ViewState(3, KItemSet() << 3))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, KItemSet() << 3))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(7, KItemSet() << 7))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(8, KItemSet() << 7 << 8))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(9, KItemSet() << 7 << 8 << 9))
+                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(8, KItemSet() << 7 << 8))
+                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 7))
+                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 6 << 7))
+                            << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(5, KItemSet() << 5 << 6 << 7))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 6 << 7))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 7))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(10, KItemSet() << 10))
+                            << qMakePair(KeyPress(nextItemKey), ViewState(11, KItemSet() << 11))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(14, KItemSet() << 14))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(17, KItemSet() << 17))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 19))
+                            << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 17))
+                            << qMakePair(KeyPress(Qt::Key_End), ViewState(19, KItemSet() << 19))
+                            << qMakePair(KeyPress(previousRowKey), ViewState(16, KItemSet() << 16))
+                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
                     }
 
                     if (columnCount == 5 && !groupingEnabled) {
@@ -351,17 +351,17 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                         // d2 d3 d4 e1 e2 | 10 11 12 13 14
                         // e3 e4 e5 e6 e7 | 15 16 17 18 19
                         testList
-                            << qMakePair(KeyPress(nextRowKey), ViewState(5, QSet<int>() << 5))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(6, QSet<int>() << 5))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(11, QSet<int>() << 11))
-                            << qMakePair(KeyPress(nextItemKey), ViewState(12, QSet<int>() << 12))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(17, QSet<int>() << 12 << 13 << 14 << 15 << 16 << 17))
-                            << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(12, QSet<int>() << 12))
-                            << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(7, QSet<int>() << 7 << 8 << 9 << 10 << 11 << 12))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(12, QSet<int>() << 12))
-                            << qMakePair(KeyPress(Qt::Key_End, Qt::ControlModifier), ViewState(19, QSet<int>() << 12))
-                            << qMakePair(KeyPress(previousRowKey), ViewState(14, QSet<int>() << 14))
-                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0));
+                            << qMakePair(KeyPress(nextRowKey), ViewState(5, KItemSet() << 5))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(6, KItemSet() << 5))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(11, KItemSet() << 11))
+                            << qMakePair(KeyPress(nextItemKey), ViewState(12, KItemSet() << 12))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(17, KItemSet() << 12 << 13 << 14 << 15 << 16 << 17))
+                            << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(12, KItemSet() << 12))
+                            << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(7, KItemSet() << 7 << 8 << 9 << 10 << 11 << 12))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(12, KItemSet() << 12))
+                            << qMakePair(KeyPress(Qt::Key_End, Qt::ControlModifier), ViewState(19, KItemSet() << 12))
+                            << qMakePair(KeyPress(previousRowKey), ViewState(14, KItemSet() << 14))
+                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
                     }
 
                     if (columnCount == 3 && groupingEnabled) {
@@ -377,19 +377,19 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                         // e4 e5 e6 | 16 17 18
                         // e7       | 19
                         testList
-                            << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet<int>() << 1))
-                            << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet<int>() << 2))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, QSet<int>() << 2 << 3))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(6, QSet<int>() << 2 << 3 << 4 << 5 << 6))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(8, QSet<int>() << 8))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(11, QSet<int>() << 11))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(12, QSet<int>() << 11))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(13, QSet<int>() << 13))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(16, QSet<int>() << 16))
-                            << qMakePair(KeyPress(nextItemKey), ViewState(17, QSet<int>() << 17))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet<int>() << 19))
-                            << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet<int>() << 17))
-                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0));
+                            << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet() << 1))
+                            << qMakePair(KeyPress(nextItemKey), ViewState(2, KItemSet() << 2))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 2 << 3))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(6, KItemSet() << 2 << 3 << 4 << 5 << 6))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(8, KItemSet() << 8))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(11, KItemSet() << 11))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(12, KItemSet() << 11))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(13, KItemSet() << 13))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(16, KItemSet() << 16))
+                            << qMakePair(KeyPress(nextItemKey), ViewState(17, KItemSet() << 17))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 19))
+                            << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 17))
+                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
                     }
 
                     if (columnCount == 5 && groupingEnabled) {
@@ -402,19 +402,19 @@ void KItemListControllerTest::testKeyboardNavigation_data()
                         // e1 e2 e3 e4 e5 | 13 14 15 16 17
                         // e6 e7          | 18 19
                         testList
-                            << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet<int>() << 1))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, QSet<int>() << 1 << 2 << 3))
-                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(5, QSet<int>() << 1 << 2 << 3 << 4 << 5))
-                            << qMakePair(KeyPress(nextItemKey), ViewState(6, QSet<int>() << 6))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(7, QSet<int>() << 6))
-                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(8, QSet<int>() << 6))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(12, QSet<int>() << 12))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(17, QSet<int>() << 17))
-                            << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet<int>() << 19))
-                            << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet<int>() << 17))
-                            << qMakePair(KeyPress(Qt::Key_End, Qt::ShiftModifier), ViewState(19, QSet<int>() << 17 << 18 << 19))
-                            << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(14, QSet<int>() << 14 << 15 << 16 << 17))
-                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet<int>() << 0));
+                            << qMakePair(KeyPress(nextItemKey), ViewState(1, KItemSet() << 1))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, KItemSet() << 1 << 2 << 3))
+                            << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(5, KItemSet() << 1 << 2 << 3 << 4 << 5))
+                            << qMakePair(KeyPress(nextItemKey), ViewState(6, KItemSet() << 6))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(7, KItemSet() << 6))
+                            << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(8, KItemSet() << 6))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(12, KItemSet() << 12))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(17, KItemSet() << 17))
+                            << qMakePair(KeyPress(nextRowKey), ViewState(19, KItemSet() << 19))
+                            << qMakePair(KeyPress(previousRowKey), ViewState(17, KItemSet() << 17))
+                            << qMakePair(KeyPress(Qt::Key_End, Qt::ShiftModifier), ViewState(19, KItemSet() << 17 << 18 << 19))
+                            << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(14, KItemSet() << 14 << 15 << 16 << 17))
+                            << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, KItemSet() << 0));
                     }
 
                     const QString testName =
@@ -470,14 +470,14 @@ void KItemListControllerTest::testKeyboardNavigation()
     QCOMPARE(m_view->m_layouter->m_columnCount, columnCount);
 
     QSignalSpy spySingleItemActivated(m_controller, SIGNAL(itemActivated(int)));
-    QSignalSpy spyMultipleItemsActivated(m_controller, SIGNAL(itemsActivated(QSet<int>)));
+    QSignalSpy spyMultipleItemsActivated(m_controller, SIGNAL(itemsActivated(KItemSet)));
 
     while (!testList.isEmpty()) {
         const QPair<KeyPress, ViewState> test = testList.takeFirst();
         const Qt::Key key = test.first.m_key;
         const Qt::KeyboardModifiers modifier = test.first.m_modifier;
         const int current = test.second.m_current;
-        const QSet<int> selection = test.second.m_selection;
+        const KItemSet selection = test.second.m_selection;
         const bool activated = test.second.m_activated;
 
         QTest::keyClick(m_container, key, modifier);
@@ -485,7 +485,7 @@ void KItemListControllerTest::testKeyboardNavigation()
         QCOMPARE(m_selectionManager->currentItem(), current);
         switch (selectionBehavior) {
         case KItemListController::NoSelection: QVERIFY(m_selectionManager->selectedItems().isEmpty()); break;
-        case KItemListController::SingleSelection: QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << current); break;
+        case KItemListController::SingleSelection: QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << current); break;
         case KItemListController::MultiSelection: QCOMPARE(m_selectionManager->selectedItems(), selection); break;
         }
 
@@ -496,12 +496,12 @@ void KItemListControllerTest::testKeyboardNavigation()
                     // The selected items should be activated.
                     if (selection.count() == 1) {
                         QVERIFY(!spySingleItemActivated.isEmpty());
-                        QCOMPARE(qvariant_cast<int>(spySingleItemActivated.takeFirst().at(0)), selection.toList().at(0));
+                        QCOMPARE(qvariant_cast<int>(spySingleItemActivated.takeFirst().at(0)), selection.first());
                         QVERIFY(spyMultipleItemsActivated.isEmpty());
                     } else {
                         QVERIFY(spySingleItemActivated.isEmpty());
                         QVERIFY(!spyMultipleItemsActivated.isEmpty());
-                        QCOMPARE(qvariant_cast<QSet<int> >(spyMultipleItemsActivated.takeFirst().at(0)), selection);
+                        QCOMPARE(qvariant_cast<KItemSet>(spyMultipleItemsActivated.takeFirst().at(0)), selection);
                     }
                     break;
                 }
@@ -641,7 +641,7 @@ void KItemListControllerTest::testMouseClickActivation()
     group.writeEntry("SingleClick", restoreKGlobalSettingsSingleClick, KConfig::Persistent|KConfig::Global);
     config.sync();
     KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE);
-    
+
     iterations = 0;
     while (KGlobalSettings::singleClick() != restoreKGlobalSettingsSingleClick && iterations < maxIterations) {
         QTest::qWait(50);
index 302985a5f4c72a0696d1f837a8d5ea1e95c6c643..af2610d8c2248e172546c82bddfe1d2a931070f1 100644 (file)
@@ -80,7 +80,7 @@ private slots:
     void testDeleteCurrentItem();
 
 private:
-    void verifySelectionChange(QSignalSpy& spy, const QSet<int>& currentSelection, const QSet<int>& previousSelection) const;
+    void verifySelectionChange(QSignalSpy& spy, const KItemSet& currentSelection, const KItemSet& previousSelection) const;
 
     KItemListSelectionManager* m_selectionManager;
     DummyModel* m_model;
@@ -127,7 +127,7 @@ void KItemListSelectionManagerTest::testCurrentItemAnchorItem()
     QCOMPARE(m_selectionManager->m_anchorItem, 5);
 
     // Items between current and anchor should be selected now
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 4 << 5);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 4 << 5);
     QVERIFY(m_selectionManager->hasSelection());
 
     // Change current item again and check the selection
@@ -138,7 +138,7 @@ void KItemListSelectionManagerTest::testCurrentItemAnchorItem()
     QCOMPARE(qvariant_cast<int>(spyCurrent.at(0).at(1)), 4);
     spyCurrent.takeFirst();
 
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 2 << 3 << 4 << 5);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 2 << 3 << 4 << 5);
     QVERIFY(m_selectionManager->hasSelection());
 
     // Inserting items should update current item and anchor item.
@@ -155,7 +155,7 @@ void KItemListSelectionManagerTest::testCurrentItemAnchorItem()
 
     QCOMPARE(m_selectionManager->m_anchorItem, 8);
 
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6 << 7 << 8);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6 << 7 << 8);
     QVERIFY(m_selectionManager->hasSelection());
 
     // Removing items should update current item and anchor item.
@@ -172,12 +172,12 @@ void KItemListSelectionManagerTest::testCurrentItemAnchorItem()
 
     QCOMPARE(m_selectionManager->m_anchorItem, 5);
 
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 2 << 3 << 4 << 5);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 2 << 3 << 4 << 5);
     QVERIFY(m_selectionManager->hasSelection());
 
     // Verify that clearSelection() also clears the anchored selection.
     m_selectionManager->clearSelection();
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>());
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet());
     QVERIFY(!m_selectionManager->hasSelection());
 
     m_selectionManager->endAnchoredSelection();
@@ -212,7 +212,7 @@ void KItemListSelectionManagerTest::testItemsInserted()
 {
     // Select items 10 to 12
     m_selectionManager->setSelected(10, 3);
-    QSet<int> selectedItems = m_selectionManager->selectedItems();
+    KItemSet selectedItems = m_selectionManager->selectedItems();
     QCOMPARE(selectedItems.count(), 3);
     QVERIFY(selectedItems.contains(10));
     QVERIFY(selectedItems.contains(11));
@@ -242,7 +242,7 @@ void KItemListSelectionManagerTest::testItemsRemoved()
 {
     // Select items 10 to 15
     m_selectionManager->setSelected(10, 6);
-    QSet<int> selectedItems = m_selectionManager->selectedItems();
+    KItemSet selectedItems = m_selectionManager->selectedItems();
     QCOMPARE(selectedItems.count(), 6);
     for (int i = 10; i <= 15; ++i) {
         QVERIFY(selectedItems.contains(i));
@@ -276,20 +276,20 @@ void KItemListSelectionManagerTest::testAnchoredSelection()
 
     m_selectionManager->setCurrentItem(6);
     QCOMPARE(m_selectionManager->currentItem(), 6);
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6);
 
     m_selectionManager->setCurrentItem(4);
     QCOMPARE(m_selectionManager->currentItem(), 4);
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 4 << 5);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 4 << 5);
 
     m_selectionManager->setCurrentItem(7);
     QCOMPARE(m_selectionManager->currentItem(), 7);
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6 << 7);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6 << 7);
 
     // Ending the anchored selection should not change the selected items.
     m_selectionManager->endAnchoredSelection();
     QVERIFY(!m_selectionManager->isAnchoredSelectionActive());
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6 << 7);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6 << 7);
 
     // Start a new anchored selection that overlaps the previous one
     m_selectionManager->beginAnchoredSelection(9);
@@ -298,15 +298,15 @@ void KItemListSelectionManagerTest::testAnchoredSelection()
 
     m_selectionManager->setCurrentItem(6);
     QCOMPARE(m_selectionManager->currentItem(), 6);
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6 << 7 << 8 << 9);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6 << 7 << 8 << 9);
 
     m_selectionManager->setCurrentItem(10);
     QCOMPARE(m_selectionManager->currentItem(), 10);
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6 << 7 << 9 << 10);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6 << 7 << 9 << 10);
 
     m_selectionManager->endAnchoredSelection();
     QVERIFY(!m_selectionManager->isAnchoredSelectionActive());
-    QCOMPARE(m_selectionManager->selectedItems(), QSet<int>() << 5 << 6 << 7 << 9 << 10);
+    QCOMPARE(m_selectionManager->selectedItems(), KItemSet() << 5 << 6 << 7 << 9 << 10);
 }
 
 namespace {
@@ -320,7 +320,7 @@ namespace {
     };
 }
 
-Q_DECLARE_METATYPE(QSet<int>);
+Q_DECLARE_METATYPE(KItemSet);
 Q_DECLARE_METATYPE(ChangeType);
 Q_DECLARE_METATYPE(KItemRange);
 Q_DECLARE_METATYPE(KItemRangeList);
@@ -355,86 +355,86 @@ Q_DECLARE_METATYPE(QList<int>);
 
 void KItemListSelectionManagerTest::testChangeSelection_data()
 {
-    QTest::addColumn<QSet<int> >("initialSelection");
+    QTest::addColumn<KItemSet>("initialSelection");
     QTest::addColumn<int>("anchor");
     QTest::addColumn<int>("current");
-    QTest::addColumn<QSet<int> >("expectedSelection");
+    QTest::addColumn<KItemSet>("expectedSelection");
     QTest::addColumn<ChangeType>("changeType");
     QTest::addColumn<QList<QVariant> >("data");
-    QTest::addColumn<QSet<int> >("finalSelection");
+    QTest::addColumn<KItemSet>("finalSelection");
 
     QTest::newRow("No change")
-        << (QSet<int>() << 5 << 6)
+        << (KItemSet() << 5 << 6)
         << 2 << 3
-        << (QSet<int>() << 2 << 3 << 5 << 6)
+        << (KItemSet() << 2 << 3 << 5 << 6)
         << NoChange
         << QList<QVariant>()
-        << (QSet<int>() << 2 << 3 << 5 << 6);
+        << (KItemSet() << 2 << 3 << 5 << 6);
 
     QTest::newRow("Insert Items")
-        << (QSet<int>() << 5 << 6)
+        << (KItemSet() << 5 << 6)
         << 2 << 3
-        << (QSet<int>() << 2 << 3 << 5 << 6)
+        << (KItemSet() << 2 << 3 << 5 << 6)
         << InsertItems
         << (QList<QVariant>() << QVariant::fromValue(KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 2) << KItemRange(10, 5)))
-        << (QSet<int>() << 3 << 4 << 8 << 9);
+        << (KItemSet() << 3 << 4 << 8 << 9);
 
     QTest::newRow("Remove Items")
-        << (QSet<int>() << 5 << 6)
+        << (KItemSet() << 5 << 6)
         << 2 << 3
-        << (QSet<int>() << 2 << 3 << 5 << 6)
+        << (KItemSet() << 2 << 3 << 5 << 6)
         << RemoveItems
         << (QList<QVariant>() << QVariant::fromValue(KItemRangeList() << KItemRange(1, 1) << KItemRange(3, 1) << KItemRange(10, 5)))
-        << (QSet<int>() << 1 << 2 << 3 << 4);
+        << (KItemSet() << 1 << 2 << 3 << 4);
 
     QTest::newRow("Empty Anchored Selection")
-        << QSet<int>()
+        << KItemSet()
         << 2 << 2
-        << QSet<int>()
+        << KItemSet()
         << EndAnchoredSelection
         << QList<QVariant>()
-        << QSet<int>();
+        << KItemSet();
 
     QTest::newRow("Toggle selection")
-        << (QSet<int>() << 1 << 3 << 4)
+        << (KItemSet() << 1 << 3 << 4)
         << 6 << 8
-        << (QSet<int>() << 1 << 3 << 4 << 6 << 7 << 8)
+        << (KItemSet() << 1 << 3 << 4 << 6 << 7 << 8)
         << SetSelected
         << (QList<QVariant>() << 0 << 10 << QVariant::fromValue(KItemListSelectionManager::Toggle))
-        << (QSet<int>() << 0 << 2 << 5 << 9);
+        << (KItemSet() << 0 << 2 << 5 << 9);
 
     // Swap items 2, 3 and 4, 5
     QTest::newRow("Move items")
-        << (QSet<int>() << 0 << 1 << 2 << 3)
+        << (KItemSet() << 0 << 1 << 2 << 3)
         << -1 << -1
-        << (QSet<int>() << 0 << 1 << 2 << 3)
+        << (KItemSet() << 0 << 1 << 2 << 3)
         << MoveItems
         << (QList<QVariant>() << QVariant::fromValue(KItemRange(2, 4))
                               << QVariant::fromValue(QList<int>() << 4 << 5 << 2 << 3))
-        << (QSet<int>() << 0 << 1 << 4 << 5);
+        << (KItemSet() << 0 << 1 << 4 << 5);
 
     // Revert sort order
     QTest::newRow("Revert sort order")
-        << (QSet<int>() << 0 << 1)
+        << (KItemSet() << 0 << 1)
         << 3 << 4
-        << (QSet<int>() << 0 << 1 << 3 << 4)
+        << (KItemSet() << 0 << 1 << 3 << 4)
         << MoveItems
         << (QList<QVariant>() << QVariant::fromValue(KItemRange(0, 10))
                               << QVariant::fromValue(QList<int>() << 9 << 8 << 7 << 6 << 5 << 4 << 3 << 2 << 1 << 0))
-        << (QSet<int>() << 5 << 6 << 8 << 9);
+        << (KItemSet() << 5 << 6 << 8 << 9);
 }
 
 void KItemListSelectionManagerTest::testChangeSelection()
 {
-    QFETCH(QSet<int>, initialSelection);
+    QFETCH(KItemSet, initialSelection);
     QFETCH(int, anchor);
     QFETCH(int, current);
-    QFETCH(QSet<int>, expectedSelection);
+    QFETCH(KItemSet, expectedSelection);
     QFETCH(ChangeType, changeType);
     QFETCH(QList<QVariant>, data);
-    QFETCH(QSet<int>, finalSelection);
+    QFETCH(KItemSet, finalSelection);
 
-    QSignalSpy spySelectionChanged(m_selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)));
+    QSignalSpy spySelectionChanged(m_selectionManager, SIGNAL(selectionChanged(KItemSet,KItemSet)));
 
     // Initial selection should be empty
     QVERIFY(!m_selectionManager->hasSelection());
@@ -443,7 +443,7 @@ void KItemListSelectionManagerTest::testChangeSelection()
     // Perform the initial selectiion
     m_selectionManager->setSelectedItems(initialSelection);
 
-    verifySelectionChange(spySelectionChanged, initialSelection, QSet<int>());
+    verifySelectionChange(spySelectionChanged, initialSelection, KItemSet());
 
     // Perform an anchored selection.
     // Note that current and anchor index are equal first because this is the case in typical uses of the
@@ -486,7 +486,7 @@ void KItemListSelectionManagerTest::testChangeSelection()
     // Finally, clear the selection
     m_selectionManager->clearSelection();
 
-    verifySelectionChange(spySelectionChanged, QSet<int>(), finalSelection);
+    verifySelectionChange(spySelectionChanged, KItemSet(), finalSelection);
 }
 
 void KItemListSelectionManagerTest::testDeleteCurrentItem_data()
@@ -520,8 +520,8 @@ void KItemListSelectionManagerTest::testDeleteCurrentItem()
 }
 
 void KItemListSelectionManagerTest::verifySelectionChange(QSignalSpy& spy,
-                                                          const QSet<int>& currentSelection,
-                                                          const QSet<int>& previousSelection) const
+                                                          const KItemSet& currentSelection,
+                                                          const KItemSet& previousSelection) const
 {
     QCOMPARE(m_selectionManager->selectedItems(), currentSelection);
     QCOMPARE(m_selectionManager->hasSelection(), !currentSelection.isEmpty());
@@ -540,8 +540,8 @@ void KItemListSelectionManagerTest::verifySelectionChange(QSignalSpy& spy,
     else {
         QCOMPARE(spy.count(), 1);
         QList<QVariant> arguments = spy.takeFirst();
-        QCOMPARE(qvariant_cast<QSet<int> >(arguments.at(0)), currentSelection);
-        QCOMPARE(qvariant_cast<QSet<int> >(arguments.at(1)), previousSelection);
+        QCOMPARE(qvariant_cast<KItemSet>(arguments.at(0)), currentSelection);
+        QCOMPARE(qvariant_cast<KItemSet>(arguments.at(1)), previousSelection);
     }
 }
 
diff --git a/src/tests/kitemsettest.cpp b/src/tests/kitemsettest.cpp
new file mode 100644 (file)
index 0000000..2832596
--- /dev/null
@@ -0,0 +1,612 @@
+/***************************************************************************
+ *   Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.com>    *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include <qtest_kde.h>
+
+#include "kitemviews/kitemset.h"
+
+#include <QVector>
+
+Q_DECLARE_METATYPE(KItemRangeList);
+
+/**
+ * Converts a KItemRangeList to a KItemSet.
+ */
+KItemSet KItemRangeList2KItemSet(const KItemRangeList& itemRanges)
+{
+    KItemSet result;
+    foreach (const KItemRange& range, itemRanges) {
+        for (int i = range.index; i < range.index + range.count; ++i) {
+            result.insert(i);
+        }
+    }
+    return result;
+}
+
+/**
+ * Converts a KItemRangeList to a QSet<int>.
+ */
+QSet<int> KItemRangeList2QSet(const KItemRangeList& itemRanges)
+{
+    QSet<int> result;
+    foreach (const KItemRange& range, itemRanges) {
+        for (int i = range.index; i < range.index + range.count; ++i) {
+            result.insert(i);
+        }
+    }
+    return result;
+}
+
+/**
+ * Converts a KItemRangeList to a QVector<int>.
+ */
+QVector<int> KItemRangeList2QVector(const KItemRangeList& itemRanges)
+{
+    QVector<int> result;
+    foreach (const KItemRange& range, itemRanges) {
+        for (int i = range.index; i < range.index + range.count; ++i) {
+            result.append(i);
+        }
+    }
+    return result;
+}
+
+/**
+ * Converts a KItemSet to a QSet<int>.
+ */
+static QSet<int> KItemSet2QSet(const KItemSet& itemSet)
+{
+    QSet<int> result;
+    foreach (int i, itemSet) {
+        result.insert(i);
+    }
+
+    // Check that the conversion was successful.
+    Q_ASSERT(itemSet.count() == result.count());
+
+    foreach (int i, itemSet) {
+        Q_ASSERT(result.contains(i));
+    }
+
+    foreach (int i, result) {
+        Q_ASSERT(itemSet.contains(i));
+    }
+
+    return result;
+}
+
+
+/**
+ * The main test class.
+ */
+class KItemSetTest : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void initTestCase();
+
+    void testConstruction_data();
+    void testConstruction();
+    void testIterators_data();
+    void testIterators();
+    void testFind_data();
+    void testFind();
+    void testChangingOneItem_data();
+    void testChangingOneItem();
+    void testAddSets_data();
+    void testAddSets();
+    /*
+    void testSubtractSets_data();
+    void testSubtractSets();
+    */
+    void testSymmetricDifference_data();
+    void testSymmetricDifference();
+
+private:
+    QHash<const char*, KItemRangeList> m_testCases;
+};
+
+void KItemSetTest::initTestCase()
+{
+    m_testCases.insert("empty", KItemRangeList());
+    m_testCases.insert("[0]", KItemRangeList() << KItemRange(0, 1));
+    m_testCases.insert("[1]", KItemRangeList() << KItemRange(1, 1));
+    m_testCases.insert("[1, 2]", KItemRangeList() << KItemRange(1, 2));
+    m_testCases.insert("[1, 2] [5]", KItemRangeList() << KItemRange(1, 2) << KItemRange(5, 1));
+    m_testCases.insert("[1] [4, 5]", KItemRangeList() << KItemRange(1, 1) << KItemRange(4, 2));
+    m_testCases.insert("[1, 2] [4, 5]", KItemRangeList() << KItemRange(1, 2) << KItemRange(4, 2));
+    m_testCases.insert("[1, 5]", KItemRangeList() << KItemRange(1, 5));
+    m_testCases.insert("[1, 2] [4, 5] [7] [9, 10] [13] [20, 25] [30]",
+                       KItemRangeList() << KItemRange(1, 2) << KItemRange(4, 2) << KItemRange(7, 1) << KItemRange(9, 2) << KItemRange(20, 6) << KItemRange(30, 1));
+    m_testCases.insert("[-10, -1]", KItemRangeList() << KItemRange(-10, 10));
+    m_testCases.insert("[-10, 0]", KItemRangeList() << KItemRange(-10, 11));
+    m_testCases.insert("[-10, 1]", KItemRangeList() << KItemRange(-10, 12));
+    m_testCases.insert("[0, 9]", KItemRangeList() << KItemRange(0, 10));
+    m_testCases.insert("[0, 19]", KItemRangeList() << KItemRange(0, 10));
+}
+
+void KItemSetTest::testConstruction_data()
+{
+    QTest::addColumn<KItemRangeList>("itemRanges");
+
+    QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
+    const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
+
+    while (it != end) {
+        QTest::newRow(it.key()) << it.value();
+        ++it;
+    }
+}
+
+void KItemSetTest::testConstruction()
+{
+    QFETCH(KItemRangeList, itemRanges);
+
+    KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
+    QSet<int> itemsQSet = KItemRangeList2QSet(itemRanges);
+
+    QVERIFY(itemSet.isValid());
+    QVERIFY(itemSet.count() == itemsQSet.count());
+    QCOMPARE(KItemSet2QSet(itemSet), itemsQSet);
+
+    // Test copy constructor.
+    KItemSet copy(itemSet);
+    QCOMPARE(itemSet, copy);
+    copy.clear();
+    QVERIFY(itemSet != copy || itemSet.isEmpty());
+
+    // Clear the set.
+    itemSet.clear();
+    QVERIFY(itemSet.isEmpty());
+    QCOMPARE(itemSet.count(), 0);
+}
+
+void KItemSetTest::testIterators_data()
+{
+    QTest::addColumn<KItemRangeList>("itemRanges");
+
+    QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
+    const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
+
+    while (it != end) {
+        QTest::newRow(it.key()) << it.value();
+        ++it;
+    }
+}
+
+/**
+ * Verify that the iterators work exactly like their counterparts for the
+ * equivalent QVector<int>.
+ */
+void KItemSetTest::testIterators()
+{
+    QFETCH(KItemRangeList, itemRanges);
+
+    KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
+    QVector<int> itemsQVector = KItemRangeList2QVector(itemRanges);
+
+    QVERIFY(itemSet.isValid());
+    QVERIFY(itemSet.count() == itemsQVector.count());
+
+    if (itemSet.count() == 0) {
+        QVERIFY(itemSet.isEmpty());
+        QVERIFY(itemSet.begin() == itemSet.end());
+        QVERIFY(itemSet.constBegin() == itemSet.constEnd());
+    } else {
+        QVERIFY(!itemSet.isEmpty());
+        QVERIFY(itemSet.begin() != itemSet.end());
+        QVERIFY(itemSet.constBegin() != itemSet.constEnd());
+
+        const int min = itemsQVector.first();
+        const int max = itemsQVector.last();
+
+        QCOMPARE(*itemSet.begin(), min);
+        QCOMPARE(*itemSet.constBegin(), min);
+        QCOMPARE(itemSet.first(), min);
+
+        QCOMPARE(*(--itemSet.end()), max);
+        QCOMPARE(*(--itemSet.constEnd()), max);
+        QCOMPARE(itemSet.last(), max);
+    }
+
+    // Test iterating using the different iterators.
+    QVector<int> testQVector;
+    for (KItemSet::iterator it = itemSet.begin(), end = itemSet.end(); it != end; ++it) {
+        testQVector.append(*it);
+    }
+    QCOMPARE(testQVector, itemsQVector);
+
+    testQVector.clear();
+    for (KItemSet::const_iterator it = itemSet.constBegin(), end = itemSet.constEnd(); it != end; ++it) {
+        testQVector.append(*it);
+    }
+    QCOMPARE(testQVector, itemsQVector);
+
+    testQVector.clear();
+    foreach (int i, itemSet) {
+        testQVector.append(i);
+    }
+    QCOMPARE(testQVector, itemsQVector);
+
+    // Verify that both variants of the (const)iterator's operator++ and
+    // operator-- functions behave exactly like their QVector equivalents.
+    KItemSet::iterator it1 = itemSet.begin();
+    KItemSet::iterator it2 = itemSet.begin();
+    KItemSet::const_iterator constIt1 = itemSet.constBegin();
+    KItemSet::const_iterator constIt2 = itemSet.constBegin();
+    QVector<int>::iterator vectorIt1 = itemsQVector.begin();
+    QVector<int>::iterator vectorIt2 = itemsQVector.begin();
+    QVector<int>::const_iterator vectorConstIt1 = itemsQVector.constBegin();
+    QVector<int>::const_iterator vectorConstIt2 = itemsQVector.constBegin();
+
+    while (it1 != itemSet.end()) {
+        if (it1 != --itemSet.end()) {
+            QCOMPARE(*(++it1), *(++vectorIt1));
+            QCOMPARE(*(++constIt1), *(++vectorConstIt1));
+        } else {
+            QCOMPARE(++it1, itemSet.end());
+            QCOMPARE(++vectorIt1, itemsQVector.end());
+            QCOMPARE(++constIt1, itemSet.constEnd());
+            QCOMPARE(++vectorConstIt1, itemsQVector.constEnd());
+        }
+
+        QCOMPARE(*(it2++), *(vectorIt2++));
+        QCOMPARE(*(constIt2++), *(vectorConstIt2++));
+
+        QCOMPARE(it1, it2);
+        QCOMPARE(constIt1, constIt2);
+        QCOMPARE(KItemSet::const_iterator(it1), constIt1);
+    }
+
+    QCOMPARE(it1, itemSet.end());
+    QCOMPARE(it2, itemSet.end());
+    QCOMPARE(constIt1, itemSet.constEnd());
+    QCOMPARE(constIt2, itemSet.constEnd());
+    QCOMPARE(vectorIt1, itemsQVector.end());
+    QCOMPARE(vectorIt2, itemsQVector.end());
+    QCOMPARE(vectorConstIt1, itemsQVector.constEnd());
+    QCOMPARE(vectorConstIt2, itemsQVector.constEnd());
+
+    while (it1 != itemSet.begin()) {
+        QCOMPARE(*(--it1), *(--vectorIt1));
+        QCOMPARE(*(--constIt1), *(--vectorConstIt1));
+
+        if (it2 != itemSet.end()) {
+            QCOMPARE(*(it2--), *(vectorIt2--));
+            QCOMPARE(*(constIt2--), *(vectorConstIt2--));
+        } else {
+            QCOMPARE(it2--, itemSet.end());
+            QCOMPARE(vectorIt2--, itemsQVector.end());
+            QCOMPARE(constIt2--, itemSet.constEnd());
+            QCOMPARE(vectorConstIt2--, itemsQVector.constEnd());
+        }
+
+        QCOMPARE(it1, it2);
+        QCOMPARE(constIt1, constIt2);
+        QCOMPARE(KItemSet::const_iterator(it1), constIt1);
+    }
+
+    QCOMPARE(it1, itemSet.begin());
+    QCOMPARE(it2, itemSet.begin());
+    QCOMPARE(constIt1, itemSet.constBegin());
+    QCOMPARE(constIt2, itemSet.constBegin());
+    QCOMPARE(vectorIt1, itemsQVector.begin());
+    QCOMPARE(vectorIt2, itemsQVector.begin());
+    QCOMPARE(vectorConstIt1, itemsQVector.constBegin());
+    QCOMPARE(vectorConstIt2, itemsQVector.constBegin());
+}
+
+void KItemSetTest::testFind_data()
+{
+    QTest::addColumn<KItemRangeList>("itemRanges");
+
+    QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
+    const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
+
+    while (it != end) {
+        QTest::newRow(it.key()) << it.value();
+        ++it;
+    }
+}
+
+/**
+ * Test all functions that find items:
+ * contais(int), find(int), constFind(int)
+ */
+void KItemSetTest::testFind()
+{
+    QFETCH(KItemRangeList, itemRanges);
+
+    KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
+    QSet<int> itemsQSet = KItemRangeList2QSet(itemRanges);
+
+    QVERIFY(itemSet.isValid());
+    QVERIFY(itemSet.count() == itemsQSet.count());
+
+    // Find the minimum and maximum items.
+    int min;
+    int max;
+
+    if (itemSet.count() == 0) {
+        // Use some arbitrary values for the upcoming tests.
+        min = 0;
+        max = 5;
+    } else {
+        min = *itemSet.begin();
+        max = *(--itemSet.end());
+    }
+
+    // Test contains(int), find(int), and constFind(int)
+    // for items between min - 2 and max + 2.
+    for (int i = min - 2; i <= max + 2; ++i) {
+        const KItemSet::iterator it = itemSet.find(i);
+        const KItemSet::const_iterator constIt = itemSet.constFind(i);
+        QCOMPARE(KItemSet::const_iterator(it), constIt);
+
+        if (itemsQSet.contains(i)) {
+            QVERIFY(itemSet.contains(i));
+            QCOMPARE(*it, i);
+            QCOMPARE(*constIt, i);
+        } else {
+            QVERIFY(!itemSet.contains(i));
+            QCOMPARE(it, itemSet.end());
+            QCOMPARE(constIt, itemSet.constEnd());
+        }
+    }
+}
+
+void KItemSetTest::testChangingOneItem_data()
+{
+    QTest::addColumn<KItemRangeList>("itemRanges");
+
+    QHash<const char*, KItemRangeList>::const_iterator it = m_testCases.constBegin();
+    const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
+
+    while (it != end) {
+        QTest::newRow(it.key()) << it.value();
+        ++it;
+    }
+}
+
+/**
+ * Test all functions that change a single item:
+ * insert(int), remove(int), erase(KItemSet::iterator)
+ */
+void KItemSetTest::testChangingOneItem()
+{
+    QFETCH(KItemRangeList, itemRanges);
+
+    KItemSet itemSet = KItemRangeList2KItemSet(itemRanges);
+    QSet<int> itemsQSet = KItemRangeList2QSet(itemRanges);
+
+    QVERIFY(itemSet.isValid());
+    QVERIFY(itemSet.count() == itemsQSet.count());
+
+    // Find the minimum and maximum items.
+    int min;
+    int max;
+
+    if (itemSet.count() == 0) {
+        // Use some arbitrary values for the upcoming tests.
+        min = 0;
+        max = 5;
+    } else {
+        min = *itemSet.begin();
+        max = *(--itemSet.end());
+    }
+
+    // Test insert(int), remove(int), and erase(KItemSet::iterator)
+    // for items between min - 2 and max + 2.
+    for (int i = min - 2; i <= max + 2; ++i) {
+
+        // Test insert(int).
+        {
+            KItemSet tmp(itemSet);
+            const KItemSet::iterator insertedIt = tmp.insert(i);
+            QCOMPARE(*insertedIt, i);
+
+            QVERIFY(tmp.isValid());
+            QVERIFY(tmp.contains(i));
+
+            QSet<int> expectedQSet = itemsQSet;
+            expectedQSet.insert(i);
+            QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
+
+            if (!itemSet.contains(i)) {
+                QVERIFY(itemSet != tmp);
+                QCOMPARE(tmp.count(), itemSet.count() + 1);
+            } else {
+                QCOMPARE(itemSet, tmp);
+            }
+
+            QCOMPARE(i, *tmp.find(i));
+            QCOMPARE(i, *tmp.constFind(i));
+
+            // Erase the new item and check that we get the old KItemSet back.
+            tmp.erase(tmp.find(i));
+            QVERIFY(tmp.isValid());
+            QVERIFY(!tmp.contains(i));
+
+            if (!itemSet.contains(i)) {
+                QCOMPARE(itemSet, tmp);
+            }
+
+            expectedQSet.remove(i);
+            QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
+        }
+
+        // Test remove(int).
+        {
+            KItemSet tmp(itemSet);
+            const bool removed = tmp.remove(i);
+
+            QCOMPARE(removed, itemSet.contains(i));
+
+            QVERIFY(tmp.isValid());
+            QVERIFY(!tmp.contains(i));
+
+            QSet<int> expectedQSet = itemsQSet;
+            expectedQSet.remove(i);
+            QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
+
+            if (itemSet.contains(i)) {
+                QVERIFY(itemSet != tmp);
+                QCOMPARE(tmp.count(), itemSet.count() - 1);
+            } else {
+                QCOMPARE(itemSet, tmp);
+            }
+
+            QCOMPARE(tmp.end(), tmp.find(i));
+            QCOMPARE(tmp.constEnd(), tmp.constFind(i));
+        }
+
+        // Test erase(KItemSet::iterator).
+        if (itemSet.contains(i)) {
+            KItemSet tmp(itemSet);
+            KItemSet::iterator it = tmp.find(i);
+            it = tmp.erase(it);
+
+            QVERIFY(tmp.isValid());
+            QVERIFY(!tmp.contains(i));
+
+            QSet<int> expectedQSet = itemsQSet;
+            expectedQSet.remove(i);
+            QCOMPARE(KItemSet2QSet(tmp), expectedQSet);
+
+            if (itemSet.contains(i)) {
+                QVERIFY(itemSet != tmp);
+                QCOMPARE(tmp.count(), itemSet.count() - 1);
+            } else {
+                QCOMPARE(itemSet, tmp);
+            }
+
+            QCOMPARE(tmp.end(), tmp.find(i));
+            QCOMPARE(tmp.constEnd(), tmp.constFind(i));
+
+            // Check the returen value, now contained in 'it'.
+            if (i == max) {
+                QCOMPARE(it, tmp.end());
+            } else {
+                // it now points to the next item.
+                QVERIFY(tmp.contains(*it));
+                for (int j = i; j < *it; ++j) {
+                    QVERIFY(!tmp.contains(j));
+                }
+            }
+        }
+    }
+
+    // Clear the set.
+    itemSet.clear();
+    QVERIFY(itemSet.isEmpty());
+    QCOMPARE(itemSet.count(), 0);
+}
+
+void KItemSetTest::testAddSets_data()
+{
+    QTest::addColumn<KItemRangeList>("itemRanges1");
+    QTest::addColumn<KItemRangeList>("itemRanges2");
+
+    QHash<const char*, KItemRangeList>::const_iterator it1 = m_testCases.constBegin();
+    const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
+
+    while (it1 != end) {
+        QHash<const char*, KItemRangeList>::const_iterator it2 = m_testCases.constBegin();
+
+        while (it2 != end) {
+            QByteArray name = it1.key() + QByteArray(" + ") + it2.key();
+            QTest::newRow(name) << it1.value() << it2.value();
+            ++it2;
+        }
+
+        ++it1;
+    }
+}
+
+void KItemSetTest::testAddSets()
+{
+    QFETCH(KItemRangeList, itemRanges1);
+    QFETCH(KItemRangeList, itemRanges2);
+
+    KItemSet itemSet1 = KItemRangeList2KItemSet(itemRanges1);
+    QSet<int> itemsQSet1 = KItemRangeList2QSet(itemRanges1);
+
+    KItemSet itemSet2 = KItemRangeList2KItemSet(itemRanges2);
+    QSet<int> itemsQSet2 = KItemRangeList2QSet(itemRanges2);
+
+    KItemSet sum = itemSet1 + itemSet2;
+    QSet<int> sumQSet = itemsQSet1 + itemsQSet2;
+
+    QCOMPARE(sum.count(), sumQSet.count());
+    QCOMPARE(KItemSet2QSet(sum), sumQSet);
+}
+
+void KItemSetTest::testSymmetricDifference_data()
+{
+    QTest::addColumn<KItemRangeList>("itemRanges1");
+    QTest::addColumn<KItemRangeList>("itemRanges2");
+
+    QHash<const char*, KItemRangeList>::const_iterator it1 = m_testCases.constBegin();
+    const QHash<const char*, KItemRangeList>::const_iterator end = m_testCases.constEnd();
+
+    while (it1 != end) {
+        QHash<const char*, KItemRangeList>::const_iterator it2 = m_testCases.constBegin();
+
+        while (it2 != end) {
+            QByteArray name = it1.key() + QByteArray(" ^ ") + it2.key();
+            QTest::newRow(name) << it1.value() << it2.value();
+            ++it2;
+        }
+
+        ++it1;
+    }
+}
+
+void KItemSetTest::testSymmetricDifference()
+{
+    QFETCH(KItemRangeList, itemRanges1);
+    QFETCH(KItemRangeList, itemRanges2);
+
+    KItemSet itemSet1 = KItemRangeList2KItemSet(itemRanges1);
+    QSet<int> itemsQSet1 = KItemRangeList2QSet(itemRanges1);
+
+    KItemSet itemSet2 = KItemRangeList2KItemSet(itemRanges2);
+    QSet<int> itemsQSet2 = KItemRangeList2QSet(itemRanges2);
+
+    KItemSet symmetricDifference = itemSet1 ^ itemSet2;
+    QSet<int> symmetricDifferenceQSet = (itemsQSet1 - itemsQSet2) + (itemsQSet2 - itemsQSet1);
+
+    QCOMPARE(symmetricDifference.count(), symmetricDifferenceQSet.count());
+    QCOMPARE(KItemSet2QSet(symmetricDifference), symmetricDifferenceQSet);
+
+    // Check commutativity.
+    QCOMPARE(itemSet2 ^ itemSet1, symmetricDifference);
+
+    // Some more checks:
+    // itemSet1 ^ symmetricDifference == itemSet2,
+    // itemSet2 ^ symmetricDifference == itemSet1.
+    QCOMPARE(itemSet1 ^ symmetricDifference, itemSet2);
+    QCOMPARE(itemSet2 ^ symmetricDifference, itemSet1);
+}
+
+
+QTEST_KDEMAIN(KItemSetTest, NoGUI)
+
+#include "kitemsettest.moc"
index fd149e0f6aa0a947680c5c3c7481ecda7c24be99..d0a85b3e26ef125112bcca4a3f903fa07d684769 100644 (file)
@@ -145,7 +145,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
 
     controller->setSelectionBehavior(KItemListController::MultiSelection);
     connect(controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
-    connect(controller, SIGNAL(itemsActivated(QSet<int>)), this, SLOT(slotItemsActivated(QSet<int>)));
+    connect(controller, SIGNAL(itemsActivated(KItemSet)), this, SLOT(slotItemsActivated(KItemSet)));
     connect(controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
     connect(controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF)));
     connect(controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
@@ -184,8 +184,8 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
             this, SLOT(slotHeaderColumnWidthChanged(QByteArray,qreal,qreal)));
 
     KItemListSelectionManager* selectionManager = controller->selectionManager();
-    connect(selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)),
-            this, SLOT(slotSelectionChanged(QSet<int>,QSet<int>)));
+    connect(selectionManager, SIGNAL(selectionChanged(KItemSet,KItemSet)),
+            this, SLOT(slotSelectionChanged(KItemSet,KItemSet)));
 
     m_toolTipManager = new ToolTipManager(this);
 
@@ -350,14 +350,9 @@ int DolphinView::itemsCount() const
 KFileItemList DolphinView::selectedItems() const
 {
     const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
-    QList<int> selectedIndexes = selectionManager->selectedItems().toList();
-
-    qSort(selectedIndexes);
 
     KFileItemList selectedItems;
-    QListIterator<int> it(selectedIndexes);
-    while (it.hasNext()) {
-        const int index = it.next();
+    foreach (int index, selectionManager->selectedItems()) {
         selectedItems.append(m_model->fileItem(index));
     }
     return selectedItems;
@@ -390,9 +385,9 @@ void DolphinView::selectItems(const QRegExp& pattern, bool enabled)
     for (int index = 0; index < m_model->count(); index++) {
         const KFileItem item = m_model->fileItem(index);
         if (pattern.exactMatch(item.text())) {
-            // An alternative approach would be to store the matching items in a QSet<int> and
+            // An alternative approach would be to store the matching items in a KItemSet and
             // select them in one go after the loop, but we'd need a new function
-            // KItemListSelectionManager::setSelected(QSet<int>, SelectionMode mode)
+            // KItemListSelectionManager::setSelected(KItemSet, SelectionMode mode)
             // for that.
             selectionManager->setSelected(index, 1, mode);
         }
@@ -803,7 +798,7 @@ void DolphinView::slotItemActivated(int index)
     }
 }
 
-void DolphinView::slotItemsActivated(const QSet<int>& indexes)
+void DolphinView::slotItemsActivated(const KItemSet& indexes)
 {
     Q_ASSERT(indexes.count() >= 2);
 
@@ -818,9 +813,7 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes)
     KFileItemList items;
     items.reserve(indexes.count());
 
-    QSetIterator<int> it(indexes);
-    while (it.hasNext()) {
-        const int index = it.next();
+    foreach (int index, indexes) {
         KFileItem item = m_model->fileItem(index);
         const KUrl& url = openItemAsFolderUrl(item);
 
@@ -1104,7 +1097,7 @@ void DolphinView::slotAboutToCreate(const KUrl::List& urls)
     }
 }
 
-void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
+void DolphinView::slotSelectionChanged(const KItemSet& current, const KItemSet& previous)
 {
     const int currentCount = current.count();
     const int previousCount = previous.count();
@@ -1323,7 +1316,7 @@ void DolphinView::updateViewState()
             m_clearSelectionBeforeSelectingNewItems = false;
         }
 
-        QSet<int> selectedItems = selectionManager->selectedItems();
+        KItemSet selectedItems = selectionManager->selectedItems();
 
         QList<KUrl>::iterator it = m_selectedUrls.begin();
         while (it != m_selectedUrls.end()) {
@@ -1659,7 +1652,7 @@ KUrl::List DolphinView::simplifiedSelectedUrls() const
 QMimeData* DolphinView::selectionMimeData() const
 {
     const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
-    const QSet<int> selectedIndexes = selectionManager->selectedItems();
+    const KItemSet selectedIndexes = selectionManager->selectedItems();
 
     return m_model->createMimeData(selectedIndexes);
 }
index a6f969bc1b7d8e27c233588199a9f6ac5e404397..b43957f226e05d639a0bb97ec4abae42da092443 100644 (file)
@@ -34,7 +34,6 @@
 #include <QBoxLayout>
 #include <QKeyEvent>
 #include <QLinkedList>
-#include <QSet>
 #include <QWidget>
 
 typedef KIO::FileUndoManager::CommandType CommandType;
@@ -45,6 +44,7 @@ class KActionCollection;
 class KFileItemModel;
 class KItemListContainer;
 class KItemModelBase;
+class KItemSet;
 class KUrl;
 class ToolTipManager;
 class VersionControlObserver;
@@ -563,7 +563,7 @@ private slots:
     void activate();
 
     void slotItemActivated(int index);
-    void slotItemsActivated(const QSet<int>& indexes);
+    void slotItemsActivated(const KItemSet& indexes);
     void slotItemMiddleClicked(int index);
     void slotItemContextMenuRequested(int index, const QPointF& pos);
     void slotViewContextMenuRequested(const QPointF& pos);
@@ -587,7 +587,7 @@ private slots:
      * the signal is emitted only after no selection change has been done
      * within a small delay.
      */
-    void slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous);
+    void slotSelectionChanged(const KItemSet& current, const KItemSet& previous);
 
     /**
      * Is called by emitDelayedSelectionChangedSignal() and emits the