1bb02e0acSNicolas Bonnefon /*
2bb02e0acSNicolas Bonnefon * Copyright (C) 2009, 2010, 2011 Nicolas Bonnefon and other contributors
3bb02e0acSNicolas Bonnefon *
4bb02e0acSNicolas Bonnefon * This file is part of glogg.
5bb02e0acSNicolas Bonnefon *
6bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify
7bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by
8bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or
9bb02e0acSNicolas Bonnefon * (at your option) any later version.
10bb02e0acSNicolas Bonnefon *
11bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful,
12bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of
13bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14bb02e0acSNicolas Bonnefon * GNU General Public License for more details.
15bb02e0acSNicolas Bonnefon *
16bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License
17bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>.
18bb02e0acSNicolas Bonnefon */
19bb02e0acSNicolas Bonnefon
20bb02e0acSNicolas Bonnefon // This file implements classes Filter and FilterSet
21bb02e0acSNicolas Bonnefon
22bb02e0acSNicolas Bonnefon #include <QSettings>
231a30cd4dSJonathan Wakely #include <QDataStream>
24bb02e0acSNicolas Bonnefon
25bb02e0acSNicolas Bonnefon #include "log.h"
26bb02e0acSNicolas Bonnefon #include "filterset.h"
27bb02e0acSNicolas Bonnefon
28bb02e0acSNicolas Bonnefon const int FilterSet::FILTERSET_VERSION = 1;
29bb02e0acSNicolas Bonnefon
getPatternOptions(bool ignoreCase)30*4fb0346eSAnton Filimonov QRegularExpression::PatternOptions getPatternOptions( bool ignoreCase )
31b9c9a815SAnton Filimonov {
32*4fb0346eSAnton Filimonov QRegularExpression::PatternOptions options =
33*4fb0346eSAnton Filimonov QRegularExpression::UseUnicodePropertiesOption
34*4fb0346eSAnton Filimonov | QRegularExpression::OptimizeOnFirstUsageOption;
35*4fb0346eSAnton Filimonov
36*4fb0346eSAnton Filimonov if ( ignoreCase ) {
37*4fb0346eSAnton Filimonov options |= QRegularExpression::CaseInsensitiveOption;
38*4fb0346eSAnton Filimonov }
39*4fb0346eSAnton Filimonov return options;
40b9c9a815SAnton Filimonov }
41b9c9a815SAnton Filimonov
Filter()42bb02e0acSNicolas Bonnefon Filter::Filter()
43bb02e0acSNicolas Bonnefon {
44bb02e0acSNicolas Bonnefon }
45bb02e0acSNicolas Bonnefon
Filter(const QString & pattern,bool ignoreCase,const QString & foreColorName,const QString & backColorName)46b9c9a815SAnton Filimonov Filter::Filter(const QString& pattern, bool ignoreCase,
47bb02e0acSNicolas Bonnefon const QString& foreColorName, const QString& backColorName ) :
48*4fb0346eSAnton Filimonov regexp_( pattern, getPatternOptions( ignoreCase ) ),
49b9c9a815SAnton Filimonov foreColorName_( foreColorName ),
50bb02e0acSNicolas Bonnefon backColorName_( backColorName ), enabled_( true )
51bb02e0acSNicolas Bonnefon {
52bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "New Filter, fore: " << foreColorName_.toStdString()
53bb02e0acSNicolas Bonnefon << " back: " << backColorName_.toStdString();
54bb02e0acSNicolas Bonnefon }
55bb02e0acSNicolas Bonnefon
pattern() const56bb02e0acSNicolas Bonnefon QString Filter::pattern() const
57bb02e0acSNicolas Bonnefon {
58bb02e0acSNicolas Bonnefon return regexp_.pattern();
59bb02e0acSNicolas Bonnefon }
60bb02e0acSNicolas Bonnefon
setPattern(const QString & pattern)61bb02e0acSNicolas Bonnefon void Filter::setPattern( const QString& pattern )
62bb02e0acSNicolas Bonnefon {
63bb02e0acSNicolas Bonnefon regexp_.setPattern( pattern );
64bb02e0acSNicolas Bonnefon }
65bb02e0acSNicolas Bonnefon
ignoreCase() const66b9c9a815SAnton Filimonov bool Filter::ignoreCase() const
67b9c9a815SAnton Filimonov {
68*4fb0346eSAnton Filimonov return regexp_.patternOptions().testFlag(QRegularExpression::CaseInsensitiveOption);
69b9c9a815SAnton Filimonov }
70b9c9a815SAnton Filimonov
setIgnoreCase(bool ignoreCase)71b9c9a815SAnton Filimonov void Filter::setIgnoreCase( bool ignoreCase )
72b9c9a815SAnton Filimonov {
73*4fb0346eSAnton Filimonov regexp_.setPatternOptions( getPatternOptions( ignoreCase ) );
74b9c9a815SAnton Filimonov }
75b9c9a815SAnton Filimonov
foreColorName() const76bb02e0acSNicolas Bonnefon const QString& Filter::foreColorName() const
77bb02e0acSNicolas Bonnefon {
78bb02e0acSNicolas Bonnefon return foreColorName_;
79bb02e0acSNicolas Bonnefon }
80bb02e0acSNicolas Bonnefon
setForeColor(const QString & foreColorName)81bb02e0acSNicolas Bonnefon void Filter::setForeColor( const QString& foreColorName )
82bb02e0acSNicolas Bonnefon {
83bb02e0acSNicolas Bonnefon foreColorName_ = foreColorName;
84bb02e0acSNicolas Bonnefon }
85bb02e0acSNicolas Bonnefon
backColorName() const86bb02e0acSNicolas Bonnefon const QString& Filter::backColorName() const
87bb02e0acSNicolas Bonnefon {
88bb02e0acSNicolas Bonnefon return backColorName_;
89bb02e0acSNicolas Bonnefon }
90bb02e0acSNicolas Bonnefon
setBackColor(const QString & backColorName)91bb02e0acSNicolas Bonnefon void Filter::setBackColor( const QString& backColorName )
92bb02e0acSNicolas Bonnefon {
93bb02e0acSNicolas Bonnefon backColorName_ = backColorName;
94bb02e0acSNicolas Bonnefon }
95bb02e0acSNicolas Bonnefon
hasMatch(const QString & string) const96*4fb0346eSAnton Filimonov bool Filter::hasMatch( const QString& string ) const
97bb02e0acSNicolas Bonnefon {
98*4fb0346eSAnton Filimonov return regexp_.match( string ).hasMatch();
99bb02e0acSNicolas Bonnefon }
100bb02e0acSNicolas Bonnefon
101bb02e0acSNicolas Bonnefon //
102bb02e0acSNicolas Bonnefon // Operators for serialization
103bb02e0acSNicolas Bonnefon //
104bb02e0acSNicolas Bonnefon
operator <<(QDataStream & out,const Filter & object)105bb02e0acSNicolas Bonnefon QDataStream& operator<<( QDataStream& out, const Filter& object )
106bb02e0acSNicolas Bonnefon {
107bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "<<operator from Filter";
108bb02e0acSNicolas Bonnefon out << object.regexp_;
109bb02e0acSNicolas Bonnefon out << object.foreColorName_;
110bb02e0acSNicolas Bonnefon out << object.backColorName_;
111bb02e0acSNicolas Bonnefon
112bb02e0acSNicolas Bonnefon return out;
113bb02e0acSNicolas Bonnefon }
114bb02e0acSNicolas Bonnefon
operator >>(QDataStream & in,Filter & object)115bb02e0acSNicolas Bonnefon QDataStream& operator>>( QDataStream& in, Filter& object )
116bb02e0acSNicolas Bonnefon {
117bb02e0acSNicolas Bonnefon LOG(logDEBUG) << ">>operator from Filter";
118bb02e0acSNicolas Bonnefon in >> object.regexp_;
119bb02e0acSNicolas Bonnefon in >> object.foreColorName_;
120bb02e0acSNicolas Bonnefon in >> object.backColorName_;
121bb02e0acSNicolas Bonnefon
122bb02e0acSNicolas Bonnefon return in;
123bb02e0acSNicolas Bonnefon }
124bb02e0acSNicolas Bonnefon
125bb02e0acSNicolas Bonnefon
126bb02e0acSNicolas Bonnefon // Default constructor
FilterSet()127bb02e0acSNicolas Bonnefon FilterSet::FilterSet()
128bb02e0acSNicolas Bonnefon {
129bb02e0acSNicolas Bonnefon qRegisterMetaTypeStreamOperators<Filter>( "Filter" );
130bb02e0acSNicolas Bonnefon qRegisterMetaTypeStreamOperators<FilterSet>( "FilterSet" );
131bb02e0acSNicolas Bonnefon qRegisterMetaTypeStreamOperators<FilterSet::FilterList>( "FilterSet::FilterList" );
132bb02e0acSNicolas Bonnefon }
133bb02e0acSNicolas Bonnefon
matchLine(const QString & line,QColor * foreColor,QColor * backColor) const134bb02e0acSNicolas Bonnefon bool FilterSet::matchLine( const QString& line,
135bb02e0acSNicolas Bonnefon QColor* foreColor, QColor* backColor ) const
136bb02e0acSNicolas Bonnefon {
137bb02e0acSNicolas Bonnefon for ( QList<Filter>::const_iterator i = filterList.constBegin();
138bb02e0acSNicolas Bonnefon i != filterList.constEnd(); i++ ) {
139*4fb0346eSAnton Filimonov if ( i->hasMatch( line ) ) {
140bb02e0acSNicolas Bonnefon foreColor->setNamedColor( i->foreColorName() );
141bb02e0acSNicolas Bonnefon backColor->setNamedColor( i->backColorName() );
142bb02e0acSNicolas Bonnefon return true;
143bb02e0acSNicolas Bonnefon }
144bb02e0acSNicolas Bonnefon }
145bb02e0acSNicolas Bonnefon
146bb02e0acSNicolas Bonnefon return false;
147bb02e0acSNicolas Bonnefon }
148bb02e0acSNicolas Bonnefon
149bb02e0acSNicolas Bonnefon //
150bb02e0acSNicolas Bonnefon // Operators for serialization
151bb02e0acSNicolas Bonnefon //
152bb02e0acSNicolas Bonnefon
operator <<(QDataStream & out,const FilterSet & object)153bb02e0acSNicolas Bonnefon QDataStream& operator<<( QDataStream& out, const FilterSet& object )
154bb02e0acSNicolas Bonnefon {
155bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "<<operator from FilterSet";
156bb02e0acSNicolas Bonnefon out << object.filterList;
157bb02e0acSNicolas Bonnefon
158bb02e0acSNicolas Bonnefon return out;
159bb02e0acSNicolas Bonnefon }
160bb02e0acSNicolas Bonnefon
operator >>(QDataStream & in,FilterSet & object)161bb02e0acSNicolas Bonnefon QDataStream& operator>>( QDataStream& in, FilterSet& object )
162bb02e0acSNicolas Bonnefon {
163bb02e0acSNicolas Bonnefon LOG(logDEBUG) << ">>operator from FilterSet";
164bb02e0acSNicolas Bonnefon in >> object.filterList;
165bb02e0acSNicolas Bonnefon
166bb02e0acSNicolas Bonnefon return in;
167bb02e0acSNicolas Bonnefon }
168bb02e0acSNicolas Bonnefon
169bb02e0acSNicolas Bonnefon //
170bb02e0acSNicolas Bonnefon // Persistable virtual functions implementation
171bb02e0acSNicolas Bonnefon //
172bb02e0acSNicolas Bonnefon
saveToStorage(QSettings & settings) const173bb02e0acSNicolas Bonnefon void Filter::saveToStorage( QSettings& settings ) const
174bb02e0acSNicolas Bonnefon {
175bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "Filter::saveToStorage";
176bb02e0acSNicolas Bonnefon
177bb02e0acSNicolas Bonnefon settings.setValue( "regexp", regexp_.pattern() );
178*4fb0346eSAnton Filimonov settings.setValue( "ignore_case", regexp_.patternOptions().testFlag( QRegularExpression::CaseInsensitiveOption ) );
179bb02e0acSNicolas Bonnefon settings.setValue( "fore_colour", foreColorName_ );
180bb02e0acSNicolas Bonnefon settings.setValue( "back_colour", backColorName_ );
181bb02e0acSNicolas Bonnefon }
182bb02e0acSNicolas Bonnefon
retrieveFromStorage(QSettings & settings)183bb02e0acSNicolas Bonnefon void Filter::retrieveFromStorage( QSettings& settings )
184bb02e0acSNicolas Bonnefon {
185bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "Filter::retrieveFromStorage";
186bb02e0acSNicolas Bonnefon
187*4fb0346eSAnton Filimonov regexp_ = QRegularExpression( settings.value( "regexp" ).toString(),
188*4fb0346eSAnton Filimonov getPatternOptions( settings.value( "ignore_case", false ).toBool() ) );
189bb02e0acSNicolas Bonnefon foreColorName_ = settings.value( "fore_colour" ).toString();
190bb02e0acSNicolas Bonnefon backColorName_ = settings.value( "back_colour" ).toString();
191bb02e0acSNicolas Bonnefon }
192bb02e0acSNicolas Bonnefon
saveToStorage(QSettings & settings) const193bb02e0acSNicolas Bonnefon void FilterSet::saveToStorage( QSettings& settings ) const
194bb02e0acSNicolas Bonnefon {
195bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "FilterSet::saveToStorage";
196bb02e0acSNicolas Bonnefon
197bb02e0acSNicolas Bonnefon settings.beginGroup( "FilterSet" );
198bb02e0acSNicolas Bonnefon // Remove everything in case the array is shorter than the previous one
199bb02e0acSNicolas Bonnefon settings.remove("");
200bb02e0acSNicolas Bonnefon settings.setValue( "version", FILTERSET_VERSION );
201bb02e0acSNicolas Bonnefon settings.beginWriteArray( "filters" );
202bb02e0acSNicolas Bonnefon for (int i = 0; i < filterList.size(); ++i) {
203bb02e0acSNicolas Bonnefon settings.setArrayIndex(i);
204bb02e0acSNicolas Bonnefon filterList[i].saveToStorage( settings );
205bb02e0acSNicolas Bonnefon }
206bb02e0acSNicolas Bonnefon settings.endArray();
207bb02e0acSNicolas Bonnefon settings.endGroup();
208bb02e0acSNicolas Bonnefon }
209bb02e0acSNicolas Bonnefon
retrieveFromStorage(QSettings & settings)210bb02e0acSNicolas Bonnefon void FilterSet::retrieveFromStorage( QSettings& settings )
211bb02e0acSNicolas Bonnefon {
212bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "FilterSet::retrieveFromStorage";
213bb02e0acSNicolas Bonnefon
214bb02e0acSNicolas Bonnefon filterList.clear();
215bb02e0acSNicolas Bonnefon
216bb02e0acSNicolas Bonnefon if ( settings.contains( "FilterSet/version" ) ) {
217bb02e0acSNicolas Bonnefon settings.beginGroup( "FilterSet" );
218bb02e0acSNicolas Bonnefon if ( settings.value( "version" ) == FILTERSET_VERSION ) {
219bb02e0acSNicolas Bonnefon int size = settings.beginReadArray( "filters" );
220bb02e0acSNicolas Bonnefon for (int i = 0; i < size; ++i) {
221bb02e0acSNicolas Bonnefon settings.setArrayIndex(i);
222bb02e0acSNicolas Bonnefon Filter filter;
223bb02e0acSNicolas Bonnefon filter.retrieveFromStorage( settings );
224bb02e0acSNicolas Bonnefon filterList.append( filter );
225bb02e0acSNicolas Bonnefon }
226bb02e0acSNicolas Bonnefon settings.endArray();
227bb02e0acSNicolas Bonnefon }
228bb02e0acSNicolas Bonnefon else {
229bb02e0acSNicolas Bonnefon LOG(logERROR) << "Unknown version of FilterSet, ignoring it...";
230bb02e0acSNicolas Bonnefon }
231bb02e0acSNicolas Bonnefon settings.endGroup();
232bb02e0acSNicolas Bonnefon }
233bb02e0acSNicolas Bonnefon else {
234bb02e0acSNicolas Bonnefon LOG(logWARNING) << "Trying to import legacy (<=0.8.2) filters...";
235bb02e0acSNicolas Bonnefon FilterSet tmp_filter_set =
236bb02e0acSNicolas Bonnefon settings.value( "filterSet" ).value<FilterSet>();
237bb02e0acSNicolas Bonnefon *this = tmp_filter_set;
238bb02e0acSNicolas Bonnefon LOG(logWARNING) << "...imported filterset: "
239bb02e0acSNicolas Bonnefon << filterList.count() << " elements";
240bb02e0acSNicolas Bonnefon // Remove the old key once migration is done
241bb02e0acSNicolas Bonnefon settings.remove( "filterSet" );
242bb02e0acSNicolas Bonnefon // And replace it with the new one
243bb02e0acSNicolas Bonnefon saveToStorage( settings );
244bb02e0acSNicolas Bonnefon settings.sync();
245bb02e0acSNicolas Bonnefon }
246bb02e0acSNicolas Bonnefon }
247