• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

akregator

articlematcher.cpp

Go to the documentation of this file.
00001 /*
00002  * articlematcher.cpp
00003  *
00004  * Copyright (c) 2004, 2005 Frerich Raabe <raabe@kde.org>
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00018  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00019  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00020  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00021  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00022  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00023  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00025  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 #include "articlematcher.h"
00028 #include "article.h"
00029 #include "types.h"
00030 
00031 #include <kapplication.h>
00032 #include <kconfiggroup.h>
00033 #include <kdebug.h>
00034 #include <krandom.h>
00035 #include <kurl.h>
00036 
00037 #include <QList>
00038 #include <QRegExp>
00039 
00040 
00041 namespace Akregator {
00042 namespace Filters {
00043 
00044 AbstractMatcher::AbstractMatcher() {}
00045 
00046 AbstractMatcher::~AbstractMatcher() {}
00047 
00048 QString Criterion::subjectToString(Subject subj)
00049 {
00050     switch (subj)
00051     {
00052         case Title:
00053             return QString::fromLatin1("Title");
00054         case Link:
00055             return QString::fromLatin1("Link");
00056         case Description:
00057             return QString::fromLatin1("Description");
00058         case Status:
00059             return QString::fromLatin1("Status");
00060         case KeepFlag:
00061             return QString::fromLatin1("KeepFlag");
00062         default: // should never happen (TM)
00063             return QString::fromLatin1("Description");
00064     }
00065 }
00066 
00067 Criterion::Subject Criterion::stringToSubject(const QString& subjStr)
00068 {
00069     if (subjStr == QString::fromLatin1("Title"))
00070         return Title;
00071     else if (subjStr == QString::fromLatin1("Link"))
00072         return Link;
00073     else if (subjStr == QString::fromLatin1("Description"))
00074         return Description;
00075     else if (subjStr == QString::fromLatin1("Status"))
00076         return Status;
00077     else if (subjStr == QString::fromLatin1("KeepFlag"))
00078         return KeepFlag;
00079 
00080     // hopefully never reached
00081     return Description;
00082 }
00083 
00084 QString Criterion::predicateToString(Predicate pred)
00085 {
00086     switch (pred)
00087     {
00088         case Contains:
00089             return QString::fromLatin1("Contains");
00090         case Equals:
00091             return QString::fromLatin1("Equals");
00092         case Matches:
00093             return QString::fromLatin1("Matches");
00094         case Negation:
00095             return QString::fromLatin1("Negation");
00096         default:// hopefully never reached
00097             return QString::fromLatin1("Contains");
00098     }
00099 }
00100 
00101 Criterion::Predicate Criterion::stringToPredicate(const QString& predStr)
00102 {
00103     if (predStr == QString::fromLatin1("Contains"))
00104         return Contains;
00105     else if (predStr == QString::fromLatin1("Equals"))
00106         return Equals;
00107     else if (predStr == QString::fromLatin1("Matches"))
00108         return Matches;
00109     else if (predStr == QString::fromLatin1("Negation"))
00110         return Negation;
00111     
00112     // hopefully never reached
00113     return Contains;
00114 }
00115 
00116 Criterion::Criterion()
00117 {
00118 }
00119 
00120 Criterion::Criterion( Subject subject, Predicate predicate, const QVariant &object )
00121     : m_subject( subject )
00122     , m_predicate( predicate )
00123     , m_object( object )
00124 {
00125 
00126 }
00127 
00128 void Criterion::writeConfig(KConfigGroup* config) const
00129 {
00130     config->writeEntry(QString::fromLatin1("subject"), subjectToString(m_subject));
00131 
00132     config->writeEntry(QString::fromLatin1("predicate"), predicateToString(m_predicate));
00133 
00134     config->writeEntry(QString::fromLatin1("objectType"), QString(m_object.typeName()));
00135 
00136     config->writeEntry(QString::fromLatin1("objectValue"), m_object);
00137 }
00138 
00139 void Criterion::readConfig(KConfigGroup* config)
00140 {
00141     m_subject = stringToSubject(config->readEntry(QString::fromLatin1("subject"), QString()));
00142     m_predicate = stringToPredicate(config->readEntry(QString::fromLatin1("predicate"), QString()));
00143     QVariant::Type type = QVariant::nameToType(config->readEntry(QString::fromLatin1("objType"), QString()).toAscii());
00144 
00145     if (type != QVariant::Invalid)
00146     {
00147         m_object = config->readEntry(QString::fromLatin1("objectValue"), QVariant(type) );
00148     }
00149 }
00150 
00151 bool Criterion::satisfiedBy( const Article &article ) const
00152 {
00153     QVariant concreteSubject;
00154 
00155     switch ( m_subject ) {
00156         case Title:
00157             concreteSubject = QVariant(article.title());
00158             break;
00159         case Description:
00160             concreteSubject = QVariant(article.description());
00161             break;
00162         case Link:
00163             // ### Maybe use prettyUrl here?
00164             concreteSubject = QVariant(article.link().url());
00165             break;
00166         case Status:
00167             concreteSubject = QVariant(article.status());
00168             break;
00169         case KeepFlag:
00170             concreteSubject = QVariant(article.keep());   
00171         default:
00172             break;
00173     }
00174 
00175     bool satisfied = false;
00176 
00177     const Predicate predicateType = static_cast<Predicate>( m_predicate & ~Negation );
00178     QString subjectType=concreteSubject.typeName();
00179 
00180     switch ( predicateType ) {
00181         case Contains:
00182             satisfied = concreteSubject.toString().indexOf( m_object.toString(), 0, Qt::CaseInsensitive ) != -1;
00183             break;
00184         case Equals:
00185             if (subjectType=="int")
00186                 satisfied = concreteSubject.toInt() == m_object.toInt();
00187             else
00188                 satisfied = concreteSubject.toString() == m_object.toString();
00189             break;
00190         case Matches:
00191             satisfied = QRegExp( m_object.toString() ).indexIn( concreteSubject.toString() ) != -1;
00192             break;
00193         default:
00194             kDebug() <<"Internal inconsistency; predicateType should never be Negation";
00195             break;
00196     }
00197 
00198     if ( m_predicate & Negation ) {
00199         satisfied = !satisfied;
00200     }
00201 
00202     return satisfied;
00203 }
00204 
00205 Criterion::Subject Criterion::subject() const
00206 {
00207     return m_subject;
00208 }
00209 
00210 Criterion::Predicate Criterion::predicate() const
00211 {
00212     return m_predicate;
00213 }
00214 
00215 QVariant Criterion::object() const
00216 {
00217     return m_object;
00218 }
00219 
00220 ArticleMatcher::ArticleMatcher()
00221     : m_association( None )
00222 {
00223 }
00224 
00225 ArticleMatcher::~ArticleMatcher()
00226 {
00227 }
00228 
00229 ArticleMatcher::ArticleMatcher( const QList<Criterion> &criteria, Association assoc)
00230     : m_criteria( criteria )
00231     , m_association( assoc )
00232 {
00233 }
00234 
00235 bool ArticleMatcher::matches( const Article &a ) const
00236 {
00237     switch ( m_association ) {
00238         case LogicalOr:
00239             return anyCriterionMatches( a );
00240         case LogicalAnd:
00241             return allCriteriaMatch( a );
00242         default:
00243             break;
00244     }
00245     return true;
00246 }
00247 
00248 void ArticleMatcher::writeConfig(KConfigGroup* config) const
00249 {
00250     config->writeEntry(QString::fromLatin1("matcherAssociation"), associationToString(m_association));
00251     
00252     config->writeEntry(QString::fromLatin1("matcherCriteriaCount"), m_criteria.count());
00253 
00254     int index = 0;
00255 
00256     QString criterionGroupPrefix = config->name() + QString::fromLatin1("_Criterion");
00257 
00258     for (QList<Criterion>::ConstIterator it = m_criteria.begin(); it != m_criteria.end(); ++it)
00259     {
00260         config->changeGroup(criterionGroupPrefix + QString::number(index));
00261         (*it).writeConfig(config);
00262         ++index;
00263     }
00264 }
00265 
00266 void ArticleMatcher::readConfig(KConfigGroup* config)
00267 {
00268     m_criteria.clear();
00269     m_association = stringToAssociation(config->readEntry(QString::fromLatin1("matcherAssociation"), QString()));
00270 
00271     int count =  config->readEntry(QString::fromLatin1("matcherCriteriaCount"), 0);
00272 
00273     QString criterionGroupPrefix = config->name() + QString::fromLatin1("_Criterion");
00274 
00275     for (int i = 0; i < count; ++i)
00276     {
00277         Criterion c;
00278         config->changeGroup(criterionGroupPrefix + QString::number(i));
00279         c.readConfig(config);
00280         m_criteria.append(c);
00281     }
00282 }
00283 
00284 bool ArticleMatcher::operator==(const AbstractMatcher& other) const
00285 {
00286     AbstractMatcher* ptr = const_cast<AbstractMatcher*>(&other);
00287     ArticleMatcher* o = dynamic_cast<ArticleMatcher*>(ptr);
00288     if (!o)
00289         return false;
00290     else
00291         return m_association == o->m_association && m_criteria == o->m_criteria;
00292 }
00293 bool ArticleMatcher::operator!=(const AbstractMatcher& other) const
00294 {
00295     return !(*this == other);
00296 }
00297 
00298 bool ArticleMatcher::anyCriterionMatches( const Article &a ) const
00299 {
00300     if (m_criteria.count()==0)
00301         return true;
00302     QList<Criterion>::ConstIterator it = m_criteria.begin();
00303     QList<Criterion>::ConstIterator end = m_criteria.end();
00304     for ( ; it != end; ++it ) {
00305         if ( ( *it ).satisfiedBy( a ) ) {
00306             return true;
00307         }
00308     }
00309     return false;
00310 }
00311 
00312 bool ArticleMatcher::allCriteriaMatch( const Article &a ) const
00313 {
00314     if (m_criteria.count()==0)
00315         return true;
00316     QList<Criterion>::ConstIterator it = m_criteria.begin();
00317     QList<Criterion>::ConstIterator end = m_criteria.end();
00318     for ( ; it != end; ++it ) {
00319         if ( !( *it ).satisfiedBy( a ) ) {
00320             return false;
00321         }
00322     }
00323     return true;
00324 }
00325 
00326 ArticleMatcher::Association ArticleMatcher::stringToAssociation(const QString& assocStr)
00327 {
00328     if (assocStr == QString::fromLatin1("LogicalAnd"))
00329         return LogicalAnd;
00330     else if (assocStr == QString::fromLatin1("LogicalOr"))
00331         return LogicalOr;
00332     else
00333         return None;
00334 }
00335 
00336 QString ArticleMatcher::associationToString(Association association)
00337 {
00338     switch (association)
00339     {
00340         case LogicalAnd:
00341             return QString::fromLatin1("LogicalAnd");
00342         case LogicalOr:
00343             return QString::fromLatin1("LogicalOr");
00344         default:
00345             return QString::fromLatin1("None");
00346     }
00347 }
00348 
00349 
00350 } //namespace Filters
00351 } //namespace Akregator

akregator

Skip menu "akregator"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  •   doc
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal