kontact Library API Documentation

newsticker/summarywidget.cpp

00001 /*
00002     This file is part of Kontact.
00003     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
00022 */
00023 
00024 #include <qeventloop.h>
00025 #include <qhbox.h>
00026 #include <qlayout.h>
00027 #include <qpixmap.h>
00028 
00029 #include <dcopclient.h>
00030 #include <kapplication.h>
00031 #include <kconfig.h>
00032 #include <kdebug.h>
00033 #include <kglobal.h>
00034 #include <kiconloader.h>
00035 #include <klocale.h>
00036 #include <kurllabel.h>
00037 #include <kcharsets.h>
00038 
00039 #include "summarywidget.h"
00040 
00041 SummaryWidget::SummaryWidget( QWidget *parent, const char *name )
00042   : Kontact::Summary( parent, name ),
00043     DCOPObject( "NewsTickerPlugin" ), mLayout( 0 )
00044 {
00045   QVBoxLayout *vlay = new QVBoxLayout( this );
00046 
00047   QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_news",
00048                                                   KIcon::Desktop, KIcon::SizeMedium );
00049 
00050   QWidget *header = createHeader( this, icon, i18n( "News Feeds" ) );
00051   vlay->addWidget( header );
00052 
00053   QString error;
00054   QCString appID;
00055 
00056   bool dcopAvailable = true;
00057   if ( !kapp->dcopClient()->isApplicationRegistered( "rssservice" ) ) {
00058     if ( KApplication::startServiceByDesktopName( "rssservice", QStringList(), &error, &appID ) ) {
00059       QLabel *label = new QLabel( i18n( "No rss dcop service available.\nYou need rssservice to use this plugin." ), this );
00060       vlay->addWidget( label, Qt::AlignHCenter );
00061       dcopAvailable = false;
00062     }
00063   }
00064 
00065   mBaseWidget = new QWidget( this, "baseWidget" );
00066   vlay->addWidget( mBaseWidget );
00067 
00068   connect( &mTimer, SIGNAL( timeout() ), this, SLOT( updateDocuments() ) );
00069 
00070   readConfig();
00071 
00072   if ( dcopAvailable )
00073     initDocuments();
00074 
00075   connectDCOPSignal( 0, 0, "added(QString)", "documentAdded(QString)", false );
00076   connectDCOPSignal( 0, 0, "removed(QString)", "documentRemoved(QString)", false );
00077 }
00078 
00079 int SummaryWidget::summaryHight() const
00080 {
00081   return ( mFeeds.count() == 0 ? 1 : mFeeds.count() );
00082 }
00083 
00084 void SummaryWidget::documentAdded( QString )
00085 {
00086   initDocuments();
00087 }
00088 
00089 void SummaryWidget::documentRemoved( QString )
00090 {
00091   initDocuments();
00092 }
00093 
00094 void SummaryWidget::configChanged()
00095 {
00096   readConfig();
00097 
00098   updateView();
00099 }
00100 
00101 void SummaryWidget::readConfig()
00102 {
00103   KConfig config( "kcmkontactkntrc" );
00104   config.setGroup( "General" );
00105 
00106   mUpdateInterval = config.readNumEntry( "UpdateInterval", 600 );
00107   mArticleCount = config.readNumEntry( "ArticleCount", 4 );
00108 }
00109 
00110 void SummaryWidget::initDocuments()
00111 {
00112   mFeeds.clear();
00113 
00114   DCOPRef dcopCall( "rssservice", "RSSService" );
00115   QStringList urls;
00116   dcopCall.call( "list()" ).get( urls );
00117 
00118   if ( urls.isEmpty() ) { // add default
00119     urls.append( "http://www.kde.org/dotkdeorg.rdf" );
00120     dcopCall.send( "add(QString)", urls[ 0 ] );
00121   }
00122 
00123   QStringList::Iterator it;
00124   for ( it = urls.begin(); it != urls.end(); ++it ) {
00125     DCOPRef feedRef = dcopCall.call( "document(QString)", *it );
00126 
00127     Feed feed;
00128     feed.ref = feedRef;
00129     feedRef.call( "title()" ).get( feed.title );
00130     feedRef.call( "link()" ).get( feed.url );
00131     feedRef.call( "pixmap()" ).get( feed.logo );
00132     mFeeds.append( feed );
00133 
00134     connectDCOPSignal( "rssservice", feedRef.obj(), "documentUpdated(DCOPRef)",
00135                        "documentUpdated(DCOPRef)", false );
00136 
00137     qApp->processEvents( QEventLoop::ExcludeUserInput | 
00138                          QEventLoop::ExcludeSocketNotifiers );
00139   }
00140 
00141   updateDocuments();
00142 }
00143 
00144 void SummaryWidget::updateDocuments()
00145 {
00146   mTimer.stop();
00147 
00148   FeedList::Iterator it;
00149   for ( it = mFeeds.begin(); it != mFeeds.end(); ++it )
00150     (*it).ref.send( "refresh()" );
00151 
00152   mTimer.start( 1000 * mUpdateInterval );
00153 }
00154 
00155 void SummaryWidget::documentUpdated( DCOPRef feedRef )
00156 {
00157   static uint feedCounter = 0;
00158   ArticleMap map;
00159 
00160   int numArticles = feedRef.call( "count()" );
00161   for ( int i = 0; i < numArticles; ++i ) {
00162     DCOPRef artRef = feedRef.call( "article(int)", i );
00163     QString title, url;
00164 
00165     qApp->processEvents( QEventLoop::ExcludeUserInput | 
00166                          QEventLoop::ExcludeSocketNotifiers );
00167 
00168     artRef.call( "title()" ).get( title );
00169     artRef.call( "link()" ).get( url );
00170 
00171     QPair<QString, KURL> article(title, KURL( url ));
00172     map.append( article );
00173   }
00174 
00175   FeedList::Iterator it;
00176   for ( it = mFeeds.begin(); it != mFeeds.end(); ++it )
00177     if ( (*it).ref.obj() == feedRef.obj() ) {
00178       (*it).map = map;
00179       if ( (*it).title.isEmpty() )
00180         feedRef.call( "title()" ).get( (*it).title );
00181       if ( (*it).url.isEmpty() )
00182         feedRef.call( "link()" ).get( (*it).url );
00183       if ( (*it).logo.isNull() )
00184         feedRef.call( "pixmap()" ).get( (*it).logo );
00185     }
00186 
00187   feedCounter++;
00188   if ( feedCounter == mFeeds.count() ) {
00189     feedCounter = 0;
00190     updateView();
00191   }
00192 }
00193 
00194 void SummaryWidget::updateView()
00195 {
00196   mLabels.setAutoDelete( true );
00197   mLabels.clear();
00198   mLabels.setAutoDelete( false );
00199 
00200   delete mLayout;
00201   mLayout = new QVBoxLayout( mBaseWidget, 3 );
00202 
00203   QFont boldFont;
00204   boldFont.setBold( true );
00205   boldFont.setPointSize( boldFont.pointSize() + 2 );
00206 
00207   FeedList::Iterator it;
00208   for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) {
00209     QHBox *hbox = new QHBox( mBaseWidget );
00210     mLayout->addWidget( hbox );
00211     hbox->show();
00212 
00213     // icon
00214     KURLLabel *urlLabel = new KURLLabel( hbox );
00215     urlLabel->setURL( (*it).url );
00216     urlLabel->setPixmap( (*it).logo );
00217     mLabels.append( urlLabel );
00218 
00219     connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
00220              kapp, SLOT( invokeBrowser( const QString& ) ) );
00221 
00222     // header
00223     QLabel *label = new QLabel( hbox );
00224     label->setText( KCharsets::resolveEntities( (*it).title ) );
00225     label->setAlignment( AlignLeft|AlignVCenter );
00226     label->setTextFormat( RichText );
00227     label->setFont( boldFont );
00228     label->setIndent( 6 );
00229     label->setSizePolicy( QSizePolicy::MinimumExpanding,
00230                           QSizePolicy::Preferred );
00231     mLabels.append( label );
00232 
00233     // articles
00234     ArticleMap articles = (*it).map;
00235     ArticleMap::Iterator artIt;
00236     int numArticles = 0;
00237     for ( artIt = articles.begin(); artIt != articles.end() && numArticles < mArticleCount; ++artIt ) {
00238       urlLabel = new KURLLabel( (*artIt).second.url(), (*artIt).first, mBaseWidget );
00239       urlLabel->setMaximumSize( urlLabel->minimumSizeHint() );
00240       mLabels.append( urlLabel );
00241       mLayout->addWidget( urlLabel );
00242 
00243       connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
00244                kapp, SLOT( invokeBrowser( const QString& ) ) );
00245 
00246       numArticles++;
00247     }
00248   }
00249 
00250   for ( QLabel *label = mLabels.first(); label; label = mLabels.next() )
00251     label->show();
00252 }
00253 
00254 QStringList SummaryWidget::configModules() const
00255 {
00256   return "kcmkontactknt.desktop";
00257 }
00258 
00259 #include "summarywidget.moc"
KDE Logo
This file is part of the documentation for kontact Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jan 31 15:56:21 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003