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();
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()
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()
{
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;
}
}
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)
*/
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;
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();
void insertItems(const KFileItemList& items);
void removeItems(const KFileItemList& items);
+ void resortAllItems();
+
void removeExpandedItems();
enum Role {
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)
{
}
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;
Q_UNUSED(previous);
}
+void KItemModelBase::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
+{
+ Q_UNUSED(current);
+ Q_UNUSED(previous);
+}
+
#include "kitemmodelbase.moc"
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;
/**
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:
/**
*/
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
void testModelConsistencyWhenInsertingItems();
void testItemRangeConsistencyWhenInsertingItems();
void testExpandItems();
+ void testSorting();
void testExpansionLevelsCompare_data();
void testExpansionLevelsCompare();
private:
bool isModelConsistent() const;
+ QStringList itemsInModel() const;
private:
KFileItemModel* m_model;
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");
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"
Qt::SortOrder DolphinView::sortOrder() const
{
- return Qt::AscendingOrder; // m_viewAccessor.proxyModel()->sortOrder();
+ KItemModelBase* model = fileItemModel();
+ return model->sortOrder();
}
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)
ViewProperties props(url());
props.setSortOrder(order);
- //m_viewAccessor.proxyModel()->setSortOrder(order);
+ KItemModelBase* model = fileItemModel();
+ model->setSortOrder(order);
emit sortOrderChanged(order);
}
ViewProperties props(url());
props.setSortFoldersFirst(foldersFirst);
- //m_viewAccessor.proxyModel()->setSortFoldersFirst(foldersFirst);
+ KFileItemModel* model = fileItemModel();
+ model->setSortFoldersFirst(foldersFirst);
emit sortFoldersFirstChanged(foldersFirst);
}
}*/
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;