diff --git a/mailtransport/CMakeLists.txt b/mailtransport/CMakeLists.txt index 2103f998f..b07e162e7 100644 --- a/mailtransport/CMakeLists.txt +++ b/mailtransport/CMakeLists.txt @@ -1,57 +1,78 @@ 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 + transportcombobox.cpp + transportlistview.cpp + transportmanagementwidget.cpp + + addtransportassistant.cpp transportconfigdialog.cpp + transportconfigwidget.cpp + akonadiconfigwidget.cpp + sendmailconfigwidget.cpp + smtpconfigwidget.cpp + transportjob.cpp - transportmanager.cpp - transportmanagementwidget.cpp + akonadijob.cpp sendmailjob.cpp smtpjob.cpp precommandjob.cpp + legacydecrypt.cpp socket.cpp servertest.cpp ) kde4_add_ui_files(mailtransport_lib_srcs - smtpsettings.ui + addtransportassistanttypepage.ui + addtransportassistantnamepage.ui + + akonadisettings.ui sendmailsettings.ui + smtpsettings.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}) +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 - transport.h + ${CMAKE_CURRENT_BINARY_DIR}/transportbase.h + transport.h + transportmanager.h + servertest.h + transportcombobox.h transportconfigdialog.h - transportjob.h transportmanagementwidget.h - transportmanager.h - servertest.h + DESTINATION ${INCLUDE_INSTALL_DIR}/mailtransport COMPONENT Devel) diff --git a/mailtransport/TODO b/mailtransport/TODO index a2e5cffdd..b08dd9eaa 100644 --- a/mailtransport/TODO +++ b/mailtransport/TODO @@ -1,36 +1,32 @@ Mail Transport TODO ~~~~~~~~~~~~~~~~~~~ Migration --------- - password migration within kwallet (for kmail and knode), requires KWallet to be fixed first TransportManager ---------------- - load passwords if another instance opens the wallet - load passwords if application opens wallet - add D-Bus interface for sending mails - test to see if there is always a default transport, by adding / deleting accounts Transport --------- - password is not reloaded from wallet on remote change TransportJob ------------ - use QByteArray for addresses instead of QString SMTPJob ------- - get rid of kmail specific stuff in start() Precommand ---------- - test conversion from kprocess to qprocess (TA) -TransportManagementWidget -------------------------- -- support inline editing of transport names - diff --git a/mailtransport/TODO.cberzan b/mailtransport/TODO.cberzan new file mode 100644 index 000000000..e03579abf --- /dev/null +++ b/mailtransport/TODO.cberzan @@ -0,0 +1,14 @@ +* 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 +* 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. +* transport type manager to handle all the switches + -> also configWidgetForType + +Bugs: +* modify -> change password -> ok. password is saved in wallet and seen ok on restart, but clicking modify again shows old password diff --git a/mailtransport/addtransportassistant.cpp b/mailtransport/addtransportassistant.cpp new file mode 100644 index 000000000..f5d0139ce --- /dev/null +++ b/mailtransport/addtransportassistant.cpp @@ -0,0 +1,199 @@ +/* + 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 +#include +#include +#include + +#include "transportconfigwidget.h" +#include "transport.h" +#include "transportbase.h" +#include "transportmanager.h" + +#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 ) +{ + // 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 + // TODO: HACKish way to get transport descriptions... + // TODO TransportManagementWidget has i18ns for transport types -> share? + Q_ASSERT( d->transport == 0 ); + d->transport = TransportManager::self()->createTransport(); + Q_ASSERT( d->transport ); + int enumid = 0; + const KConfigSkeleton::ItemEnum *const item = d->transport->typeItem(); + foreach( const KConfigSkeleton::ItemEnum::Choice2 &choice, item->choices2() ) { + QTreeWidgetItem *treeItem = new QTreeWidgetItem( d->uiTypePage.typeListView ); + treeItem->setData( 0, Qt::UserRole, enumid ); // the transport type + enumid++; + treeItem->setText( 0, choice.label ); + treeItem->setText( 1, choice.whatsThis ); + } + 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 = TransportManager::self()->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/tests/transportmgr.h b/mailtransport/addtransportassistant.h similarity index 51% copy from mailtransport/tests/transportmgr.h copy to mailtransport/addtransportassistant.h index e5f14ed49..57a12e087 100644 --- a/mailtransport/tests/transportmgr.h +++ b/mailtransport/addtransportassistant.h @@ -1,53 +1,66 @@ /* - Copyright (c) 2006 - 2007 Volker Krause + 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 TRANSPORTMGR_H -#define TRANSPORTMGR_H +#ifndef MAILTRANSPORT_ADDTRANSPORTASSISTANT_H +#define MAILTRANSPORT_ADDTRANSPORTASSISTANT_H + +#include -#include -#include +#include -class KJob; -class KLineEdit; -class QTextEdit; -class TransportMgr : public KVBox +namespace MailTransport +{ + + +/** + Assistant to help the user set up a new transport. +*/ +class MAILTRANSPORT_EXPORT AddTransportAssistant : public KAssistantDialog { Q_OBJECT - public: - TransportMgr(); - - private slots: - void removeAllBtnClicked(); - void editBtnClicked(); - void sendBtnClicked(); - void cancelBtnClicked(); - void jobResult( KJob *job ); - void jobPercent( KJob *job, unsigned long percent ); - void jobInfoMessage( KJob *job, const QString &info, const QString &info2 ); - - private: - MailTransport::TransportComboBox *mComboBox; - KLineEdit *mSenderEdit, *mToEdit, *mCcEdit, *mBccEdit; - QTextEdit *mMailEdit; - KJob *mCurrentJob; +public: + // TODO docu + explicit AddTransportAssistant( QWidget *parent = 0 ); + ~AddTransportAssistant(); + +private slots: + void typeListClicked(); + void typeListDoubleClicked(); + +protected slots: + virtual void accept(); + virtual void next(); + virtual void reject(); + +private: + class Private; + Private * const d; + }; + +} + + #endif + diff --git a/mailtransport/addtransportassistantnamepage.ui b/mailtransport/addtransportassistantnamepage.ui new file mode 100644 index 000000000..1abc2b0ea --- /dev/null +++ b/mailtransport/addtransportassistantnamepage.ui @@ -0,0 +1,71 @@ + + + AddTransportAssistantNamePage + + + + 0 + 0 + 482 + 353 + + + + + 0 + 0 + + + + Final Step: Choose Transport Name + + + + + + + 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> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Name: + + + + + + + + + + Make this the default mail transport. + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+
+ + +
diff --git a/mailtransport/addtransportassistanttypepage.ui b/mailtransport/addtransportassistanttypepage.ui new file mode 100644 index 000000000..f1401901a --- /dev/null +++ b/mailtransport/addtransportassistanttypepage.ui @@ -0,0 +1,62 @@ + + + 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/akonadiconfigwidget.cpp b/mailtransport/akonadiconfigwidget.cpp new file mode 100644 index 000000000..b27aeb0cf --- /dev/null +++ b/mailtransport/akonadiconfigwidget.cpp @@ -0,0 +1,77 @@ +/* + 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/tests/transportmgr.h b/mailtransport/akonadiconfigwidget.h similarity index 52% copy from mailtransport/tests/transportmgr.h copy to mailtransport/akonadiconfigwidget.h index e5f14ed49..57d9f9d6e 100644 --- a/mailtransport/tests/transportmgr.h +++ b/mailtransport/akonadiconfigwidget.h @@ -1,53 +1,62 @@ /* - Copyright (c) 2006 - 2007 Volker Krause + 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 TRANSPORTMGR_H -#define TRANSPORTMGR_H +#ifndef MAILTRANSPORT_AKONADICONFIGWIDGET_H +#define MAILTRANSPORT_AKONADICONFIGWIDGET_H -#include -#include +#include "transportconfigwidget.h" -class KJob; -class KLineEdit; -class QTextEdit; +namespace MailTransport { -class TransportMgr : public KVBox +class Transport; + +/** + @internal +*/ +class AkonadiConfigWidgetPrivate; + +/** + @internal + Configuration widget for an Akonadi transport. +*/ +class AkonadiConfigWidget : public TransportConfigWidget { Q_OBJECT public: - TransportMgr(); + explicit AkonadiConfigWidget( Transport *transport, QWidget *parent = 0 ); + //virtual ~AkonadiConfigWidget(); - private slots: - void removeAllBtnClicked(); - void editBtnClicked(); - void sendBtnClicked(); - void cancelBtnClicked(); - void jobResult( KJob *job ); - void jobPercent( KJob *job, unsigned long percent ); - void jobInfoMessage( KJob *job, const QString &info, const QString &info2 ); + public Q_SLOTS: + /** reimpl */ + virtual void apply(); + + protected: + AkonadiConfigWidget( AkonadiConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ); private: - MailTransport::TransportComboBox *mComboBox; - KLineEdit *mSenderEdit, *mToEdit, *mCcEdit, *mBccEdit; - QTextEdit *mMailEdit; - KJob *mCurrentJob; + Q_DECLARE_PRIVATE( AkonadiConfigWidget ) + + void init(); + }; +} + #endif diff --git a/mailtransport/akonadijob.cpp b/mailtransport/akonadijob.cpp new file mode 100644 index 000000000..dc05dea3f --- /dev/null +++ b/mailtransport/akonadijob.cpp @@ -0,0 +1,112 @@ +/* + 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 "akonadijob.h" +#include "transport.h" + +#include +#include +#include +#include + +#include + +#include + +using namespace Akonadi; +using namespace MailTransport; + +/** + * Private class that helps to provide binary compatibility between releases. + * @internal + */ +class AkonadiJobPrivate +{ + public: + Item::Id itemId; + QDBusInterface *iface; +}; + +AkonadiJob::AkonadiJob( Transport *transport, QObject *parent ) + : TransportJob( transport, parent ), d( new AkonadiJobPrivate ) +{ + d->itemId = -1; + d->iface = 0; +} + +AkonadiJob::~ AkonadiJob() +{ + delete d; +} + +Akonadi::Item::Id AkonadiJob::itemId() const +{ + return d->itemId; +} + +void AkonadiJob::setItemId( Akonadi::Item::Id id ) +{ + d->itemId = id; +} + +void AkonadiJob::doStart() +{ + if( !d->itemId < 0 ) { + // TODO should this check be performed here or somewhere on a higher level? + setError( UserDefinedError ); + setErrorText( i18n( "Asked to send invalid item with id %1.", d->itemId ) ); + emitResult(); + return; + } + + d->iface = new QDBusInterface( QLatin1String( "org.freedesktop.Akonadi.Resource." ) + transport()->host(), + QLatin1String( "/" ), QLatin1String( "org.freedesktop.Akonadi.Resource.Transport" ), + QDBusConnection::sessionBus(), this ); + if( !d->iface->isValid() ) { + setError( UserDefinedError ); + setErrorText( i18n( "Failed to get D-Bus interface of resource %1.", transport()->host() ) ); + emitResult(); + return; + } + + connect( d->iface, SIGNAL( transportResult( bool, const QString & ) ), + this, SLOT( resourceResult( bool, const QString & ) ) ); + + // What TODO about timeouts? It is quite possible that the result D-Bus signal + // will get lost, and then what? + + QDBusReply reply = d->iface->call( QLatin1String( "send" ), d->itemId ); + if( !reply.isValid() ) { + setError( UserDefinedError ); + setErrorText( i18n( "Invalid D-Bus reply from resource %1.", transport()->host() ) ); + emitResult(); + return; + } +} + +void AkonadiJob::resourceResult( bool success, const QString &message ) +{ + if( !success ) { + setError( UserDefinedError ); + setErrorText( message ); + } + emitResult(); +} + +#include "akonadijob.moc" diff --git a/mailtransport/akonadijob.h b/mailtransport/akonadijob.h new file mode 100644 index 000000000..b1fb61b3a --- /dev/null +++ b/mailtransport/akonadijob.h @@ -0,0 +1,77 @@ +/* + 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_AKONADIJOB_H +#define MAILTRANSPORT_AKONADIJOB_H + +#include + +#include + +class AkonadiJobPrivate; + +namespace MailTransport { + +/** + Mail transport job for an Akonadi resource. + + TODO docu... apps need to call setItem if it's an Akonadi job... +*/ +class MAILTRANSPORT_EXPORT AkonadiJob : public TransportJob +{ + Q_OBJECT + public: + /** + Creates an AkonadiJob. + @param transport The transport settings. + @param parent The parent object. + */ + explicit AkonadiJob( Transport *transport, QObject *parent = 0 ); + + /** + Destroys this job. + */ + virtual ~AkonadiJob(); + + // TODO have these here or in TransportJob? They are useless in {SMTP,Sendmail}Job... + /** + The id of the item to send. + */ + Akonadi::Item::Id itemId() const; + + /** + Set the id of the item to send. + @param itemId id of the item to send + */ + void setItemId( Akonadi::Item::Id id ); + + protected: + virtual void doStart(); + + private Q_SLOTS: + void resourceResult( bool success, const QString &message ); + + private: + AkonadiJobPrivate *const d; + +}; + +} + +#endif diff --git a/mailtransport/akonadisettings.ui b/mailtransport/akonadisettings.ui new file mode 100644 index 000000000..450bd9215 --- /dev/null +++ b/mailtransport/akonadisettings.ui @@ -0,0 +1,40 @@ + + + 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.kcfg b/mailtransport/mailtransport.kcfg index d4bad38ed..60ab46fae 100644 --- a/mailtransport/mailtransport.kcfg +++ b/mailtransport/mailtransport.kcfg @@ -1,112 +1,118 @@ 0 The name that will be used when referring to this server. i18n("Unnamed") + TODO smtp description + TODO sendmail description + + + + TODO Akonadi description SMTP The domain name or numerical address of the SMTP server. The port number that the SMTP server is listening on. The default port is 25. 25 The user name to send to the server for authorization. A command to run locally, prior to sending email. This can be used to set up SSH tunnels, for example. Leave it empty if no command should be run. Check this option if your SMTP server requires authentication before accepting mail. This is known as 'Authenticated SMTP' or simply ASMTP. false Check this option to have your password stored. If KWallet is available the password will be stored there which is considered safe. However, if KWallet is not available, the password will be stored in the configuration file. 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. false PLAIN Check this option to use a custom hostname when identifying to the mail server. This is useful when your system's hostname may not be set correctly or to mask your system's true hostname. false Enter the hostname that should be used when identifying to the server. diff --git a/mailtransport/sendmailconfigwidget.cpp b/mailtransport/sendmailconfigwidget.cpp new file mode 100644 index 000000000..739fb0e0b --- /dev/null +++ b/mailtransport/sendmailconfigwidget.cpp @@ -0,0 +1,73 @@ +/* + 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 "sendmailconfigwidget.h" +#include "transportconfigwidget_p.h" +#include "ui_sendmailsettings.h" + +#include + +using namespace MailTransport; + + +class MailTransport::SendmailConfigWidgetPrivate : public TransportConfigWidgetPrivate +{ + public: + Ui::SendmailSettings ui; + +}; + +SendmailConfigWidget::SendmailConfigWidget( Transport *transport, QWidget *parent ) + : TransportConfigWidget( *new SendmailConfigWidgetPrivate, transport, parent ) +{ + init(); +} + +SendmailConfigWidget::SendmailConfigWidget( SendmailConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ) + : TransportConfigWidget( dd, transport, parent ) +{ + init(); +} + +void SendmailConfigWidget::init() +{ + Q_D( SendmailConfigWidget ); + + d->ui.setupUi( this ); + d->ui.kcfg_host->setMode( KFile::File|KFile::ExistingOnly|KFile::LocalOnly ); + d->manager->addWidget( this ); // otherwise it doesn't find out about these widgets + d->manager->updateWidgets(); + + if( d->ui.kcfg_host->url().isEmpty() ) { + // Locate sendmail. + // This is imperfect, because it shows the standard path if an empty path + // is saved in the config. + d->ui.kcfg_host->setText( KStandardDirs::findExe( QLatin1String( "sendmail" ) ) ); + } +} + + +#include "sendmailconfigwidget.moc" diff --git a/mailtransport/transportmanagementwidget.h b/mailtransport/sendmailconfigwidget.h similarity index 54% copy from mailtransport/transportmanagementwidget.h copy to mailtransport/sendmailconfigwidget.h index 3b10d22ed..8327aa8c5 100644 --- a/mailtransport/transportmanagementwidget.h +++ b/mailtransport/sendmailconfigwidget.h @@ -1,66 +1,64 @@ /* + Copyright (c) 2009 Constantin Berzan + + Based on MailTransport code by: Copyright (c) 2006 - 2007 Volker Krause Based on KMail code by: - Copyright (C) 2001-2003 Marc Mutz + 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_TRANSPORTMANAGEMENTWIDGET_H -#define MAILTRANSPORT_TRANSPORTMANAGEMENTWIDGET_H +#ifndef MAILTRANSPORT_SENDMAILCONFIGWIDGET_H +#define MAILTRANSPORT_SENDMAILCONFIGWIDGET_H -#include -#include +#include "transportconfigwidget.h" namespace MailTransport { +class Transport; + +/** + @internal +*/ +class SendmailConfigWidgetPrivate; + /** - A widget to manage mail transports. + @internal + Configuration widget for a Sendmail transport. */ -class MAILTRANSPORT_EXPORT TransportManagementWidget : public QWidget +class SendmailConfigWidget : public TransportConfigWidget { Q_OBJECT public: - /** - Creates a new TransportManagementWidget. - @param parent The parent widget. - */ - TransportManagementWidget( QWidget *parent = 0 ); - - /** - Destroys the widget. - */ - virtual ~TransportManagementWidget(); - - private Q_SLOTS: - void fillTransportList(); - void updateButtonState(); - void addClicked(); - void editClicked(); - void removeClicked(); - void defaultClicked(); - void slotSendmail(); + explicit SendmailConfigWidget( Transport *transport, QWidget *parent = 0 ); + //virtual ~SendmailConfigWidget(); + + protected: + SendmailConfigWidget( SendmailConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ); private: - class Private; - Private * const d; + Q_DECLARE_PRIVATE( SendmailConfigWidget ) + + void init(); + }; } #endif diff --git a/mailtransport/sendmailsettings.ui b/mailtransport/sendmailsettings.ui index 745b8ad22..fee1cca7e 100644 --- a/mailtransport/sendmailsettings.ui +++ b/mailtransport/sendmailsettings.ui @@ -1,103 +1,43 @@ - - Volker Krause <vkrause@kde.org> + + + Volker Krause <vkrause@kde.org> SendmailSettings - - + + 0 0 400 159 - - - 9 - - - 6 - - - - - Qt::Vertical + + + + + Sendmail &Location: - - - 20 - 21 - - - - - - - - - - - - 75 - true - - - - Transport: Sendmail - - - - - - - &Location: - - + kcfg_host - - - - &Name: - - - kcfg_name - - - - - - - Choos&e... + + + + text - - - - - - - KSeparator + KUrlRequester QFrame -
kseparator.h
-
- - KPushButton - QPushButton -
kpushbutton.h
-
- - KLineEdit - QLineEdit -
klineedit.h
+
kurlrequester.h
diff --git a/mailtransport/smtpconfigwidget.cpp b/mailtransport/smtpconfigwidget.cpp new file mode 100644 index 000000000..294467534 --- /dev/null +++ b/mailtransport/smtpconfigwidget.cpp @@ -0,0 +1,326 @@ +/* + 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 "smtpconfigwidget.h" +#include "transportconfigwidget_p.h" +#include "transport.h" +#include "transportmanager.h" +#include "servertest.h" +#include "mailtransport_defs.h" + +#include "ui_smtpsettings.h" + +#include +#include + +#include + +namespace { + +// TODO: is this really necessary? +class BusyCursorHelper : public QObject +{ + public: + inline BusyCursorHelper( QObject *parent ) : QObject( parent ) + { + qApp->setOverrideCursor( Qt::BusyCursor ); + } + + inline ~BusyCursorHelper() + { + qApp->restoreOverrideCursor(); + } +}; + +} + +using namespace MailTransport; + +class MailTransport::SMTPConfigWidgetPrivate : public TransportConfigWidgetPrivate +{ + public: + Ui::SMTPSettings ui; + + ServerTest *serverTest; + QButtonGroup *encryptionGroup; + QButtonGroup *authGroup; + + // detected authentication capabilities + QList noEncCapa, sslCapa, tlsCapa; + + bool serverTestFailed; + + void resetAuthCapabilities() + { + noEncCapa.clear(); + noEncCapa << Transport::EnumAuthenticationType::LOGIN + << Transport::EnumAuthenticationType::PLAIN + << Transport::EnumAuthenticationType::CRAM_MD5 + << Transport::EnumAuthenticationType::DIGEST_MD5 + << Transport::EnumAuthenticationType::NTLM + << Transport::EnumAuthenticationType::GSSAPI; + sslCapa = tlsCapa = noEncCapa; + if ( authGroup ) { + updateAuthCapbilities(); + } + } + + void updateAuthCapbilities() + { + if ( serverTestFailed ) { + return; + } + + QList capa = noEncCapa; + if ( ui.ssl->isChecked() ) { + capa = sslCapa; + } else if ( ui.tls->isChecked() ) { + capa = tlsCapa; + } + + for ( int i = 0; i < authGroup->buttons().count(); ++i ) { + authGroup->buttons().at( i )->setEnabled( capa.contains( i ) ); + } + + if ( capa.count() == 0 ) { + ui.noAuthPossible->setVisible( true ); + ui.kcfg_requiresAuthentication->setChecked( false ); + ui.kcfg_requiresAuthentication->setEnabled( false ); + } else { + ui.noAuthPossible->setVisible( false ); + ui.kcfg_requiresAuthentication->setEnabled( true ); + } + } +}; + +SMTPConfigWidget::SMTPConfigWidget( Transport *transport, QWidget *parent ) + : TransportConfigWidget( *new SMTPConfigWidgetPrivate, transport, parent ) +{ + init(); +} + +SMTPConfigWidget::SMTPConfigWidget( SMTPConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ) + : TransportConfigWidget( dd, transport, parent ) +{ + init(); +} + +void SMTPConfigWidget::init() +{ + Q_D( SMTPConfigWidget ); + d->serverTest = 0; + + connect( TransportManager::self(), SIGNAL(passwordsChanged()), + SLOT(passwordsLoaded()) ); + + d->ui.setupUi( this ); + d->manager->addWidget( this ); // otherwise it doesn't find out about these widgets + d->manager->updateWidgets(); + + d->encryptionGroup = new QButtonGroup( this ); + d->encryptionGroup->addButton( d->ui.none ); + d->encryptionGroup->addButton( d->ui.ssl ); + d->encryptionGroup->addButton( d->ui.tls ); + + d->authGroup = new QButtonGroup( this ); + d->authGroup->addButton( d->ui.login ); + d->authGroup->addButton( d->ui.plain ); + d->authGroup->addButton( d->ui.crammd5 ); + d->authGroup->addButton( d->ui.digestmd5 ); + d->authGroup->addButton( d->ui.gssapi ); + d->authGroup->addButton( d->ui.ntlm ); + d->resetAuthCapabilities(); + + if ( KProtocolInfo::capabilities( SMTP_PROTOCOL ).contains( QLatin1String( "SASL" ) ) == 0 ) { + d->ui.ntlm->hide(); + d->ui.gssapi->hide(); + } + + connect( d->ui.checkCapabilities, SIGNAL( clicked() ), + SLOT( checkSmtpCapabilities() ) ); + connect( d->ui.kcfg_host, SIGNAL( textChanged(QString) ), + SLOT( hostNameChanged(QString) ) ); + connect( d->ui.kcfg_encryption, SIGNAL( clicked(int) ), + SLOT( encryptionChanged(int) ) ); + connect( d->ui.kcfg_requiresAuthentication, SIGNAL( toggled(bool) ), + SLOT( ensureValidAuthSelection() ) ); + + // load the password + d->transport->updatePasswordState(); + if ( d->transport->isComplete() ) { + d->ui.password->setText( d->transport->password() ); + } else { + if ( d->transport->requiresAuthentication() ) { + TransportManager::self()->loadPasswordsAsync(); + } + } + + hostNameChanged( d->transport->host() ); +} + +void SMTPConfigWidget::checkSmtpCapabilities() +{ + Q_D( SMTPConfigWidget ); + + d->serverTest = new ServerTest( this ); + d->serverTest->setProtocol( SMTP_PROTOCOL ); + d->serverTest->setServer( d->ui.kcfg_host->text().trimmed() ); + if ( d->ui.kcfg_specifyHostname->isChecked() ) { + d->serverTest->setFakeHostname( d->ui.kcfg_localHostname->text() ); + } + d->serverTest->setProgressBar( d->ui.checkCapabilitiesProgress ); + BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( d->serverTest ); + + connect( d->serverTest, SIGNAL( finished( QList ) ), + SLOT(slotFinished( QList ))); + connect( d->serverTest, SIGNAL( finished( QList ) ), + busyCursorHelper, SLOT( deleteLater() ) ); + d->ui.checkCapabilities->setEnabled( false ); + d->serverTest->start(); + d->serverTestFailed = false; +} + +void SMTPConfigWidget::apply() +{ + Q_D( SMTPConfigWidget ); + + Q_ASSERT( d->manager ); + d->manager->updateSettings(); + d->transport->setPassword( d->ui.password->text() ); + + TransportConfigWidget::apply(); +} + +void SMTPConfigWidget::passwordsLoaded() +{ + Q_D( SMTPConfigWidget ); + + // Load the password from the original to our cloned copy + d->transport->updatePasswordState(); + + if ( d->ui.password->text().isEmpty() ) { + d->ui.password->setText( d->transport->password() ); + } +} + +static void checkHighestEnabledButton( QButtonGroup *group ) +{ + Q_ASSERT( group ); + + for ( int i = group->buttons().count() - 1; i >= 0; --i ) { + QAbstractButton *b = group->buttons().at( i ); + if ( b && b->isEnabled() ) { + b->animateClick(); + return; + } + } +} + +// TODO rename +void SMTPConfigWidget::slotFinished( QList results ) +{ + Q_D( SMTPConfigWidget ); + + d->ui.checkCapabilities->setEnabled( true ); + d->serverTest->deleteLater(); + + // If the servertest did not find any useable authentication modes, assume the + // connection failed and don't disable any of the radioboxes. + if ( results.isEmpty() ) { + d->serverTestFailed = true; + return; + } + + // encryption method + d->ui.none->setEnabled( results.contains( Transport::EnumEncryption::None ) ); + d->ui.ssl->setEnabled( results.contains( Transport::EnumEncryption::SSL ) ); + d->ui.tls->setEnabled( results.contains( Transport::EnumEncryption::TLS ) ); + checkHighestEnabledButton( d->encryptionGroup ); + + d->noEncCapa = d->serverTest->normalProtocols(); + if ( d->ui.tls->isEnabled() ) { + d->tlsCapa = d->serverTest->tlsProtocols(); + } else { + d->tlsCapa.clear(); + } + d->sslCapa = d->serverTest->secureProtocols(); + d->updateAuthCapbilities(); + checkHighestEnabledButton( d->authGroup ); +} + +void SMTPConfigWidget::hostNameChanged( const QString &text ) +{ + // TODO: really? is this done at every change? wtf + + Q_D( SMTPConfigWidget ); + + // sanitize hostname... + int pos = d->ui.kcfg_host->cursorPosition(); + d->ui.kcfg_host->blockSignals( true ); + d->ui.kcfg_host->setText( text.trimmed() ); + d->ui.kcfg_host->blockSignals( false ); + d->ui.kcfg_host->setCursorPosition( pos ); + + d->resetAuthCapabilities(); + for ( int i = 0; d->encryptionGroup && i < d->encryptionGroup->buttons().count(); i++ ) { + d->encryptionGroup->buttons().at( i )->setEnabled( true ); + } +} + +void SMTPConfigWidget::ensureValidAuthSelection() +{ + Q_D( SMTPConfigWidget ); + + // adjust available authentication methods + d->updateAuthCapbilities(); + foreach ( QAbstractButton *b, d->authGroup->buttons() ) { + if ( b->isChecked() && !b->isEnabled() ) { + checkHighestEnabledButton( d->authGroup ); + break; + } + } +} + +void SMTPConfigWidget::encryptionChanged( int enc ) +{ + Q_D( SMTPConfigWidget ); + kDebug() << enc; + + // adjust port + if ( enc == Transport::EnumEncryption::SSL ) { + if ( d->ui.kcfg_port->value() == SMTP_PORT ) { + d->ui.kcfg_port->setValue( SMTPS_PORT ); + } + } else { + if ( d->ui.kcfg_port->value() == SMTPS_PORT ) { + d->ui.kcfg_port->setValue( SMTP_PORT ); + } + } + + ensureValidAuthSelection(); +} + +#include "smtpconfigwidget.moc" diff --git a/mailtransport/transportconfigdialog.h b/mailtransport/smtpconfigwidget.h similarity index 58% copy from mailtransport/transportconfigdialog.h copy to mailtransport/smtpconfigwidget.h index f0cc949d6..4bce4d51b 100644 --- a/mailtransport/transportconfigdialog.h +++ b/mailtransport/smtpconfigwidget.h @@ -1,77 +1,77 @@ /* + Copyright (c) 2009 Constantin Berzan + + Based on MailTransport code by: Copyright (c) 2006 - 2007 Volker Krause 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 +#ifndef MAILTRANSPORT_SMTPCONFIGWIDGET_H +#define MAILTRANSPORT_SMTPCONFIGWIDGET_H -#include -#include +#include "transportconfigwidget.h" namespace MailTransport { class Transport; /** - Configuration dialog for a mail transport. + @internal +*/ +class SMTPConfigWidgetPrivate; + +/** + @internal + Configuration widget for a SMTP transport. */ -class MAILTRANSPORT_EXPORT TransportConfigDialog : public KDialog +class SMTPConfigWidget : public TransportConfigWidget { Q_OBJECT public: - /** - Creates a new mail transport configuration dialog for the given - Transport object. - @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(); + explicit SMTPConfigWidget( Transport *transport, QWidget *parent = 0 ); + //virtual ~SMTPConfigWidget(); + + public Q_SLOTS: + /** reimpl */ + virtual void apply(); + + protected: + // TODO probably not needed since no one will inherit from us + SMTPConfigWidget( SMTPConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ); private Q_SLOTS: void checkSmtpCapabilities(); - void chooseSendmail(); void passwordsLoaded(); - void save(); - void slotUser3(); void slotFinished( QList results ); void hostNameChanged( const QString &text ); void encryptionChanged( int enc ); void ensureValidAuthSelection(); private: - class Private; - Private *const d; + Q_DECLARE_PRIVATE( SMTPConfigWidget ) + + void init(); - Q_SIGNALS: - void sendmailClicked(); }; } #endif diff --git a/mailtransport/smtpjob.h b/mailtransport/smtpjob.h index d6eacd508..c2b3e758d 100644 --- a/mailtransport/smtpjob.h +++ b/mailtransport/smtpjob.h @@ -1,83 +1,83 @@ /* Copyright (c) 2007 Volker Krause Based on KMail code by: Copyright (c) 1996-1998 Stefan Taferner 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_SMTPJOB_H #define MAILTRANSPORT_SMTPJOB_H #include namespace KIO { class Job; class Slave; } class SmtpJobPrivate; namespace MailTransport { /** Mail transport job for SMTP. Internally, all jobs for a specific transport are queued to use the same KIO::Slave. This avoids multiple simultaneous connections to the server, which is not always allowed. Also, re-using an already existing connection avoids the login overhead and can improve performance. Precommands are automatically executed, once per opening a connection to the server (not necessarily once per message). */ class MAILTRANSPORT_EXPORT SmtpJob : public TransportJob { Q_OBJECT public: /** - Creates a SendmailJob. + Creates a SmtpJob. @param transport The transport settings. @param parent The parent object. */ explicit SmtpJob( Transport *transport, QObject *parent = 0 ); /** Deletes this job. */ virtual ~SmtpJob(); protected: virtual void doStart(); virtual bool doKill(); protected Q_SLOTS: virtual void slotResult( KJob *job ); void slaveError( KIO::Slave *slave, int errorCode, const QString &errorMsg ); private: void startSmtpJob(); private Q_SLOTS: void dataRequest( KIO::Job *job, QByteArray &data ); private: SmtpJobPrivate *const d; }; } #endif diff --git a/mailtransport/smtpsettings.ui b/mailtransport/smtpsettings.ui index cd6140c1a..fcbaadb7a 100644 --- a/mailtransport/smtpsettings.ui +++ b/mailtransport/smtpsettings.ui @@ -1,574 +1,513 @@ Volker Krause <vkrause@kde.org>, KovoKs <tomalbers@kde.nl> SMTPSettings 0 0 - 524 - 509 + 362 + 438 - - - - 75 - true - - - - Transport: SMTP - - - - - - - 0 General - - - - - &Name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - kcfg_name - - - - - - - - - - Outgoing mail &server: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Outgoing mail &server: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_host + + + + + + + + + + &Port: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_port + + + + + + + + + 25 - - kcfg_host + + 1 - - - - - - - &Port: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + Qt::Horizontal - - kcfg_port + + + 231 + 23 + - - - - - - - - 25 - - - 1 - - - - - - - Qt::Horizontal - - - - 231 - 23 - - - - - + - - - - - - Encryption - - + + + + Encryption + + + + - - - - - &None - - - - - - - &SSL - - - - - - - &TLS - - - - + + + &None + + - + - Check &What the Server Supports + &SSL - - - false + + + &TLS - - - - - - Qt::Horizontal - - - - 166 - 81 - - - - - + + + + + Check &What the Server Supports + + + + + + + false + + + + + Advanced - - - - + + + + + Server &requires authentication + + + + + + false - - QFrame::Box + + &Login: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_userName + + + + + + + false - - QFrame::Raised + + + + + + false - This server does not support authentication + P&assword: - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + password - - + + + + false + + + The password to send to the server for authorization. + + + QLineEdit::Password + + + + + + + false + - Server &requires authentication + &Store SMTP password - - - - - - false - - - &Login: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - kcfg_userName - - - - - - - false - - - - - - - false - - - P&assword: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - password - - - - - - - false - - - The password to send to the server for authorization. - - - QLineEdit::Password - - - - - - - false - - - &Store SMTP password - - - - - - - false - - - Authentication Method - + + + + false + + + Authentication Method + + + - - - - - &LOGIN - - - - - - - &PLAIN - - - - - - - CRAM-MD&5 - - - - - - - &DIGEST-MD5 - - - - - - - &GSSAPI - - - - - - - &NTLM - - - - + + + &LOGIN + + + + + + + &PLAIN + + + + + + + CRAM-MD&5 + + + + + + + &DIGEST-MD5 + + + + + + + &GSSAPI + + + + + + + &NTLM + + - - - + + + - + - + Sen&d custom hostname to server - - - - - - false - - - Hos&tname: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - kcfg_localHostname - - - - - - - false - - - - + + + + false + + + Hos&tname: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_localHostname + + + + + + + false + + - + - - - - - - Precommand: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - + + + + Precommand: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + 0 + 0 + 100 + 30 + + + + false + + + QFrame::Box + + + QFrame::Raised + + + This server does not support authentication + + + Qt::AlignCenter + + KButtonGroup QGroupBox
kbuttongroup.h
1
KPushButton QPushButton
kpushbutton.h
KLineEdit QLineEdit
klineedit.h
1
KTabWidget QTabWidget
ktabwidget.h
1
KIntNumInput QWidget
knuminput.h
KSeparator QFrame
kseparator.h
1
- tabWidget - kcfg_name kcfg_host kcfg_requiresAuthentication toggled(bool) usernameLabel setEnabled(bool) 29 88 112 117 kcfg_requiresAuthentication toggled(bool) kcfg_userName setEnabled(bool) 35 85 186 115 kcfg_requiresAuthentication toggled(bool) passwordLabel setEnabled(bool) 49 88 61 142 kcfg_requiresAuthentication toggled(bool) password setEnabled(bool) 43 89 140 142 kcfg_requiresAuthentication toggled(bool) kcfg_storePassword setEnabled(bool) 75 86 62 176 kcfg_requiresAuthentication toggled(bool) kcfg_authenticationType setEnabled(bool) 82 89 78 202 kcfg_specifyHostname toggled(bool) hostnameLabel setEnabled(bool) 90 334 81 357 kcfg_specifyHostname toggled(bool) kcfg_localHostname setEnabled(bool) 185 327 179 360
diff --git a/mailtransport/tests/transportmgr.cpp b/mailtransport/tests/transportmgr.cpp index be6c7accb..211a916ea 100644 --- a/mailtransport/tests/transportmgr.cpp +++ b/mailtransport/tests/transportmgr.cpp @@ -1,146 +1,146 @@ /* 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 "transportmgr.h" #include #include #include #include #include #include #include #include +#include #include -#include using namespace MailTransport; TransportMgr::TransportMgr() : mCurrentJob( 0 ) { new TransportManagementWidget( this ); mComboBox = new TransportComboBox( this ); mComboBox->setEditable( true ); QPushButton *b = new QPushButton( "&Edit", this ); connect( b, SIGNAL(clicked(bool)), SLOT(editBtnClicked()) ); b = new QPushButton( "&Remove all transports", this ); connect( b, SIGNAL(clicked(bool)), SLOT(removeAllBtnClicked()) ); mSenderEdit = new KLineEdit( this ); mSenderEdit->setClickMessage( "Sender" ); mToEdit = new KLineEdit( this ); mToEdit->setClickMessage( "To" ); mCcEdit = new KLineEdit( this ); mCcEdit->setClickMessage( "Cc" ); mBccEdit = new KLineEdit( this ); mBccEdit->setClickMessage( "Bcc" ); - mMailEdit = new QTextEdit( this ); + mMailEdit = new KTextEdit( this ); mMailEdit->setAcceptRichText( false ); mMailEdit->setLineWrapMode( QTextEdit::NoWrap ); b = new QPushButton( "&Send", this ); connect( b, SIGNAL(clicked(bool)), SLOT(sendBtnClicked()) ); b = new QPushButton( "&Cancel", this ); connect( b, SIGNAL(clicked(bool)), SLOT(cancelBtnClicked()) ); } void TransportMgr::removeAllBtnClicked() { MailTransport::TransportManager *manager = MailTransport::TransportManager::self(); QList transports = manager->transports(); for ( int i=0; i < transports.count(); i++ ) { MailTransport::Transport *transport = transports.at( i ); kDebug() << transport->host(); manager->removeTransport( transport->id() ); } } void TransportMgr::editBtnClicked() { TransportConfigDialog *t = new TransportConfigDialog( TransportManager::self()->transportById( mComboBox->currentTransportId() ), this ); t->exec(); delete t; } void TransportMgr::sendBtnClicked() { TransportJob *job; job = TransportManager::self()->createTransportJob( mComboBox->currentTransportId() ); if ( !job ) { kDebug() << "Invalid transport!"; return; } job->setSender( mSenderEdit->text() ); job->setTo( mToEdit->text().isEmpty() ? QStringList() : mToEdit->text().split( ',' ) ); job->setCc( mCcEdit->text().isEmpty() ? QStringList() : mCcEdit->text().split( ',' ) ); job->setBcc( mBccEdit->text().isEmpty() ? QStringList() : mBccEdit->text().split( ',' ) ); job->setData( mMailEdit->document()->toPlainText().toLatin1() ); connect( job, SIGNAL(result(KJob*)), SLOT(jobResult(KJob*)) ); connect( job, SIGNAL(percent(KJob*,unsigned long)), SLOT(jobPercent(KJob*,unsigned long)) ); connect( job, SIGNAL(infoMessage(KJob*,QString,QString)), SLOT(jobInfoMessage(KJob*,QString,QString)) ); mCurrentJob = job; TransportManager::self()->schedule( job ); } void TransportMgr::cancelBtnClicked() { if ( mCurrentJob ) { kDebug() << "kill success:" << mCurrentJob->kill(); } mCurrentJob = 0; } int main( int argc, char **argv ) { KCmdLineArgs::init( argc, argv, "transportmgr", 0, ki18n( "transportmgr" ), "0", ki18n( "Mail Transport Manager Demo" ) ); KApplication app; TransportMgr *t = new TransportMgr(); t->show(); app.exec(); delete t; } void TransportMgr::jobResult( KJob *job ) { kDebug() << job->error() << job->errorText(); mCurrentJob = 0; } void TransportMgr::jobPercent( KJob *job, unsigned long percent ) { Q_UNUSED( job ); kDebug() << percent << "%"; } void TransportMgr::jobInfoMessage( KJob *job, const QString &info, const QString &info2 ) { Q_UNUSED( job ); kDebug() << info; kDebug() << info2; } #include "transportmgr.moc" diff --git a/mailtransport/tests/transportmgr.h b/mailtransport/tests/transportmgr.h index e5f14ed49..f1dda1cc0 100644 --- a/mailtransport/tests/transportmgr.h +++ b/mailtransport/tests/transportmgr.h @@ -1,53 +1,53 @@ /* 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 TRANSPORTMGR_H #define TRANSPORTMGR_H #include #include class KJob; class KLineEdit; -class QTextEdit; +class KTextEdit; class TransportMgr : public KVBox { Q_OBJECT public: TransportMgr(); private slots: void removeAllBtnClicked(); void editBtnClicked(); void sendBtnClicked(); void cancelBtnClicked(); void jobResult( KJob *job ); void jobPercent( KJob *job, unsigned long percent ); void jobInfoMessage( KJob *job, const QString &info, const QString &info2 ); private: MailTransport::TransportComboBox *mComboBox; KLineEdit *mSenderEdit, *mToEdit, *mCcEdit, *mBccEdit; - QTextEdit *mMailEdit; + KTextEdit *mMailEdit; KJob *mCurrentJob; }; #endif diff --git a/mailtransport/transport.cpp b/mailtransport/transport.cpp index 6304cbe5c..1b902c4c3 100644 --- a/mailtransport/transport.cpp +++ b/mailtransport/transport.cpp @@ -1,273 +1,292 @@ /* 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 #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: 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(); } // 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 ); } #include "transport.moc" diff --git a/mailtransport/transport.h b/mailtransport/transport.h index 8e8a00512..8d6c2b30c 100644 --- a/mailtransport/transport.h +++ b/mailtransport/transport.h @@ -1,127 +1,133 @@ /* 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 class TransportPrivate; namespace MailTransport { /** Represents the settings of a specific mail transport. To create a new empty Transport object, use TransportManager::createTransport(). */ class MAILTRANSPORT_EXPORT Transport : public TransportBase { Q_OBJECT friend class TransportManager; public: /** 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; 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 1ef1e5a69..e755e89b9 100644 --- a/mailtransport/transportconfigdialog.cpp +++ b/mailtransport/transportconfigdialog.cpp @@ -1,394 +1,64 @@ /* 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 "servertest.h" -#include "mailtransport_defs.h" - -#include "ui_smtpsettings.h" -#include "ui_sendmailsettings.h" - -#include -#include -#include -#include - -#include - -namespace { -class BusyCursorHelper : public QObject -{ - public: - inline BusyCursorHelper( QObject *parent ) : QObject( parent ) - { - qApp->setOverrideCursor( Qt::BusyCursor ); - } +#include - inline ~BusyCursorHelper() - { - qApp->restoreOverrideCursor(); - } -}; - -} +#include using namespace MailTransport; class MailTransport::TransportConfigDialog::Private { public: - Transport *transport; - - Ui::SMTPSettings smtp; - Ui::SendmailSettings sendmail; - - KConfigDialogManager *manager; - KLineEdit *passwordEdit; - ServerTest *serverTest; - QButtonGroup *encryptionGroup; - QButtonGroup *authGroup; - - // detected authentication capabilities - QList noEncCapa, sslCapa, tlsCapa; - - bool serverTestFailed; - - void resetAuthCapabilities() - { - noEncCapa.clear(); - noEncCapa << Transport::EnumAuthenticationType::LOGIN - << Transport::EnumAuthenticationType::PLAIN - << Transport::EnumAuthenticationType::CRAM_MD5 - << Transport::EnumAuthenticationType::DIGEST_MD5 - << Transport::EnumAuthenticationType::NTLM - << Transport::EnumAuthenticationType::GSSAPI; - sslCapa = tlsCapa = noEncCapa; - if ( authGroup ) { - updateAuthCapbilities(); - } - } - - void updateAuthCapbilities() - { - Q_ASSERT( transport->type() == Transport::EnumType::SMTP ); - - if ( serverTestFailed ) { - return; - } - - QList capa = noEncCapa; - if ( smtp.ssl->isChecked() ) { - capa = sslCapa; - } else if ( smtp.tls->isChecked() ) { - capa = tlsCapa; - } - - for ( int i = 0; i < authGroup->buttons().count(); ++i ) { - authGroup->buttons().at( i )->setEnabled( capa.contains( i ) ); - } + TransportConfigWidget *configWidget; + // TODO not really necessary right now; used only in constructor - if ( capa.count() == 0 ) { - smtp.noAuthPossible->setVisible( true ); - smtp.kcfg_requiresAuthentication->setChecked( false ); - smtp.kcfg_requiresAuthentication->setEnabled( false ); - } else { - smtp.noAuthPossible->setVisible( false ); - smtp.kcfg_requiresAuthentication->setEnabled( true ); - } - } }; TransportConfigDialog::TransportConfigDialog( Transport *transport, QWidget *parent ) : KDialog( parent ), d( new Private ) { Q_ASSERT( transport ); - d->transport = transport; - d->passwordEdit = 0; - d->serverTest = 0; - d->encryptionGroup = 0; - d->authGroup = 0; - d->resetAuthCapabilities(); + d->configWidget = TransportManager::self()->configWidgetForTransport( transport ); + kDebug() << "transport" << transport->id() << "config widget" << d->configWidget; + Q_ASSERT( d->configWidget ); + setMainWidget( d->configWidget ); - setButtons( Ok|Cancel|User3 ); - showButton( User3, false ); - setButtonText( User3, i18n( "Use Sendmail" ) ); - connect( this, SIGNAL( user3Clicked() ), SLOT( slotUser3() ) ); - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - connect( TransportManager::self(), SIGNAL(passwordsChanged()), - SLOT(passwordsLoaded()) ); - - switch ( transport->type() ) { - case Transport::EnumType::SMTP: - { - showButton( User3, true ); - - d->smtp.setupUi( mainWidget() ); - d->passwordEdit = d->smtp.password; - - d->encryptionGroup = new QButtonGroup( this ); - d->encryptionGroup->addButton( d->smtp.none ); - d->encryptionGroup->addButton( d->smtp.ssl ); - d->encryptionGroup->addButton( d->smtp.tls ); - - d->authGroup = new QButtonGroup( this ); - d->authGroup->addButton( d->smtp.login ); - d->authGroup->addButton( d->smtp.plain ); - d->authGroup->addButton( d->smtp.crammd5 ); - d->authGroup->addButton( d->smtp.digestmd5 ); - d->authGroup->addButton( d->smtp.gssapi ); - d->authGroup->addButton( d->smtp.ntlm ); - - if ( KProtocolInfo::capabilities( SMTP_PROTOCOL ).contains( QLatin1String( "SASL" ) ) == 0 ) { - d->smtp.ntlm->hide(); - d->smtp.gssapi->hide(); - } - - connect( d->smtp.checkCapabilities, SIGNAL(clicked()), - SLOT(checkSmtpCapabilities()) ); - connect( d->smtp.kcfg_host, SIGNAL(textChanged(QString)), - SLOT(hostNameChanged(QString)) ); - connect( d->smtp.kcfg_encryption, SIGNAL(clicked(int)), - SLOT(encryptionChanged(int)) ); - connect( d->smtp.kcfg_requiresAuthentication, SIGNAL( toggled(bool) ), - SLOT( ensureValidAuthSelection() ) ); - break; - } - case Transport::EnumType::Sendmail: - { - d->sendmail.setupUi( mainWidget() ); - - connect( d->sendmail.chooseButton, SIGNAL(clicked()), - SLOT(chooseSendmail()) ); - connect( d->sendmail.kcfg_host, SIGNAL(textChanged(QString)), - SLOT(hostNameChanged(QString)) ); - } - } - - // load the password if necessary - if ( d->passwordEdit ) { - if ( d->transport->isComplete() ) { - d->passwordEdit->setText( d->transport->password() ); - } else { - if ( d->transport->requiresAuthentication() ) { - TransportManager::self()->loadPasswordsAsync(); - } - } - } - - d->manager = new KConfigDialogManager( this, transport ); - d->manager->updateWidgets(); - hostNameChanged( d->transport->host() ); + setButtons( Ok|Cancel ); + connect( this, SIGNAL( okClicked() ), d->configWidget, SLOT( apply() ) ); } TransportConfigDialog::~ TransportConfigDialog() { delete d; } -void TransportConfigDialog::checkSmtpCapabilities() -{ - Q_ASSERT( d->transport->type() == Transport::EnumType::SMTP ); - - d->serverTest = new ServerTest( this ); - d->serverTest->setProtocol( SMTP_PROTOCOL ); - d->serverTest->setServer( d->smtp.kcfg_host->text().trimmed() ); - if ( d->smtp.kcfg_specifyHostname->isChecked() ) { - d->serverTest->setFakeHostname( d->smtp.kcfg_localHostname->text() ); - } - d->serverTest->setProgressBar( d->smtp.checkCapabilitiesProgress ); - BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( d->serverTest ); - - connect( d->serverTest, SIGNAL(finished( QList< int > )), - SLOT(slotFinished( QList< int > ))); - connect( d->serverTest, SIGNAL(finished( QList< int > )), - busyCursorHelper, SLOT(deleteLater()) ); - d->smtp.checkCapabilities->setEnabled( false ); - d->serverTest->start(); - d->serverTestFailed = false; -} - -void TransportConfigDialog::save() -{ - d->manager->updateSettings(); - if ( d->passwordEdit ) { - d->transport->setPassword( d->passwordEdit->text() ); - } - - // enforce unique name - QStringList existingNames; - foreach ( Transport *t, TransportManager::self()->transports() ) { - if ( t->id() != d->transport->id() ) { - existingNames << t->name(); - } - } - int suffix = 1; - QString origName = d->transport->name(); - while ( existingNames.contains( d->transport->name() ) ) { - d->transport->setName( i18nc( "%1: name; %2: number appended to it to make " - "it unique among a list of names", "%1 #%2", origName, suffix ) ); - ++suffix; - } - - d->transport->writeConfig(); -} - -void TransportConfigDialog::slotUser3() -{ - reject(); - emit sendmailClicked(); -} - -void TransportConfigDialog::chooseSendmail() -{ - Q_ASSERT( d->transport->type() == Transport::EnumType::Sendmail ); - - KFileDialog dialog( KUrl( "/" ), QString(), this ); - dialog.setCaption( i18n( "Choose sendmail Location" ) ); - - if ( dialog.exec() == QDialog::Accepted ) { - KUrl url = dialog.selectedUrl(); - if ( url.isEmpty() == true ) { - return; - } - if ( !url.isLocalFile() ) { - KMessageBox::sorry( this, i18n( "Only local files allowed." ) ); - return; - } - d->sendmail.kcfg_host->setText( url.path() ); - } -} - -void TransportConfigDialog::passwordsLoaded() -{ - Q_ASSERT( d->passwordEdit ); - - // Load the password from the original to our cloned copy - d->transport->updatePasswordState(); - - if ( d->passwordEdit->text().isEmpty() ) { - d->passwordEdit->setText( d->transport->password() ); - } -} - -static void checkHighestEnabledButton( QButtonGroup *group ) -{ - Q_ASSERT( group ); - - for ( int i = group->buttons().count() - 1; i >= 0; --i ) { - QAbstractButton *b = group->buttons().at( i ); - if ( b && b->isEnabled() ) { - b->animateClick(); - return; - } - } -} - -void TransportConfigDialog::slotFinished( QList results ) -{ - d->smtp.checkCapabilities->setEnabled( true ); - d->serverTest->deleteLater(); - - // If the servertest did not find any useable authentication modes, assume the - // connection failed and don't disable any of the radioboxes. - if ( results.isEmpty() ) { - d->serverTestFailed = true; - return; - } - - // encryption method - d->smtp.none->setEnabled( results.contains( Transport::EnumEncryption::None ) ); - d->smtp.ssl->setEnabled( results.contains( Transport::EnumEncryption::SSL ) ); - d->smtp.tls->setEnabled( results.contains( Transport::EnumEncryption::TLS ) ); - checkHighestEnabledButton( d->encryptionGroup ); - - d->noEncCapa = d->serverTest->normalProtocols(); - if ( d->smtp.tls->isEnabled() ) { - d->tlsCapa = d->serverTest->tlsProtocols(); - } else { - d->tlsCapa.clear(); - } - d->sslCapa = d->serverTest->secureProtocols(); - d->updateAuthCapbilities(); - checkHighestEnabledButton( d->authGroup ); -} - -void TransportConfigDialog::hostNameChanged( const QString &text ) -{ - // sanitize hostname... - if ( d->transport->type() == Transport::EnumType::Sendmail ) { - int pos = d->sendmail.kcfg_host->cursorPosition(); - d->sendmail.kcfg_host->blockSignals( true ); - d->sendmail.kcfg_host->setText( text.trimmed() ); - d->sendmail.kcfg_host->blockSignals( false ); - d->sendmail.kcfg_host->setCursorPosition( pos ); - } else if ( d->transport->type() == Transport::EnumType::SMTP ) { - int pos = d->smtp.kcfg_host->cursorPosition(); - d->smtp.kcfg_host->blockSignals( true ); - d->smtp.kcfg_host->setText( text.trimmed() ); - d->smtp.kcfg_host->blockSignals( false ); - d->smtp.kcfg_host->setCursorPosition( pos ); - } - - d->resetAuthCapabilities(); - enableButton( Ok, !text.isEmpty() ); - for ( int i = 0; d->encryptionGroup && i < d->encryptionGroup->buttons().count(); i++ ) { - d->encryptionGroup->buttons().at( i )->setEnabled( true ); - } -} - -void TransportConfigDialog::ensureValidAuthSelection() -{ - // adjust available authentication methods - d->updateAuthCapbilities(); - foreach ( QAbstractButton *b, d->authGroup->buttons() ) { - if ( b->isChecked() && !b->isEnabled() ) { - checkHighestEnabledButton( d->authGroup ); - break; - } - } -} - -void TransportConfigDialog::encryptionChanged( int enc ) -{ - Q_ASSERT( d->transport->type() == Transport::EnumType::SMTP ); - kDebug() << enc; - - // adjust port - if ( enc == Transport::EnumEncryption::SSL ) { - if ( d->smtp.kcfg_port->value() == SMTP_PORT ) { - d->smtp.kcfg_port->setValue( SMTPS_PORT ); - } - } else { - if ( d->smtp.kcfg_port->value() == SMTPS_PORT ) { - d->smtp.kcfg_port->setValue( SMTP_PORT ); - } - } - - ensureValidAuthSelection(); -} - #include "transportconfigdialog.moc" diff --git a/mailtransport/transportconfigdialog.h b/mailtransport/transportconfigdialog.h index f0cc949d6..55a816b69 100644 --- a/mailtransport/transportconfigdialog.h +++ b/mailtransport/transportconfigdialog.h @@ -1,77 +1,70 @@ /* 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 { 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. + @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 Q_SLOTS: - void checkSmtpCapabilities(); - void chooseSendmail(); - void passwordsLoaded(); - void save(); - void slotUser3(); - void slotFinished( QList results ); - void hostNameChanged( const QString &text ); - void encryptionChanged( int enc ); - void ensureValidAuthSelection(); - private: class Private; Private *const d; - Q_SIGNALS: - void sendmailClicked(); }; } #endif diff --git a/mailtransport/transportconfigwidget.cpp b/mailtransport/transportconfigwidget.cpp new file mode 100644 index 000000000..bd94234e9 --- /dev/null +++ b/mailtransport/transportconfigwidget.cpp @@ -0,0 +1,84 @@ +/* + 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(); +} + + +#include "transportconfigwidget.moc" diff --git a/mailtransport/transportconfigwidget.h b/mailtransport/transportconfigwidget.h new file mode 100644 index 000000000..907494f1f --- /dev/null +++ b/mailtransport/transportconfigwidget.h @@ -0,0 +1,93 @@ +/* + Copyright (c) 2009 Constantin Berzan + + Based on MailTransport code by: + Copyright (c) 2006 - 2007 Volker Krause + + 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_TRANSPORTCONFIGWIDGET_H +#define MAILTRANSPORT_TRANSPORTCONFIGWIDGET_H + +#include + +class KConfigDialogManager; + +namespace MailTransport { + +class Transport; +class TransportConfigWidgetPrivate; + +/** + @internal + Abstract configuration widget for a mail transport. + There is a derived class for each transport, such as SMTPConfigWidget etc. +*/ +class TransportConfigWidget : public QWidget +{ + Q_OBJECT + + public: + /** + Creates a new mail transport configuration widget for the given + Transport object. + @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 TransportConfigWidget( Transport *transport, QWidget *parent = 0 ); + + /** + Destroys the widget. + */ + virtual ~TransportConfigWidget(); + + /** + @internal + Get the KConfigDialogManager for this widget. + */ + KConfigDialogManager *configManager() const; + + public Q_SLOTS: + /** + Saves the transport's settings. + + The base implementation writes the settings to the config file and makes + sure the transport has a unique name. Reimplement in derived classes to + save your custom settings, and call the base implementation. + */ + // TODO: do we also want to check for invalid settings? + virtual void apply(); + + protected: + TransportConfigWidgetPrivate *const d_ptr; + TransportConfigWidget( TransportConfigWidgetPrivate &dd, Transport *transport, QWidget *parent ); + + private: + Q_DECLARE_PRIVATE( TransportConfigWidget ) + + void init( Transport *transport ); + +}; + +} + +#endif diff --git a/mailtransport/tests/transportmgr.h b/mailtransport/transportconfigwidget_p.h similarity index 52% copy from mailtransport/tests/transportmgr.h copy to mailtransport/transportconfigwidget_p.h index e5f14ed49..32618c9fd 100644 --- a/mailtransport/tests/transportmgr.h +++ b/mailtransport/transportconfigwidget_p.h @@ -1,53 +1,44 @@ /* - Copyright (c) 2006 - 2007 Volker Krause + 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 TRANSPORTMGR_H -#define TRANSPORTMGR_H +#ifndef MAILTRANSPORT_TRANSPORTCONFIGWIDGET_P_H +#define MAILTRANSPORT_TRANSPORTCONFIGWIDGET_P_H -#include -#include +#include "transport.h" -class KJob; -class KLineEdit; -class QTextEdit; +#include -class TransportMgr : public KVBox +namespace MailTransport { - Q_OBJECT +class TransportConfigWidgetPrivate +{ public: - TransportMgr(); - - private slots: - void removeAllBtnClicked(); - void editBtnClicked(); - void sendBtnClicked(); - void cancelBtnClicked(); - void jobResult( KJob *job ); - void jobPercent( KJob *job, unsigned long percent ); - void jobInfoMessage( KJob *job, const QString &info, const QString &info2 ); - - private: - MailTransport::TransportComboBox *mComboBox; - KLineEdit *mSenderEdit, *mToEdit, *mCcEdit, *mBccEdit; - QTextEdit *mMailEdit; - KJob *mCurrentJob; + Transport *transport; + KConfigDialogManager *manager; + + virtual ~TransportConfigWidgetPrivate() + { + } + }; +} + #endif diff --git a/mailtransport/transportlistview.cpp b/mailtransport/transportlistview.cpp new file mode 100644 index 000000000..1471bcc01 --- /dev/null +++ b/mailtransport/transportlistview.cpp @@ -0,0 +1,129 @@ +/* + 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 +#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; + // TODO: perhaps Transport or TransportManager should have nameForType()? + switch ( t->type() ) { + case Transport::EnumType::SMTP: + type = i18nc( "@option SMTP transport", "SMTP" ); + break; + case Transport::EnumType::Sendmail: + type = i18nc( "@option sendmail transport", "Sendmail" ); + break; + case Transport::EnumType::Akonadi: + type = i18nc( "@option Akonadi Resource transport", "Akonadi Resource" ); + break; + } + if ( TransportManager::self()->defaultTransportId() == t->id() ) { + type += i18nc( "@label the default mail transport", " (Default)" ); + } + item->setText( 1, type ); + if ( t->id() == selected ) { + setCurrentItem( item ); + } + } + + // updateButtonState(); //TODO see comment in TransportManagementWidget +} + + +#include "transportlistview.moc" diff --git a/mailtransport/tests/transportmgr.h b/mailtransport/transportlistview.h similarity index 53% copy from mailtransport/tests/transportmgr.h copy to mailtransport/transportlistview.h index e5f14ed49..4061fa4a1 100644 --- a/mailtransport/tests/transportmgr.h +++ b/mailtransport/transportlistview.h @@ -1,53 +1,56 @@ /* - Copyright (c) 2006 - 2007 Volker Krause + 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 TRANSPORTMGR_H -#define TRANSPORTMGR_H +#ifndef MAILTRANSPORT_TRANSPORTLISTVIEW_H +#define MAILTRANSPORT_TRANSPORTLISTVIEW_H -#include -#include -class KJob; -class KLineEdit; -class QTextEdit; +#include -class TransportMgr : public KVBox +namespace MailTransport +{ + +/** + @internal + A QTreeWidget for transports. +*/ +class TransportListView : public QTreeWidget { Q_OBJECT public: - TransportMgr(); + TransportListView( QWidget *parent = 0 ); + //virtual ~TransportListView() {} + + // overloaded from QTreeWidget + void editItem( QTreeWidgetItem *item, int column = 0 ); + + protected slots: + virtual void commitData( QWidget *editor ); private slots: - void removeAllBtnClicked(); - void editBtnClicked(); - void sendBtnClicked(); - void cancelBtnClicked(); - void jobResult( KJob *job ); - void jobPercent( KJob *job, unsigned long percent ); - void jobInfoMessage( KJob *job, const QString &info, const QString &info2 ); - - private: - MailTransport::TransportComboBox *mComboBox; - KLineEdit *mSenderEdit, *mToEdit, *mCcEdit, *mBccEdit; - QTextEdit *mMailEdit; - KJob *mCurrentJob; + void fillTransportList(); // TODO rename? + }; + +} + + #endif diff --git a/mailtransport/transportmanagementwidget.cpp b/mailtransport/transportmanagementwidget.cpp index b5e18a702..a50c315d3 100644 --- a/mailtransport/transportmanagementwidget.cpp +++ b/mailtransport/transportmanagementwidget.cpp @@ -1,183 +1,130 @@ /* 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 "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(); - d->ui.transportList->setHeaderLabels( QStringList() - << i18nc( "@title:column email transport name", "Name" ) - << i18nc( "@title:column email transport type", "Type" ) ); - d->ui.transportList->sortItems( 0, Qt::AscendingOrder ); 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()) ); - - fillTransportList(); - connect( TransportManager::self(), SIGNAL(transportsChanged()), - SLOT(fillTransportList()) ); } TransportManagementWidget::~TransportManagementWidget() { delete d; } -void TransportManagementWidget::fillTransportList() -{ - // try to preserve the selection - int selected = -1; - if ( d->ui.transportList->currentItem() ) { - selected = d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt(); - } - - d->ui.transportList->clear(); - foreach ( Transport *t, TransportManager::self()->transports() ) { - QTreeWidgetItem *item = new QTreeWidgetItem( d->ui.transportList ); - item->setData( 0, Qt::UserRole, t->id() ); - item->setText( 0, t->name() ); - QString type; - switch ( t->type() ) { - case Transport::EnumType::SMTP: - type = i18nc( "@option SMTP transport", "SMTP" ); - break; - case Transport::EnumType::Sendmail: - type = i18nc( "@option sendmail transport", "Sendmail" ); - break; - } - if ( TransportManager::self()->defaultTransportId() == t->id() ) { - type += i18nc( "@label the default mail transport", " (Default)" ); - } - item->setText( 1, type ); - if ( t->id() == selected ) { - d->ui.transportList->setCurrentItem( item ); - } - } - - updateButtonState(); -} - void TransportManagementWidget::updateButtonState() { + // TODO figure out current item vs. selected item -> using both ATM 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() { - // initialize transport - Transport *t = TransportManager::self()->createTransport(); - t->setType( Transport::EnumType::SMTP ); - - // configure transporr - TransportConfigDialog *tcd = new TransportConfigDialog( t, this ); - connect( tcd, SIGNAL(sendmailClicked()), SLOT(slotSendmail()) ); - tcd->setCaption( i18nc( "@title:window", "Add Transport" ) ); - if ( tcd->exec() == KDialog::Accepted ) { - TransportManager::self()->addTransport( t ); - } else { - delete t; - } -} - -void TransportManagementWidget::slotSendmail() -{ - // initialize transport - Transport *t = TransportManager::self()->createTransport(); - t->setType( Transport::EnumType::Sendmail ); - t->setHost( QLatin1String( "/usr/sbin/sendmail" ) ); - - TransportConfigDialog tcd( t, this ); - tcd.setCaption( i18nc( "@title:window", "Add Transport" ) ); - if ( tcd.exec() == KDialog::Accepted ) { - TransportManager::self()->addTransport( t ); - } else { - delete t; - } + QPointer ass = new AddTransportAssistant( this ); + ass->exec(); + delete ass; } void TransportManagementWidget::editClicked() { Q_ASSERT( d->ui.transportList->currentItem() ); int currentId = d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt(); Transport *transport = TransportManager::self()->transportById( currentId ); - if ( !transport ) { - return; - } + Q_ASSERT( transport ); transport = transport->clone(); - TransportConfigDialog t( transport, this ); - t.setCaption( i18nc( "@title:window", "Modify Transport" ) ); - t.exec(); + QPointer dlg = new TransportConfigDialog( transport, this ); + dlg->setCaption( i18nc( "@title:window", "Modify Transport" ) ); + dlg->exec(); + delete dlg; delete transport; } +void TransportManagementWidget::renameClicked() +{ + // TODO test all of these for cases when the transport is removed from outside + Q_ASSERT( d->ui.transportList->currentItem() ); + + d->ui.transportList->editItem( d->ui.transportList->currentItem(), 0 ); +} + void TransportManagementWidget::removeClicked() { Q_ASSERT( d->ui.transportList->currentItem() ); TransportManager::self()->removeTransport( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt() ); } void TransportManagementWidget::defaultClicked() { Q_ASSERT( d->ui.transportList->currentItem() ); TransportManager::self()->setDefaultTransport( d->ui.transportList->currentItem()->data( 0, Qt::UserRole ).toInt() ); } #include "transportmanagementwidget.moc" diff --git a/mailtransport/transportmanagementwidget.h b/mailtransport/transportmanagementwidget.h index 3b10d22ed..864d13044 100644 --- a/mailtransport/transportmanagementwidget.h +++ b/mailtransport/transportmanagementwidget.h @@ -1,66 +1,65 @@ /* 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. */ #ifndef MAILTRANSPORT_TRANSPORTMANAGEMENTWIDGET_H #define MAILTRANSPORT_TRANSPORTMANAGEMENTWIDGET_H #include #include namespace MailTransport { /** A widget to manage mail transports. */ class MAILTRANSPORT_EXPORT TransportManagementWidget : public QWidget { Q_OBJECT public: /** Creates a new TransportManagementWidget. @param parent The parent widget. */ TransportManagementWidget( QWidget *parent = 0 ); /** Destroys the widget. */ virtual ~TransportManagementWidget(); private Q_SLOTS: - void fillTransportList(); void updateButtonState(); void addClicked(); void editClicked(); + void renameClicked(); void removeClicked(); void defaultClicked(); - void slotSendmail(); private: class Private; Private * const d; }; } #endif diff --git a/mailtransport/transportmanagementwidget.ui b/mailtransport/transportmanagementwidget.ui index f43cb5f49..b243783dd 100644 --- a/mailtransport/transportmanagementwidget.ui +++ b/mailtransport/transportmanagementwidget.ui @@ -1,103 +1,85 @@ - + + MailTransport::TransportManagementWidget - - + + 0 0 400 300 - - - 9 - - - 6 - - - - - Qt::Vertical - - - - 20 - 141 - - - - - - - - Set Default + + + + + false - - - - R&emove + + + + A&dd... - - - + + + &Modify... - - - - A&dd... + + + + &Rename - - - - true - - - false + + + + Remo&ve - - false - - - true + + + + + + &Set as Default - - true + + + + + + Qt::Vertical - - 2 + + + 20 + 141 + - - - 1 - - - - - 1 - - - + KPushButton QPushButton
kpushbutton.h
+ + TransportListView + QTreeWidget +
transportlistview.h
+
diff --git a/mailtransport/transportmanager.cpp b/mailtransport/transportmanager.cpp index 620a14f3a..632b8bf61 100644 --- a/mailtransport/transportmanager.cpp +++ b/mailtransport/transportmanager.cpp @@ -1,588 +1,612 @@ /* 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 "mailtransport_defs.h" #include "transport.h" -#include "smtpjob.h" +#include "akonadijob.h" #include "sendmailjob.h" +#include "smtpjob.h" +#include "transportconfigwidget.h" +#include "sendmailconfigwidget.h" +#include "akonadiconfigwidget.h" +#include "smtpconfigwidget.h" #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; 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)) ); } 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; } 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 ) ) { return; } 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."; } } TransportJob *TransportManager::createTransportJob( int transportId ) { Transport *t = transportById( transportId, false ); if ( !t ) { return 0; } switch ( t->type() ) { case Transport::EnumType::SMTP: return new SmtpJob( t->clone(), this ); case Transport::EnumType::Sendmail: return new SendmailJob( t->clone(), this ); + case Transport::EnumType::Akonadi: + return new AkonadiJob( t->clone(), 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; } +TransportConfigWidget *TransportManager::configWidgetForTransport( Transport *transport, QWidget *parent ) +{ + Q_ASSERT( transport ); + + 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; +} + + 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() ); 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::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 4d750873b..e31255eda 100644 --- a/mailtransport/transportmanager.h +++ b/mailtransport/transportmanager.h @@ -1,254 +1,266 @@ /* 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 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; /** 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(); + /** + Creates an appropriate configuration widget for the transport, depending + on its type. + + @param transport The transport + @param parent The parent passed to the widget's constructor + + TODO should this be public? + */ + TransportConfigWidget *configWidgetForTransport( Transport *transport, QWidget *parent = 0 ); + 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 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