Commit 9037b80c authored by Constantin Berzan's avatar Constantin Berzan
Browse files

Re-design handling of send-enabled Akonadi resources in MailTransport.

* TransportManager now queries all agent types and selects those that support sending email.
* TransportType class for each Transport, because for Akonadi types we now need to keep track of the AgentType as well.
* Config of Akonadi-based transports now simply calls AgentInstance::configure().
* Deprecate TransportConfigDialog, since it doesn't work for Akonadi transports.  Use TransportManager::configureTransport() instead.
* Remove the add transport assistant, replace it with a simple dialog.

svn path=/branches/work/akonadi-ports/kdepimlibs/; revision=987521
parent 6a8405c8
add_subdirectory( kconf_update )
add_subdirectory( tests )
......@@ -8,16 +7,15 @@ add_definitions( -DKDE_DEFAULT_DEBUG_AREA=5324 )
set(mailtransport_lib_srcs
transport.cpp
transportmanager.cpp
transporttypeinfo.cpp
transporttype.cpp
transportcombobox.cpp
transportlistview.cpp
transportmanagementwidget.cpp
addtransportassistant.cpp
addtransportdialog.cpp
transportconfigdialog.cpp
transportconfigwidget.cpp
akonadiconfigwidget.cpp
sendmailconfigwidget.cpp
smtpconfigwidget.cpp
......@@ -34,13 +32,10 @@ set(mailtransport_lib_srcs
kde4_add_ui_files(mailtransport_lib_srcs
addtransportassistanttypepage.ui
addtransportassistantnamepage.ui
akonadisettings.ui
sendmailsettings.ui
smtpsettings.ui
addtransportdialog.ui
transportmanagementwidget.ui
)
kde4_add_kcfg_files(mailtransport_lib_srcs transportbase.kcfgc)
......@@ -69,6 +64,7 @@ install( FILES
${CMAKE_CURRENT_BINARY_DIR}/transportbase.h
transport.h
transportmanager.h
transporttype.h
servertest.h
transportcombobox.h
......
* TransportConfigDialog needs validate()
* all CamelCase...
* smtpsettings.ui has hidden widgets... test those... and why can't I set/see the 'visible' property in designer?
* why is identitylistview in kmail instead of kpimidentities?
* figure out what needs to be exported and what not (add .hs to CMakeLists afterwards)
* include KLocale or KLocalizedString??
Design:
* is there a way to make KConfig XT give me separate settings for SMTP, Sendmail, Akonadi? Currently all of the settings are for SMTP, and Sendmail and Akonadi just use the 'host' setting for storing the sendmail path or Akonadi resource id, respectively.
* SMTPJob (and probably others) give empty errorString when killed
Bugs:
* modify -> change password -> ok. password is saved in wallet and seen ok on restart, but clicking modify again shows old password
* Type=Akonadi and Type=Sendmail appear in the config file, but no Type=SMTP (probably because SMTP == 0 == default)
* cancel doesn't work in transportmgr, apparently
/*
Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
Based on code from Kopete (addaccountwizard)
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "addtransportassistant.h"
#include "transport.h"
#include "transportconfigwidget.h"
#include "transportmanager.h"
#include "transporttypeinfo.h"
#include <KConfigDialogManager>
#include <KConfigSkeleton>
#include <KDebug>
#include <KVBox>
#include "ui_addtransportassistanttypepage.h"
#include "ui_addtransportassistantnamepage.h"
using namespace MailTransport;
/**
@internal
*/
class AddTransportAssistant::Private
{
public:
Private()
: typePage( 0 )
, configPage( 0 )
, namePage( 0 )
, configPageContents( 0 )
, transport( 0 )
, lastType( -1 )
{
}
QTreeWidgetItem* selectedType();
KPageWidgetItem *typeItem;
KPageWidgetItem *configItem;
KPageWidgetItem *nameItem;
QWidget *typePage;
KVBox *configPage;
QWidget *namePage;
TransportConfigWidget *configPageContents;
Transport *transport;
int lastType;
Ui::AddTransportAssistantTypePage uiTypePage;
Ui::AddTransportAssistantNamePage uiNamePage;
};
AddTransportAssistant::AddTransportAssistant( QWidget *parent )
: KAssistantDialog( parent )
, d( new Private )
{
d->transport = TransportManager::self()->createTransport();
Q_ASSERT( d->transport );
// type page
d->typePage = new QWidget( this );
d->uiTypePage.setupUi( d->typePage );
d->uiTypePage.typeListView->setColumnCount( 2 );
QStringList header;
header << i18n( "Type" ) << i18n( "Description" );
d->uiTypePage.typeListView->setHeaderLabels( header );
d->typeItem = addPage( d->typePage, d->typePage->windowTitle() );
setValid( d->typeItem, false );
// populate type list
for( int i = 0; i < TransportTypeInfo::typeCount(); i++ ) {
QTreeWidgetItem *treeItem = new QTreeWidgetItem( d->uiTypePage.typeListView );
treeItem->setData( 0, Qt::UserRole, i ); // the transport type
treeItem->setText( 0, TransportTypeInfo::nameForType( i ) );
treeItem->setText( 1, TransportTypeInfo::descriptionForType( i ) );
}
d->uiTypePage.typeListView->resizeColumnToContents( 0 );
d->uiTypePage.typeListView->setFocus();
// connect user input
connect( d->uiTypePage.typeListView, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ),
this, SLOT( typeListClicked() ) );
connect( d->uiTypePage.typeListView, SIGNAL( itemSelectionChanged() ),
this, SLOT( typeListClicked() ) );
connect( d->uiTypePage.typeListView, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ),
this, SLOT( typeListDoubleClicked() ) );
// settings page
d->configPage = new KVBox( this );
d->configItem = addPage( d->configPage, i18n( "Step Two: Transport Settings" ) );
// name page
d->namePage = new QWidget( this );
d->uiNamePage.setupUi( d->namePage );
// TODO set up sensible default name
d->nameItem = addPage( d->namePage, d->namePage->windowTitle() );
}
QTreeWidgetItem* AddTransportAssistant::Private::selectedType()
{
QList<QTreeWidgetItem*> sel = uiTypePage.typeListView->selectedItems();
if( !sel.empty() )
return sel.first();
return 0;
}
void AddTransportAssistant::typeListClicked()
{
// Make sure a type is selected before allowing the user to continue.
setValid( d->typeItem, d->selectedType() != 0 );
}
void AddTransportAssistant::typeListDoubleClicked()
{
// Proceed to the next page if a type is double clicked.
next();
}
void AddTransportAssistant::accept()
{
// register transport
d->configPageContents->apply();
TransportManager::self()->addTransport( d->transport );
d->transport = 0; // don't delete it
if( d->uiNamePage.setDefault->isChecked() ) {
TransportManager::self()->setDefaultTransport( d->transport->id() );
}
KAssistantDialog::accept();
}
void AddTransportAssistant::next()
{
if( currentPage() == d->typeItem ) {
QTreeWidgetItem *item = d->selectedType();
int type = item->data( 0, Qt::UserRole ).toInt(); // the transport type
Q_ASSERT( type >= 0 && type < TransportBase::EnumType::COUNT );
// create appropriate config widget
if( d->configPageContents && d->lastType == type ) {
// same type as before; keep settings
} else {
d->transport->setType( type );
d->lastType = type;
delete d->configPageContents;
d->configPageContents = TransportTypeInfo::configWidgetForTransport( d->transport, d->configPage );
// let the configWidget's KConfigDialogManager handle kcfg_name:
KConfigDialogManager *mgr = d->configPageContents->configManager();
Q_ASSERT( mgr );
Q_ASSERT( d->namePage );
mgr->addWidget( d->namePage );
}
}
KAssistantDialog::next();
}
void AddTransportAssistant::reject()
{
delete d->transport;
d->transport = 0;
KAssistantDialog::reject();
}
AddTransportAssistant::~AddTransportAssistant()
{
delete d->transport;
delete d;
}
#include "addtransportassistant.moc"
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddTransportAssistantTypePage</class>
<widget class="QWidget" name="AddTransportAssistantTypePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>482</width>
<height>353</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Step One: Select Transport Type</string>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="m_header">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;h2&gt;Welcome to the Add Transport Assistant&lt;/h2&gt;
&lt;p&gt;Select the transport type from the list below.&lt;/p&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="typeListView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
/*
Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
Based on code from Kopete (addaccountwizard)
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "addtransportdialog.h"
#include "transport.h"
#include "transportconfigwidget.h"
#include "transportmanager.h"
#include "transporttype.h"
#include "ui_addtransportdialog.h"
#include <KConfigDialogManager>
#include <KConfigSkeleton>
#include <KDebug>
#include <akonadi/agentinstance.h>
#include <akonadi/agentinstancecreatejob.h>
using namespace MailTransport;
/**
@internal
*/
class AddTransportDialog::Private
{
public:
Private( AddTransportDialog *qq )
: q( qq )
{
}
TransportType selectedType() const;
// slots
void typeListClicked();
AddTransportDialog *const q;
Ui::AddTransportDialog ui;
};
TransportType AddTransportDialog::Private::selectedType() const
{
QList<QTreeWidgetItem*> sel = ui.typeListView->selectedItems();
if( !sel.empty() ) {
return sel.first()->data( 0, Qt::UserRole ).value<TransportType>();
}
return TransportType();
}
void AddTransportDialog::Private::typeListClicked()
{
// Make sure a type is selected before allowing the user to continue.
q->enableButtonOk( selectedType().isValid() );
}
AddTransportDialog::AddTransportDialog( QWidget *parent )
: KDialog( parent )
, d( new Private( this ) )
{
// Setup UI.
{
QWidget *widget = new QWidget( this );
d->ui.setupUi( widget );
setMainWidget( widget );
setCaption( i18n( "Create Outgoing Account" ) );
setButtons( Ok|Cancel );
enableButtonOk( false );
setButtonText( Ok, i18nc( "create and configure a mail transport", "Create and Configure" ) );
}
// Populate type list.
foreach( const TransportType &type, TransportManager::self()->types() ) {
QTreeWidgetItem *treeItem = new QTreeWidgetItem( d->ui.typeListView );
treeItem->setText( 0, type.name() );
treeItem->setText( 1, type.description() );
treeItem->setData( 0, Qt::UserRole, QVariant::fromValue( type ) ); // the transport type
}
d->ui.typeListView->resizeColumnToContents( 0 );
updateGeometry();
d->ui.typeListView->setFocus();
// Connect user input.
connect( d->ui.typeListView, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
this, SLOT(typeListClicked()) );
connect( d->ui.typeListView, SIGNAL(itemSelectionChanged()),
this, SLOT(typeListClicked()) );
}
AddTransportDialog::~AddTransportDialog()
{
}
void AddTransportDialog::accept()
{
if( !d->selectedType().isValid() ) {
return;
}
// Create a new transport and configure it.
Transport *transport = TransportManager::self()->createTransport();
transport->setTransportType( d->selectedType() );
if( d->selectedType().type() == Transport::EnumType::Akonadi ) {
// Create a resource instance if Akonadi-type transport.
using namespace Akonadi;
AgentInstanceCreateJob *cjob = new AgentInstanceCreateJob( d->selectedType().agentType() );
if( !cjob->exec() ) {
kWarning() << "Failed to create agent instance of type"
<< d->selectedType().agentType().identifier();
return;
}
transport->setHost( cjob->instance().identifier() );
}
transport->setName( d->ui.name->text() );
transport->forceUniqueName();
if( TransportManager::self()->configureTransport( transport, this ) ) {
// The user clicked OK and the transport settings were saved.
TransportManager::self()->addTransport( transport );
if( d->ui.setDefault->isChecked() ) {
TransportManager::self()->setDefaultTransport( transport->id() );
}
KDialog::accept();
}
}
#include "addtransportdialog.moc"
/*
Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
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
......@@ -19,42 +17,35 @@
02110-1301, USA.
*/
#ifndef MAILTRANSPORT_ADDTRANSPORTASSISTANT_H
#define MAILTRANSPORT_ADDTRANSPORTASSISTANT_H
#ifndef MAILTRANSPORT_ADDTRANSPORTDIALOG_H
#define MAILTRANSPORT_ADDTRANSPORTDIALOG_H
#include <mailtransport/mailtransport_export.h>
#include <KDE/KAssistantDialog>
namespace MailTransport
{
#include <KDE/KDialog>
namespace MailTransport {
/**
Assistant to help the user set up a new transport.
A dialog for creating a new transport. It asks the user for the transport
type and name, and then proceeds to configure the new transport.
*/
class MAILTRANSPORT_EXPORT AddTransportAssistant : public KAssistantDialog
class AddTransportDialog : public KDialog
{
Q_OBJECT
public:
// TODO docu
explicit AddTransportAssistant( QWidget *parent = 0 );
~AddTransportAssistant();
private slots:
void typeListClicked();
void typeListDoubleClicked();
explicit AddTransportDialog( QWidget *parent = 0 );
virtual ~AddTransportDialog();
protected slots:
/* reimpl */
virtual void accept();
virtual void next();
virtual void reject();
private:
class Private;
Private * const d;
Private *const d;
Q_PRIVATE_SLOT( d, void typeListClicked() )
};
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddTransportAssistantNamePage</class>
<widget class="QWidget" name="AddTransportAssistantNamePage">
<class>AddTransportDialog</class>
<widget class="QWidget" name="AddTransportDialog">
<property name="geometry">
<rect>
<x>0</x>
......@@ -17,11 +17,11 @@
</size>
</property>
<property name="windowTitle">
<string>Final Step: Choose Transport Name</string>
<string>Step One: Select Transport Type</string>
</property>
<layout class="QFormLayout" name="formLayout">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="m_header">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
......@@ -29,8 +29,7 @@
</sizepolicy>
</property>
<property name="text">
<string>&lt;h2&gt;Congratulations&lt;/h2&gt;
&lt;p&gt;You have finished configuring your mail transport. Please specify a name for it below, and click the Finish button.&lt;/p&gt;</string>
<string>Select an account type from the list below:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
......@@ -40,20 +39,40 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="0" colspan="2">
<widget class="QTreeWidget" name="typeListView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KLineEdit" name="kcfg_name"/>
</item>
<item row="2" column="1">
<widget class="KLineEdit" name="name"/>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="setDefault">
<property name="text">
<string>Make this the default mail transport.</string>
<string>Make this the default outgoing account.</string>
</property>
</widget>
</item>
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>Volker Krause &lt;vkrause@kde.org&gt;</author>
<class>AkonadiSettings</class>
<widget class="QWidget" name="AkonadiSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>383</width>
<height>315</height>
</rect>