00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
00113
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
00187
00188 bool KListViewSearchLine::itemMatches(
const QListViewItem *item,
const QString &s)
const
00189
{
00190
if(s.isEmpty())
00191
return true;
00192
00193
00194
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
00240
if (allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
00241 d->searchColumns.clear();
00242
00243
return popup;
00244 }
00245
00247
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
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
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"