]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Drag and drop: Adjust destination if the item is no directory or desktop-file
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index d81ddd965529b79a5e86e996f443f5d24a829d9a..e0ae033026f94b8d42f9362dc004fce904bbae19 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <KDirLister>
 #include <KDirModel>
+#include <KGlobalSettings>
 #include <KLocale>
 #include <KStringHandler>
 #include <KDebug>
@@ -33,7 +34,7 @@
 KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
     KItemModelBase("name", parent),
     m_dirLister(dirLister),
-    m_naturalSorting(true),
+    m_naturalSorting(KGlobalSettings::naturalSorting()),
     m_sortFoldersFirst(true),
     m_sortRole(NameRole),
     m_roles(),
@@ -95,6 +96,8 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
     connect(m_resortAllItemsTimer, SIGNAL(timeout()), this, SLOT(resortAllItems()));
 
     Q_ASSERT(m_minimumUpdateIntervalTimer->interval() <= m_maximumUpdateIntervalTimer->interval());
+    
+    connect(KGlobalSettings::self(), SIGNAL(naturalSortingChanged()), this, SLOT(slotNaturalSortingChanged()));
 }
 
 KFileItemModel::~KFileItemModel()
@@ -183,6 +186,20 @@ bool KFileItemModel::showHiddenFiles() const
     return dirLister ? dirLister->showingDotFiles() : false;
 }
 
+void KFileItemModel::setShowFoldersOnly(bool enabled)
+{
+    KDirLister* dirLister = m_dirLister.data();
+    if (dirLister) {
+        dirLister->setDirOnlyMode(enabled);
+    }
+}
+
+bool KFileItemModel::showFoldersOnly() const
+{
+    KDirLister* dirLister = m_dirLister.data();
+    return dirLister ? dirLister->dirOnlyMode() : false;
+}
+
 QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
 {
     QMimeData* data = new QMimeData();
@@ -240,7 +257,7 @@ int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromInd
 bool KFileItemModel::supportsDropping(int index) const
 {
     const KFileItem item = fileItem(index);
-    return item.isNull() ? false : item.isDir();
+    return item.isNull() ? false : item.isDir() || item.isDesktopFile();
 }
 
 QString KFileItemModel::roleDescription(const QByteArray& role) const
@@ -461,29 +478,24 @@ void KFileItemModel::restoreExpandedUrls(const QSet<KUrl>& urls)
     m_urlsToExpand = urls;
 }
 
-void KFileItemModel::setExpanded(const QSet<KUrl>& urls)
+void KFileItemModel::expandParentItems(const KUrl& url)
 {
     const KDirLister* dirLister = m_dirLister.data();
     if (!dirLister) {
         return;
     }
 
-    const int pos = dirLister->url().url().length();
+    const int pos = dirLister->url().path().length();
 
-    // Assure that each sub-path of the URLs that should be
-    // expanded is added to m_urlsToExpand too. KDirLister
+    // Assure that each sub-path of the URL that should be
+    // expanded is added to m_urlsToExpand. KDirLister
     // does not care whether the parent-URL has already been
     // expanded.
-    QSetIterator<KUrl> it1(urls);
-    while (it1.hasNext()) {
-        const KUrl& url = it1.next();
-
-        KUrl urlToExpand = dirLister->url();
-        const QStringList subDirs = url.url().mid(pos).split(QDir::separator());
-        for (int i = 0; i < subDirs.count(); ++i) {
-            urlToExpand.addPath(subDirs.at(i));
-            m_urlsToExpand.insert(urlToExpand);
-        }
+    KUrl urlToExpand = dirLister->url();
+    const QStringList subDirs = url.path().mid(pos).split(QDir::separator());
+    for (int i = 0; i < subDirs.count() - 1; ++i) {
+        urlToExpand.addPath(subDirs.at(i));
+        m_urlsToExpand.insert(urlToExpand);
     }
 
     // KDirLister::open() must called at least once to trigger an initial
@@ -848,6 +860,12 @@ void KFileItemModel::slotClear(const KUrl& url)
     Q_UNUSED(url);
 }
 
+void KFileItemModel::slotNaturalSortingChanged()
+{
+    m_naturalSorting = KGlobalSettings::naturalSorting();
+    resortAllItems();
+}
+
 void KFileItemModel::dispatchPendingItemsToInsert()
 {
     if (!m_pendingItemsToInsert.isEmpty()) {
@@ -1102,6 +1120,30 @@ KFileItemModel::Role KFileItemModel::roleIndex(const QByteArray& role) const
     return rolesHash.value(role, NoRole);
 }
 
+QByteArray KFileItemModel::roleByteArray(Role role) const
+{
+    static const char* const roles[RolesCount] = {
+        0, // NoRole
+        "name",
+        "size",
+        "date",
+        "permissions",
+        "owner",
+        "group",
+        "type",
+        "destination",
+        "path",
+        "comment",
+        "tags",
+        "rating",
+        "isDir",
+        "isExpanded",
+        "isExpandable",
+        "expansionLevel"        
+    };
+    return roles[role];
+}
+
 QHash<QByteArray, QVariant> KFileItemModel::retrieveData(const KFileItem& item) const
 {    
     // It is important to insert only roles that are fast to retrieve. E.g.
@@ -1251,62 +1293,69 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const
     case NameRole:
         // The name role is handled as default fallback after the switch
         break;
-
-    case DateRole: {
-        const KDateTime dateTimeA = itemA.time(KFileItem::ModificationTime);
-        const KDateTime dateTimeB = itemB.time(KFileItem::ModificationTime);
-        if (dateTimeA < dateTimeB) {
-            result = -1;
-        } else if (dateTimeA > dateTimeB) {
-            result = +1;
-        }
-        break;
-    }
-
+        
     case SizeRole: {
         if (itemA.isDir()) {
-            Q_ASSERT(itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above
+            // See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
+            Q_ASSERT(itemB.isDir());
 
             const QVariant valueA = a->values.value("size");
             const QVariant valueB = b->values.value("size");
-
-            if (valueA.isNull()) {
+            if (valueA.isNull() && valueB.isNull()) {
+                result = 0;
+            } else if (valueA.isNull()) {
                 result = -1;
             } else if (valueB.isNull()) {
                 result = +1;
             } else {
-                result = valueA.value<KIO::filesize_t>() - valueB.value<KIO::filesize_t>();
+                result = valueA.toInt() - valueB.toInt();
             }
         } else {
-            Q_ASSERT(!itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above
-            result = itemA.size() - itemB.size();
+            // See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
+            Q_ASSERT(!itemB.isDir());
+            const KIO::filesize_t sizeA = itemA.size();
+            const KIO::filesize_t sizeB = itemB.size();
+            if (sizeA > sizeB) {
+                result = +1;
+            } else if (sizeA < sizeB) {
+                result = -1;
+            } else {
+                result = 0;
+            }
         }
         break;
     }
 
-    case TypeRole: {
-        result = QString::compare(a->values.value("type").toString(),
-                                  b->values.value("type").toString());
+    case DateRole: {
+        const KDateTime dateTimeA = itemA.time(KFileItem::ModificationTime);
+        const KDateTime dateTimeB = itemB.time(KFileItem::ModificationTime);
+        if (dateTimeA < dateTimeB) {
+            result = -1;
+        } else if (dateTimeA > dateTimeB) {
+            result = +1;
+        }
         break;
     }
-
-    case CommentRole: {
-        result = QString::compare(a->values.value("comment").toString(),
-                                  b->values.value("comment").toString());
+    
+    case RatingRole: {
+        result = a->values.value("rating").toInt() - b->values.value("rating").toInt();
         break;
     }
-
+    
+    case PermissionsRole:
+    case OwnerRole:
+    case GroupRole:
+    case TypeRole:
+    case DestinationRole:
+    case PathRole:
+    case CommentRole:
     case TagsRole: {
-        result = QString::compare(a->values.value("tags").toString(),
-                                  b->values.value("tags").toString());
+        const QByteArray role = roleByteArray(m_sortRole);
+        result = QString::compare(a->values.value(role).toString(),
+                                  b->values.value(role).toString());
         break;
     }
-
-    case RatingRole: {
-        result = a->values.value("rating").toInt() - b->values.value("rating").toInt();
-        break;
-    }
-
+        
     default:
         break;
     }