From: Frank Reininghaus Date: Sun, 18 Sep 2011 13:03:45 +0000 (+0200) Subject: Implement some missing sorting options X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/31d3b91813c2b9d74d175876d2551cca4484ab5e?ds=inline Implement some missing sorting options Changing the sort order and enabling/disabling the "Sort Folders First" option works now. --- diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index f5d8d41a2..1391acb83 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -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& 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) diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 4156b2be8..b84cef216 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -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& 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 { diff --git a/src/kitemviews/kitemmodelbase.cpp b/src/kitemviews/kitemmodelbase.cpp index 541f802e3..7bfe607a4 100644 --- a/src/kitemviews/kitemmodelbase.cpp +++ b/src/kitemviews/kitemmodelbase.cpp @@ -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" diff --git a/src/kitemviews/kitemmodelbase.h b/src/kitemviews/kitemmodelbase.h index de6e1bb1d..adb48669d 100644 --- a/src/kitemviews/kitemmodelbase.h +++ b/src/kitemviews/kitemmodelbase.h @@ -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 diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index d3404782c..820cf7848 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -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("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" diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 11fe17ac5..db546fe95 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -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& 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 infoList = props.additionalInfoList(); if (infoList != m_additionalInfoList) { const QList previousList = m_additionalInfoList;