]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Implement some missing sorting options
authorFrank Reininghaus <frank78ac@googlemail.com>
Sun, 18 Sep 2011 13:03:45 +0000 (15:03 +0200)
committerFrank Reininghaus <frank78ac@googlemail.com>
Sun, 18 Sep 2011 13:03:45 +0000 (15:03 +0200)
Changing the sort order and enabling/disabling the
"Sort Folders First" option works now.

src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/kitemviews/kitemmodelbase.cpp
src/kitemviews/kitemmodelbase.h
src/tests/kfileitemmodeltest.cpp
src/views/dolphinview.cpp

index f5d8d41a2e5391f51ae97aedfac08ab42cd683df..1391acb835ff50e766651097da24674db262fdb2 100644 (file)
@@ -137,6 +137,19 @@ bool KFileItemModel::supportsSorting() const
     return true;
 }
 
+void KFileItemModel::setSortFoldersFirst(bool foldersFirst)
+{
+    if (foldersFirst != m_sortFoldersFirst) {
+        m_sortFoldersFirst = foldersFirst;
+        resortAllItems();
+    }
+}
+
+bool KFileItemModel::sortFoldersFirst() const
+{
+    return m_sortFoldersFirst;
+}
+
 QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
 {
     QMimeData* data = new QMimeData();
@@ -370,30 +383,15 @@ void KFileItemModel::onGroupRoleChanged(const QByteArray& current, const QByteAr
 void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous)
 {
     Q_UNUSED(previous);
-    const int itemCount = count();
-    if (itemCount <= 0) {
-        return;
-    }
-
     m_sortRole = roleIndex(current);
+    resortAllItems();
+}
 
-    KFileItemList sortedItems = m_sortedItems;
-    m_sortedItems.clear();
-    m_items.clear();
-    m_data.clear();
-    emit itemsRemoved(KItemRangeList() << KItemRange(0, itemCount));
-
-    sort(sortedItems.begin(), sortedItems.end());
-    int index = 0;
-    foreach (const KFileItem& item, sortedItems) {
-        m_sortedItems.append(item);
-        m_items.insert(item.url(), index);
-        m_data.append(retrieveData(item));
-
-        ++index;
-    }
-
-    emit itemsInserted(KItemRangeList() << KItemRange(0, itemCount));
+void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+    resortAllItems();
 }
 
 void KFileItemModel::slotCompleted()
@@ -698,6 +696,32 @@ void KFileItemModel::removeItems(const KFileItemList& items)
     emit itemsRemoved(itemRanges);
 }
 
+void KFileItemModel::resortAllItems()
+{
+    const int itemCount = count();
+    if (itemCount <= 0) {
+        return;
+    }
+
+    KFileItemList sortedItems = m_sortedItems;
+    m_sortedItems.clear();
+    m_items.clear();
+    m_data.clear();
+    emit itemsRemoved(KItemRangeList() << KItemRange(0, itemCount));
+
+    sort(sortedItems.begin(), sortedItems.end());
+    int index = 0;
+    foreach (const KFileItem& item, sortedItems) {
+        m_sortedItems.append(item);
+        m_items.insert(item.url(), index);
+        m_data.append(retrieveData(item));
+
+        ++index;
+    }
+
+    emit itemsInserted(KItemRangeList() << KItemRange(0, itemCount));
+}
+
 void KFileItemModel::removeExpandedItems()
 {
 
@@ -840,7 +864,7 @@ bool KFileItemModel::lessThan(const KFileItem& a, const KFileItem& b) const
         result = expansionLevelsCompare(a, b);
         if (result != 0) {
             // The items have parents with different expansion levels
-            return result < 0;
+            return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0;
         }
     }
 
@@ -887,7 +911,7 @@ bool KFileItemModel::lessThan(const KFileItem& a, const KFileItem& b) const
         result = QString::compare(a.url().url(), b.url().url(), Qt::CaseSensitive);
     }
 
-    return result < 0;
+    return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0;
 }
 
 void KFileItemModel::sort(const KFileItemList::iterator& startIterator, const KFileItemList::iterator& endIterator)
index 4156b2be807c1bf213cb6143dcbcca889f8669a9..b84cef216922b70b46853d5185268048caa91482 100644 (file)
@@ -66,6 +66,12 @@ public:
      */
     virtual bool supportsSorting() const;
 
+    /**
+     * Sets a separate sorting with folders first (true) or a mixed sorting of files and folders (false).
+     */
+    void setSortFoldersFirst(bool foldersFirst);
+    bool sortFoldersFirst() const;
+
     /** @reimp */
     virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
 
@@ -122,6 +128,7 @@ signals:
 protected:
     virtual void onGroupRoleChanged(const QByteArray& current, const QByteArray& previous);
     virtual void onSortRoleChanged(const QByteArray& current, const QByteArray& previous);
+    virtual void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
 
 private slots:
     void slotCompleted();
@@ -138,6 +145,8 @@ private:
     void insertItems(const KFileItemList& items);
     void removeItems(const KFileItemList& items);
 
+    void resortAllItems();
+
     void removeExpandedItems();
 
     enum Role {
index 541f802e3253e52789d6f4eb9ae24ee646d238b4..7bfe607a46f8a28fbc1f39376666acdcaee1adbe 100644 (file)
@@ -36,14 +36,16 @@ bool KItemRange::operator == (const KItemRange& other) const
 KItemModelBase::KItemModelBase(QObject* parent) :
     QObject(parent),
     m_groupRole(),
-    m_sortRole()
+    m_sortRole(),
+    m_sortOrder(Qt::AscendingOrder)
 {
 }
 
 KItemModelBase::KItemModelBase(const QByteArray& groupRole, const QByteArray& sortRole, QObject* parent) :
     QObject(parent),
     m_groupRole(groupRole),
-    m_sortRole(sortRole)
+    m_sortRole(sortRole),
+    m_sortOrder(Qt::AscendingOrder)
 {
 }
 
@@ -98,6 +100,16 @@ QByteArray KItemModelBase::sortRole() const
     return m_sortRole;
 }
 
+void KItemModelBase::setSortOrder(Qt::SortOrder order)
+{
+    if (supportsSorting() && order != m_sortOrder) {
+        const Qt::SortOrder previous = m_sortOrder;
+        m_sortOrder = order;
+        onSortOrderChanged(order, previous);
+        emit sortOrderChanged(order, previous);
+    }
+}
+
 QString KItemModelBase::roleDescription(const QByteArray& role) const
 {
     return role;
@@ -134,4 +146,10 @@ void KItemModelBase::onSortRoleChanged(const QByteArray& current, const QByteArr
     Q_UNUSED(previous);
 }
 
+void KItemModelBase::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+}
+
 #include "kitemmodelbase.moc"
index de6e1bb1ddfe7cf518048d3058f60fec50d71ccc..adb48669d680a1480f5bc9493a6327bcb75fc003 100644 (file)
@@ -100,13 +100,21 @@ public:
     virtual bool supportsSorting() const;
 
     /**
-     * Sets the sor-role to \a role. The method KItemModelBase::onSortRoleChanged() will be
+     * Sets the sort-role to \a role. The method KItemModelBase::onSortRoleChanged() will be
      * called so that model-implementations can react on the sort-role change. Afterwards the
      * signal sortRoleChanged() will be emitted.
      */
     void setSortRole(const QByteArray& role);
     QByteArray sortRole() const;
 
+    /**
+     * Sets the sort order to \a order. The method KItemModelBase::onSortOrderChanged() will be
+     * called so that model-implementations can react on the sort order change. Afterwards the
+     * signal sortOrderChanged() will be emitted.
+     */
+    void setSortOrder(Qt::SortOrder order);
+    Qt::SortOrder sortOrder() const;
+
     virtual QString roleDescription(const QByteArray& role) const;
 
     /**
@@ -182,6 +190,7 @@ signals:
 
     void groupRoleChanged(const QByteArray& current, const QByteArray& previous);
     void sortRoleChanged(const QByteArray& current, const QByteArray& previous);
+    void sortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
 
 protected:
     /**
@@ -204,11 +213,27 @@ protected:
      */
     virtual void onSortRoleChanged(const QByteArray& current, const QByteArray& previous);
 
+    /**
+     * Is invoked if the sort order has been changed by KItemModelBase::setSortOrder(). Allows
+     * to react on the changed sort order before the signal sortOrderChanged() will be emitted.
+     * The implementation must assure that the items are sorted by the order given by \a current.
+     * Usually the most efficient way is to emit a
+     * itemsRemoved() signal for all items, reorder the items internally and to emit a
+     * itemsInserted() signal afterwards.
+     */
+    virtual void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
+
 private:
     QByteArray m_groupRole;
     QByteArray m_sortRole;
+    Qt::SortOrder m_sortOrder;
 };
 
+inline Qt::SortOrder KItemModelBase::sortOrder() const
+{
+    return m_sortOrder;
+}
+
 #endif
 
 
index d3404782cb59432200504a51f22221dfbf3654ec..820cf78481081df3d0c6b922f9c8cf55ccd89ae9 100644 (file)
@@ -46,6 +46,7 @@ private slots:
     void testModelConsistencyWhenInsertingItems();
     void testItemRangeConsistencyWhenInsertingItems();
     void testExpandItems();
+    void testSorting();
 
     void testExpansionLevelsCompare_data();
     void testExpansionLevelsCompare();
@@ -54,6 +55,7 @@ private slots:
 
 private:
     bool isModelConsistent() const;
+    QStringList itemsInModel() const;
 
 private:
     KFileItemModel* m_model;
@@ -331,6 +333,62 @@ void KFileItemModelTest::testExpandItems()
     QCOMPARE(m_model->expandedUrls(), allFolders);
 }
 
+void KFileItemModelTest::testSorting()
+{
+    // Create some files with different sizes and modification times to check the different sorting options
+    QDateTime now = QDateTime::currentDateTime();
+
+    m_testDir->createFile("a", "A file", now.addDays(-3));
+    m_testDir->createFile("b", "A larger file", now.addDays(0));
+    m_testDir->createDir("c", now.addDays(-2));
+    m_testDir->createFile("d", "The largest file in this directory", now.addDays(-1));
+    m_testDir->createFile("e", "An even larger file", now.addDays(-4));
+    m_testDir->createFile(".f");
+
+    m_dirLister->openUrl(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+
+    // Default: Sort by Name, ascending
+    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
+    QVERIFY(m_model->sortFoldersFirst());
+    //QVERIFY(!m_model->showHiddenFiles());
+    QCOMPARE(itemsInModel(), QStringList() << "c" << "a" << "b" << "d" << "e");
+
+    // Sort by Name, descending
+    m_model->setSortOrder(Qt::DescendingOrder);
+    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder);
+    QCOMPARE(itemsInModel(), QStringList() << "c" << "e" << "d" << "b" << "a");
+
+    // Sort by Date, decending
+    m_model->setSortRole("date");
+    QCOMPARE(m_model->sortRole(), QByteArray("date"));
+    QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder);
+    QCOMPARE(itemsInModel(), QStringList() << "c" << "b" << "d" << "a" << "e");
+
+    // Sort by Date, ascending
+    m_model->setSortOrder(Qt::AscendingOrder);
+    QCOMPARE(m_model->sortRole(), QByteArray("date"));
+    QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
+    QCOMPARE(itemsInModel(), QStringList() << "c" << "e" << "a" << "d" << "b");
+
+    // Sort by Date, ascending, 'Sort Folders First' disabled
+    m_model->setSortFoldersFirst(false);
+    QCOMPARE(m_model->sortRole(), QByteArray("date"));
+    QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
+    QVERIFY(!m_model->sortFoldersFirst());
+    QCOMPARE(itemsInModel(), QStringList() << "e" << "a" << "c" << "d" << "b");
+
+    // Default: Sort by Name, ascending, 'Sort Folders First' disabled
+    m_model->setSortRole("name");
+    QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
+    QVERIFY(!m_model->sortFoldersFirst());
+    QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "d" << "e");
+
+    // TODO: Sort by other roles; show/hide hidden files
+}
+
 void KFileItemModelTest::testExpansionLevelsCompare_data()
 {
     QTest::addColumn<QString>("urlA");
@@ -426,6 +484,17 @@ bool KFileItemModelTest::isModelConsistent() const
     return true;
 }
 
+QStringList KFileItemModelTest::itemsInModel() const
+{
+    QStringList items;
+
+    for (int i = 0; i < m_model->count(); i++) {
+        items << m_model->data(i).value("name").toString();
+    }
+
+    return items;
+}
+
 QTEST_KDEMAIN(KFileItemModelTest, NoGUI)
 
 #include "kfileitemmodeltest.moc"
index 11fe17ac56f4f23b7a0bbff0d66fe1135918a890..db546fe95d177a043120db7c68775a749bb8b801 100644 (file)
@@ -371,7 +371,8 @@ void DolphinView::setSortOrder(Qt::SortOrder order)
 
 Qt::SortOrder DolphinView::sortOrder() const
 {
-    return Qt::AscendingOrder; // m_viewAccessor.proxyModel()->sortOrder();
+    KItemModelBase* model = fileItemModel();
+    return model->sortOrder();
 }
 
 void DolphinView::setSortFoldersFirst(bool foldersFirst)
@@ -383,7 +384,8 @@ void DolphinView::setSortFoldersFirst(bool foldersFirst)
 
 bool DolphinView::sortFoldersFirst() const
 {
-    return true; // m_viewAccessor.proxyModel()->sortFoldersFirst();
+    KFileItemModel* model = fileItemModel();
+    return model->sortFoldersFirst();
 }
 
 void DolphinView::setAdditionalInfoList(const QList<AdditionalInfo>& info)
@@ -885,7 +887,8 @@ void DolphinView::updateSortOrder(Qt::SortOrder order)
     ViewProperties props(url());
     props.setSortOrder(order);
 
-    //m_viewAccessor.proxyModel()->setSortOrder(order);
+    KItemModelBase* model = fileItemModel();
+    model->setSortOrder(order);
 
     emit sortOrderChanged(order);
 }
@@ -895,7 +898,8 @@ void DolphinView::updateSortFoldersFirst(bool foldersFirst)
     ViewProperties props(url());
     props.setSortFoldersFirst(foldersFirst);
 
-    //m_viewAccessor.proxyModel()->setSortFoldersFirst(foldersFirst);
+    KFileItemModel* model = fileItemModel();
+    model->setSortFoldersFirst(foldersFirst);
 
     emit sortFoldersFirstChanged(foldersFirst);
 }
@@ -1143,25 +1147,25 @@ void DolphinView::applyViewProperties()
     }*/
 
     const DolphinView::Sorting sorting = props.sorting();
-    KItemModelBase* model = m_container->controller()->model();
+    KFileItemModel* model = fileItemModel();
     const QByteArray newSortRole = sortRoleForSorting(sorting);
     if (newSortRole != model->sortRole()) {
         model->setSortRole(newSortRole);
         emit sortingChanged(sorting);
     }
-/*
+
     const Qt::SortOrder sortOrder = props.sortOrder();
-    if (sortOrder != m_viewAccessor.proxyModel()->sortOrder()) {
-        m_viewAccessor.proxyModel()->setSortOrder(sortOrder);
+    if (sortOrder != model->sortOrder()) {
+        model->setSortOrder(sortOrder);
         emit sortOrderChanged(sortOrder);
     }
 
     const bool sortFoldersFirst = props.sortFoldersFirst();
-    if (sortFoldersFirst != m_viewAccessor.proxyModel()->sortFoldersFirst()) {
-        m_viewAccessor.proxyModel()->setSortFoldersFirst(sortFoldersFirst);
+    if (sortFoldersFirst != model->sortFoldersFirst()) {
+        model->setSortFoldersFirst(sortFoldersFirst);
         emit sortFoldersFirstChanged(sortFoldersFirst);
     }
-*/
+
     const QList<DolphinView::AdditionalInfo> infoList = props.additionalInfoList();
     if (infoList != m_additionalInfoList) {
         const QList<DolphinView::AdditionalInfo> previousList = m_additionalInfoList;