You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/knode/knarticlefilter.cpp

384 lines
9.6 KiB

/*
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) {
TQString fname(locate("data",TQString( "knode/filters/%1.fltr" ).tqarg(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()
{
TQString fname(locate("data",TQString( "knode/filters/%1.fltr").tqarg(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;
TQString dir(locateLocal("data","knode/")+"filters/");
if (dir.isNull()) {
KNHelper::displayInternalFileError();
return;
}
KSimpleConfig conf(dir+TQString("%1.fltr").tqarg(i_d));
conf.setGroup("GENERAL");
conf.writeEntry("name", TQString(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;
TQString 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
TQString 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 TQString();
} else
return n_ame;
}
// *tries* to retranslate the name to english
void KNArticleFilter::setTranslatedName(const TQString &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 = TQString::tqfromLatin1(*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) {
TQString tmp = (a->from()->name()+"##") + TQString(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) {
TQString tmp = (a->from()->name()+"##") + TQString(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;
}