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