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     if (d->listView->columns()>1) {
00230         QPopupMenu *subMenu = new QPopupMenu( popup );
00231         connect( subMenu, SIGNAL( activated(int) ), this, SLOT( searchColumnsMenuActivated(int) ) );
00232 
00233         popup->insertSeparator();
00234         popup->insertItem( i18n("Search Columns"), subMenu );
00235     
00236         subMenu->insertItem(i18n("All Columns"), KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID);
00237         subMenu->insertSeparator();    
00238     
00239         bool allColumnsAreSearchColumns = true;
00240         for(int i = 0; i < d->listView->columns(); i++) {
00241             subMenu->insertItem(d->listView->columnText(i), i);
00242             if (d->searchColumns.isEmpty() || d->searchColumns.find(i) != d->searchColumns.end())
00243                 subMenu->setItemChecked(i, true);
00244             else
00245                 allColumnsAreSearchColumns = false;
00246         }
00247         subMenu->setItemChecked(KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID, allColumnsAreSearchColumns);
00248     
00249         // searchColumnsMenuActivated() relies on one possible "all" representation
00250         if (allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
00251             d->searchColumns.clear();
00252     }
00253     
00254     return popup;   
00255 }    
00256 
00258 // protected slots
00260 
00261 void KListViewSearchLine::queueSearch(const QString &search)
00262 {
00263     d->queuedSearches++;
00264     d->search = search;
00265     QTimer::singleShot(200, this, SLOT(activateSearch()));
00266 }
00267 
00268 void KListViewSearchLine::activateSearch()
00269 {
00270     d->queuedSearches--;
00271 
00272     if(d->queuedSearches == 0)
00273         updateSearch(d->search);
00274 }
00275 
00277 // private slots
00279 
00280 void KListViewSearchLine::itemAdded(QListViewItem *item) const
00281 {
00282     item->setVisible(itemMatches(item, text()));
00283 }
00284 
00285 void KListViewSearchLine::listViewDeleted()
00286 {
00287     d->listView = 0;
00288     setEnabled(false);
00289 }
00290 
00291 void KListViewSearchLine::searchColumnsMenuActivated(int id)
00292 {
00293     if (id==KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID) {
00294       if (d->searchColumns.isEmpty())
00295           d->searchColumns.append(0);
00296       else
00297           d->searchColumns.clear();
00298     }
00299     else {
00300       if (d->searchColumns.find(id) != d->searchColumns.end())
00301           d->searchColumns.remove(id);
00302       else {
00303           if (d->searchColumns.isEmpty())
00304              for(int i = 0; i < d->listView->columns(); i++) {
00305                  if (i!=id)
00306                      d->searchColumns.append(i);
00307              }
00308           else
00309               d->searchColumns.append(id);
00310       }
00311     }
00312     updateSearch();
00313 }
00314 
00316 // private methods
00318 
00319 void KListViewSearchLine::checkItemParentsNotVisible()
00320 {
00321     QListViewItemIterator it(d->listView);
00322     for(; it.current(); ++it)
00323     {
00324         QListViewItem *item = it.current();
00325         if(itemMatches(item, d->search))
00326             item->setVisible(true);
00327         else
00328             item->setVisible(false);
00329     }
00330 }
00331 
00332 bool KListViewSearchLine::checkItemParentsVisible(QListViewItem *item)
00333 {
00334     bool visible = false;
00335     for(; item; item = item->nextSibling()) {
00336         if((item->firstChild() && checkItemParentsVisible(item->firstChild())) ||
00337            itemMatches(item, d->search))
00338         {
00339             item->setVisible( true );
00340             visible = true;
00341         }
00342         else
00343             item->setVisible(false);
00344     }
00345     return visible;
00346 }
00347 
00348 #include "klistviewsearchline.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:12:01 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003