diff --git a/mailtransport/CMakeLists.txt b/mailtransport/CMakeLists.txt index 0c18fdda5..b647c5af0 100644 --- a/mailtransport/CMakeLists.txt +++ b/mailtransport/CMakeLists.txt @@ -1,79 +1,75 @@ - add_subdirectory( kconf_update ) add_subdirectory( tests ) add_definitions("-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII") add_definitions( -DKDE_DEFAULT_DEBUG_AREA=5324 ) set(mailtransport_lib_srcs transport.cpp transportmanager.cpp - transporttypeinfo.cpp + transporttype.cpp transportcombobox.cpp transportlistview.cpp transportmanagementwidget.cpp - addtransportassistant.cpp + addtransportdialog.cpp transportconfigdialog.cpp transportconfigwidget.cpp - akonadiconfigwidget.cpp sendmailconfigwidget.cpp smtpconfigwidget.cpp transportjob.cpp akonadijob.cpp sendmailjob.cpp smtpjob.cpp precommandjob.cpp legacydecrypt.cpp socket.cpp servertest.cpp ) kde4_add_ui_files(mailtransport_lib_srcs - addtransportassistanttypepage.ui - addtransportassistantnamepage.ui - - akonadisettings.ui sendmailsettings.ui smtpsettings.ui + addtransportdialog.ui transportmanagementwidget.ui ) kde4_add_kcfg_files(mailtransport_lib_srcs transportbase.kcfgc) kde4_add_library(mailtransport SHARED ${mailtransport_lib_srcs}) target_link_libraries(mailtransport ${KDE4_KIO_LIBS} akonadi-kde) set_target_properties(mailtransport PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) install(TARGETS mailtransport EXPORT kdepimlibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES mailtransport.kcfg DESTINATION ${KCFG_INSTALL_DIR}) set(mailtransport_kcm_srcs configmodule.cpp) kde4_add_plugin(kcm_mailtransport ${mailtransport_kcm_srcs}) target_link_libraries(kcm_mailtransport ${KDE4_KDEUI_LIBS} mailtransport) install(TARGETS kcm_mailtransport DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES kcm_mailtransport.desktop DESTINATION ${SERVICES_INSTALL_DIR}) install( FILES mailtransport_export.h transportjob.h akonadijob.h sendmailjob.h smtpjob.h ${CMAKE_CURRENT_BINARY_DIR}/transportbase.h transport.h transportmanager.h + transporttype.h servertest.h transportcombobox.h transportconfigdialog.h transportmanagementwidget.h DESTINATION ${INCLUDE_INSTALL_DIR}/mailtransport COMPONENT Devel) diff --git a/mailtransport/TODO.cberzan b/mailtransport/TODO.cberzan index d5c4cc074..4c0d501c7 100644 --- a/mailtransport/TODO.cberzan +++ b/mailtransport/TODO.cberzan @@ -1,12 +1,12 @@ -* TransportConfigDialog needs validate() * all CamelCase... * smtpsettings.ui has hidden widgets... test those... and why can't I set/see the 'visible' property in designer? * why is identitylistview in kmail instead of kpimidentities? * figure out what needs to be exported and what not (add .hs to CMakeLists afterwards) * include KLocale or KLocalizedString?? - -Design: -* is there a way to make KConfig XT give me separate settings for SMTP, Sendmail, Akonadi? Currently all of the settings are for SMTP, and Sendmail and Akonadi just use the 'host' setting for storing the sendmail path or Akonadi resource id, respectively. +* SMTPJob (and probably others) give empty errorString when killed Bugs: * modify -> change password -> ok. password is saved in wallet and seen ok on restart, but clicking modify again shows old password +* Type=Akonadi and Type=Sendmail appear in the config file, but no Type=SMTP (probably because SMTP == 0 == default) +* cancel doesn't work in transportmgr, apparently + diff --git a/mailtransport/addtransportassistant.cpp b/mailtransport/addtransportassistant.cpp deleted file mode 100644 index e3c4ca14b..000000000 --- a/mailtransport/addtransportassistant.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - Copyright (c) 2009 Constantin Berzan - - Based on code from Kopete (addaccountwizard) - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "addtransportassistant.h" - -#include "transport.h" -#include "transportconfigwidget.h" -#include "transportmanager.h" -#include "transporttypeinfo.h" - -#include -#include -#include -#include - -#include "ui_addtransportassistanttypepage.h" -#include "ui_addtransportassistantnamepage.h" - - -using namespace MailTransport; - - -/** - @internal -*/ -class AddTransportAssistant::Private -{ - public: - Private() - : typePage( 0 ) - , configPage( 0 ) - , namePage( 0 ) - , configPageContents( 0 ) - , transport( 0 ) - , lastType( -1 ) - { - } - - QTreeWidgetItem* selectedType(); - - KPageWidgetItem *typeItem; - KPageWidgetItem *configItem; - KPageWidgetItem *nameItem; - QWidget *typePage; - KVBox *configPage; - QWidget *namePage; - TransportConfigWidget *configPageContents; - Transport *transport; - int lastType; - Ui::AddTransportAssistantTypePage uiTypePage; - Ui::AddTransportAssistantNamePage uiNamePage; - -}; - -AddTransportAssistant::AddTransportAssistant( QWidget *parent ) - : KAssistantDialog( parent ) - , d( new Private ) -{ - d->transport = TransportManager::self()->createTransport(); - Q_ASSERT( d->transport ); - - // type page - d->typePage = new QWidget( this ); - d->uiTypePage.setupUi( d->typePage ); - d->uiTypePage.typeListView->setColumnCount( 2 ); - QStringList header; - header << i18n( "Type" ) << i18n( "Description" ); - d->uiTypePage.typeListView->setHeaderLabels( header ); - - d->typeItem = addPage( d->typePage, d->typePage->windowTitle() ); - setValid( d->typeItem, false ); - - // populate type list - for( int i = 0; i < TransportTypeInfo::typeCount(); i++ ) { - QTreeWidgetItem *treeItem = new QTreeWidgetItem( d->uiTypePage.typeListView ); - treeItem->setData( 0, Qt::UserRole, i ); // the transport type - treeItem->setText( 0, TransportTypeInfo::nameForType( i ) ); - treeItem->setText( 1, TransportTypeInfo::descriptionForType( i ) ); - } - d->uiTypePage.typeListView->resizeColumnToContents( 0 ); - d->uiTypePage.typeListView->setFocus(); - - // connect user input - connect( d->uiTypePage.typeListView, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), - this, SLOT( typeListClicked() ) ); - connect( d->uiTypePage.typeListView, SIGNAL( itemSelectionChanged() ), - this, SLOT( typeListClicked() ) ); - connect( d->uiTypePage.typeListView, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ), - this, SLOT( typeListDoubleClicked() ) ); - - // settings page - d->configPage = new KVBox( this ); - d->configItem = addPage( d->configPage, i18n( "Step Two: Transport Settings" ) ); - - // name page - d->namePage = new QWidget( this ); - d->uiNamePage.setupUi( d->namePage ); - // TODO set up sensible default name - d->nameItem = addPage( d->namePage, d->namePage->windowTitle() ); -} - -QTreeWidgetItem* AddTransportAssistant::Private::selectedType() -{ - QList sel = uiTypePage.typeListView->selectedItems(); - if( !sel.empty() ) - return sel.first(); - return 0; -} - -void AddTransportAssistant::typeListClicked() -{ - // Make sure a type is selected before allowing the user to continue. - setValid( d->typeItem, d->selectedType() != 0 ); -} - -void AddTransportAssistant::typeListDoubleClicked() -{ - // Proceed to the next page if a type is double clicked. - next(); -} - -void AddTransportAssistant::accept() -{ - // register transport - d->configPageContents->apply(); - TransportManager::self()->addTransport( d->transport ); - d->transport = 0; // don't delete it - if( d->uiNamePage.setDefault->isChecked() ) { - TransportManager::self()->setDefaultTransport( d->transport->id() ); - } - KAssistantDialog::accept(); -} - -void AddTransportAssistant::next() -{ - if( currentPage() == d->typeItem ) { - QTreeWidgetItem *item = d->selectedType(); - int type = item->data( 0, Qt::UserRole ).toInt(); // the transport type - Q_ASSERT( type >= 0 && type < TransportBase::EnumType::COUNT ); - - // create appropriate config widget - if( d->configPageContents && d->lastType == type ) { - // same type as before; keep settings - } else { - d->transport->setType( type ); - d->lastType = type; - delete d->configPageContents; - d->configPageContents = TransportTypeInfo::configWidgetForTransport( d->transport, d->configPage ); - - // let the configWidget's KConfigDialogManager handle kcfg_name: - KConfigDialogManager *mgr = d->configPageContents->configManager(); - Q_ASSERT( mgr ); - Q_ASSERT( d->namePage ); - mgr->addWidget( d->namePage ); - } - } - - KAssistantDialog::next(); -} - -void AddTransportAssistant::reject() -{ - delete d->transport; - d->transport = 0; - KAssistantDialog::reject(); -} - -AddTransportAssistant::~AddTransportAssistant() -{ - delete d->transport; - delete d; -} - - -#include "addtransportassistant.moc" - diff --git a/mailtransport/addtransportassistanttypepage.ui b/mailtransport/addtransportassistanttypepage.ui deleted file mode 100644 index f1401901a..000000000 --- a/mailtransport/addtransportassistanttypepage.ui +++ /dev/null @@ -1,62 +0,0 @@ - - - AddTransportAssistantTypePage - - - - 0 - 0 - 482 - 353 - - - - - 0 - 0 - - - - Step One: Select Transport Type - - - - - - - 0 - 0 - - - - <h2>Welcome to the Add Transport Assistant</h2> -<p>Select the transport type from the list below.</p> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - - - - - true - - - false - - - - 1 - - - - - - - - - diff --git a/mailtransport/addtransportdialog.cpp b/mailtransport/addtransportdialog.cpp new file mode 100644 index 000000000..a79b1f0ef --- /dev/null +++ b/mailtransport/addtransportdialog.cpp @@ -0,0 +1,144 @@ +/* + Copyright (c) 2009 Constantin Berzan + + Based on code from Kopete (addaccountwizard) + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "addtransportdialog.h" +#include "transport.h" +#include "transportconfigwidget.h" +#include "transportmanager.h" +#include "transporttype.h" +#include "ui_addtransportdialog.h" + +#include +#include +#include + +#include +#include + +using namespace MailTransport; + +/** + @internal +*/ +class AddTransportDialog::Private +{ + public: + Private( AddTransportDialog *qq ) + : q( qq ) + { + } + + TransportType selectedType() const; + + // slots + void typeListClicked(); + + AddTransportDialog *const q; + Ui::AddTransportDialog ui; +}; + +TransportType AddTransportDialog::Private::selectedType() const +{ + QList sel = ui.typeListView->selectedItems(); + if( !sel.empty() ) { + return sel.first()->data( 0, Qt::UserRole ).value(); + } + return TransportType(); +} + +void AddTransportDialog::Private::typeListClicked() +{ + // Make sure a type is selected before allowing the user to continue. + q->enableButtonOk( selectedType().isValid() ); +} + + + +AddTransportDialog::AddTransportDialog( QWidget *parent ) + : KDialog( parent ) + , d( new Private( this ) ) +{ + // Setup UI. + { + QWidget *widget = new QWidget( this ); + d->ui.setupUi( widget ); + setMainWidget( widget ); + setCaption( i18n( "Create Outgoing Account" ) ); + setButtons( Ok|Cancel ); + enableButtonOk( false ); + setButtonText( Ok, i18nc( "create and configure a mail transport", "Create and Configure" ) ); + } + + // Populate type list. + foreach( const TransportType &type, TransportManager::self()->types() ) { + QTreeWidgetItem *treeItem = new QTreeWidgetItem( d->ui.typeListView ); + treeItem->setText( 0, type.name() ); + treeItem->setText( 1, type.description() ); + treeItem->setData( 0, Qt::UserRole, QVariant::fromValue( type ) ); // the transport type + } + d->ui.typeListView->resizeColumnToContents( 0 ); + updateGeometry(); + d->ui.typeListView->setFocus(); + + // Connect user input. + connect( d->ui.typeListView, SIGNAL(itemClicked(QTreeWidgetItem*,int)), + this, SLOT(typeListClicked()) ); + connect( d->ui.typeListView, SIGNAL(itemSelectionChanged()), + this, SLOT(typeListClicked()) ); +} + +AddTransportDialog::~AddTransportDialog() +{ +} + +void AddTransportDialog::accept() +{ + if( !d->selectedType().isValid() ) { + return; + } + + // Create a new transport and configure it. + Transport *transport = TransportManager::self()->createTransport(); + transport->setTransportType( d->selectedType() ); + if( d->selectedType().type() == Transport::EnumType::Akonadi ) { + // Create a resource instance if Akonadi-type transport. + using namespace Akonadi; + AgentInstanceCreateJob *cjob = new AgentInstanceCreateJob( d->selectedType().agentType() ); + if( !cjob->exec() ) { + kWarning() << "Failed to create agent instance of type" + << d->selectedType().agentType().identifier(); + return; + } + transport->setHost( cjob->instance().identifier() ); + } + transport->setName( d->ui.name->text() ); + transport->forceUniqueName(); + if( TransportManager::self()->configureTransport( transport, this ) ) { + // The user clicked OK and the transport settings were saved. + TransportManager::self()->addTransport( transport ); + if( d->ui.setDefault->isChecked() ) { + TransportManager::self()->setDefaultTransport( transport->id() ); + } + KDialog::accept(); + } +} + +#include "addtransportdialog.moc" diff --git a/mailtransport/addtransportassistant.h b/mailtransport/addtransportdialog.h similarity index 63% rename from mailtransport/addtransportassistant.h rename to mailtransport/addtransportdialog.h index 57a12e087..f21c87bf0 100644 --- a/mailtransport/addtransportassistant.h +++ b/mailtransport/addtransportdialog.h @@ -1,66 +1,57 @@ /* Copyright (c) 2009 Constantin Berzan - Based on code from Kopete (addaccountwizard) - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef MAILTRANSPORT_ADDTRANSPORTASSISTANT_H -#define MAILTRANSPORT_ADDTRANSPORTASSISTANT_H +#ifndef MAILTRANSPORT_ADDTRANSPORTDIALOG_H +#define MAILTRANSPORT_ADDTRANSPORTDIALOG_H #include -#include - - -namespace MailTransport -{ +#include +namespace MailTransport { /** - Assistant to help the user set up a new transport. + A dialog for creating a new transport. It asks the user for the transport + type and name, and then proceeds to configure the new transport. */ -class MAILTRANSPORT_EXPORT AddTransportAssistant : public KAssistantDialog +class AddTransportDialog : public KDialog { Q_OBJECT public: - // TODO docu - explicit AddTransportAssistant( QWidget *parent = 0 ); - ~AddTransportAssistant(); - -private slots: - void typeListClicked(); - void typeListDoubleClicked(); + explicit AddTransportDialog( QWidget *parent = 0 ); + virtual ~AddTransportDialog(); -protected slots: + /* reimpl */ virtual void accept(); - virtual void next(); - virtual void reject(); private: class Private; - Private * const d; + Private *const d; + + Q_PRIVATE_SLOT( d, void typeListClicked() ) }; } #endif diff --git a/mailtransport/addtransportassistantnamepage.ui b/mailtransport/addtransportdialog.ui similarity index 58% rename from mailtransport/addtransportassistantnamepage.ui rename to mailtransport/addtransportdialog.ui index 1abc2b0ea..0f5761712 100644 --- a/mailtransport/addtransportassistantnamepage.ui +++ b/mailtransport/addtransportdialog.ui @@ -1,71 +1,90 @@ - AddTransportAssistantNamePage - + AddTransportDialog + 0 0 482 353 0 0 - Final Step: Choose Transport Name + Step One: Select Transport Type - + - + 0 0 - <h2>Congratulations</h2> -<p>You have finished configuring your mail transport. Please specify a name for it below, and click the Finish button.</p> + Select an account type from the list below: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true - + + + + true + + + false + + + + Type + + + + + Description + + + + + Name: - - - + + + - Make this the default mail transport. + Make this the default outgoing account. KLineEdit QLineEdit
klineedit.h
diff --git a/mailtransport/akonadiconfigwidget.cpp b/mailtransport/akonadiconfigwidget.cpp deleted file mode 100644 index b196cb2c2..000000000 --- a/mailtransport/akonadiconfigwidget.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2009 Constantin Berzan - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "akonadiconfigwidget.h" -#include "transportconfigwidget_p.h" -#include "ui_akonadisettings.h" - -#include - -#include -#include - -using namespace Akonadi; -using namespace MailTransport; - - -class MailTransport::AkonadiConfigWidgetPrivate : public TransportConfigWidgetPrivate -{ - public: - Ui::AkonadiSettings ui; - -}; - -AkonadiConfigWidget::AkonadiConfigWidget( Transport *transport, QWidget *parent ) - : TransportConfigWidget( *new AkonadiConfigWidgetPrivate, transport, parent ) -{ - init(); -} - -AkonadiConfigWidget::AkonadiConfigWidget( AkonadiConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ) - : TransportConfigWidget( dd, transport, parent ) -{ - init(); -} - -void AkonadiConfigWidget::init() -{ - Q_D( AkonadiConfigWidget ); - - d->ui.setupUi( this ); - // The KConfigDialogManager is useless here, it doesn't handle the Akonadi::AgentInstanceWidget - //d->manager->addWidget( this ); // otherwise it doesn't find out about these widgets - //d->manager->updateWidgets(); - - d->ui.agentInstances->agentFilterProxyModel()->addCapabilityFilter( QLatin1String( "MailTransport" ) ); -} - -void AkonadiConfigWidget::apply() -{ - Q_D( AkonadiConfigWidget ); - - const AgentInstance instance = d->ui.agentInstances->currentAgentInstance(); - if( instance.isValid() ) { - d->transport->setHost( instance.identifier() ); - } - - TransportConfigWidget::apply(); -} - - -#include "akonadiconfigwidget.moc" diff --git a/mailtransport/akonadisettings.ui b/mailtransport/akonadisettings.ui deleted file mode 100644 index 450bd9215..000000000 --- a/mailtransport/akonadisettings.ui +++ /dev/null @@ -1,40 +0,0 @@ - - - Volker Krause <vkrause@kde.org> - AkonadiSettings - - - - 0 - 0 - 383 - 315 - - - - - - - Please choose the Akonadi resource which will be used to send messages: - - - false - - - - - - - - - - - Akonadi::AgentInstanceWidget - QWidget -
akonadi/agentinstancewidget.h
- 1 -
-
- - -
diff --git a/mailtransport/mailtransport_export.h b/mailtransport/mailtransport_export.h index 83968b468..cfd80d55e 100644 --- a/mailtransport/mailtransport_export.h +++ b/mailtransport/mailtransport_export.h @@ -1,35 +1,39 @@ /* Copyright (c) 2006 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILTRANSPORT_MAILTRANSPORT_EXPORT_H #define MAILTRANSPORT_MAILTRANSPORT_EXPORT_H #include #ifndef MAILTRANSPORT_EXPORT # if defined(MAKE_MAILTRANSPORT_LIB) /* We are building this library */ # define MAILTRANSPORT_EXPORT KDE_EXPORT # else /* We are using this library */ # define MAILTRANSPORT_EXPORT KDE_IMPORT # endif #endif +#ifndef MAILTRANSPORT_EXPORT_DEPRECATED +# define MAILTRANSPORT_EXPORT_DEPRECATED KDE_DEPRECATED MAILTRANSPORT_EXPORT +#endif + #endif diff --git a/mailtransport/transport.cpp b/mailtransport/transport.cpp index 1b902c4c3..871783ae0 100644 --- a/mailtransport/transport.cpp +++ b/mailtransport/transport.cpp @@ -1,292 +1,337 @@ /* Copyright (c) 2006 - 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transport.h" -#include "transportmanager.h" -#include "mailtransport_defs.h" #include "legacydecrypt.h" +#include "mailtransport_defs.h" +#include "transportmanager.h" +#include "transporttype_p.h" #include #include #include #include #include #include #include +#include +#include + using namespace MailTransport; using namespace KWallet; /** * Private class that helps to provide binary compatibility between releases. * @internal */ class TransportPrivate { public: + TransportType transportType; QString password; bool passwordLoaded; bool passwordDirty; bool storePasswordInFile; bool needsWalletMigration; QString oldName; }; Transport::Transport( const QString &cfgGroup ) : TransportBase( cfgGroup ), d( new TransportPrivate ) { kDebug() << cfgGroup; d->passwordLoaded = false; d->passwordDirty = false; d->storePasswordInFile = false; d->needsWalletMigration = false; readConfig(); } Transport::~Transport() { delete d; } bool Transport::isValid() const { return ( id() > 0 ) && !host().isEmpty() && port() <= 65536; } QString Transport::password() { if ( !d->passwordLoaded && requiresAuthentication() && storePassword() && d->password.isEmpty() ) { TransportManager::self()->loadPasswords(); d->password = TransportManager::self()->transportById( id(), false )->password(); } return d->password; } void Transport::setPassword( const QString &passwd ) { d->passwordLoaded = true; if ( d->password == passwd ) { return; } d->passwordDirty = true; d->password = passwd; } void Transport::forceUniqueName() { QStringList existingNames; foreach ( Transport *t, TransportManager::self()->transports() ) { if ( t->id() != id() ) { existingNames << t->name(); } } int suffix = 1; QString origName = name(); while ( existingNames.contains( name() ) ) { setName( i18nc( "%1: name; %2: number appended to it to make " "it unique among a list of names", "%1 #%2", origName, suffix ) ); ++suffix; } } void Transport::updatePasswordState() { Transport *original = TransportManager::self()->transportById( id(), false ); if ( original == this ) { kWarning() << "Tried to update password state of non-cloned transport."; return; } if ( original ) { d->password = original->d->password; d->passwordLoaded = original->d->passwordLoaded; d->passwordDirty = original->d->passwordDirty; } else { kWarning() << "Transport with this ID not managed by transport manager."; } } bool Transport::isComplete() const { return !requiresAuthentication() || !storePassword() || d->passwordLoaded; } QString Transport::authenticationTypeString() const { switch ( authenticationType() ) { case EnumAuthenticationType::LOGIN: return QLatin1String( "LOGIN" ); case EnumAuthenticationType::PLAIN: return QLatin1String( "PLAIN" ); case EnumAuthenticationType::CRAM_MD5: return QLatin1String( "CRAM-MD5" ); case EnumAuthenticationType::DIGEST_MD5: return QLatin1String( "DIGEST-MD5" ); case EnumAuthenticationType::NTLM: return QLatin1String( "NTLM" ); case EnumAuthenticationType::GSSAPI: return QLatin1String( "GSSAPI" ); } Q_ASSERT( false ); return QString(); } void Transport::usrReadConfig() { TransportBase::usrReadConfig(); setHost( host().trimmed() ); if ( d->oldName.isEmpty() ) { d->oldName = name(); } + // Set TransportType. + { + using namespace Akonadi; + d->transportType = TransportType(); + d->transportType.d->mType = type(); + kDebug() << "type" << type(); + if( type() == EnumType::Akonadi ) { + const AgentInstance instance = AgentManager::self()->instance( host() ); + if( !instance.isValid() ) { + kWarning() << "Akonadi transport with invalid resource instance."; + } + d->transportType.d->mAgentType = instance.type(); + kDebug() << "agent type" << instance.type().name() << "id" << instance.type().identifier(); + } + // Now we have the type and possibly agentType. Get the name, description + // etc. from TransportManager. + const TransportType::List &types = TransportManager::self()->types(); + int index = types.indexOf( d->transportType ); + if( index != -1 ) { + d->transportType = types[ index ]; + } else { + kWarning() << "Type unknown to manager."; + } + } + // we have everything we need if ( !storePassword() || d->passwordLoaded ) { return; } // try to find a password in the config file otherwise KConfigGroup group( config(), currentGroup() ); if ( group.hasKey( "password" ) ) { d->password = KStringHandler::obscure( group.readEntry( "password" ) ); } else if ( group.hasKey( "password-kmail" ) ) { d->password = Legacy::decryptKMail( group.readEntry( "password-kmail" ) ); } else if ( group.hasKey( "password-knode" ) ) { d->password = Legacy::decryptKNode( group.readEntry( "password-knode" ) ); } if ( !d->password.isEmpty() ) { d->passwordLoaded = true; if ( Wallet::isEnabled() ) { d->needsWalletMigration = true; } else { d->storePasswordInFile = true; } } else { // read password if wallet is open, defer otherwise if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) { // Don't read the password right away because this can lead // to reentrancy problems in KDBusServiceStarter when an application // run in Kontact creates the transports (due to a QEventLoop in the // synchronous KWallet openWallet call). QTimer::singleShot( 0, this, SLOT(readPassword()) ); } } } void Transport::usrWriteConfig() { if ( requiresAuthentication() && storePassword() && d->passwordDirty ) { Wallet *wallet = TransportManager::self()->wallet(); if ( !wallet || wallet->writePassword( QString::number( id() ), d->password ) != 0 ) { // wallet saving failed, ask if we should store in the config file instead if ( d->storePasswordInFile || KMessageBox::warningYesNo( 0, i18n( "KWallet is not available. It is strongly recommended to use " "KWallet for managing your passwords.\n" "However, the password can be stored in the configuration " "file instead. The password is stored in an obfuscated format, " "but should not be considered secure from decryption efforts " "if access to the configuration file is obtained.\n" "Do you want to store the password for server '%1' in the " "configuration file?", name() ), i18n( "KWallet Not Available" ), KGuiItem( i18n( "Store Password" ) ), KGuiItem( i18n( "Do Not Store Password" ) ) ) == KMessageBox::Yes ) { // write to config file KConfigGroup group( config(), currentGroup() ); group.writeEntry( "password", KStringHandler::obscure( d->password ) ); d->storePasswordInFile = true; } } d->passwordDirty = false; } TransportBase::usrWriteConfig(); TransportManager::self()->emitChangesCommitted(); if ( name() != d->oldName ) { emit TransportManager::self()->transportRenamed( id(), d->oldName, name() ); d->oldName = name(); } } void Transport::readPassword() { // no need to load a password if the account doesn't require auth if ( !requiresAuthentication() ) { return; } d->passwordLoaded = true; // check whether there is a chance to find our password at all if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER ) || Wallet::keyDoesNotExist( Wallet::NetworkWallet(), WALLET_FOLDER, QString::number( id() ) ) ) { // try migrating password from kmail if ( Wallet::folderDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER ) || Wallet::keyDoesNotExist( Wallet::NetworkWallet(), KMAIL_WALLET_FOLDER, QString::fromLatin1( "transport-%1" ).arg( id() ) ) ) { return; } kDebug() << "migrating password from kmail wallet"; KWallet::Wallet *wallet = TransportManager::self()->wallet(); if ( wallet ) { wallet->setFolder( KMAIL_WALLET_FOLDER ); wallet->readPassword( QString::fromLatin1( "transport-%1" ).arg( id() ), d->password ); wallet->removeEntry( QString::fromLatin1( "transport-%1" ).arg( id() ) ); wallet->setFolder( WALLET_FOLDER ); d->passwordDirty = true; writeConfig(); } return; } // finally try to open the wallet and read the password KWallet::Wallet *wallet = TransportManager::self()->wallet(); if ( wallet ) { wallet->readPassword( QString::number( id() ), d->password ); } } bool Transport::needsWalletMigration() const { return d->needsWalletMigration; } void Transport::migrateToWallet() { kDebug() << "migrating" << id() << "to wallet"; d->needsWalletMigration = false; KConfigGroup group( config(), currentGroup() ); group.deleteEntry( "password" ); d->passwordDirty = true; d->storePasswordInFile = false; writeConfig(); } Transport *Transport::clone() const { QString id = currentGroup().mid( 10 ); return new Transport( id ); } +TransportType Transport::transportType() const +{ + if( !d->transportType.isValid() ) { + kWarning() << "Invalid transport type."; + } + return d->transportType; +} + +void Transport::setTransportType( const TransportType &type ) +{ + Q_ASSERT( type.isValid() ); + d->transportType = type; + setType( type.type() ); +} + #include "transport.moc" diff --git a/mailtransport/transport.h b/mailtransport/transport.h index 8d6c2b30c..41e62849d 100644 --- a/mailtransport/transport.h +++ b/mailtransport/transport.h @@ -1,133 +1,154 @@ /* Copyright (c) 2006 - 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILTRANSPORT_TRANSPORT_H #define MAILTRANSPORT_TRANSPORT_H -#include #include +#include +#include class TransportPrivate; namespace MailTransport { +class TransportType; + /** Represents the settings of a specific mail transport. To create a new empty Transport object, use TransportManager::createTransport(). */ +// TODO KDE5: Do something about the kcfg-generated TransportBase. +// Currently it has the config stuff as private members, which means it is +// utterly inextensible. Also the sendmail and akonadi-type transports use +// the "host" setting for keeping the location of the sendmail executable and +// the resource id, respectively. This is a hack; they should have separate +// config options... (cberzan) class MAILTRANSPORT_EXPORT Transport : public TransportBase { Q_OBJECT friend class TransportManager; public: - /** - Destructor - */ + /** + Destructor + */ virtual ~Transport(); typedef QList List; /** Returns true if this transport is valid, ie. has all necessary data set. */ bool isValid() const; /** Returns the password of this transport. */ QString password(); /** Sets the password of this transport. @param passwd The new password. */ void setPassword( const QString &passwd ); /** Makes sure the transport has a unique name. Adds #1, #2, #3 etc. if necessary. */ void forceUniqueName(); /** This function synchronizes the password of this transport with the password of the transport with the same ID that is managed by the transport manager. This is only useful for cloned transports, since their passwords don't automatically get updated when calling TransportManager::loadPasswordsAsync() or TransportManager::loadPasswords(). @sa clone() @since 4.2 */ void updatePasswordState(); /** Returns true if all settings have been loaded. This is the way to find out if the password has already been loaded from the wallet. */ bool isComplete() const; /** Returns a string representation of the authentication type. */ QString authenticationTypeString() const; /** Returns a deep copy of this Transport object which will no longer be automatically updated. Use this if you need to store a Transport object over a longer time. However it is recommended to store transport identifiers instead if possible. @sa updatePasswordState() */ Transport *clone() const; + /** + Returns the type of this transport. + @see TransportType. + */ + TransportType transportType() const; + + /** + Sets the type of this transport. + @see TransportType. + */ + void setTransportType( const TransportType &type ); + protected: /** Creates a Transport object. Should only be used by TransportManager. @param cfgGroup The KConfig group to read its data from. */ Transport( const QString &cfgGroup ); virtual void usrReadConfig(); virtual void usrWriteConfig(); /** Returns true if the password was not stored in the wallet. */ bool needsWalletMigration() const; /** Try to migrate the password from the config file to the wallet. */ void migrateToWallet(); private Q_SLOTS: void readPassword(); private: TransportPrivate *const d; }; } #endif diff --git a/mailtransport/transportconfigdialog.cpp b/mailtransport/transportconfigdialog.cpp index 7d9c1dded..f069fcfeb 100644 --- a/mailtransport/transportconfigdialog.cpp +++ b/mailtransport/transportconfigdialog.cpp @@ -1,65 +1,104 @@ /* Copyright (c) 2006 - 2007 Volker Krause Copyright (c) 2007 KovoKs Copyright (c) 2009 Constantin Berzan Based on KMail code by: Copyright (c) 2001-2002 Michael Haeckel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transportconfigdialog.h" - #include "transport.h" #include "transportconfigwidget.h" #include "transportmanager.h" -#include "transporttypeinfo.h" +#include "transporttype.h" +#include "sendmailconfigwidget.h" +#include "smtpconfigwidget.h" +#include #include #include +#include using namespace MailTransport; class MailTransport::TransportConfigDialog::Private { public: - TransportConfigWidget *configWidget; - // TODO not really necessary right now; used only in constructor + Transport *transport; + QWidget *configWidget; + // slots + void okClicked(); }; +void TransportConfigDialog::Private::okClicked() +{ + if( TransportConfigWidget *w = dynamic_cast( configWidget ) ) { + // It is not an Akonadi transport. + w->apply(); + transport->writeConfig(); + } +} + + + TransportConfigDialog::TransportConfigDialog( Transport *transport, QWidget *parent ) - : KDialog( parent ), d( new Private ) + : KDialog( parent ) + , d( new Private ) { Q_ASSERT( transport ); - - d->configWidget = TransportTypeInfo::configWidgetForTransport( transport ); - kDebug() << "transport" << transport->id() << "config widget" << d->configWidget; - Q_ASSERT( d->configWidget ); + d->transport = transport; + + switch( transport->type() ) { + case Transport::EnumType::SMTP: + { + d->configWidget = new SMTPConfigWidget( transport, this ); + break; + } + case Transport::EnumType::Sendmail: + { + d->configWidget = new SendmailConfigWidget( transport, this ); + break; + } + case Transport::EnumType::Akonadi: + { + kWarning() << "Tried to configure an Akonadi transport."; + d->configWidget = new QLabel( i18n( "This transport cannot be configured." ), this ); + break; + } + default: + { + Q_ASSERT( false ); + d->configWidget = 0; + break; + } + } setMainWidget( d->configWidget ); setButtons( Ok|Cancel ); - connect( this, SIGNAL( okClicked() ), d->configWidget, SLOT( apply() ) ); + connect( this, SIGNAL(okClicked()), this, SLOT(okClicked()) ); } -TransportConfigDialog::~ TransportConfigDialog() +TransportConfigDialog::~TransportConfigDialog() { delete d; } #include "transportconfigdialog.moc" diff --git a/mailtransport/transportconfigdialog.h b/mailtransport/transportconfigdialog.h index 55a816b69..85963e7d2 100644 --- a/mailtransport/transportconfigdialog.h +++ b/mailtransport/transportconfigdialog.h @@ -1,70 +1,79 @@ /* Copyright (c) 2006 - 2007 Volker Krause Copyright (c) 2009 Constantin Berzan Based on KMail code by: Copyright (c) 2001-2002 Michael Haeckel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILTRANSPORT_TRANSPORTCONFIGDIALOG_H #define MAILTRANSPORT_TRANSPORTCONFIGDIALOG_H #include -#include +#include namespace MailTransport { class Transport; /** Configuration dialog for a mail transport. -*/ -class MAILTRANSPORT_EXPORT TransportConfigDialog : public KDialog + @deprecated Use TransportManager::configureTransport() instead. +*/ +// KDE5: this class should not be exported. +// FIXME how to avoid deprecated warning from its own moc? +class MAILTRANSPORT_EXPORT_DEPRECATED TransportConfigDialog : public KDialog { Q_OBJECT public: /** Creates a new mail transport configuration dialog for the given Transport object. The config dialog does not delete @p transport, you have to delete it yourself. + Note that this class only works for transports that are handled directly + by MailTransport, i.e. SMTP and Sendmail. This class cannot be used to + configure an Akonadi transport. + @param transport The Transport object to configure. This must be a deep copy of a Transport object or a newly created one, which hasn't been added to the TransportManager yet. @param parent The parent widget. */ explicit TransportConfigDialog( Transport *transport, QWidget *parent = 0 ); /** Destroys the dialog. */ virtual ~TransportConfigDialog(); private: class Private; Private *const d; + Q_PRIVATE_SLOT( d, void okClicked() ) + }; } #endif diff --git a/mailtransport/transportconfigwidget.cpp b/mailtransport/transportconfigwidget.cpp index bd94234e9..640b159e6 100644 --- a/mailtransport/transportconfigwidget.cpp +++ b/mailtransport/transportconfigwidget.cpp @@ -1,84 +1,85 @@ /* Copyright (c) 2009 Constantin Berzan Based on MailTransport code by: Copyright (c) 2006 - 2007 Volker Krause Copyright (c) 2007 KovoKs Based on KMail code by: Copyright (c) 2001-2002 Michael Haeckel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transportconfigwidget.h" #include "transportconfigwidget_p.h" #include "transport.h" #include "transportmanager.h" #include #include #include using namespace MailTransport; TransportConfigWidget::TransportConfigWidget( Transport *transport, QWidget *parent ) : QWidget( parent ) , d_ptr( new TransportConfigWidgetPrivate ) { init( transport ); } TransportConfigWidget::TransportConfigWidget( TransportConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ) : QWidget( parent ) , d_ptr( &dd ) { init( transport ); } TransportConfigWidget::~ TransportConfigWidget() { delete d_ptr; } void TransportConfigWidget::init( Transport *transport ) { Q_D( TransportConfigWidget ); kDebug() << "this" << this << "d" << d; Q_ASSERT( transport ); d->transport = transport; d->manager = new KConfigDialogManager( this, transport ); //d->manager->updateWidgets(); // no use; ui is set up in subclasses. } KConfigDialogManager *TransportConfigWidget::configManager() const { Q_D( const TransportConfigWidget ); Q_ASSERT( d->manager ); return d->manager; } void TransportConfigWidget::apply() { Q_D( TransportConfigWidget ); d->manager->updateSettings(); d->transport->forceUniqueName(); d->transport->writeConfig(); + kDebug() << "Config written."; } #include "transportconfigwidget.moc" diff --git a/mailtransport/transportlistview.cpp b/mailtransport/transportlistview.cpp index 2a296c803..d9568999c 100644 --- a/mailtransport/transportlistview.cpp +++ b/mailtransport/transportlistview.cpp @@ -1,116 +1,116 @@ /* Copyright (c) 2009 Constantin Berzan Based on KMail code by: Copyright (c) 2002 Marc Mutz 2007 Mathias Soeken This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transportlistview.h" #include "transport.h" #include "transportmanager.h" -#include "transporttypeinfo.h" +#include "transporttype.h" #include #include #include #include using namespace MailTransport; TransportListView::TransportListView( QWidget *parent ) : QTreeWidget( parent ) { setHeaderLabels( QStringList() << i18nc( "@title:column email transport name", "Name" ) << i18nc( "@title:column email transport type", "Type" ) ); setRootIsDecorated( false ); header()->setMovable( false ); setAllColumnsShowFocus( true ); setAlternatingRowColors( true ); setSortingEnabled( true ); sortByColumn( 0, Qt::AscendingOrder ); setSelectionMode( SingleSelection ); fillTransportList(); connect( TransportManager::self(), SIGNAL(transportsChanged()), this, SLOT(fillTransportList()) ); } void TransportListView::editItem( QTreeWidgetItem *item, int column ) { // TODO: is there a nicer way to make only the 'name' column editable? if ( column == 0 && item ) { Qt::ItemFlags oldFlags = item->flags(); item->setFlags( oldFlags | Qt::ItemIsEditable ); QTreeWidget::editItem( item, 0 ); item->setFlags( oldFlags ); } } void TransportListView::commitData( QWidget *editor ) { if( selectedItems().size() < 1 ) { // transport was deleted by someone else??? kDebug() << "No selected item."; return; } QTreeWidgetItem *item = selectedItems()[0]; QLineEdit *edit = dynamic_cast( editor ); // krazy:exclude=qclasses Q_ASSERT( edit ); // original code had if int id = item->data( 0, Qt::UserRole ).toInt(); Transport *t = TransportManager::self()->transportById( id ); if( !t ) { kWarning() << "Transport" << id << "not known by manager."; return; } kDebug() << "Renaming transport" << id << "to" << edit->text(); t->setName( edit->text() ); t->forceUniqueName(); t->writeConfig(); } void TransportListView::fillTransportList() { // try to preserve the selection int selected = -1; if ( currentItem() ) { selected = currentItem()->data( 0, Qt::UserRole ).toInt(); } clear(); foreach ( Transport *t, TransportManager::self()->transports() ) { QTreeWidgetItem *item = new QTreeWidgetItem( this ); item->setData( 0, Qt::UserRole, t->id() ); item->setText( 0, t->name() ); - QString type = TransportTypeInfo::nameForType( t->type() ); + QString type = t->transportType().name(); if ( TransportManager::self()->defaultTransportId() == t->id() ) { type += i18nc( "@label the default mail transport", " (Default)" ); } item->setText( 1, type ); if ( t->id() == selected ) { setCurrentItem( item ); } } } #include "transportlistview.moc" diff --git a/mailtransport/transportmanagementwidget.cpp b/mailtransport/transportmanagementwidget.cpp index a50c315d3..3260008c9 100644 --- a/mailtransport/transportmanagementwidget.cpp +++ b/mailtransport/transportmanagementwidget.cpp @@ -1,130 +1,131 @@ /* Copyright (c) 2006 - 2007 Volker Krause Based on KMail code by: Copyright (C) 2001-2003 Marc Mutz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transportmanagementwidget.h" -#include "addtransportassistant.h" +#include "addtransportdialog.h" #include "ui_transportmanagementwidget.h" #include "transportmanager.h" #include "transport.h" #include "transportconfigdialog.h" #include using namespace MailTransport; class TransportManagementWidget::Private { public: Ui::TransportManagementWidget ui; }; TransportManagementWidget::TransportManagementWidget( QWidget *parent ) : QWidget( parent ), d( new Private ) { KGlobal::locale()->insertCatalog( QString::fromLatin1( "libmailtransport" ) ); d->ui.setupUi( this ); updateButtonState(); connect( d->ui.transportList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(updateButtonState()) ); connect( d->ui.transportList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(editClicked()) ); connect( d->ui.addButton, SIGNAL(clicked()), SLOT(addClicked()) ); connect( d->ui.editButton, SIGNAL(clicked()), SLOT(editClicked()) ); connect( d->ui.renameButton, SIGNAL(clicked()), SLOT(renameClicked()) ); connect( d->ui.removeButton, SIGNAL(clicked()), SLOT(removeClicked()) ); connect( d->ui.defaultButton, SIGNAL(clicked()), SLOT(defaultClicked()) ); } TransportManagementWidget::~TransportManagementWidget() { delete d; } void TransportManagementWidget::updateButtonState() { - // TODO figure out current item vs. selected item -> using both ATM + // TODO figure out current item vs. selected item (in almost every function) if ( !d->ui.transportList->currentItem() ) { d->ui.editButton->setEnabled( false ); d->ui.renameButton->setEnabled( false ); d->ui.removeButton->setEnabled( false ); d->ui.defaultButton->setEnabled( false ); } else { d->ui.editButton->setEnabled( true ); d->ui.renameButton->setEnabled( true ); d->ui.removeButton->setEnabled( true ); if ( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ) == TransportManager::self()->defaultTransportId() ) { d->ui.defaultButton->setEnabled( false ); } else { d->ui.defaultButton->setEnabled( true ); } } } void TransportManagementWidget::addClicked() { - QPointer ass = new AddTransportAssistant( this ); - ass->exec(); - delete ass; + QPointer dialog = new AddTransportDialog( this ); + dialog->exec(); + delete dialog; } void TransportManagementWidget::editClicked() { - Q_ASSERT( d->ui.transportList->currentItem() ); + if( !d->ui.transportList->currentItem() ) { + return; + } int currentId = d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt(); Transport *transport = TransportManager::self()->transportById( currentId ); - Q_ASSERT( transport ); - transport = transport->clone(); - QPointer dlg = new TransportConfigDialog( transport, this ); - dlg->setCaption( i18nc( "@title:window", "Modify Transport" ) ); - dlg->exec(); - delete dlg; - delete transport; + TransportManager::self()->configureTransport( transport, this ); } void TransportManagementWidget::renameClicked() { - // TODO test all of these for cases when the transport is removed from outside - Q_ASSERT( d->ui.transportList->currentItem() ); + if( !d->ui.transportList->currentItem() ) { + return; + } d->ui.transportList->editItem( d->ui.transportList->currentItem(), 0 ); } void TransportManagementWidget::removeClicked() { - Q_ASSERT( d->ui.transportList->currentItem() ); + if( !d->ui.transportList->currentItem() ) { + return; + } TransportManager::self()->removeTransport( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt() ); } void TransportManagementWidget::defaultClicked() { - Q_ASSERT( d->ui.transportList->currentItem() ); + if( !d->ui.transportList->currentItem() ) { + return; + } TransportManager::self()->setDefaultTransport( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt() ); } #include "transportmanagementwidget.moc" diff --git a/mailtransport/transportmanager.cpp b/mailtransport/transportmanager.cpp index c5154d104..377f6064e 100644 --- a/mailtransport/transportmanager.cpp +++ b/mailtransport/transportmanager.cpp @@ -1,608 +1,731 @@ /* Copyright (c) 2006 - 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "transportmanager.h" +#include "addtransportdialog.h" +#include "akonadijob.h" #include "mailtransport_defs.h" #include "transport.h" #include "transportconfigwidget.h" #include "transportjob.h" -#include "transporttypeinfo.h" +#include "transporttype.h" +#include "transporttype_p.h" #include "transportconfigdialog.h" +#include "sendmailconfigwidget.h" +#include "sendmailjob.h" +#include "smtpconfigwidget.h" +#include "smtpjob.h" #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include +#include +#include + using namespace MailTransport; using namespace KWallet; /** * Private class that helps to provide binary compatibility between releases. * @internal */ class TransportManager::Private { public: Private() {} ~Private() { delete config; qDeleteAll( transports ); } KConfig *config; QList transports; + TransportType::List types; bool myOwnChange; bool appliedChange; KWallet::Wallet *wallet; bool walletOpenFailed; bool walletAsyncOpen; int defaultTransportId; bool isMainInstance; QList walletQueue; }; class StaticTransportManager : public TransportManager { public: StaticTransportManager() : TransportManager() {} }; StaticTransportManager *sSelf = 0; static void destroyStaticTransportManager() { delete sSelf; } TransportManager::TransportManager() : QObject(), d( new Private ) { KGlobal::locale()->insertCatalog( QLatin1String( "libmailtransport" ) ); qAddPostRoutine( destroyStaticTransportManager ); d->myOwnChange = false; d->appliedChange = false; d->wallet = 0; d->walletOpenFailed = false; d->walletAsyncOpen = false; d->defaultTransportId = -1; d->config = new KConfig( QLatin1String( "mailtransports" ) ); QDBusConnection::sessionBus().registerObject( DBUS_OBJECT_PATH, this, QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportScriptableSignals ); QDBusConnection::sessionBus().connect( QString(), QString(), DBUS_INTERFACE_NAME, DBUS_CHANGE_SIGNAL, this, SLOT(slotTransportsChanged()) ); d->isMainInstance = QDBusConnection::sessionBus().registerService( DBUS_SERVICE_NAME ); connect( QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), SLOT(dbusServiceOwnerChanged(QString,QString,QString)) ); + + fillTypes(); } TransportManager::~TransportManager() { qRemovePostRoutine( destroyStaticTransportManager ); delete d; } TransportManager *TransportManager::self() { if ( !sSelf ) { sSelf = new StaticTransportManager; sSelf->readConfig(); } return sSelf; } Transport *TransportManager::transportById( int id, bool def ) const { foreach ( Transport *t, d->transports ) { if ( t->id() == id ) { return t; } } if ( def || ( id == 0 && d->defaultTransportId != id ) ) { return transportById( d->defaultTransportId, false ); } return 0; } Transport *TransportManager::transportByName( const QString &name, bool def ) const { foreach ( Transport *t, d->transports ) { if ( t->name() == name ) { return t; } } if ( def ) { return transportById( 0, false ); } return 0; } QList< Transport * > TransportManager::transports() const { return d->transports; } +const TransportType::List &TransportManager::types() const +{ + return d->types; +} + Transport *TransportManager::createTransport() const { int id = createId(); Transport *t = new Transport( QString::number( id ) ); t->setId( id ); return t; } void TransportManager::addTransport( Transport *transport ) { if ( d->transports.contains( transport ) ) { + kDebug() << "Already have this transport."; return; } + kDebug() << "Added transport" << transport; d->transports.append( transport ); validateDefault(); emitChangesCommitted(); } void TransportManager::schedule( TransportJob *job ) { connect( job, SIGNAL(result(KJob*)), SLOT(jobResult(KJob*)) ); // check if the job is waiting for the wallet if ( !job->transport()->isComplete() ) { kDebug() << "job waits for wallet:" << job; d->walletQueue << job; loadPasswordsAsync(); return; } job->start(); } void TransportManager::createDefaultTransport() { KEMailSettings kes; Transport *t = createTransport(); t->setName( i18n( "Default Transport" ) ); t->setHost( kes.getSetting( KEMailSettings::OutServer ) ); if ( t->isValid() ) { t->writeConfig(); addTransport( t ); } else { kWarning() << "KEMailSettings does not contain a valid transport."; } } -bool TransportManager::checkTransport( QWidget *parent ) +bool TransportManager::promptCreateTransportIfNoneExists( QWidget *parent ) { if ( !isEmpty() ) return true; const int response = KMessageBox::messageBox( parent, KMessageBox::WarningContinueCancel, i18n("You must create an outgoing account before sending."), i18n("Create Account Now?"), KGuiItem( i18n("Create Account Now") ) ); if ( response == KMessageBox::Continue ) { - Transport* transport = createTransport(); - TransportConfigDialog* dialog = new TransportConfigDialog( transport, parent ); - dialog->setAttribute( Qt::WA_DeleteOnClose ); - dialog->setWindowModality( Qt::WindowModal ); - if ( ( dialog->exec() == QDialog::Accepted ) && transport->isValid() ) { - addTransport( transport ); - return true; - } else { - delete transport; - } + QPointer dialog = new AddTransportDialog( parent ); + dialog->exec(); + delete dialog; + return !isEmpty(); // The user has created and configured a transport. } return false; } +bool TransportManager::configureTransport( Transport *transport, QWidget *parent ) +{ + if( transport->type() == Transport::EnumType::Akonadi ) { + using namespace Akonadi; + AgentInstance instance = AgentManager::self()->instance( transport->host() ); + if( !instance.isValid() ) { + kWarning() << "Invalid resource instance" << transport->host(); + } + instance.configure( parent ); // Async... + transport->writeConfig(); + return true; // No way to know here if the user cancelled or not. + } + + QPointer dialog = new KDialog( parent ); + TransportConfigWidget *configWidget = 0; + switch( transport->type() ) { + case Transport::EnumType::SMTP: + { + configWidget = new SMTPConfigWidget( transport, dialog ); + break; + } + case Transport::EnumType::Sendmail: + { + configWidget = new SendmailConfigWidget( transport, dialog ); + break; + } + default: + { + Q_ASSERT( false ); + delete dialog; + return false; + } + } + dialog->setMainWidget( configWidget ); + dialog->setCaption( i18n( "Configure account" ) ); + dialog->setButtons( KDialog::Ok | KDialog::Cancel ); + bool okClicked = ( dialog->exec() == QDialog::Accepted ); + if( okClicked ) { + configWidget->apply(); // calls transport->writeConfig() + } + delete dialog; + return okClicked; +} + TransportJob *TransportManager::createTransportJob( int transportId ) { Transport *t = transportById( transportId, false ); if ( !t ) { return 0; } - return TransportTypeInfo::jobForTransport( t->clone(), this ); + switch ( t->type() ) { + case Transport::EnumType::SMTP: + return new SmtpJob( t, this ); + case Transport::EnumType::Sendmail: + return new SendmailJob( t, this ); + case Transport::EnumType::Akonadi: + return new AkonadiJob( t, this ); + } + Q_ASSERT( false ); + return 0; } TransportJob *TransportManager::createTransportJob( const QString &transport ) { bool ok = false; Transport *t = 0; int transportId = transport.toInt( &ok ); if ( ok ) { t = transportById( transportId ); } if ( !t ) { t = transportByName( transport, false ); } if ( t ) { return createTransportJob( t->id() ); } return 0; } bool TransportManager::isEmpty() const { return d->transports.isEmpty(); } QList TransportManager::transportIds() const { QList rv; foreach ( Transport *t, d->transports ) { rv << t->id(); } return rv; } QStringList TransportManager::transportNames() const { QStringList rv; foreach ( Transport *t, d->transports ) { rv << t->name(); } return rv; } QString TransportManager::defaultTransportName() const { Transport *t = transportById( d->defaultTransportId, false ); if ( t ) { return t->name(); } return QString(); } int TransportManager::defaultTransportId() const { return d->defaultTransportId; } void TransportManager::setDefaultTransport( int id ) { if ( id == d->defaultTransportId || !transportById( id, false ) ) { return; } d->defaultTransportId = id; writeConfig(); } void TransportManager::removeTransport( int id ) { Transport *t = transportById( id, false ); if ( !t ) { return; } emit transportRemoved( t->id(), t->name() ); + + // Kill the resource, if Akonadi-type transport. + if( t->type() == Transport::EnumType::Akonadi ) { + using namespace Akonadi; + const AgentInstance instance = AgentManager::self()->instance( t->host() ); + if( !instance.isValid() ) { + kWarning() << "Could not find resource instance."; + } + AgentManager::self()->removeInstance( instance ); + } + d->transports.removeAll( t ); validateDefault(); QString group = t->currentGroup(); delete t; d->config->deleteGroup( group ); writeConfig(); + } void TransportManager::readConfig() { QList oldTransports = d->transports; d->transports.clear(); QRegExp re( QLatin1String( "^Transport (.+)$" ) ); QStringList groups = d->config->groupList().filter( re ); foreach ( const QString &s, groups ) { re.indexIn( s ); Transport *t = 0; // see if we happen to have that one already foreach ( Transport *old, oldTransports ) { if ( old->currentGroup() == QLatin1String( "Transport " ) + re.cap( 1 ) ) { kDebug() << "reloading existing transport:" << s; t = old; t->readConfig(); oldTransports.removeAll( old ); break; } } if ( !t ) { t = new Transport( re.cap( 1 ) ); } if ( t->id() <= 0 ) { t->setId( createId() ); t->writeConfig(); } d->transports.append( t ); } qDeleteAll( oldTransports ); oldTransports.clear(); // read default transport KConfigGroup group( d->config, "General" ); d->defaultTransportId = group.readEntry( "default-transport", 0 ); if ( d->defaultTransportId == 0 ) { // migrated default transport contains the name instead QString name = group.readEntry( "default-transport", QString() ); if ( !name.isEmpty() ) { Transport *t = transportByName( name, false ); if ( t ) { d->defaultTransportId = t->id(); writeConfig(); } } } validateDefault(); migrateToWallet(); } void TransportManager::writeConfig() { KConfigGroup group( d->config, "General" ); group.writeEntry( "default-transport", d->defaultTransportId ); d->config->sync(); emitChangesCommitted(); } +void TransportManager::fillTypes() +{ + Q_ASSERT( d->types.isEmpty() ); + + // SMTP. + { + TransportType type; + type.d->mType = Transport::EnumType::SMTP; + type.d->mName = i18nc( "@option SMTP transport", "SMTP" ); + type.d->mDescription = i18n( "An SMTP server on the internet" ); + d->types << type; + } + + // Sendmail. + { + TransportType type; + type.d->mType = Transport::EnumType::Sendmail; + type.d->mName = i18nc( "@option sendmail transport", "Sendmail" ); + type.d->mDescription = i18n( "A local sendmail installation" ); + d->types << type; + } + + // All Akonadi resources with MailTransport capability. + { + using namespace Akonadi; + foreach( const AgentType &atype, AgentManager::self()->types() ) { + // TODO probably the string "MailTransport" should be #defined somewhere + // and used like that in the resources (?) + if( atype.capabilities().contains( QLatin1String( "MailTransport" ) ) ) { + TransportType type; + type.d->mType = Transport::EnumType::Akonadi; + type.d->mAgentType = atype; + type.d->mName = atype.name(); + type.d->mDescription = atype.description(); + d->types << type; + kDebug() << "Found Akonadi type" << atype.name(); + } + } + } + + kDebug() << "Have SMTP, Sendmail, and" << d->types.count() - 2 << "Akonadi types."; +} + void TransportManager::emitChangesCommitted() { d->myOwnChange = true; // prevent us from reading our changes again d->appliedChange = false; // but we have to read them at least once emit transportsChanged(); emit changesCommitted(); } void TransportManager::slotTransportsChanged() { if ( d->myOwnChange && d->appliedChange ) { d->myOwnChange = false; d->appliedChange = false; return; } kDebug(); d->config->reparseConfiguration(); // FIXME: this deletes existing transport objects! readConfig(); d->appliedChange = true; // to prevent recursion emit transportsChanged(); } int TransportManager::createId() const { QList usedIds; foreach ( Transport *t, d->transports ) { usedIds << t->id(); } usedIds << 0; // 0 is default for unknown int newId; do { newId = KRandom::random(); } while ( usedIds.contains( newId ) ); return newId; } KWallet::Wallet * TransportManager::wallet() { if ( d->wallet && d->wallet->isOpen() ) { return d->wallet; } if ( !Wallet::isEnabled() || d->walletOpenFailed ) { return 0; } WId window = 0; if ( qApp->activeWindow() ) { window = qApp->activeWindow()->winId(); } else if ( !QApplication::topLevelWidgets().isEmpty() ) { window = qApp->topLevelWidgets().first()->winId(); } delete d->wallet; d->wallet = Wallet::openWallet( Wallet::NetworkWallet(), window ); if ( !d->wallet ) { d->walletOpenFailed = true; return 0; } prepareWallet(); return d->wallet; } void TransportManager::prepareWallet() { if ( !d->wallet ) { return; } if ( !d->wallet->hasFolder( WALLET_FOLDER ) ) { d->wallet->createFolder( WALLET_FOLDER ); } d->wallet->setFolder( WALLET_FOLDER ); } void TransportManager::loadPasswords() { foreach ( Transport *t, d->transports ) { t->readPassword(); } // flush the wallet queue foreach ( TransportJob *job, d->walletQueue ) { job->start(); } d->walletQueue.clear(); emit passwordsChanged(); } void TransportManager::loadPasswordsAsync() { kDebug(); // check if there is anything to do at all bool found = false; foreach ( Transport *t, d->transports ) { if ( !t->isComplete() ) { found = true; break; } } if ( !found ) { return; } // async wallet opening if ( !d->wallet && !d->walletOpenFailed ) { WId window = 0; if ( qApp->activeWindow() ) { window = qApp->activeWindow()->winId(); } else if ( !QApplication::topLevelWidgets().isEmpty() ) { window = qApp->topLevelWidgets().first()->winId(); } d->wallet = Wallet::openWallet( Wallet::NetworkWallet(), window, Wallet::Asynchronous ); if ( d->wallet ) { connect( d->wallet, SIGNAL(walletOpened(bool)), SLOT(slotWalletOpened(bool)) ); d->walletAsyncOpen = true; } else { d->walletOpenFailed = true; loadPasswords(); } return; } if ( d->wallet && !d->walletAsyncOpen ) { loadPasswords(); } } void TransportManager::slotWalletOpened( bool success ) { kDebug(); d->walletAsyncOpen = false; if ( !success ) { d->walletOpenFailed = true; delete d->wallet; d->wallet = 0; } else { prepareWallet(); } loadPasswords(); } void TransportManager::validateDefault() { if ( !transportById( d->defaultTransportId, false ) ) { if ( isEmpty() ) { d->defaultTransportId = -1; } else { d->defaultTransportId = d->transports.first()->id(); writeConfig(); } } } void TransportManager::migrateToWallet() { // check if we tried this already static bool firstRun = true; if ( !firstRun ) { return; } firstRun = false; // check if we are the main instance if ( !d->isMainInstance ) { return; } // check if migration is needed QStringList names; foreach ( Transport *t, d->transports ) { if ( t->needsWalletMigration() ) { names << t->name(); } } if ( names.isEmpty() ) { return; } // ask user if he wants to migrate int result = KMessageBox::questionYesNoList( 0, i18n( "The following mail transports store their passwords in an " "unencrypted configuration file.\nFor security reasons, " "please consider migrating these passwords to KWallet, the " "KDE Wallet management tool,\nwhich stores sensitive data " "for you in a strongly encrypted file.\n" "Do you want to migrate your passwords to KWallet?" ), names, i18n( "Question" ), KGuiItem( i18n( "Migrate" ) ), KGuiItem( i18n( "Keep" ) ), QString::fromAscii( "WalletMigrate" ) ); if ( result != KMessageBox::Yes ) { return; } // perform migration foreach ( Transport *t, d->transports ) { if ( t->needsWalletMigration() ) { t->migrateToWallet(); } } } void TransportManager::dbusServiceOwnerChanged( const QString &service, const QString &oldOwner, const QString &newOwner ) { Q_UNUSED( oldOwner ); if ( service == DBUS_SERVICE_NAME && newOwner.isEmpty() ) { QDBusConnection::sessionBus().registerService( DBUS_SERVICE_NAME ); } } void TransportManager::jobResult( KJob *job ) { d->walletQueue.removeAll( static_cast( job ) ); } #include "transportmanager.moc" diff --git a/mailtransport/transportmanager.h b/mailtransport/transportmanager.h index 64acdcc5e..2a7dbde00 100644 --- a/mailtransport/transportmanager.h +++ b/mailtransport/transportmanager.h @@ -1,263 +1,281 @@ /* Copyright (c) 2006 - 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAILTRANSPORT_TRANSPORTMANAGER_H #define MAILTRANSPORT_TRANSPORTMANAGER_H #include +#include #include #include class KJob; namespace KWallet { class Wallet; } namespace MailTransport { class Transport; class TransportConfigWidget; class TransportJob; /** Takes care of loading and storing mail transport settings and creating of transport jobs. */ class MAILTRANSPORT_EXPORT TransportManager : public QObject { Q_OBJECT Q_CLASSINFO( "D-Bus Interface", "org.kde.pim.TransportManager" ) friend class Transport; friend class Private; public: class Private; /** Destructor. */ virtual ~TransportManager(); /** Returns the TransportManager instance. */ static TransportManager *self(); /** Tries to load passwords asynchronously from KWallet if needed. The passwordsChanged() signal is emitted once the passwords have been loaded. Nothing happens if the passwords were already available. */ void loadPasswordsAsync(); /** Returns the Transport object with the given id. @param id The identifier of the Transport. @param def if set to true, the default transport will be returned if the specified Transport object could not be found, 0 otherwise. @returns A Transport object for immediate use. It might become invalid as soon as the event loop is entered again due to remote changes. If you need to store a Transport object, store the transport identifier instead. */ Transport *transportById( int id, bool def = true ) const; /** Returns the transport object with the given name. @param name The transport name. @param def if set to true, the default transport will be returned if the specified Transport object could not be found, 0 otherwise. @returns A Transport object for immediate use, see transportById() for limitations. */ Transport *transportByName( const QString &name, bool def = true ) const; /** Returns a list of all available transports. Note: The Transport objects become invalid as soon as a change occur, so they are only suitable for immediate use. */ QListtransports() const; + /** + Returns a list of all available transport types. + */ + const TransportType::List &types() const; + /** Creates a new, empty Transport object. The object is owned by the caller. If you want to add the Transport permanently (eg. after configuring it) call addTransport(). */ Transport *createTransport() const; /** Adds the given transport. The object ownership is transferred to TransportMananger, ie. you must not delete @p transport. @param transport The Transport object to add. */ void addTransport( Transport *transport ); /** Creates a mail transport job for the given transport identifier. Returns 0 if the specified transport is invalid. @param transportId The transport identifier. */ TransportJob *createTransportJob( int transportId ); /** Creates a mail transport job for the given transport identifer, or transport name. Returns 0 if the specified transport is invalid. @param transport A string defining a mail transport. */ TransportJob *createTransportJob( const QString &transport ); /** Executes the given transport job. This is the preferred way to start transport jobs. It takes care of asynchronously loading passwords from KWallet if necessary. @param job The completely configured transport job to execute. */ void schedule( TransportJob *job ); /** Tries to create a transport based on KEMailSettings. If the data in KEMailSettings is incomplete, no transport is created. */ void createDefaultTransport(); /** - Check for an existing transport, and show a configuration dialog if not. - Returns true if transport exists or user creates one. Otherwise false. - @param parent Parent widget of the dialog + If no transport exists, asks the user to create and configure one. + Returns true if a transport exists or the user created one. Otherwise + returns false. + @param parent Parent widget of the dialog. + @since 4.4 + */ + bool promptCreateTransportIfNoneExists( QWidget *parent ); + + /** + Open a configuration dialog for an existing transport. + @param transport The transport to configure. It can be a new transport, + or one already managed by TransportManager. + @param parent The parent widget for the dialog. + @return True if the user clicked Ok, false if the user cancelled. @since 4.4 */ - bool checkTransport( QWidget *parent ); + bool configureTransport( Transport *transport, QWidget *parent ); public Q_SLOTS: /** Returns true if there are no mail transports at all. */ Q_SCRIPTABLE bool isEmpty() const; /** Returns a list of transport identifiers. */ Q_SCRIPTABLE QList transportIds() const; /** Returns a list of transport names. */ Q_SCRIPTABLE QStringList transportNames() const; /** Returns the default transport name. */ Q_SCRIPTABLE QString defaultTransportName() const; /** Returns the default transport identifier. Invalid if there are no transports at all. */ Q_SCRIPTABLE int defaultTransportId() const; /** Sets the default transport. The change will be in effect immediately. @param id The identifier of the new default transport. */ Q_SCRIPTABLE void setDefaultTransport( int id ); /** Deletes the specified transport. @param id The identifier of the mail transport to remove. */ Q_SCRIPTABLE void removeTransport( int id ); Q_SIGNALS: /** Emitted when transport settings have changed (by this or any other TransportManager instance). */ Q_SCRIPTABLE void transportsChanged(); /** Internal signal to synchronize all TransportManager instances. This signal is emitted by the instance writing the changes. You probably want to use transportsChanged() instead. */ Q_SCRIPTABLE void changesCommitted(); /** Emitted when passwords have been loaded from the wallet. If you made a deep copy of a transport, you should call updatePasswordState() for the cloned transport to ensure its password is updated as well. */ void passwordsChanged(); /** Emitted when a transport is deleted. @param id The identifier of the deleted transport. @param name The name of the deleted transport. */ void transportRemoved( int id, const QString &name ); /** Emitted when a transport has been renamed. @param id The identifier of the renamed transport. @param oldName The old name. @param newName The new name. */ void transportRenamed( int id, const QString &oldName, const QString &newName ); protected: /** Returns a pointer to an open wallet if available, 0 otherwise. The wallet is opened synchronously if necessary. */ KWallet::Wallet *wallet(); /** Loads all passwords synchronously. */ void loadPasswords(); TransportManager(); private: void readConfig(); void writeConfig(); + void fillTypes(); void emitChangesCommitted(); int createId() const; void prepareWallet(); void validateDefault(); void migrateToWallet(); private Q_SLOTS: void slotTransportsChanged(); void slotWalletOpened( bool success ); void dbusServiceOwnerChanged( const QString &service, const QString &oldOwner, const QString &newOwner ); void jobResult( KJob *job ); private: Private *const d; }; } #endif diff --git a/mailtransport/transporttype.cpp b/mailtransport/transporttype.cpp new file mode 100644 index 000000000..3446f9b1c --- /dev/null +++ b/mailtransport/transporttype.cpp @@ -0,0 +1,82 @@ +/* + Copyright (c) 2009 Constantin Berzan + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "transporttype.h" +#include "transporttype_p.h" +#include "transport.h" + +#include + +using namespace MailTransport; + +TransportType::TransportType() + : d( new Private ) +{ +} + +TransportType::TransportType( const TransportType &other ) + : d( other.d ) +{ +} + +TransportType::~TransportType() +{ +} + +bool TransportType::operator==( const TransportType &other ) const +{ + if( d->mType == Transport::EnumType::Akonadi && + other.d->mType == Transport::EnumType::Akonadi ) { + return ( d->mAgentType == other.d->mAgentType ); + } + return ( d->mType == other.d->mType ); +} + +bool TransportType::isValid() const +{ + using namespace Akonadi; + + if( d->mType == Transport::EnumType::Akonadi ) { + return d->mAgentType.isValid() && + AgentManager::self()->types().contains( d->mAgentType ); + } else { + return d->mType >= 0; + } +} + +int TransportType::type() const +{ + return d->mType; +} + +QString TransportType::name() const +{ + return d->mName; +} + +QString TransportType::description() const +{ + return d->mDescription; +} + +Akonadi::AgentType TransportType::agentType() const +{ + Q_ASSERT( d->mType == Transport::EnumType::Akonadi ); + return d->mAgentType; +} diff --git a/mailtransport/transporttype.h b/mailtransport/transporttype.h new file mode 100644 index 000000000..d8548b8c9 --- /dev/null +++ b/mailtransport/transporttype.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2009 Constantin Berzan + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef MAILTRANSPORT_TRANSPORTTYPE_H +#define MAILTRANSPORT_TRANSPORTTYPE_H + +#include "mailtransport_export.h" +#include "transport.h" + +#include + +#include + +namespace MailTransport { + +class AddTransportDialog; +class TransportManager; + +/** + A representation of a transport type. + + TODO docu look at Akonadi::AgentType +*/ +class MAILTRANSPORT_EXPORT TransportType +{ + friend class AddTransportDialog; + friend class Transport; + friend class TransportManager; + + public: + typedef QList List; + + TransportType(); + TransportType( const TransportType &other ); + ~TransportType(); + bool operator==( const TransportType &other ) const; + + bool isValid() const; + + // TODO should this be Transport::EnumType::type instead of int? + int type() const; + QString name() const; + QString description() const; + + /// only valid if this is an Akonadi transport + Akonadi::AgentType agentType() const; + + private: + class Private; + QSharedDataPointer d; + +}; + +} + +Q_DECLARE_METATYPE( MailTransport::TransportType ) + +#endif diff --git a/mailtransport/akonadiconfigwidget.h b/mailtransport/transporttype_p.h similarity index 56% rename from mailtransport/akonadiconfigwidget.h rename to mailtransport/transporttype_p.h index 57d9f9d6e..82620c023 100644 --- a/mailtransport/akonadiconfigwidget.h +++ b/mailtransport/transporttype_p.h @@ -1,62 +1,59 @@ /* Copyright (c) 2009 Constantin Berzan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef MAILTRANSPORT_AKONADICONFIGWIDGET_H -#define MAILTRANSPORT_AKONADICONFIGWIDGET_H +#ifndef MAILTRANSPORT_TRANSPORTTYPE_P_H +#define MAILTRANSPORT_TRANSPORTTYPE_P_H -#include "transportconfigwidget.h" +#include +#include -namespace MailTransport { +#include -class Transport; - -/** - @internal -*/ -class AkonadiConfigWidgetPrivate; +namespace MailTransport +{ /** @internal - Configuration widget for an Akonadi transport. */ -class AkonadiConfigWidget : public TransportConfigWidget +class TransportType::Private : public QSharedData { - Q_OBJECT - public: - explicit AkonadiConfigWidget( Transport *transport, QWidget *parent = 0 ); - //virtual ~AkonadiConfigWidget(); - - public Q_SLOTS: - /** reimpl */ - virtual void apply(); - - protected: - AkonadiConfigWidget( AkonadiConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ); - - private: - Q_DECLARE_PRIVATE( AkonadiConfigWidget ) - - void init(); - + Private() + { + mType = -1; + } + + Private( const Private &other ) + : QSharedData( other ) + { + mType = other.mType; + mName = other.mName; + mDescription = other.mDescription; + mAgentType = other.mAgentType; + } + + int mType; + QString mName; + QString mDescription; + Akonadi::AgentType mAgentType; }; } #endif diff --git a/mailtransport/transporttypeinfo.cpp b/mailtransport/transporttypeinfo.cpp deleted file mode 100644 index 4d95b6442..000000000 --- a/mailtransport/transporttypeinfo.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (c) 2009 Constantin Berzan - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "transporttypeinfo.h" - -#include "akonadiconfigwidget.h" -#include "sendmailconfigwidget.h" -#include "smtpconfigwidget.h" -#include "akonadijob.h" -#include "sendmailjob.h" -#include "smtpjob.h" -#include "transport.h" - -#include -#include - -#include - -using namespace MailTransport; - -int TransportTypeInfo::typeCount() -{ - return 3; -} - -QString TransportTypeInfo::nameForType( int type ) -{ - switch( type ) { - case Transport::EnumType::SMTP: - return i18nc( "@option SMTP transport", "SMTP" ); - case Transport::Transport::EnumType::Sendmail: - return i18nc( "@option sendmail transport", "Sendmail" ); - case Transport::EnumType::Akonadi: - return i18nc( "@option Akonadi Resource transport", "Akonadi Resource" ); - } - Q_ASSERT( false ); - return QString(); -} - -QString TransportTypeInfo::descriptionForType( int type ) -{ - // TODO polish these - switch( type ) { - case Transport::EnumType::SMTP: - return i18n( "An SMTP server on the internet" ); - case Transport::EnumType::Sendmail: - return i18n( "A local sendmail installation" ); - case Transport::EnumType::Akonadi: - return i18n( "A local Akonadi resource with the ability to send mail" ); - } - Q_ASSERT( false ); - return QString(); -} - -TransportJob *TransportTypeInfo::jobForTransport( Transport *transport, QObject *parent ) -{ - switch( transport->type() ) { - case Transport::EnumType::SMTP: - return new SmtpJob( transport, parent ); - case Transport::EnumType::Sendmail: - return new SendmailJob( transport, parent ); - case Transport::EnumType::Akonadi: - return new AkonadiJob( transport, parent ); - } - Q_ASSERT( false ); - return 0; -} - -TransportConfigWidget *TransportTypeInfo::configWidgetForTransport( Transport *transport, QWidget *parent ) -{ - switch( transport->type() ) { - case Transport::EnumType::SMTP: - return new SMTPConfigWidget( transport, parent ); - case Transport::EnumType::Sendmail: - return new SendmailConfigWidget( transport, parent ); - case Transport::EnumType::Akonadi: - return new AkonadiConfigWidget( transport, parent ); - } - Q_ASSERT( false ); - return 0; -} - diff --git a/mailtransport/transporttypeinfo.h b/mailtransport/transporttypeinfo.h deleted file mode 100644 index 5941fb857..000000000 --- a/mailtransport/transporttypeinfo.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2009 Constantin Berzan - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef MAILTRANSPORT_TRANSPORTTYPEINFO_H -#define MAILTRANSPORT_TRANSPORTTYPEINFO_H - -#include - -class QObject; -class QWidget; - -namespace MailTransport { - -class Transport; -class TransportConfigWidget; -class TransportJob; - -/** - A class providing central information about the types supported by - Mailtransport. It avoids having to switch(type) all over the place. - - TODO export? - - TODO docu -*/ -class TransportTypeInfo -{ - public: - static int typeCount(); - - static QString nameForType( int type ); - static QString descriptionForType( int type ); - static TransportJob *jobForTransport( Transport *transport, QObject *parent = 0 ); - static TransportConfigWidget *configWidgetForTransport( Transport *transport, QWidget *parent = 0 ); - - private: - TransportTypeInfo(); - ~TransportTypeInfo(); - -}; - -} - -#endif