KDEUI
klistwidgetsearchline.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (c) 2003 Scott Wheeler <wheeler@kde.org> 00003 Copyright (c) 2004 Gustavo Sverzut Barbieri <gsbarbieri@users.sourceforge.net> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "klistwidgetsearchline.h" 00021 00022 #include <QtGui/QListWidget> 00023 #include <QtGui/QApplication> 00024 #include <QtGui/QKeyEvent> 00025 #include <QtCore/QEvent> 00026 00027 #include <klocale.h> 00028 #include <QtCore/QTimer> 00029 #include <kdebug.h> 00030 00031 #define DEFAULT_CASESENSITIVE Qt::CaseInsensitive 00032 00033 class KListWidgetSearchLine::KListWidgetSearchLinePrivate 00034 { 00035 public: 00036 KListWidgetSearchLinePrivate(KListWidgetSearchLine *parent) : 00037 q( parent ), 00038 listWidget( 0 ), 00039 caseSensitivity( DEFAULT_CASESENSITIVE ), 00040 activeSearch( false ), 00041 queuedSearches( 0 ) 00042 {} 00043 00044 void _k_listWidgetDeleted(); 00045 void _k_queueSearch(const QString&); 00046 void _k_activateSearch(); 00047 00048 void init( QListWidget *listWidget = 0 ); 00049 00050 KListWidgetSearchLine *q; 00051 QListWidget *listWidget; 00052 Qt::CaseSensitivity caseSensitivity; 00053 bool activeSearch; 00054 QString search; 00055 int queuedSearches; 00056 }; 00057 00058 /****************************************************************************** 00059 * Public Methods * 00060 *****************************************************************************/ 00061 KListWidgetSearchLine::KListWidgetSearchLine( QWidget *parent, QListWidget *listWidget ) : 00062 KLineEdit( parent ), 00063 d( new KListWidgetSearchLinePrivate(this) ) 00064 00065 { 00066 d->init( listWidget ); 00067 } 00068 00069 KListWidgetSearchLine::~KListWidgetSearchLine() 00070 { 00071 clear(); // returning items back to listWidget 00072 delete d; 00073 } 00074 00075 Qt::CaseSensitivity KListWidgetSearchLine::caseSensitive() const 00076 { 00077 return d->caseSensitivity; 00078 } 00079 00080 QListWidget *KListWidgetSearchLine::listWidget() const 00081 { 00082 return d->listWidget; 00083 } 00084 00085 /****************************************************************************** 00086 * Public Slots * 00087 *****************************************************************************/ 00088 void KListWidgetSearchLine::updateSearch( const QString &s ) 00089 { 00090 QListWidget *lw = d->listWidget; 00091 if ( !lw ) 00092 return ; // disabled 00093 00094 QString search = d->search = s.isNull() ? text() : s; 00095 00096 QListWidgetItem *currentItem = lw->currentItem(); 00097 00098 // Remove Non-Matching items 00099 int index = 0; 00100 while ( index < lw->count() ) { 00101 QListWidgetItem *item = lw->item(index); 00102 if ( ! itemMatches( item, search ) ) { 00103 item->setHidden( true ); 00104 00105 if ( item == currentItem ) { 00106 currentItem = 0; // It's not in listWidget anymore. 00107 } 00108 } else if ( item->isHidden() ){ 00109 item->setHidden( false ); 00110 } 00111 00112 index++; 00113 } 00114 00115 if ( lw->isSortingEnabled() ) 00116 lw->sortItems(); 00117 00118 if ( currentItem != 0 ) 00119 lw->scrollToItem( currentItem ); 00120 } 00121 00122 void KListWidgetSearchLine::clear() 00123 { 00124 // Show items back to QListWidget 00125 if ( d->listWidget != 0 ) { 00126 for (int i = 0 ; i < d->listWidget->count(); ++i) { 00127 d->listWidget->item( i )->setHidden( false ); 00128 } 00129 } 00130 00131 d->search = ""; 00132 d->queuedSearches = 0; 00133 KLineEdit::clear(); 00134 } 00135 00136 void KListWidgetSearchLine::setCaseSensitivity( Qt::CaseSensitivity cs ) 00137 { 00138 d->caseSensitivity = cs; 00139 } 00140 00141 void KListWidgetSearchLine::setListWidget( QListWidget *lw ) 00142 { 00143 if ( d->listWidget != 0 ) 00144 disconnect( d->listWidget, SIGNAL( destroyed() ), 00145 this, SLOT( _k_listWidgetDeleted() ) ); 00146 00147 d->listWidget = lw; 00148 00149 if ( lw != 0 ) { 00150 connect( d->listWidget, SIGNAL( destroyed() ), 00151 this, SLOT( _k_listWidgetDeleted() ) ); 00152 setEnabled( true ); 00153 } else 00154 setEnabled( false ); 00155 } 00156 00157 /****************************************************************************** 00158 * Protected Methods * 00159 *****************************************************************************/ 00160 bool KListWidgetSearchLine::itemMatches( const QListWidgetItem *item, 00161 const QString &s ) const 00162 { 00163 if ( s.isEmpty() ) 00164 return true; 00165 00166 if ( item == 0 ) 00167 return false; 00168 00169 return ( item->text().indexOf( s, 0, 00170 caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive ) >= 0 ); 00171 } 00172 00173 void KListWidgetSearchLine::KListWidgetSearchLinePrivate::init( QListWidget *_listWidget ) 00174 { 00175 listWidget = _listWidget; 00176 00177 connect( q, SIGNAL( textChanged( const QString & ) ), 00178 q, SLOT( _k_queueSearch( const QString & ) ) ); 00179 00180 if ( listWidget != 0 ) { 00181 connect( listWidget, SIGNAL( destroyed() ), 00182 q, SLOT( _k_listWidgetDeleted() ) ); 00183 q->setEnabled( true ); 00184 } else { 00185 q->setEnabled( false ); 00186 } 00187 00188 q->setClearButtonShown(true); 00189 } 00190 00191 bool KListWidgetSearchLine::event(QEvent *event) { 00192 00193 if (event->type() == QEvent::KeyPress) { 00194 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); 00195 if(keyEvent->matches(QKeySequence::MoveToNextLine) || keyEvent->matches(QKeySequence::SelectNextLine) || 00196 keyEvent->matches(QKeySequence::MoveToPreviousLine) || keyEvent->matches(QKeySequence::SelectPreviousLine) || 00197 keyEvent->matches(QKeySequence::MoveToNextPage) || keyEvent->matches(QKeySequence::SelectNextPage) || 00198 keyEvent->matches(QKeySequence::MoveToPreviousPage) || keyEvent->matches(QKeySequence::SelectPreviousPage) || 00199 keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) 00200 { 00201 if(d->listWidget) { 00202 QApplication::sendEvent(d->listWidget, event); 00203 return true; 00204 } 00205 } 00206 } 00207 return KLineEdit::event(event); 00208 } 00209 /****************************************************************************** 00210 * Protected Slots * 00211 *****************************************************************************/ 00212 void KListWidgetSearchLine::KListWidgetSearchLinePrivate::_k_queueSearch( const QString &s ) 00213 { 00214 queuedSearches++; 00215 search = s; 00216 QTimer::singleShot( 200, q, SLOT( _k_activateSearch() ) ); 00217 } 00218 00219 void KListWidgetSearchLine::KListWidgetSearchLinePrivate::_k_activateSearch() 00220 { 00221 queuedSearches--; 00222 00223 if ( queuedSearches <= 0 ) { 00224 q->updateSearch( search ); 00225 queuedSearches = 0; 00226 } 00227 } 00228 00229 /****************************************************************************** 00230 * Private Slots * 00231 *****************************************************************************/ 00232 void KListWidgetSearchLine::KListWidgetSearchLinePrivate::_k_listWidgetDeleted() 00233 { 00234 listWidget = 0; 00235 q->setEnabled( false ); 00236 } 00237 00238 #include "klistwidgetsearchline.moc"
KDE 4.6 API Reference