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

mailtransport

  • sources
  • kde-4.14
  • kdepimlibs
  • 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 #include <KMessageBox>
46 
47 namespace {
48 
49 // TODO: is this really necessary?
50 class BusyCursorHelper : public QObject
51 {
52  public:
53  inline BusyCursorHelper( QObject *parent ) : QObject( parent )
54  {
55 #ifndef QT_NO_CURSOR
56  qApp->setOverrideCursor( Qt::BusyCursor );
57 #endif
58  }
59 
60  inline ~BusyCursorHelper()
61  {
62 #ifndef QT_NO_CURSOR
63  qApp->restoreOverrideCursor();
64 #endif
65  }
66 };
67 
68 }
69 
70 using namespace MailTransport;
71 
72 class MailTransport::SMTPConfigWidgetPrivate : public TransportConfigWidgetPrivate
73 {
74  public:
75  ::Ui::SMTPSettings ui;
76 
77  ServerTest *serverTest;
78  QButtonGroup *encryptionGroup;
79 
80  // detected authentication capabilities
81  QList<int> noEncCapa, sslCapa, tlsCapa;
82 
83  bool serverTestFailed;
84 
85  static void addAuthenticationItem( KComboBox *combo,
86  int authenticationType )
87  {
88  combo->addItem( Transport::authenticationTypeString( authenticationType ),
89  QVariant( authenticationType ) );
90  }
91 
92  void resetAuthCapabilities()
93  {
94  noEncCapa.clear();
95  noEncCapa << Transport::EnumAuthenticationType::LOGIN
96  << Transport::EnumAuthenticationType::PLAIN
97  << Transport::EnumAuthenticationType::CRAM_MD5
98  << Transport::EnumAuthenticationType::DIGEST_MD5
99  << Transport::EnumAuthenticationType::NTLM
100  << Transport::EnumAuthenticationType::GSSAPI;
101  sslCapa = tlsCapa = noEncCapa;
102  updateAuthCapbilities();
103 
104  }
105 
106  void updateAuthCapbilities()
107  {
108  if ( serverTestFailed ) {
109  return;
110  }
111 
112  QList<int> capa = noEncCapa;
113  if ( ui.ssl->isChecked() ) {
114  capa = sslCapa;
115  } else if ( ui.tls->isChecked() ) {
116  capa = tlsCapa;
117  }
118 
119  ui.authCombo->clear();
120  foreach ( int authType, capa ) {
121  addAuthenticationItem( ui.authCombo, authType );
122  }
123 
124  if ( transport->isValid() ) {
125  const int idx = ui.authCombo->findData( transport->authenticationType() );
126 
127  if ( idx != -1 ) {
128  ui.authCombo->setCurrentIndex( idx );
129  }
130  }
131 
132  if ( capa.count() == 0 ) {
133  ui.noAuthPossible->setVisible( true );
134  ui.kcfg_requiresAuthentication->setChecked( false );
135  ui.kcfg_requiresAuthentication->setEnabled( false );
136  ui.kcfg_requiresAuthentication->setVisible( false );
137  ui.authCombo->setEnabled( false );
138  ui.authLabel->setEnabled( false );
139  } else {
140  ui.noAuthPossible->setVisible( false );
141  ui.kcfg_requiresAuthentication->setEnabled( true );
142  ui.kcfg_requiresAuthentication->setVisible( true );
143  ui.authCombo->setEnabled( true );
144  ui.authLabel->setEnabled( true );
145  }
146  }
147 };
148 
149 SMTPConfigWidget::SMTPConfigWidget( Transport *transport, QWidget *parent )
150  : TransportConfigWidget( *new SMTPConfigWidgetPrivate, transport, parent )
151 {
152  init();
153 }
154 
155 SMTPConfigWidget::SMTPConfigWidget( SMTPConfigWidgetPrivate &dd,
156  Transport *transport, QWidget *parent )
157  : TransportConfigWidget( dd, transport, parent )
158 {
159  init();
160 }
161 
162 static void checkHighestEnabledButton( QButtonGroup *group )
163 {
164  Q_ASSERT( group );
165 
166  for ( int i = group->buttons().count() - 1; i >= 0; --i ) {
167  QAbstractButton *b = group->buttons().at( i );
168  if ( b && b->isEnabled() ) {
169  b->animateClick();
170  return;
171  }
172  }
173 }
174 
175 void SMTPConfigWidget::init()
176 {
177  Q_D( SMTPConfigWidget );
178  d->serverTest = 0;
179 
180  connect( TransportManager::self(), SIGNAL(passwordsChanged()),
181  SLOT(passwordsLoaded()) );
182 
183  d->serverTestFailed = false;
184 
185  d->ui.setupUi( this );
186  d->manager->addWidget( this ); // otherwise it doesn't find out about these widgets
187  d->manager->updateWidgets();
188 
189  d->encryptionGroup = new QButtonGroup( this );
190  d->encryptionGroup->addButton( d->ui.none, Transport::EnumEncryption::None );
191  d->encryptionGroup->addButton( d->ui.ssl, Transport::EnumEncryption::SSL );
192  d->encryptionGroup->addButton( d->ui.tls, Transport::EnumEncryption::TLS );
193 
194  d->resetAuthCapabilities();
195 
196  if ( KProtocolInfo::capabilities( SMTP_PROTOCOL ).contains( QLatin1String( "SASL" ) ) == 0 ) {
197  d->ui.authCombo->removeItem( d->ui.authCombo->findData(
198  Transport::EnumAuthenticationType::NTLM ) );
199  d->ui.authCombo->removeItem( d->ui.authCombo->findData(
200  Transport::EnumAuthenticationType::GSSAPI ) );
201  }
202 
203  connect( d->ui.checkCapabilities, SIGNAL(clicked()),
204  SLOT(checkSmtpCapabilities()) );
205  connect( d->ui.kcfg_host, SIGNAL(textChanged(QString)),
206  SLOT(hostNameChanged(QString)) );
207  connect( d->encryptionGroup, SIGNAL(buttonClicked(int)),
208  SLOT(encryptionChanged(int)) );
209  connect( d->ui.kcfg_requiresAuthentication, SIGNAL(toggled(bool)),
210  SLOT(ensureValidAuthSelection()) );
211 
212  if ( !d->transport->isValid() ) {
213  checkHighestEnabledButton( d->encryptionGroup );
214  }
215 
216  // load the password
217  d->transport->updatePasswordState();
218  if ( d->transport->isComplete() ) {
219  d->ui.password->setText( d->transport->password() );
220  } else {
221  if ( d->transport->requiresAuthentication() ) {
222  TransportManager::self()->loadPasswordsAsync();
223  }
224  }
225 
226  hostNameChanged( d->transport->host() );
227 
228 #ifdef KDEPIM_MOBILE_UI
229  d->ui.smtpSettingsGroupBox->hide();
230 #endif
231 }
232 
233 void SMTPConfigWidget::checkSmtpCapabilities()
234 {
235  Q_D( SMTPConfigWidget );
236 
237  d->serverTest = new ServerTest( this );
238  d->serverTest->setProtocol( SMTP_PROTOCOL );
239  d->serverTest->setServer( d->ui.kcfg_host->text().trimmed() );
240  if ( d->ui.kcfg_specifyHostname->isChecked() ) {
241  d->serverTest->setFakeHostname( d->ui.kcfg_localHostname->text() );
242  }
243  QAbstractButton *encryptionChecked = d->encryptionGroup->checkedButton();
244  if (encryptionChecked == d->ui.none) {
245  d->serverTest->setPort( Transport::EnumEncryption::None, d->ui.kcfg_port->value());
246  } else if (encryptionChecked == d->ui.ssl) {
247  d->serverTest->setPort( Transport::EnumEncryption::SSL, d->ui.kcfg_port->value());
248  }
249  d->serverTest->setProgressBar( d->ui.checkCapabilitiesProgress );
250  d->ui.checkCapabilitiesStack->setCurrentIndex( 1 );
251  BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( d->serverTest );
252 
253  connect( d->serverTest, SIGNAL(finished(QList<int>)),
254  SLOT(slotFinished(QList<int>)));
255  connect( d->serverTest, SIGNAL(finished(QList<int>)),
256  busyCursorHelper, SLOT(deleteLater()) );
257  d->ui.checkCapabilities->setEnabled( false );
258  d->serverTest->start();
259  d->serverTestFailed = false;
260 }
261 
262 void SMTPConfigWidget::apply()
263 {
264  Q_D( SMTPConfigWidget );
265  Q_ASSERT( d->manager );
266  d->manager->updateSettings();
267  d->transport->setPassword( d->ui.password->text() );
268 
269  KConfigGroup group( d->transport->config(), d->transport->currentGroup() );
270  const int index = d->ui.authCombo->currentIndex();
271  if ( index >= 0 ) {
272  group.writeEntry( "authtype", d->ui.authCombo->itemData( index ).toInt() );
273  }
274 
275  TransportConfigWidget::apply();
276 }
277 
278 void SMTPConfigWidget::passwordsLoaded()
279 {
280  Q_D( SMTPConfigWidget );
281 
282  // Load the password from the original to our cloned copy
283  d->transport->updatePasswordState();
284 
285  if ( d->ui.password->text().isEmpty() ) {
286  d->ui.password->setText( d->transport->password() );
287  }
288 }
289 
290 // TODO rename
291 void SMTPConfigWidget::slotFinished( QList<int> results )
292 {
293  Q_D( SMTPConfigWidget );
294 
295  d->ui.checkCapabilitiesStack->setCurrentIndex( 0 );
296 
297  d->ui.checkCapabilities->setEnabled( true );
298  d->serverTest->deleteLater();
299 
300  // If the servertest did not find any useable authentication modes, assume the
301  // connection failed and don't disable any of the radioboxes.
302  if ( results.isEmpty() ) {
303  KMessageBox::error(this, i18n("Failed to check capabilities. Please verify port and authentication mode."), i18n("Check Capabilities Failed"));
304  d->serverTestFailed = true;
305  d->serverTest->deleteLater();
306  return;
307  }
308 
309  // encryption method
310  d->ui.none->setEnabled( results.contains( Transport::EnumEncryption::None ) );
311  d->ui.ssl->setEnabled( results.contains( Transport::EnumEncryption::SSL ) );
312  d->ui.tls->setEnabled( results.contains( Transport::EnumEncryption::TLS ) );
313  checkHighestEnabledButton( d->encryptionGroup );
314 
315  d->noEncCapa = d->serverTest->normalProtocols();
316  if ( d->ui.tls->isEnabled() ) {
317  d->tlsCapa = d->serverTest->tlsProtocols();
318  } else {
319  d->tlsCapa.clear();
320  }
321  d->sslCapa = d->serverTest->secureProtocols();
322  d->updateAuthCapbilities();
323  //Show correct port from capabilities.
324  if (d->ui.ssl->isEnabled()) {
325  const int portValue = d->serverTest->port(Transport::EnumEncryption::SSL);
326  d->ui.kcfg_port->setValue(portValue == -1 ? SMTPS_PORT : portValue);
327  } else if (d->ui.none->isEnabled()) {
328  const int portValue = d->serverTest->port(Transport::EnumEncryption::None);
329  d->ui.kcfg_port->setValue(portValue == -1 ? SMTP_PORT : portValue);
330  }
331  d->serverTest->deleteLater();
332 }
333 
334 void SMTPConfigWidget::hostNameChanged( const QString &text )
335 {
336  // TODO: really? is this done at every change? wtf
337 
338  Q_D( SMTPConfigWidget );
339 
340  // sanitize hostname...
341  int pos = d->ui.kcfg_host->cursorPosition();
342  d->ui.kcfg_host->blockSignals( true );
343  d->ui.kcfg_host->setText( text.trimmed() );
344  d->ui.kcfg_host->blockSignals( false );
345  d->ui.kcfg_host->setCursorPosition( pos );
346 
347  d->resetAuthCapabilities();
348  for ( int i = 0; d->encryptionGroup && i < d->encryptionGroup->buttons().count(); i++ ) {
349  d->encryptionGroup->buttons().at( i )->setEnabled( true );
350  }
351 }
352 
353 void SMTPConfigWidget::ensureValidAuthSelection()
354 {
355  Q_D( SMTPConfigWidget );
356 
357  // adjust available authentication methods
358  d->updateAuthCapbilities();
359 }
360 
361 void SMTPConfigWidget::encryptionChanged( int enc )
362 {
363  Q_D( SMTPConfigWidget );
364  kDebug() << enc;
365 
366  // adjust port
367  if ( enc == Transport::EnumEncryption::SSL ) {
368  if ( d->ui.kcfg_port->value() == SMTP_PORT ) {
369  d->ui.kcfg_port->setValue( SMTPS_PORT );
370  }
371  } else {
372  if ( d->ui.kcfg_port->value() == SMTPS_PORT ) {
373  d->ui.kcfg_port->setValue( SMTP_PORT );
374  }
375  }
376 
377  ensureValidAuthSelection();
378 }
379 
QList::clear
void clear()
QWidget
MailTransport::TransportManager::self
static TransportManager * self()
Returns the TransportManager instance.
Definition: transportmanager.cpp:162
MailTransport::SMTPConfigWidget::apply
virtual void apply()
reimpl
Definition: smtpconfigwidget.cpp:262
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
QButtonGroup
MailTransport::TransportConfigWidget::apply
virtual void apply()
Saves the transport's settings.
Definition: transportconfigwidget.cpp:73
QWidget::isEnabled
bool isEnabled() const
QList::count
int count(const T &value) const
QObject
QList::isEmpty
bool isEmpty() const
QString::trimmed
QString trimmed() const
MailTransport::Transport::authenticationTypeString
QString authenticationTypeString() const
Returns a string representation of the authentication type.
Definition: transport.cpp:122
QWidget::pos
QPoint pos() const
QObject::deleteLater
void deleteLater()
QString
QList< int >
MailTransport::Transport::isValid
bool isValid() const
Returns true if this transport is valid, ie.
Definition: transport.cpp:59
QList::contains
bool contains(const T &value) const
QAbstractButton
MailTransport::TransportConfigWidget
Definition: transportconfigwidget.h:59
QButtonGroup::buttons
QList< QAbstractButton * > buttons() const
QLatin1String
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:630
MailTransport::TransportConfigWidgetPrivate
Definition: transportconfigwidget_p.h:32
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
MailTransport::Transport
Represents the settings of a specific mail transport.
Definition: transport.h:50
QAbstractButton::animateClick
void animateClick(int msec)
QVariant
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:37:48 by doxygen 1.8.7 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 API Reference

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

Search



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