xref: /glogg/src/filterset.cpp (revision 4fb0346e73d7caa82d42531c8c8681b5eb607728)
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