succesfuly ---> successfully
[kdepim.git] / knode / knarticlefilter.cpp
blob5a15bbbe57b0d476632326c5f210415ad5ba38e4
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",QString( "knode/filters/%1.fltr" ).arg(i_d) ) );
80 if (fname.isNull())
81 return false;
82 KConfig conf( fname, KConfig::SimpleConfig);
84 KConfigGroup group = conf.group("GENERAL");
85 n_ame=group.readEntry("name");
86 translateName = group.readEntry("Translate_Name",true);
87 e_nabled=group.readEntry("enabled", true);
88 apon=(ApOn) group.readEntry("applyOn", 0);
89 return true;
91 return false;
96 void KNArticleFilter::load()
98 QString fname(KStandardDirs::locate("data",QString( "knode/filters/%1.fltr").arg(i_d) ) );
100 if (fname.isNull())
101 return;
102 KConfig conf( fname, KConfig::SimpleConfig);
104 KConfigGroup group = conf.group("STATUS");
105 status.load(group);
107 group = conf.group("SCORE");
108 score.load(group);
110 group = conf.group("AGE");
111 age.load(group);
113 group = conf.group("LINES");
114 lines.load(group);
116 group = conf.group("SUBJECT");
117 subject.load(group);
119 group = conf.group("FROM");
120 from.load(group);
122 group = conf.group("MESSAGEID");
123 messageId.load(group);
125 group = conf.group("REFERENCES");
126 references.load(group);
128 l_oaded=true;
130 kDebug(5003) <<"KNMessageFilter: filter loaded \"" << n_ame <<"\"";
136 void KNArticleFilter::save()
138 if (i_d==-1)
139 return;
140 QString dir(KStandardDirs::locateLocal("data","knode/")+"filters/");
141 if (dir.isNull()) {
142 KNHelper::displayInternalFileError();
143 return;
145 KConfig conf(dir+QString("%1.fltr").arg(i_d), KConfig::SimpleConfig);
147 KConfigGroup group = conf.group("GENERAL");
148 group.writeEntry("name", QString(n_ame));
149 group.writeEntry("Translate_Name",translateName);
150 group.writeEntry("enabled", e_nabled);
151 group.writeEntry("applyOn", (int) apon);
153 group = conf.group("STATUS");
154 status.save(group);
156 group = conf.group("SCORE");
157 score.save(group);
159 group = conf.group("AGE");
160 age.save(group);
162 group = conf.group("LINES");
163 lines.save(group);
165 group = conf.group("SUBJECT");
166 subject.save(group);
168 group = conf.group("FROM");
169 from.save(group);
171 group = conf.group("MESSAGEID");
172 messageId.save(group);
174 group = conf.group("REFERENCES");
175 references.save(group);
177 kDebug(5003) <<"KNMessageFilter: filter saved \"" << n_ame <<"\"";
182 void KNArticleFilter::doFilter(KNGroup *g)
184 c_ount=0;
185 KNRemoteArticle *art=0, *ref=0;
186 KNRemoteArticle::List orphant_threads;
187 int idRef;
188 int mergeCnt=0;
189 bool inThread=false;
191 if(!l_oaded) load();
193 subject.expand(g); // replace placeholders
194 from.expand(g);
195 messageId.expand(g);
196 references.expand(g);
198 for(int idx=0; idx<g->length(); idx++) {
199 art=g->at(idx);
200 art->setFiltered(false);
201 art->setVisibleFollowUps(false);
202 art->setDisplayedReference(0);
205 for(int idx=0; idx<g->length(); idx++) {
207 art=g->at(idx);
209 if(!art->isFiltered() && applyFilter(art) && apon==threads) {
210 idRef=art->idRef();
211 while(idRef!=0) {
212 ref=g->byId(idRef);
213 ref->setFilterResult(true);
214 ref->setFiltered(true);
215 if ( idRef==ref->idRef() ) break;
216 idRef=ref->idRef();
222 for(int idx=0; idx<g->length(); idx++) {
224 art=g->at(idx);
226 if( apon==threads && !art->filterResult() ) {
227 inThread=false;
228 idRef=art->idRef();
229 while(idRef!=0 && !inThread) {
230 ref=g->byId(idRef);
231 inThread=ref->filterResult();
232 idRef=ref->idRef();
234 art->setFilterResult(inThread);
237 if(art->filterResult()) {
238 c_ount++;
240 ref = (art->idRef()>0) ? g->byId(art->idRef()) : 0;
241 while(ref && !ref->filterResult())
242 ref = (ref->idRef()>0) ? g->byId(ref->idRef()) : 0;
244 art->setDisplayedReference(ref);
245 if(ref)
246 ref->setVisibleFollowUps(true);
247 else if(art->idRef()>0) {
248 orphant_threads.append(art);
254 if( orphant_threads.count() > 0 ) {
255 // try to merge orphant threads by subject
256 KNRemoteArticle::List same_subjects;
257 QString s;
258 for ( KNRemoteArticle::List::Iterator it = orphant_threads.begin(); it != orphant_threads.end(); ++it ) {
259 if ( (*it)->displayedReference() ) // already processed
260 continue;
262 s = (*it)->subject()->asUnicodeString();
263 same_subjects.clear();
264 for ( KNRemoteArticle::List::Iterator it2 = orphant_threads.begin(); it2 != orphant_threads.end(); ++it2 ) {
265 if ( (*it2) != (*it) && (*it2)->subject()->asUnicodeString() == s )
266 same_subjects.append( (*it2) );
269 (*it)->setVisibleFollowUps( (*it)->hasVisibleFollowUps() || same_subjects.count() > 0 );
270 for ( KNRemoteArticle::List::Iterator it2 = same_subjects.begin(); it2 != same_subjects.end(); ++it2 ) {
271 (*it2)->setDisplayedReference( (*it) );
272 mergeCnt++;
277 kDebug(5003) <<"KNArticleFilter::doFilter() : matched" << c_ount
278 << "articles , merged" << mergeCnt
279 << "threads by subject";
284 void KNArticleFilter::doFilter(KNFolder *f)
286 c_ount=0;
287 KNLocalArticle *art=0;
289 if(!l_oaded) load();
291 subject.expand(0); // replace placeholders
292 from.expand(0);
293 messageId.expand(0);
294 references.expand(0);
296 for(int idx=0; idx<f->length(); idx++) {
297 art=f->at(idx);
298 if (applyFilter(art))
299 c_ount++;
304 // *tries* to translate the name
305 QString KNArticleFilter::translatedName()
307 if (translateName) {
308 // major hack alert !!!
309 if (!n_ame.isEmpty()) {
310 if (i18nc("default filter name",n_ame.toLocal8Bit())!=n_ame.toLocal8Bit().data()) // try to guess if this english or not
311 return i18nc("default filter name",n_ame.toLocal8Bit());
312 else
313 return n_ame;
314 } else
315 return QString();
316 } else
317 return n_ame;
322 // *tries* to retranslate the name to english
323 void KNArticleFilter::setTranslatedName(const QString &s)
325 bool retranslated = false;
326 for (const char **c=defFil;(*c)!=0;c++) // ok, try if it matches any of the standard filter names
327 if (s==i18nc("default filter name",*c)) {
328 n_ame = QString::fromLatin1(*c);
329 retranslated = true;
330 break;
333 if (!retranslated) { // ok, we give up and store the maybe non-english string
334 n_ame = s;
335 translateName = false; // and don't try to translate it, so a german user *can* use the original english name
336 } else
337 translateName = true;
342 bool KNArticleFilter::applyFilter(KNRemoteArticle *a)
344 bool result=true;
346 if(result) result=status.doFilter(a);
347 if(result) result=score.doFilter(a->score());
348 if(result) result=lines.doFilter(a->lines()->numberOfLines());
349 if(result) result=age.doFilter(a->date()->ageInDays());
350 if(result) result=subject.doFilter(a->subject()->asUnicodeString());
351 if(result) {
352 QString tmp;
353 if ( !a->from()->isEmpty() )
354 tmp = a->from()->displayNames().first() + QLatin1String("##")
355 + QString::fromLatin1( a->from()->addresses().first() );
356 result=from.doFilter(tmp);
358 if(result) result=messageId.doFilter(a->messageID()->asUnicodeString());
359 if(result) result=references.doFilter(a->references()->asUnicodeString());
361 a->setFilterResult(result);
362 a->setFiltered(true);
364 return result;
368 bool KNArticleFilter::applyFilter(KNLocalArticle *a)
370 bool result=true;
372 if (isSearchFilter()) {
373 if(result) result=lines.doFilter(a->lines()->numberOfLines());
374 if(result) result=age.doFilter(a->date()->ageInDays());
375 if(result) result=subject.doFilter(a->subject()->asUnicodeString());
376 if(result) {
377 QString tmp;
378 if ( !a->from()->isEmpty() )
379 tmp = a->from()->displayNames().first() + QLatin1String("##")
380 + QString::fromLatin1( a->from()->addresses().first() );
381 result=from.doFilter(tmp);
383 if(result) result=messageId.doFilter(a->messageID()->asUnicodeString());
384 if(result) result=references.doFilter(a->references()->asUnicodeString());
387 a->setFilterResult(result);
389 return result;