[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdevelop/lib/util
From:       Harald Fernengel <harry () kdevelop ! org>
Date:       2005-11-03 21:17:01
Message-ID: 1131052621.607675.26740.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 477347 by harald:

add incremental filtering. If the new filter string starts with the old filter \
string, only the already filtered parts are filtered again.


 M  +72 -7     kfiltermodel.cpp  
 M  +3 -1      kfiltermodel.h  


--- trunk/KDE/kdevelop/lib/util/kfiltermodel.cpp #477346:477347
@@ -26,11 +26,14 @@
         : q(qq), sourceModel(source), topLevelRowCount(0) {}
 
     void doFiltering();
+    void doIncrementalFiltering();
     int nextSiblingIdx(int idx, int count = 1) const;
     int addItems(int level, const QModelIndex &parent);
     void modelDestroyed();
     void modelChanged();
+    int parentIndex(int index) const;
     QModelIndex childIdx(const QModelIndex &index) const;
+    void recalcSiblingIdx(int &idx);
 
     KFilterModel *q;
     QAbstractItemModel *sourceModel;
@@ -54,6 +57,18 @@
     return sourceModel->index(idx.row(), index.column(), sourceModel->parent(idx));
 }
 
+/* return index of parent or -1 if toplevel */
+/* TODO - linear search. Optimize by storing the parent index in the FilterIdx? */
+int KFilterModelPrivate::parentIndex(int index) const
+{
+    int level = filteredIdx.at(index).level;
+    if (level == 0)
+        return -1;
+
+    while (filteredIdx.at(--index).level >= level) { /* nada */ };
+    return index;
+}
+
 void KFilterModelPrivate::modelDestroyed()
 {
     sourceModel = 0;
@@ -120,6 +135,45 @@
     q->reset();
 }
 
+void KFilterModelPrivate::recalcSiblingIdx(int &idx)
+{
+    int sibIdx = -1;
+    const int fcount = filteredIdx.count();
+    while (idx < fcount) {
+        filteredIdx[idx].siblingIdx = ++sibIdx;
+        int level = filteredIdx.at(idx).level;
+        ++idx;
+        int nextLevel = filteredIdx.value(idx).level;
+        if (nextLevel != level) {
+            if (nextLevel > level)
+                recalcSiblingIdx(idx);
+            if (filteredIdx.value(idx).level < level)
+                return;
+        }
+    }
+    topLevelRowCount = sibIdx + 1;
+}
+
+void KFilterModelPrivate::doIncrementalFiltering()
+{
+    QVector<FilterIdx> newIdxs;
+    for (int i = filteredIdx.count() - 1; i >= 0; --i) {
+        FilterIdx idx = filteredIdx.at(i);
+        bool hit = q->matches(idx.index);
+        if (!hit && !idx.childCount) {
+            int parentIdx = parentIndex(i);
+            if (parentIdx != -1)
+                --(filteredIdx[parentIdx].childCount);
+        } else {
+            newIdxs.prepend(idx);
+        }
+    }
+    filteredIdx = newIdxs;
+    int sibIdx = 0;
+    recalcSiblingIdx(sibIdx);
+    q->reset();
+}
+
 KFilterModel::KFilterModel(QAbstractItemModel *model, QObject *parent)
     : QAbstractItemModel(parent), d(new KFilterModelPrivate(this, model))
 {
@@ -190,20 +244,31 @@
 
 QModelIndex KFilterModel::parent(const QModelIndex &child) const
 {
-    int idx = child.internalId();
-    int level = d->filteredIdx.at(idx).level;
-    if (level == 0)
+    int idx = d->parentIndex(child.internalId());
+    if (idx == -1)
         return QModelIndex();
-
-    while (d->filteredIdx.at(--idx).level >= level);
     return createIndex(d->filteredIdx.at(idx).siblingIdx, 0, idx);
 }
 
-void KFilterModel::setFilter(const QString &expression)
+void KFilterModel::setFilter(const QString &expression, FilterMode mode)
 {
+    QString oldFilter = d->filterStr;
     d->filterStr = expression;
 
-    d->doFiltering();
+    switch (mode) {
+    case FilterAuto:
+        if (expression.startsWith(oldFilter))
+            d->doIncrementalFiltering();
+        else
+            d->doFiltering();
+        break;
+    case FilterAll:
+        d->doFiltering();
+        break;
+    case FilterIncremental:
+        d->doIncrementalFiltering();
+        break;
+    }
 }
 
 /**
--- trunk/KDE/kdevelop/lib/util/kfiltermodel.h #477346:477347
@@ -45,8 +45,10 @@
     QAbstractItemModel *model() const;
     QString filter() const;
 
+    enum FilterMode { FilterAuto, FilterAll, FilterIncremental };
+
 public slots:
-    void setFilter(const QString &expression);
+    void setFilter(const QString &expression, FilterMode mode = FilterAuto);
 
 protected:
     virtual bool matches(const QModelIndex &index) const;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic