kontact Library API Documentation

kcmkontactknt.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 <qgroupbox.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 #include <qlineedit.h>
00028 #include <qvaluevector.h>
00029 #include <qspinbox.h>
00030 
00031 #include <dcopref.h>
00032 #include <dcopclient.h>
00033 
00034 #include <kaboutdata.h>
00035 #include <kapplication.h>
00036 #include <kaccelmanager.h>
00037 #include <kconfig.h>
00038 #include <kdebug.h>
00039 #include <kdialogbase.h>
00040 #include <klistview.h>
00041 #include <klocale.h>
00042 #include <kpushbutton.h>
00043 
00044 #include "kcmkontactknt.h"
00045 
00046 #include "newsfeeds.h"
00047 
00048 extern "C"
00049 {
00050   KCModule *create_kontactknt( QWidget *parent, const char * )
00051   {
00052     return new KCMKontactKNT( parent, "kcmkontactknt" );
00053   }
00054 }
00055 
00056 class NewsEditDialog : public KDialogBase
00057 {
00058   public:
00059     NewsEditDialog( const QString& title, const QString& url, QWidget *parent )
00060       : KDialogBase( Plain, i18n( "New News Feed" ), Ok | Cancel,
00061                      Ok, parent, 0, true, true )
00062     {
00063       QWidget *page = plainPage();
00064       QGridLayout *layout = new QGridLayout( page, 2, 3, marginHint(),
00065                                              spacingHint() );
00066 
00067       QLabel *label = new QLabel( i18n( "Name:" ), page );
00068       layout->addWidget( label, 0, 0 );
00069 
00070       mTitle = new QLineEdit( page );
00071       label->setBuddy( mTitle );
00072       layout->addMultiCellWidget( mTitle, 0, 0, 1, 2 );
00073 
00074       label = new QLabel( i18n( "URL:" ), page );
00075       layout->addWidget( label, 1, 0 );
00076 
00077       mURL = new QLineEdit( page );
00078       label->setBuddy( mURL );
00079       layout->addMultiCellWidget( mURL, 1, 1, 1, 2 );
00080 
00081       mTitle->setText( title );
00082       mURL->setText( url );
00083     }
00084 
00085     QString title() const { return mTitle->text(); }
00086     QString url() const { return mURL->text(); }
00087 
00088   private:
00089     QLineEdit *mTitle;
00090     QLineEdit *mURL;
00091 };
00092 
00093 class NewsItem : public QListViewItem
00094 {
00095   public:
00096     NewsItem( QListView *parent, const QString& title, const QString& url, bool custom )
00097       : QListViewItem( parent ), mTitle( title ), mUrl( url ), mCustom( custom )
00098     {
00099       setText( 0, mTitle );
00100     }
00101 
00102     NewsItem( QListViewItem *parent, const QString& title, const QString& url, bool custom )
00103       : QListViewItem( parent ), mTitle( title ), mUrl( url ), mCustom( custom )
00104     {
00105       setText( 0, mTitle );
00106     }
00107 
00108     QString title() const { return mTitle; }
00109     QString url() const { return mUrl; }
00110     bool custom() const { return mCustom; }
00111 
00112   private:
00113     QString mTitle;
00114     QString mUrl;
00115     bool mCustom;
00116 };
00117 
00118 KCMKontactKNT::KCMKontactKNT( QWidget *parent, const char *name )
00119   : KCModule( parent, name )
00120 {
00121   initGUI();
00122 
00123   connect( mAllNews, SIGNAL( currentChanged( QListViewItem* ) ),
00124            this, SLOT( allCurrentChanged( QListViewItem* ) ) );
00125   connect( mSelectedNews, SIGNAL( selectionChanged( QListViewItem* ) ),
00126            this, SLOT( selectedChanged( QListViewItem* ) ) );
00127 
00128   connect( mUpdateInterval, SIGNAL( valueChanged( int ) ), SLOT( modified() ) );
00129   connect( mArticleCount, SIGNAL( valueChanged( int ) ), SLOT( modified() ) );
00130 
00131   connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addNews() ) );
00132   connect( mRemoveButton, SIGNAL( clicked() ), this, SLOT( removeNews() ) );
00133   connect( mNewButton, SIGNAL( clicked() ), this, SLOT( newFeed() ) );
00134   connect( mDeleteButton, SIGNAL( clicked() ), this, SLOT( deleteFeed() ) );
00135 
00136   KAcceleratorManager::manage( this );
00137 
00138   load();
00139 }
00140 
00141 void KCMKontactKNT::loadNews()
00142 {
00143   QValueVector<QListViewItem*> parents;
00144   QValueVector<QListViewItem*>::Iterator it;
00145 
00146   parents.append( new QListViewItem( mAllNews, i18n( "Arts" ) ) );
00147   parents.append( new QListViewItem( mAllNews, i18n( "Business" ) ) );
00148   parents.append( new QListViewItem( mAllNews, i18n( "Computers" ) ) );
00149   parents.append( new QListViewItem( mAllNews, i18n( "Misc" ) ) );
00150   parents.append( new QListViewItem( mAllNews, i18n( "Recreation" ) ) );
00151   parents.append( new QListViewItem( mAllNews, i18n( "Society" ) ) );
00152 
00153   for ( it = parents.begin(); it != parents.end(); ++it )
00154     (*it)->setSelectable( false );
00155 
00156   for ( int i = 0; i < DEFAULT_NEWSSOURCES; ++i ) {
00157     NewsSourceData data = NewsSourceDefault[ i ];
00158     new NewsItem( parents[ data.category() ], data.name(), data.url(), false );
00159     mFeedMap.insert( data.url(), data.name() );
00160   }
00161 }
00162 
00163 void KCMKontactKNT::loadCustomNews()
00164 {
00165   KConfig config( "kcmkontactkntrc" );
00166   QMap<QString, QString> customFeeds = config.entryMap( "CustomFeeds" );
00167   config.setGroup( "CustomFeeds" );
00168 
00169   mCustomItem = new QListViewItem( mAllNews, i18n( "Customs" ) );
00170   mCustomItem->setSelectable( false );
00171 
00172   if ( customFeeds.count() == 0 )
00173     mCustomItem->setVisible( false );
00174 
00175   QMap<QString, QString>::Iterator it;
00176   for ( it = customFeeds.begin(); it != customFeeds.end(); ++it ) {
00177     QStringList value = config.readListEntry( it.key() );
00178     mCustomFeeds.append( new NewsItem( mCustomItem, value[ 0 ], value[ 1 ], true ) );
00179     mFeedMap.insert( value[ 1 ], value[ 0 ] );
00180     mCustomItem->setVisible( true );
00181   }
00182 }
00183 
00184 void KCMKontactKNT::storeCustomNews()
00185 {
00186   KConfig config( "kcmkontactkntrc" );
00187   config.deleteGroup( "CustomFeeds" );
00188   config.setGroup( "CustomFeeds" );
00189 
00190   int counter = 0;
00191   QValueList<NewsItem*>::Iterator it;
00192   for ( it = mCustomFeeds.begin(); it != mCustomFeeds.end(); ++it ) {
00193     QStringList value;
00194     value << (*it)->title() << (*it)->url();
00195     config.writeEntry( QString::number( counter ), value );
00196   }
00197 
00198   config.sync();
00199 }
00200 
00201 void KCMKontactKNT::addNews()
00202 {
00203   if ( !dcopActive() )
00204     return;
00205 
00206   NewsItem *item = dynamic_cast<NewsItem*>( mAllNews->selectedItem() );
00207   if ( item == 0 )
00208     return;
00209 
00210   DCOPRef service( "rssservice", "RSSService" );
00211   service.send( "add(QString)", item->url() );
00212 
00213   scanNews();
00214 
00215   emit changed( true );
00216 }
00217 
00218 void KCMKontactKNT::removeNews()
00219 {
00220   if ( !dcopActive() )
00221     return;
00222 
00223   NewsItem *item = dynamic_cast<NewsItem*>( mSelectedNews->selectedItem() );
00224   if ( item == 0 )
00225     return;
00226 
00227   DCOPRef service( "rssservice", "RSSService" );
00228   service.send( "remove(QString)", item->url() );
00229 
00230   scanNews();
00231 
00232   emit changed( true );
00233 }
00234 
00235 void KCMKontactKNT::newFeed()
00236 {
00237   NewsEditDialog dlg( "", "", this );
00238 
00239   if ( dlg.exec() ) {
00240     NewsItem *item = new NewsItem( mCustomItem, dlg.title(), dlg.url(), true );
00241     mCustomFeeds.append( item );
00242     mFeedMap.insert( dlg.url(), dlg.title() );
00243 
00244     mCustomItem->setVisible( true );
00245     mCustomItem->setOpen( true );
00246     mAllNews->ensureItemVisible( item );
00247     mAllNews->setSelected( item, true );
00248 
00249     emit changed( true );
00250   }
00251 }
00252 
00253 void KCMKontactKNT::deleteFeed()
00254 {
00255   NewsItem *item = dynamic_cast<NewsItem*>( mAllNews->selectedItem() );
00256   if ( !item )
00257     return;
00258 
00259   if ( mCustomFeeds.find( item ) == mCustomFeeds.end() )
00260     return;
00261 
00262   mCustomFeeds.remove( item );
00263   mFeedMap.remove( item->url() );
00264   delete item;
00265 
00266   if ( mCustomFeeds.count() == 0 )
00267     mCustomItem->setVisible( false );
00268 
00269   emit changed( true );
00270 }
00271 
00272 void KCMKontactKNT::scanNews()
00273 {
00274   if ( !dcopActive() )
00275     return;
00276 
00277   mSelectedNews->clear();
00278 
00279   DCOPRef service( "rssservice", "RSSService" );
00280   QStringList urls = service.call( "list()" );
00281 
00282   for ( uint i = 0; i < urls.count(); ++i )
00283     new NewsItem( mSelectedNews, mFeedMap[ urls[ i ] ], urls[ i ], false );
00284 }
00285 
00286 void KCMKontactKNT::selectedChanged( QListViewItem *item )
00287 {
00288   mRemoveButton->setEnabled( item && item->isSelected() );
00289 }
00290 
00291 void KCMKontactKNT::allCurrentChanged( QListViewItem *item )
00292 {
00293   NewsItem *newsItem = dynamic_cast<NewsItem*>( item );
00294 
00295   bool addState = false;
00296   bool delState = false;
00297   if ( newsItem && newsItem->isSelected() ) {
00298     addState = true;
00299     delState = (mCustomFeeds.find( newsItem ) != mCustomFeeds.end());
00300   }
00301 
00302   mAddButton->setEnabled( addState );
00303   mDeleteButton->setEnabled( delState );
00304 }
00305 
00306 void KCMKontactKNT::modified()
00307 {
00308   emit changed( true );
00309 }
00310 
00311 void KCMKontactKNT::initGUI()
00312 {
00313   QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(),
00314                                          KDialog::spacingHint() );
00315 
00316   mAllNews = new KListView( this );
00317   mAllNews->addColumn( i18n( "All" ) );
00318   mAllNews->setRootIsDecorated( true );
00319   mAllNews->setFullWidth( true );
00320   layout->addWidget( mAllNews, 0, 0 );
00321 
00322   QVBoxLayout *vbox = new QVBoxLayout( layout, KDialog::spacingHint() );
00323 
00324   vbox->addStretch();
00325   mAddButton = new KPushButton( i18n( "Add" ), this );
00326   mAddButton->setEnabled( false );
00327   vbox->addWidget( mAddButton );
00328   mRemoveButton = new KPushButton( i18n( "Remove" ), this );
00329   mRemoveButton->setEnabled( false );
00330   vbox->addWidget( mRemoveButton );
00331   vbox->addStretch();
00332 
00333   mSelectedNews = new KListView( this );
00334   mSelectedNews->addColumn( i18n( "Selected" ) );
00335   mSelectedNews->setFullWidth( true );
00336   layout->addWidget( mSelectedNews, 0, 2 );
00337 
00338   QGroupBox *box = new QGroupBox( 0, Qt::Vertical,
00339                                   i18n( "News Feed Settings" ), this );
00340 
00341   QGridLayout *boxLayout = new QGridLayout( box->layout(), 2, 3,
00342                                             KDialog::spacingHint() );
00343 
00344   QLabel *label = new QLabel( i18n( "Refresh time:" ), box );
00345   boxLayout->addWidget( label, 0, 0 );
00346 
00347   mUpdateInterval = new QSpinBox( 1, 3600, 1, box );
00348   mUpdateInterval->setSuffix( " sec." );
00349   label->setBuddy( mUpdateInterval );
00350   boxLayout->addWidget( mUpdateInterval, 0, 1 );
00351 
00352   label = new QLabel( i18n( "Number of items shown:" ), box );
00353   boxLayout->addWidget( label, 1, 0 );
00354 
00355   mArticleCount = new QSpinBox( box );
00356   label->setBuddy( mArticleCount );
00357   boxLayout->addWidget( mArticleCount, 1, 1 );
00358 
00359   mNewButton = new KPushButton( i18n( "New Feed..." ), box );
00360   boxLayout->addWidget( mNewButton, 0, 2 );
00361 
00362   mDeleteButton = new KPushButton( i18n( "Delete Feed" ), box );
00363   mDeleteButton->setEnabled( false );
00364   boxLayout->addWidget( mDeleteButton, 1, 2 );
00365 
00366   layout->addMultiCellWidget( box, 1, 1, 0, 2 );
00367 }
00368 
00369 bool KCMKontactKNT::dcopActive() const
00370 {
00371   QString error;
00372   QCString appID;
00373   bool isGood = true;
00374   DCOPClient *client = kapp->dcopClient();
00375   if ( !client->isApplicationRegistered( "rssservice" ) ) {
00376     if ( KApplication::startServiceByDesktopName( "rssservice", QStringList(), &error, &appID ) )
00377       isGood = false;
00378   }
00379 
00380   return isGood;
00381 }
00382 
00383 void KCMKontactKNT::load()
00384 {
00385   mAllNews->clear();
00386 
00387   loadNews();
00388   loadCustomNews();
00389   scanNews();
00390 
00391   KConfig config( "kcmkontactkntrc" );
00392   config.setGroup( "General" );
00393 
00394   mUpdateInterval->setValue( config.readNumEntry( "UpdateInterval", 600 ) );
00395   mArticleCount->setValue( config.readNumEntry( "ArticleCount", 4 ) );
00396 
00397   emit changed( false );
00398 }
00399 
00400 void KCMKontactKNT::save()
00401 {
00402   storeCustomNews();
00403 
00404   KConfig config( "kcmkontactkntrc" );
00405   config.setGroup( "General" );
00406 
00407   config.writeEntry( "UpdateInterval", mUpdateInterval->value() );
00408   config.writeEntry( "ArticleCount", mArticleCount->value() );
00409 
00410   config.sync();
00411 
00412   emit changed( false );
00413 }
00414 
00415 void KCMKontactKNT::defaults()
00416 {
00417 }
00418 
00419 const KAboutData* KCMKontactKNT::aboutData() const
00420 {
00421   KAboutData *about = new KAboutData( I18N_NOOP( "kcmkontactknt" ),
00422                                       I18N_NOOP( "Newsticker Configuration Dialog" ),
00423                                       0, 0, KAboutData::License_GPL,
00424                                       I18N_NOOP( "(c) 2003 - 2004 Tobias Koenig" ) );
00425 
00426   about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" );
00427 
00428   return about;
00429 }
00430 
00431 #include "kcmkontactknt.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 Jul 25 11:21:31 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003