┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Reininghaus <[email protected]>2011-09-18 15:03:45 +0200
committerFrank Reininghaus <[email protected]>2011-09-18 15:03:45 +0200
commit31d3b91813c2b9d74d175876d2551cca4484ab5e (patch)
tree8eba74dfe6075f3c45c7983b2ee1743823c3ae5b
parent01d4b8d0820ee3ab9f05df23c31a8230acfe7083 (diff)
Implement some missing sorting options
Changing the sort order and enabling/disabling the "Sort Folders First" option works now.
-rw-r--r--src/kitemviews/kfileitemmodel.cpp72
-rw-r--r--src/kitemviews/kfileitemmodel.h9
-rw-r--r--src/kitemviews/kitemmodelbase.cpp22
-rw-r--r--src/kitemviews/kitemmodelbase.h27
-rw-r--r--src/tests/kfileitemmodeltest.cpp69
-rw-r--r--src/views/dolphinview.cpp26
6 files changed, 187 insertions, 38 deletions
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<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)
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<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 {
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<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"
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<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;