]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
KFileItemModel: emit itemsChanged() signal
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index c2f49f70518ffb74770d00035eebf486dd45b9c2..ff0c4a02d9d0394832df493d42be6e0bd4392ded 100644 (file)
@@ -45,7 +45,6 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
     m_minimumUpdateIntervalTimer(0),
     m_maximumUpdateIntervalTimer(0),
     m_pendingItemsToInsert(),
-    m_pendingItemsToDelete(),
     m_rootExpansionLevel(-1)
 {
     resetRoles();
@@ -58,6 +57,7 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
     connect(dirLister, SIGNAL(completed()), this, SLOT(slotCompleted()));
     connect(dirLister, SIGNAL(newItems(KFileItemList)), this, SLOT(slotNewItems(KFileItemList)));
     connect(dirLister, SIGNAL(itemsDeleted(KFileItemList)), this, SLOT(slotItemsDeleted(KFileItemList)));
+    connect(dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)), this, SLOT(slotRefreshItems(QList<QPair<KFileItem,KFileItem> >)));
     connect(dirLister, SIGNAL(clear()), this, SLOT(slotClear()));
     connect(dirLister, SIGNAL(clear(KUrl)), this, SLOT(slotClear(KUrl)));
 
@@ -67,14 +67,14 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
     m_minimumUpdateIntervalTimer = new QTimer(this);
     m_minimumUpdateIntervalTimer->setInterval(1000);
     m_minimumUpdateIntervalTimer->setSingleShot(true);
-    connect(m_minimumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItems()));
+    connect(m_minimumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItemsToInsert()));
 
     // 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.
     m_maximumUpdateIntervalTimer = new QTimer(this);
     m_maximumUpdateIntervalTimer->setInterval(2000);
     m_maximumUpdateIntervalTimer->setSingleShot(true);
-    connect(m_maximumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItems()));
+    connect(m_maximumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItemsToInsert()));
 
     Q_ASSERT(m_minimumUpdateIntervalTimer->interval() <= m_maximumUpdateIntervalTimer->interval());
 }
@@ -124,24 +124,6 @@ bool KFileItemModel::setData(int index, const QHash<QByteArray, QVariant>& value
     return false;
 }
 
-int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
-{
-    startFromIndex = qMax(0, startFromIndex);
-    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++) {
-        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
-            kDebug() << data(i)["name"].toString();
-            return i;
-        }
-    }
-    return -1;
-}
-
 bool KFileItemModel::supportsGrouping() const
 {
     return true;
@@ -179,7 +161,7 @@ QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
     }
 
     const bool different = canUseMostLocalUrls && mostLocalUrls != urls;
-    urls = KDirModel::simplifiedUrlList(urls);
+    urls = KDirModel::simplifiedUrlList(urls); // TODO: Check if we still need KDirModel for this in KDE 5.0
     if (different) {
         mostLocalUrls = KDirModel::simplifiedUrlList(mostLocalUrls);
         urls.populateMimeData(mostLocalUrls, data);
@@ -190,6 +172,30 @@ QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
     return data;
 }
 
+int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
+{
+    startFromIndex = qMax(0, startFromIndex);
+    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++) {
+        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+            kDebug() << data(i)["name"].toString();
+            return i;
+        }
+    }
+    return -1;
+}
+
+bool KFileItemModel::supportsDropping(int index) const
+{
+    const KFileItem item = fileItem(index);
+    return item.isNull() ? false : item.isDir();
+}
+
 KFileItem KFileItemModel::fileItem(int index) const
 {
     if (index >= 0 && index < count()) {
@@ -199,13 +205,31 @@ KFileItem KFileItemModel::fileItem(int index) const
     return KFileItem();
 }
 
+KFileItem KFileItemModel::fileItem(const KUrl& url) const
+{
+    const int index = m_items.value(url, -1);
+    if (index >= 0) {
+        return m_sortedItems.at(index);
+    }
+    return KFileItem();
+}
+
 int KFileItemModel::index(const KFileItem& item) const
 {
     if (item.isNull()) {
         return -1;
     }
 
-    return m_items.value(item, -1);
+    return m_items.value(item.url(), -1);
+}
+
+KUrl KFileItemModel::rootDirectory() const
+{
+    const KDirLister* dirLister = m_dirLister.data();
+    if (dirLister) {
+        return dirLister->url();
+    }
+    return KUrl();
 }
 
 void KFileItemModel::clear()
@@ -346,7 +370,7 @@ void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArr
     int index = 0;
     foreach (const KFileItem& item, sortedItems) {
         m_sortedItems.append(item);
-        m_items.insert(item, index);
+        m_items.insert(item.url(), index);
         m_data.append(retrieveData(item));
 
         ++index;
@@ -363,7 +387,7 @@ void KFileItemModel::slotCompleted()
         return;
     }
 
-    dispatchPendingItems();
+    dispatchPendingItemsToInsert();
     m_minimumUpdateIntervalTimer->start();
 }
 
@@ -371,15 +395,11 @@ void KFileItemModel::slotCanceled()
 {
     m_minimumUpdateIntervalTimer->stop();
     m_maximumUpdateIntervalTimer->stop();
-    dispatchPendingItems();
+    dispatchPendingItemsToInsert();
 }
 
 void KFileItemModel::slotNewItems(const KFileItemList& items)
 {
-    if (!m_pendingItemsToDelete.isEmpty()) {
-        removeItems(m_pendingItemsToDelete);
-        m_pendingItemsToDelete.clear();
-    }
     m_pendingItemsToInsert.append(items);
 
     if (useMaximumUpdateInterval() && !m_maximumUpdateIntervalTimer->isActive()) {
@@ -395,7 +415,56 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items)
         insertItems(m_pendingItemsToInsert);
         m_pendingItemsToInsert.clear();
     }
-    m_pendingItemsToDelete.append(items);
+    removeItems(items);
+}
+
+void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& items)
+{
+    Q_ASSERT(!items.isEmpty());
+#ifdef KFILEITEMMODEL_DEBUG
+    kDebug() << "Refreshing" << items.count() << "items";
+#endif
+
+    // Get the indexes of all items that have been refreshed
+    QList<int> indexes;
+    indexes.reserve(items.count());
+
+    QListIterator<QPair<KFileItem, KFileItem> > it(items);
+    while (it.hasNext()) {
+        const QPair<KFileItem, KFileItem>& itemPair = it.next();
+        const int index = m_items.value(itemPair.second.url(), -1);
+        if (index >= 0) {
+            indexes.append(index);
+        }
+    }
+
+    // Extract the item-ranges out of the changed indexes
+    qSort(indexes);
+
+    KItemRangeList itemRangeList;
+    int rangeIndex = 0;
+    int rangeCount = 1;
+    int previousIndex = indexes.at(0);
+
+    const int maxIndex = indexes.count() - 1;
+    for (int i = 1; i <= maxIndex; ++i) {
+        const int currentIndex = indexes.at(i);
+        if (currentIndex == previousIndex + 1) {
+            ++rangeCount;
+        } else {
+            itemRangeList.append(KItemRange(rangeIndex, rangeCount));
+
+            rangeIndex = currentIndex;
+            rangeCount = 1;
+        }
+        previousIndex = currentIndex;
+    }
+
+    if (rangeCount > 0) {
+        itemRangeList.append(KItemRange(rangeIndex, rangeCount));
+    }
+
+    emit itemsChanged(itemRangeList, QSet<QByteArray>());
 }
 
 void KFileItemModel::slotClear()
@@ -407,7 +476,6 @@ void KFileItemModel::slotClear()
     m_minimumUpdateIntervalTimer->stop();
     m_maximumUpdateIntervalTimer->stop();
     m_pendingItemsToInsert.clear();
-    m_pendingItemsToDelete.clear();
 
     m_rootExpansionLevel = -1;
 
@@ -425,16 +493,11 @@ void KFileItemModel::slotClear(const KUrl& url)
     Q_UNUSED(url);
 }
 
-void KFileItemModel::dispatchPendingItems()
+void KFileItemModel::dispatchPendingItemsToInsert()
 {
     if (!m_pendingItemsToInsert.isEmpty()) {
-        Q_ASSERT(m_pendingItemsToDelete.isEmpty());
         insertItems(m_pendingItemsToInsert);
         m_pendingItemsToInsert.clear();
-    } else if (!m_pendingItemsToDelete.isEmpty()) {
-        Q_ASSERT(m_pendingItemsToInsert.isEmpty());
-        removeItems(m_pendingItemsToDelete);
-        m_pendingItemsToDelete.clear();
     }
 }
 
@@ -500,7 +563,7 @@ void KFileItemModel::insertItems(const KFileItemList& items)
     // The indexes of all m_items must be adjusted, not only the index
     // of the new items
     for (int i = 0; i < m_sortedItems.count(); ++i) {
-        m_items.insert(m_sortedItems.at(i), i);
+        m_items.insert(m_sortedItems.at(i).url(), i);
     }
 
     itemRanges << KItemRange(insertedAtIndex, insertedCount);
@@ -562,7 +625,7 @@ void KFileItemModel::removeItems(const KFileItemList& items)
     // Delete the items
     for (int i = indexesToRemove.count() - 1; i >= 0; --i) {
         const int indexToRemove = indexesToRemove.at(i);
-        m_items.remove(m_sortedItems.at(indexToRemove));
+        m_items.remove(m_sortedItems.at(indexToRemove).url());
         m_sortedItems.removeAt(indexToRemove);
         m_data.removeAt(indexToRemove);
     }
@@ -570,7 +633,7 @@ void KFileItemModel::removeItems(const KFileItemList& items)
     // The indexes of all m_items must be adjusted, not only the index
     // of the removed items
     for (int i = 0; i < m_sortedItems.count(); ++i) {
-        m_items.insert(m_sortedItems.at(i), i);
+        m_items.insert(m_sortedItems.at(i).url(), i);
     }
 
     if (count() <= 0) {