mailtransport
transportmanager.cpp
00001 /* 00002 Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "transportmanager.h" 00021 #include "resourcesendjob_p.h" 00022 #include "mailtransport_defs.h" 00023 #include "sendmailjob.h" 00024 #include "smtpjob.h" 00025 #include "transport.h" 00026 #include "transport_p.h" 00027 #include "transportjob.h" 00028 #include "transporttype.h" 00029 #include "transporttype_p.h" 00030 #include "addtransportdialog.h" 00031 #include "transportconfigdialog.h" 00032 #include "transportconfigwidget.h" 00033 #include "sendmailconfigwidget.h" 00034 #include "smtpconfigwidget.h" 00035 00036 #include <QApplication> 00037 #include <QtDBus/QDBusConnection> 00038 #include <QtDBus/QDBusConnectionInterface> 00039 #include <QtDBus/QDBusServiceWatcher> 00040 #include <QPointer> 00041 #include <QRegExp> 00042 #include <QStringList> 00043 00044 #include <KConfig> 00045 #include <KConfigGroup> 00046 #include <KDebug> 00047 #include <KEMailSettings> 00048 #include <KLocale> 00049 #include <KMessageBox> 00050 #include <KRandom> 00051 #include <KUrl> 00052 #include <KWallet/Wallet> 00053 00054 #include <akonadi/agentinstance.h> 00055 #include <akonadi/agentmanager.h> 00056 00057 using namespace MailTransport; 00058 using namespace KWallet; 00059 00060 namespace MailTransport { 00065 class TransportManagerPrivate 00066 { 00067 public: 00068 TransportManagerPrivate( TransportManager *parent ) 00069 : q( parent ) 00070 { 00071 } 00072 00073 ~TransportManagerPrivate() { 00074 delete config; 00075 qDeleteAll( transports ); 00076 } 00077 00078 KConfig *config; 00079 QList<Transport *> transports; 00080 TransportType::List types; 00081 bool myOwnChange; 00082 bool appliedChange; 00083 KWallet::Wallet *wallet; 00084 bool walletOpenFailed; 00085 bool walletAsyncOpen; 00086 int defaultTransportId; 00087 bool isMainInstance; 00088 QList<TransportJob *> walletQueue; 00089 TransportManager *q; 00090 00091 void readConfig(); 00092 void writeConfig(); 00093 void fillTypes(); 00094 int createId() const; 00095 void prepareWallet(); 00096 void validateDefault(); 00097 void migrateToWallet(); 00098 00099 // Slots 00100 void slotTransportsChanged(); 00101 void slotWalletOpened( bool success ); 00102 void dbusServiceUnregistered(); 00103 void agentTypeAdded( const Akonadi::AgentType &atype ); 00104 void agentTypeRemoved( const Akonadi::AgentType &atype ); 00105 void jobResult( KJob *job ); 00106 }; 00107 00108 } 00109 00110 class StaticTransportManager : public TransportManager 00111 { 00112 public: 00113 StaticTransportManager() : TransportManager() {} 00114 }; 00115 00116 StaticTransportManager *sSelf = 0; 00117 00118 static void destroyStaticTransportManager() { 00119 delete sSelf; 00120 } 00121 00122 TransportManager::TransportManager() 00123 : QObject(), d( new TransportManagerPrivate( this ) ) 00124 { 00125 KGlobal::locale()->insertCatalog( QLatin1String( "libmailtransport" ) ); 00126 KGlobal::locale()->insertCatalog( QLatin1String( "libakonadi-kmime" ) ); 00127 qAddPostRoutine( destroyStaticTransportManager ); 00128 d->myOwnChange = false; 00129 d->appliedChange = false; 00130 d->wallet = 0; 00131 d->walletOpenFailed = false; 00132 d->walletAsyncOpen = false; 00133 d->defaultTransportId = -1; 00134 d->config = new KConfig( QLatin1String( "mailtransports" ) ); 00135 00136 QDBusConnection::sessionBus().registerObject( DBUS_OBJECT_PATH, this, 00137 QDBusConnection::ExportScriptableSlots | 00138 QDBusConnection::ExportScriptableSignals ); 00139 00140 QDBusServiceWatcher *watcher = new QDBusServiceWatcher( DBUS_SERVICE_NAME, QDBusConnection::sessionBus(), 00141 QDBusServiceWatcher::WatchForUnregistration, this ); 00142 connect( watcher, SIGNAL( serviceUnregistered( const QString& ) ), SLOT( dbusServiceUnregistered() ) ); 00143 00144 QDBusConnection::sessionBus().connect( QString(), QString(), 00145 DBUS_INTERFACE_NAME, DBUS_CHANGE_SIGNAL, 00146 this, SLOT(slotTransportsChanged()) ); 00147 00148 d->isMainInstance = QDBusConnection::sessionBus().registerService( DBUS_SERVICE_NAME ); 00149 00150 d->fillTypes(); 00151 } 00152 00153 TransportManager::~TransportManager() 00154 { 00155 qRemovePostRoutine( destroyStaticTransportManager ); 00156 delete d; 00157 } 00158 00159 TransportManager *TransportManager::self() 00160 { 00161 if ( !sSelf ) { 00162 sSelf = new StaticTransportManager; 00163 sSelf->d->readConfig(); 00164 } 00165 return sSelf; 00166 } 00167 00168 Transport *TransportManager::transportById( int id, bool def ) const 00169 { 00170 foreach ( Transport *t, d->transports ) { 00171 if ( t->id() == id ) { 00172 return t; 00173 } 00174 } 00175 00176 if ( def || ( id == 0 && d->defaultTransportId != id ) ) { 00177 return transportById( d->defaultTransportId, false ); 00178 } 00179 return 0; 00180 } 00181 00182 Transport *TransportManager::transportByName( const QString &name, bool def ) const 00183 { 00184 foreach ( Transport *t, d->transports ) { 00185 if ( t->name() == name ) { 00186 return t; 00187 } 00188 } 00189 if ( def ) { 00190 return transportById( 0, false ); 00191 } 00192 return 0; 00193 } 00194 00195 QList< Transport * > TransportManager::transports() const 00196 { 00197 return d->transports; 00198 } 00199 00200 TransportType::List TransportManager::types() const 00201 { 00202 return d->types; 00203 } 00204 00205 Transport *TransportManager::createTransport() const 00206 { 00207 int id = d->createId(); 00208 Transport *t = new Transport( QString::number( id ) ); 00209 t->setId( id ); 00210 return t; 00211 } 00212 00213 void TransportManager::addTransport( Transport *transport ) 00214 { 00215 if ( d->transports.contains( transport ) ) { 00216 kDebug() << "Already have this transport."; 00217 return; 00218 } 00219 00220 kDebug() << "Added transport" << transport; 00221 d->transports.append( transport ); 00222 d->validateDefault(); 00223 emitChangesCommitted(); 00224 } 00225 00226 void TransportManager::schedule( TransportJob *job ) 00227 { 00228 connect( job, SIGNAL(result(KJob*)), SLOT(jobResult(KJob*)) ); 00229 00230 // check if the job is waiting for the wallet 00231 if ( !job->transport()->isComplete() ) { 00232 kDebug() << "job waits for wallet:" << job; 00233 d->walletQueue << job; 00234 loadPasswordsAsync(); 00235 return; 00236 } 00237 00238 job->start(); 00239 } 00240 00241 void TransportManager::createDefaultTransport() 00242 { 00243 KEMailSettings kes; 00244 Transport *t = createTransport(); 00245 t->setName( i18n( "Default Transport" ) ); 00246 t->setHost( kes.getSetting( KEMailSettings::OutServer ) ); 00247 if ( t->isValid() ) { 00248 t->writeConfig(); 00249 addTransport( t ); 00250 } else { 00251 kWarning() << "KEMailSettings does not contain a valid transport."; 00252 } 00253 } 00254 00255 bool TransportManager::showTransportCreationDialog( QWidget *parent, 00256 ShowCondition showCondition ) 00257 { 00258 if ( showCondition == IfNoTransportExists ) { 00259 if ( !isEmpty() ) { 00260 return true; 00261 } 00262 00263 const int response = KMessageBox::messageBox( parent, 00264 KMessageBox::WarningContinueCancel, 00265 i18n( "You must create an outgoing account before sending." ), 00266 i18n( "Create Account Now?" ), 00267 KGuiItem( i18n( "Create Account Now" ) ) ); 00268 if ( response != KMessageBox::Continue ) { 00269 return false; 00270 } 00271 } 00272 00273 QPointer<AddTransportDialog> dialog = new AddTransportDialog( parent ); 00274 const bool accepted = ( dialog->exec() == QDialog::Accepted ); 00275 delete dialog; 00276 return accepted; 00277 } 00278 00279 bool TransportManager::configureTransport( Transport *transport, QWidget *parent ) 00280 { 00281 if( transport->type() == Transport::EnumType::Akonadi ) { 00282 using namespace Akonadi; 00283 AgentInstance instance = AgentManager::self()->instance( transport->host() ); 00284 if( !instance.isValid() ) { 00285 kWarning() << "Invalid resource instance" << transport->host(); 00286 } 00287 instance.configure( parent ); // Async... 00288 transport->writeConfig(); 00289 return true; // No way to know here if the user cancelled or not. 00290 } 00291 00292 QPointer<KDialog> dialog = new KDialog( parent ); 00293 TransportConfigWidget *configWidget = 0; 00294 switch( transport->type() ) { 00295 case Transport::EnumType::SMTP: 00296 { 00297 configWidget = new SMTPConfigWidget( transport, dialog ); 00298 break; 00299 } 00300 case Transport::EnumType::Sendmail: 00301 { 00302 configWidget = new SendmailConfigWidget( transport, dialog ); 00303 break; 00304 } 00305 default: 00306 { 00307 Q_ASSERT( false ); 00308 delete dialog; 00309 return false; 00310 } 00311 } 00312 dialog->setMainWidget( configWidget ); 00313 dialog->setCaption( i18n( "Configure account" ) ); 00314 dialog->setButtons( KDialog::Ok | KDialog::Cancel ); 00315 bool okClicked = ( dialog->exec() == QDialog::Accepted ); 00316 if( okClicked ) { 00317 configWidget->apply(); // calls transport->writeConfig() 00318 } 00319 delete dialog; 00320 return okClicked; 00321 } 00322 00323 TransportJob *TransportManager::createTransportJob( int transportId ) 00324 { 00325 Transport *t = transportById( transportId, false ); 00326 if ( !t ) { 00327 return 0; 00328 } 00329 t = t->clone(); // Jobs delete their transports. 00330 t->updatePasswordState(); 00331 switch ( t->type() ) { 00332 case Transport::EnumType::SMTP: 00333 return new SmtpJob( t, this ); 00334 case Transport::EnumType::Sendmail: 00335 return new SendmailJob( t, this ); 00336 case Transport::EnumType::Akonadi: 00337 return new ResourceSendJob( t, this ); 00338 } 00339 Q_ASSERT( false ); 00340 return 0; 00341 } 00342 00343 TransportJob *TransportManager::createTransportJob( const QString &transport ) 00344 { 00345 bool ok = false; 00346 Transport *t = 0; 00347 00348 int transportId = transport.toInt( &ok ); 00349 if ( ok ) { 00350 t = transportById( transportId ); 00351 } 00352 00353 if ( !t ) { 00354 t = transportByName( transport, false ); 00355 } 00356 00357 if ( t ) { 00358 return createTransportJob( t->id() ); 00359 } 00360 00361 return 0; 00362 } 00363 00364 bool TransportManager::isEmpty() const 00365 { 00366 return d->transports.isEmpty(); 00367 } 00368 00369 QList<int> TransportManager::transportIds() const 00370 { 00371 QList<int> rv; 00372 foreach ( Transport *t, d->transports ) { 00373 rv << t->id(); 00374 } 00375 return rv; 00376 } 00377 00378 QStringList TransportManager::transportNames() const 00379 { 00380 QStringList rv; 00381 foreach ( Transport *t, d->transports ) { 00382 rv << t->name(); 00383 } 00384 return rv; 00385 } 00386 00387 QString TransportManager::defaultTransportName() const 00388 { 00389 Transport *t = transportById( d->defaultTransportId, false ); 00390 if ( t ) { 00391 return t->name(); 00392 } 00393 return QString(); 00394 } 00395 00396 int TransportManager::defaultTransportId() const 00397 { 00398 return d->defaultTransportId; 00399 } 00400 00401 void TransportManager::setDefaultTransport( int id ) 00402 { 00403 if ( id == d->defaultTransportId || !transportById( id, false ) ) { 00404 return; 00405 } 00406 d->defaultTransportId = id; 00407 d->writeConfig(); 00408 } 00409 00410 void TransportManager::removeTransport( int id ) 00411 { 00412 Transport *t = transportById( id, false ); 00413 if ( !t ) { 00414 return; 00415 } 00416 emit transportRemoved( t->id(), t->name() ); 00417 00418 // Kill the resource, if Akonadi-type transport. 00419 if( t->type() == Transport::EnumType::Akonadi ) { 00420 using namespace Akonadi; 00421 const AgentInstance instance = AgentManager::self()->instance( t->host() ); 00422 if( !instance.isValid() ) { 00423 kWarning() << "Could not find resource instance."; 00424 } 00425 AgentManager::self()->removeInstance( instance ); 00426 } 00427 00428 d->transports.removeAll( t ); 00429 d->validateDefault(); 00430 QString group = t->currentGroup(); 00431 delete t; 00432 d->config->deleteGroup( group ); 00433 d->writeConfig(); 00434 00435 } 00436 00437 void TransportManagerPrivate::readConfig() 00438 { 00439 QList<Transport *> oldTransports = transports; 00440 transports.clear(); 00441 00442 QRegExp re( QLatin1String( "^Transport (.+)$" ) ); 00443 QStringList groups = config->groupList().filter( re ); 00444 foreach ( const QString &s, groups ) { 00445 re.indexIn( s ); 00446 Transport *t = 0; 00447 00448 // see if we happen to have that one already 00449 foreach ( Transport *old, oldTransports ) { 00450 if ( old->currentGroup() == QLatin1String( "Transport " ) + re.cap( 1 ) ) { 00451 kDebug() << "reloading existing transport:" << s; 00452 t = old; 00453 t->d->passwordNeedsUpdateFromWallet = true; 00454 t->readConfig(); 00455 oldTransports.removeAll( old ); 00456 break; 00457 } 00458 } 00459 00460 if ( !t ) { 00461 t = new Transport( re.cap( 1 ) ); 00462 } 00463 if ( t->id() <= 0 ) { 00464 t->setId( createId() ); 00465 t->writeConfig(); 00466 } 00467 transports.append( t ); 00468 } 00469 00470 qDeleteAll( oldTransports ); 00471 oldTransports.clear(); 00472 00473 // read default transport 00474 KConfigGroup group( config, "General" ); 00475 defaultTransportId = group.readEntry( "default-transport", 0 ); 00476 if ( defaultTransportId == 0 ) { 00477 // migrated default transport contains the name instead 00478 QString name = group.readEntry( "default-transport", QString() ); 00479 if ( !name.isEmpty() ) { 00480 Transport *t = q->transportByName( name, false ); 00481 if ( t ) { 00482 defaultTransportId = t->id(); 00483 writeConfig(); 00484 } 00485 } 00486 } 00487 validateDefault(); 00488 migrateToWallet(); 00489 } 00490 00491 void TransportManagerPrivate::writeConfig() 00492 { 00493 KConfigGroup group( config, "General" ); 00494 group.writeEntry( "default-transport", defaultTransportId ); 00495 config->sync(); 00496 q->emitChangesCommitted(); 00497 } 00498 00499 void TransportManagerPrivate::fillTypes() 00500 { 00501 Q_ASSERT( types.isEmpty() ); 00502 00503 // SMTP. 00504 { 00505 TransportType type; 00506 type.d->mType = Transport::EnumType::SMTP; 00507 type.d->mName = i18nc( "@option SMTP transport", "SMTP" ); 00508 type.d->mDescription = i18n( "An SMTP server on the Internet" ); 00509 types << type; 00510 } 00511 00512 // Sendmail. 00513 { 00514 TransportType type; 00515 type.d->mType = Transport::EnumType::Sendmail; 00516 type.d->mName = i18nc( "@option sendmail transport", "Sendmail" ); 00517 type.d->mDescription = i18n( "A local sendmail installation" ); 00518 types << type; 00519 } 00520 00521 // All Akonadi resources with MailTransport capability. 00522 { 00523 using namespace Akonadi; 00524 foreach ( const AgentType &atype, AgentManager::self()->types() ) { 00525 // TODO probably the string "MailTransport" should be #defined somewhere 00526 // and used like that in the resources (?) 00527 if( atype.capabilities().contains( QLatin1String( "MailTransport" ) ) ) { 00528 TransportType type; 00529 type.d->mType = Transport::EnumType::Akonadi; 00530 type.d->mAgentType = atype; 00531 type.d->mName = atype.name(); 00532 type.d->mDescription = atype.description(); 00533 types << type; 00534 kDebug() << "Found Akonadi type" << atype.name(); 00535 } 00536 } 00537 00538 // Watch for appearing and disappearing types. 00539 QObject::connect( AgentManager::self(), SIGNAL(typeAdded(Akonadi::AgentType)), 00540 q, SLOT(agentTypeAdded(Akonadi::AgentType)) ); 00541 QObject::connect( AgentManager::self(), SIGNAL(typeRemoved(Akonadi::AgentType)), 00542 q, SLOT(agentTypeRemoved(Akonadi::AgentType)) ); 00543 } 00544 00545 kDebug() << "Have SMTP, Sendmail, and" << types.count() - 2 << "Akonadi types."; 00546 } 00547 00548 void TransportManager::emitChangesCommitted() 00549 { 00550 d->myOwnChange = true; // prevent us from reading our changes again 00551 d->appliedChange = false; // but we have to read them at least once 00552 emit transportsChanged(); 00553 emit changesCommitted(); 00554 } 00555 00556 void TransportManagerPrivate::slotTransportsChanged() 00557 { 00558 if ( myOwnChange && appliedChange ) { 00559 myOwnChange = false; 00560 appliedChange = false; 00561 return; 00562 } 00563 00564 kDebug(); 00565 config->reparseConfiguration(); 00566 // FIXME: this deletes existing transport objects! 00567 readConfig(); 00568 appliedChange = true; // to prevent recursion 00569 emit q->transportsChanged(); 00570 } 00571 00572 int TransportManagerPrivate::createId() const 00573 { 00574 QList<int> usedIds; 00575 foreach ( Transport *t, transports ) { 00576 usedIds << t->id(); 00577 } 00578 usedIds << 0; // 0 is default for unknown 00579 int newId; 00580 do { 00581 newId = KRandom::random(); 00582 } while ( usedIds.contains( newId ) ); 00583 return newId; 00584 } 00585 00586 KWallet::Wallet * TransportManager::wallet() 00587 { 00588 if ( d->wallet && d->wallet->isOpen() ) { 00589 return d->wallet; 00590 } 00591 00592 if ( !Wallet::isEnabled() || d->walletOpenFailed ) { 00593 return 0; 00594 } 00595 00596 WId window = 0; 00597 if ( qApp->activeWindow() ) { 00598 window = qApp->activeWindow()->winId(); 00599 } else if ( !QApplication::topLevelWidgets().isEmpty() ) { 00600 window = qApp->topLevelWidgets().first()->winId(); 00601 } 00602 00603 delete d->wallet; 00604 d->wallet = Wallet::openWallet( Wallet::NetworkWallet(), window ); 00605 00606 if ( !d->wallet ) { 00607 d->walletOpenFailed = true; 00608 return 0; 00609 } 00610 00611 d->prepareWallet(); 00612 return d->wallet; 00613 } 00614 00615 void TransportManagerPrivate::prepareWallet() 00616 { 00617 if ( !wallet ) { 00618 return; 00619 } 00620 if ( !wallet->hasFolder( WALLET_FOLDER ) ) { 00621 wallet->createFolder( WALLET_FOLDER ); 00622 } 00623 wallet->setFolder( WALLET_FOLDER ); 00624 } 00625 00626 void TransportManager::loadPasswords() 00627 { 00628 foreach ( Transport *t, d->transports ) { 00629 t->readPassword(); 00630 } 00631 00632 // flush the wallet queue 00633 const QList<TransportJob*> copy = d->walletQueue; 00634 d->walletQueue.clear(); 00635 foreach ( TransportJob *job, copy ) { 00636 job->start(); 00637 } 00638 00639 emit passwordsChanged(); 00640 } 00641 00642 void TransportManager::loadPasswordsAsync() 00643 { 00644 kDebug(); 00645 00646 // check if there is anything to do at all 00647 bool found = false; 00648 foreach ( Transport *t, d->transports ) { 00649 if ( !t->isComplete() ) { 00650 found = true; 00651 break; 00652 } 00653 } 00654 if ( !found ) { 00655 return; 00656 } 00657 00658 // async wallet opening 00659 if ( !d->wallet && !d->walletOpenFailed ) { 00660 WId window = 0; 00661 if ( qApp->activeWindow() ) { 00662 window = qApp->activeWindow()->winId(); 00663 } else if ( !QApplication::topLevelWidgets().isEmpty() ) { 00664 window = qApp->topLevelWidgets().first()->winId(); 00665 } 00666 00667 d->wallet = Wallet::openWallet( Wallet::NetworkWallet(), window, 00668 Wallet::Asynchronous ); 00669 if ( d->wallet ) { 00670 connect( d->wallet, SIGNAL(walletOpened(bool)), SLOT(slotWalletOpened(bool)) ); 00671 d->walletAsyncOpen = true; 00672 } else { 00673 d->walletOpenFailed = true; 00674 loadPasswords(); 00675 } 00676 return; 00677 } 00678 if ( d->wallet && !d->walletAsyncOpen ) { 00679 loadPasswords(); 00680 } 00681 } 00682 00683 void TransportManagerPrivate::slotWalletOpened( bool success ) 00684 { 00685 kDebug(); 00686 walletAsyncOpen = false; 00687 if ( !success ) { 00688 walletOpenFailed = true; 00689 delete wallet; 00690 wallet = 0; 00691 } else { 00692 prepareWallet(); 00693 } 00694 q->loadPasswords(); 00695 } 00696 00697 void TransportManagerPrivate::validateDefault() 00698 { 00699 if ( !q->transportById( defaultTransportId, false ) ) { 00700 if ( q->isEmpty() ) { 00701 defaultTransportId = -1; 00702 } else { 00703 defaultTransportId = transports.first()->id(); 00704 writeConfig(); 00705 } 00706 } 00707 } 00708 00709 void TransportManagerPrivate::migrateToWallet() 00710 { 00711 // check if we tried this already 00712 static bool firstRun = true; 00713 if ( !firstRun ) { 00714 return; 00715 } 00716 firstRun = false; 00717 00718 // check if we are the main instance 00719 if ( !isMainInstance ) { 00720 return; 00721 } 00722 00723 // check if migration is needed 00724 QStringList names; 00725 foreach ( Transport *t, transports ) { 00726 if ( t->needsWalletMigration() ) { 00727 names << t->name(); 00728 } 00729 } 00730 if ( names.isEmpty() ) { 00731 return; 00732 } 00733 00734 // ask user if he wants to migrate 00735 int result = KMessageBox::questionYesNoList( 00736 0, 00737 i18n( "The following mail transports store their passwords in an " 00738 "unencrypted configuration file.\nFor security reasons, " 00739 "please consider migrating these passwords to KWallet, the " 00740 "KDE Wallet management tool,\nwhich stores sensitive data " 00741 "for you in a strongly encrypted file.\n" 00742 "Do you want to migrate your passwords to KWallet?" ), 00743 names, i18n( "Question" ), 00744 KGuiItem( i18n( "Migrate" ) ), KGuiItem( i18n( "Keep" ) ), 00745 QString::fromAscii( "WalletMigrate" ) ); 00746 if ( result != KMessageBox::Yes ) { 00747 return; 00748 } 00749 00750 // perform migration 00751 foreach ( Transport *t, transports ) { 00752 if ( t->needsWalletMigration() ) { 00753 t->migrateToWallet(); 00754 } 00755 } 00756 } 00757 00758 void TransportManagerPrivate::dbusServiceUnregistered() 00759 { 00760 QDBusConnection::sessionBus().registerService( DBUS_SERVICE_NAME ); 00761 } 00762 00763 void TransportManagerPrivate::agentTypeAdded( const Akonadi::AgentType &atype ) 00764 { 00765 using namespace Akonadi; 00766 if( atype.capabilities().contains( QLatin1String( "MailTransport" ) ) ) { 00767 TransportType type; 00768 type.d->mType = Transport::EnumType::Akonadi; 00769 type.d->mAgentType = atype; 00770 type.d->mName = atype.name(); 00771 type.d->mDescription = atype.description(); 00772 types << type; 00773 kDebug() << "Added new Akonadi type" << atype.name(); 00774 } 00775 } 00776 00777 void TransportManagerPrivate::agentTypeRemoved( const Akonadi::AgentType &atype ) 00778 { 00779 using namespace Akonadi; 00780 foreach ( const TransportType &type, types ) { 00781 if( type.type() == Transport::EnumType::Akonadi && 00782 type.agentType() == atype ) { 00783 types.removeAll( type ); 00784 kDebug() << "Removed Akonadi type" << atype.name(); 00785 } 00786 } 00787 } 00788 00789 void TransportManagerPrivate::jobResult( KJob *job ) 00790 { 00791 walletQueue.removeAll( static_cast<TransportJob*>( job ) ); 00792 } 00793 00794 #include "transportmanager.moc"