/*
* Copyright (C) 2010, 2013 Nicolas Bonnefon and other contributors
*
* This file is part of glogg.
*
* glogg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* glogg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with glogg. If not, see .
*/
#ifndef QUICKFIND_H
#define QUICKFIND_H
#include
#include
#include
#include "utils.h"
#include "qfnotifications.h"
#include "selection.h"
class QuickFindPattern;
class AbstractLogData;
class Portion;
// Handle "long processing" notifications to the UI.
// reset() shall be called at the beginning of the search
// and then ping() should be called periodically during the processing.
// The notify() signal should be forwarded to the UI.
class SearchingNotifier : public QObject
{
Q_OBJECT
public:
SearchingNotifier() {};
// Reset internal timers at the beiginning of the processing
void reset();
// Shall be called frequently during processing, send the notification
// and call the event loop when appropriate.
// Pass the current line number and total number of line so that
// a progress percentage is calculated and displayed.
// (line shall be negative if ging in reverse)
inline void ping( qint64 line, qint64 nb_lines ) {
if ( startTime_.msecsTo( QTime::currentTime() ) > 200 )
sendNotification( line, nb_lines );
}
signals:
// Sent when the UI shall display a message to the user.
void notify( const QFNotification& message );
private:
void sendNotification( qint64 current_line, qint64 nb_lines );
QTime startTime_;
int dotToDisplay_;
};
// Represents a search made with Quick Find (without its results)
// it keeps a pointer to a set of data and to a QuickFindPattern which
// are used for the searches. (the caller retains ownership of both).
class QuickFind : public QObject
{
Q_OBJECT
public:
// Construct a search
QuickFind( const AbstractLogData* const logData, Selection* selection,
const QuickFindPattern* const quickFindPattern );
// Set the starting point that will be used by the next search
void setSearchStartPoint( QPoint startPoint );
// Used for incremental searches
// Return the first occurence of the passed pattern from the starting
// point. These searches don't use the QFP and don't change the
// starting point.
// TODO Update comment
qint64 incrementallySearchForward();
qint64 incrementallySearchBackward();
// Stop the currently ongoing incremental search, leave the selection
// where it is if a match has been found, restore the old one
// if not. Also throw away the start point associated with
// the search.
void incrementalSearchStop();
// Throw away the current search and restore the initial
// position/selection
void incrementalSearchAbort();
// Used for 'repeated' (n/N) QF searches using the current direction
// Return the line of the first occurence of the QFP and
// update the selection. It returns -1 if nothing is found.
/*
int searchNext();
int searchPrevious();
*/
// Idem but ignore the direction and always search in the
// specified direction
qint64 searchForward();
qint64 searchBackward();
// Make the object forget the 'no more match' flag.
void resetLimits();
signals:
// Sent when the UI shall display a message to the user.
void notify( const QFNotification& message );
// Sent when the UI shall clear the notification.
void clearNotification();
private:
enum QFDirection {
None,
Forward,
Backward,
};
enum class SearchState {
Idle,
OnGoing,
RestartNeeded,
};
class LastMatchPosition {
public:
LastMatchPosition() : line_( -1 ), column_( -1 ) {}
void set( int line, int column );
void set( const FilePosition& position );
void reset() { line_ = -1; column_ = -1; }
// Does the passed position come after the recorded one
bool isLater( int line, int column ) const;
bool isLater( const FilePosition& position ) const;
// Does the passed position come before the recorded one
bool isSooner( int line, int column ) const;
bool isSooner( const FilePosition& position ) const;
private:
int line_;
int column_;
};
class IncrementalSearchStatus {
public:
/* Constructors */
IncrementalSearchStatus() :
ongoing_( None ), position_(), initialSelection_() {}
IncrementalSearchStatus(
QFDirection direction,
const FilePosition& position,
const Selection& initial_selection ) :
ongoing_( direction ),
position_( position ),
initialSelection_( initial_selection ) {}
bool isOngoing() const { return ( ongoing_ != None ); }
QFDirection direction() const { return ongoing_; }
FilePosition position() const { return position_; }
Selection initialSelection() const { return initialSelection_; }
private:
QFDirection ongoing_;
FilePosition position_;
Selection initialSelection_;
};
// Pointers to external objects
const AbstractLogData* const logData_;
Selection* selection_;
const QuickFindPattern* const quickFindPattern_;
// Owned objects
// Position of the last match in the file
// (to avoid searching multiple times where there is no result)
LastMatchPosition lastMatch_;
LastMatchPosition firstMatch_;
SearchingNotifier searchingNotifier_;
// Incremental search status
IncrementalSearchStatus incrementalSearchStatus_;
// Flag to request stopping the search
// (e.g. on key press)
SearchState searchState_;
// Private functions
qint64 doSearchForward( const FilePosition &start_position );
qint64 doSearchBackward( const FilePosition &start_position );
};
#endif