• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdeui
 

kdeui

  • kdeui
klistviewsearchline.cpp
1 /* This file is part of the KDE libraries
2  Copyright (c) 2003 Scott Wheeler <wheeler@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 */
18 
19 #include "klistviewsearchline.h"
20 
21 #include <klistview.h>
22 #include <kiconloader.h>
23 #include <ktoolbar.h>
24 #include <ktoolbarbutton.h>
25 #include <kdebug.h>
26 #include <klocale.h>
27 
28 #include <tqapplication.h>
29 #include <tqtimer.h>
30 #include <tqpopupmenu.h>
31 #include <tqlabel.h>
32 #include <tqheader.h>
33 
34 #define KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID 2004
35 
36 class KListViewSearchLine::KListViewSearchLinePrivate
37 {
38 public:
39  KListViewSearchLinePrivate() :
40  listView(0),
41  caseSensitive(false),
42  activeSearch(false),
43  keepParentsVisible(true),
44  queuedSearches(0) {}
45 
46  KListView *listView;
47  bool caseSensitive;
48  bool activeSearch;
49  bool keepParentsVisible;
50  TQString search;
51  int queuedSearches;
52  TQValueList<int> searchColumns;
53 };
54 
56 // public methods
58 
59 KListViewSearchLine::KListViewSearchLine(TQWidget *parent, KListView *listView, const char *name) :
60  KLineEdit(parent, name)
61 {
62  d = new KListViewSearchLinePrivate;
63 
64  d->listView = listView;
65 
66  connect(this, TQT_SIGNAL(textChanged(const TQString &)),
67  this, TQT_SLOT(queueSearch(const TQString &)));
68 
69  if(listView) {
70  connect(listView, TQT_SIGNAL(destroyed()),
71  this, TQT_SLOT(listViewDeleted()));
72 
73  connect(listView, TQT_SIGNAL(itemAdded(TQListViewItem *)),
74  this, TQT_SLOT(itemAdded(TQListViewItem *)));
75  }
76  else
77  setEnabled(false);
78 }
79 
80 KListViewSearchLine::KListViewSearchLine(TQWidget *parent, const char *name) :
81  KLineEdit(parent, name)
82 {
83  d = new KListViewSearchLinePrivate;
84 
85  d->listView = 0;
86 
87  connect(this, TQT_SIGNAL(textChanged(const TQString &)),
88  this, TQT_SLOT(queueSearch(const TQString &)));
89 
90  setEnabled(false);
91 }
92 
93 KListViewSearchLine::~KListViewSearchLine()
94 {
95  delete d;
96 }
97 
98 bool KListViewSearchLine::caseSensitive() const
99 {
100  return d->caseSensitive;
101 }
102 
103 TQValueList<int> KListViewSearchLine::searchColumns() const
104 {
105  return d->searchColumns;
106 }
107 
108 bool KListViewSearchLine::keepParentsVisible() const
109 {
110  return d->keepParentsVisible;
111 }
112 
113 KListView *KListViewSearchLine::listView() const
114 {
115  return d->listView;
116 }
117 
119 // public slots
121 
122 void KListViewSearchLine::updateSearch(const TQString &s)
123 {
124  if(!d->listView)
125  return;
126 
127  d->search = s.isNull() ? text() : s;
128 
129  // If there's a selected item that is visible, make sure that it's visible
130  // when the search changes too (assuming that it still matches).
131 
132  TQListViewItem *currentItem = 0;
133 
134  switch(d->listView->selectionMode())
135  {
136  case KListView::NoSelection:
137  break;
138  case KListView::Single:
139  currentItem = d->listView->selectedItem();
140  break;
141  default:
142  {
143  int flags = TQListViewItemIterator::Selected | TQListViewItemIterator::Visible;
144  for(TQListViewItemIterator it(d->listView, flags);
145  it.current() && !currentItem;
146  ++it)
147  {
148  if(d->listView->itemRect(it.current()).isValid())
149  currentItem = it.current();
150  }
151  }
152  }
153 
154  if(d->keepParentsVisible)
155  checkItemParentsVisible(d->listView->firstChild());
156  else
157  checkItemParentsNotVisible();
158 
159  if(currentItem)
160  d->listView->ensureItemVisible(currentItem);
161 }
162 
163 void KListViewSearchLine::setCaseSensitive(bool cs)
164 {
165  d->caseSensitive = cs;
166 }
167 
168 void KListViewSearchLine::setKeepParentsVisible(bool v)
169 {
170  d->keepParentsVisible = v;
171 }
172 
173 void KListViewSearchLine::setSearchColumns(const TQValueList<int> &columns)
174 {
175  d->searchColumns = columns;
176 }
177 
178 void KListViewSearchLine::setListView(KListView *lv)
179 {
180  if(d->listView) {
181  disconnect(d->listView, TQT_SIGNAL(destroyed()),
182  this, TQT_SLOT(listViewDeleted()));
183 
184  disconnect(d->listView, TQT_SIGNAL(itemAdded(TQListViewItem *)),
185  this, TQT_SLOT(itemAdded(TQListViewItem *)));
186  }
187 
188  d->listView = lv;
189 
190  if(lv) {
191  connect(d->listView, TQT_SIGNAL(destroyed()),
192  this, TQT_SLOT(listViewDeleted()));
193 
194  connect(d->listView, TQT_SIGNAL(itemAdded(TQListViewItem *)),
195  this, TQT_SLOT(itemAdded(TQListViewItem *)));
196  }
197 
198  setEnabled(bool(lv));
199 }
200 
202 // protected members
204 
205 bool KListViewSearchLine::itemMatches(const TQListViewItem *item, const TQString &s) const
206 {
207  if(s.isEmpty())
208  return true;
209 
210  // If the search column list is populated, search just the columns
211  // specifified. If it is empty default to searching all of the columns.
212 
213  if(!d->searchColumns.isEmpty()) {
214  TQValueList<int>::ConstIterator it = d->searchColumns.begin();
215  for(; it != d->searchColumns.end(); ++it) {
216  if(*it < item->listView()->columns() &&
217  item->text(*it).find(s, 0, d->caseSensitive) >= 0)
218  return true;
219  }
220  }
221  else {
222  for(int i = 0; i < item->listView()->columns(); i++) {
223  if(item->listView()->columnWidth(i) > 0 &&
224  item->text(i).find(s, 0, d->caseSensitive) >= 0)
225  {
226  return true;
227  }
228  }
229  }
230 
231  return false;
232 }
233 
234 TQPopupMenu *KListViewSearchLine::createPopupMenu()
235 {
236  TQPopupMenu *popup = KLineEdit::createPopupMenu();
237 
238  if (d->listView->columns()>1) {
239  TQPopupMenu *subMenu = new TQPopupMenu(popup);
240  connect(subMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(searchColumnsMenuActivated(int)));
241 
242  popup->insertSeparator();
243  popup->insertItem(i18n("Search Columns"), subMenu);
244 
245  subMenu->insertItem(i18n("All Visible Columns"), KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID);
246  subMenu->insertSeparator();
247 
248  bool allColumnsAreSearchColumns = true;
249  // TODO Make the entry order match the actual column order
250  TQHeader* const header = d->listView->header();
251  int visibleColumns = 0;
252  for(int i = 0; i < d->listView->columns(); i++) {
253  if(d->listView->columnWidth(i)>0) {
254  TQString columnText = d->listView->columnText(i);
255  if(columnText.isEmpty()) {
256  int visiblePosition=1;
257  for(int j = 0; j < header->mapToIndex(i); j++)
258  if(d->listView->columnWidth(header->mapToSection(j))>0)
259  visiblePosition++;
260  columnText = i18n("Column number %1","Column No. %1").arg(visiblePosition);
261  }
262  subMenu->insertItem(columnText, visibleColumns);
263  if(d->searchColumns.isEmpty() || d->searchColumns.find(i) != d->searchColumns.end())
264  subMenu->setItemChecked(visibleColumns, true);
265  else
266  allColumnsAreSearchColumns = false;
267  visibleColumns++;
268  }
269  }
270  subMenu->setItemChecked(KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID, allColumnsAreSearchColumns);
271 
272  // searchColumnsMenuActivated() relies on one possible "all" representation
273  if(allColumnsAreSearchColumns && !d->searchColumns.isEmpty())
274  d->searchColumns.clear();
275  }
276 
277  return popup;
278 }
279 
281 // protected slots
283 
284 void KListViewSearchLine::queueSearch(const TQString &search)
285 {
286  d->queuedSearches++;
287  d->search = search;
288  TQTimer::singleShot(200, this, TQT_SLOT(activateSearch()));
289 }
290 
291 void KListViewSearchLine::activateSearch()
292 {
293  --(d->queuedSearches);
294 
295  if(d->queuedSearches == 0)
296  updateSearch(d->search);
297 }
298 
300 // private slots
302 
303 void KListViewSearchLine::itemAdded(TQListViewItem *item) const
304 {
305  item->setVisible(itemMatches(item, text()));
306 }
307 
308 void KListViewSearchLine::listViewDeleted()
309 {
310  d->listView = 0;
311  setEnabled(false);
312 }
313 
314 void KListViewSearchLine::searchColumnsMenuActivated(int id)
315 {
316  if(id == KLISTVIEWSEARCHLINE_ALLVISIBLECOLUMNS_ID) {
317  if(d->searchColumns.isEmpty())
318  d->searchColumns.append(0);
319  else
320  d->searchColumns.clear();
321  }
322  else {
323  if(d->searchColumns.find(id) != d->searchColumns.end())
324  d->searchColumns.remove(id);
325  else {
326  if(d->searchColumns.isEmpty()) {
327  for(int i = 0; i < d->listView->columns(); i++) {
328  if(i != id)
329  d->searchColumns.append(i);
330  }
331  }
332  else
333  d->searchColumns.append(id);
334  }
335  }
336  updateSearch();
337 }
338 
340 // private methods
342 
343 void KListViewSearchLine::checkItemParentsNotVisible()
344 {
345  TQListViewItemIterator it(d->listView);
346  for(; it.current(); ++it)
347  {
348  TQListViewItem *item = it.current();
349  if(itemMatches(item, d->search))
350  item->setVisible(true);
351  else
352  item->setVisible(false);
353  }
354 }
355 
356 #include <kdebug.h>
357 
367 bool KListViewSearchLine::checkItemParentsVisible(TQListViewItem *item, TQListViewItem *highestHiddenParent)
368 {
369  bool visible = false;
370  TQListViewItem * first = item;
371  for(; item; item = item->nextSibling())
372  {
373  //What we pass to our children as highestHiddenParent:
374  TQListViewItem * hhp = highestHiddenParent ? highestHiddenParent : item->isVisible() ? 0L : item;
375  bool childMatch = false;
376  if(item->firstChild() && checkItemParentsVisible(item->firstChild(), hhp))
377  childMatch = true;
378  // Should this item be shown? It should if any children should be, or if it matches.
379  if(childMatch || itemMatches(item, d->search))
380  {
381  visible = true;
382  if (highestHiddenParent)
383  {
384  highestHiddenParent->setVisible(true);
385  // Calling setVisible on our ancestor will unhide all its descendents. Hide the ones
386  // before us that should not be shown.
387  for(TQListViewItem *hide = first; hide != item; hide = hide->nextSibling())
388  hide->setVisible(false);
389  highestHiddenParent = 0;
390  // If we matched, than none of our children matched, yet the setVisible() call on our
391  // ancestor unhid them, undo the damage:
392  if(!childMatch)
393  for(TQListViewItem *hide = item->firstChild(); hide; hide = hide->nextSibling())
394  hide->setVisible(false);
395  }
396  else
397  item->setVisible(true);
398  }
399  else
400  item->setVisible(false);
401  }
402  return visible;
403 }
404 
406 // KListViewSearchLineWidget
408 
409 class KListViewSearchLineWidget::KListViewSearchLineWidgetPrivate
410 {
411 public:
412  KListViewSearchLineWidgetPrivate() : listView(0), searchLine(0), clearButton(0) {}
413  KListView *listView;
414  KListViewSearchLine *searchLine;
415  TQToolButton *clearButton;
416 };
417 
418 KListViewSearchLineWidget::KListViewSearchLineWidget(KListView *listView,
419  TQWidget *parent,
420  const char *name) :
421  TQHBox(parent, name)
422 {
423  d = new KListViewSearchLineWidgetPrivate;
424  d->listView = listView;
425 
426  setSpacing(5);
427 
428  TQTimer::singleShot(0, this, TQT_SLOT(createWidgets()));
429 }
430 
431 KListViewSearchLineWidget::~KListViewSearchLineWidget()
432 {
433  delete d;
434 }
435 
436 KListViewSearchLine *KListViewSearchLineWidget::createSearchLine(KListView *listView)
437 {
438  if(!d->searchLine)
439  d->searchLine = new KListViewSearchLine(this, listView);
440  return d->searchLine;
441 }
442 
443 void KListViewSearchLineWidget::createWidgets()
444 {
445  positionInToolBar();
446 
447  if(!d->clearButton) {
448  d->clearButton = new TQToolButton(this);
449  TQIconSet icon = SmallIconSet(TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase");
450  d->clearButton->setIconSet(icon);
451  }
452 
453  d->clearButton->show();
454 
455  TQLabel *label = new TQLabel(i18n("S&earch:"), this, "kde toolbar widget");
456 
457  d->searchLine = createSearchLine(d->listView);
458  d->searchLine->show();
459 
460  label->setBuddy(d->searchLine);
461  label->show();
462 
463  connect(d->clearButton, TQT_SIGNAL(clicked()), d->searchLine, TQT_SLOT(clear()));
464 }
465 
466 KListViewSearchLine *KListViewSearchLineWidget::searchLine() const
467 {
468  return d->searchLine;
469 }
470 
471 void KListViewSearchLineWidget::positionInToolBar()
472 {
473  KToolBar *toolBar = tqt_dynamic_cast<KToolBar *>(parent());
474 
475  if(toolBar) {
476 
477  // Here we have The Big Ugly. Figure out how many widgets are in the
478  // and do a hack-ish iteration over them to find this widget so that we
479  // can insert the clear button before it.
480 
481  int widgetCount = toolBar->count();
482 
483  for(int index = 0; index < widgetCount; index++) {
484  int id = toolBar->idAt(index);
485  if(toolBar->getWidget(id) == this) {
486  toolBar->setItemAutoSized(id);
487  if(!d->clearButton) {
488  TQString icon = TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase";
489  d->clearButton = new KToolBarButton(icon, 2005, toolBar);
490  }
491  toolBar->insertWidget(2005, d->clearButton->width(), d->clearButton, index);
492  break;
493  }
494  }
495  }
496 
497  if(d->searchLine)
498  d->searchLine->show();
499 }
500 
501 #include "klistviewsearchline.moc"

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdeui

Skip menu "kdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdeui by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |