xref: /glogg/src/quickfind.h (revision bb02e0acf44ddb4e4f83d6127a1e488789162922)
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 #ifndef QUICKFIND_H
21*bb02e0acSNicolas Bonnefon #define QUICKFIND_H
22*bb02e0acSNicolas Bonnefon 
23*bb02e0acSNicolas Bonnefon #include <QObject>
24*bb02e0acSNicolas Bonnefon #include <QPoint>
25*bb02e0acSNicolas Bonnefon #include <QTime>
26*bb02e0acSNicolas Bonnefon 
27*bb02e0acSNicolas Bonnefon #include "utils.h"
28*bb02e0acSNicolas Bonnefon #include "qfnotifications.h"
29*bb02e0acSNicolas Bonnefon #include "selection.h"
30*bb02e0acSNicolas Bonnefon 
31*bb02e0acSNicolas Bonnefon class QuickFindPattern;
32*bb02e0acSNicolas Bonnefon class AbstractLogData;
33*bb02e0acSNicolas Bonnefon class Portion;
34*bb02e0acSNicolas Bonnefon 
35*bb02e0acSNicolas Bonnefon // Handle "long processing" notifications to the UI.
36*bb02e0acSNicolas Bonnefon // reset() shall be called at the beginning of the search
37*bb02e0acSNicolas Bonnefon // and then ping() should be called periodically during the processing.
38*bb02e0acSNicolas Bonnefon // The notify() signal should be forwarded to the UI.
39*bb02e0acSNicolas Bonnefon class SearchingNotifier : public QObject
40*bb02e0acSNicolas Bonnefon {
41*bb02e0acSNicolas Bonnefon   Q_OBJECT
42*bb02e0acSNicolas Bonnefon 
43*bb02e0acSNicolas Bonnefon   public:
44*bb02e0acSNicolas Bonnefon     SearchingNotifier() {};
45*bb02e0acSNicolas Bonnefon 
46*bb02e0acSNicolas Bonnefon     // Reset internal timers at the beiginning of the processing
47*bb02e0acSNicolas Bonnefon     void reset();
48*bb02e0acSNicolas Bonnefon     // Shall be called frequently during processing, send the notification
49*bb02e0acSNicolas Bonnefon     // and call the event loop when appropriate.
50*bb02e0acSNicolas Bonnefon     // Pass the current line number and total number of line so that
51*bb02e0acSNicolas Bonnefon     // a progress percentage is calculated and displayed.
52*bb02e0acSNicolas Bonnefon     // (line shall be negative if ging in reverse)
53*bb02e0acSNicolas Bonnefon     inline void ping( qint64 line, qint64 nb_lines ) {
54*bb02e0acSNicolas Bonnefon         if ( startTime_.msecsTo( QTime::currentTime() ) > 1000 )
55*bb02e0acSNicolas Bonnefon             sendNotification( line, nb_lines );
56*bb02e0acSNicolas Bonnefon     }
57*bb02e0acSNicolas Bonnefon 
58*bb02e0acSNicolas Bonnefon   signals:
59*bb02e0acSNicolas Bonnefon     // Sent when the UI shall display a message to the user.
60*bb02e0acSNicolas Bonnefon     void notify( const QFNotification& message );
61*bb02e0acSNicolas Bonnefon 
62*bb02e0acSNicolas Bonnefon   private:
63*bb02e0acSNicolas Bonnefon     void sendNotification( qint64 current_line, qint64 nb_lines );
64*bb02e0acSNicolas Bonnefon 
65*bb02e0acSNicolas Bonnefon     QTime startTime_;
66*bb02e0acSNicolas Bonnefon     int dotToDisplay_;
67*bb02e0acSNicolas Bonnefon };
68*bb02e0acSNicolas Bonnefon 
69*bb02e0acSNicolas Bonnefon // Represents a search made with Quick Find (without its results)
70*bb02e0acSNicolas Bonnefon // it keeps a pointer to a set of data and to a QuickFindPattern which
71*bb02e0acSNicolas Bonnefon // are used for the searches. (the caller retains ownership of both).
72*bb02e0acSNicolas Bonnefon class QuickFind : public QObject
73*bb02e0acSNicolas Bonnefon {
74*bb02e0acSNicolas Bonnefon   Q_OBJECT
75*bb02e0acSNicolas Bonnefon 
76*bb02e0acSNicolas Bonnefon   public:
77*bb02e0acSNicolas Bonnefon     // Construct a search
78*bb02e0acSNicolas Bonnefon     QuickFind( const AbstractLogData* const logData, Selection* selection,
79*bb02e0acSNicolas Bonnefon             const QuickFindPattern* const quickFindPattern );
80*bb02e0acSNicolas Bonnefon 
81*bb02e0acSNicolas Bonnefon     // Set the starting point that will be used by the next search
82*bb02e0acSNicolas Bonnefon     void setSearchStartPoint( QPoint startPoint );
83*bb02e0acSNicolas Bonnefon 
84*bb02e0acSNicolas Bonnefon     // Used for incremental searches
85*bb02e0acSNicolas Bonnefon     // Return the first occurence of the passed pattern from the starting
86*bb02e0acSNicolas Bonnefon     // point.  These searches don't use the QFP and don't change the
87*bb02e0acSNicolas Bonnefon     // starting point.
88*bb02e0acSNicolas Bonnefon     // TODO Update comment
89*bb02e0acSNicolas Bonnefon     qint64 incrementallySearchForward();
90*bb02e0acSNicolas Bonnefon     qint64 incrementallySearchBackward();
91*bb02e0acSNicolas Bonnefon 
92*bb02e0acSNicolas Bonnefon     // Stop the currently ongoing incremental search, leave the selection
93*bb02e0acSNicolas Bonnefon     // where it is if a match has been found, restore the old one
94*bb02e0acSNicolas Bonnefon     // if not. Also throw away the start point associated with
95*bb02e0acSNicolas Bonnefon     // the search.
96*bb02e0acSNicolas Bonnefon     void incrementalSearchStop();
97*bb02e0acSNicolas Bonnefon 
98*bb02e0acSNicolas Bonnefon     // Throw away the current search and restore the initial
99*bb02e0acSNicolas Bonnefon     // position/selection
100*bb02e0acSNicolas Bonnefon     void incrementalSearchAbort();
101*bb02e0acSNicolas Bonnefon 
102*bb02e0acSNicolas Bonnefon     // Used for 'repeated' (n/N) QF searches using the current direction
103*bb02e0acSNicolas Bonnefon     // Return the line of the first occurence of the QFP and
104*bb02e0acSNicolas Bonnefon     // update the selection. It returns -1 if nothing is found.
105*bb02e0acSNicolas Bonnefon     /*
106*bb02e0acSNicolas Bonnefon     int searchNext();
107*bb02e0acSNicolas Bonnefon     int searchPrevious();
108*bb02e0acSNicolas Bonnefon     */
109*bb02e0acSNicolas Bonnefon 
110*bb02e0acSNicolas Bonnefon     // Idem but ignore the direction and always search in the
111*bb02e0acSNicolas Bonnefon     // specified direction
112*bb02e0acSNicolas Bonnefon     qint64 searchForward();
113*bb02e0acSNicolas Bonnefon     qint64 searchBackward();
114*bb02e0acSNicolas Bonnefon 
115*bb02e0acSNicolas Bonnefon     // Make the object forget the 'no more match' flag.
116*bb02e0acSNicolas Bonnefon     void resetLimits();
117*bb02e0acSNicolas Bonnefon 
118*bb02e0acSNicolas Bonnefon   signals:
119*bb02e0acSNicolas Bonnefon     // Sent when the UI shall display a message to the user.
120*bb02e0acSNicolas Bonnefon     void notify( const QFNotification& message );
121*bb02e0acSNicolas Bonnefon     // Sent when the UI shall clear the notification.
122*bb02e0acSNicolas Bonnefon     void clearNotification();
123*bb02e0acSNicolas Bonnefon 
124*bb02e0acSNicolas Bonnefon   private:
125*bb02e0acSNicolas Bonnefon     enum QFDirection {
126*bb02e0acSNicolas Bonnefon         None,
127*bb02e0acSNicolas Bonnefon         Forward,
128*bb02e0acSNicolas Bonnefon         Backward,
129*bb02e0acSNicolas Bonnefon     };
130*bb02e0acSNicolas Bonnefon 
131*bb02e0acSNicolas Bonnefon     class LastMatchPosition {
132*bb02e0acSNicolas Bonnefon       public:
133*bb02e0acSNicolas Bonnefon         LastMatchPosition() : line_( -1 ), column_( -1 ) {}
134*bb02e0acSNicolas Bonnefon         void set( int line, int column );
135*bb02e0acSNicolas Bonnefon         void set( const FilePosition& position );
136*bb02e0acSNicolas Bonnefon         void reset() { line_ = -1; column_ = -1; }
137*bb02e0acSNicolas Bonnefon         // Does the passed position come after the recorded one
138*bb02e0acSNicolas Bonnefon         bool isLater( int line, int column ) const;
139*bb02e0acSNicolas Bonnefon         bool isLater( const FilePosition& position ) const;
140*bb02e0acSNicolas Bonnefon         // Does the passed position come before the recorded one
141*bb02e0acSNicolas Bonnefon         bool isSooner( int line, int column ) const;
142*bb02e0acSNicolas Bonnefon         bool isSooner( const FilePosition& position ) const;
143*bb02e0acSNicolas Bonnefon 
144*bb02e0acSNicolas Bonnefon       private:
145*bb02e0acSNicolas Bonnefon         int line_;
146*bb02e0acSNicolas Bonnefon         int column_;
147*bb02e0acSNicolas Bonnefon     };
148*bb02e0acSNicolas Bonnefon 
149*bb02e0acSNicolas Bonnefon     class IncrementalSearchStatus {
150*bb02e0acSNicolas Bonnefon       public:
151*bb02e0acSNicolas Bonnefon         /* Constructors */
152*bb02e0acSNicolas Bonnefon         IncrementalSearchStatus() :
153*bb02e0acSNicolas Bonnefon             ongoing_( None ), position_(), initialSelection_() {}
154*bb02e0acSNicolas Bonnefon         IncrementalSearchStatus(
155*bb02e0acSNicolas Bonnefon                 QFDirection direction,
156*bb02e0acSNicolas Bonnefon                 const FilePosition& position,
157*bb02e0acSNicolas Bonnefon                 const Selection& initial_selection ) :
158*bb02e0acSNicolas Bonnefon             ongoing_( direction ),
159*bb02e0acSNicolas Bonnefon             position_( position ),
160*bb02e0acSNicolas Bonnefon             initialSelection_( initial_selection ) {}
161*bb02e0acSNicolas Bonnefon 
162*bb02e0acSNicolas Bonnefon         bool isOngoing() const { return ( ongoing_ != None ); }
163*bb02e0acSNicolas Bonnefon         QFDirection direction() const { return ongoing_; }
164*bb02e0acSNicolas Bonnefon         FilePosition position() const { return position_; }
165*bb02e0acSNicolas Bonnefon         Selection initialSelection() const { return initialSelection_; }
166*bb02e0acSNicolas Bonnefon       private:
167*bb02e0acSNicolas Bonnefon         QFDirection ongoing_;
168*bb02e0acSNicolas Bonnefon         FilePosition position_;
169*bb02e0acSNicolas Bonnefon         Selection initialSelection_;
170*bb02e0acSNicolas Bonnefon     };
171*bb02e0acSNicolas Bonnefon 
172*bb02e0acSNicolas Bonnefon     // Pointers to external objects
173*bb02e0acSNicolas Bonnefon     const AbstractLogData* const logData_;
174*bb02e0acSNicolas Bonnefon     Selection* selection_;
175*bb02e0acSNicolas Bonnefon     const QuickFindPattern* const quickFindPattern_;
176*bb02e0acSNicolas Bonnefon 
177*bb02e0acSNicolas Bonnefon     // Owned objects
178*bb02e0acSNicolas Bonnefon 
179*bb02e0acSNicolas Bonnefon     // Position of the last match in the file
180*bb02e0acSNicolas Bonnefon     // (to avoid searching multiple times where there is no result)
181*bb02e0acSNicolas Bonnefon     LastMatchPosition lastMatch_;
182*bb02e0acSNicolas Bonnefon     LastMatchPosition firstMatch_;
183*bb02e0acSNicolas Bonnefon 
184*bb02e0acSNicolas Bonnefon     SearchingNotifier searchingNotifier_;
185*bb02e0acSNicolas Bonnefon 
186*bb02e0acSNicolas Bonnefon     // Incremental search status
187*bb02e0acSNicolas Bonnefon     IncrementalSearchStatus incrementalSearchStatus_;
188*bb02e0acSNicolas Bonnefon 
189*bb02e0acSNicolas Bonnefon     // Private functions
190*bb02e0acSNicolas Bonnefon     qint64 doSearchForward( const FilePosition &start_position );
191*bb02e0acSNicolas Bonnefon     qint64 doSearchBackward( const FilePosition &start_position );
192*bb02e0acSNicolas Bonnefon };
193*bb02e0acSNicolas Bonnefon 
194*bb02e0acSNicolas Bonnefon #endif
195