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.password->setRevealPasswordMode(
KAuthorized::authorize(QStringLiteral(
"lineedit_reveal_password")) ? KPassword::RevealMode::OnlyNew
146 : KPassword::RevealMode::Never);
147 d->manager->addWidget(
this);
148 d->manager->updateWidgets();
150 d->ui.password->setWhatsThis(
i18n(
"The password to send to the server for authorization."));
152 d->ui.kcfg_userName->setClearButtonEnabled(
true);
154 d->encryptionGroup->addButton(d->ui.encryptionNone, Transport::EnumEncryption::None);
155 d->encryptionGroup->addButton(d->ui.encryptionSsl, Transport::EnumEncryption::SSL);
156 d->encryptionGroup->addButton(d->ui.encryptionTls, Transport::EnumEncryption::TLS);
158 d->ui.encryptionNone->setChecked(d->transport->encryption() == Transport::EnumEncryption::None);
159 d->ui.encryptionSsl->setChecked(d->transport->encryption() == Transport::EnumEncryption::SSL);
160 d->ui.encryptionTls->setChecked(d->transport->encryption() == Transport::EnumEncryption::TLS);
162 d->ui.checkCapabilitiesProgress->setFormat(
i18nc(
"Percent value; %p is the value, % is the percent sign",
"%p%"));
164 d->resetAuthCapabilities();
166 if (!KProtocolInfo::capabilities(SMTP_PROTOCOL).contains(
"SASL"_L1)) {
167 d->ui.authCombo->removeItem(d->ui.authCombo->findData(Transport::EnumAuthenticationType::NTLM));
168 d->ui.authCombo->removeItem(d->ui.authCombo->findData(Transport::EnumAuthenticationType::GSSAPI));
177 if (!d->transport->isValid()) {
178 checkHighestEnabledButton(d->encryptionGroup);
182 d->transport->updatePasswordState();
183 if (d->transport->isComplete()) {
184 d->ui.password->setPassword(d->transport->password());
186 if (d->transport->requiresAuthentication()) {
191 hostNameChanged(d->transport->host());
193 const KPluginMetaData editWidgetPlugin(QStringLiteral(
"pim6/mailtransportactivities/kmailtransportactivitiesplugin"));
195 const auto result = KPluginFactory::instantiatePlugin<MailTransport::TransportActivitiesAbstractPlugin>(editWidgetPlugin);
197 mTransportActivitiesPlugin = result.plugin;
199 if (mTransportActivitiesPlugin) {
200 d->ui.tabWidget->addTab(mTransportActivitiesPlugin,
i18n(
"Activities"));
201 TransportActivitiesAbstractPlugin::ActivitySettings settings{
202 d->transport->activities(),
203 d->transport->activitiesEnabled(),
205 mTransportActivitiesPlugin->setActivitiesSettings(settings);
209void SMTPConfigWidget::enablePasswordLine()
212 d->enablePasswordLine();
215void SMTPConfigWidget::checkSmtpCapabilities()
220 d->serverTest->setProtocol(SMTP_PROTOCOL);
221 d->serverTest->setServer(d->ui.kcfg_host->text().trimmed());
222 if (d->ui.kcfg_specifyHostname->isChecked()) {
223 d->serverTest->setFakeHostname(d->ui.kcfg_localHostname->text());
225 QAbstractButton *encryptionChecked = d->encryptionGroup->checkedButton();
226 if (encryptionChecked == d->ui.encryptionNone) {
227 d->serverTest->setPort(Transport::EnumEncryption::None, d->ui.kcfg_port->value());
228 }
else if (encryptionChecked == d->ui.encryptionSsl) {
229 d->serverTest->setPort(Transport::EnumEncryption::SSL, d->ui.kcfg_port->value());
231 d->serverTest->setProgressBar(d->ui.checkCapabilitiesProgress);
232 d->ui.checkCapabilitiesStack->setCurrentIndex(1);
237 qApp->restoreOverrideCursor();
239 d->ui.checkCapabilities->setEnabled(
false);
240 d->serverTest->start();
241 d->serverTestFailed =
false;
247 Q_ASSERT(d->manager);
248 d->manager->updateSettings();
249 if (!d->ui.kcfg_storePassword->isChecked() && d->ui.kcfg_requiresAuthentication->isChecked()) {
253 d->transport->setPassword(d->ui.password->password());
255 KConfigGroup group(d->transport->config(), d->transport->currentGroup());
256 const int index = d->ui.authCombo->currentIndex();
258 group.
writeEntry(
"authtype", d->ui.authCombo->itemData(index).toInt());
261 if (d->ui.encryptionNone->isChecked()) {
262 d->transport->setEncryption(Transport::EnumEncryption::None);
263 }
else if (d->ui.encryptionSsl->isChecked()) {
264 d->transport->setEncryption(Transport::EnumEncryption::SSL);
265 }
else if (d->ui.encryptionTls->isChecked()) {
266 d->transport->setEncryption(Transport::EnumEncryption::TLS);
269 if (mTransportActivitiesPlugin) {
270 const TransportActivitiesAbstractPlugin::ActivitySettings settings = mTransportActivitiesPlugin->activitiesSettings();
271 d->transport->setActivities(settings.activities);
272 d->transport->setActivitiesEnabled(settings.enabled);
278void SMTPConfigWidget::passwordsLoaded()
283 d->transport->updatePasswordState();
285 if (d->ui.password->password().isEmpty()) {
286 d->ui.password->setPassword(d->transport->password());
290void SMTPConfigWidget::slotTestFinished(
const QList<int> &results)
294 d->ui.checkCapabilitiesStack->setCurrentIndex(0);
296 d->ui.checkCapabilities->setEnabled(
true);
297 d->serverTest->deleteLater();
303 i18n(
"Failed to check capabilities. Please verify port and authentication mode."),
304 i18nc(
"@title:window",
"Check Capabilities Failed"));
305 d->serverTestFailed =
true;
306 d->serverTest->deleteLater();
311 d->ui.encryptionNone->setEnabled(results.
contains(Transport::EnumEncryption::None));
312 d->ui.encryptionSsl->setEnabled(results.
contains(Transport::EnumEncryption::SSL));
313 d->ui.encryptionTls->setEnabled(results.
contains(Transport::EnumEncryption::TLS));
314 checkHighestEnabledButton(d->encryptionGroup);
316 d->noEncCapa = d->serverTest->normalProtocols();
317 if (d->ui.encryptionTls->isEnabled()) {
318 d->tlsCapa = d->serverTest->tlsProtocols();
322 d->sslCapa = d->serverTest->secureProtocols();
323 d->updateAuthCapbilities();
325 if (d->ui.encryptionSsl->isEnabled()) {
326 const int portValue = d->serverTest->port(Transport::EnumEncryption::SSL);
327 d->ui.kcfg_port->setValue(portValue == -1 ? SMTPS_PORT : portValue);
328 }
else if (d->ui.encryptionNone->isEnabled()) {
329 const int portValue = d->serverTest->port(Transport::EnumEncryption::None);
330 d->ui.kcfg_port->setValue(portValue == -1 ? SMTP_PORT : portValue);
332 d->serverTest->deleteLater();
335void SMTPConfigWidget::hostNameChanged(
const QString &text)
342 const int pos = d->ui.kcfg_host->cursorPosition();
343 d->ui.kcfg_host->blockSignals(
true);
344 d->ui.kcfg_host->setText(text.
trimmed());
345 d->ui.kcfg_host->blockSignals(
false);
346 d->ui.kcfg_host->setCursorPosition(
pos);
348 d->resetAuthCapabilities();
349 if (d->encryptionGroup) {
350 for (
int i = 0; i < d->encryptionGroup->buttons().count(); ++i) {
351 d->encryptionGroup->buttons().at(i)->setEnabled(
true);
356void SMTPConfigWidget::ensureValidAuthSelection()
361 d->updateAuthCapbilities();
362 d->enablePasswordLine();
365void SMTPConfigWidget::encryptionAbstractButtonChanged(
QAbstractButton *button)
369 encryptionChanged(d->encryptionGroup->id(button));
373void SMTPConfigWidget::encryptionChanged(
int enc)
376 qCDebug(MAILTRANSPORT_SMTP_LOG) << enc;
379 if (enc == Transport::EnumEncryption::SSL) {
380 if (d->ui.kcfg_port->value() == SMTP_PORT) {
381 d->ui.kcfg_port->setValue(SMTPS_PORT);
384 if (d->ui.kcfg_port->value() == SMTPS_PORT) {
385 d->ui.kcfg_port->setValue(SMTP_PORT);
389 ensureValidAuthSelection();
392#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 init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
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