kdeui Library API Documentation

klistviewsearchline.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (c) 2003 Scott Wheeler <wheeler@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016    Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include "klistviewsearchline.h"
00020 
00021 #include <klistview.h>
00022 #include <kdebug.h>
00023 #include <klocale.h>
00024 
00025 #include <qtimer.h>
00026 #include <qpopupmenu.h>
00027 
00028 #define KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID 2004
00029 
00030 class KListViewSearchLine::KListViewSearchLinePrivate
00031 {
00032 public:
00033     KListViewSearchLinePrivate() :
00034         listView(0),
00035         caseSensitive(false),
00036         activeSearch(false),
00037         keepParentsVisible(true),
00038         queuedSearches(0) {}
00039 
00040     KListView *listView;
00041     bool caseSensitive;
00042     bool activeSearch;
00043     bool keepParentsVisible;
00044     QString search;
00045     int queuedSearches;
00046     QValueList<int> searchColumns;
00047 };
00048 
00050 // public methods
00052 
00053 KListViewSearchLine::KListViewSearchLine(QWidget *parent, KListView *listView, const char *name) :
00054     KLineEdit(parent, name)
00055 {
00056     d = new KListViewSearchLinePrivate;
00057 
00058     d->listView = listView;
00059 
00060     connect(this, SIGNAL(textChanged(const QString &)),
00061             this, SLOT(queueSearch(const QString &)));
00062 
00063     if(listView) {
00064         connect(listView, SIGNAL(destroyed()),
00065                 this, SLOT(listViewDeleted()));
00066 
00067         connect(listView, SIGNAL(itemAdded(QListViewItem *)),
00068                 this, SLOT(itemAdded(QListViewItem *)));
00069     }
00070     else
00071         setEnabled(false);
00072 }
00073 
00074 KListViewSearchLine::KListViewSearchLine(QWidget *parent, const char *name) :
00075     KLineEdit(parent, name)
00076 {
00077     d = new KListViewSearchLinePrivate;
00078 
00079     d->listView = 0L;
00080 
00081     connect(this, SIGNAL(textChanged(const QString &)),
00082             this, SLOT(queueSearch(const QString &)));
00083 
00084     setEnabled(false);
00085 }
00086 
00087 KListViewSearchLine::~KListViewSearchLine()
00088 {
00089     delete d;
00090 }
00091 
00092 bool KListViewSearchLine::caseSensitive() const
00093 {
00094     return d->caseSensitive;
00095 }
00096 
00097 QValueList<int> KListViewSearchLine::searchColumns() const
00098 {
00099     return d->searchColumns;
00100 }
00101 
00102 bool KListViewSearchLine::keepParentsVisible() const
00103 {
00104     return d->keepParentsVisible;
00105 }
00106 
00107 KListView *KListViewSearchLine::listView() const
00108 {
00109     return d->listView;
00110 }
00111 
00113 // public slots
00115 
00116 void KListViewSearchLine::updateSearch(const QString &s)
00117 {
00118     if(!d->listView)
00119         return;
00120 
00121     d->search = s.isNull() ? text() : s;
00122 
00123     // If there's a selected item that is visible, make sure that it's visible
00124     // when the search changes too (assuming that it still matches).
00125 
00126     QListViewItem *currentItem = 0;
00127 
00128     switch(d->listView->selectionMode())
00129     {
00130     case KListView::NoSelection:
00131         break;
00132     case KListView::Single:
00133         currentItem = d->listView->selectedItem();
00134         break;
00135     default:
00136     {
00137         int flags = QListViewItemIterator::Selected | QListViewItemIterator::Visible;
00138         for(QListViewItemIterator it(d->listView, flags);
00139             it.current() && !currentItem;
00140             ++it)
00141         {
00142             if(d->listView->itemRect(it.current()).isValid())
00143                 currentItem = it.current();
00144         }
00145     }
00146     }
00147 
00148     if(d->keepParentsVisible)
00149         checkItemParentsVisible(d->listView->firstChild());
00150     else
00151         checkItemParentsNotVisible();
00152 
00153     if(currentItem)
00154         d->listView->ensureItemVisible(currentItem);
00155 }
00156 
00157 void KListViewSearchLine::setCaseSensitive(bool cs)
00158 {
00159     d->caseSensitive = cs;
00160 }
00161 
00162 void KListViewSearchLine::setKeepParentsVisible(bool v)
00163 {
00164     d->keepParentsVisible = v;
00165 }
00166 
00167 void KListViewSearchLine::setSearchColumns(const QValueList<int> &columns)
00168 {
00169     d->searchColumns = columns;
00170 }
00171 
00172 void KListViewSearchLine::setListView(KListView *lv)
00173 {
00174     if(d->listView) {
00175         disconnect(d->listView, SIGNAL(destroyed()),
00176                    this, SLOT(listViewDeleted()));
00177 
00178         disconnect(d->listView, SIGNAL(itemAdded(QListViewItem *)),
00179                    this, SLOT(itemAdded(QListViewItem *)));
00180     }
00181 
00182     d->listView = lv;
00183 
00184     if(lv) {
00185         connect(d->listView, SIGNAL(destroyed()),
00186                 this, SLOT(listViewDeleted()));
00187 
00188         connect(d->listView, SIGNAL(itemAdded(QListViewItem *)),
00189                 this, SLOT(itemAdded(QListViewItem *)));
00190     }
00191 
00192     setEnabled(bool(lv));
00193 }
00194 
00196 // protected members
00198 
00199 bool KListViewSearchLine::itemMatches(const QListViewItem *item, const QString &s) const
00200 {
00201     if(s.isEmpty())
00202         return true;
00203 
00204     // If the search column list is populated, search just the columns
00205     // specifified.  If it is empty default to searching all of the columns.
00206 
00207     if(!d->searchColumns.isEmpty()) {
00208         QValueList<int>::ConstIterator it = d->searchColumns.begin();
00209         for(; it != d->searchColumns.end(); ++it) {
00210             if(*it < item->listView()->columns() &&
00211                item->text(*it).find(s, 0, d->caseSensitive) >= 0)
00212                 return true;
00213         }
00214     }
00215     else {
00216         for(int i = 0; i < item->listView()->columns(); i++) {
00217             if(item->text(i).find(s, 0, d->caseSensitive) >= 0)
00218                 return true;
00219         }
00220     }
00221 
00222     return false;
00223 }
00224 
00225 QPopupMenu *KListViewSearchLine::createPopupMenu()
00226 {
00227     QPopupMenu *popup = KLineEdit::createPopupMenu();
00228 
00229     QPopupMenu *subMenu = new QPopupMenu( popup );
00230     connect( subMenu, SIGNAL( activated(int) ), this, SLOT( searchColumnsMenuActivated(int) ) );
00231 
00232     popup->insertSeparator();
00233     popup->insertItem( i18n("Search Columns"), subMenu );
00234     
00235     subMenu->insertItem(i18n("All Columns"), KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID);
00236     subMenu->insertSeparator();    
00237     
00238     bool allColumnsAreSearchColumns = true;
00239     for(int i = 0; i < d->listView->columns(); i++) {
00240         subMenu->insertItem(d->listView->columnText(i), i);
00241         if (d->searchColumns.isEmpty() || d->searchColumns.find(i) != d->searchColumns.end())
00242             subMenu->setItemChecked(i, true);
00243         else
00244             allColumnsAreSearchColumns = false;
00245     }
00246     subMenu->setItemChecked(KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID, allColumnsAreSearchColumns);
00247     
00248     // searchColumnsMenuActivated() relies on one possible "all" representation
00249     if (allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
00250       d->searchColumns.clear();
00251     
00252     return popup;   
00253 }    
00254 
00256 // protected slots
00258 
00259 void KListViewSearchLine::queueSearch(const QString &search)
00260 {
00261     d->queuedSearches++;
00262     d->search = search;
00263     QTimer::singleShot(200, this, SLOT(activateSearch()));
00264 }
00265 
00266 void KListViewSearchLine::activateSearch()
00267 {
00268     d->queuedSearches--;
00269 
00270     if(d->queuedSearches == 0)
00271         updateSearch(d->search);
00272 }
00273 
00275 // private slots
00277 
00278 void KListViewSearchLine::itemAdded(QListViewItem *item) const
00279 {
00280     item->setVisible(itemMatches(item, text()));
00281 }
00282 
00283 void KListViewSearchLine::listViewDeleted()
00284 {
00285     d->listView = 0;
00286     setEnabled(false);
00287 }
00288 
00289 void KListViewSearchLine::searchColumnsMenuActivated(int id)
00290 {
00291     if (id==KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID) {
00292       if (d->searchColumns.isEmpty())
00293           d->searchColumns.append(0);
00294       else
00295           d->searchColumns.clear();
00296     }
00297     else {
00298       if (d->searchColumns.find(id) != d->searchColumns.end())
00299           d->searchColumns.remove(id);
00300       else {
00301           if (d->searchColumns.isEmpty())
00302              for(int i = 0; i < d->listView->columns(); i++) {
00303                  if (i!=id)
00304                      d->searchColumns.append(i);
00305              }
00306           else
00307               d->searchColumns.append(id);
00308       }
00309     }
00310     updateSearch();
00311 }
00312 
00314 // private methods
00316 
00317 void KListViewSearchLine::checkItemParentsNotVisible()
00318 {
00319     QListViewItemIterator it(d->listView);
00320     for(; it.current(); ++it)
00321     {
00322         QListViewItem *item = it.current();
00323         if(itemMatches(item, d->search))
00324             item->setVisible(true);
00325         else
00326             item->setVisible(false);
00327     }
00328 }
00329 
00330 bool KListViewSearchLine::checkItemParentsVisible(QListViewItem *item)
00331 {
00332     bool visible = false;
00333     for(; item; item = item->nextSibling()) {
00334         if((item->firstChild() && checkItemParentsVisible(item->firstChild())) ||
00335            itemMatches(item, d->search))
00336         {
00337             item->setVisible( true );
00338             visible = true;
00339         }
00340         else
00341             item->setVisible(false);
00342     }
00343     return visible;
00344 }
00345 
00346 #include "klistviewsearchline.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Feb 18 15:10:19 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003