]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Interface cleanups to prepare the return of "grouped sorting"
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index f5d8d41a2e5391f51ae97aedfac08ab42cd683df..3a49135f903755dea13b5baeb07f6e1b10394d9f 100644 (file)
 #define KFILEITEMMODEL_DEBUG
 
 KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
-    KItemModelBase(QByteArray(), "name", parent),
+    KItemModelBase("name", parent),
     m_dirLister(dirLister),
     m_naturalSorting(true),
     m_sortFoldersFirst(true),
-    m_groupRole(NoRole),
     m_sortRole(NameRole),
     m_caseSensitivity(Qt::CaseInsensitive),
     m_sortedItems(),
@@ -127,14 +126,17 @@ bool KFileItemModel::setData(int index, const QHash<QByteArray, QVariant>& value
     return false;
 }
 
-bool KFileItemModel::supportsGrouping() const
+void KFileItemModel::setSortFoldersFirst(bool foldersFirst)
 {
-    return true;
+    if (foldersFirst != m_sortFoldersFirst) {
+        m_sortFoldersFirst = foldersFirst;
+        resortAllItems();
+    }
 }
 
-bool KFileItemModel::supportsSorting() const
+bool KFileItemModel::sortFoldersFirst() const
 {
-    return true;
+    return m_sortFoldersFirst;
 }
 
 QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
@@ -178,15 +180,13 @@ QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
 int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
 {
     startFromIndex = qMax(0, startFromIndex);
-    for (int i = startFromIndex; i < count(); i++) {
+    for (int i = startFromIndex; i < count(); ++i) {
         if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
-            kDebug() << data(i)["name"].toString();
             return i;
         }
     }
-    for (int i = 0; i < startFromIndex; i++) {
+    for (int i = 0; i < startFromIndex; ++i) {
         if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
-            kDebug() << data(i)["name"].toString();
             return i;
         }
     }
@@ -199,6 +199,44 @@ bool KFileItemModel::supportsDropping(int index) const
     return item.isNull() ? false : item.isDir();
 }
 
+QString KFileItemModel::roleDescription(const QByteArray& role) const
+{
+    QString descr;
+
+    switch (roleIndex(role)) {
+    case NameRole:           descr = i18nc("@item:intable", "Name"); break;
+    case SizeRole:           descr = i18nc("@item:intable", "Size"); break;
+    case DateRole:           descr = i18nc("@item:intable", "Date"); break;
+    case PermissionsRole:    descr = i18nc("@item:intable", "Permissions"); break;
+    case OwnerRole:          descr = i18nc("@item:intable", "Owner"); break;
+    case GroupRole:          descr = i18nc("@item:intable", "Group"); break;
+    case TypeRole:           descr = i18nc("@item:intable", "Type"); break;
+    case DestinationRole:    descr = i18nc("@item:intable", "Destination"); break;
+    case PathRole:           descr = i18nc("@item:intable", "Path"); break;
+    case NoRole:             break;
+    case IsDirRole:          break;
+    case IsExpandedRole:     break;
+    case ExpansionLevelRole: break;
+    default:                 Q_ASSERT(false); break;
+    }
+
+    return descr;
+}
+
+QList<QPair<int, QVariant> > KFileItemModel::groups() const
+{
+    // TODO:
+    QPair<int, QVariant> group1(0, "Group 1");
+    QPair<int, QVariant> group2(5, "Group 2");
+    QPair<int, QVariant> group3(10, "Group 3");
+
+    QList<QPair<int, QVariant> > groups;
+    groups.append(group1);
+    groups.append(group2);
+    groups.append(group3);
+    return groups;
+}
+
 KFileItem KFileItemModel::fileItem(int index) const
 {
     if (index >= 0 && index < count()) {
@@ -226,6 +264,13 @@ int KFileItemModel::index(const KFileItem& item) const
     return m_items.value(item.url(), -1);
 }
 
+int KFileItemModel::index(const KUrl& url) const
+{
+    KUrl urlToFind = url;
+    urlToFind.adjustPath(KUrl::RemoveTrailingSlash);
+    return m_items.value(urlToFind, -1);
+}
+
 KFileItem KFileItemModel::rootItem() const
 {
     const KDirLister* dirLister = m_dirLister.data();
@@ -361,39 +406,23 @@ void KFileItemModel::restoreExpandedUrls(const QSet<KUrl>& urls)
     m_restoredExpandedUrls = urls;
 }
 
-void KFileItemModel::onGroupRoleChanged(const QByteArray& current, const QByteArray& previous)
+void KFileItemModel::onGroupedSortingChanged(bool current)
 {
-    Q_UNUSED(previous);
-    m_groupRole = roleIndex(current);
+    Q_UNUSED(current);
 }
 
 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,9 +727,49 @@ void KFileItemModel::removeItems(const KFileItemList& items)
     emit itemsRemoved(itemRanges);
 }
 
-void KFileItemModel::removeExpandedItems()
+void KFileItemModel::resortAllItems()
 {
+    const int itemCount = count();
+    if (itemCount <= 0) {
+        return;
+    }
+
+    const KFileItemList oldSortedItems = m_sortedItems;
+    const QHash<KUrl, int> oldItems = m_items;
+    const QList<QHash<QByteArray, QVariant> > oldData = m_data;
+
+    m_items.clear();
+    m_data.clear();
+
+    sort(m_sortedItems.begin(), m_sortedItems.end());
+    int index = 0;
+    foreach (const KFileItem& item, m_sortedItems) {
+        m_items.insert(item.url(), index);
+
+        const int oldItemIndex = oldItems.value(item.url());
+        m_data.append(oldData.at(oldItemIndex));
+
+        ++index;
+    }
 
+    bool emitItemsMoved = false;
+    QList<int> movedToIndexes;
+    movedToIndexes.reserve(m_sortedItems.count());
+    for (int i = 0; i < itemCount; i++) {
+        const int newIndex = m_items.value(oldSortedItems.at(i).url());
+        movedToIndexes.append(newIndex);
+        if (!emitItemsMoved && newIndex != i) {
+            emitItemsMoved = true;
+        }
+    }
+
+    if (emitItemsMoved) {
+        emit itemsMoved(KItemRange(0, itemCount), movedToIndexes);
+    }
+}
+
+void KFileItemModel::removeExpandedItems()
+{
     KFileItemList expandedItems;
 
     const int maxIndex = m_data.count() - 1;
@@ -840,11 +909,11 @@ 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;
         }
     }
 
-    if (m_sortFoldersFirst) {
+    if (m_sortFoldersFirst || m_sortRole == SizeRole) {
         const bool isDirA = a.isDir();
         const bool isDirB = b.isDir();
         if (isDirA && !isDirB) {
@@ -876,6 +945,20 @@ bool KFileItemModel::lessThan(const KFileItem& a, const KFileItem& b) const
         break;
     }
 
+    case SizeRole: {
+        // TODO: Implement sorting folders by the number of items inside.
+        // This is more tricky to get right because this number is retrieved
+        // asynchronously by KFileItemModelRolesUpdater.
+        const KIO::filesize_t sizeA = a.size();
+        const KIO::filesize_t sizeB = b.size();
+        if (sizeA < sizeB) {
+            result = -1;
+        } else if (sizeA > sizeB) {
+            result = +1;
+        }
+        break;
+    }
+
     default:
         break;
     }
@@ -887,7 +970,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)