00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "tdelistviewsearchline.h"
00020
00021 #include <tdelistview.h>
00022 #include <kiconloader.h>
00023 #include <tdetoolbar.h>
00024 #include <tdetoolbarbutton.h>
00025 #include <kdebug.h>
00026 #include <tdelocale.h>
00027
00028 #include <tqapplication.h>
00029 #include <tqtimer.h>
00030 #include <tqpopupmenu.h>
00031 #include <tqlabel.h>
00032 #include <tqheader.h>
00033
00034 #define KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID 2004
00035
00036 class TDEListViewSearchLine::TDEListViewSearchLinePrivate
00037 {
00038 public:
00039 TDEListViewSearchLinePrivate() :
00040 listView(0),
00041 caseSensitive(false),
00042 activeSearch(false),
00043 keepParentsVisible(true),
00044 queuedSearches(0) {}
00045
00046 TDEListView *listView;
00047 bool caseSensitive;
00048 bool activeSearch;
00049 bool keepParentsVisible;
00050 TQString search;
00051 int queuedSearches;
00052 TQValueList<int> searchColumns;
00053 };
00054
00056
00058
00059 TDEListViewSearchLine::TDEListViewSearchLine(TQWidget *parent, TDEListView *listView, const char *name) :
00060 KLineEdit(parent, name)
00061 {
00062 d = new TDEListViewSearchLinePrivate;
00063
00064 d->listView = listView;
00065
00066 connect(this, TQT_SIGNAL(textChanged(const TQString &)),
00067 this, TQT_SLOT(queueSearch(const TQString &)));
00068
00069 if(listView) {
00070 connect(listView, TQT_SIGNAL(destroyed()),
00071 this, TQT_SLOT(listViewDeleted()));
00072
00073 connect(listView, TQT_SIGNAL(itemAdded(TQListViewItem *)),
00074 this, TQT_SLOT(itemAdded(TQListViewItem *)));
00075 }
00076 else
00077 setEnabled(false);
00078 }
00079
00080 TDEListViewSearchLine::TDEListViewSearchLine(TQWidget *parent, const char *name) :
00081 KLineEdit(parent, name)
00082 {
00083 d = new TDEListViewSearchLinePrivate;
00084
00085 d->listView = 0;
00086
00087 connect(this, TQT_SIGNAL(textChanged(const TQString &)),
00088 this, TQT_SLOT(queueSearch(const TQString &)));
00089
00090 setEnabled(false);
00091 }
00092
00093 TDEListViewSearchLine::~TDEListViewSearchLine()
00094 {
00095 delete d;
00096 }
00097
00098 bool TDEListViewSearchLine::caseSensitive() const
00099 {
00100 return d->caseSensitive;
00101 }
00102
00103 TQValueList<int> TDEListViewSearchLine::searchColumns() const
00104 {
00105 return d->searchColumns;
00106 }
00107
00108 bool TDEListViewSearchLine::keepParentsVisible() const
00109 {
00110 return d->keepParentsVisible;
00111 }
00112
00113 TDEListView *TDEListViewSearchLine::listView() const
00114 {
00115 return d->listView;
00116 }
00117
00119
00121
00122 void TDEListViewSearchLine::updateSearch(const TQString &s)
00123 {
00124 if(!d->listView)
00125 return;
00126
00127 d->search = s.isNull() ? text() : s;
00128
00129
00130
00131
00132 TQListViewItem *currentItem = 0;
00133
00134 switch(d->listView->selectionMode())
00135 {
00136 case TDEListView::NoSelection:
00137 break;
00138 case TDEListView::Single:
00139 currentItem = d->listView->selectedItem();
00140 break;
00141 default:
00142 {
00143 int flags = TQListViewItemIterator::Selected | TQListViewItemIterator::Visible;
00144 for(TQListViewItemIterator it(d->listView, flags);
00145 it.current() && !currentItem;
00146 ++it)
00147 {
00148 if(d->listView->itemRect(it.current()).isValid())
00149 currentItem = it.current();
00150 }
00151 }
00152 }
00153
00154 if(d->keepParentsVisible)
00155 checkItemParentsVisible(d->listView->firstChild());
00156 else
00157 checkItemParentsNotVisible();
00158
00159 if(currentItem)
00160 d->listView->ensureItemVisible(currentItem);
00161 }
00162
00163 void TDEListViewSearchLine::setCaseSensitive(bool cs)
00164 {
00165 d->caseSensitive = cs;
00166 }
00167
00168 void TDEListViewSearchLine::setKeepParentsVisible(bool v)
00169 {
00170 d->keepParentsVisible = v;
00171 }
00172
00173 void TDEListViewSearchLine::setSearchColumns(const TQValueList<int> &columns)
00174 {
00175 d->searchColumns = columns;
00176 }
00177
00178 void TDEListViewSearchLine::setListView(TDEListView *lv)
00179 {
00180 if(d->listView) {
00181 disconnect(d->listView, TQT_SIGNAL(destroyed()),
00182 this, TQT_SLOT(listViewDeleted()));
00183
00184 disconnect(d->listView, TQT_SIGNAL(itemAdded(TQListViewItem *)),
00185 this, TQT_SLOT(itemAdded(TQListViewItem *)));
00186 }
00187
00188 d->listView = lv;
00189
00190 if(lv) {
00191 connect(d->listView, TQT_SIGNAL(destroyed()),
00192 this, TQT_SLOT(listViewDeleted()));
00193
00194 connect(d->listView, TQT_SIGNAL(itemAdded(TQListViewItem *)),
00195 this, TQT_SLOT(itemAdded(TQListViewItem *)));
00196 }
00197
00198 setEnabled(bool(lv));
00199 }
00200
00202
00204
00205 bool TDEListViewSearchLine::itemMatches(const TQListViewItem *item, const TQString &s) const
00206 {
00207 if(s.isEmpty())
00208 return true;
00209
00210
00211
00212
00213 if(!d->searchColumns.isEmpty()) {
00214 TQValueList<int>::ConstIterator it = d->searchColumns.begin();
00215 for(; it != d->searchColumns.end(); ++it) {
00216 if(*it < item->listView()->columns() &&
00217 item->text(*it).find(s, 0, d->caseSensitive) >= 0)
00218 return true;
00219 }
00220 }
00221 else {
00222 for(int i = 0; i < item->listView()->columns(); i++) {
00223 if(item->listView()->columnWidth(i) > 0 &&
00224 item->text(i).find(s, 0, d->caseSensitive) >= 0)
00225 {
00226 return true;
00227 }
00228 }
00229 }
00230
00231 return false;
00232 }
00233
00234 TQPopupMenu *TDEListViewSearchLine::createPopupMenu()
00235 {
00236 TQPopupMenu *popup = KLineEdit::createPopupMenu();
00237
00238 if (d->listView->columns()>1) {
00239 TQPopupMenu *subMenu = new TQPopupMenu(popup);
00240 connect(subMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(searchColumnsMenuActivated(int)));
00241
00242 popup->insertSeparator();
00243 popup->insertItem(i18n("Search Columns"), subMenu);
00244
00245 subMenu->insertItem(i18n("All Visible Columns"), KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID);
00246 subMenu->insertSeparator();
00247
00248 bool allColumnsAreSearchColumns = true;
00249
00250 TQHeader* const header = d->listView->header();
00251 int visibleColumns = 0;
00252 for(int i = 0; i < d->listView->columns(); i++) {
00253 if(d->listView->columnWidth(i)>0) {
00254 TQString columnText = d->listView->columnText(i);
00255 if(columnText.isEmpty()) {
00256 int visiblePosition=1;
00257 for(int j = 0; j < header->mapToIndex(i); j++)
00258 if(d->listView->columnWidth(header->mapToSection(j))>0)
00259 visiblePosition++;
00260 columnText = i18n("Column number %1","Column No. %1").arg(visiblePosition);
00261 }
00262 subMenu->insertItem(columnText, visibleColumns);
00263 if(d->searchColumns.isEmpty() || d->searchColumns.find(i) != d->searchColumns.end())
00264 subMenu->setItemChecked(visibleColumns, true);
00265 else
00266 allColumnsAreSearchColumns = false;
00267 visibleColumns++;
00268 }
00269 }
00270 subMenu->setItemChecked(KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID, allColumnsAreSearchColumns);
00271
00272
00273 if(allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
00274 d->searchColumns.clear();
00275 }
00276
00277 return popup;
00278 }
00279
00281
00283
00284 void TDEListViewSearchLine::queueSearch(const TQString &search)
00285 {
00286 d->queuedSearches++;
00287 d->search = search;
00288 TQTimer::singleShot(200, this, TQT_SLOT(activateSearch()));
00289 }
00290
00291 void TDEListViewSearchLine::activateSearch()
00292 {
00293 --(d->queuedSearches);
00294
00295 if(d->queuedSearches == 0)
00296 updateSearch(d->search);
00297 }
00298
00300
00302
00303 void TDEListViewSearchLine::itemAdded(TQListViewItem *item) const
00304 {
00305 item->setVisible(itemMatches(item, text()));
00306 }
00307
00308 void TDEListViewSearchLine::listViewDeleted()
00309 {
00310 d->listView = 0;
00311 setEnabled(false);
00312 }
00313
00314 void TDEListViewSearchLine::searchColumnsMenuActivated(int id)
00315 {
00316 if(id == KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID) {
00317 if(d->searchColumns.isEmpty())
00318 d->searchColumns.append(0);
00319 else
00320 d->searchColumns.clear();
00321 }
00322 else {
00323 if(d->searchColumns.find(id) != d->searchColumns.end())
00324 d->searchColumns.remove(id);
00325 else {
00326 if(d->searchColumns.isEmpty()) {
00327 for(int i = 0; i < d->listView->columns(); i++) {
00328 if(i != id)
00329 d->searchColumns.append(i);
00330 }
00331 }
00332 else
00333 d->searchColumns.append(id);
00334 }
00335 }
00336 updateSearch();
00337 }
00338
00340
00342
00343 void TDEListViewSearchLine::checkItemParentsNotVisible()
00344 {
00345 TQListViewItemIterator it(d->listView);
00346 for(; it.current(); ++it)
00347 {
00348 TQListViewItem *item = it.current();
00349 if(itemMatches(item, d->search))
00350 item->setVisible(true);
00351 else
00352 item->setVisible(false);
00353 }
00354 }
00355
00356 #include <kdebug.h>
00357
00367 bool TDEListViewSearchLine::checkItemParentsVisible(TQListViewItem *item, TQListViewItem *highestHiddenParent)
00368 {
00369 bool visible = false;
00370 TQListViewItem * first = item;
00371 for(; item; item = item->nextSibling())
00372 {
00373
00374 TQListViewItem * hhp = highestHiddenParent ? highestHiddenParent : item->isVisible() ? 0L : item;
00375 bool childMatch = false;
00376 if(item->firstChild() && checkItemParentsVisible(item->firstChild(), hhp))
00377 childMatch = true;
00378
00379 if(childMatch || itemMatches(item, d->search))
00380 {
00381 visible = true;
00382 if (highestHiddenParent)
00383 {
00384 highestHiddenParent->setVisible(true);
00385
00386
00387 for(TQListViewItem *hide = first; hide != item; hide = hide->nextSibling())
00388 hide->setVisible(false);
00389 highestHiddenParent = 0;
00390
00391
00392 if(!childMatch)
00393 for(TQListViewItem *hide = item->firstChild(); hide; hide = hide->nextSibling())
00394 hide->setVisible(false);
00395 }
00396 else
00397 item->setVisible(true);
00398 }
00399 else
00400 item->setVisible(false);
00401 }
00402 return visible;
00403 }
00404
00406
00408
00409 class TDEListViewSearchLineWidget::TDEListViewSearchLineWidgetPrivate
00410 {
00411 public:
00412 TDEListViewSearchLineWidgetPrivate() : listView(0), searchLine(0), clearButton(0) {}
00413 TDEListView *listView;
00414 TDEListViewSearchLine *searchLine;
00415 TQToolButton *clearButton;
00416 };
00417
00418 TDEListViewSearchLineWidget::TDEListViewSearchLineWidget(TDEListView *listView,
00419 TQWidget *parent,
00420 const char *name) :
00421 TQHBox(parent, name)
00422 {
00423 d = new TDEListViewSearchLineWidgetPrivate;
00424 d->listView = listView;
00425
00426 setSpacing(5);
00427
00428 TQTimer::singleShot(0, this, TQT_SLOT(createWidgets()));
00429 }
00430
00431 TDEListViewSearchLineWidget::~TDEListViewSearchLineWidget()
00432 {
00433 delete d;
00434 }
00435
00436 TDEListViewSearchLine *TDEListViewSearchLineWidget::createSearchLine(TDEListView *listView)
00437 {
00438 if(!d->searchLine)
00439 d->searchLine = new TDEListViewSearchLine(this, listView);
00440 return d->searchLine;
00441 }
00442
00443 void TDEListViewSearchLineWidget::createWidgets()
00444 {
00445 positionInToolBar();
00446
00447 if(!d->clearButton) {
00448 d->clearButton = new TQToolButton(this);
00449 TQIconSet icon = SmallIconSet(TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase");
00450 d->clearButton->setIconSet(icon);
00451 }
00452
00453 d->clearButton->show();
00454
00455 TQLabel *label = new TQLabel(i18n("S&earch:"), this, "tde toolbar widget");
00456
00457 d->searchLine = createSearchLine(d->listView);
00458 d->searchLine->show();
00459
00460 label->setBuddy(d->searchLine);
00461 label->show();
00462
00463 connect(d->clearButton, TQT_SIGNAL(clicked()), d->searchLine, TQT_SLOT(clear()));
00464 }
00465
00466 TDEListViewSearchLine *TDEListViewSearchLineWidget::searchLine() const
00467 {
00468 return d->searchLine;
00469 }
00470
00471 void TDEListViewSearchLineWidget::positionInToolBar()
00472 {
00473 TDEToolBar *toolBar = tqt_dynamic_cast<TDEToolBar *>(parent());
00474
00475 if(toolBar) {
00476
00477
00478
00479
00480
00481 int widgetCount = toolBar->count();
00482
00483 for(int index = 0; index < widgetCount; index++) {
00484 int id = toolBar->idAt(index);
00485 if(toolBar->getWidget(id) == this) {
00486 toolBar->setItemAutoSized(id);
00487 if(!d->clearButton) {
00488 TQString icon = TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase";
00489 d->clearButton = new TDEToolBarButton(icon, 2005, toolBar);
00490 }
00491 toolBar->insertWidget(2005, d->clearButton->width(), d->clearButton, index);
00492 break;
00493 }
00494 }
00495 }
00496
00497 if(d->searchLine)
00498 d->searchLine->show();
00499 }
00500
00501 #include "tdelistviewsearchline.moc"