[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