xref: /glogg/src/quickfindpattern.cpp (revision 4fb0346e73d7caa82d42531c8c8681b5eb607728)
1 /*
2  * Copyright (C) 2010 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 // This file implements QuickFindPattern.
21 // This class implements part of the Quick Find mechanism, it only stores the
22 // current search pattern, once it has been confirmed (return pressed),
23 // it can be asked to return the matches in a specific string.
24 
25 #include "quickfindpattern.h"
26 
27 #include "persistentinfo.h"
28 #include "configuration.h"
29 
30 QuickFindPattern::QuickFindPattern() : QObject(), regexp_()
31 {
32     active_ = false;
33 }
34 
35 void QuickFindPattern::changeSearchPattern( const QString& pattern )
36 {
37     // Determine the type of regexp depending on the config
38     QString searchPattern;
39     switch ( Persistent<Configuration>( "settings" )->quickfindRegexpType() ) {
40         case Wildcard:
41             searchPattern = pattern;
42             searchPattern.replace('*', ".*").replace('?', ".");
43             break;
44         case FixedString:
45             searchPattern = QRegularExpression::escape(pattern);
46             break;
47         default:
48             searchPattern = pattern;
49             break;
50     }
51 
52     regexp_.setPattern( pattern );
53 
54     if ( regexp_.isValid() && ( ! searchPattern.isEmpty() ) )
55         active_ = true;
56     else
57         active_ = false;
58 
59     emit patternUpdated();
60 }
61 
62 void QuickFindPattern::changeSearchPattern( const QString& pattern, bool ignoreCase )
63 {
64     QRegularExpression::PatternOptions options =
65             QRegularExpression::UseUnicodePropertiesOption
66             | QRegularExpression::OptimizeOnFirstUsageOption;
67 
68     if ( ignoreCase )
69         options |= QRegularExpression::CaseInsensitiveOption;
70 
71     regexp_.setPatternOptions(options);
72     changeSearchPattern( pattern );
73 }
74 
75 bool QuickFindPattern::matchLine( const QString& line,
76         QList<QuickFindMatch>& matches ) const
77 {
78     matches.clear();
79 
80     if ( active_ ) {
81         QRegularExpressionMatchIterator matchIterator = regexp_.globalMatch(line);
82 
83         while( matchIterator.hasNext() ) {
84             QRegularExpressionMatch match = matchIterator.next();
85             matches << QuickFindMatch ( match.capturedStart(), match.capturedLength() );
86         }
87     }
88 
89     return ( matches.count() > 0 );
90 }
91 
92 bool QuickFindPattern::isLineMatching( const QString& line, int column ) const
93 {
94     if ( ! active_ )
95         return false;
96 
97     QRegularExpressionMatch match = regexp_.match( line, column );
98     if ( match.hasMatch() ) {
99         lastMatchStart_ = match.capturedStart();
100         lastMatchEnd_ = match.capturedEnd() - 1;
101         return true;
102     }
103     else {
104         return false;
105     }
106 }
107 
108 bool QuickFindPattern::isLineMatchingBackward(
109         const QString& line, int column ) const
110 {
111     int pos = 0;
112 
113     if ( ! active_ )
114         return false;
115 
116     QRegularExpressionMatchIterator matches = regexp_.globalMatch(line);
117     QRegularExpressionMatch lastMatch;
118     while ( matches.hasNext() ) {
119         QRegularExpressionMatch nextMatch = matches.peekNext();
120         if ( column >= 0 && nextMatch.capturedEnd() >= column ) {
121             break;
122         }
123 
124         lastMatch = matches.next();
125     }
126 
127     if ( lastMatch.hasMatch() ) {
128         lastMatchStart_ = lastMatch.capturedStart();
129         lastMatchEnd_ = lastMatch.capturedEnd() - 1;
130         return true;
131     }
132     else {
133         return false;
134     }
135 }
136 
137 void QuickFindPattern::getLastMatch( int* start_col, int* end_col ) const
138 {
139     *start_col = lastMatchStart_;
140     *end_col   = lastMatchEnd_;
141 }
142