• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.11.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  d->serverTest->setProgressBar( d->ui.checkCapabilitiesProgress );
243  d->ui.checkCapabilitiesStack->setCurrentIndex( 1 );
244  BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( d->serverTest );
245 
246  connect( d->serverTest, SIGNAL(finished(QList<int>)),
247  SLOT(slotFinished(QList<int>)));
248  connect( d->serverTest, SIGNAL(finished(QList<int>)),
249  busyCursorHelper, SLOT(deleteLater()) );
250  d->ui.checkCapabilities->setEnabled( false );
251  d->serverTest->start();
252  d->serverTestFailed = false;
253 }
254 
255 void SMTPConfigWidget::apply()
256 {
257  Q_D( SMTPConfigWidget );
258  Q_ASSERT( d->manager );
259  d->manager->updateSettings();
260  d->transport->setPassword( d->ui.password->text() );
261 
262  KConfigGroup group( d->transport->config(), d->transport->currentGroup() );
263  const int index = d->ui.authCombo->currentIndex();
264  if ( index >= 0 ) {
265  group.writeEntry( "authtype", d->ui.authCombo->itemData( index ).toInt() );
266  }
267 
268  TransportConfigWidget::apply();
269 }
270 
271 void SMTPConfigWidget::passwordsLoaded()
272 {
273  Q_D( SMTPConfigWidget );
274 
275  // Load the password from the original to our cloned copy
276  d->transport->updatePasswordState();
277 
278  if ( d->ui.password->text().isEmpty() ) {
279  d->ui.password->setText( d->transport->password() );
280  }
281 }
282 
283 // TODO rename
284 void SMTPConfigWidget::slotFinished( QList<int> results )
285 {
286  Q_D( SMTPConfigWidget );
287 
288  d->ui.checkCapabilitiesStack->setCurrentIndex( 0 );
289 
290  d->ui.checkCapabilities->setEnabled( true );
291  d->serverTest->deleteLater();
292 
293  // If the servertest did not find any useable authentication modes, assume the
294  // connection failed and don't disable any of the radioboxes.
295  if ( results.isEmpty() ) {
296  d->serverTestFailed = true;
297  return;
298  }
299 
300  // encryption method
301  d->ui.none->setEnabled( results.contains( Transport::EnumEncryption::None ) );
302  d->ui.ssl->setEnabled( results.contains( Transport::EnumEncryption::SSL ) );
303  d->ui.tls->setEnabled( results.contains( Transport::EnumEncryption::TLS ) );
304  checkHighestEnabledButton( d->encryptionGroup );
305 
306  d->noEncCapa = d->serverTest->normalProtocols();
307  if ( d->ui.tls->isEnabled() ) {
308  d->tlsCapa = d->serverTest->tlsProtocols();
309  } else {
310  d->tlsCapa.clear();
311  }
312  d->sslCapa = d->serverTest->secureProtocols();
313  d->updateAuthCapbilities();
314 }
315 
316 void SMTPConfigWidget::hostNameChanged( const QString &text )
317 {
318  // TODO: really? is this done at every change? wtf
319 
320  Q_D( SMTPConfigWidget );
321 
322  // sanitize hostname...
323  int pos = d->ui.kcfg_host->cursorPosition();
324  d->ui.kcfg_host->blockSignals( true );
325  d->ui.kcfg_host->setText( text.trimmed() );
326  d->ui.kcfg_host->blockSignals( false );
327  d->ui.kcfg_host->setCursorPosition( pos );
328 
329  d->resetAuthCapabilities();
330  for ( int i = 0; d->encryptionGroup && i < d->encryptionGroup->buttons().count(); i++ ) {
331  d->encryptionGroup->buttons().at( i )->setEnabled( true );
332  }
333 }
334 
335 void SMTPConfigWidget::ensureValidAuthSelection()
336 {
337  Q_D( SMTPConfigWidget );
338 
339  // adjust available authentication methods
340  d->updateAuthCapbilities();
341 }
342 
343 void SMTPConfigWidget::encryptionChanged( int enc )
344 {
345  Q_D( SMTPConfigWidget );
346  kDebug() << enc;
347 
348  // adjust port
349  if ( enc == Transport::EnumEncryption::SSL ) {
350  if ( d->ui.kcfg_port->value() == SMTP_PORT ) {
351  d->ui.kcfg_port->setValue( SMTPS_PORT );
352  }
353  } else {
354  if ( d->ui.kcfg_port->value() == SMTPS_PORT ) {
355  d->ui.kcfg_port->setValue( SMTP_PORT );
356  }
357  }
358 
359  ensureValidAuthSelection();
360 }
361 
MailTransport::TransportManager::self
static TransportManager * self()
Returns the TransportManager instance.
Definition: transportmanager.cpp:163
MailTransport::SMTPConfigWidget::apply
virtual void apply()
reimpl
Definition: smtpconfigwidget.cpp:255
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&#39;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::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-2013 The KDE developers.
Generated on Tue Nov 26 2013 09:03:01 by doxygen 1.8.5 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.11.3 API Reference

Skip menu "kdepimlibs-4.11.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