/* * articlefilter.h * * Copyright (c) 2004, 2005 Frerich Raabe * 2005 Frank Osterfeld * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ARTICLEFILTER_H #define ARTICLEFILTER_H #include #include #include class TDEConfig; namespace Akregator { class Article; namespace Filters { class AbstractAction; class AbstractMatcher; class Criterion; /** an article filter, basically a matcher and an action. * @author Frank Osterfeld */ class ArticleFilter { public: ArticleFilter(); ArticleFilter(const AbstractMatcher& matcher, const AbstractAction& action); ArticleFilter(const ArticleFilter& other); virtual ~ArticleFilter(); /** checks whether an article matches the matcher, and executes the action if so */ void applyTo(Article& article) const; /** name of the filter, for display in filter list */ const TQString& name() const; void setName(const TQString& name); int id() const; AbstractMatcher* matcher() const; void setMatcher(const AbstractMatcher& matcher); AbstractAction* action() const; void setAction(const AbstractAction& action); ArticleFilter& operator=(const ArticleFilter& other); bool operator==(const ArticleFilter& other) const; void writeConfig(TDEConfig* config) const; void readConfig(TDEConfig* config); private: class ArticleFilterPrivate; ArticleFilterPrivate* d; }; class ArticleFilterList : public TQValueList { public: void writeConfig(TDEConfig* config) const; void readConfig(TDEConfig* config); }; /** Abstract base class for matchers, a matcher just takes an article and checks whether the article matches some criterion or not. * @author Frank Osterfeld */ class AbstractMatcher { public: virtual ~AbstractMatcher() {} /** returns a copy of the matcher */ virtual AbstractMatcher* clone() const = 0; virtual bool matches(const Article& article) const = 0; virtual void writeConfig(TDEConfig* config) const = 0; virtual void readConfig(TDEConfig* config) = 0; virtual bool operator==(const AbstractMatcher&) const = 0; virtual bool operator!=(const AbstractMatcher &other) const = 0; }; class TagMatcher : public AbstractMatcher { public: TagMatcher(); TagMatcher(const TQString& tagID); TagMatcher(const TagMatcher& other); virtual ~TagMatcher(); virtual bool matches(const Article& article) const; virtual TagMatcher* clone() const; virtual void writeConfig(TDEConfig* config) const; virtual void readConfig(TDEConfig* config); TagMatcher& operator=(const TagMatcher& other); virtual bool operator==(const AbstractMatcher&) const; virtual bool operator!=(const AbstractMatcher &other) const; private: class TagMatcherPrivate; TagMatcherPrivate* d; }; class AbstractAction { public: virtual void exec(Article& article) = 0; virtual void writeConfig(TDEConfig* config) const = 0; virtual void readConfig(TDEConfig* config) = 0; virtual AbstractAction* clone() const = 0; virtual bool operator==(const AbstractAction& other) = 0; }; class DeleteAction : public AbstractAction { public: virtual void exec(Article& article); virtual void writeConfig(TDEConfig* config) const; virtual void readConfig(TDEConfig* config); virtual DeleteAction* clone() const { return new DeleteAction; } virtual bool operator==(const AbstractAction& other); }; class SetStatusAction : public AbstractAction { public: SetStatusAction(int status=0); virtual void exec(Article& article); int status() const; void setStatus(int status); virtual void writeConfig(TDEConfig* config) const; virtual void readConfig(TDEConfig* config); virtual SetStatusAction* clone() const { return new SetStatusAction(*this); } virtual bool operator==(const AbstractAction& other); private: int m_status; }; class AssignTagAction : public AbstractAction { public: AssignTagAction(const TQString& tagID=TQString()); virtual void exec(Article& article); const TQString& tagID() const; void setTagID(const TQString& tagID); virtual void writeConfig(TDEConfig* config) const; virtual void readConfig(TDEConfig* config); virtual AssignTagAction* clone() const { return new AssignTagAction(*this); } virtual bool operator==(const AbstractAction& other); private: TQString m_tagID; }; /** a powerful matcher supporting multiple criterions, which can be combined via logical OR or AND * @author Frerich Raabe */ class ArticleMatcher : public AbstractMatcher { public: enum Association { None, LogicalAnd, LogicalOr }; ArticleMatcher(); ArticleMatcher( const TQValueList &criteria, Association assoc); ArticleMatcher(const ArticleMatcher& other); virtual ~ArticleMatcher(); /** * returns whether the matcher matches all articles anyway (empty criteria list), * so there is no need to call matches() at all. */ virtual bool matchesAll() const; ArticleMatcher& operator=(const ArticleMatcher& other); virtual ArticleMatcher* clone() const; virtual bool matches(const Article &article) const; virtual bool operator==(const AbstractMatcher &other) const; virtual bool operator!=(const AbstractMatcher &other) const; virtual void writeConfig(TDEConfig* config) const; virtual void readConfig(TDEConfig* config); private: static Association stringToAssociation(const TQString& assocStr); static TQString associationToString(Association association); bool anyCriterionMatches( const Article &a ) const; bool allCriteriaMatch( const Article &a ) const; TQValueList m_criteria; Association m_association; }; /** Criterion for ArticleMatcher * @author Frerich Raabe */ class Criterion { public: enum Subject { Title, Description, Author, Link, Status, KeepFlag }; static TQString subjectToString(Subject subj); static Subject stringToSubject(const TQString& subjStr); enum Predicate { Contains = 0x01, Equals = 0x02, Matches = 0x03, Negation = 0x80 }; static TQString predicateToString(Predicate pred); static Predicate stringToPredicate(const TQString& predStr); Criterion(); Criterion( Subject subject, Predicate predicate, const TQVariant &object ); bool satisfiedBy( const Article &article ) const; virtual void writeConfig(TDEConfig* config) const; virtual void readConfig(TDEConfig* config); Subject subject() const; Predicate predicate() const; TQVariant object() const; bool operator==(const Criterion& other) const { return m_subject == other.m_subject && m_predicate == other.m_predicate && m_object == other.m_object; } private: Subject m_subject; Predicate m_predicate; TQVariant m_object; }; } // namespace Filters } // namespace Akregator #endif