• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.13.3 API Reference
  • KDE Home
  • Contact Us
 

mailtransport

  • mailtransport
smtpconfigwidget.cpp
1 /*
2  Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
3 
4  Based on MailTransport code by:
5  Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
6  Copyright (c) 2007 KovoKs <kovoks@kovoks.nl>
7 
8  Based on KMail code by:
9  Copyright (c) 2001-2002 Michael Haeckel <haeckel@kde.org>
10 
11  This library is free software; you can redistribute it and/or modify it
12  under the terms of the GNU Library General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or (at your
14  option) any later version.
15 
16  This library is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
19  License for more details.
20 
21  You should have received a copy of the GNU Library General Public License
22  along with this library; see the file COPYING.LIB. If not, write to the
23  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24  02110-1301, USA.
25 */
26 
27 #include "smtpconfigwidget.h"
28 #include "transportconfigwidget_p.h"
29 #include "transport.h"
30 #include "transportmanager.h"
31 #include "servertest.h"
32 #include "mailtransport_defs.h"
33 
34 #ifndef KDEPIM_MOBILE_UI
35 #include "ui_smtpsettings_desktop.h"
36 #else
37 #include "ui_smtpsettings_mobile.h"
38 #endif
39 
40 #include <QAbstractButton>
41 #include <QButtonGroup>
42 
43 #include <KProtocolInfo>
44 #include <KDebug>
45 
46 namespace {
47 
48 // TODO: is this really necessary?
49 class BusyCursorHelper : public QObject
50 {
51  public:
52  inline BusyCursorHelper( QObject *parent ) : QObject( parent )
53  {
54 #ifndef QT_NO_CURSOR
55  qApp->setOverrideCursor( Qt::BusyCursor );
56 #endif
57  }
58 
59  inline ~BusyCursorHelper()
60  {
61 #ifndef QT_NO_CURSOR
62  qApp->restoreOverrideCursor();
63 #endif
64  }
65 };
66 
67 }
68 
69 using namespace MailTransport;
70 
71 class MailTransport::SMTPConfigWidgetPrivate : public TransportConfigWidgetPrivate
72 {
73  public:
74  ::Ui::SMTPSettings ui;
75 
76  ServerTest *serverTest;
77  QButtonGroup *encryptionGroup;
78 
79  // detected authentication capabilities
80  QList<int> noEncCapa, sslCapa, tlsCapa;
81 
82  bool serverTestFailed;
83 
84  static void addAuthenticationItem( KComboBox *combo,
85  int authenticationType )
86  {
87  combo->addItem( Transport::authenticationTypeString( authenticationType ),
88  QVariant( authenticationType ) );
89  }
90 
91  void resetAuthCapabilities()
92  {
93  noEncCapa.clear();
94  noEncCapa << Transport::EnumAuthenticationType::LOGIN
95  << Transport::EnumAuthenticationType::PLAIN
96  << Transport::EnumAuthenticationType::CRAM_MD5
97  << Transport::EnumAuthenticationType::DIGEST_MD5
98  << Transport::EnumAuthenticationType::NTLM
99  << Transport::EnumAuthenticationType::GSSAPI;
100  sslCapa = tlsCapa = noEncCapa;
101  updateAuthCapbilities();
102 
103  }
104 
105  void updateAuthCapbilities()
106  {
107  if ( serverTestFailed ) {
108  return;
109  }
110 
111  QList<int> capa = noEncCapa;
112  if ( ui.ssl->isChecked() ) {
113  capa = sslCapa;
114  } else if ( ui.tls->isChecked() ) {
115  capa = tlsCapa;
116  }
117 
118  ui.authCombo->clear();
119  foreach ( int authType, capa ) {
120  addAuthenticationItem( ui.authCombo, authType );
121  }
122 
123  if ( transport->isValid() ) {
124  const int idx = ui.authCombo->findData( transport->authenticationType() );
125 
126  if ( idx != -1 ) {
127  ui.authCombo->setCurrentIndex( idx );
128  }
129  }
130 
131  if ( capa.count() == 0 ) {
132  ui.noAuthPossible->setVisible( true );
133  ui.kcfg_requiresAuthentication->setChecked( false );
134  ui.kcfg_requiresAuthentication->setEnabled( false );
135  ui.kcfg_requiresAuthentication->setVisible( false );
136  ui.authCombo->setEnabled( false );
137  ui.authLabel->setEnabled( false );
138  } else {
139  ui.noAuthPossible->setVisible( false );
140  ui.kcfg_requiresAuthentication->setEnabled( true );
141  ui.kcfg_requiresAuthentication->setVisible( true );
142  ui.authCombo->setEnabled( true );
143  ui.authLabel->setEnabled( true );
144  }
145  }
146 };
147 
148 SMTPConfigWidget::SMTPConfigWidget( Transport *transport, QWidget *parent )
149  : TransportConfigWidget( *new SMTPConfigWidgetPrivate, transport, parent )
150 {
151  init();
152 }
153 
154 SMTPConfigWidget::SMTPConfigWidget( SMTPConfigWidgetPrivate &dd,
155  Transport *transport, QWidget *parent )
156  : TransportConfigWidget( dd, transport, parent )
157 {
158  init();
159 }
160 
161 static void checkHighestEnabledButton( QButtonGroup *group )
162 {
163  Q_ASSERT( group );
164 
165  for ( int i = group->buttons().count() - 1; i >= 0; --i ) {
166  QAbstractButton *b = group->buttons().at( i );
167  if ( b && b->isEnabled() ) {
168  b->animateClick();
169  return;
170  }
171  }
172 }
173 
174 void SMTPConfigWidget::init()
175 {
176  Q_D( SMTPConfigWidget );
177  d->serverTest = 0;
178 
179  connect( TransportManager::self(), SIGNAL(passwordsChanged()),
180  SLOT(passwordsLoaded()) );
181 
182  d->serverTestFailed = false;
183 
184  d->ui.setupUi( this );
185  d->manager->addWidget( this ); // otherwise it doesn't find out about these widgets
186  d->manager->updateWidgets();
187 
188  d->encryptionGroup = new QButtonGroup( this );
189  d->encryptionGroup->addButton( d->ui.none, Transport::EnumEncryption::None );
190  d->encryptionGroup->addButton( d->ui.ssl, Transport::EnumEncryption::SSL );
191  d->encryptionGroup->addButton( d->ui.tls, Transport::EnumEncryption::TLS );
192 
193  d->resetAuthCapabilities();
194 
195  if ( KProtocolInfo::capabilities( SMTP_PROTOCOL ).contains( QLatin1String( "SASL" ) ) == 0 ) {
196  d->ui.authCombo->removeItem( d->ui.authCombo->findData(
197  Transport::EnumAuthenticationType::NTLM ) );
198  d->ui.authCombo->removeItem( d->ui.authCombo->findData(
199  Transport::EnumAuthenticationType::GSSAPI ) );
200  }
201 
202  connect( d->ui.checkCapabilities, SIGNAL(clicked()),
203  SLOT(checkSmtpCapabilities()) );
204  connect( d->ui.kcfg_host, SIGNAL(textChanged(QString)),
205  SLOT(hostNameChanged(QString)) );
206  connect( d->encryptionGroup, SIGNAL(buttonClicked(int)),
207  SLOT(encryptionChanged(int)) );
208  connect( d->ui.kcfg_requiresAuthentication, SIGNAL(toggled(bool)),
209  SLOT(ensureValidAuthSelection()) );
210 
211  if ( !d->transport->isValid() ) {
212  checkHighestEnabledButton( d->encryptionGroup );
213  }
214 
215  // load the password
216  d->transport->updatePasswordState();
217  if ( d->transport->isComplete() ) {
218  d->ui.password->setText( d->transport->password() );
219  } else {
220  if ( d->transport->requiresAuthentication() ) {
221  TransportManager::self()->loadPasswordsAsync();
222  }
223  }
224 
225  hostNameChanged( d->transport->host() );
226 
227 #ifdef KDEPIM_MOBILE_UI
228  d->ui.smtpSettingsGroupBox->hide();
229 #endif
230 }
231 
232 void SMTPConfigWidget::checkSmtpCapabilities()
233 {
234  Q_D( SMTPConfigWidget );
235 
236  d->serverTest = new ServerTest( this );
237  d->serverTest->setProtocol( SMTP_PROTOCOL );
238  d->serverTest->setServer( d->ui.kcfg_host->text().trimmed() );
239  if ( d->ui.kcfg_specifyHostname->isChecked() ) {
240  d->serverTest->setFakeHostname( d->ui.kcfg_localHostname->text() );
241  }
242  QAbstractButton *encryptionChecked = d->encryptionGroup->checkedButton();
243  if (encryptionChecked == d->ui.none) {
244  d->serverTest->setPort( Transport::EnumEncryption::None, d->ui.kcfg_port->value());
245  } else if (encryptionChecked == d->ui.ssl) {
246  d->serverTest->setPort( Transport::EnumEncryption::SSL, d->ui.kcfg_port->value());
247  }
248  d->serverTest->setProgressBar( d->ui.checkCapabilitiesProgress );
249  d->ui.checkCapabilitiesStack->setCurrentIndex( 1 );
250  BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( d->serverTest );
251 
252  connect( d->serverTest, SIGNAL(finished(QList<int>)),
253  SLOT(slotFinished(QList<int>)));
254  connect( d->serverTest, SIGNAL(finished(QList<int>)),
255  busyCursorHelper, SLOT(deleteLater()) );
256  d->ui.checkCapabilities->setEnabled( false );
257  d->serverTest->start();
258  d->serverTestFailed = false;
259 }
260 
261 void SMTPConfigWidget::apply()
262 {
263  Q_D( SMTPConfigWidget );
264  Q_ASSERT( d->manager );
265  d->manager->updateSettings();
266  d->transport->setPassword( d->ui.password->text() );
267 
268  KConfigGroup group( d->transport->config(), d->transport->currentGroup() );
269  const int index = d->ui.authCombo->currentIndex();
270  if ( index >= 0 ) {
271  group.writeEntry( "authtype", d->ui.authCombo->itemData( index ).toInt() );
272  }
273 
274  TransportConfigWidget::apply();
275 }
276 
277 void SMTPConfigWidget::passwordsLoaded()
278 {
279  Q_D( SMTPConfigWidget );
280 
281  // Load the password from the original to our cloned copy
282  d->transport->updatePasswordState();
283 
284  if ( d->ui.password->text().isEmpty() ) {
285  d->ui.password->setText( d->transport->password() );
286  }
287 }
288 
289 // TODO rename
290 void SMTPConfigWidget::slotFinished( QList<int> results )
291 {
292  Q_D( SMTPConfigWidget );
293 
294  d->ui.checkCapabilitiesStack->setCurrentIndex( 0 );
295 
296  d->ui.checkCapabilities->setEnabled( true );
297  d->serverTest->deleteLater();
298 
299  // If the servertest did not find any useable authentication modes, assume the
300  // connection failed and don't disable any of the radioboxes.
301  if ( results.isEmpty() ) {
302  d->serverTestFailed = true;
303  d->serverTest->deleteLater();
304  return;
305  }
306 
307  // encryption method
308  d->ui.none->setEnabled( results.contains( Transport::EnumEncryption::None ) );
309  d->ui.ssl->setEnabled( results.contains( Transport::EnumEncryption::SSL ) );
310  d->ui.tls->setEnabled( results.contains( Transport::EnumEncryption::TLS ) );
311  checkHighestEnabledButton( d->encryptionGroup );
312 
313  d->noEncCapa = d->serverTest->normalProtocols();
314  if ( d->ui.tls->isEnabled() ) {
315  d->tlsCapa = d->serverTest->tlsProtocols();
316  } else {
317  d->tlsCapa.clear();
318  }
319  d->sslCapa = d->serverTest->secureProtocols();
320  d->updateAuthCapbilities();
321  //Show correct port from capabilities.
322  if (d->ui.ssl->isEnabled()) {
323  const int portValue = d->serverTest->port(Transport::EnumEncryption::SSL);
324  d->ui.kcfg_port->setValue(portValue == -1 ? SMTPS_PORT : portValue);
325  } else if (d->ui.none->isEnabled()) {
326  const int portValue = d->serverTest->port(Transport::EnumEncryption::None);
327  d->ui.kcfg_port->setValue(portValue == -1 ? SMTP_PORT : portValue);
328  }
329  d->serverTest->deleteLater();
330 }
331 
332 void SMTPConfigWidget::hostNameChanged( const QString &text )
333 {
334  // TODO: really? is this done at every change? wtf
335 
336  Q_D( SMTPConfigWidget );
337 
338  // sanitize hostname...
339  int pos = d->ui.kcfg_host->cursorPosition();
340  d->ui.kcfg_host->blockSignals( true );
341  d->ui.kcfg_host->setText( text.trimmed() );
342  d->ui.kcfg_host->blockSignals( false );
343  d->ui.kcfg_host->setCursorPosition( pos );
344 
345  d->resetAuthCapabilities();
346  for ( int i = 0; d->encryptionGroup && i < d->encryptionGroup->buttons().count(); i++ ) {
347  d->encryptionGroup->buttons().at( i )->setEnabled( true );
348  }
349 }
350 
351 void SMTPConfigWidget::ensureValidAuthSelection()
352 {
353  Q_D( SMTPConfigWidget );
354 
355  // adjust available authentication methods
356  d->updateAuthCapbilities();
357 }
358 
359 void SMTPConfigWidget::encryptionChanged( int enc )
360 {
361  Q_D( SMTPConfigWidget );
362  kDebug() << enc;
363 
364  // adjust port
365  if ( enc == Transport::EnumEncryption::SSL ) {
366  if ( d->ui.kcfg_port->value() == SMTP_PORT ) {
367  d->ui.kcfg_port->setValue( SMTPS_PORT );
368  }
369  } else {
370  if ( d->ui.kcfg_port->value() == SMTPS_PORT ) {
371  d->ui.kcfg_port->setValue( SMTP_PORT );
372  }
373  }
374 
375  ensureValidAuthSelection();
376 }
377 
MailTransport::TransportManager::self
static TransportManager * self()
Returns the TransportManager instance.
Definition: transportmanager.cpp:162
MailTransport::SMTPConfigWidget::apply
virtual void apply()
reimpl
Definition: smtpconfigwidget.cpp:261
MailTransport::ServerTest
This class can be used to test certain server to see if they support stuff.
Definition: servertest.h:41
MailTransport::SMTPConfigWidget
Definition: smtpconfigwidget.h:44
MailTransport::TransportConfigWidget::apply
virtual void apply()
Saves the transport's settings.
Definition: transportconfigwidget.cpp:73
MailTransport::Transport::authenticationTypeString
QString authenticationTypeString() const
Returns a string representation of the authentication type.
Definition: transport.cpp:122
MailTransport::Transport::isValid
bool isValid() const
Returns true if this transport is valid, ie.
Definition: transport.cpp:59
MailTransport::TransportConfigWidget
Definition: transportconfigwidget.h:59
mailtransport_defs.h
Internal file containing constant definitions etc.
MailTransport::TransportManager::loadPasswordsAsync
void loadPasswordsAsync()
Tries to load passwords asynchronously from KWallet if needed.
Definition: transportmanager.cpp:624
MailTransport::TransportConfigWidgetPrivate
Definition: transportconfigwidget_p.h:32
MailTransport::Transport
Represents the settings of a specific mail transport.
Definition: transport.h:50
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Mon Jul 21 2014 08:03:03 by doxygen 1.8.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

mailtransport

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

kdepimlibs-4.13.3 API Reference

Skip menu "kdepimlibs-4.13.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal