1bb02e0acSNicolas Bonnefon /*
2*e85b29ccSNicolas Bonnefon * Copyright (C) 2010, 2013, 2017 Nicolas Bonnefon and other contributors
3bb02e0acSNicolas Bonnefon *
4bb02e0acSNicolas Bonnefon * This file is part of glogg.
5bb02e0acSNicolas Bonnefon *
6bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify
7bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by
8bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or
9bb02e0acSNicolas Bonnefon * (at your option) any later version.
10bb02e0acSNicolas Bonnefon *
11bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful,
12bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of
13bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14bb02e0acSNicolas Bonnefon * GNU General Public License for more details.
15bb02e0acSNicolas Bonnefon *
16bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License
17bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>.
18bb02e0acSNicolas Bonnefon */
19bb02e0acSNicolas Bonnefon
20bb02e0acSNicolas Bonnefon // This file implements QuickFind.
21bb02e0acSNicolas Bonnefon // This class implements the Quick Find mechanism using references
22bb02e0acSNicolas Bonnefon // to the logData, the QFP and the selection passed.
23bb02e0acSNicolas Bonnefon // Search is started just after the selection and the selection is updated
24bb02e0acSNicolas Bonnefon // if a match is found.
25bb02e0acSNicolas Bonnefon
26bb02e0acSNicolas Bonnefon #include <QApplication>
27bb02e0acSNicolas Bonnefon
28bb02e0acSNicolas Bonnefon #include "log.h"
29bb02e0acSNicolas Bonnefon #include "quickfindpattern.h"
30bb02e0acSNicolas Bonnefon #include "selection.h"
31bb02e0acSNicolas Bonnefon #include "data/abstractlogdata.h"
32bb02e0acSNicolas Bonnefon
33bb02e0acSNicolas Bonnefon #include "quickfind.h"
34bb02e0acSNicolas Bonnefon
reset()35bb02e0acSNicolas Bonnefon void SearchingNotifier::reset()
36bb02e0acSNicolas Bonnefon {
37bb02e0acSNicolas Bonnefon dotToDisplay_ = 0;
38bb02e0acSNicolas Bonnefon startTime_ = QTime::currentTime();
39bb02e0acSNicolas Bonnefon }
40bb02e0acSNicolas Bonnefon
sendNotification(qint64 current_line,qint64 nb_lines)41bb02e0acSNicolas Bonnefon void SearchingNotifier::sendNotification( qint64 current_line, qint64 nb_lines )
42bb02e0acSNicolas Bonnefon {
43bb02e0acSNicolas Bonnefon qint64 progress;
44bb02e0acSNicolas Bonnefon if ( current_line < 0 )
45bb02e0acSNicolas Bonnefon progress = ( nb_lines + current_line ) * 100 / nb_lines;
46bb02e0acSNicolas Bonnefon else
47bb02e0acSNicolas Bonnefon progress = current_line * 100 / nb_lines;
48bb02e0acSNicolas Bonnefon emit notify( QFNotificationProgress( progress ) );
49bb02e0acSNicolas Bonnefon
50bb02e0acSNicolas Bonnefon QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
51*e85b29ccSNicolas Bonnefon startTime_ = QTime::currentTime();
52bb02e0acSNicolas Bonnefon }
53bb02e0acSNicolas Bonnefon
set(int line,int column)54bb02e0acSNicolas Bonnefon void QuickFind::LastMatchPosition::set( int line, int column )
55bb02e0acSNicolas Bonnefon {
56bb02e0acSNicolas Bonnefon if ( ( line_ == -1 ) ||
57bb02e0acSNicolas Bonnefon ( ( line <= line_ ) && ( column < column_ ) ) )
58bb02e0acSNicolas Bonnefon {
59bb02e0acSNicolas Bonnefon line_ = line;
60bb02e0acSNicolas Bonnefon column_ = column;
61bb02e0acSNicolas Bonnefon }
62bb02e0acSNicolas Bonnefon }
63bb02e0acSNicolas Bonnefon
set(const FilePosition & position)64bb02e0acSNicolas Bonnefon void QuickFind::LastMatchPosition::set( const FilePosition &position )
65bb02e0acSNicolas Bonnefon {
66bb02e0acSNicolas Bonnefon set( position.line(), position.column() );
67bb02e0acSNicolas Bonnefon }
68bb02e0acSNicolas Bonnefon
isLater(int line,int column) const69bb02e0acSNicolas Bonnefon bool QuickFind::LastMatchPosition::isLater( int line, int column ) const
70bb02e0acSNicolas Bonnefon {
71bb02e0acSNicolas Bonnefon if ( line_ == -1 )
72bb02e0acSNicolas Bonnefon return false;
73bb02e0acSNicolas Bonnefon else if ( ( line == line_ ) && ( column >= column_ ) )
74bb02e0acSNicolas Bonnefon return true;
75bb02e0acSNicolas Bonnefon else if ( line > line_ )
76bb02e0acSNicolas Bonnefon return true;
77bb02e0acSNicolas Bonnefon else
78bb02e0acSNicolas Bonnefon return false;
79bb02e0acSNicolas Bonnefon }
80bb02e0acSNicolas Bonnefon
isLater(const FilePosition & position) const81bb02e0acSNicolas Bonnefon bool QuickFind::LastMatchPosition::isLater( const FilePosition &position ) const
82bb02e0acSNicolas Bonnefon {
83bb02e0acSNicolas Bonnefon return isLater( position.line(), position.column() );
84bb02e0acSNicolas Bonnefon }
85bb02e0acSNicolas Bonnefon
isSooner(int line,int column) const86bb02e0acSNicolas Bonnefon bool QuickFind::LastMatchPosition::isSooner( int line, int column ) const
87bb02e0acSNicolas Bonnefon {
88bb02e0acSNicolas Bonnefon if ( line_ == -1 )
89bb02e0acSNicolas Bonnefon return false;
90bb02e0acSNicolas Bonnefon else if ( ( line == line_ ) && ( column <= column_ ) )
91bb02e0acSNicolas Bonnefon return true;
92bb02e0acSNicolas Bonnefon else if ( line < line_ )
93bb02e0acSNicolas Bonnefon return true;
94bb02e0acSNicolas Bonnefon else
95bb02e0acSNicolas Bonnefon return false;
96bb02e0acSNicolas Bonnefon }
97bb02e0acSNicolas Bonnefon
isSooner(const FilePosition & position) const98bb02e0acSNicolas Bonnefon bool QuickFind::LastMatchPosition::isSooner( const FilePosition &position ) const
99bb02e0acSNicolas Bonnefon {
100bb02e0acSNicolas Bonnefon return isSooner( position.line(), position.column() );
101bb02e0acSNicolas Bonnefon }
102bb02e0acSNicolas Bonnefon
QuickFind(const AbstractLogData * const logData,Selection * selection,const QuickFindPattern * const quickFindPattern)103bb02e0acSNicolas Bonnefon QuickFind::QuickFind( const AbstractLogData* const logData,
104bb02e0acSNicolas Bonnefon Selection* selection,
105bb02e0acSNicolas Bonnefon const QuickFindPattern* const quickFindPattern ) :
106bb02e0acSNicolas Bonnefon logData_( logData ), selection_( selection ),
107bb02e0acSNicolas Bonnefon quickFindPattern_( quickFindPattern ),
108bb02e0acSNicolas Bonnefon lastMatch_(), firstMatch_(), searchingNotifier_(),
109bb02e0acSNicolas Bonnefon incrementalSearchStatus_()
110bb02e0acSNicolas Bonnefon {
111bb02e0acSNicolas Bonnefon connect( &searchingNotifier_, SIGNAL( notify( const QFNotification& ) ),
112bb02e0acSNicolas Bonnefon this, SIGNAL( notify( const QFNotification& ) ) );
113bb02e0acSNicolas Bonnefon }
114bb02e0acSNicolas Bonnefon
incrementalSearchStop()115bb02e0acSNicolas Bonnefon void QuickFind::incrementalSearchStop()
116bb02e0acSNicolas Bonnefon {
117bb02e0acSNicolas Bonnefon if ( incrementalSearchStatus_.isOngoing() ) {
118bb02e0acSNicolas Bonnefon if ( selection_->isEmpty() ) {
119bb02e0acSNicolas Bonnefon // Nothing found?
120bb02e0acSNicolas Bonnefon // We reset the selection to what it was
121bb02e0acSNicolas Bonnefon *selection_ = incrementalSearchStatus_.initialSelection();
122bb02e0acSNicolas Bonnefon }
123bb02e0acSNicolas Bonnefon
124bb02e0acSNicolas Bonnefon incrementalSearchStatus_ = IncrementalSearchStatus();
125bb02e0acSNicolas Bonnefon }
126bb02e0acSNicolas Bonnefon }
127bb02e0acSNicolas Bonnefon
incrementalSearchAbort()128bb02e0acSNicolas Bonnefon void QuickFind::incrementalSearchAbort()
129bb02e0acSNicolas Bonnefon {
130bb02e0acSNicolas Bonnefon if ( incrementalSearchStatus_.isOngoing() ) {
131bb02e0acSNicolas Bonnefon // We reset the selection to what it was
132bb02e0acSNicolas Bonnefon *selection_ = incrementalSearchStatus_.initialSelection();
133bb02e0acSNicolas Bonnefon incrementalSearchStatus_ = IncrementalSearchStatus();
134bb02e0acSNicolas Bonnefon }
135bb02e0acSNicolas Bonnefon }
136bb02e0acSNicolas Bonnefon
incrementallySearchForward()137bb02e0acSNicolas Bonnefon qint64 QuickFind::incrementallySearchForward()
138bb02e0acSNicolas Bonnefon {
139bb02e0acSNicolas Bonnefon LOG( logDEBUG ) << "QuickFind::incrementallySearchForward";
140bb02e0acSNicolas Bonnefon
141bb02e0acSNicolas Bonnefon // Position where we start the search from
142bb02e0acSNicolas Bonnefon FilePosition start_position = selection_->getNextPosition();
143bb02e0acSNicolas Bonnefon
144bb02e0acSNicolas Bonnefon if ( incrementalSearchStatus_.direction() == Forward ) {
145bb02e0acSNicolas Bonnefon // An incremental search is active, we restart the search
146bb02e0acSNicolas Bonnefon // from the initial point
147bb02e0acSNicolas Bonnefon LOG( logDEBUG ) << "Restart search from initial point";
148bb02e0acSNicolas Bonnefon start_position = incrementalSearchStatus_.position();
149bb02e0acSNicolas Bonnefon }
150bb02e0acSNicolas Bonnefon else {
151bb02e0acSNicolas Bonnefon // It's a new search so we search from the selection
152bb02e0acSNicolas Bonnefon incrementalSearchStatus_ = IncrementalSearchStatus(
153bb02e0acSNicolas Bonnefon Forward,
154bb02e0acSNicolas Bonnefon start_position,
155bb02e0acSNicolas Bonnefon *selection_ );
156bb02e0acSNicolas Bonnefon }
157bb02e0acSNicolas Bonnefon
158bb02e0acSNicolas Bonnefon qint64 line_found = doSearchForward( start_position );
159bb02e0acSNicolas Bonnefon
160bb02e0acSNicolas Bonnefon if ( line_found >= 0 ) {
161bb02e0acSNicolas Bonnefon // We have found a result...
162bb02e0acSNicolas Bonnefon // ... the caller will jump to this line.
163bb02e0acSNicolas Bonnefon return line_found;
164bb02e0acSNicolas Bonnefon }
165bb02e0acSNicolas Bonnefon else {
166bb02e0acSNicolas Bonnefon // No result...
167bb02e0acSNicolas Bonnefon // ... we want the client to show the initial line.
168bb02e0acSNicolas Bonnefon selection_->clear();
169bb02e0acSNicolas Bonnefon return incrementalSearchStatus_.position().line();
170bb02e0acSNicolas Bonnefon }
171bb02e0acSNicolas Bonnefon }
172bb02e0acSNicolas Bonnefon
incrementallySearchBackward()173bb02e0acSNicolas Bonnefon qint64 QuickFind::incrementallySearchBackward()
174bb02e0acSNicolas Bonnefon {
175bb02e0acSNicolas Bonnefon LOG( logDEBUG ) << "QuickFind::incrementallySearchBackward";
176bb02e0acSNicolas Bonnefon
177bb02e0acSNicolas Bonnefon // Position where we start the search from
178bb02e0acSNicolas Bonnefon FilePosition start_position = selection_->getPreviousPosition();
179bb02e0acSNicolas Bonnefon
180bb02e0acSNicolas Bonnefon if ( incrementalSearchStatus_.direction() == Backward ) {
181bb02e0acSNicolas Bonnefon // An incremental search is active, we restart the search
182bb02e0acSNicolas Bonnefon // from the initial point
183bb02e0acSNicolas Bonnefon LOG( logDEBUG ) << "Restart search from initial point";
184bb02e0acSNicolas Bonnefon start_position = incrementalSearchStatus_.position();
185bb02e0acSNicolas Bonnefon }
186bb02e0acSNicolas Bonnefon else {
187bb02e0acSNicolas Bonnefon // It's a new search so we search from the selection
188bb02e0acSNicolas Bonnefon incrementalSearchStatus_ = IncrementalSearchStatus(
189bb02e0acSNicolas Bonnefon Backward,
190bb02e0acSNicolas Bonnefon start_position,
191bb02e0acSNicolas Bonnefon *selection_ );
192bb02e0acSNicolas Bonnefon }
193bb02e0acSNicolas Bonnefon
194bb02e0acSNicolas Bonnefon qint64 line_found = doSearchBackward( start_position );
195bb02e0acSNicolas Bonnefon
196bb02e0acSNicolas Bonnefon if ( line_found >= 0 ) {
197bb02e0acSNicolas Bonnefon // We have found a result...
198bb02e0acSNicolas Bonnefon // ... the caller will jump to this line.
199bb02e0acSNicolas Bonnefon return line_found;
200bb02e0acSNicolas Bonnefon }
201bb02e0acSNicolas Bonnefon else {
202bb02e0acSNicolas Bonnefon // No result...
203bb02e0acSNicolas Bonnefon // ... we want the client to show the initial line.
204bb02e0acSNicolas Bonnefon selection_->clear();
205bb02e0acSNicolas Bonnefon return incrementalSearchStatus_.position().line();
206bb02e0acSNicolas Bonnefon }
207bb02e0acSNicolas Bonnefon }
208bb02e0acSNicolas Bonnefon
searchForward()209bb02e0acSNicolas Bonnefon qint64 QuickFind::searchForward()
210bb02e0acSNicolas Bonnefon {
211bb02e0acSNicolas Bonnefon incrementalSearchStatus_ = IncrementalSearchStatus();
212bb02e0acSNicolas Bonnefon
213bb02e0acSNicolas Bonnefon // Position where we start the search from
214bb02e0acSNicolas Bonnefon FilePosition start_position = selection_->getNextPosition();
215bb02e0acSNicolas Bonnefon
216bb02e0acSNicolas Bonnefon return doSearchForward( start_position );
217bb02e0acSNicolas Bonnefon }
218bb02e0acSNicolas Bonnefon
219bb02e0acSNicolas Bonnefon
searchBackward()220bb02e0acSNicolas Bonnefon qint64 QuickFind::searchBackward()
221bb02e0acSNicolas Bonnefon {
222bb02e0acSNicolas Bonnefon incrementalSearchStatus_ = IncrementalSearchStatus();
223bb02e0acSNicolas Bonnefon
224bb02e0acSNicolas Bonnefon // Position where we start the search from
225bb02e0acSNicolas Bonnefon FilePosition start_position = selection_->getPreviousPosition();
226bb02e0acSNicolas Bonnefon
227bb02e0acSNicolas Bonnefon return doSearchBackward( start_position );
228bb02e0acSNicolas Bonnefon }
229bb02e0acSNicolas Bonnefon
230bb02e0acSNicolas Bonnefon // Internal implementation of forward search,
231bb02e0acSNicolas Bonnefon // returns the line where the pattern is found or -1 if not found.
232bb02e0acSNicolas Bonnefon // Parameters are the position the search shall start
doSearchForward(const FilePosition & start_position)233bb02e0acSNicolas Bonnefon qint64 QuickFind::doSearchForward( const FilePosition &start_position )
234bb02e0acSNicolas Bonnefon {
235bb02e0acSNicolas Bonnefon bool found = false;
236bb02e0acSNicolas Bonnefon int found_start_col;
237bb02e0acSNicolas Bonnefon int found_end_col;
238bb02e0acSNicolas Bonnefon
239*e85b29ccSNicolas Bonnefon if ( searchState_ == SearchState::OnGoing ) {
240*e85b29ccSNicolas Bonnefon // This happens if this function is re-entered via the notifier
241*e85b29ccSNicolas Bonnefon // We want the top most call to restart the search
242*e85b29ccSNicolas Bonnefon searchState_ = SearchState::RestartNeeded;
243*e85b29ccSNicolas Bonnefon return -1;
244*e85b29ccSNicolas Bonnefon }
245*e85b29ccSNicolas Bonnefon
246bb02e0acSNicolas Bonnefon if ( ! quickFindPattern_->isActive() )
247bb02e0acSNicolas Bonnefon return -1;
248bb02e0acSNicolas Bonnefon
249bb02e0acSNicolas Bonnefon // Optimisation: if we are already after the last match,
250bb02e0acSNicolas Bonnefon // we don't do any search at all.
251bb02e0acSNicolas Bonnefon if ( lastMatch_.isLater( start_position ) ) {
252bb02e0acSNicolas Bonnefon // Send a notification
253bb02e0acSNicolas Bonnefon emit notify( QFNotificationReachedEndOfFile() );
254bb02e0acSNicolas Bonnefon
255bb02e0acSNicolas Bonnefon return -1;
256bb02e0acSNicolas Bonnefon }
257bb02e0acSNicolas Bonnefon
258bb02e0acSNicolas Bonnefon qint64 line = start_position.line();
259bb02e0acSNicolas Bonnefon LOG( logDEBUG ) << "Start searching at line " << line;
260bb02e0acSNicolas Bonnefon // We look at the rest of the first line
261bb02e0acSNicolas Bonnefon if ( quickFindPattern_->isLineMatching(
262bb02e0acSNicolas Bonnefon logData_->getExpandedLineString( line ),
263bb02e0acSNicolas Bonnefon start_position.column() ) ) {
264bb02e0acSNicolas Bonnefon quickFindPattern_->getLastMatch( &found_start_col, &found_end_col );
265bb02e0acSNicolas Bonnefon found = true;
266bb02e0acSNicolas Bonnefon }
267bb02e0acSNicolas Bonnefon else {
268bb02e0acSNicolas Bonnefon searchingNotifier_.reset();
269*e85b29ccSNicolas Bonnefon searchState_ = SearchState::OnGoing;
270bb02e0acSNicolas Bonnefon // And then the rest of the file
271bb02e0acSNicolas Bonnefon qint64 nb_lines = logData_->getNbLine();
272*e85b29ccSNicolas Bonnefon int start_line = ++line;
273bb02e0acSNicolas Bonnefon while ( line < nb_lines ) {
274*e85b29ccSNicolas Bonnefon // Check if someone has changed the search within this loop
275*e85b29ccSNicolas Bonnefon if ( searchState_ == SearchState::RestartNeeded ) {
276*e85b29ccSNicolas Bonnefon line = start_line;
277*e85b29ccSNicolas Bonnefon searchState_ = SearchState::OnGoing;
278*e85b29ccSNicolas Bonnefon LOG( logDEBUG ) << "QuickFind restarted at line " << line;
279*e85b29ccSNicolas Bonnefon }
280*e85b29ccSNicolas Bonnefon
281bb02e0acSNicolas Bonnefon if ( quickFindPattern_->isLineMatching(
282bb02e0acSNicolas Bonnefon logData_->getExpandedLineString( line ) ) ) {
283bb02e0acSNicolas Bonnefon quickFindPattern_->getLastMatch(
284bb02e0acSNicolas Bonnefon &found_start_col, &found_end_col );
285bb02e0acSNicolas Bonnefon found = true;
286*e85b29ccSNicolas Bonnefon LOG( logDEBUG ) << "QuickFind found!";
287bb02e0acSNicolas Bonnefon break;
288bb02e0acSNicolas Bonnefon }
289bb02e0acSNicolas Bonnefon line++;
290bb02e0acSNicolas Bonnefon
291bb02e0acSNicolas Bonnefon // See if we need to notify of the ongoing search
292*e85b29ccSNicolas Bonnefon // Note this could re-enter this function if the pattern is
293*e85b29ccSNicolas Bonnefon // modified whilst the search is on-going, this is okay.
294bb02e0acSNicolas Bonnefon searchingNotifier_.ping( line, nb_lines );
295bb02e0acSNicolas Bonnefon }
296*e85b29ccSNicolas Bonnefon
297*e85b29ccSNicolas Bonnefon searchState_ = SearchState::Idle;
298bb02e0acSNicolas Bonnefon }
299bb02e0acSNicolas Bonnefon
300bb02e0acSNicolas Bonnefon if ( found ) {
301bb02e0acSNicolas Bonnefon selection_->selectPortion(
302bb02e0acSNicolas Bonnefon line, found_start_col, found_end_col );
303bb02e0acSNicolas Bonnefon
304bb02e0acSNicolas Bonnefon // Clear any notification
305bb02e0acSNicolas Bonnefon emit clearNotification();
306bb02e0acSNicolas Bonnefon
307bb02e0acSNicolas Bonnefon return line;
308bb02e0acSNicolas Bonnefon }
309bb02e0acSNicolas Bonnefon else {
310bb02e0acSNicolas Bonnefon // Update the position of the last match
311bb02e0acSNicolas Bonnefon FilePosition last_match_position = selection_->getPreviousPosition();
312bb02e0acSNicolas Bonnefon lastMatch_.set( last_match_position );
313bb02e0acSNicolas Bonnefon
314bb02e0acSNicolas Bonnefon // Send a notification
315bb02e0acSNicolas Bonnefon emit notify( QFNotificationReachedEndOfFile() );
316bb02e0acSNicolas Bonnefon
317bb02e0acSNicolas Bonnefon return -1;
318bb02e0acSNicolas Bonnefon }
319bb02e0acSNicolas Bonnefon }
320bb02e0acSNicolas Bonnefon
321bb02e0acSNicolas Bonnefon // Internal implementation of backward search,
322bb02e0acSNicolas Bonnefon // returns the line where the pattern is found or -1 if not found.
323bb02e0acSNicolas Bonnefon // Parameters are the position the search shall start
doSearchBackward(const FilePosition & start_position)324bb02e0acSNicolas Bonnefon qint64 QuickFind::doSearchBackward( const FilePosition &start_position )
325bb02e0acSNicolas Bonnefon {
326bb02e0acSNicolas Bonnefon bool found = false;
327bb02e0acSNicolas Bonnefon int start_col;
328bb02e0acSNicolas Bonnefon int end_col;
329bb02e0acSNicolas Bonnefon
330bb02e0acSNicolas Bonnefon if ( ! quickFindPattern_->isActive() )
331bb02e0acSNicolas Bonnefon return -1;
332bb02e0acSNicolas Bonnefon
333bb02e0acSNicolas Bonnefon // Optimisation: if we are already before the first match,
334bb02e0acSNicolas Bonnefon // we don't do any search at all.
335bb02e0acSNicolas Bonnefon if ( firstMatch_.isSooner( start_position ) ) {
336bb02e0acSNicolas Bonnefon // Send a notification
337bb02e0acSNicolas Bonnefon emit notify( QFNotificationReachedBegininningOfFile() );
338bb02e0acSNicolas Bonnefon
339bb02e0acSNicolas Bonnefon return -1;
340bb02e0acSNicolas Bonnefon }
341bb02e0acSNicolas Bonnefon
342bb02e0acSNicolas Bonnefon qint64 line = start_position.line();
343bb02e0acSNicolas Bonnefon LOG( logDEBUG ) << "Start searching at line " << line;
344bb02e0acSNicolas Bonnefon // We look at the beginning of the first line
345bb02e0acSNicolas Bonnefon if ( ( start_position.column() > 0 )
346bb02e0acSNicolas Bonnefon && ( quickFindPattern_->isLineMatchingBackward(
347bb02e0acSNicolas Bonnefon logData_->getExpandedLineString( line ),
348bb02e0acSNicolas Bonnefon start_position.column() ) )
349bb02e0acSNicolas Bonnefon ) {
350bb02e0acSNicolas Bonnefon quickFindPattern_->getLastMatch( &start_col, &end_col );
351bb02e0acSNicolas Bonnefon found = true;
352bb02e0acSNicolas Bonnefon }
353bb02e0acSNicolas Bonnefon else {
354bb02e0acSNicolas Bonnefon searchingNotifier_.reset();
355bb02e0acSNicolas Bonnefon // And then the rest of the file
356bb02e0acSNicolas Bonnefon qint64 nb_lines = logData_->getNbLine();
357bb02e0acSNicolas Bonnefon line--;
358bb02e0acSNicolas Bonnefon while ( line >= 0 ) {
359bb02e0acSNicolas Bonnefon if ( quickFindPattern_->isLineMatchingBackward(
360bb02e0acSNicolas Bonnefon logData_->getExpandedLineString( line ) ) ) {
361bb02e0acSNicolas Bonnefon quickFindPattern_->getLastMatch( &start_col, &end_col );
362bb02e0acSNicolas Bonnefon found = true;
363bb02e0acSNicolas Bonnefon break;
364bb02e0acSNicolas Bonnefon }
365bb02e0acSNicolas Bonnefon line--;
366bb02e0acSNicolas Bonnefon
367bb02e0acSNicolas Bonnefon // See if we need to notify of the ongoing search
368bb02e0acSNicolas Bonnefon searchingNotifier_.ping( -line, nb_lines );
369bb02e0acSNicolas Bonnefon }
370bb02e0acSNicolas Bonnefon }
371bb02e0acSNicolas Bonnefon
372bb02e0acSNicolas Bonnefon if ( found )
373bb02e0acSNicolas Bonnefon {
374bb02e0acSNicolas Bonnefon selection_->selectPortion( line, start_col, end_col );
375bb02e0acSNicolas Bonnefon
376bb02e0acSNicolas Bonnefon // Clear any notification
377bb02e0acSNicolas Bonnefon emit clearNotification();
378bb02e0acSNicolas Bonnefon
379bb02e0acSNicolas Bonnefon return line;
380bb02e0acSNicolas Bonnefon }
381bb02e0acSNicolas Bonnefon else {
382bb02e0acSNicolas Bonnefon // Update the position of the first match
383bb02e0acSNicolas Bonnefon FilePosition first_match_position = selection_->getNextPosition();
384bb02e0acSNicolas Bonnefon firstMatch_.set( first_match_position );
385bb02e0acSNicolas Bonnefon
386bb02e0acSNicolas Bonnefon // Send a notification
387b423cd88SNicolas Bonnefon LOG( logDEBUG ) << "QF: Send BOF notification.";
388bb02e0acSNicolas Bonnefon emit notify( QFNotificationReachedBegininningOfFile() );
389bb02e0acSNicolas Bonnefon
390bb02e0acSNicolas Bonnefon return -1;
391bb02e0acSNicolas Bonnefon }
392bb02e0acSNicolas Bonnefon }
393bb02e0acSNicolas Bonnefon
resetLimits()394bb02e0acSNicolas Bonnefon void QuickFind::resetLimits()
395bb02e0acSNicolas Bonnefon {
396bb02e0acSNicolas Bonnefon lastMatch_.reset();
397bb02e0acSNicolas Bonnefon firstMatch_.reset();
398bb02e0acSNicolas Bonnefon }
399