summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Reininghaus <frank78ac@googlemail.com>2011-02-21 18:29:47 (GMT)
committerFrank Reininghaus <frank78ac@googlemail.com>2011-02-21 20:53:06 (GMT)
commitabc9c4c67cf5a25d0f279beedc81727cca154cad (patch)
tree3d63fc1e1cbc2a44a0a23c8964054badca4aac19
parente3b0aed5bf72858b772577f8b6688b9c7085bca2 (diff)
KListWidgetSearchLine: filter items that are inserted or changed
Up to now, the search line only filters items that are in the widget at the time a search is started. With this commit, items that are added or modified later are filtered as well. Unit test included
-rw-r--r--kdeui/itemviews/klistwidgetsearchline.cpp98
-rw-r--r--kdeui/itemviews/klistwidgetsearchline.h3
-rw-r--r--kdeui/tests/CMakeLists.txt1
-rw-r--r--kdeui/tests/klistwidgetsearchlinetest.cpp80
4 files changed, 152 insertions, 30 deletions
diff --git a/kdeui/itemviews/klistwidgetsearchline.cpp b/kdeui/itemviews/klistwidgetsearchline.cpp
index 5b9b03d..043c452 100644
--- a/kdeui/itemviews/klistwidgetsearchline.cpp
+++ b/kdeui/itemviews/klistwidgetsearchline.cpp
@@ -44,8 +44,11 @@ public:
void _k_listWidgetDeleted();
void _k_queueSearch(const QString&);
void _k_activateSearch();
+ void _k_rowsInserted(const QModelIndex&, int, int);
+ void _k_dataChanged(const QModelIndex&, const QModelIndex&);
void init( QListWidget *listWidget = 0 );
+ void updateHiddenState( int start, int end );
KListWidgetSearchLine *q;
QListWidget *listWidget;
@@ -87,36 +90,10 @@ QListWidget *KListWidgetSearchLine::listWidget() const
*****************************************************************************/
void KListWidgetSearchLine::updateSearch( const QString &s )
{
- QListWidget *lw = d->listWidget;
- if ( !lw )
- return ; // disabled
-
- QString search = d->search = s.isNull() ? text() : s;
-
- QListWidgetItem *currentItem = lw->currentItem();
-
- // Remove Non-Matching items
- int index = 0;
- while ( index < lw->count() ) {
- QListWidgetItem *item = lw->item(index);
- if ( ! itemMatches( item, search ) ) {
- item->setHidden( true );
-
- if ( item == currentItem ) {
- currentItem = 0; // It's not in listWidget anymore.
- }
- } else if ( item->isHidden() ){
- item->setHidden( false );
- }
-
- index++;
+ d->search = s.isNull() ? text() : s;
+ if( d->listWidget ) {
+ d->updateHiddenState( 0, d->listWidget->count() - 1 );
}
-
- if ( lw->isSortingEnabled() )
- lw->sortItems();
-
- if ( currentItem != 0 )
- lw->scrollToItem( currentItem );
}
void KListWidgetSearchLine::clear()
@@ -140,15 +117,21 @@ void KListWidgetSearchLine::setCaseSensitivity( Qt::CaseSensitivity cs )
void KListWidgetSearchLine::setListWidget( QListWidget *lw )
{
- if ( d->listWidget != 0 )
+ if ( d->listWidget != 0 ) {
disconnect( d->listWidget, SIGNAL( destroyed() ),
this, SLOT( _k_listWidgetDeleted() ) );
+ d->listWidget->model()->disconnect( this );
+ }
d->listWidget = lw;
if ( lw != 0 ) {
connect( d->listWidget, SIGNAL( destroyed() ),
this, SLOT( _k_listWidgetDeleted() ) );
+ connect( d->listWidget->model(), SIGNAL( rowsInserted( const QModelIndex &, int, int ) ),
+ this, SLOT( _k_rowsInserted( const QModelIndex &, int, int ) ) );
+ connect( d->listWidget->model(), SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
+ this, SLOT( _k_dataChanged( const QModelIndex &, const QModelIndex & ) ) );
setEnabled( true );
} else
setEnabled( false );
@@ -180,6 +163,10 @@ void KListWidgetSearchLine::KListWidgetSearchLinePrivate::init( QListWidget *_li
if ( listWidget != 0 ) {
connect( listWidget, SIGNAL( destroyed() ),
q, SLOT( _k_listWidgetDeleted() ) );
+ connect( listWidget->model(), SIGNAL( rowsInserted( const QModelIndex &, int, int ) ),
+ q, SLOT( _k_rowsInserted( const QModelIndex &, int, int ) ) );
+ connect( listWidget->model(), SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
+ q, SLOT( _k_dataChanged( const QModelIndex &, const QModelIndex & ) ) );
q->setEnabled( true );
} else {
q->setEnabled( false );
@@ -188,6 +175,36 @@ void KListWidgetSearchLine::KListWidgetSearchLinePrivate::init( QListWidget *_li
q->setClearButtonShown(true);
}
+void KListWidgetSearchLine::KListWidgetSearchLinePrivate::updateHiddenState( int start, int end ) {
+ if ( !listWidget ) {
+ return;
+ }
+
+ QListWidgetItem *currentItem = listWidget->currentItem();
+
+ // Remove Non-Matching items
+ for( int index = start; index <= end; ++index ) {
+ QListWidgetItem *item = listWidget->item(index);
+ if ( ! q->itemMatches( item, search ) ) {
+ item->setHidden( true );
+
+ if ( item == currentItem ) {
+ currentItem = 0; // It's not in listWidget anymore.
+ }
+ } else if ( item->isHidden() ) {
+ item->setHidden( false );
+ }
+ }
+
+ if ( listWidget->isSortingEnabled() ) {
+ listWidget->sortItems();
+ }
+
+ if ( currentItem != 0 ) {
+ listWidget->scrollToItem( currentItem );
+ }
+}
+
bool KListWidgetSearchLine::event(QEvent *event) {
if (event->type() == QEvent::KeyPress) {
@@ -235,4 +252,25 @@ void KListWidgetSearchLine::KListWidgetSearchLinePrivate::_k_listWidgetDeleted()
q->setEnabled( false );
}
+
+void KListWidgetSearchLine::KListWidgetSearchLinePrivate::_k_rowsInserted( const QModelIndex &parent, int start, int end )
+{
+ if( parent.isValid() ) {
+ return;
+ }
+
+ updateHiddenState( start, end );
+}
+
+void KListWidgetSearchLine::KListWidgetSearchLinePrivate::_k_dataChanged( const QModelIndex & topLeft, const QModelIndex & bottomRight )
+{
+ if( topLeft.parent().isValid() ) {
+ return;
+ }
+
+ updateHiddenState( topLeft.row(), bottomRight.row() );
+}
+
+
+
#include "klistwidgetsearchline.moc"
diff --git a/kdeui/itemviews/klistwidgetsearchline.h b/kdeui/itemviews/klistwidgetsearchline.h
index a78fb9b..9ab82e2 100644
--- a/kdeui/itemviews/klistwidgetsearchline.h
+++ b/kdeui/itemviews/klistwidgetsearchline.h
@@ -25,6 +25,7 @@
class QListWidget;
class QListWidgetItem;
+class QModelIndex;
/**
* This class makes it easy to add a search line for filtering the items in a
@@ -117,6 +118,8 @@ private:
Q_PRIVATE_SLOT(d, void _k_listWidgetDeleted())
Q_PRIVATE_SLOT(d, void _k_queueSearch(const QString&))
Q_PRIVATE_SLOT(d, void _k_activateSearch())
+ Q_PRIVATE_SLOT(d, void _k_rowsInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d, void _k_dataChanged(const QModelIndex&, const QModelIndex&))
};
diff --git a/kdeui/tests/CMakeLists.txt b/kdeui/tests/CMakeLists.txt
index 71c2426..c7b8026 100644
--- a/kdeui/tests/CMakeLists.txt
+++ b/kdeui/tests/CMakeLists.txt
@@ -67,6 +67,7 @@ KDEUI_UNIT_TESTS(
ktoolbar_unittest
krichtextedittest
kselectaction_unittest
+ klistwidgetsearchlinetest
)
KDEUI_PROXYMODEL_TESTS(
diff --git a/kdeui/tests/klistwidgetsearchlinetest.cpp b/kdeui/tests/klistwidgetsearchlinetest.cpp
new file mode 100644
index 0000000..01e9bbf
--- /dev/null
+++ b/kdeui/tests/klistwidgetsearchlinetest.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Frank Reininghaus (frank78ac@googlemail.com) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include <qtest_kde.h>
+
+#include <klistwidgetsearchline.h>
+
+#include <QListWidget>
+
+class KListWidgetSearchLineTest : public QObject
+{
+ Q_OBJECT
+
+private slots:
+
+ void testAddItems();
+
+};
+
+/**
+ * If items are added to the list view or modified, KListWidgetSearchLine
+ * should hide them if they do not match the search string, see
+ *
+ * https://bugs.kde.org/show_bug.cgi?id=265709
+ */
+
+void KListWidgetSearchLineTest::testAddItems()
+{
+ QListWidget listWidget;
+ listWidget.addItem("Matching test item");
+ listWidget.addItem("Another test item");
+
+ KListWidgetSearchLine searchLine(0, &listWidget);
+ searchLine.setText("match");
+
+ // The initial filtering is delayed; we have to wait
+ while(!listWidget.item(1)->isHidden()) {
+ QTest::qWait(50);
+ }
+
+ QVERIFY(!listWidget.item(0)->isHidden());
+ QVERIFY(listWidget.item(1)->isHidden());
+
+ // Add two items
+ listWidget.addItem("Another item that matches the search pattern");
+ listWidget.addItem("This item should be hidden");
+
+ QVERIFY(!listWidget.item(0)->isHidden());
+ QVERIFY(listWidget.item(1)->isHidden());
+ QVERIFY(!listWidget.item(2)->isHidden());
+ QVERIFY(listWidget.item(3)->isHidden());
+
+ // Modify an item
+ listWidget.item(3)->setText("Now this item matches");
+
+ QVERIFY(!listWidget.item(0)->isHidden());
+ QVERIFY(listWidget.item(1)->isHidden());
+ QVERIFY(!listWidget.item(2)->isHidden());
+ QVERIFY(!listWidget.item(3)->isHidden());
+}
+
+QTEST_KDEMAIN(KListWidgetSearchLineTest, GUI)
+
+#include "klistwidgetsearchlinetest.moc" \ No newline at end of file