libkdepim Library API Documentation

klistviewsearchline_pimcopy.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_pimcopy.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 namespace KPIM {
00031 
00032 class KListViewSearchLine::KListViewSearchLinePrivate
00033 {
00034 public:
00035     KListViewSearchLinePrivate() :
00036         listView(0),
00037         caseSensitive(false),
00038         activeSearch(false),
00039         keepParentsVisible(true),
00040         queuedSearches(0) {}
00041 
00042     KListView *listView;
00043     bool caseSensitive;
00044     bool activeSearch;
00045     bool keepParentsVisible;
00046     QString search;
00047     int queuedSearches;
00048     QValueList<int> searchColumns;
00049 };
00050 
00052 // public methods
00054 
00055 KListViewSearchLine::KListViewSearchLine(QWidget *parent, KListView *listView, const char *name) :
00056     KLineEdit(parent, name)
00057 {
00058     d = new KListViewSearchLinePrivate;
00059 
00060     d->listView = listView;
00061 
00062     connect(this, SIGNAL(textChanged(const QString &)),
00063             this, SLOT(queueSearch(const QString &)));
00064 
00065     if(listView) {
00066         connect(listView, SIGNAL(destroyed()),
00067                 this, SLOT(listViewDeleted()));
00068 
00069         connect(listView, SIGNAL(itemAdded(QListViewItem *)),
00070                 this, SLOT(itemAdded(QListViewItem *)));
00071     }
00072     else
00073         setEnabled(false);
00074 }
00075 
00076 KListViewSearchLine::~KListViewSearchLine()
00077 {
00078     delete d;
00079 }
00080 
00081 bool KListViewSearchLine::caseSensitive() const
00082 {
00083     return d->caseSensitive;
00084 }
00085 
00086 QValueList<int> KListViewSearchLine::searchColumns() const
00087 {
00088     return d->searchColumns;
00089 }
00090 
00091 bool KListViewSearchLine::keepParentsVisible() const
00092 {
00093     return d->keepParentsVisible;
00094 }
00095 
00096 KListView *KListViewSearchLine::listView() const
00097 {
00098     return d->listView;
00099 }
00100 
00102 // public slots
00104 
00105 void KListViewSearchLine::updateSearch(const QString &s)
00106 {
00107     if(!d->listView)
00108         return;
00109 
00110     d->search = s.isNull() ? text() : s;
00111 
00112     // If there's a selected item that is visible, make sure that it's visible
00113     // when the search changes too (assuming that it still matches).
00114 
00115     QListViewItem *currentItem = 0;
00116 
00117     switch(d->listView->selectionMode())
00118     {
00119     case KListView::NoSelection:
00120         break;
00121     case KListView::Single:
00122         currentItem = d->listView->selectedItem();
00123         break;
00124     default:
00125     {
00126         int flags = QListViewItemIterator::Selected | QListViewItemIterator::Visible;
00127         for(QListViewItemIterator it(d->listView, flags);
00128             it.current() && !currentItem;
00129             ++it)
00130         {
00131             if(d->listView->itemRect(it.current()).isValid())
00132                 currentItem = it.current();
00133         }
00134     }
00135     }
00136 
00137     if(d->keepParentsVisible)
00138         checkItemParentsVisible(d->listView->firstChild());
00139     else
00140         checkItemParentsNotVisible();
00141 
00142     if(currentItem)
00143         d->listView->ensureItemVisible(currentItem);
00144 }
00145 
00146 void KListViewSearchLine::setCaseSensitive(bool cs)
00147 {
00148     d->caseSensitive = cs;
00149 }
00150 
00151 void KListViewSearchLine::setKeepParentsVisible(bool v)
00152 {
00153     d->keepParentsVisible = v;
00154 }
00155 
00156 void KListViewSearchLine::setSearchColumns(const QValueList<int> &columns)
00157 {
00158     d->searchColumns = columns;
00159 }
00160 
00161 void KListViewSearchLine::setListView(KListView *lv)
00162 {
00163     if(d->listView) {
00164         disconnect(d->listView, SIGNAL(destroyed()),
00165                    this, SLOT(listViewDeleted()));
00166 
00167         disconnect(d->listView, SIGNAL(itemAdded(QListViewItem *)),
00168                    this, SLOT(itemAdded(QListViewItem *)));
00169     }
00170 
00171     d->listView = lv;
00172 
00173     if(lv) {
00174         connect(d->listView, SIGNAL(destroyed()),
00175                 this, SLOT(listViewDeleted()));
00176 
00177         connect(d->listView, SIGNAL(itemAdded(QListViewItem *)),
00178                 this, SLOT(itemAdded(QListViewItem *)));
00179     }
00180 
00181     setEnabled(bool(lv));
00182 }
00183 
00185 // protected members
00187 
00188 bool KListViewSearchLine::itemMatches(const QListViewItem *item, const QString &s) const
00189 {
00190     if(s.isEmpty())
00191         return true;
00192 
00193     // If the search column list is populated, search just the columns
00194     // specifified.  If it is empty default to searching all of the columns.
00195 
00196     if(!d->searchColumns.isEmpty()) {
00197         QValueList<int>::ConstIterator it = d->searchColumns.begin();
00198         for(; it != d->searchColumns.end(); ++it) {
00199             if(*it < item->listView()->columns() &&
00200                item->text(*it).find(s, 0, d->caseSensitive) >= 0)
00201             {
00202                 return true;
00203             }
00204         }
00205     }
00206     else {
00207         for(int i = 0; i < item->listView()->columns(); i++) {
00208             if(item->text(i).find(s, 0, d->caseSensitive) >= 0)
00209                 return true;
00210         }
00211     }
00212 
00213     return false;
00214 }
00215 
00216 QPopupMenu *KListViewSearchLine::createPopupMenu()
00217 {
00218     QPopupMenu *popup = KLineEdit::createPopupMenu();
00219 
00220     QPopupMenu *subMenu = new QPopupMenu( popup );
00221     connect( subMenu, SIGNAL( activated(int) ), this, SLOT( searchColumnsMenuActivated(int) ) );
00222 
00223     popup->insertSeparator();
00224     popup->insertItem( i18n("Search Columns"), subMenu );
00225     
00226     subMenu->insertItem(i18n("All Columns"), KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID);
00227     subMenu->insertSeparator();    
00228     
00229     bool allColumnsAreSearchColumns = true;
00230     for(int i = 0; i < d->listView->columns(); i++) {
00231         subMenu->insertItem(d->listView->columnText(i), i);
00232         if (d->searchColumns.isEmpty() || d->searchColumns.find(i) != d->searchColumns.end())
00233             subMenu->setItemChecked(i, true);
00234         else
00235             allColumnsAreSearchColumns = false;
00236     }
00237     subMenu->setItemChecked(KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID, allColumnsAreSearchColumns);
00238     
00239     // searchColumnsMenuActivated() relies on one possible "all" representation
00240     if (allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
00241       d->searchColumns.clear();
00242     
00243     return popup;   
00244 }    
00245 
00247 // protected slots
00249 
00250 void KListViewSearchLine::queueSearch(const QString &search)
00251 {
00252     d->queuedSearches++;
00253     d->search = search;
00254     QTimer::singleShot(200, this, SLOT(activateSearch()));
00255 }
00256 
00257 void KListViewSearchLine::activateSearch()
00258 {
00259     d->queuedSearches--;
00260 
00261     if(d->queuedSearches == 0)
00262         updateSearch(d->search);
00263 }
00264 
00266 // private slots
00268 
00269 void KListViewSearchLine::itemAdded(QListViewItem *item) const
00270 {
00271     item->setVisible(itemMatches(item, text()));
00272 }
00273 
00274 void KListViewSearchLine::listViewDeleted()
00275 {
00276     d->listView = 0;
00277     setEnabled(false);
00278 }
00279 
00280 void KListViewSearchLine::searchColumnsMenuActivated(int id)
00281 {
00282     if (id==KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID) {
00283       if (d->searchColumns.isEmpty())
00284           d->searchColumns.append(0);
00285       else
00286           d->searchColumns.clear();
00287     }
00288     else {
00289       if (d->searchColumns.find(id) != d->searchColumns.end())
00290           d->searchColumns.remove(id);
00291       else {
00292           if (d->searchColumns.isEmpty())
00293              for(int i = 0; i < d->listView->columns(); i++) {
00294                  if (i!=id)
00295                      d->searchColumns.append(i);
00296              }
00297           else
00298               d->searchColumns.append(id);
00299       }
00300     }
00301     updateSearch();
00302 }
00303 
00305 // private methods
00307 
00308 void KListViewSearchLine::checkItemParentsNotVisible()
00309 {
00310     QListViewItemIterator it(d->listView);
00311     for(; it.current(); ++it)
00312     {
00313         QListViewItem *item = it.current();
00314         if(itemMatches(item, d->search))
00315             item->setVisible(true);
00316         else
00317             item->setVisible(false);
00318     }
00319 }
00320 
00321 
00322 bool KListViewSearchLine::checkItemParentsVisible(QListViewItem *item)
00323 {
00324     bool visible = false;
00325     for(; item; item = item->nextSibling()) {
00326         if((item->firstChild() && checkItemParentsVisible(item->firstChild())) ||
00327            itemMatches(item, d->search))
00328         {
00329             item->setVisible( true );
00330             visible = true;
00331         }
00332         else
00333             item->setVisible(false);
00334     }
00335     return visible;
00336 }
00337 
00338 }
00339 #include "klistviewsearchline_pimcopy.moc"
KDE Logo
This file is part of the documentation for libkdepim Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Aug 2 09:53:36 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003