14#include "smtpconfigwidget.h"
17#include "ui_smtpsettings.h"
20#include "mailtransportplugin_smtp_debug.h"
21#include "servertest.h"
23#include "transportmanager.h"
24#include "widgets/transportactivitiesabstractplugin.h"
25#include "widgets/transportconfigwidget_p.h"
27#include <QAbstractButton>
28#include <QButtonGroup>
31#include <KLocalizedString>
33#include <KPluginFactory>
34#include <KPluginMetaData>
35#include <KProtocolInfo>
37using namespace MailTransport;
39class MailTransport::SMTPConfigWidgetPrivate :
public TransportConfigWidgetPrivate
42 ::Ui::SMTPSettings ui;
50 bool serverTestFailed;
52 static void addAuthenticationItem(
QComboBox *combo,
int authenticationType)
57 void resetAuthCapabilities()
60 noEncCapa << Transport::EnumAuthenticationType::LOGIN << Transport::EnumAuthenticationType::PLAIN << Transport::EnumAuthenticationType::CRAM_MD5
61 << Transport::EnumAuthenticationType::DIGEST_MD5 << Transport::EnumAuthenticationType::NTLM << Transport::EnumAuthenticationType::GSSAPI
62 << Transport::EnumAuthenticationType::XOAUTH2;
63 sslCapa = tlsCapa = noEncCapa;
64 updateAuthCapbilities();
67 void enablePasswordLine()
69 ui.password->setEnabled(ui.kcfg_storePassword->isChecked());
72 void updateAuthCapbilities()
74 if (serverTestFailed) {
79 if (ui.encryptionSsl->isChecked()) {
81 }
else if (ui.encryptionTls->isChecked()) {
85 ui.authCombo->
clear();
86 for (
int authType : std::as_const(capa)) {
87 addAuthenticationItem(ui.authCombo, authType);
90 if (transport->isValid()) {
91 const int idx = ui.authCombo->findData(transport->authenticationType());
94 ui.authCombo->setCurrentIndex(idx);
99 ui.noAuthPossible->setVisible(
true);
100 ui.kcfg_requiresAuthentication->setChecked(
false);
101 ui.kcfg_requiresAuthentication->setEnabled(
false);
102 ui.kcfg_requiresAuthentication->setVisible(
false);
103 ui.authCombo->setEnabled(
false);
104 ui.authLabel->setEnabled(
false);
106 ui.noAuthPossible->setVisible(
false);
107 ui.kcfg_requiresAuthentication->setEnabled(
true);
108 ui.kcfg_requiresAuthentication->setVisible(
true);
109 ui.authCombo->setEnabled(
true);
110 ui.authLabel->setEnabled(
true);
111 enablePasswordLine();
122static void checkHighestEnabledButton(
QButtonGroup *group)
126 for (
int i = group->
buttons().count() - 1; i >= 0; --i) {
135void SMTPConfigWidget::init()
138 d->serverTest =
nullptr;
142 d->serverTestFailed =
false;
145 d->ui.tabWidget->tabBar()->setExpanding(
true);
146 d->ui.password->setRevealPasswordMode(
KAuthorized::authorize(QStringLiteral(
"lineedit_reveal_password")) ? KPassword::RevealMode::OnlyNew
147 : KPassword::RevealMode::Never);
148 d->manager->addWidget(
this);
149 d->manager->updateWidgets();
151 d->ui.password->setWhatsThis(
i18n(
"The password to send to the server for authorization."));
153 d->ui.kcfg_userName->setClearButtonEnabled(
true);
155 d->encryptionGroup->addButton(d->ui.encryptionNone, Transport::EnumEncryption::None);
156 d->encryptionGroup->addButton(d->ui.encryptionSsl, Transport::EnumEncryption::SSL);
157 d->encryptionGroup->addButton(d->ui.encryptionTls, Transport::EnumEncryption::TLS);
159 d->ui.encryptionNone->setChecked(d->transport->encryption() == Transport::EnumEncryption::None);
160 d->ui.encryptionSsl->setChecked(d->transport->encryption() == Transport::EnumEncryption::SSL);
161 d->ui.encryptionTls->setChecked(d->transport->encryption() == Transport::EnumEncryption::TLS);
163 d->ui.checkCapabilitiesProgress->setFormat(
i18nc(
"Percent value; %p is the value, % is the percent sign",
"%p%"));
165 d->resetAuthCapabilities();
167 if (!KProtocolInfo::capabilities(SMTP_PROTOCOL).contains(
"SASL"_L1)) {
168 d->ui.authCombo->removeItem(d->ui.authCombo->findData(Transport::EnumAuthenticationType::NTLM));
169 d->ui.authCombo->removeItem(d->ui.authCombo->findData(Transport::EnumAuthenticationType::GSSAPI));
178 if (!d->transport->isValid()) {
179 checkHighestEnabledButton(d->encryptionGroup);
183 d->transport->updatePasswordState();
184 if (d->transport->isComplete()) {
185 d->ui.password->setPassword(d->transport->password());
187 if (d->transport->requiresAuthentication()) {
192 hostNameChanged(d->transport->host());
194 const KPluginMetaData editWidgetPlugin(QStringLiteral(
"pim6/mailtransportactivities/kmailtransportactivitiesplugin"));
196 const auto result = KPluginFactory::instantiatePlugin<MailTransport::TransportActivitiesAbstractPlugin>(editWidgetPlugin);
198 mTransportActivitiesPlugin = result.plugin;
200 if (mTransportActivitiesPlugin) {
201 d->ui.tabWidget->addTab(mTransportActivitiesPlugin,
i18n(
"Activities"));
202 TransportActivitiesAbstractPlugin::ActivitySettings settings{
203 d->transport->activities(),
204 d->transport->activitiesEnabled(),
206 mTransportActivitiesPlugin->setActivitiesSettings(settings);
210void SMTPConfigWidget::enablePasswordLine()
213 d->enablePasswordLine();
216void SMTPConfigWidget::checkSmtpCapabilities()
221 d->serverTest->setProtocol(SMTP_PROTOCOL);
222 d->serverTest->setServer(d->ui.kcfg_host->text().trimmed());
223 if (d->ui.kcfg_specifyHostname->isChecked()) {
224 d->serverTest->setFakeHostname(d->ui.kcfg_localHostname->text());
226 QAbstractButton *encryptionChecked = d->encryptionGroup->checkedButton();
227 if (encryptionChecked == d->ui.encryptionNone) {
228 d->serverTest->setPort(Transport::EnumEncryption::None, d->ui.kcfg_port->value());
229 }
else if (encryptionChecked == d->ui.encryptionSsl) {
230 d->serverTest->setPort(Transport::EnumEncryption::SSL, d->ui.kcfg_port->value());
232 d->serverTest->setProgressBar(d->ui.checkCapabilitiesProgress);
233 d->ui.checkCapabilitiesStack->setCurrentIndex(1);
238 qApp->restoreOverrideCursor();
240 d->ui.checkCapabilities->setEnabled(
false);
241 d->serverTest->start();
242 d->serverTestFailed =
false;
248 Q_ASSERT(d->manager);
249 d->manager->updateSettings();
250 if (!d->ui.kcfg_storePassword->isChecked() && d->ui.kcfg_requiresAuthentication->isChecked()) {
254 d->transport->setPassword(d->ui.password->password());
256 KConfigGroup group(d->transport->config(), d->transport->currentGroup());
257 const int index = d->ui.authCombo->currentIndex();
259 group.
writeEntry(
"authtype", d->ui.authCombo->itemData(index).toInt());
262 if (d->ui.encryptionNone->isChecked()) {
263 d->transport->setEncryption(Transport::EnumEncryption::None);
264 }
else if (d->ui.encryptionSsl->isChecked()) {
265 d->transport->setEncryption(Transport::EnumEncryption::SSL);
266 }
else if (d->ui.encryptionTls->isChecked()) {
267 d->transport->setEncryption(Transport::EnumEncryption::TLS);
270 if (mTransportActivitiesPlugin) {
271 const TransportActivitiesAbstractPlugin::ActivitySettings settings = mTransportActivitiesPlugin->activitiesSettings();
272 d->transport->setActivities(settings.activities);
273 d->transport->setActivitiesEnabled(settings.enabled);
279void SMTPConfigWidget::passwordsLoaded()
284 d->transport->updatePasswordState();
286 if (d->ui.password->password().isEmpty()) {
287 d->ui.password->setPassword(d->transport->password());
291void SMTPConfigWidget::slotTestFinished(
const QList<int> &results)
295 d->ui.checkCapabilitiesStack->setCurrentIndex(0);
297 d->ui.checkCapabilities->setEnabled(
true);
298 d->serverTest->deleteLater();
304 i18n(
"Failed to check capabilities. Please verify port and authentication mode."),
305 i18nc(
"@title:window",
"Check Capabilities Failed"));
306 d->serverTestFailed =
true;
307 d->serverTest->deleteLater();
312 d->ui.encryptionNone->setEnabled(results.
contains(Transport::EnumEncryption::None));
313 d->ui.encryptionSsl->setEnabled(results.
contains(Transport::EnumEncryption::SSL));
314 d->ui.encryptionTls->setEnabled(results.
contains(Transport::EnumEncryption::TLS));
315 checkHighestEnabledButton(d->encryptionGroup);
317 d->noEncCapa = d->serverTest->normalProtocols();
318 if (d->ui.encryptionTls->isEnabled()) {
319 d->tlsCapa = d->serverTest->tlsProtocols();
323 d->sslCapa = d->serverTest->secureProtocols();
324 d->updateAuthCapbilities();
326 if (d->ui.encryptionSsl->isEnabled()) {
327 const int portValue = d->serverTest->port(Transport::EnumEncryption::SSL);
328 d->ui.kcfg_port->setValue(portValue == -1 ? SMTPS_PORT : portValue);
329 }
else if (d->ui.encryptionNone->isEnabled()) {
330 const int portValue = d->serverTest->port(Transport::EnumEncryption::None);
331 d->ui.kcfg_port->setValue(portValue == -1 ? SMTP_PORT : portValue);
333 d->serverTest->deleteLater();
336void SMTPConfigWidget::hostNameChanged(
const QString &text)
343 const int pos = d->ui.kcfg_host->cursorPosition();
344 d->ui.kcfg_host->blockSignals(
true);
345 d->ui.kcfg_host->setText(text.
trimmed());
346 d->ui.kcfg_host->blockSignals(
false);
347 d->ui.kcfg_host->setCursorPosition(
pos);
349 d->resetAuthCapabilities();
350 if (d->encryptionGroup) {
351 for (
int i = 0; i < d->encryptionGroup->buttons().count(); ++i) {
352 d->encryptionGroup->buttons().at(i)->setEnabled(
true);
357void SMTPConfigWidget::ensureValidAuthSelection()
362 d->updateAuthCapbilities();
363 d->enablePasswordLine();
366void SMTPConfigWidget::encryptionAbstractButtonChanged(
QAbstractButton *button)
370 encryptionChanged(d->encryptionGroup->id(button));
374void SMTPConfigWidget::encryptionChanged(
int enc)
377 qCDebug(MAILTRANSPORT_SMTP_LOG) << enc;
380 if (enc == Transport::EnumEncryption::SSL) {
381 if (d->ui.kcfg_port->value() == SMTP_PORT) {
382 d->ui.kcfg_port->setValue(SMTPS_PORT);
385 if (d->ui.kcfg_port->value() == SMTPS_PORT) {
386 d->ui.kcfg_port->setValue(SMTP_PORT);
390 ensureValidAuthSelection();
393#include "moc_smtpconfigwidget.cpp"
static Q_INVOKABLE bool authorize(const QString &action)
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
This class can be used to test certain server to see if they support stuff.
void finished(const QList< int > &)
This will be emitted when the test is done.
void loadPasswordsAsync()
Tries to load passwords asynchronously from KWallet if needed.
void passwordsChanged()
Emitted when passwords have been loaded from the wallet.
static TransportManager * self()
Returns the TransportManager instance.
Represents the settings of a specific mail transport.
QString authenticationTypeString() const
Returns a string representation of the authentication type.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Internal file containing constant definitions etc.
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void textChanged(const QString &text)
bool contains(const AT &value) const const
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString trimmed() const const