• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • kdeui
  • findreplace
kfind.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2001, S.R.Haque <srhaque@iee.org>.
3  Copyright (C) 2002, David Faure <david@mandrakesoft.com>
4  Copyright (C) 2004, Arend van Beelen jr. <arend@auton.nl>
5  This file is part of the KDE project
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License version 2, as published by the Free Software Foundation.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "kfind.h"
23 #include "kfind_p.h"
24 #include "kfinddialog.h"
25 
26 #include <klocale.h>
27 #include <kmessagebox.h>
28 #include <kdebug.h>
29 
30 #include <QtGui/QLabel>
31 #include <QtCore/QRegExp>
32 #include <QtCore/QHash>
33 #include <QTextDocument>
34 
35 // #define DEBUG_FIND
36 
37 static const int INDEX_NOMATCH = -1;
38 
39 class KFindNextDialog : public KDialog
40 {
41 public:
42  KFindNextDialog(const QString &pattern, QWidget *parent);
43 };
44 
45 // Create the dialog.
46 KFindNextDialog::KFindNextDialog(const QString &pattern, QWidget *parent) :
47  KDialog(parent)
48 {
49  setModal( false );
50  setCaption( i18n("Find Next") );
51  setButtons( User1 | Close );
52  setButtonGuiItem( User1, KStandardGuiItem::find() );
53  setDefaultButton( User1 );
54 
55  setMainWidget( new QLabel( i18n("<qt>Find next occurrence of '<b>%1</b>'?</qt>", pattern), this ) );
56 }
57 
59 
60 
61 KFind::KFind( const QString &pattern, long options, QWidget *parent )
62  : QObject( parent ),
63  d(new KFind::Private(this))
64 {
65  d->options = options;
66  d->init( pattern );
67 }
68 
69 KFind::KFind( const QString &pattern, long options, QWidget *parent, QWidget *findDialog )
70  : QObject( parent ),
71  d(new KFind::Private(this))
72 {
73  d->findDialog = findDialog;
74  d->options = options;
75  d->init( pattern );
76 }
77 
78 void KFind::Private::init( const QString& _pattern )
79 {
80  matches = 0;
81  pattern = _pattern;
82  dialog = 0;
83  dialogClosed = false;
84  index = INDEX_NOMATCH;
85  lastResult = NoMatch;
86  regExp = 0;
87  q->setOptions( options ); // create d->regExp with the right options
88 }
89 
90 KFind::~KFind()
91 {
92  delete d;
93  kDebug() ;
94 }
95 
96 bool KFind::needData() const
97 {
98  // always true when d->text is empty.
99  if (d->options & KFind::FindBackwards)
100  // d->index==-1 and d->lastResult==Match means we haven't answered nomatch yet
101  // This is important in the "replace with a prompt" case.
102  return ( d->index < 0 && d->lastResult != Match );
103  else
104  // "index over length" test removed: we want to get a nomatch before we set data again
105  // This is important in the "replace with a prompt" case.
106  return d->index == INDEX_NOMATCH;
107 }
108 
109 void KFind::setData( const QString& data, int startPos )
110 {
111  setData( -1, data, startPos );
112 }
113 
114 void KFind::setData( int id, const QString& data, int startPos )
115 {
116  // cache the data for incremental find
117  if ( d->options & KFind::FindIncremental )
118  {
119  if ( id != -1 )
120  d->customIds = true;
121  else
122  id = d->currentId + 1;
123 
124  Q_ASSERT( id <= d->data.size() );
125 
126  if ( id == d->data.size() )
127  d->data.append( Private::Data(id, data, true) );
128  else
129  d->data.replace( id, Private::Data(id, data, true) );
130  Q_ASSERT( d->data.at(id).text == data );
131  }
132 
133  if ( !(d->options & KFind::FindIncremental) || needData() )
134  {
135  d->text = data;
136 
137  if ( startPos != -1 )
138  d->index = startPos;
139  else if (d->options & KFind::FindBackwards)
140  d->index = d->text.length();
141  else
142  d->index = 0;
143 #ifdef DEBUG_FIND
144  kDebug() << "setData: '" << d->text << "' d->index=" << d->index;
145 #endif
146  Q_ASSERT( d->index != INDEX_NOMATCH );
147  d->lastResult = NoMatch;
148 
149  d->currentId = id;
150  }
151 }
152 
153 KDialog* KFind::findNextDialog( bool create )
154 {
155  if ( !d->dialog && create )
156  {
157  d->dialog = new KFindNextDialog( d->pattern, parentWidget() );
158  connect( d->dialog, SIGNAL(user1Clicked()), this, SLOT(_k_slotFindNext()) );
159  connect( d->dialog, SIGNAL(finished()), this, SLOT(_k_slotDialogClosed()) );
160  }
161  return d->dialog;
162 }
163 
164 KFind::Result KFind::find()
165 {
166  Q_ASSERT( d->index != INDEX_NOMATCH || d->patternChanged );
167 
168  if ( d->lastResult == Match && !d->patternChanged )
169  {
170  // Move on before looking for the next match, _if_ we just found a match
171  if (d->options & KFind::FindBackwards) {
172  d->index--;
173  if ( d->index == -1 ) // don't call KFind::find with -1, it has a special meaning
174  {
175  d->lastResult = NoMatch;
176  return NoMatch;
177  }
178  } else
179  d->index++;
180  }
181  d->patternChanged = false;
182 
183  if ( d->options & KFind::FindIncremental )
184  {
185  // if the current pattern is shorter than the matchedPattern we can
186  // probably look up the match in the incrementalPath
187  if ( d->pattern.length() < d->matchedPattern.length() )
188  {
189  Private::Match match;
190  if ( !d->pattern.isEmpty() )
191  match = d->incrementalPath.value( d->pattern );
192  else if ( d->emptyMatch )
193  match = *d->emptyMatch;
194  QString previousPattern (d->matchedPattern);
195  d->matchedPattern = d->pattern;
196  if ( !match.isNull() )
197  {
198  bool clean = true;
199 
200  // find the first result backwards on the path that isn't dirty
201  while ( d->data.at(match.dataId).dirty == true &&
202  !d->pattern.isEmpty() )
203  {
204  d->pattern.truncate( d->pattern.length() - 1 );
205 
206  match = d->incrementalPath.value( d->pattern );
207 
208  clean = false;
209  }
210 
211  // remove all matches that lie after the current match
212  while ( d->pattern.length() < previousPattern.length() )
213  {
214  d->incrementalPath.remove(previousPattern);
215  previousPattern.truncate(previousPattern.length() - 1);
216  }
217 
218  // set the current text, index, etc. to the found match
219  d->text = d->data.at(match.dataId).text;
220  d->index = match.index;
221  d->matchedLength = match.matchedLength;
222  d->currentId = match.dataId;
223 
224  // if the result is clean we can return it now
225  if ( clean )
226  {
227  if ( d->customIds )
228  emit highlight(d->currentId, d->index, d->matchedLength);
229  else
230  emit highlight(d->text, d->index, d->matchedLength);
231 
232  d->lastResult = Match;
233  d->matchedPattern = d->pattern;
234  return Match;
235  }
236  }
237  // if we couldn't look up the match, the new pattern isn't a
238  // substring of the matchedPattern, so we start a new search
239  else
240  {
241  d->startNewIncrementalSearch();
242  }
243  }
244  // if the new pattern is longer than the matchedPattern we might be
245  // able to proceed from the last search
246  else if ( d->pattern.length() > d->matchedPattern.length() )
247  {
248  // continue from the previous pattern
249  if ( d->pattern.startsWith(d->matchedPattern) )
250  {
251  // we can't proceed from the previous position if the previous
252  // position already failed
253  if ( d->index == INDEX_NOMATCH )
254  return NoMatch;
255 
256  QString temp (d->pattern);
257  d->pattern.truncate(d->matchedPattern.length() + 1);
258  d->matchedPattern = temp;
259  }
260  // start a new search
261  else
262  {
263  d->startNewIncrementalSearch();
264  }
265  }
266  // if the new pattern is as long as the matchedPattern, we reset if
267  // they are not equal
268  else if ( d->pattern != d->matchedPattern )
269  {
270  d->startNewIncrementalSearch();
271  }
272  }
273 
274 #ifdef DEBUG_FIND
275  kDebug() << "d->index=" << d->index;
276 #endif
277  do
278  {
279  // if we have multiple data blocks in our cache, walk through these
280  // blocks till we either searched all blocks or we find a match
281  do
282  {
283  // Find the next candidate match.
284  if ( d->options & KFind::RegularExpression )
285  d->index = KFind::find(d->text, *d->regExp, d->index, d->options, &d->matchedLength);
286  else
287  d->index = KFind::find(d->text, d->pattern, d->index, d->options, &d->matchedLength);
288 
289  if ( d->options & KFind::FindIncremental )
290  d->data[d->currentId].dirty = false;
291 
292  if (d->index == -1 && d->currentId < d->data.count() - 1) {
293  d->text = d->data.at(++d->currentId).text;
294 
295  if ( d->options & KFind::FindBackwards )
296  d->index = d->text.length();
297  else
298  d->index = 0;
299  } else {
300  break;
301  }
302  } while ( !(d->options & KFind::RegularExpression) );
303 
304  if ( d->index != -1 )
305  {
306  // Flexibility: the app can add more rules to validate a possible match
307  if ( validateMatch( d->text, d->index, d->matchedLength ) )
308  {
309  bool done = true;
310 
311  if ( d->options & KFind::FindIncremental )
312  {
313  if ( d->pattern.isEmpty() ) {
314  delete d->emptyMatch;
315  d->emptyMatch = new Private::Match( d->currentId, d->index, d->matchedLength );
316  } else
317  d->incrementalPath.insert(d->pattern, Private::Match(d->currentId, d->index, d->matchedLength));
318 
319  if ( d->pattern.length() < d->matchedPattern.length() )
320  {
321  d->pattern += d->matchedPattern.mid(d->pattern.length(), 1);
322  done = false;
323  }
324  }
325 
326  if ( done )
327  {
328  d->matches++;
329  // Tell the world about the match we found, in case someone wants to
330  // highlight it.
331  if ( d->customIds )
332  emit highlight(d->currentId, d->index, d->matchedLength);
333  else
334  emit highlight(d->text, d->index, d->matchedLength);
335 
336  if ( !d->dialogClosed )
337  findNextDialog(true)->show();
338 
339 #ifdef DEBUG_FIND
340  kDebug() << "Match. Next d->index=" << d->index;
341 #endif
342  d->lastResult = Match;
343  return Match;
344  }
345  }
346  else // Skip match
347  {
348  if (d->options & KFind::FindBackwards)
349  d->index--;
350  else
351  d->index++;
352  }
353  }
354  else
355  {
356  if ( d->options & KFind::FindIncremental )
357  {
358  QString temp (d->pattern);
359  temp.truncate(temp.length() - 1);
360  d->pattern = d->matchedPattern;
361  d->matchedPattern = temp;
362  }
363 
364  d->index = INDEX_NOMATCH;
365  }
366  }
367  while (d->index != INDEX_NOMATCH);
368 
369 #ifdef DEBUG_FIND
370  kDebug() << "NoMatch. d->index=" << d->index;
371 #endif
372  d->lastResult = NoMatch;
373  return NoMatch;
374 }
375 
376 void KFind::Private::startNewIncrementalSearch()
377 {
378  Private::Match *match = emptyMatch;
379  if(match == 0)
380  {
381  text.clear();
382  index = 0;
383  currentId = 0;
384  }
385  else
386  {
387  text = data.at(match->dataId).text;
388  index = match->index;
389  currentId = match->dataId;
390  }
391  matchedLength = 0;
392  incrementalPath.clear();
393  delete emptyMatch; emptyMatch = 0;
394  matchedPattern = pattern;
395  pattern.clear();
396 }
397 
398 static bool isInWord(QChar ch)
399 {
400  return ch.isLetter() || ch.isDigit() || ch == '_';
401 }
402 
403 static bool isWholeWords(const QString &text, int starts, int matchedLength)
404 {
405  if (starts == 0 || !isInWord(text.at(starts-1)))
406  {
407  const int ends = starts + matchedLength;
408  if (ends == text.length() || !isInWord(text.at(ends))) {
409  return true;
410  }
411  }
412  return false;
413 }
414 
415 static bool matchOk(const QString& text, int index, int matchedLength, long options)
416 {
417  if (options & KFind::WholeWordsOnly) {
418  // Is the match delimited correctly?
419  if (isWholeWords(text, index, matchedLength))
420  return true;
421  } else {
422  // Non-whole-word search: this match is good
423  return true;
424  }
425  return false;
426 }
427 
428 // static
429 int KFind::find(const QString &text, const QString &pattern, int index, long options, int *matchedLength)
430 {
431  // Handle regular expressions in the appropriate way.
432  if (options & KFind::RegularExpression)
433  {
434  Qt::CaseSensitivity caseSensitive = (options & KFind::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
435  QRegExp regExp(pattern, caseSensitive);
436 
437  return find(text, regExp, index, options, matchedLength);
438  }
439 
440  // In Qt4 QString("aaaaaa").lastIndexOf("a",6) returns -1; we need
441  // to start at text.length() - pattern.length() to give a valid index to QString.
442  if (options & KFind::FindBackwards) {
443  index = qMin( qMax(0, text.length() - pattern.length()), index );
444  }
445 
446  Qt::CaseSensitivity caseSensitive = (options & KFind::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
447 
448  if (options & KFind::FindBackwards) {
449  // Backward search, until the beginning of the line...
450  while (index >= 0) {
451  // ...find the next match.
452  index = text.lastIndexOf(pattern, index, caseSensitive);
453  if (index == -1)
454  break;
455 
456  if (matchOk(text, index, pattern.length(), options))
457  break;
458  index--;
459  kDebug() << "decrementing:" << index;
460  }
461  } else {
462  // Forward search, until the end of the line...
463  while (index <= text.length())
464  {
465  // ...find the next match.
466  index = text.indexOf(pattern, index, caseSensitive);
467  if (index == -1)
468  break;
469 
470  if (matchOk(text, index, pattern.length(), options))
471  break;
472  index++;
473  }
474  if (index > text.length()) { // end of line
475  kDebug() << "at" << index << "-> not found";
476  index = -1; // not found
477  }
478  }
479  if (index <= -1)
480  *matchedLength = 0;
481  else
482  *matchedLength = pattern.length();
483  return index;
484 }
485 
486 // Core method for the regexp-based find
487 static int doFind(const QString &text, const QRegExp &pattern, int index, long options, int *matchedLength)
488 {
489  if (options & KFind::FindBackwards) {
490  // Backward search, until the beginning of the line...
491  while (index >= 0) {
492  // ...find the next match.
493  index = text.lastIndexOf(pattern, index);
494  if (index == -1)
495  break;
496 
497  /*int pos =*/ pattern.indexIn( text.mid(index) );
498  *matchedLength = pattern.matchedLength();
499  if (matchOk(text, index, *matchedLength, options))
500  break;
501  index--;
502  }
503  } else {
504  // Forward search, until the end of the line...
505  while (index <= text.length()) {
506  // ...find the next match.
507  index = text.indexOf(pattern, index);
508  if (index == -1)
509  break;
510 
511  /*int pos =*/ pattern.indexIn( text.mid(index) );
512  *matchedLength = pattern.matchedLength();
513  if (matchOk(text, index, *matchedLength, options))
514  break;
515  index++;
516  }
517  if (index > text.length()) { // end of line
518  index = -1; // not found
519  }
520  }
521  if (index == -1)
522  *matchedLength = 0;
523  return index;
524 }
525 
526 // Since QRegExp doesn't support multiline searches (the equivalent of perl's /m)
527 // we have to cut the text into lines if the pattern starts with ^ or ends with $.
528 static int lineBasedFind(const QString &text, const QRegExp &pattern, int index, long options, int *matchedLength)
529 {
530  const QStringList lines = text.split('\n');
531  int offset = 0;
532  // Use "index" to find the first line we should start from
533  int startLineNumber = 0;
534  for (; startLineNumber < lines.count(); ++startLineNumber) {
535  const QString line = lines.at(startLineNumber);
536  if (index < offset + line.length()) {
537  break;
538  }
539  offset += line.length() + 1 /*newline*/;
540  }
541 
542  if (options & KFind::FindBackwards) {
543 
544  if (startLineNumber == lines.count()) {
545  // We went too far, go back to the last line
546  --startLineNumber;
547  offset -= lines.at(startLineNumber).length() + 1;
548  }
549 
550  for (int lineNumber = startLineNumber; lineNumber >= 0; --lineNumber) {
551  const QString line = lines.at(lineNumber);
552  const int ret = doFind(line, pattern, lineNumber == startLineNumber ? index - offset : line.length(), options, matchedLength);
553  if (ret > -1)
554  return ret + offset;
555  offset -= line.length() + 1 /*newline*/;
556  }
557 
558  } else {
559  for (int lineNumber = startLineNumber; lineNumber < lines.count(); ++lineNumber) {
560  const QString line = lines.at(lineNumber);
561  const int ret = doFind(line, pattern, lineNumber == startLineNumber ? (index - offset) : 0, options, matchedLength);
562  if (ret > -1) {
563  return ret + offset;
564  }
565  offset += line.length() + 1 /*newline*/;
566  }
567  }
568  return -1;
569 }
570 
571 // static
572 int KFind::find(const QString &text, const QRegExp &pattern, int index, long options, int *matchedLength)
573 {
574  if (pattern.pattern().startsWith('^') || pattern.pattern().endsWith('$')) {
575  return lineBasedFind(text, pattern, index, options, matchedLength);
576  }
577 
578  return doFind(text, pattern, index, options, matchedLength);
579 }
580 
581 void KFind::Private::_k_slotFindNext()
582 {
583  emit q->findNext();
584 }
585 
586 void KFind::Private::_k_slotDialogClosed()
587 {
588 #ifdef DEBUG_FIND
589  kDebug() << " Begin";
590 #endif
591  emit q->dialogClosed();
592  dialogClosed = true;
593 #ifdef DEBUG_FIND
594  kDebug() << " End";
595 #endif
596 
597 }
598 
599 void KFind::displayFinalDialog() const
600 {
601  QString message;
602  if ( numMatches() )
603  message = i18np( "1 match found.", "%1 matches found.", numMatches() );
604  else
605  message = i18n("<qt>No matches found for '<b>%1</b>'.</qt>", Qt::escape(d->pattern));
606  KMessageBox::information(dialogsParent(), message);
607 }
608 
609 bool KFind::shouldRestart( bool forceAsking, bool showNumMatches ) const
610 {
611  // Only ask if we did a "find from cursor", otherwise it's pointless.
612  // Well, unless the user can modify the document during a search operation,
613  // hence the force boolean.
614  if ( !forceAsking && (d->options & KFind::FromCursor) == 0 )
615  {
616  displayFinalDialog();
617  return false;
618  }
619  QString message;
620  if ( showNumMatches )
621  {
622  if ( numMatches() )
623  message = i18np( "1 match found.", "%1 matches found.", numMatches() );
624  else
625  message = i18n("No matches found for '<b>%1</b>'.", Qt::escape(d->pattern));
626  }
627  else
628  {
629  if ( d->options & KFind::FindBackwards )
630  message = i18n( "Beginning of document reached." );
631  else
632  message = i18n( "End of document reached." );
633  }
634 
635  message += "<br><br>"; // can't be in the i18n() of the first if() because of the plural form.
636  // Hope this word puzzle is ok, it's a different sentence
637  message +=
638  ( d->options & KFind::FindBackwards ) ?
639  i18n("Continue from the end?")
640  : i18n("Continue from the beginning?");
641 
642  int ret = KMessageBox::questionYesNo( dialogsParent(), "<qt>"+message+"</qt>",
643  QString(), KStandardGuiItem::cont(), KStandardGuiItem::stop() );
644  bool yes = ( ret == KMessageBox::Yes );
645  if ( yes )
646  const_cast<KFind*>(this)->d->options &= ~KFind::FromCursor; // clear FromCursor option
647  return yes;
648 }
649 
650 long KFind::options() const
651 {
652  return d->options;
653 }
654 
655 void KFind::setOptions( long options )
656 {
657  d->options = options;
658 
659  delete d->regExp;
660  if (d->options & KFind::RegularExpression) {
661  Qt::CaseSensitivity caseSensitive = (d->options & KFind::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
662  d->regExp = new QRegExp(d->pattern, caseSensitive);
663  } else
664  d->regExp = 0;
665 }
666 
667 void KFind::closeFindNextDialog()
668 {
669  if (d->dialog) {
670  d->dialog->deleteLater();
671  d->dialog = 0;
672  }
673  d->dialogClosed = true;
674 }
675 
676 int KFind::index() const
677 {
678  return d->index;
679 }
680 
681 QString KFind::pattern() const
682 {
683  return d->pattern;
684 }
685 
686 void KFind::setPattern( const QString& pattern )
687 {
688  if ( d->options & KFind::FindIncremental && d->pattern != pattern )
689  d->patternChanged = true;
690 
691  d->pattern = pattern;
692  setOptions( options() ); // rebuild d->regExp if necessary
693 }
694 
695 int KFind::numMatches() const
696 {
697  return d->matches;
698 }
699 
700 void KFind::resetCounts()
701 {
702  d->matches = 0;
703 }
704 
705 bool KFind::validateMatch( const QString &, int, int )
706 {
707  return true;
708 }
709 
710 QWidget* KFind::parentWidget() const
711 {
712  return (QWidget *)parent();
713 }
714 
715 QWidget* KFind::dialogsParent() const
716 {
717  // If the find dialog is still up, it should get the focus when closing a message box
718  // Otherwise, maybe the "find next?" dialog is up
719  // Otherwise, the "view" is the parent.
720  return d->findDialog ? (QWidget*)d->findDialog : ( d->dialog ? d->dialog : parentWidget() );
721 }
722 
723 #include "kfind.moc"
INDEX_NOMATCH
static const int INDEX_NOMATCH
Definition: kfind.cpp:37
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
i18n
QString i18n(const char *text)
KFind::validateMatch
virtual bool validateMatch(const QString &text, int index, int matchedlength)
Virtual method, which allows applications to add extra checks for validating a candidate match...
Definition: kfind.cpp:705
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QWidget
KFind::~KFind
virtual ~KFind()
Definition: kfind.cpp:90
QString::truncate
void truncate(int position)
KFind::index
int index() const
Definition: kfind.cpp:676
kdebug.h
KFind::find
Result find()
Walk the text fragment (e.g.
Definition: kfind.cpp:164
KFind::parentWidget
QWidget * parentWidget() const
Definition: kfind.cpp:710
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
i18np
QString i18np(const char *sing, const char *plur, const A1 &a1)
KMessageBox::information
static void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
Display an "Information" dialog.
Definition: kmessagebox.cpp:960
QChar::isDigit
bool isDigit() const
QList::at
const T & at(int i) const
QString::size
int size() const
KFind::setOptions
virtual void setOptions(long options)
Set new options.
Definition: kfind.cpp:655
KFind::WholeWordsOnly
Match whole words only.
Definition: kfind.h:111
KDialog
A dialog base class with standard buttons and predefined layouts.
Definition: kdialog.h:128
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
klocale.h
kfind.h
KFind::RegularExpression
Interpret the pattern as a regular expression.
Definition: kfind.h:116
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QChar::isLetter
bool isLetter() const
isInWord
static bool isInWord(QChar ch)
Definition: kfind.cpp:398
QString::clear
void clear()
QRegExp::matchedLength
int matchedLength() const
QRegExp::indexIn
int indexIn(const QString &str, int offset, CaretMode caretMode) const
QRegExp
KFind::FromCursor
Start from current cursor position.
Definition: kfind.h:112
QList::count
int count(const T &value) const
KFind::FindIncremental
Find incremental.
Definition: kfind.h:117
KStandardAction::Close
Definition: kstandardaction.h:129
QObject
KFind::Match
Definition: kfind.h:139
KFind::setData
void setData(const QString &data, int startPos=-1)
Call this when needData returns true, before calling find().
Definition: kfind.cpp:109
KFind::displayFinalDialog
virtual void displayFinalDialog() const
Displays the final dialog saying "no match was found", if that was the case.
Definition: kfind.cpp:599
KFind::highlight
void highlight(const QString &text, int matchingIndex, int matchedLength)
Connect to this signal to implement highlighting of found text during the find operation.
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KFind::numMatches
int numMatches() const
Return the number of matches found (i.e.
Definition: kfind.cpp:695
KFind::KFind
KFind(const QString &pattern, long options, QWidget *parent)
Only use this constructor if you don't use KFindDialog, or if you use it as a modal dialog...
Definition: kfind.cpp:61
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
matchOk
static bool matchOk(const QString &text, int index, int matchedLength, long options)
Definition: kfind.cpp:415
QString
isWholeWords
static bool isWholeWords(const QString &text, int starts, int matchedLength)
Definition: kfind.cpp:403
doFind
static int doFind(const QString &text, const QRegExp &pattern, int index, long options, int *matchedLength)
Definition: kfind.cpp:487
QStringList
KMessageBox::questionYesNo
static int questionYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Notify)
Display a simple "question" dialog.
Definition: kmessagebox.cpp:353
KFind::Result
Result
Definition: kfind.h:139
KFind
A generic implementation of the "find" function.
Definition: kfind.h:101
KFind::shouldRestart
virtual bool shouldRestart(bool forceAsking=false, bool showNumMatches=true) const
Returns true if we should restart the search from scratch.
Definition: kfind.cpp:609
KFind::pattern
QString pattern() const
Definition: kfind.cpp:681
KFind::dialogsParent
QWidget * dialogsParent() const
Definition: kfind.cpp:715
QString::mid
QString mid(int position, int n) const
Qt::escape
QString escape(const QString &plain)
KFind::closeFindNextDialog
void closeFindNextDialog()
Close the "find next?" dialog.
Definition: kfind.cpp:667
KFind::FindBackwards
Go backwards.
Definition: kfind.h:115
KStandardGuiItem::find
KGuiItem find()
Returns the 'Find' gui item.
Definition: kstandardguiitem.cpp:274
KStandardGuiItem::stop
KGuiItem stop()
Returns the 'Stop' gui item.
Definition: kstandardguiitem.cpp:279
QString::at
const QChar at(int position) const
KStandardAction::create
KAction * create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
Creates an action corresponding to one of the KStandardAction::StandardAction actions, which is connected to the given object and slot, and is owned by parent.
Definition: kstandardaction.cpp:82
QRegExp::pattern
QString pattern() const
QString::length
int length() const
KFind::resetCounts
virtual void resetCounts()
Call this to reset the numMatches count (and the numReplacements count for a KReplace).
Definition: kfind.cpp:700
KFind::CaseSensitive
Consider case when matching.
Definition: kfind.h:114
KFind::setPattern
void setPattern(const QString &pattern)
Change the pattern we're looking for.
Definition: kfind.cpp:686
KStandardGuiItem::cont
KGuiItem cont()
Returns the 'Continue' gui item.
Definition: kstandardguiitem.cpp:234
KMessageBox::Yes
Definition: kmessagebox.h:72
QWidget::show
void show()
lineBasedFind
static int lineBasedFind(const QString &text, const QRegExp &pattern, int index, long options, int *matchedLength)
Definition: kfind.cpp:528
KFind::options
long options() const
Return the current options.
Definition: kfind.cpp:650
KFind::NoMatch
Definition: kfind.h:139
KFind::needData
bool needData() const
Definition: kfind.cpp:96
kfinddialog.h
kmessagebox.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QLabel
QObject::parent
QObject * parent() const
KFind::findNextDialog
KDialog * findNextDialog(bool create=false)
Return (or create) the dialog that shows the "find next?" prompt.
Definition: kfind.cpp:153
KStandardGuiItem::yes
KGuiItem yes()
Returns the 'Yes' gui item.
Definition: kstandardguiitem.cpp:118
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:23:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal