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

KDEUI

  • 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
37static const int INDEX_NOMATCH = -1;
38
39class KFindNextDialog : public KDialog
40{
41public:
42 KFindNextDialog(const QString &pattern, QWidget *parent);
43};
44
45// Create the dialog.
46KFindNextDialog::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
61KFind::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
69KFind::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
78void 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
90KFind::~KFind()
91{
92 delete d;
93 kDebug() ;
94}
95
96bool 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
109void KFind::setData( const QString& data, int startPos )
110{
111 setData( -1, data, startPos );
112}
113
114void 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
153KDialog* 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
164KFind::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
376void 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
398static bool isInWord(QChar ch)
399{
400 return ch.isLetter() || ch.isDigit() || ch == '_';
401}
402
403static 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
415static 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
429int 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
487static 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 $.
528static 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
572int 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
581void KFind::Private::_k_slotFindNext()
582{
583 emit q->findNext();
584}
585
586void 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
599void 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
609bool 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
650long KFind::options() const
651{
652 return d->options;
653}
654
655void 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
667void KFind::closeFindNextDialog()
668{
669 if (d->dialog) {
670 d->dialog->deleteLater();
671 d->dialog = 0;
672 }
673 d->dialogClosed = true;
674}
675
676int KFind::index() const
677{
678 return d->index;
679}
680
681QString KFind::pattern() const
682{
683 return d->pattern;
684}
685
686void 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
695int KFind::numMatches() const
696{
697 return d->matches;
698}
699
700void KFind::resetCounts()
701{
702 d->matches = 0;
703}
704
705bool KFind::validateMatch( const QString &, int, int )
706{
707 return true;
708}
709
710QWidget* KFind::parentWidget() const
711{
712 return (QWidget *)parent();
713}
714
715QWidget* 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"
KDialog
A dialog base class with standard buttons and predefined layouts.
Definition: kdialog.h:129
KFind
A generic implementation of the "find" function.
Definition: kfind.h:103
KFind::dialogsParent
QWidget * dialogsParent() const
Definition: kfind.cpp:715
KFind::findNextDialog
KDialog * findNextDialog(bool create=false)
Return (or create) the dialog that shows the "find next?" prompt.
Definition: kfind.cpp:153
KFind::Result
Result
Definition: kfind.h:139
KFind::NoMatch
@ NoMatch
Definition: kfind.h:139
KFind::Match
@ Match
Definition: kfind.h:139
KFind::numMatches
int numMatches() const
Return the number of matches found (i.e.
Definition: kfind.cpp:695
KFind::parentWidget
QWidget * parentWidget() const
Definition: kfind.cpp:710
KFind::~KFind
virtual ~KFind()
Definition: kfind.cpp:90
KFind::needData
bool needData() const
Definition: kfind.cpp:96
KFind::setPattern
void setPattern(const QString &pattern)
Change the pattern we're looking for.
Definition: kfind.cpp:686
KFind::closeFindNextDialog
void closeFindNextDialog()
Close the "find next?" dialog.
Definition: kfind.cpp:667
KFind::index
int index() const
Definition: kfind.cpp:676
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::setOptions
virtual void setOptions(long options)
Set new options.
Definition: kfind.cpp:655
KFind::resetCounts
virtual void resetCounts()
Call this to reset the numMatches count (and the numReplacements count for a KReplace).
Definition: kfind.cpp:700
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
KFind::CaseSensitive
@ CaseSensitive
Consider case when matching.
Definition: kfind.h:114
KFind::RegularExpression
@ RegularExpression
Interpret the pattern as a regular expression.
Definition: kfind.h:116
KFind::FromCursor
@ FromCursor
Start from current cursor position.
Definition: kfind.h:112
KFind::FindBackwards
@ FindBackwards
Go backwards.
Definition: kfind.h:115
KFind::FindIncremental
@ FindIncremental
Find incremental.
Definition: kfind.h:117
KFind::WholeWordsOnly
@ WholeWordsOnly
Match whole words only.
Definition: kfind.h:111
KFind::setData
void setData(const QString &data, int startPos=-1)
Call this when needData returns true, before calling find().
Definition: kfind.cpp:109
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
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::find
Result find()
Walk the text fragment (e.g.
Definition: kfind.cpp:164
KFind::options
long options() const
Return the current options.
Definition: kfind.cpp:650
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.
KMessageBox::Yes
@ Yes
Definition: kmessagebox.h:72
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
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
QLabel
QObject
QWidget
kDebug
#define kDebug
kdebug.h
INDEX_NOMATCH
static const int INDEX_NOMATCH
Definition: kfind.cpp:37
isInWord
static bool isInWord(QChar ch)
Definition: kfind.cpp:398
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
matchOk
static bool matchOk(const QString &text, int index, int matchedLength, long options)
Definition: kfind.cpp:415
lineBasedFind
static int lineBasedFind(const QString &text, const QRegExp &pattern, int index, long options, int *matchedLength)
Definition: kfind.cpp:528
kfind.h
kfinddialog.h
klocale.h
i18n
QString i18n(const char *text)
i18np
QString i18np(const char *sing, const char *plur, const A1 &a1)
kmessagebox.h
INDEX_NOMATCH
#define INDEX_NOMATCH
Definition: kreplace.cpp:34
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
KStandardGuiItem::cont
KGuiItem cont()
Returns the 'Continue' gui item.
Definition: kstandardguiitem.cpp:234
KStandardGuiItem::stop
KGuiItem stop()
Returns the 'Stop' gui item.
Definition: kstandardguiitem.cpp:279
KStandardGuiItem::find
KGuiItem find()
Returns the 'Find' gui item.
Definition: kstandardguiitem.cpp:274
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
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