summaryrefslogtreecommitdiffstats
path: root/kontact/plugins/newsticker/kcmkontactknt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kontact/plugins/newsticker/kcmkontactknt.cpp')
-rw-r--r--kontact/plugins/newsticker/kcmkontactknt.cpp452
1 files changed, 452 insertions, 0 deletions
diff --git a/kontact/plugins/newsticker/kcmkontactknt.cpp b/kontact/plugins/newsticker/kcmkontactknt.cpp
new file mode 100644
index 000000000..18f439c8e
--- /dev/null
+++ b/kontact/plugins/newsticker/kcmkontactknt.cpp
@@ -0,0 +1,452 @@
+/*
+ This file is part of Kontact.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qvaluevector.h>
+#include <qspinbox.h>
+
+#include <dcopref.h>
+#include <dcopclient.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kaccelmanager.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+
+#include "kcmkontactknt.h"
+
+#include "newsfeeds.h"
+
+#include <kdepimmacros.h>
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_kontactknt( QWidget *parent, const char * )
+ {
+ return new KCMKontactKNT( parent, "kcmkontactknt" );
+ }
+}
+
+NewsEditDialog::NewsEditDialog( const QString& title, const QString& url, QWidget *parent )
+ : KDialogBase( Plain, i18n( "New News Feed" ), Ok | Cancel,
+ Ok, parent, 0, true, true )
+{
+ QWidget *page = plainPage();
+ QGridLayout *layout = new QGridLayout( page, 2, 3, marginHint(),
+ spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Name:" ), page );
+ layout->addWidget( label, 0, 0 );
+
+ mTitle = new QLineEdit( page );
+ label->setBuddy( mTitle );
+ layout->addMultiCellWidget( mTitle, 0, 0, 1, 2 );
+
+ label = new QLabel( i18n( "URL:" ), page );
+ layout->addWidget( label, 1, 0 );
+
+ mURL = new QLineEdit( page );
+ label->setBuddy( mURL );
+ layout->addMultiCellWidget( mURL, 1, 1, 1, 2 );
+
+ mTitle->setText( title );
+ mURL->setText( url );
+ mTitle->setFocus();
+ connect( mTitle, SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( modified() ) );
+ connect( mURL, SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( modified() ) );
+
+ modified();
+}
+
+void NewsEditDialog::modified()
+{
+ enableButton( KDialogBase::Ok, !title().isEmpty() && !url().isEmpty() );
+}
+
+QString NewsEditDialog::title() const
+{
+ return mTitle->text();
+}
+
+QString NewsEditDialog::url() const
+{
+ return mURL->text();
+}
+
+class NewsItem : public QListViewItem
+{
+ public:
+ NewsItem( QListView *parent, const QString& title, const QString& url, bool custom )
+ : QListViewItem( parent ), mTitle( title ), mUrl( url ), mCustom( custom )
+ {
+ setText( 0, mTitle );
+ }
+
+ NewsItem( QListViewItem *parent, const QString& title, const QString& url, bool custom )
+ : QListViewItem( parent ), mTitle( title ), mUrl( url ), mCustom( custom )
+ {
+ setText( 0, mTitle );
+ }
+
+ QString title() const { return mTitle; }
+ QString url() const { return mUrl; }
+ bool custom() const { return mCustom; }
+
+ private:
+ QString mTitle;
+ QString mUrl;
+ bool mCustom;
+};
+
+KCMKontactKNT::KCMKontactKNT( QWidget *parent, const char *name )
+ : KCModule( parent, name )
+{
+ initGUI();
+
+ connect( mAllNews, SIGNAL( currentChanged( QListViewItem* ) ),
+ this, SLOT( allCurrentChanged( QListViewItem* ) ) );
+ connect( mSelectedNews, SIGNAL( selectionChanged( QListViewItem* ) ),
+ this, SLOT( selectedChanged( QListViewItem* ) ) );
+
+ connect( mUpdateInterval, SIGNAL( valueChanged( int ) ), SLOT( modified() ) );
+ connect( mArticleCount, SIGNAL( valueChanged( int ) ), SLOT( modified() ) );
+
+ connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addNews() ) );
+ connect( mRemoveButton, SIGNAL( clicked() ), this, SLOT( removeNews() ) );
+ connect( mNewButton, SIGNAL( clicked() ), this, SLOT( newFeed() ) );
+ connect( mDeleteButton, SIGNAL( clicked() ), this, SLOT( deleteFeed() ) );
+
+ KAcceleratorManager::manage( this );
+
+ load();
+}
+
+void KCMKontactKNT::loadNews()
+{
+ QValueVector<QListViewItem*> parents;
+ QValueVector<QListViewItem*>::Iterator it;
+
+ parents.append( new QListViewItem( mAllNews, i18n( "Arts" ) ) );
+ parents.append( new QListViewItem( mAllNews, i18n( "Business" ) ) );
+ parents.append( new QListViewItem( mAllNews, i18n( "Computers" ) ) );
+ parents.append( new QListViewItem( mAllNews, i18n( "Misc" ) ) );
+ parents.append( new QListViewItem( mAllNews, i18n( "Recreation" ) ) );
+ parents.append( new QListViewItem( mAllNews, i18n( "Society" ) ) );
+
+ for ( it = parents.begin(); it != parents.end(); ++it )
+ (*it)->setSelectable( false );
+
+ for ( int i = 0; i < DEFAULT_NEWSSOURCES; ++i ) {
+ NewsSourceData data = NewsSourceDefault[ i ];
+ new NewsItem( parents[ data.category() ], data.name(), data.url(), false );
+ mFeedMap.insert( data.url(), data.name() );
+ }
+}
+
+void KCMKontactKNT::loadCustomNews()
+{
+ KConfig config( "kcmkontactkntrc" );
+ QMap<QString, QString> customFeeds = config.entryMap( "CustomFeeds" );
+ config.setGroup( "CustomFeeds" );
+
+ mCustomItem = new QListViewItem( mAllNews, i18n( "Custom" ) );
+ mCustomItem->setSelectable( false );
+
+ if ( customFeeds.count() == 0 )
+ mCustomItem->setVisible( false );
+
+ QMap<QString, QString>::Iterator it;
+ for ( it = customFeeds.begin(); it != customFeeds.end(); ++it ) {
+ QStringList value = config.readListEntry( it.key() );
+ mCustomFeeds.append( new NewsItem( mCustomItem, value[ 0 ], value[ 1 ], true ) );
+ mFeedMap.insert( value[ 1 ], value[ 0 ] );
+ mCustomItem->setVisible( true );
+ }
+}
+
+void KCMKontactKNT::storeCustomNews()
+{
+ KConfig config( "kcmkontactkntrc" );
+ config.deleteGroup( "CustomFeeds" );
+ config.setGroup( "CustomFeeds" );
+
+ int counter = 0;
+ QValueList<NewsItem*>::Iterator it;
+ for ( it = mCustomFeeds.begin(); it != mCustomFeeds.end(); ++it ) {
+ QStringList value;
+ value << (*it)->title() << (*it)->url();
+ config.writeEntry( QString::number( counter ), value );
+
+ ++counter;
+ }
+
+ config.sync();
+}
+
+void KCMKontactKNT::addNews()
+{
+ if ( !dcopActive() )
+ return;
+
+ NewsItem *item = dynamic_cast<NewsItem*>( mAllNews->selectedItem() );
+ if ( item == 0 )
+ return;
+
+ DCOPRef service( "rssservice", "RSSService" );
+ service.send( "add(QString)", item->url() );
+
+ scanNews();
+
+ emit changed( true );
+}
+
+void KCMKontactKNT::removeNews()
+{
+ if ( !dcopActive() )
+ return;
+
+ NewsItem *item = dynamic_cast<NewsItem*>( mSelectedNews->selectedItem() );
+ if ( item == 0 )
+ return;
+
+ DCOPRef service( "rssservice", "RSSService" );
+ service.send( "remove(QString)", item->url() );
+
+ scanNews();
+
+ emit changed( true );
+}
+
+void KCMKontactKNT::newFeed()
+{
+ NewsEditDialog dlg( "", "", this );
+
+ if ( dlg.exec() ) {
+ NewsItem *item = new NewsItem( mCustomItem, dlg.title(), dlg.url(), true );
+ mCustomFeeds.append( item );
+ mFeedMap.insert( dlg.url(), dlg.title() );
+
+ mCustomItem->setVisible( true );
+ mCustomItem->setOpen( true );
+ mAllNews->ensureItemVisible( item );
+ mAllNews->setSelected( item, true );
+
+ emit changed( true );
+ }
+}
+
+void KCMKontactKNT::deleteFeed()
+{
+ NewsItem *item = dynamic_cast<NewsItem*>( mAllNews->selectedItem() );
+ if ( !item )
+ return;
+
+ if ( mCustomFeeds.find( item ) == mCustomFeeds.end() )
+ return;
+
+ mCustomFeeds.remove( item );
+ mFeedMap.remove( item->url() );
+ delete item;
+
+ if ( mCustomFeeds.count() == 0 )
+ mCustomItem->setVisible( false );
+
+ emit changed( true );
+}
+
+void KCMKontactKNT::scanNews()
+{
+ if ( !dcopActive() )
+ return;
+
+ mSelectedNews->clear();
+
+ DCOPRef service( "rssservice", "RSSService" );
+ QStringList urls = service.call( "list()" );
+
+ for ( uint i = 0; i < urls.count(); ++i )
+ {
+ QString url = urls[ i ];
+ QString feedName = mFeedMap[ url ];
+ if ( feedName.isEmpty() )
+ feedName = url;
+ new NewsItem( mSelectedNews, feedName, url, false );
+ }
+}
+
+void KCMKontactKNT::selectedChanged( QListViewItem *item )
+{
+ mRemoveButton->setEnabled( item && item->isSelected() );
+}
+
+void KCMKontactKNT::allCurrentChanged( QListViewItem *item )
+{
+ NewsItem *newsItem = dynamic_cast<NewsItem*>( item );
+
+ bool addState = false;
+ bool delState = false;
+ if ( newsItem && newsItem->isSelected() ) {
+ addState = true;
+ delState = (mCustomFeeds.find( newsItem ) != mCustomFeeds.end());
+ }
+
+ mAddButton->setEnabled( addState );
+ mDeleteButton->setEnabled( delState );
+}
+
+void KCMKontactKNT::modified()
+{
+ emit changed( true );
+}
+
+void KCMKontactKNT::initGUI()
+{
+ QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ mAllNews = new KListView( this );
+ mAllNews->addColumn( i18n( "All" ) );
+ mAllNews->setRootIsDecorated( true );
+ mAllNews->setFullWidth( true );
+ layout->addWidget( mAllNews, 0, 0 );
+
+ QVBoxLayout *vbox = new QVBoxLayout( layout, KDialog::spacingHint() );
+
+ vbox->addStretch();
+ mAddButton = new KPushButton( i18n( "Add" ), this );
+ mAddButton->setEnabled( false );
+ vbox->addWidget( mAddButton );
+ mRemoveButton = new KPushButton( i18n( "Remove" ), this );
+ mRemoveButton->setEnabled( false );
+ vbox->addWidget( mRemoveButton );
+ vbox->addStretch();
+
+ mSelectedNews = new KListView( this );
+ mSelectedNews->addColumn( i18n( "Selected" ) );
+ mSelectedNews->setFullWidth( true );
+ layout->addWidget( mSelectedNews, 0, 2 );
+
+ QGroupBox *box = new QGroupBox( 0, Qt::Vertical,
+ i18n( "News Feed Settings" ), this );
+
+ QGridLayout *boxLayout = new QGridLayout( box->layout(), 2, 3,
+ KDialog::spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Refresh time:" ), box );
+ boxLayout->addWidget( label, 0, 0 );
+
+ mUpdateInterval = new QSpinBox( 1, 3600, 1, box );
+ mUpdateInterval->setSuffix( " sec." );
+ label->setBuddy( mUpdateInterval );
+ boxLayout->addWidget( mUpdateInterval, 0, 1 );
+
+ label = new QLabel( i18n( "Number of items shown:" ), box );
+ boxLayout->addWidget( label, 1, 0 );
+
+ mArticleCount = new QSpinBox( box );
+ label->setBuddy( mArticleCount );
+ boxLayout->addWidget( mArticleCount, 1, 1 );
+
+ mNewButton = new KPushButton( i18n( "New Feed..." ), box );
+ boxLayout->addWidget( mNewButton, 0, 2 );
+
+ mDeleteButton = new KPushButton( i18n( "Delete Feed" ), box );
+ mDeleteButton->setEnabled( false );
+ boxLayout->addWidget( mDeleteButton, 1, 2 );
+
+ layout->addMultiCellWidget( box, 1, 1, 0, 2 );
+}
+
+bool KCMKontactKNT::dcopActive() const
+{
+ QString error;
+ QCString appID;
+ bool isGood = true;
+ DCOPClient *client = kapp->dcopClient();
+ if ( !client->isApplicationRegistered( "rssservice" ) ) {
+ if ( KApplication::startServiceByDesktopName( "rssservice", QStringList(), &error, &appID ) )
+ isGood = false;
+ }
+
+ return isGood;
+}
+
+void KCMKontactKNT::load()
+{
+ mAllNews->clear();
+
+ loadNews();
+ loadCustomNews();
+ scanNews();
+
+ KConfig config( "kcmkontactkntrc" );
+ config.setGroup( "General" );
+
+ mUpdateInterval->setValue( config.readNumEntry( "UpdateInterval", 600 ) );
+ mArticleCount->setValue( config.readNumEntry( "ArticleCount", 4 ) );
+
+ emit changed( false );
+}
+
+void KCMKontactKNT::save()
+{
+ storeCustomNews();
+
+ KConfig config( "kcmkontactkntrc" );
+ config.setGroup( "General" );
+
+ config.writeEntry( "UpdateInterval", mUpdateInterval->value() );
+ config.writeEntry( "ArticleCount", mArticleCount->value() );
+
+ config.sync();
+
+ emit changed( false );
+}
+
+void KCMKontactKNT::defaults()
+{
+}
+
+const KAboutData* KCMKontactKNT::aboutData() const
+{
+ KAboutData *about = new KAboutData( I18N_NOOP( "kcmkontactknt" ),
+ I18N_NOOP( "Newsticker Configuration Dialog" ),
+ 0, 0, KAboutData::License_GPL,
+ I18N_NOOP( "(c) 2003 - 2004 Tobias Koenig" ) );
+
+ about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" );
+
+ return about;
+}
+
+#include "kcmkontactknt.moc"