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