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