]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Merge remote-tracking branch 'origin/KDE/4.9'
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index c16820fa35f31fef42eb729d62708ed9793d41b1..231bfe077e2d12ce195f38d42f65fbc5b0a241b5 100644 (file)
@@ -31,6 +31,7 @@
 #include <QApplication>
 #include <QMimeData>
 #include <QTimer>
+#include <QWidget>
 
 // #define KFILEITEMMODEL_DEBUG
 
@@ -59,7 +60,11 @@ KFileItemModel::KFileItemModel(QObject* parent) :
     m_dirLister = new KFileItemModelDirLister(this);
     m_dirLister->setAutoUpdate(true);
     m_dirLister->setDelayedMimeTypes(true);
-    m_dirLister->setMainWindow(qApp->activeWindow());
+
+    const QWidget* parentWidget = qobject_cast<QWidget*>(parent);
+    if (parentWidget) {
+        m_dirLister->setMainWindow(parentWidget->window());
+    }
 
     connect(m_dirLister, SIGNAL(started(KUrl)), this, SIGNAL(directoryLoadingStarted()));
     connect(m_dirLister, SIGNAL(canceled()), this, SLOT(slotCanceled()));
@@ -72,13 +77,16 @@ KFileItemModel::KFileItemModel(QObject* parent) :
     connect(m_dirLister, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString)));
     connect(m_dirLister, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
     connect(m_dirLister, SIGNAL(redirection(KUrl,KUrl)), this, SIGNAL(directoryRedirection(KUrl,KUrl)));
+    connect(m_dirLister, SIGNAL(urlIsFileError(KUrl)), this, SIGNAL(urlIsFileError(KUrl)));
 
     // Apply default roles that should be determined
     resetRoles();
     m_requestRole[NameRole] = true;
     m_requestRole[IsDirRole] = true;
+    m_requestRole[IsLinkRole] = true;
     m_roles.insert("text");
     m_roles.insert("isDir");
+    m_roles.insert("isLink");
 
     // For slow KIO-slaves like used for searching it makes sense to show results periodically even
     // before the completed() or canceled() signal has been emitted.
@@ -165,6 +173,12 @@ bool KFileItemModel::setData(int index, const QHash<QByteArray, QVariant>& value
     }
 
     m_itemData[index]->values = currentValues;
+    if (changedRoles.contains("text")) {
+        KUrl url = m_itemData[index]->item.url();
+        url.setFileName(currentValues["text"].toString());
+        m_itemData[index]->item.setUrl(url);
+    }
+
     emit itemsChanged(KItemRangeList() << KItemRange(index, 1), changedRoles);
 
     if (changedRoles.contains(sortRole())) {
@@ -278,7 +292,7 @@ QString KFileItemModel::roleDescription(const QByteArray& role) const
         int count = 0;
         const RoleInfoMap* map = rolesInfoMap(count);
         for (int i = 0; i < count; ++i) {
-            description.insert(map[i].role, map[i].roleTranslation);
+            description.insert(map[i].role, i18nc(map[i].roleTranslationContext, map[i].roleTranslation));
         }
     }
 
@@ -499,46 +513,64 @@ void KFileItemModel::setNameFilter(const QString& nameFilter)
 {
     if (m_filter.pattern() != nameFilter) {
         dispatchPendingItemsToInsert();
-
         m_filter.setPattern(nameFilter);
+        applyFilters();
+    }
+}
 
-        // Check which shown items from m_itemData must get
-        // hidden and hence moved to m_filteredItems.
-        KFileItemList newFilteredItems;
+QString KFileItemModel::nameFilter() const
+{
+    return m_filter.pattern();
+}
 
-        foreach (ItemData* itemData, m_itemData) {
+void KFileItemModel::setMimeTypeFilters(const QStringList& filters)
+{
+    if (m_filter.mimeTypes() != filters) {
+        dispatchPendingItemsToInsert();
+        m_filter.setMimeTypes(filters);
+        applyFilters();
+    }
+}
+
+QStringList KFileItemModel::mimeTypeFilters() const
+{
+    return m_filter.mimeTypes();
+}
+
+
+void KFileItemModel::applyFilters()
+{
+    // Check which shown items from m_itemData must get
+    // hidden and hence moved to m_filteredItems.
+    KFileItemList newFilteredItems;
+
+    foreach (ItemData* itemData, m_itemData) {
+        // Only filter non-expanded items as child items may never
+        // exist without a parent item
+        if (!itemData->values.value("isExpanded").toBool()) {
             if (!m_filter.matches(itemData->item)) {
-                // Only filter non-expanded items as child items may never
-                // exist without a parent item
-                if (!itemData->values.value("isExpanded").toBool()) {
-                    newFilteredItems.append(itemData->item);
-                    m_filteredItems.insert(itemData->item);
-                }
+                newFilteredItems.append(itemData->item);
+                m_filteredItems.insert(itemData->item);
             }
         }
+    }
 
-        removeItems(newFilteredItems);
+    removeItems(newFilteredItems);
 
-        // Check which hidden items from m_filteredItems should
-        // get visible again and hence removed from m_filteredItems.
-        KFileItemList newVisibleItems;
+    // Check which hidden items from m_filteredItems should
+    // get visible again and hence removed from m_filteredItems.
+    KFileItemList newVisibleItems;
 
-        QMutableSetIterator<KFileItem> it(m_filteredItems);
-        while (it.hasNext()) {
-            const KFileItem item = it.next();
-            if (m_filter.matches(item)) {
-                newVisibleItems.append(item);
-                m_filteredItems.remove(item);
-            }
+    QMutableSetIterator<KFileItem> it(m_filteredItems);
+    while (it.hasNext()) {
+        const KFileItem item = it.next();
+        if (m_filter.matches(item)) {
+            newVisibleItems.append(item);
+            it.remove();
         }
-
-        insertItems(newVisibleItems);
     }
-}
 
-QString KFileItemModel::nameFilter() const
-{
-    return m_filter.pattern();
+    insertItems(newVisibleItems);
 }
 
 QList<KFileItemModel::RoleInfo> KFileItemModel::rolesInformation()
@@ -551,8 +583,15 @@ QList<KFileItemModel::RoleInfo> KFileItemModel::rolesInformation()
             if (map[i].roleType != NoRole) {
                 RoleInfo info;
                 info.role = map[i].role;
-                info.translation = map[i].roleTranslation;
-                info.group = map[i].groupTranslation;
+                info.translation = i18nc(map[i].roleTranslationContext, map[i].roleTranslation);
+                if (map[i].groupTranslation) {
+                    info.group = i18nc(map[i].groupTranslationContext, map[i].groupTranslation);
+                } else {
+                    // For top level roles, groupTranslation is 0. We must make sure that
+                    // info.group is an empty string then because the code that generates
+                    // menus tries to put the actions into sub menus otherwise.
+                    info.group = QString();
+                }
                 info.requiresNepomuk = map[i].requiresNepomuk;
                 info.requiresIndexer = map[i].requiresIndexer;
                 rolesInfo.append(info);
@@ -653,7 +692,7 @@ void KFileItemModel::slotCompleted()
         // Note that the parent folder must be expanded before any of its subfolders become visible.
         // Therefore, some URLs in m_restoredExpandedUrls might not be visible yet
         // -> we expand the first visible URL we find in m_restoredExpandedUrls.
-        foreach(const KUrl& url, m_urlsToExpand) {
+        foreach (const KUrl& url, m_urlsToExpand) {
             const int index = m_items.value(url, -1);
             if (index >= 0) {
                 m_urlsToExpand.remove(url);
@@ -677,6 +716,8 @@ void KFileItemModel::slotCanceled()
 {
     m_maximumUpdateIntervalTimer->stop();
     dispatchPendingItemsToInsert();
+
+    emit directoryLoadingCanceled();
 }
 
 void KFileItemModel::slotNewItems(const KFileItemList& items)
@@ -713,10 +754,10 @@ void KFileItemModel::slotNewItems(const KFileItemList& items)
         }
     }
 
-    if (m_filter.pattern().isEmpty()) {
+    if (!m_filter.hasSetFilters()) {
         m_pendingItemsToInsert.append(items);
     } else {
-        // The name-filter is active. Hide filtered items
+        // The name or type filter is active. Hide filtered items
         // before inserting them into the model and remember
         // the filtered items in m_filteredItems.
         KFileItemList filteredItems;
@@ -930,7 +971,7 @@ void KFileItemModel::insertItems(const KFileItemList& items)
             insertedCount = 0;
         }
 
-        // Insert item at the position targetIndex by transfering
+        // Insert item at the position targetIndex by transferring
         // the ownership of the item-data from sortedItems to m_itemData.
         // m_items will be inserted after the loop (see comment below)
         m_itemData.insert(targetIndex, sortedItems.at(sourceIndex));
@@ -1116,6 +1157,7 @@ KFileItemModel::RoleType KFileItemModel::typeForRole(const QByteArray& role) con
         // Insert internal roles (take care to synchronize the implementation
         // with KFileItemModel::roleForType() in case if a change is done).
         roles.insert("isDir", IsDirRole);
+        roles.insert("isLink", IsLinkRole);
         roles.insert("isExpanded", IsExpandedRole);
         roles.insert("isExpandable", IsExpandableRole);
         roles.insert("expandedParentsCount", ExpandedParentsCountRole);
@@ -1141,6 +1183,7 @@ QByteArray KFileItemModel::roleForType(RoleType roleType) const
         // Insert internal roles (take care to synchronize the implementation
         // with KFileItemModel::typeForRole() in case if a change is done).
         roles.insert(IsDirRole, "isDir");
+        roles.insert(IsLinkRole, "isLink");
         roles.insert(IsExpandedRole, "isExpanded");
         roles.insert(IsExpandableRole, "isExpandable");
         roles.insert(ExpandedParentsCountRole, "expandedParentsCount");
@@ -1164,6 +1207,11 @@ QHash<QByteArray, QVariant> KFileItemModel::retrieveData(const KFileItem& item)
         data.insert("isDir", isDir);
     }
 
+    if (m_requestRole[IsLinkRole]) {
+        const bool isLink = item.isLink();
+        data.insert("isLink", isLink);
+    }
+
     if (m_requestRole[NameRole]) {
         data.insert("text", item.text());
     }
@@ -1209,7 +1257,17 @@ QHash<QByteArray, QVariant> KFileItemModel::retrieveData(const KFileItem& item)
         if (item.url().protocol() == QLatin1String("trash")) {
             path = item.entry().stringValue(KIO::UDSEntry::UDS_EXTRA);
         } else {
+            // For performance reasons cache the home-path in a static QString
+            // (see QDir::homePath() for more details)
+            static QString homePath;
+            if (homePath.isEmpty()) {
+                homePath = QDir::homePath();
+            }
+
             path = item.localPath();
+            if (path.startsWith(homePath)) {
+                path.replace(0, homePath.length(), QLatin1Char('~'));
+            }
         }
 
         const int index = path.lastIndexOf(item.text());
@@ -1357,22 +1415,13 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const
         break;
     }
 
-    case PermissionsRole:
-    case OwnerRole:
-    case GroupRole:
-    case TypeRole:
-    case DestinationRole:
-    case PathRole:
-    case CommentRole:
-    case TagsRole: {
+    default: {
         const QByteArray role = roleForType(m_sortRole);
         result = QString::compare(a->values.value(role).toString(),
                                   b->values.value(role).toString());
         break;
     }
 
-    default:
-        break;
     }
 
     if (result != 0) {
@@ -1904,7 +1953,7 @@ void KFileItemModel::determineMimeTypes(const KFileItemList& items, int timeout)
 {
     QElapsedTimer timer;
     timer.start();
-    foreach (KFileItem item, items) {
+    foreach (KFileItem item, items) { // krazy:exclude=foreach
         item.determineMimeType();
         if (timer.elapsed() > timeout) {
             // Don't block the user interface, let the remaining items