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

akregator

articlemodel.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of Akregator.
00003 
00004     Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 #include "articlemodel.h"
00025 
00026 #include "article.h"
00027 #include "articlematcher.h"
00028 #include "akregatorconfig.h"
00029 #include "treenode.h"
00030 #include "feed.h"
00031 
00032 #include <syndication/tools.h>
00033 
00034 #include <QString>
00035 #include <QVector>
00036 
00037 #include <KLocale>
00038 #include <KGlobal>
00039 
00040 #include <cassert>
00041 #include <cmath>
00042 
00043 using namespace Akregator;
00044 
00045 class ArticleModel::Private {
00046 private:
00047     ArticleModel* const q;
00048 public:
00049     Private( TreeNode* node_, ArticleModel* qq );
00050     Akregator::TreeNode* node;
00051     QList<Akregator::Article> articles;
00052     QVector<QString> titleCache;
00053 
00054     void nodeDestroyed();
00055     void articlesAdded( TreeNode*, const QList<Article>& );
00056     void articlesRemoved( TreeNode*, const QList<Article>& );
00057     void articlesUpdated( TreeNode*, const QList<Article>& );
00058 
00059 };
00060 
00061 ArticleModel::Private::Private( TreeNode* node_, ArticleModel* qq )
00062  : q( qq ), node( node_ )
00063 {
00064     Q_ASSERT( node );
00065     articles = node->articles();
00066     titleCache.resize( articles.count() );
00067     for ( int i = 0; i < articles.count(); ++i )
00068         titleCache[i] = Syndication::htmlToPlainText( articles[i].title() );
00069     connect( node, SIGNAL( destroyed() ) , q, SLOT( nodeDestroyed() ) );
00070     connect( node, SIGNAL( signalArticlesAdded( Akregator::TreeNode*, QList<Akregator::Article> ) ),
00071                           q, SLOT( articlesAdded( Akregator::TreeNode*, QList<Akregator::Article> ) ) );
00072     connect( node, SIGNAL( signalArticlesRemoved( Akregator::TreeNode*, QList<Akregator::Article> ) ),
00073                            q, SLOT( articlesRemoved( Akregator::TreeNode*, QList<Akregator::Article> ) ) );
00074     connect( node, SIGNAL( signalArticlesUpdated( Akregator::TreeNode*, QList<Akregator::Article> ) ),
00075                            q, SLOT( articlesUpdated( Akregator::TreeNode*, QList<Akregator::Article> ) ) );
00076 
00077 }
00078 
00079 Akregator::ArticleModel::ArticleModel(TreeNode* node, QObject* parent) : QAbstractTableModel( parent ), d( new Private( node, this ) )
00080 {
00081 }
00082 
00083 Akregator::ArticleModel::~ArticleModel()
00084 {
00085     delete d;
00086 }
00087 
00088 int Akregator::ArticleModel::columnCount( const QModelIndex& parent ) const
00089 {
00090     return parent.isValid() ? 0 : ColumnCount;
00091 }
00092 
00093 int Akregator::ArticleModel::rowCount( const QModelIndex& parent ) const
00094 {
00095     return parent.isValid() ? 0 : d->articles.count();
00096 }
00097 
00098 QVariant Akregator::ArticleModel::headerData( int section, Qt::Orientation, int role ) const
00099 {
00100     if ( role != Qt::DisplayRole )
00101         return QVariant();
00102 
00103     switch (section)
00104     {
00105         case ItemTitleColumn:
00106             return i18n("Title");
00107         case FeedTitleColumn:
00108             return i18n("Feed");
00109         case DateColumn:
00110             return i18n("Date");
00111         case AuthorColumn:
00112             return i18n("Author");
00113         case DescriptionColumn:
00114             return i18n("Description");
00115         case ContentColumn:
00116             return i18n("Content");
00117     }
00118 
00119     return QVariant();
00120 }
00121 
00122 QVariant Akregator::ArticleModel::data( const QModelIndex& index, int role ) const
00123 {
00124     if ( !index.isValid() || index.row() < 0 || index.row() >= d->articles.count() )
00125         return QVariant();
00126     const int row = index.row();
00127     const Akregator::Article& article( d->articles[row] );
00128 
00129     if ( article.isNull() )
00130         return QVariant();
00131 
00132     switch ( role )
00133     {
00134         case SortRole:
00135             if ( index.column() == DateColumn )
00136                 return article.pubDate();
00137             // no break
00138         case Qt::DisplayRole:
00139         {
00140             switch ( index.column() )
00141             {
00142                 case FeedTitleColumn:
00143                     return article.feed() ? article.feed()->title() : QVariant();
00144                 case DateColumn:
00145                     return KGlobal::locale()->formatDateTime(article.pubDate(),
00146                                                              KLocale::FancyShortDate );
00147                 case ItemTitleColumn:
00148                     return d->titleCache[row];
00149                 case AuthorColumn:
00150                     return article.authorShort();
00151                 case DescriptionColumn:
00152                 case ContentColumn:
00153                     return article.description();
00154             }
00155         }
00156         case LinkRole:
00157         {
00158             return article.link();
00159         }
00160         case ItemIdRole:
00161         case GuidRole:
00162         {
00163             return article.guid();
00164         }
00165         case FeedIdRole:
00166         {
00167             return article.feed() ? article.feed()->xmlUrl() : QVariant();
00168         }
00169         case StatusRole:
00170         {
00171             return article.status();
00172         }
00173         case IsImportantRole:
00174         {
00175             return article.keep();
00176         }
00177         case IsDeletedRole:
00178         {
00179             return article.isDeleted();
00180         }
00181     }
00182 
00183     return QVariant();
00184 }
00185 
00186 void Akregator::ArticleModel::Private::nodeDestroyed()
00187 {
00188     node = 0;
00189     articles.clear();
00190     q->reset();
00191 }
00192 
00193 void ArticleModel::Private::articlesAdded( TreeNode* node, const QList<Article>& list )
00194 {
00195     Q_UNUSED( node );
00196     if ( list.isEmpty() ) //assert?
00197         return;
00198     const int first = static_cast<int>( articles.count() );
00199     q->beginInsertRows( QModelIndex(), first, first + list.size() - 1 );
00200 
00201     const int oldSize = articles.size();
00202     articles << list;
00203     titleCache.resize( articles.count() );
00204     for ( int i = oldSize; i < articles.count(); ++i )
00205         titleCache[i] = Syndication::htmlToPlainText( articles[i].title() );
00206     q->endInsertRows();
00207 }
00208 
00209 void ArticleModel::Private::articlesRemoved( TreeNode* node, const QList<Article>& list )
00210 {
00211     Q_UNUSED( node );
00212     //might want to avoid indexOf() in case of performance problems
00213     Q_FOREACH ( const Article& i, list )
00214     {
00215         const int row = articles.indexOf( i );
00216         assert( row != -1 );
00217         q->removeRow( row, QModelIndex() );
00218     }
00219 }
00220 
00221 
00222 void ArticleModel::Private::articlesUpdated( TreeNode* node, const QList<Article>& list )
00223 {
00224     Q_UNUSED( node );
00225     int rmin = 0;
00226     int rmax = 0;
00227 
00228     if ( articles.count() > 0 )
00229     {
00230          rmin = articles.count() - 1;
00231         //might want to avoid indexOf() in case of performance problems
00232         Q_FOREACH ( const Article& i, list )
00233         {
00234             const int row = articles.indexOf( i );
00235             //TODO: figure out how why the Article might not be found in
00236             //TODO: the articles list because we should need this conditional.
00237             if ( row >= 0 )
00238             {
00239                 titleCache[row] = Syndication::htmlToPlainText( articles[row].title() );
00240                 rmin = std::min( row, rmin );
00241                 rmax = std::max( row, rmax );
00242             }
00243         }
00244     }
00245     emit q->dataChanged( q->index( rmin, 0 ), q->index( rmax, ColumnCount-1 ) );
00246 }
00247 
00248 
00249 bool ArticleModel::rowMatches( int row, const boost::shared_ptr<const Akregator::Filters::AbstractMatcher>& matcher ) const
00250 {
00251     assert( matcher );
00252     return matcher->matches( article( row ) );
00253 }
00254 
00255 Article ArticleModel::article( int row ) const
00256 {
00257     if ( row < 0 || row >= d->articles.count() )
00258         return Article();
00259     return d->articles[row];
00260 }
00261 
00262 #include "articlemodel.moc"

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
  • 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