• Skip to content
  • Skip to link menu
KDE 4.5 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

mailtransport

smtpconfigwidget.cpp

00001 /*
00002     Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
00003 
00004     Based on MailTransport code by:
00005     Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
00006     Copyright (c) 2007 KovoKs <kovoks@kovoks.nl>
00007 
00008     Based on KMail code by:
00009     Copyright (c) 2001-2002 Michael Haeckel <haeckel@kde.org>
00010 
00011     This library is free software; you can redistribute it and/or modify it
00012     under the terms of the GNU Library General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or (at your
00014     option) any later version.
00015 
00016     This library is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00019     License for more details.
00020 
00021     You should have received a copy of the GNU Library General Public License
00022     along with this library; see the file COPYING.LIB.  If not, write to the
00023     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00024     02110-1301, USA.
00025 */
00026 
00027 #include "smtpconfigwidget.h"
00028 #include "transportconfigwidget_p.h"
00029 #include "transport.h"
00030 #include "transportmanager.h"
00031 #include "servertest.h"
00032 #include "mailtransport_defs.h"
00033 
00034 #include "ui_smtpsettings.h"
00035 
00036 #include <QAbstractButton>
00037 #include <QButtonGroup>
00038 
00039 #include <KProtocolInfo>
00040 
00041 namespace {
00042 
00043 // TODO: is this really necessary?
00044 class BusyCursorHelper : public QObject
00045 {
00046   public:
00047     inline BusyCursorHelper( QObject *parent ) : QObject( parent )
00048     {
00049       qApp->setOverrideCursor( Qt::BusyCursor );
00050     }
00051 
00052     inline ~BusyCursorHelper()
00053     {
00054       qApp->restoreOverrideCursor();
00055     }
00056 };
00057 
00058 }
00059 
00060 using namespace MailTransport;
00061 
00062 class MailTransport::SMTPConfigWidgetPrivate : public TransportConfigWidgetPrivate
00063 {
00064   public:
00065     ::Ui::SMTPSettings ui;
00066 
00067     ServerTest *serverTest;
00068     QButtonGroup *encryptionGroup;
00069 
00070     // detected authentication capabilities
00071     QList<int> noEncCapa, sslCapa, tlsCapa;
00072 
00073     bool serverTestFailed;
00074 
00075     static void addAuthenticationItem( KComboBox *combo,
00076                                    int authenticationType )
00077     {
00078       combo->addItem( Transport::authenticationTypeString( authenticationType ),
00079                   QVariant( authenticationType ) );
00080     }
00081 
00082     void resetAuthCapabilities()
00083     {
00084       noEncCapa.clear();
00085       noEncCapa << Transport::EnumAuthenticationType::LOGIN
00086                 << Transport::EnumAuthenticationType::PLAIN
00087                 << Transport::EnumAuthenticationType::CRAM_MD5
00088                 << Transport::EnumAuthenticationType::DIGEST_MD5
00089                 << Transport::EnumAuthenticationType::NTLM
00090                 << Transport::EnumAuthenticationType::GSSAPI;
00091       sslCapa = tlsCapa = noEncCapa;
00092       updateAuthCapbilities();
00093 
00094     }
00095 
00096     void updateAuthCapbilities()
00097     {
00098       if ( serverTestFailed ) {
00099         return;
00100       }
00101 
00102       QList<int> capa = noEncCapa;
00103       if ( ui.ssl->isChecked() ) {
00104         capa = sslCapa;
00105       } else if ( ui.tls->isChecked() ) {
00106         capa = tlsCapa;
00107       }
00108 
00109       ui.authCombo->clear();
00110       foreach ( int authType, capa ) {
00111         addAuthenticationItem( ui.authCombo, authType );
00112       }
00113 
00114 
00115       if ( transport->isValid() ) {
00116         const int idx = ui.authCombo->findData( transport->authenticationType() );
00117 
00118         if ( idx != -1 ) {
00119           ui.authCombo->setCurrentIndex( idx );
00120         }
00121       }
00122 
00123       if ( capa.count() == 0 ) {
00124         ui.noAuthPossible->setVisible( true );
00125         ui.kcfg_requiresAuthentication->setChecked( false );
00126         ui.kcfg_requiresAuthentication->setEnabled( false );
00127         ui.kcfg_requiresAuthentication->setVisible( false );
00128         ui.authCombo->setEnabled( false );
00129         ui.authLabel->setEnabled( false );
00130       } else {
00131         ui.noAuthPossible->setVisible( false );
00132         ui.kcfg_requiresAuthentication->setEnabled( true );
00133         ui.kcfg_requiresAuthentication->setVisible( true );
00134         ui.authCombo->setEnabled( true );
00135         ui.authLabel->setEnabled( true );
00136       }
00137     }
00138 };
00139 
00140 SMTPConfigWidget::SMTPConfigWidget( Transport *transport, QWidget *parent )
00141   : TransportConfigWidget( *new SMTPConfigWidgetPrivate, transport, parent )
00142 {
00143   init();
00144 }
00145 
00146 SMTPConfigWidget::SMTPConfigWidget( SMTPConfigWidgetPrivate &dd,
00147                                     Transport *transport, QWidget *parent )
00148   : TransportConfigWidget( dd, transport, parent )
00149 {
00150   init();
00151 }
00152 
00153 static void checkHighestEnabledButton( QButtonGroup *group )
00154 {
00155   Q_ASSERT( group );
00156 
00157   for ( int i = group->buttons().count() - 1; i >= 0; --i ) {
00158     QAbstractButton *b = group->buttons().at( i );
00159     if ( b && b->isEnabled() ) {
00160       b->animateClick();
00161       return;
00162     }
00163   }
00164 }
00165 
00166 void SMTPConfigWidget::init()
00167 {
00168   Q_D( SMTPConfigWidget );
00169   d->serverTest = 0;
00170 
00171   connect( TransportManager::self(), SIGNAL(passwordsChanged()),
00172            SLOT(passwordsLoaded()) );
00173 
00174   d->serverTestFailed = false;
00175 
00176   d->ui.setupUi( this );
00177   d->manager->addWidget( this ); // otherwise it doesn't find out about these widgets
00178   d->manager->updateWidgets();
00179 
00180   d->encryptionGroup = new QButtonGroup( this );
00181   d->encryptionGroup->addButton( d->ui.none, Transport::EnumEncryption::None );
00182   d->encryptionGroup->addButton( d->ui.ssl, Transport::EnumEncryption::SSL );
00183   d->encryptionGroup->addButton( d->ui.tls, Transport::EnumEncryption::TLS );
00184 
00185   d->resetAuthCapabilities();
00186 
00187   if ( KProtocolInfo::capabilities( SMTP_PROTOCOL ).contains( QLatin1String( "SASL" ) ) == 0 ) {
00188     d->ui.authCombo->removeItem( d->ui.authCombo->findData(
00189                                  Transport::EnumAuthenticationType::NTLM ) );
00190     d->ui.authCombo->removeItem( d->ui.authCombo->findData(
00191                                  Transport::EnumAuthenticationType::GSSAPI ) );
00192   }
00193 
00194   connect( d->ui.checkCapabilities, SIGNAL( clicked() ),
00195            SLOT( checkSmtpCapabilities() ) );
00196   connect( d->ui.kcfg_host, SIGNAL( textChanged(QString) ),
00197            SLOT( hostNameChanged(QString) ) );
00198   connect( d->encryptionGroup, SIGNAL( buttonClicked( int ) ),
00199            SLOT( encryptionChanged(int) ) );
00200   connect( d->ui.kcfg_requiresAuthentication, SIGNAL( toggled(bool) ),
00201            SLOT( ensureValidAuthSelection() ) );
00202 
00203   if ( !d->transport->isValid() ) {
00204     checkHighestEnabledButton( d->encryptionGroup );
00205   }
00206 
00207   // load the password
00208   d->transport->updatePasswordState();
00209   if ( d->transport->isComplete() ) {
00210     d->ui.password->setText( d->transport->password() );
00211   } else {
00212     if ( d->transport->requiresAuthentication() ) {
00213       TransportManager::self()->loadPasswordsAsync();
00214     }
00215   }
00216 
00217   hostNameChanged( d->transport->host() );
00218 }
00219 
00220 void SMTPConfigWidget::checkSmtpCapabilities()
00221 {
00222   Q_D( SMTPConfigWidget );
00223 
00224   d->serverTest = new ServerTest( this );
00225   d->serverTest->setProtocol( SMTP_PROTOCOL );
00226   d->serverTest->setServer( d->ui.kcfg_host->text().trimmed() );
00227   if ( d->ui.kcfg_specifyHostname->isChecked() ) {
00228     d->serverTest->setFakeHostname( d->ui.kcfg_localHostname->text() );
00229   }
00230   d->serverTest->setProgressBar( d->ui.checkCapabilitiesProgress );
00231   d->ui.checkCapabilitiesStack->setCurrentIndex( 1 );
00232   BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( d->serverTest );
00233 
00234   connect( d->serverTest, SIGNAL( finished( QList<int> ) ),
00235            SLOT(slotFinished( QList<int> )));
00236   connect( d->serverTest, SIGNAL( finished( QList<int> ) ),
00237            busyCursorHelper, SLOT( deleteLater() ) );
00238   d->ui.checkCapabilities->setEnabled( false );
00239   d->serverTest->start();
00240   d->serverTestFailed = false;
00241 }
00242 
00243 void SMTPConfigWidget::apply()
00244 {
00245   Q_D( SMTPConfigWidget );
00246   Q_ASSERT( d->manager );
00247   d->manager->updateSettings();
00248   d->transport->setPassword( d->ui.password->text() );
00249 
00250   KConfigGroup group( d->transport->config(), d->transport->currentGroup() );
00251   const int index = d->ui.authCombo->currentIndex();
00252   if ( index >= 0 ) {
00253     group.writeEntry( "authtype", d->ui.authCombo->itemData( index ).toInt() );
00254   }
00255 
00256   TransportConfigWidget::apply();
00257 }
00258 
00259 void SMTPConfigWidget::passwordsLoaded()
00260 {
00261   Q_D( SMTPConfigWidget );
00262 
00263   // Load the password from the original to our cloned copy
00264   d->transport->updatePasswordState();
00265 
00266   if ( d->ui.password->text().isEmpty() ) {
00267     d->ui.password->setText( d->transport->password() );
00268   }
00269 }
00270 
00271 // TODO rename
00272 void SMTPConfigWidget::slotFinished( QList<int> results )
00273 {
00274   Q_D( SMTPConfigWidget );
00275 
00276   d->ui.checkCapabilitiesStack->setCurrentIndex( 0 );
00277 
00278   d->ui.checkCapabilities->setEnabled( true );
00279   d->serverTest->deleteLater();
00280 
00281   // If the servertest did not find any useable authentication modes, assume the
00282   // connection failed and don't disable any of the radioboxes.
00283   if ( results.isEmpty() ) {
00284     d->serverTestFailed = true;
00285     return;
00286   }
00287 
00288   // encryption method
00289   d->ui.none->setEnabled( results.contains( Transport::EnumEncryption::None ) );
00290   d->ui.ssl->setEnabled( results.contains( Transport::EnumEncryption::SSL ) );
00291   d->ui.tls->setEnabled( results.contains( Transport::EnumEncryption::TLS ) );
00292   checkHighestEnabledButton( d->encryptionGroup );
00293 
00294   d->noEncCapa = d->serverTest->normalProtocols();
00295   if ( d->ui.tls->isEnabled() ) {
00296     d->tlsCapa = d->serverTest->tlsProtocols();
00297   } else {
00298     d->tlsCapa.clear();
00299   }
00300   d->sslCapa = d->serverTest->secureProtocols();
00301   d->updateAuthCapbilities();
00302 }
00303 
00304 void SMTPConfigWidget::hostNameChanged( const QString &text )
00305 {
00306   // TODO: really? is this done at every change? wtf
00307 
00308   Q_D( SMTPConfigWidget );
00309 
00310   // sanitize hostname...
00311   int pos = d->ui.kcfg_host->cursorPosition();
00312   d->ui.kcfg_host->blockSignals( true );
00313   d->ui.kcfg_host->setText( text.trimmed() );
00314   d->ui.kcfg_host->blockSignals( false );
00315   d->ui.kcfg_host->setCursorPosition( pos );
00316 
00317   d->resetAuthCapabilities();
00318   for ( int i = 0; d->encryptionGroup && i < d->encryptionGroup->buttons().count(); i++ ) {
00319     d->encryptionGroup->buttons().at( i )->setEnabled( true );
00320   }
00321 }
00322 
00323 void SMTPConfigWidget::ensureValidAuthSelection()
00324 {
00325   Q_D( SMTPConfigWidget );
00326 
00327   // adjust available authentication methods
00328   d->updateAuthCapbilities();
00329 }
00330 
00331 void SMTPConfigWidget::encryptionChanged( int enc )
00332 {
00333   Q_D( SMTPConfigWidget );
00334   kDebug() << enc;
00335 
00336   // adjust port
00337   if ( enc == Transport::EnumEncryption::SSL ) {
00338     if ( d->ui.kcfg_port->value() == SMTP_PORT ) {
00339       d->ui.kcfg_port->setValue( SMTPS_PORT );
00340     }
00341   } else {
00342     if ( d->ui.kcfg_port->value() == SMTPS_PORT ) {
00343       d->ui.kcfg_port->setValue( SMTP_PORT );
00344     }
00345   }
00346 
00347   ensureValidAuthSelection();
00348 }
00349 
00350 #include "smtpconfigwidget.moc"

mailtransport

Skip menu "mailtransport"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal