diff options
Diffstat (limited to 'knode/knarticlefilter.cpp')
-rw-r--r-- | knode/knarticlefilter.cpp | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/knode/knarticlefilter.cpp b/knode/knarticlefilter.cpp new file mode 100644 index 000000000..b5a49d55b --- /dev/null +++ b/knode/knarticlefilter.cpp @@ -0,0 +1,383 @@ +/* + KNode, the KDE newsreader + Copyright (c) 1999-2005 the KNode authors. + See file AUTHORS for details + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US +*/ + +#include <kstandarddirs.h> +#include <ksimpleconfig.h> +#include <klocale.h> +#include <kdebug.h> + +#include "kngroup.h" +#include "knfolder.h" +#include "utilities.h" +#include "knarticlefilter.h" + +//============================================================================================================= + + +// the names of our default filters +static const char *defFil[] = { "all","unread","new","watched","threads with unread", + "threads with new","own articles","threads with own articles", 0 }; +void dummyFilter() +{ + i18n("default filter name","all"); + i18n("default filter name","unread"); + i18n("default filter name","new"); + i18n("default filter name","watched"); + i18n("default filter name","threads with unread"); + i18n("default filter name","threads with new"); + i18n("default filter name","own articles"); + i18n("default filter name","threads with own articles"); +} + + +//============================================================================================================= + + +KNArticleFilter::KNArticleFilter(int id) +: i_d(id), c_ount(0), l_oaded(false), e_nabled(true), translateName(true), s_earchFilter(false), apon(articles) +{} + + + +// constructs a copy of org +KNArticleFilter::KNArticleFilter(const KNArticleFilter& org) +: i_d(-1), c_ount(0), l_oaded(false), e_nabled(org.e_nabled), translateName(true), s_earchFilter(org.s_earchFilter), apon(org.apon) +{ + status = org.status; + score = org.score; + age = org.age; + lines = org.lines; + subject = org.subject; + from = org.from; + messageId = org.messageId; + references = org.messageId; +} + + + +KNArticleFilter::~KNArticleFilter() +{} + + + +bool KNArticleFilter::loadInfo() +{ + if (i_d!=-1) { + QString fname(locate("data",QString( "knode/filters/%1.fltr" ).arg(i_d) ) ); + + if (fname.isNull()) + return false; + KSimpleConfig conf(fname,true); + + conf.setGroup("GENERAL"); + n_ame=conf.readEntry("name"); + translateName = conf.readBoolEntry("Translate_Name",true); + e_nabled=conf.readBoolEntry("enabled", true); + apon=(ApOn) conf.readNumEntry("applyOn", 0); + return true; + } + return false; +} + + + +void KNArticleFilter::load() +{ + QString fname(locate("data",QString( "knode/filters/%1.fltr").arg(i_d) ) ); + + if (fname.isNull()) + return; + KSimpleConfig conf(fname,true); + + conf.setGroup("STATUS"); + status.load(&conf); + + conf.setGroup("SCORE"); + score.load(&conf); + + conf.setGroup("AGE"); + age.load(&conf); + + conf.setGroup("LINES"); + lines.load(&conf); + + conf.setGroup("SUBJECT"); + subject.load(&conf); + + conf.setGroup("FROM"); + from.load(&conf); + + conf.setGroup("MESSAGEID"); + messageId.load(&conf); + + conf.setGroup("REFERENCES"); + references.load(&conf); + + l_oaded=true; + + kdDebug(5003) << "KNMessageFilter: filter loaded \"" << n_ame << "\" " << endl; + +} + + + +void KNArticleFilter::save() +{ + if (i_d==-1) + return; + QString dir(locateLocal("data","knode/")+"filters/"); + if (dir.isNull()) { + KNHelper::displayInternalFileError(); + return; + } + KSimpleConfig conf(dir+QString("%1.fltr").arg(i_d)); + + conf.setGroup("GENERAL"); + conf.writeEntry("name", QString(n_ame)); + conf.writeEntry("Translate_Name",translateName); + conf.writeEntry("enabled", e_nabled); + conf.writeEntry("applyOn", (int) apon); + + conf.setGroup("STATUS"); + status.save(&conf); + + conf.setGroup("SCORE"); + score.save(&conf); + + conf.setGroup("AGE"); + age.save(&conf); + + conf.setGroup("LINES"); + lines.save(&conf); + + conf.setGroup("SUBJECT"); + subject.save(&conf); + + conf.setGroup("FROM"); + from.save(&conf); + + conf.setGroup("MESSAGEID"); + messageId.save(&conf); + + conf.setGroup("REFERENCES"); + references.save(&conf); + + kdDebug(5003) << "KNMessageFilter: filter saved \"" << n_ame << "\" " << endl; +} + + + +void KNArticleFilter::doFilter(KNGroup *g) +{ + c_ount=0; + KNRemoteArticle *art=0, *ref=0; + KNRemoteArticle::List orphant_threads; + int idRef; + int mergeCnt=0; + bool inThread=false; + + if(!l_oaded) load(); + + subject.expand(g); // replace placeholders + from.expand(g); + messageId.expand(g); + references.expand(g); + + for(int idx=0; idx<g->length(); idx++) { + art=g->at(idx); + art->setFiltered(false); + art->setVisibleFollowUps(false); + art->setDisplayedReference(0); + } + + for(int idx=0; idx<g->length(); idx++) { + + art=g->at(idx); + + if(!art->isFiltered() && applyFilter(art) && apon==threads) { + idRef=art->idRef(); + while(idRef!=0) { + ref=g->byId(idRef); + ref->setFilterResult(true); + ref->setFiltered(true); + if ( idRef==ref->idRef() ) break; + idRef=ref->idRef(); + } + } + + } + + for(int idx=0; idx<g->length(); idx++) { + + art=g->at(idx); + + if( apon==threads && !art->filterResult() ) { + inThread=false; + idRef=art->idRef(); + while(idRef!=0 && !inThread) { + ref=g->byId(idRef); + inThread=ref->filterResult(); + idRef=ref->idRef(); + } + art->setFilterResult(inThread); + } + + if(art->filterResult()) { + c_ount++; + + ref = (art->idRef()>0) ? g->byId(art->idRef()) : 0; + while(ref && !ref->filterResult()) + ref = (ref->idRef()>0) ? g->byId(ref->idRef()) : 0; + + art->setDisplayedReference(ref); + if(ref) + ref->setVisibleFollowUps(true); + else if(art->idRef()>0) { + orphant_threads.append(art); + } + } + + } + + if( orphant_threads.count() > 0 ) { + // try to merge orphant threads by subject + KNRemoteArticle::List same_subjects; + QString s; + for ( KNRemoteArticle::List::Iterator it = orphant_threads.begin(); it != orphant_threads.end(); ++it ) { + if ( (*it)->displayedReference() ) // already processed + continue; + + s = (*it)->subject()->asUnicodeString(); + same_subjects.clear(); + for ( KNRemoteArticle::List::Iterator it2 = orphant_threads.begin(); it2 != orphant_threads.end(); ++it2 ) { + if ( (*it2) != (*it) && (*it2)->subject()->asUnicodeString() == s ) + same_subjects.append( (*it2) ); + } + + (*it)->setVisibleFollowUps( (*it)->hasVisibleFollowUps() || same_subjects.count() > 0 ); + for ( KNRemoteArticle::List::Iterator it2 = same_subjects.begin(); it2 != same_subjects.end(); ++it2 ) { + (*it2)->setDisplayedReference( (*it) ); + mergeCnt++; + } + } + } + + kdDebug(5003) << "KNArticleFilter::doFilter() : matched " << c_ount + << " articles , merged " << mergeCnt + << " threads by subject" << endl; + +} + + +void KNArticleFilter::doFilter(KNFolder *f) +{ + c_ount=0; + KNLocalArticle *art=0; + + if(!l_oaded) load(); + + subject.expand(0); // replace placeholders + from.expand(0); + messageId.expand(0); + references.expand(0); + + for(int idx=0; idx<f->length(); idx++) { + art=f->at(idx); + if (applyFilter(art)) + c_ount++; + } +} + + +// *tries* to translate the name +QString KNArticleFilter::translatedName() +{ + if (translateName) { + // major hack alert !!! + if (!n_ame.isEmpty()) { + if (i18n("default filter name",n_ame.local8Bit())!=n_ame.local8Bit().data()) // try to guess if this english or not + return i18n("default filter name",n_ame.local8Bit()); + else + return n_ame; + } else + return QString::null; + } else + return n_ame; +} + + + +// *tries* to retranslate the name to english +void KNArticleFilter::setTranslatedName(const QString &s) +{ + bool retranslated = false; + for (const char **c=defFil;(*c)!=0;c++) // ok, try if it matches any of the standard filter names + if (s==i18n("default filter name",*c)) { + n_ame = QString::fromLatin1(*c); + retranslated = true; + break; + } + + if (!retranslated) { // ok, we give up and store the maybe non-english string + n_ame = s; + translateName = false; // and don't try to translate it, so a german user *can* use the original english name + } else + translateName = true; +} + + + +bool KNArticleFilter::applyFilter(KNRemoteArticle *a) +{ + bool result=true; + + if(result) result=status.doFilter(a); + if(result) result=score.doFilter(a->score()); + if(result) result=lines.doFilter(a->lines()->numberOfLines()); + if(result) result=age.doFilter(a->date()->ageInDays()); + if(result) result=subject.doFilter(a->subject()->asUnicodeString()); + if(result) { + QString tmp = (a->from()->name()+"##") + QString(a->from()->email().data()); + result=from.doFilter(tmp); + } + if(result) result=messageId.doFilter(a->messageID()->asUnicodeString()); + if(result) result=references.doFilter(a->references()->asUnicodeString()); + + a->setFilterResult(result); + a->setFiltered(true); + + return result; +} + + +bool KNArticleFilter::applyFilter(KNLocalArticle *a) +{ + bool result=true; + + if (isSearchFilter()) { + if(result) result=lines.doFilter(a->lines()->numberOfLines()); + if(result) result=age.doFilter(a->date()->ageInDays()); + if(result) result=subject.doFilter(a->subject()->asUnicodeString()); + if(result) { + QString tmp = (a->from()->name()+"##") + QString(a->from()->email().data()); + result=from.doFilter(tmp); + } + if(result) result=messageId.doFilter(a->messageID()->asUnicodeString()); + if(result) result=references.doFilter(a->references()->asUnicodeString()); + } + + a->setFilterResult(result); + + return result; +} |