]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Reimplement name-filtering
authorPeter Penz <peter.penz19@gmail.com>
Tue, 29 Nov 2011 23:18:22 +0000 (00:18 +0100)
committerPeter Penz <peter.penz19@gmail.com>
Tue, 29 Nov 2011 23:24:33 +0000 (00:24 +0100)
The filtering of items has not been implemented yet in
the KFileItemModel of the new view-engine. The patch brings back
this functionality again, but some minor issues are open:
- When filtering trees expanded directories should only get
  hidden if no child is visible
- Regular expressions are not supported yet (they have not been
  supported in Dolphin 1.x but it is now quite simple to implement).
- When filtering previews and removing the filter it might be
  possible that the preview is not shown (is most probably an
  an already existing bug in KFileItemModelRolesUpdater).

BUG: 287642
FIXED-IN: 4.8.0

src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/tests/kfileitemmodeltest.cpp
src/views/dolphinview.cpp

index d1e0fc6f14ece89ad2ab5e9a04db3fa82a6fd318..bd83bf62137c0988d256ea735e8ade0f020f5e5e 100644 (file)
@@ -40,6 +40,8 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
     m_caseSensitivity(Qt::CaseInsensitive),
     m_itemData(),
     m_items(),
+    m_nameFilter(),
+    m_filteredItems(),
     m_requestRole(),
     m_minimumUpdateIntervalTimer(0),
     m_maximumUpdateIntervalTimer(0),
@@ -475,6 +477,57 @@ void KFileItemModel::setExpanded(const QSet<KUrl>& urls)
     }
 }
 
+void KFileItemModel::setNameFilter(const QString& nameFilter)
+{
+    if (m_nameFilter != nameFilter) {
+        // TODO #1: Assure that expanded items only can get hidden
+        // if no child item is visible
+
+        // TODO #2: If the user entered a '*' use a regular expression
+
+        m_nameFilter = nameFilter;
+
+        const QString filter = nameFilter.toLower();
+
+        // Check which shown items from m_itemData must get
+        // hidden and hence moved to m_filteredItems.
+        KFileItemList newFilteredItems;
+
+        foreach (ItemData* itemData, m_itemData) {
+            if (!matchesNameFilter(itemData->item, filter)) {
+                m_filteredItems.append(itemData->item);
+                newFilteredItems.append(itemData->item);
+            }
+        }
+
+        if (!newFilteredItems.isEmpty()) {
+            slotItemsDeleted(newFilteredItems);
+        }
+
+        // Check which hidden items from m_filteredItems should
+        // get visible again and hence removed from m_filteredItems.
+        KFileItemList newVisibleItems;
+
+        for (int i = m_filteredItems.count() - 1; i >= 0; --i) {
+            const KFileItem item = m_filteredItems.at(i);
+            if (matchesNameFilter(item, filter)) {
+                newVisibleItems.append(item);
+                m_filteredItems.removeAt(i);
+            }
+        }
+
+        if (!newVisibleItems.isEmpty()) {
+            slotNewItems(newVisibleItems);
+            dispatchPendingItemsToInsert();
+        }
+    }
+}
+
+QString KFileItemModel::nameFilter() const
+{
+    return m_nameFilter;
+}
+
 void KFileItemModel::onGroupedSortingChanged(bool current)
 {
     Q_UNUSED(current);
@@ -1654,4 +1707,10 @@ QList<QPair<int, QVariant> > KFileItemModel::genericStringRoleGroups(const QByte
     return groups;
 }
 
+bool KFileItemModel::matchesNameFilter(const KFileItem& item, const QString& nameFilter)
+{
+    const QString itemText = item.text().toLower();
+    return itemText.contains(nameFilter);
+}
+
 #include "kfileitemmodel.moc"
index 8cbcb1216a72c29112c9de7d6eb8b46c15621b32..a83d57ba8bf15fa6f9129c8b34891d4822b58a8a 100644 (file)
@@ -134,6 +134,9 @@ public:
      */
     void setExpanded(const QSet<KUrl>& urls);
 
+    void setNameFilter(const QString& nameFilter);
+    QString nameFilter() const;
+
 signals:
     void loadingCompleted();
 
@@ -271,6 +274,11 @@ private:
      */
     bool isChildItem(int index) const;
 
+    /**
+     * @return True if the given item matches with the name filter.
+     */
+    static bool matchesNameFilter(const KFileItem& item, const QString& nameFilter);
+
 private:
     QWeakPointer<KDirLister> m_dirLister;
 
@@ -284,6 +292,9 @@ private:
     QList<ItemData*> m_itemData;
     QHash<KUrl, int> m_items; // Allows O(1) access for KFileItemModel::index(const KFileItem& item)
 
+    QString m_nameFilter;
+    KFileItemList m_filteredItems; // Items that got hidden by KFileItemModel::setNameFilter()
+
     bool m_requestRole[RolesCount];
 
     QTimer* m_minimumUpdateIntervalTimer;
index 59e817fff7c6a701e0ad19dea2e3995c4faaa931..23b899136860c50ead521402cef15555ef6cf369 100644 (file)
@@ -75,6 +75,8 @@ private slots:
 
     void testIndexForKeyboardSearch();
 
+    void testNameFilter();
+
 private:
     bool isModelConsistent() const;
     QStringList itemsInModel() const;
@@ -643,6 +645,34 @@ void KFileItemModelTest::testIndexForKeyboardSearch()
     // TODO: Maybe we should also test keyboard searches in directories which are not sorted by Name?
 }
 
+void KFileItemModelTest::testNameFilter()
+{
+    QStringList files;
+    files << "A1" << "A2" << "Abc" << "Bcd" << "Cde";
+    m_testDir->createFiles(files);
+
+    m_dirLister->openUrl(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+
+    m_model->setNameFilter("A"); // Shows A1, A2 and Abc
+    QCOMPARE(m_model->count(), 3);
+
+    m_model->setNameFilter("A2"); // Shows only A2
+    QCOMPARE(m_model->count(), 1);
+
+    m_model->setNameFilter("A2"); // Shows only A1
+    QCOMPARE(m_model->count(), 1);
+
+    m_model->setNameFilter("Bc"); // Shows "Abc" and "Bcd"
+    QCOMPARE(m_model->count(), 2);
+
+    m_model->setNameFilter("bC"); // Shows "Abc" and "Bcd"
+    QCOMPARE(m_model->count(), 2);
+
+    m_model->setNameFilter(QString()); // Shows again all items
+    QCOMPARE(m_model->count(), 5);
+}
+
 bool KFileItemModelTest::isModelConsistent() const
 {
     for (int i = 0; i < m_model->count(); ++i) {
index 829e1a302d504be2abd5e55be106245efbee50cf..857aae395a15494cc1c31bdc65ac1bd68686d77c 100644 (file)
@@ -459,13 +459,12 @@ void DolphinView::refresh()
 
 void DolphinView::setNameFilter(const QString& nameFilter)
 {
-    Q_UNUSED(nameFilter);
-    //m_viewModeController->setNameFilter(nameFilter);
+    fileItemModel()->setNameFilter(nameFilter);
 }
 
 QString DolphinView::nameFilter() const
 {
-    return QString(); //m_viewModeController->nameFilter();
+    return fileItemModel()->nameFilter();
 }
 
 void DolphinView::calculateItemCount(int& fileCount,