1 /*
2 * Copyright (C) 2009, 2010, 2011 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 classes Filter and FilterSet
21
22 #include <QSettings>
23 #include <QDataStream>
24
25 #include "log.h"
26 #include "filterset.h"
27
28 const int FilterSet::FILTERSET_VERSION = 1;
29
getPatternOptions(bool ignoreCase)30 QRegularExpression::PatternOptions getPatternOptions( bool ignoreCase )
31 {
32 QRegularExpression::PatternOptions options =
33 QRegularExpression::UseUnicodePropertiesOption
34 | QRegularExpression::OptimizeOnFirstUsageOption;
35
36 if ( ignoreCase ) {
37 options |= QRegularExpression::CaseInsensitiveOption;
38 }
39 return options;
40 }
41
Filter()42 Filter::Filter()
43 {
44 }
45
Filter(const QString & pattern,bool ignoreCase,const QString & foreColorName,const QString & backColorName)46 Filter::Filter(const QString& pattern, bool ignoreCase,
47 const QString& foreColorName, const QString& backColorName ) :
48 regexp_( pattern, getPatternOptions( ignoreCase ) ),
49 foreColorName_( foreColorName ),
50 backColorName_( backColorName ), enabled_( true )
51 {
52 LOG(logDEBUG) << "New Filter, fore: " << foreColorName_.toStdString()
53 << " back: " << backColorName_.toStdString();
54 }
55
pattern() const56 QString Filter::pattern() const
57 {
58 return regexp_.pattern();
59 }
60
setPattern(const QString & pattern)61 void Filter::setPattern( const QString& pattern )
62 {
63 regexp_.setPattern( pattern );
64 }
65
ignoreCase() const66 bool Filter::ignoreCase() const
67 {
68 return regexp_.patternOptions().testFlag(QRegularExpression::CaseInsensitiveOption);
69 }
70
setIgnoreCase(bool ignoreCase)71 void Filter::setIgnoreCase( bool ignoreCase )
72 {
73 regexp_.setPatternOptions( getPatternOptions( ignoreCase ) );
74 }
75
foreColorName() const76 const QString& Filter::foreColorName() const
77 {
78 return foreColorName_;
79 }
80
setForeColor(const QString & foreColorName)81 void Filter::setForeColor( const QString& foreColorName )
82 {
83 foreColorName_ = foreColorName;
84 }
85
backColorName() const86 const QString& Filter::backColorName() const
87 {
88 return backColorName_;
89 }
90
setBackColor(const QString & backColorName)91 void Filter::setBackColor( const QString& backColorName )
92 {
93 backColorName_ = backColorName;
94 }
95
hasMatch(const QString & string) const96 bool Filter::hasMatch( const QString& string ) const
97 {
98 return regexp_.match( string ).hasMatch();
99 }
100
101 //
102 // Operators for serialization
103 //
104
operator <<(QDataStream & out,const Filter & object)105 QDataStream& operator<<( QDataStream& out, const Filter& object )
106 {
107 LOG(logDEBUG) << "<<operator from Filter";
108 out << object.regexp_;
109 out << object.foreColorName_;
110 out << object.backColorName_;
111
112 return out;
113 }
114
operator >>(QDataStream & in,Filter & object)115 QDataStream& operator>>( QDataStream& in, Filter& object )
116 {
117 LOG(logDEBUG) << ">>operator from Filter";
118 in >> object.regexp_;
119 in >> object.foreColorName_;
120 in >> object.backColorName_;
121
122 return in;
123 }
124
125
126 // Default constructor
FilterSet()127 FilterSet::FilterSet()
128 {
129 qRegisterMetaTypeStreamOperators<Filter>( "Filter" );
130 qRegisterMetaTypeStreamOperators<FilterSet>( "FilterSet" );
131 qRegisterMetaTypeStreamOperators<FilterSet::FilterList>( "FilterSet::FilterList" );
132 }
133
matchLine(const QString & line,QColor * foreColor,QColor * backColor) const134 bool FilterSet::matchLine( const QString& line,
135 QColor* foreColor, QColor* backColor ) const
136 {
137 for ( QList<Filter>::const_iterator i = filterList.constBegin();
138 i != filterList.constEnd(); i++ ) {
139 if ( i->hasMatch( line ) ) {
140 foreColor->setNamedColor( i->foreColorName() );
141 backColor->setNamedColor( i->backColorName() );
142 return true;
143 }
144 }
145
146 return false;
147 }
148
149 //
150 // Operators for serialization
151 //
152
operator <<(QDataStream & out,const FilterSet & object)153 QDataStream& operator<<( QDataStream& out, const FilterSet& object )
154 {
155 LOG(logDEBUG) << "<<operator from FilterSet";
156 out << object.filterList;
157
158 return out;
159 }
160
operator >>(QDataStream & in,FilterSet & object)161 QDataStream& operator>>( QDataStream& in, FilterSet& object )
162 {
163 LOG(logDEBUG) << ">>operator from FilterSet";
164 in >> object.filterList;
165
166 return in;
167 }
168
169 //
170 // Persistable virtual functions implementation
171 //
172
saveToStorage(QSettings & settings) const173 void Filter::saveToStorage( QSettings& settings ) const
174 {
175 LOG(logDEBUG) << "Filter::saveToStorage";
176
177 settings.setValue( "regexp", regexp_.pattern() );
178 settings.setValue( "ignore_case", regexp_.patternOptions().testFlag( QRegularExpression::CaseInsensitiveOption ) );
179 settings.setValue( "fore_colour", foreColorName_ );
180 settings.setValue( "back_colour", backColorName_ );
181 }
182
retrieveFromStorage(QSettings & settings)183 void Filter::retrieveFromStorage( QSettings& settings )
184 {
185 LOG(logDEBUG) << "Filter::retrieveFromStorage";
186
187 regexp_ = QRegularExpression( settings.value( "regexp" ).toString(),
188 getPatternOptions( settings.value( "ignore_case", false ).toBool() ) );
189 foreColorName_ = settings.value( "fore_colour" ).toString();
190 backColorName_ = settings.value( "back_colour" ).toString();
191 }
192
saveToStorage(QSettings & settings) const193 void FilterSet::saveToStorage( QSettings& settings ) const
194 {
195 LOG(logDEBUG) << "FilterSet::saveToStorage";
196
197 settings.beginGroup( "FilterSet" );
198 // Remove everything in case the array is shorter than the previous one
199 settings.remove("");
200 settings.setValue( "version", FILTERSET_VERSION );
201 settings.beginWriteArray( "filters" );
202 for (int i = 0; i < filterList.size(); ++i) {
203 settings.setArrayIndex(i);
204 filterList[i].saveToStorage( settings );
205 }
206 settings.endArray();
207 settings.endGroup();
208 }
209
retrieveFromStorage(QSettings & settings)210 void FilterSet::retrieveFromStorage( QSettings& settings )
211 {
212 LOG(logDEBUG) << "FilterSet::retrieveFromStorage";
213
214 filterList.clear();
215
216 if ( settings.contains( "FilterSet/version" ) ) {
217 settings.beginGroup( "FilterSet" );
218 if ( settings.value( "version" ) == FILTERSET_VERSION ) {
219 int size = settings.beginReadArray( "filters" );
220 for (int i = 0; i < size; ++i) {
221 settings.setArrayIndex(i);
222 Filter filter;
223 filter.retrieveFromStorage( settings );
224 filterList.append( filter );
225 }
226 settings.endArray();
227 }
228 else {
229 LOG(logERROR) << "Unknown version of FilterSet, ignoring it...";
230 }
231 settings.endGroup();
232 }
233 else {
234 LOG(logWARNING) << "Trying to import legacy (<=0.8.2) filters...";
235 FilterSet tmp_filter_set =
236 settings.value( "filterSet" ).value<FilterSet>();
237 *this = tmp_filter_set;
238 LOG(logWARNING) << "...imported filterset: "
239 << filterList.count() << " elements";
240 // Remove the old key once migration is done
241 settings.remove( "filterSet" );
242 // And replace it with the new one
243 saveToStorage( settings );
244 settings.sync();
245 }
246 }
247