00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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() ) {
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
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
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
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"