00001 #include "managesievescriptsdialog.h"
00002 #include "managesievescriptsdialog_p.h"
00003
00004 #include "sieveconfig.h"
00005 #include "accountmanager.h"
00006 #include "imapaccountbase.h"
00007 #include "sievejob.h"
00008 #include "kmkernel.h"
00009
00010 #include <klocale.h>
00011 #include <kiconloader.h>
00012 #include <kwin.h>
00013 #include <kapplication.h>
00014 #include <kinputdialog.h>
00015 #include <kglobalsettings.h>
00016 #include <kmessagebox.h>
00017
00018 #include <qlayout.h>
00019 #include <qlistview.h>
00020 #include <qtextedit.h>
00021 #include <qpopupmenu.h>
00022
00023 #include <cassert>
00024
00025 inline QCheckListItem * qcli_cast( QListViewItem * lvi ) {
00026 return lvi && lvi->rtti() == 1 ? static_cast<QCheckListItem*>( lvi ) : 0 ;
00027 }
00028 inline const QCheckListItem * qcli_cast( const QListViewItem * lvi ) {
00029 return lvi && lvi->rtti() == 1 ? static_cast<const QCheckListItem*>( lvi ) : 0 ;
00030 }
00031
00032 KMail::ManageSieveScriptsDialog::ManageSieveScriptsDialog( QWidget * parent, const char * name )
00033 : KDialogBase( Plain, i18n( "Manage Sieve Scripts" ), Close, Close,
00034 parent, name, false ),
00035 mSieveEditor( 0 ),
00036 mContextMenuItem( 0 ),
00037 mWasActive( false )
00038 {
00039 setWFlags( WGroupLeader|WDestructiveClose );
00040 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
00041
00042 QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, 0 );
00043
00044 mListView = new QListView( plainPage() );
00045 mListView->addColumn( i18n( "Available Scripts" ) );
00046 mListView->setResizeMode( QListView::LastColumn );
00047 mListView->setRootIsDecorated( true );
00048 mListView->setSelectionMode( QListView::Single );
00049 connect( mListView, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&,int)),
00050 this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&)) );
00051 connect( mListView, SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
00052 this, SLOT(slotDoubleClicked(QListViewItem*)) );
00053 connect( mListView, SIGNAL(selectionChanged(QListViewItem*)),
00054 this, SLOT(slotSelectionChanged(QListViewItem*)) );
00055 vlay->addWidget( mListView );
00056
00057 resize( 2 * sizeHint().width(), sizeHint().height() );
00058
00059 slotRefresh();
00060 }
00061
00062 KMail::ManageSieveScriptsDialog::~ManageSieveScriptsDialog() {
00063 killAllJobs();
00064 }
00065
00066 void KMail::ManageSieveScriptsDialog::killAllJobs() {
00067 for ( QMap<SieveJob*,QCheckListItem*>::const_iterator it = mJobs.constBegin(), end = mJobs.constEnd() ; it != end ; ++it )
00068 it.key()->kill();
00069 mJobs.clear();
00070 }
00071
00072 static KURL findUrlForAccount( const KMail::ImapAccountBase * a ) {
00073 assert( a );
00074 const KMail::SieveConfig sieve = a->sieveConfig();
00075 if ( !sieve.managesieveSupported() )
00076 return KURL();
00077 if ( sieve.reuseConfig() ) {
00078
00079 KURL u;
00080 u.setProtocol( "sieve" );
00081 u.setHost( a->host() );
00082 u.setUser( a->login() );
00083 u.setPass( a->passwd() );
00084 u.setPort( sieve.port() );
00085
00086 u.setQuery( "x-mech=" + ( a->auth() == "*" ? "PLAIN" : a->auth() ) );
00087 return u;
00088 } else {
00089 return sieve.alternateURL();
00090 }
00091 }
00092
00093 void KMail::ManageSieveScriptsDialog::slotRefresh() {
00094 killAllJobs();
00095 mUrls.clear();
00096 mListView->clear();
00097
00098 KMail::AccountManager * am = kmkernel->acctMgr();
00099 assert( am );
00100 QCheckListItem * last = 0;
00101 for ( KMAccount * a = am->first() ; a ; a = am->next() ) {
00102 last = new QCheckListItem( mListView, last, a->name(), QCheckListItem::Controller );
00103 last->setPixmap( 0, SmallIcon( "server" ) );
00104 if ( ImapAccountBase * iab = dynamic_cast<ImapAccountBase*>( a ) ) {
00105 const KURL u = ::findUrlForAccount( iab );
00106 if ( u.isEmpty() )
00107 continue;
00108 SieveJob * job = SieveJob::list( u );
00109 connect( job, SIGNAL(item(KMail::SieveJob*,const QString&,bool)),
00110 this, SLOT(slotItem(KMail::SieveJob*,const QString&,bool)) );
00111 connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
00112 this, SLOT(slotResult(KMail::SieveJob*,bool,const QString&,bool)) );
00113 mJobs.insert( job, last );
00114 mUrls.insert( last, u );
00115 } else {
00116 QListViewItem * item = new QListViewItem( last, i18n( "No Sieve URL configured" ) );
00117 item->setEnabled( false );
00118 last->setOpen( true );
00119 }
00120 }
00121 }
00122
00123 void KMail::ManageSieveScriptsDialog::slotResult( KMail::SieveJob * job, bool success, const QString &, bool ) {
00124 QCheckListItem * parent = mJobs[job];
00125 if ( !parent )
00126 return;
00127
00128 mJobs.remove( job );
00129
00130 parent->setOpen( true );
00131
00132 if ( success )
00133 return;
00134
00135 QListViewItem * item = new QListViewItem( parent, i18n( "Failed to fetch the list of scripts" ) );
00136 item->setEnabled( false );
00137 }
00138
00139 void KMail::ManageSieveScriptsDialog::slotItem( KMail::SieveJob * job, const QString & filename, bool isActive ) {
00140 QCheckListItem * parent = mJobs[job];
00141 if ( !parent )
00142 return;
00143 QCheckListItem * item = new QCheckListItem( parent, filename, QCheckListItem::RadioButton );
00144 if ( isActive ) {
00145 item->setOn( true );
00146 mSelectedItems[parent] = item;
00147 }
00148 }
00149
00150 void KMail::ManageSieveScriptsDialog::slotContextMenuRequested( QListViewItem * i, const QPoint & p ) {
00151 QCheckListItem * item = qcli_cast( i );
00152 if ( !item )
00153 return;
00154 if ( !item->depth() && !mUrls.count( item ) )
00155 return;
00156 QPopupMenu menu;
00157 mContextMenuItem = item;
00158 if ( item->depth() ) {
00159
00160 menu.insertItem( i18n( "Delete Script" ), this, SLOT(slotDeleteScript()) );
00161 menu.insertItem( i18n( "Edit Script..." ), this, SLOT(slotEditScript()) );
00162 } else {
00163
00164 menu.insertItem( i18n( "New Script..." ), this, SLOT(slotNewScript()) );
00165 }
00166 menu.exec( p );
00167 mContextMenuItem = 0;
00168 }
00169
00170 void KMail::ManageSieveScriptsDialog::slotSelectionChanged( QListViewItem * i ) {
00171 QCheckListItem * item = qcli_cast( i );
00172 if ( !item )
00173 return;
00174 QCheckListItem * parent = qcli_cast( item->parent() );
00175 if ( !parent )
00176 return;
00177 if ( item->isOn() && mSelectedItems[parent] != item ) {
00178 mSelectedItems[parent] = item;
00179 changeActiveScript( parent );
00180 }
00181 }
00182
00183 void KMail::ManageSieveScriptsDialog::changeActiveScript( QCheckListItem * item ) {
00184 if ( !item )
00185 return;
00186 if ( !mUrls.count( item ) )
00187 return;
00188 if ( !mSelectedItems.count( item ) )
00189 return;
00190 KURL u = mUrls[item];
00191 if ( u.isEmpty() )
00192 return;
00193 QCheckListItem * selected = mSelectedItems[item];
00194 if ( !selected )
00195 return;
00196 u.setFileName( selected->text( 0 ) );
00197
00198 SieveJob * job = SieveJob::activate( u );
00199 connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
00200 this, SLOT(slotRefresh()) );
00201 }
00202
00203 void KMail::ManageSieveScriptsDialog::slotDoubleClicked( QListViewItem * i ) {
00204 QCheckListItem * item = qcli_cast( i );
00205 if ( !item )
00206 return;
00207 if ( !item->depth() )
00208 return;
00209 mContextMenuItem = item;
00210 slotEditScript();
00211 mContextMenuItem = 0;
00212 }
00213
00214 void KMail::ManageSieveScriptsDialog::slotDeleteScript() {
00215 if ( !mContextMenuItem )
00216 return;
00217 if ( !mContextMenuItem->depth() )
00218 return;
00219
00220 QCheckListItem * parent = qcli_cast( mContextMenuItem->parent() );
00221 if ( !parent )
00222 return;
00223
00224 if ( !mUrls.count( parent ) )
00225 return;
00226
00227 KURL u = mUrls[parent];
00228 if ( u.isEmpty() )
00229 return;
00230
00231 u.setFileName( mContextMenuItem->text( 0 ) );
00232
00233 if ( KMessageBox::warningContinueCancel( this, i18n( "Really delete script \"%1\" from the server?" ).arg( u.fileName() ),
00234 i18n( "Delete Sieve Script Confirmation" ),
00235 KStdGuiItem::del() )
00236 != KMessageBox::Continue )
00237 return;
00238
00239 SieveJob * job = SieveJob::del( u );
00240 connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
00241 this, SLOT(slotRefresh()) );
00242 }
00243
00244 void KMail::ManageSieveScriptsDialog::slotEditScript() {
00245 if ( !mContextMenuItem )
00246 return;
00247 if ( !mContextMenuItem->depth() )
00248 return;
00249 QCheckListItem * parent = qcli_cast( mContextMenuItem->parent() );
00250 if ( !mUrls.count( parent ) )
00251 return;
00252 KURL url = mUrls[parent];
00253 if ( url.isEmpty() )
00254 return;
00255 url.setFileName( mContextMenuItem->text( 0 ) );
00256 mCurrentURL = url;
00257 SieveJob * job = SieveJob::get( url );
00258 connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
00259 this, SLOT(slotGetResult(KMail::SieveJob*,bool,const QString&,bool)) );
00260 }
00261
00262 void KMail::ManageSieveScriptsDialog::slotNewScript() {
00263 if ( !mContextMenuItem )
00264 return;
00265 if ( mContextMenuItem->depth() )
00266 mContextMenuItem = qcli_cast( mContextMenuItem->parent() );
00267 if ( !mContextMenuItem )
00268 return;
00269
00270 if ( !mUrls.count( mContextMenuItem ) )
00271 return;
00272
00273 KURL u = mUrls[mContextMenuItem];
00274 if ( u.isEmpty() )
00275 return;
00276
00277 bool ok = false;
00278 const QString name = KInputDialog::getText( i18n( "New Sieve Script" ),
00279 i18n( "Please enter a name for the new Sieve script:" ),
00280 i18n( "unnamed" ), &ok, this );
00281 if ( !ok || name.isEmpty() )
00282 return;
00283
00284 u.setFileName( name );
00285
00286 (void) new QCheckListItem( mContextMenuItem, name, QCheckListItem::RadioButton );
00287
00288 mCurrentURL = u;
00289 slotGetResult( 0, true, QString::null, false );
00290 }
00291
00292 KMail::SieveEditor::SieveEditor( QWidget * parent, const char * name )
00293 : KDialogBase( Plain, i18n( "Edit Sieve Script" ), Ok|Cancel, Ok, parent, name )
00294 {
00295 QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
00296 mTextEdit = new QTextEdit( plainPage() );
00297 vlay->addWidget( mTextEdit );
00298 mTextEdit->setTextFormat( QTextEdit::PlainText );
00299 mTextEdit->setWordWrap( QTextEdit::NoWrap );
00300 mTextEdit->setFont( KGlobalSettings::fixedFont() );
00301
00302 resize( 3 * sizeHint() );
00303 }
00304
00305 KMail::SieveEditor::~SieveEditor() {}
00306
00307 void KMail::ManageSieveScriptsDialog::slotGetResult( KMail::SieveJob *, bool success, const QString & script, bool isActive ) {
00308 if ( !success )
00309 return;
00310
00311 if ( mSieveEditor )
00312 return;
00313
00314 mSieveEditor = new SieveEditor( this );
00315 mSieveEditor->setScript( script );
00316 connect( mSieveEditor, SIGNAL(okClicked()), this, SLOT(slotSieveEditorOkClicked()) );
00317 connect( mSieveEditor, SIGNAL(cancelClicked()), this, SLOT(slotSieveEditorCancelClicked()) );
00318 mSieveEditor->show();
00319 mWasActive = isActive;
00320 }
00321
00322 void KMail::ManageSieveScriptsDialog::slotSieveEditorOkClicked() {
00323 if ( !mSieveEditor )
00324 return;
00325 SieveJob * job = SieveJob::put( mCurrentURL,mSieveEditor->script(), mWasActive, mWasActive );
00326 connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
00327 this, SLOT(slotPutResult(KMail::SieveJob*,bool)) );
00328 }
00329
00330 void KMail::ManageSieveScriptsDialog::slotSieveEditorCancelClicked() {
00331 mSieveEditor->deleteLater(); mSieveEditor = 0;
00332 mCurrentURL = KURL();
00333 }
00334
00335 void KMail::ManageSieveScriptsDialog::slotPutResult( KMail::SieveJob *, bool success ) {
00336 if ( success ) {
00337 KMessageBox::information( this, i18n( "The Sieve script was successfully uploaded." ),
00338 i18n( "Sieve Script Upload" ) );
00339 mSieveEditor->deleteLater(); mSieveEditor = 0;
00340 mCurrentURL = KURL();
00341 } else {
00342 mSieveEditor->show();
00343 }
00344 }
00345
00346 #include "managesievescriptsdialog.moc"
00347 #include "managesievescriptsdialog_p.moc"