french -> French
[kdepim.git] / knode / knarticlefilter.cpp
blob438d8af03a9e71b807c5735d3c5c06c115c32647
1 /*
2 KNode, the KDE newsreader
3 Copyright (c) 1999-2006 the KNode authors.
4 See file AUTHORS for details
6 This program 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 2 of the License, or
9 (at your option) any later version.
10 You should have received a copy of the GNU General Public License
11 along with this program; if not, write to the Free Software Foundation,
12 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
15 #include <kstandarddirs.h>
16 #include <kconfig.h>
17 #include <kconfiggroup.h>
18 #include <klocale.h>
19 #include <kdebug.h>
21 #include "kngroup.h"
22 #include "knfolder.h"
23 #include "utilities.h"
24 #include "knarticlefilter.h"
26 //=============================================================================================================
29 // the names of our default filters
30 static const char *defFil[] = { "all","unread","new","watched","threads with unread",
31 "threads with new","own articles","threads with own articles", 0 };
32 void dummyFilter()
34 i18nc("default filter name","all");
35 i18nc("default filter name","unread");
36 i18nc("default filter name","new");
37 i18nc("default filter name","watched");
38 i18nc("default filter name","threads with unread");
39 i18nc("default filter name","threads with new");
40 i18nc("default filter name","own articles");
41 i18nc("default filter name","threads with own articles");
45 //=============================================================================================================
48 KNArticleFilter::KNArticleFilter(int id)
49 : i_d(id), c_ount(0), l_oaded(false), e_nabled(true), translateName(true), s_earchFilter(false), apon(articles)
54 // constructs a copy of org
55 KNArticleFilter::KNArticleFilter(const KNArticleFilter& org)
56 : i_d(-1), c_ount(0), l_oaded(false), e_nabled(org.e_nabled), translateName(true), s_earchFilter(org.s_earchFilter), apon(org.apon)
58 status = org.status;
59 score = org.score;
60 age = org.age;
61 lines = org.lines;
62 subject = org.subject;
63 from = org.from;
64 messageId = org.messageId;
65 references = org.messageId;
70 KNArticleFilter::~KNArticleFilter()
75 bool KNArticleFilter::loadInfo()
77 if (i_d!=-1) {
78 QString fname( KStandardDirs::locate( "data",
79 QString( "knode/filters/%1.fltr" ).arg( i_d ) ) );
81 if (fname.isNull())
82 return false;
83 KConfig conf( fname, KConfig::SimpleConfig);
85 KConfigGroup group = conf.group("GENERAL");
86 n_ame=group.readEntry("name");
87 translateName = group.readEntry("Translate_Name",true);
88 e_nabled=group.readEntry("enabled", true);
89 apon=(ApOn) group.readEntry("applyOn", 0);
90 return true;
92 return false;
97 void KNArticleFilter::load()
99 QString fname(KStandardDirs::locate( "data", QString( "knode/filters/%1.fltr" ).arg( i_d ) ) );
101 if (fname.isNull())
102 return;
103 KConfig conf( fname, KConfig::SimpleConfig);
105 KConfigGroup group = conf.group("STATUS");
106 status.load(group);
108 group = conf.group("SCORE");
109 score.load(group);
111 group = conf.group("AGE");
112 age.load(group);
114 group = conf.group("LINES");
115 lines.load(group);
117 group = conf.group("SUBJECT");
118 subject.load(group);
120 group = conf.group("FROM");
121 from.load(group);
123 group = conf.group("MESSAGEID");
124 messageId.load(group);
126 group = conf.group("REFERENCES");
127 references.load(group);
129 l_oaded=true;
131 kDebug(5003) <<"KNMessageFilter: filter loaded \"" << n_ame <<"\"";
137 void KNArticleFilter::save()
139 if (i_d==-1)
140 return;
141 QString dir( KStandardDirs::locateLocal( "data", "knode/filters/" ) );
142 if (dir.isNull()) {
143 KNHelper::displayInternalFileError();
144 return;
146 KConfig conf(dir+QString("%1.fltr").arg(i_d), KConfig::SimpleConfig);
148 KConfigGroup group = conf.group("GENERAL");
149 group.writeEntry("name", QString(n_ame));
150 group.writeEntry("Translate_Name",translateName);
151 group.writeEntry("enabled", e_nabled);
152 group.writeEntry("applyOn", (int) apon);
154 group = conf.group("STATUS");
155 status.save(group);
157 group = conf.group("SCORE");
158 score.save(group);
160 group = conf.group("AGE");
161 age.save(group);
163 group = conf.group("LINES");
164 lines.save(group);
166 group = conf.group("SUBJECT");
167 subject.save(group);
169 group = conf.group("FROM");
170 from.save(group);
172 group = conf.group("MESSAGEID");
173 messageId.save(group);
175 group = conf.group("REFERENCES");
176 references.save(group);
178 kDebug(5003) <<"KNMessageFilter: filter saved \"" << n_ame <<"\"";
183 void KNArticleFilter::doFilter( KNGroup::Ptr g )
185 c_ount=0;
186 KNRemoteArticle::Ptr art, ref;
187 KNRemoteArticle::List orphant_threads;
188 int idRef;
189 int mergeCnt=0;
190 bool inThread=false;
192 if(!l_oaded) load();
194 subject.expand( g.get() ); // replace placeholders
195 from.expand( g.get() );
196 messageId.expand( g.get() );
197 references.expand( g.get() );
199 for(int idx=0; idx<g->length(); idx++) {
200 art=g->at(idx);
201 art->setFiltered(false);
202 art->setVisibleFollowUps(false);
203 art->setDisplayedReference( KNRemoteArticle::Ptr() );
206 for(int idx=0; idx<g->length(); idx++) {
208 art=g->at(idx);
210 if(!art->isFiltered() && applyFilter(art) && apon==threads) {
211 idRef=art->idRef();
212 while(idRef!=0) {
213 ref=g->byId(idRef);
214 ref->setFilterResult(true);
215 ref->setFiltered(true);
216 if ( idRef==ref->idRef() ) break;
217 idRef=ref->idRef();
223 for(int idx=0; idx<g->length(); idx++) {
225 art=g->at(idx);
227 if( apon==threads && !art->filterResult() ) {
228 inThread=false;
229 idRef=art->idRef();
230 while(idRef!=0 && !inThread) {
231 ref=g->byId(idRef);
232 inThread=ref->filterResult();
233 idRef=ref->idRef();
235 art->setFilterResult(inThread);
238 if(art->filterResult()) {
239 c_ount++;
241 ref = ( art->idRef() > 0 ) ? g->byId( art->idRef() ) : KNRemoteArticle::Ptr();
242 while(ref && !ref->filterResult())
243 ref = ( ref->idRef() > 0 ) ? g->byId( ref->idRef() ) : KNRemoteArticle::Ptr();
245 art->setDisplayedReference(ref);
246 if(ref)
247 ref->setVisibleFollowUps(true);
248 else if(art->idRef()>0) {
249 orphant_threads.append(art);
255 if( orphant_threads.count() > 0 ) {
256 // try to merge orphant threads by subject
257 KNRemoteArticle::List same_subjects;
258 QString s;
259 for ( KNRemoteArticle::List::Iterator it = orphant_threads.begin(); it != orphant_threads.end(); ++it ) {
260 if ( (*it)->displayedReference() ) // already processed
261 continue;
263 s = (*it)->subject()->asUnicodeString();
264 same_subjects.clear();
265 for ( KNRemoteArticle::List::Iterator it2 = orphant_threads.begin(); it2 != orphant_threads.end(); ++it2 ) {
266 if ( (*it2) != (*it) && (*it2)->subject()->asUnicodeString() == s )
267 same_subjects.append( (*it2) );
270 (*it)->setVisibleFollowUps( (*it)->hasVisibleFollowUps() || same_subjects.count() > 0 );
271 for ( KNRemoteArticle::List::Iterator it2 = same_subjects.begin(); it2 != same_subjects.end(); ++it2 ) {
272 (*it2)->setDisplayedReference( (*it) );
273 mergeCnt++;
278 kDebug(5003) <<"KNArticleFilter::doFilter() : matched" << c_ount
279 << "articles , merged" << mergeCnt
280 << "threads by subject";
285 void KNArticleFilter::doFilter( KNFolder::Ptr f )
287 c_ount=0;
288 KNLocalArticle::Ptr art;
290 if(!l_oaded) load();
292 subject.expand(0); // replace placeholders
293 from.expand(0);
294 messageId.expand(0);
295 references.expand(0);
297 for(int idx=0; idx<f->length(); idx++) {
298 art=f->at(idx);
299 if (applyFilter(art))
300 c_ount++;
305 // *tries* to translate the name
306 QString KNArticleFilter::translatedName()
308 if (translateName) {
309 // major hack alert !!!
310 if (!n_ame.isEmpty()) {
311 if (i18nc("default filter name",n_ame.toLocal8Bit())!=n_ame.toLocal8Bit().data()) // try to guess if this english or not
312 return i18nc("default filter name",n_ame.toLocal8Bit());
313 else
314 return n_ame;
315 } else
316 return QString();
317 } else
318 return n_ame;
323 // *tries* to retranslate the name to english
324 void KNArticleFilter::setTranslatedName(const QString &s)
326 bool retranslated = false;
327 for (const char **c=defFil;(*c)!=0;c++) // ok, try if it matches any of the standard filter names
328 if (s==i18nc("default filter name",*c)) {
329 n_ame = QString::fromLatin1(*c);
330 retranslated = true;
331 break;
334 if (!retranslated) { // ok, we give up and store the maybe non-english string
335 n_ame = s;
336 translateName = false; // and don't try to translate it, so a german user *can* use the original english name
337 } else
338 translateName = true;
343 bool KNArticleFilter::applyFilter( KNRemoteArticle::Ptr a )
345 bool result=true;
347 if(result) result=status.doFilter(a);
348 if(result) result=score.doFilter(a->score());
349 if(result) result=lines.doFilter(a->lines()->numberOfLines());
350 if(result) result=age.doFilter(a->date()->ageInDays());
351 if(result) result=subject.doFilter(a->subject()->asUnicodeString());
352 if(result) {
353 QString tmp;
354 if ( !a->from()->isEmpty() )
355 tmp = a->from()->displayNames().first() + QLatin1String("##")
356 + QString::fromLatin1( a->from()->addresses().first() );
357 result=from.doFilter(tmp);
359 if(result) result=messageId.doFilter(a->messageID()->asUnicodeString());
360 if(result) result=references.doFilter(a->references()->asUnicodeString());
362 a->setFilterResult(result);
363 a->setFiltered(true);
365 return result;
369 bool KNArticleFilter::applyFilter( KNLocalArticle::Ptr a )
371 bool result=true;
373 if (isSearchFilter()) {
374 if(result) result=lines.doFilter(a->lines()->numberOfLines());
375 if(result) result=age.doFilter(a->date()->ageInDays());
376 if(result) result=subject.doFilter(a->subject()->asUnicodeString());
377 if(result) {
378 QString tmp;
379 if ( !a->from()->isEmpty() )
380 tmp = a->from()->displayNames().first() + QLatin1String("##")
381 + QString::fromLatin1( a->from()->addresses().first() );
382 result=from.doFilter(tmp);
384 if(result) result=messageId.doFilter(a->messageID()->asUnicodeString());
385 if(result) result=references.doFilter(a->references()->asUnicodeString());
388 a->setFilterResult(result);
390 return result;