00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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()
00075 {
00076
delete d;
00077 }
00078
00079 bool KListViewSearchLine::caseSensitive()
const
00080
{
00081
return d->caseSensitive;
00082 }
00083
00084 QValueList<int> KListViewSearchLine::searchColumns()
const
00085
{
00086
return d->searchColumns;
00087 }
00088
00089 bool KListViewSearchLine::keepParentsVisible()
const
00090
{
00091
return d->keepParentsVisible;
00092 }
00093
00094 KListView *
KListViewSearchLine::listView()
const
00095
{
00096
return d->listView;
00097 }
00098
00100
00102
00103 void KListViewSearchLine::updateSearch(
const QString &s)
00104 {
00105
if(!d->listView)
00106
return;
00107
00108 d->search = s.isNull() ? text() : s;
00109
00110
00111
00112
00113
QListViewItem *currentItem = 0;
00114
00115
switch(d->listView->selectionMode())
00116 {
00117
case KListView::NoSelection:
00118
break;
00119
case KListView::Single:
00120 currentItem = d->listView->selectedItem();
00121
break;
00122
default:
00123 {
00124
int flags = QListViewItemIterator::Selected | QListViewItemIterator::Visible;
00125
for(
QListViewItemIterator it(d->listView, flags);
00126 it.current() && !currentItem;
00127 ++it)
00128 {
00129
if(d->listView->itemRect(it.current()).isValid())
00130 currentItem = it.current();
00131 }
00132 }
00133 }
00134
00135
if(d->keepParentsVisible)
00136 checkItemParentsVisible(d->listView->firstChild());
00137
else
00138 checkItemParentsNotVisible();
00139
00140
if(currentItem)
00141 d->listView->ensureItemVisible(currentItem);
00142 }
00143
00144 void KListViewSearchLine::setCaseSensitive(
bool cs)
00145 {
00146 d->caseSensitive = cs;
00147 }
00148
00149 void KListViewSearchLine::setKeepParentsVisible(
bool v)
00150 {
00151 d->keepParentsVisible = v;
00152 }
00153
00154 void KListViewSearchLine::setSearchColumns(
const QValueList<int> &columns)
00155 {
00156 d->searchColumns = columns;
00157 }
00158
00159 void KListViewSearchLine::setListView(
KListView *lv)
00160 {
00161
if(d->listView) {
00162 disconnect(d->listView, SIGNAL(destroyed()),
00163
this, SLOT(listViewDeleted()));
00164
00165 disconnect(d->listView, SIGNAL(itemAdded(
QListViewItem *)),
00166
this, SLOT(itemAdded(
QListViewItem *)));
00167 }
00168
00169 d->listView = lv;
00170
00171
if(lv) {
00172 connect(d->listView, SIGNAL(destroyed()),
00173
this, SLOT(listViewDeleted()));
00174
00175 connect(d->listView, SIGNAL(itemAdded(
QListViewItem *)),
00176
this, SLOT(itemAdded(
QListViewItem *)));
00177 }
00178
00179 setEnabled(
bool(lv));
00180 }
00181
00183
00185
00186 bool KListViewSearchLine::itemMatches(
const QListViewItem *item,
const QString &s)
const
00187
{
00188
if(s.isEmpty())
00189
return true;
00190
00191
00192
00193
00194
if(!d->searchColumns.isEmpty()) {
00195
QValueList<int>::ConstIterator it = d->searchColumns.begin();
00196
for(; it != d->searchColumns.end(); ++it) {
00197
if(*it < item->listView()->columns() &&
00198 item->text(*it).find(s, 0, d->caseSensitive) >= 0)
00199
return true;
00200 }
00201 }
00202
else {
00203
for(
int i = 0; i < item->listView()->columns(); i++) {
00204
if(item->text(i).find(s, 0, d->caseSensitive) >= 0)
00205
return true;
00206 }
00207 }
00208
00209
return false;
00210 }
00211
00212 QPopupMenu *
KListViewSearchLine::createPopupMenu()
00213 {
00214
QPopupMenu *popup =
KLineEdit::createPopupMenu();
00215
00216
QPopupMenu *subMenu =
new QPopupMenu( popup );
00217 connect( subMenu, SIGNAL( activated(
int) ),
this, SLOT( searchColumnsMenuActivated(
int) ) );
00218
00219 popup->insertSeparator();
00220 popup->insertItem( i18n(
"Search Columns"), subMenu );
00221
00222 subMenu->insertItem(i18n(
"All Columns"), KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID);
00223 subMenu->insertSeparator();
00224
00225
bool allColumnsAreSearchColumns =
true;
00226
for(
int i = 0; i < d->listView->columns(); i++) {
00227 subMenu->insertItem(d->listView->columnText(i), i);
00228
if (d->searchColumns.isEmpty() || d->searchColumns.find(i) != d->searchColumns.end())
00229 subMenu->setItemChecked(i,
true);
00230
else
00231 allColumnsAreSearchColumns =
false;
00232 }
00233 subMenu->setItemChecked(KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID, allColumnsAreSearchColumns);
00234
00235
00236
if (allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
00237 d->searchColumns.clear();
00238
00239
return popup;
00240 }
00241
00243
00245
00246 void KListViewSearchLine::queueSearch(
const QString &search)
00247 {
00248 d->queuedSearches++;
00249 d->search = search;
00250 QTimer::singleShot(200,
this, SLOT(
activateSearch()));
00251 }
00252
00253 void KListViewSearchLine::activateSearch()
00254 {
00255 d->queuedSearches--;
00256
00257
if(d->queuedSearches == 0)
00258
updateSearch(d->search);
00259 }
00260
00262
00264
00265
void KListViewSearchLine::itemAdded(
QListViewItem *item)
const
00266
{
00267 item->setVisible(itemMatches(item, text()));
00268 }
00269
00270
void KListViewSearchLine::listViewDeleted()
00271 {
00272 d->listView = 0;
00273 setEnabled(
false);
00274 }
00275
00276
void KListViewSearchLine::searchColumnsMenuActivated(
int id)
00277 {
00278
if (
id==KLISTVIEWSEARCHLINE_ALLCOLUMNS_ID) {
00279
if (d->searchColumns.isEmpty())
00280 d->searchColumns.append(0);
00281
else
00282 d->searchColumns.clear();
00283 }
00284
else {
00285
if (d->searchColumns.find(
id) != d->searchColumns.end())
00286 d->searchColumns.remove(
id);
00287
else {
00288
if (d->searchColumns.isEmpty())
00289
for(
int i = 0; i < d->listView->columns(); i++) {
00290
if (i!=
id)
00291 d->searchColumns.append(i);
00292 }
00293
else
00294 d->searchColumns.append(
id);
00295 }
00296 }
00297
updateSearch();
00298 }
00299
00301
00303
00304
void KListViewSearchLine::checkItemParentsNotVisible()
00305 {
00306
QListViewItemIterator it(d->listView);
00307
for(; it.current(); ++it)
00308 {
00309
QListViewItem *item = it.current();
00310
if(
itemMatches(item, d->search))
00311 item->setVisible(
true);
00312
else
00313 item->setVisible(
false);
00314 }
00315 }
00316
00317
bool KListViewSearchLine::checkItemParentsVisible(
QListViewItem *item)
00318 {
00319
bool visible =
false;
00320
for(; item; item = item->nextSibling()) {
00321
if((item->firstChild() && checkItemParentsVisible(item->firstChild())) ||
00322
itemMatches(item, d->search))
00323 {
00324 item->setVisible(
true );
00325 visible =
true;
00326 }
00327
else
00328 item->setVisible(
false);
00329 }
00330
return visible;
00331 }
00332
00333
#include "klistviewsearchline.moc"