diff --git a/resources/dav/resource/urlconfigurationdialog.cpp b/resources/dav/resource/urlconfigurationdialog.cpp index beb0ab5ff..abea23d54 100644 --- a/resources/dav/resource/urlconfigurationdialog.cpp +++ b/resources/dav/resource/urlconfigurationdialog.cpp @@ -1,297 +1,298 @@ /* Copyright (c) 2010 Grégory Oestreicher This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "urlconfigurationdialog.h" #include #include #include #include "settings.h" #include #include +#include #include #include #include UrlConfigurationDialog::UrlConfigurationDialog(QWidget *parent) : QDialog(parent) , mRemoteProtocolGroup(new QButtonGroup(this)) { QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(mainWidget); mUi.setupUi(mainWidget); mUi.credentialsGroup->setVisible(false); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); mOkButton = buttonBox->button(QDialogButtonBox::Ok); mOkButton->setDefault(true); mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &UrlConfigurationDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &UrlConfigurationDialog::reject); mainLayout->addWidget(buttonBox); mModel = new QStandardItemModel(); initModel(); mUi.discoveredUrls->setModel(mModel); mUi.discoveredUrls->setRootIsDecorated(false); connect(mModel, &QStandardItemModel::dataChanged, this, &UrlConfigurationDialog::onModelDataChanged); mRemoteProtocolGroup->setExclusive(true); mRemoteProtocolGroup->addButton(mUi.caldav, KDAV::CalDav); mRemoteProtocolGroup->addButton(mUi.carddav, KDAV::CardDav); mRemoteProtocolGroup->addButton(mUi.groupdav, KDAV::GroupDav); connect(mRemoteProtocolGroup, QOverload::of(&QButtonGroup::buttonToggled), this, &UrlConfigurationDialog::onConfigChanged); connect(mUi.remoteUrl, &KLineEdit::textChanged, this, &UrlConfigurationDialog::onConfigChanged); connect(mUi.useDefaultCreds, &QRadioButton::toggled, this, &UrlConfigurationDialog::onConfigChanged); connect(mUi.username, &KLineEdit::textChanged, this, &UrlConfigurationDialog::onConfigChanged); connect(mUi.password, &KPasswordLineEdit::passwordChanged, this, &UrlConfigurationDialog::onConfigChanged); connect(mUi.fetchButton, &QPushButton::clicked, this, &UrlConfigurationDialog::onFetchButtonClicked); connect(mOkButton, &QPushButton::clicked, this, &UrlConfigurationDialog::onOkButtonClicked); checkUserInput(); readConfig(); } UrlConfigurationDialog::~UrlConfigurationDialog() { writeConfig(); } void UrlConfigurationDialog::readConfig() { KConfigGroup grp(KSharedConfig::openConfig(), "UrlConfigurationDialog"); const QSize size = grp.readEntry("Size", QSize(300, 200)); if (size.isValid()) { resize(size); } } void UrlConfigurationDialog::writeConfig() { KConfigGroup grp(KSharedConfig::openConfig(), "UrlConfigurationDialog"); grp.writeEntry("Size", size()); grp.sync(); } KDAV::Protocol UrlConfigurationDialog::protocol() const { return KDAV::Protocol(mRemoteProtocolGroup->id(mRemoteProtocolGroup->checkedButton())); } void UrlConfigurationDialog::setProtocol(KDAV::Protocol protocol) { mRemoteProtocolGroup->button(protocol)->setChecked(true); } QString UrlConfigurationDialog::remoteUrl() const { return mUi.remoteUrl->text(); } void UrlConfigurationDialog::setRemoteUrl(const QString &url) { mUi.remoteUrl->setText(url); } bool UrlConfigurationDialog::useDefaultCredentials() const { return mUi.useDefaultCreds->isChecked(); } void UrlConfigurationDialog::setUseDefaultCredentials(bool defaultCreds) { if (defaultCreds) { mUi.useDefaultCreds->setChecked(true); } else { mUi.useSpecificCreds->setChecked(true); } } QString UrlConfigurationDialog::username() const { if (mUi.useDefaultCreds->isChecked()) { return mDefaultUsername; } else { return mUi.username->text(); } } void UrlConfigurationDialog::setDefaultUsername(const QString &userName) { mDefaultUsername = userName; } void UrlConfigurationDialog::setUsername(const QString &userName) { mUi.username->setText(userName); } QString UrlConfigurationDialog::password() const { if (mUi.useDefaultCreds->isChecked()) { return mDefaultPassword; } else { return mUi.password->password(); } } void UrlConfigurationDialog::setDefaultPassword(const QString &password) { mDefaultPassword = password; } void UrlConfigurationDialog::setPassword(const QString &password) { mUi.password->setPassword(password); } void UrlConfigurationDialog::onConfigChanged() { initModel(); mUi.fetchButton->setEnabled(false); mOkButton->setEnabled(false); checkUserInput(); } void UrlConfigurationDialog::checkUserInput() { if (!mUi.remoteUrl->text().trimmed().isEmpty() && checkUserAuthInput()) { mUi.fetchButton->setEnabled(true); if (mModel->rowCount() > 0) { mOkButton->setEnabled(true); } } else { mUi.fetchButton->setEnabled(false); mOkButton->setEnabled(false); } } void UrlConfigurationDialog::onFetchButtonClicked() { mUi.discoveredUrls->setEnabled(false); initModel(); if (!remoteUrl().endsWith(QLatin1Char('/'))) { setRemoteUrl(remoteUrl() + QLatin1Char('/')); } if (!remoteUrl().startsWith(QStringLiteral("https://")) && !remoteUrl().startsWith(QStringLiteral("http://"))) { setRemoteUrl(QStringLiteral("https://") + remoteUrl()); } QUrl url(mUi.remoteUrl->text()); if (mUi.useDefaultCreds->isChecked()) { url.setUserName(mDefaultUsername); url.setPassword(mDefaultPassword); } else { url.setUserName(username()); url.setPassword(password()); } KDAV::DavUrl davUrl(url, protocol()); KDAV::DavCollectionsFetchJob *job = new KDAV::DavCollectionsFetchJob(davUrl); connect(job, &KDAV::DavCollectionsFetchJob::result, this, &UrlConfigurationDialog::onCollectionsFetchDone); job->start(); } void UrlConfigurationDialog::onOkButtonClicked() { if (!remoteUrl().endsWith(QLatin1Char('/'))) { setRemoteUrl(remoteUrl() + QLatin1Char('/')); } } void UrlConfigurationDialog::onCollectionsFetchDone(KJob *job) { mUi.discoveredUrls->setEnabled(true); if (job->error()) { KMessageBox::error(this, job->errorText()); return; } KDAV::DavCollectionsFetchJob *davJob = qobject_cast< KDAV::DavCollectionsFetchJob *>(job); const KDAV::DavCollection::List collections = davJob->collections(); for (const KDAV::DavCollection &collection : collections) { addModelRow(collection.displayName(), collection.url().toDisplayString()); } checkUserInput(); } void UrlConfigurationDialog::onModelDataChanged(const QModelIndex &topLeft, const QModelIndex &) { // Actually only the display name can be changed, so no stricts checks are required const QString newName = topLeft.data().toString(); const QString url = topLeft.sibling(topLeft.row(), 1).data().toString(); QUrl fullUrl(url); fullUrl.setUserInfo(QString()); KDAV::DavUrl davUrl(fullUrl, protocol()); KDAV::DavCollectionModifyJob *job = new KDAV::DavCollectionModifyJob(davUrl); job->setProperty(QStringLiteral("displayname"), newName); connect(job, &KDAV::DavCollectionModifyJob::result, this, &UrlConfigurationDialog::onChangeDisplayNameFinished); job->start(); mUi.discoveredUrls->setEnabled(false); } void UrlConfigurationDialog::onChangeDisplayNameFinished(KJob *job) { if (job->error()) { KMessageBox::error(this, job->errorText()); } onFetchButtonClicked(); } void UrlConfigurationDialog::initModel() { mModel->clear(); const QStringList headers = { i18n("Display name"), i18n("URL") }; mModel->setHorizontalHeaderLabels(headers); } bool UrlConfigurationDialog::checkUserAuthInput() { return mUi.useDefaultCreds->isChecked() || !(mUi.username->text().isEmpty() || mUi.password->password().isEmpty()); } void UrlConfigurationDialog::addModelRow(const QString &displayName, const QString &url) { QStandardItem *rootItem = mModel->invisibleRootItem(); QList items; QStandardItem *displayNameStandardItem = new QStandardItem(displayName); displayNameStandardItem->setEditable(true); items << displayNameStandardItem; QStandardItem *urlStandardItem = new QStandardItem(url); urlStandardItem->setEditable(false); items << urlStandardItem; rootItem->appendRow(items); } diff --git a/resources/kalarm/shared/alarmtyperadiowidget.cpp b/resources/kalarm/shared/alarmtyperadiowidget.cpp index a5663688a..7134d177f 100644 --- a/resources/kalarm/shared/alarmtyperadiowidget.cpp +++ b/resources/kalarm/shared/alarmtyperadiowidget.cpp @@ -1,72 +1,74 @@ /* * alarmtyperadiowidget.cpp - KAlarm alarm type exclusive selection widget * Program: kalarm * Copyright © 2011 by David Jarvie * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "alarmtyperadiowidget.h" +#include + AlarmTypeRadioWidget::AlarmTypeRadioWidget(QWidget *parent) : Akonadi::SingleFileValidatingWidget(parent) { ui.setupUi(this); ui.mainLayout->setContentsMargins(0, 0, 0, 0); mButtonGroup = new QButtonGroup(ui.groupBox); mButtonGroup->addButton(ui.activeRadio); mButtonGroup->addButton(ui.archivedRadio); mButtonGroup->addButton(ui.templateRadio); connect(ui.activeRadio, &QRadioButton::toggled, this, &AlarmTypeRadioWidget::changed); connect(ui.archivedRadio, &QRadioButton::toggled, this, &AlarmTypeRadioWidget::changed); connect(ui.templateRadio, &QRadioButton::toggled, this, &AlarmTypeRadioWidget::changed); } void AlarmTypeRadioWidget::setAlarmType(CalEvent::Type type) { switch (type) { case CalEvent::ACTIVE: ui.activeRadio->setChecked(true); break; case CalEvent::ARCHIVED: ui.archivedRadio->setChecked(true); break; case CalEvent::TEMPLATE: ui.templateRadio->setChecked(true); break; default: break; } } CalEvent::Type AlarmTypeRadioWidget::alarmType() const { if (ui.activeRadio->isChecked()) { return CalEvent::ACTIVE; } if (ui.archivedRadio->isChecked()) { return CalEvent::ARCHIVED; } if (ui.templateRadio->isChecked()) { return CalEvent::TEMPLATE; } return CalEvent::EMPTY; } bool AlarmTypeRadioWidget::validate() const { return static_cast(mButtonGroup->checkedButton()); } diff --git a/resources/pop3/accountdialog.cpp b/resources/pop3/accountdialog.cpp index 378a0d84c..fa59f306c 100644 --- a/resources/pop3/accountdialog.cpp +++ b/resources/pop3/accountdialog.cpp @@ -1,657 +1,659 @@ /* * Copyright (C) 2000 Espen Sand, espen@kde.org * Copyright 2009 Thomas McGuire * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company * Copyright (C) 2010 Casey Link * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ // Local includes #include "accountdialog.h" #include "pop3resource.h" #include "settings.h" #include "settingsadaptor.h" // KDEPIMLIBS includes #include #include #include #include #include #include // KDELIBS includes #include #include #include #include #include #include "pop3resource_debug.h" + +#include #include #include #include using namespace MailTransport; using namespace Akonadi; using namespace KWallet; namespace { class BusyCursorHelper : public QObject { public: inline BusyCursorHelper(QObject *parent) : QObject(parent) { #ifndef QT_NO_CURSOR qApp->setOverrideCursor(Qt::BusyCursor); #endif } inline ~BusyCursorHelper() { #ifndef QT_NO_CURSOR qApp->restoreOverrideCursor(); #endif } }; } AccountDialog::AccountDialog(POP3Resource *parentResource, WId parentWindow) : QDialog() , mParentResource(parentResource) , mServerTest(nullptr) , mValidator(this) , mWallet(nullptr) { KWindowSystem::setMainWindow(this, parentWindow); setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server"))); setWindowTitle(i18n("POP3 Account Settings")); mValidator.setRegExp(QRegExp(QLatin1String("[A-Za-z0-9-_:.]*"))); setupWidgets(); loadSettings(); } AccountDialog::~AccountDialog() { delete mWallet; mWallet = nullptr; delete mServerTest; mServerTest = nullptr; } void AccountDialog::setupWidgets() { QVBoxLayout *mainLayout = new QVBoxLayout(this); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); mOkButton = buttonBox->button(QDialogButtonBox::Ok); mOkButton->setDefault(true); mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &AccountDialog::slotAccepted); connect(buttonBox, &QDialogButtonBox::rejected, this, &AccountDialog::reject); QWidget *page = new QWidget(this); mainLayout->addWidget(page); mainLayout->addWidget(buttonBox); setupUi(page); // only letters, digits, '-', '.', ':' (IPv6) and '_' (for Windows // compatibility) are allowed hostEdit->setValidator(&mValidator); intervalSpin->setSuffix(ki18np(" minute", " minutes")); intervalSpin->setRange(ResourceSettings::self()->minimumCheckInterval(), 10000); intervalSpin->setSingleStep(1); connect(leaveOnServerCheck, &QCheckBox::clicked, this, &AccountDialog::slotLeaveOnServerClicked); connect(leaveOnServerDaysCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnableLeaveOnServerDays); connect(leaveOnServerDaysSpin, QOverload::of(&QSpinBox::valueChanged), this, &AccountDialog::slotLeaveOnServerDaysChanged); connect(leaveOnServerCountCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnableLeaveOnServerCount); connect(leaveOnServerCountSpin, QOverload::of(&QSpinBox::valueChanged), this, &AccountDialog::slotLeaveOnServerCountChanged); connect(leaveOnServerSizeCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnableLeaveOnServerSize); connect(filterOnServerSizeSpin, QOverload::of(&QSpinBox::valueChanged), this, &AccountDialog::slotFilterOnServerSizeChanged); connect(filterOnServerCheck, &QCheckBox::toggled, filterOnServerSizeSpin, &QSpinBox::setEnabled); connect(filterOnServerCheck, &QCheckBox::clicked, this, &AccountDialog::slotFilterOnServerClicked); connect(checkCapabilities, &QPushButton::clicked, this, &AccountDialog::slotCheckPopCapabilities); encryptionButtonGroup = new QButtonGroup(); encryptionButtonGroup->addButton(encryptionNone, Transport::EnumEncryption::None); encryptionButtonGroup->addButton(encryptionSSL, Transport::EnumEncryption::SSL); encryptionButtonGroup->addButton(encryptionTLS, Transport::EnumEncryption::TLS); connect(encryptionButtonGroup, QOverload::of(&QButtonGroup::buttonClicked), this, &AccountDialog::slotPopEncryptionChanged); connect(intervalCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnablePopInterval); populateDefaultAuthenticationOptions(); folderRequester->setMimeTypeFilter( QStringList() << QStringLiteral("message/rfc822")); folderRequester->setAccessRightsFilter(Akonadi::Collection::CanCreateItem); folderRequester->changeCollectionDialogOptions(Akonadi::CollectionDialog::AllowToCreateNewChildCollection); connect(usePipeliningCheck, &QCheckBox::clicked, this, &AccountDialog::slotPipeliningClicked); // FIXME: Hide widgets which are not supported yet filterOnServerCheck->hide(); filterOnServerSizeSpin->hide(); } void AccountDialog::loadSettings() { if (mParentResource->name() == mParentResource->identifier()) { mParentResource->setName(i18n("POP3 Account")); } nameEdit->setText(mParentResource->name()); nameEdit->setFocus(); loginEdit->setText(!Settings::self()->login().isEmpty() ? Settings::self()->login() : KUser().loginName()); hostEdit->setText( !Settings::self()->host().isEmpty() ? Settings::self()->host() : KEMailSettings().getSetting(KEMailSettings::InServer)); hostEdit->setText(Settings::self()->host()); portEdit->setValue(Settings::self()->port()); precommand->setText(Settings::self()->precommand()); usePipeliningCheck->setChecked(Settings::self()->pipelining()); leaveOnServerCheck->setChecked(Settings::self()->leaveOnServer()); leaveOnServerDaysCheck->setEnabled(Settings::self()->leaveOnServer()); leaveOnServerDaysCheck->setChecked(Settings::self()->leaveOnServerDays() >= 1); leaveOnServerDaysSpin->setValue(Settings::self()->leaveOnServerDays() >= 1 ? Settings::self()->leaveOnServerDays() : 7); leaveOnServerCountCheck->setEnabled(Settings::self()->leaveOnServer()); leaveOnServerCountCheck->setChecked(Settings::self()->leaveOnServerCount() >= 1); leaveOnServerCountSpin->setValue(Settings::self()->leaveOnServerCount() >= 1 ? Settings::self()->leaveOnServerCount() : 100); leaveOnServerSizeCheck->setEnabled(Settings::self()->leaveOnServer()); leaveOnServerSizeCheck->setChecked(Settings::self()->leaveOnServerSize() >= 1); leaveOnServerSizeSpin->setValue(Settings::self()->leaveOnServerSize() >= 1 ? Settings::self()->leaveOnServerSize() : 10); filterOnServerCheck->setChecked(Settings::self()->filterOnServer()); filterOnServerSizeSpin->setValue(Settings::self()->filterCheckSize()); intervalCheck->setChecked(Settings::self()->intervalCheckEnabled()); intervalSpin->setValue(Settings::self()->intervalCheckInterval()); intervalSpin->setEnabled(Settings::self()->intervalCheckEnabled()); const int authenticationMethod = Settings::self()->authenticationMethod(); authCombo->setCurrentIndex(authCombo->findData(authenticationMethod)); encryptionNone->setChecked(!Settings::self()->useSSL() && !Settings::self()->useTLS()); encryptionSSL->setChecked(Settings::self()->useSSL()); encryptionTLS->setChecked(Settings::self()->useTLS()); slotEnableLeaveOnServerDays(leaveOnServerDaysCheck->isEnabled() ? Settings::self()->leaveOnServerDays() >= 1 : false); slotEnableLeaveOnServerCount(leaveOnServerCountCheck->isEnabled() ? Settings::self()->leaveOnServerCount() >= 1 : false); slotEnableLeaveOnServerSize(leaveOnServerSizeCheck->isEnabled() ? Settings::self()->leaveOnServerSize() >= 1 : false); // We need to fetch the collection, as the CollectionRequester needs the name // of it to work correctly Collection targetCollection(Settings::self()->targetCollection()); if (targetCollection.isValid()) { CollectionFetchJob *fetchJob = new CollectionFetchJob(targetCollection, CollectionFetchJob::Base, this); connect(fetchJob, &CollectionFetchJob::collectionsReceived, this, &AccountDialog::targetCollectionReceived); } else { // FIXME: This is a bit duplicated from POP3Resource... // No target collection set in the config? Try requesting a default inbox SpecialMailCollectionsRequestJob *requestJob = new SpecialMailCollectionsRequestJob(this); requestJob->requestDefaultCollection(SpecialMailCollections::Inbox); requestJob->start(); connect(requestJob, &SpecialMailCollectionsRequestJob::result, this, &AccountDialog::localFolderRequestJobFinished); } mWallet = Wallet::openWallet(Wallet::NetworkWallet(), winId(), Wallet::Asynchronous); if (mWallet) { connect(mWallet, &KWallet::Wallet::walletOpened, this, &AccountDialog::walletOpenedForLoading); } else { passwordEdit->lineEdit()->setPlaceholderText(i18n("Wallet disabled in system settings")); } passwordEdit->setEnabled(false); passwordLabel->setEnabled(false); } void AccountDialog::walletOpenedForLoading(bool success) { if (success) { if (mWallet->isOpen()) { passwordEdit->setEnabled(true); passwordLabel->setEnabled(true); } if (mWallet->isOpen() && mWallet->hasFolder(QStringLiteral("pop3"))) { QString password; mWallet->setFolder(QStringLiteral("pop3")); mWallet->readPassword(mParentResource->identifier(), password); passwordEdit->setPassword(password); mInitalPassword = password; } else { qCWarning(POP3RESOURCE_LOG) << "Wallet not open or doesn't have pop3 folder."; } } else { qCWarning(POP3RESOURCE_LOG) << "Failed to open wallet for loading the password."; } const bool walletError = !success || !mWallet->isOpen(); if (walletError) { passwordEdit->lineEdit()->setPlaceholderText(i18n("Unable to open wallet")); } } void AccountDialog::walletOpenedForSaving(bool success) { if (success) { if (mWallet && mWallet->isOpen()) { // Remove the password from the wallet if the user doesn't want to store it if (passwordEdit->password().isEmpty() && mWallet->hasFolder(QStringLiteral("pop3"))) { mWallet->setFolder(QStringLiteral("pop3")); mWallet->removeEntry(mParentResource->identifier()); } // Store the password in the wallet if the user wants that else if (!passwordEdit->password().isEmpty()) { if (!mWallet->hasFolder(QStringLiteral("pop3"))) { mWallet->createFolder(QStringLiteral("pop3")); } mWallet->setFolder(QStringLiteral("pop3")); mWallet->writePassword(mParentResource->identifier(), passwordEdit->password()); } mParentResource->clearCachedPassword(); } else { qCWarning(POP3RESOURCE_LOG) << "Wallet not open."; } } else { // Should we alert the user here? qCWarning(POP3RESOURCE_LOG) << "Failed to open wallet for saving the password."; } delete mWallet; mWallet = nullptr; accept(); } void AccountDialog::slotLeaveOnServerClicked() { const bool state = leaveOnServerCheck->isChecked(); leaveOnServerDaysCheck->setEnabled(state); leaveOnServerCountCheck->setEnabled(state); leaveOnServerSizeCheck->setEnabled(state); if (state) { if (leaveOnServerDaysCheck->isChecked()) { slotEnableLeaveOnServerDays(state); } if (leaveOnServerCountCheck->isChecked()) { slotEnableLeaveOnServerCount(state); } if (leaveOnServerSizeCheck->isChecked()) { slotEnableLeaveOnServerSize(state); } } else { slotEnableLeaveOnServerDays(state); slotEnableLeaveOnServerCount(state); slotEnableLeaveOnServerSize(state); } if (mServerTest && !mServerTest->capabilities().contains(ServerTest::UIDL) && leaveOnServerCheck->isChecked()) { KMessageBox::information(topLevelWidget(), i18n("The server does not seem to support unique " "message numbers, but this is a " "requirement for leaving messages on the " "server.\n" "Since some servers do not correctly " "announce their capabilities you still " "have the possibility to turn leaving " "fetched messages on the server on.")); } } void AccountDialog::slotFilterOnServerClicked() { if (mServerTest && !mServerTest->capabilities().contains(ServerTest::Top) && filterOnServerCheck->isChecked()) { KMessageBox::information(topLevelWidget(), i18n("The server does not seem to support " "fetching message headers, but this is a " "requirement for filtering messages on the " "server.\n" "Since some servers do not correctly " "announce their capabilities you still " "have the possibility to turn filtering " "messages on the server on.")); } } void AccountDialog::slotPipeliningClicked() { if (usePipeliningCheck->isChecked()) { KMessageBox::information(topLevelWidget(), i18n("Please note that this feature can cause some POP3 servers " "that do not support pipelining to send corrupted mail;\n" "this is configurable, though, because some servers support pipelining " "but do not announce their capabilities. To check whether your POP3 server " "announces pipelining support use the \"Auto Detect\"" " button at the bottom of the dialog;\n" "if your server does not announce it, but you want more speed, then " "you should do some testing first by sending yourself a batch " "of mail and downloading it."), QString(), QStringLiteral("pipelining")); } } void AccountDialog::slotPopEncryptionChanged(int id) { qCDebug(POP3RESOURCE_LOG) << "setting port"; // adjust port if (id == Transport::EnumEncryption::SSL || portEdit->value() == 995) { portEdit->setValue((id == Transport::EnumEncryption::SSL) ? 995 : 110); } qCDebug(POP3RESOURCE_LOG) << "port set "; enablePopFeatures(); // removes invalid auth options from the combobox } void AccountDialog::slotCheckPopCapabilities() { if (hostEdit->text().isEmpty()) { KMessageBox::sorry(this, i18n("Please specify a server and port on " "the General tab first.")); return; } delete mServerTest; mServerTest = new ServerTest(this); BusyCursorHelper *busyCursorHelper = new BusyCursorHelper(mServerTest); mServerTest->setProgressBar(checkCapabilitiesProgress); mOkButton->setEnabled(false); checkCapabilitiesStack->setCurrentIndex(1); Transport::EnumEncryption::type encryptionType; if (encryptionSSL->isChecked()) { encryptionType = Transport::EnumEncryption::SSL; } else { encryptionType = Transport::EnumEncryption::None; } mServerTest->setPort(encryptionType, portEdit->value()); mServerTest->setServer(hostEdit->text()); mServerTest->setProtocol(QStringLiteral("pop")); connect(mServerTest, &MailTransport::ServerTest::finished, this, &AccountDialog::slotPopCapabilities); connect(mServerTest, &MailTransport::ServerTest::finished, busyCursorHelper, &BusyCursorHelper::deleteLater); mServerTest->start(); mServerTestFailed = false; } void AccountDialog::slotPopCapabilities(const QVector &encryptionTypes) { checkCapabilitiesStack->setCurrentIndex(0); mOkButton->setEnabled(true); // if both fail, popup a dialog if (!mServerTest->isNormalPossible() && !mServerTest->isSecurePossible()) { KMessageBox::sorry(this, i18n("Unable to connect to the server, please verify the server address.")); } // If the servertest did not find any useable authentication modes, assume the // connection failed and don't disable any of the radioboxes. if (encryptionTypes.isEmpty()) { mServerTestFailed = true; return; } encryptionNone->setEnabled(encryptionTypes.contains(Transport::EnumEncryption::None)); encryptionSSL->setEnabled(encryptionTypes.contains(Transport::EnumEncryption::SSL)); encryptionTLS->setEnabled(encryptionTypes.contains(Transport::EnumEncryption::TLS)); usePipeliningCheck->setChecked(mServerTest->capabilities().contains(ServerTest::Pipelining)); checkHighest(encryptionButtonGroup); } void AccountDialog::enablePopFeatures() { if (!mServerTest || mServerTestFailed) { return; } QVector supportedAuths; if (encryptionButtonGroup->checkedId() == Transport::EnumEncryption::None) { supportedAuths = mServerTest->normalProtocols(); } if (encryptionButtonGroup->checkedId() == Transport::EnumEncryption::SSL) { supportedAuths = mServerTest->secureProtocols(); } if (encryptionButtonGroup->checkedId() == Transport::EnumEncryption::TLS) { supportedAuths = mServerTest->tlsProtocols(); } authCombo->clear(); for (int prot : qAsConst(supportedAuths)) { authCombo->addItem(Transport::authenticationTypeString(prot), prot); } if (mServerTest && !mServerTest->capabilities().contains(ServerTest::Pipelining) && usePipeliningCheck->isChecked()) { usePipeliningCheck->setChecked(false); KMessageBox::information(topLevelWidget(), i18n("The server does not seem to support " "pipelining; therefore, this option has " "been disabled.\n" "Since some servers do not correctly " "announce their capabilities you still " "have the possibility to turn pipelining " "on. But please note that this feature can " "cause some POP servers that do not " "support pipelining to send corrupt " "messages. So before using this feature " "with important mail you should first " "test it by sending yourself a larger " "number of test messages which you all " "download in one go from the POP " "server.")); } if (mServerTest && !mServerTest->capabilities().contains(ServerTest::UIDL) && leaveOnServerCheck->isChecked()) { leaveOnServerCheck->setChecked(false); KMessageBox::information(topLevelWidget(), i18n("The server does not seem to support unique " "message numbers, but this is a " "requirement for leaving messages on the " "server; therefore, this option has been " "disabled.\n" "Since some servers do not correctly " "announce their capabilities you still " "have the possibility to turn leaving " "fetched messages on the server on.")); } if (mServerTest && !mServerTest->capabilities().contains(ServerTest::Top) && filterOnServerCheck->isChecked()) { filterOnServerCheck->setChecked(false); KMessageBox::information(topLevelWidget(), i18n("The server does not seem to support " "fetching message headers, but this is a " "requirement for filtering messages on the " "server; therefore, this option has been " "disabled.\n" "Since some servers do not correctly " "announce their capabilities you still " "have the possibility to turn filtering " "messages on the server on.")); } } static void addAuthenticationItem(QComboBox *combo, int authenticationType) { combo->addItem(Transport::authenticationTypeString(authenticationType), QVariant(authenticationType)); } void AccountDialog::populateDefaultAuthenticationOptions() { authCombo->clear(); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::CLEAR); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::LOGIN); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::PLAIN); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::CRAM_MD5); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::DIGEST_MD5); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::NTLM); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::GSSAPI); addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::APOP); } void AccountDialog::slotLeaveOnServerDaysChanged(int value) { leaveOnServerDaysSpin->setSuffix(i18np(" day", " days", value)); } void AccountDialog::slotLeaveOnServerCountChanged(int value) { leaveOnServerCountSpin->setSuffix(i18np(" message", " messages", value)); } void AccountDialog::slotFilterOnServerSizeChanged(int value) { filterOnServerSizeSpin->setSuffix(i18np(" byte", " bytes", value)); } void AccountDialog::checkHighest(QButtonGroup *btnGroup) { QListIterator it(btnGroup->buttons()); it.toBack(); while (it.hasPrevious()) { QAbstractButton *btn = it.previous(); if (btn && btn->isEnabled()) { btn->animateClick(); return; } } } void AccountDialog::slotAccepted() { saveSettings(); // Don't call accept() yet, saveSettings() triggers an asnychronous wallet operation, // which will call accept() when it is finished } void AccountDialog::saveSettings() { mParentResource->setName(nameEdit->text()); Settings::self()->setIntervalCheckEnabled(intervalCheck->checkState() == Qt::Checked); Settings::self()->setIntervalCheckInterval(intervalSpin->value()); Settings::self()->setHost(hostEdit->text().trimmed()); Settings::self()->setPort(portEdit->value()); Settings::self()->setLogin(loginEdit->text().trimmed()); Settings::self()->setPrecommand(precommand->text()); Settings::self()->setUseSSL(encryptionSSL->isChecked()); Settings::self()->setUseTLS(encryptionTLS->isChecked()); Settings::self()->setAuthenticationMethod(authCombo->itemData(authCombo->currentIndex()).toInt()); Settings::self()->setPipelining(usePipeliningCheck->isChecked()); Settings::self()->setLeaveOnServer(leaveOnServerCheck->isChecked()); Settings::self()->setLeaveOnServerDays(leaveOnServerCheck->isChecked() ? (leaveOnServerDaysCheck->isChecked() ? leaveOnServerDaysSpin->value() : -1) : 0); Settings::self()->setLeaveOnServerCount(leaveOnServerCheck->isChecked() ? (leaveOnServerCountCheck->isChecked() ? leaveOnServerCountSpin->value() : -1) : 0); Settings::self()->setLeaveOnServerSize(leaveOnServerCheck->isChecked() ? (leaveOnServerSizeCheck->isChecked() ? leaveOnServerSizeSpin->value() : -1) : 0); Settings::self()->setFilterOnServer(filterOnServerCheck->isChecked()); Settings::self()->setFilterCheckSize(filterOnServerSizeSpin->value()); Settings::self()->setTargetCollection(folderRequester->collection().id()); Settings::self()->save(); // Now, either save the password or delete it from the wallet. For both, we need // to open it. const bool userChangedPassword = mInitalPassword != passwordEdit->password(); const bool userWantsToDeletePassword = passwordEdit->password().isEmpty() && userChangedPassword; if ((!passwordEdit->password().isEmpty() && userChangedPassword) || userWantsToDeletePassword) { qCDebug(POP3RESOURCE_LOG) << mWallet << mWallet->isOpen(); if (mWallet && mWallet->isOpen()) { // wallet is already open walletOpenedForSaving(true); } else { // we need to open the wallet qCDebug(POP3RESOURCE_LOG) << "we need to open the wallet"; mWallet = Wallet::openWallet(Wallet::NetworkWallet(), winId(), Wallet::Asynchronous); if (mWallet) { connect(mWallet, &KWallet::Wallet::walletOpened, this, &AccountDialog::walletOpenedForSaving); } else { accept(); } } } else { accept(); } } void AccountDialog::slotEnableLeaveOnServerDays(bool state) { if (state && !leaveOnServerDaysCheck->isEnabled()) { return; } leaveOnServerDaysSpin->setEnabled(state); } void AccountDialog::slotEnableLeaveOnServerCount(bool state) { if (state && !leaveOnServerCountCheck->isEnabled()) { return; } leaveOnServerCountSpin->setEnabled(state); } void AccountDialog::slotEnableLeaveOnServerSize(bool state) { if (state && !leaveOnServerSizeCheck->isEnabled()) { return; } leaveOnServerSizeSpin->setEnabled(state); } void AccountDialog::slotEnablePopInterval(bool state) { intervalSpin->setEnabled(state); intervalLabel->setEnabled(state); } void AccountDialog::targetCollectionReceived(Akonadi::Collection::List collections) { folderRequester->setCollection(collections.first()); } void AccountDialog::localFolderRequestJobFinished(KJob *job) { if (!job->error()) { Collection targetCollection = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::Inbox); Q_ASSERT(targetCollection.isValid()); folderRequester->setCollection(targetCollection); } } diff --git a/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp b/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp index f493f21d9..ac7c27f6f 100644 --- a/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp +++ b/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp @@ -1,230 +1,231 @@ /* Copyright (c) 2008 Bertjan Broeksema Copyright (c) 2008 Volker Krause Copyright (c) 2010,2011 David Jarvie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "singlefileresourceconfigdialogbase.h" #include #include #include #include #include #include #include #include #include #include +#include #include using namespace Akonadi; SingleFileResourceConfigDialogBase::SingleFileResourceConfigDialogBase(WId windowId) : QDialog() , mManager(nullptr) , mStatJob(nullptr) , mAppendedWidget(nullptr) , mDirUrlChecked(false) , mMonitorEnabled(true) , mLocalFileOnly(false) { QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(mainWidget); ui.setupUi(mainWidget); ui.kcfg_Path->setMode(KFile::File); ui.statusLabel->setText(QString()); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); mOkButton = buttonBox->button(QDialogButtonBox::Ok); mOkButton->setDefault(true); mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &SingleFileResourceConfigDialogBase::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &SingleFileResourceConfigDialogBase::reject); mainLayout->addWidget(buttonBox); if (windowId) { KWindowSystem::setMainWindow(this, windowId); } ui.tabWidget->tabBar()->hide(); connect(mOkButton, &QPushButton::clicked, this, &SingleFileResourceConfigDialogBase::save); connect(ui.kcfg_Path, &KUrlRequester::textChanged, this, &SingleFileResourceConfigDialogBase::validate); connect(ui.kcfg_MonitorFile, &QCheckBox::toggled, this, &SingleFileResourceConfigDialogBase::validate); ui.kcfg_Path->setFocus(); QTimer::singleShot(0, this, &SingleFileResourceConfigDialogBase::validate); setMinimumSize(800, 700); readConfig(); } SingleFileResourceConfigDialogBase::~SingleFileResourceConfigDialogBase() { writeConfig(); } void SingleFileResourceConfigDialogBase::writeConfig() { KConfigGroup group(KSharedConfig::openConfig(), "SingleFileResourceConfigDialogBase"); group.writeEntry("Size", size()); } void SingleFileResourceConfigDialogBase::readConfig() { KConfigGroup group(KSharedConfig::openConfig(), "SingleFileResourceConfigDialogBase"); const QSize sizeDialog = group.readEntry("Size", QSize(600, 540)); if (sizeDialog.isValid()) { resize(sizeDialog); } } void SingleFileResourceConfigDialogBase::addPage(const QString &title, QWidget *page) { ui.tabWidget->tabBar()->show(); ui.tabWidget->addTab(page, title); mManager->addWidget(page); mManager->updateWidgets(); } void SingleFileResourceConfigDialogBase::setFilter(const QString &filter) { ui.kcfg_Path->setFilter(filter); } void SingleFileResourceConfigDialogBase::setMonitorEnabled(bool enable) { mMonitorEnabled = enable; ui.groupBox_MonitorFile->setVisible(mMonitorEnabled); } void SingleFileResourceConfigDialogBase::setUrl(const QUrl &url) { ui.kcfg_Path->setUrl(url); } QUrl SingleFileResourceConfigDialogBase::url() const { return ui.kcfg_Path->url(); } void SingleFileResourceConfigDialogBase::setLocalFileOnly(bool local) { mLocalFileOnly = local; ui.kcfg_Path->setMode(mLocalFileOnly ? KFile::File | KFile::LocalOnly : KFile::File); } void SingleFileResourceConfigDialogBase::appendWidget(SingleFileValidatingWidget *widget) { widget->setParent(static_cast(ui.tab)); ui.tabLayout->addWidget(widget); connect(widget, &SingleFileValidatingWidget::changed, this, &SingleFileResourceConfigDialogBase::validate); mAppendedWidget = widget; } void SingleFileResourceConfigDialogBase::validate() { if (mAppendedWidget && !mAppendedWidget->validate()) { mOkButton->setEnabled(false); return; } const QUrl currentUrl = ui.kcfg_Path->url(); if (ui.kcfg_Path->text().trimmed().isEmpty() || currentUrl.isEmpty()) { mOkButton->setEnabled(false); return; } if (currentUrl.isLocalFile()) { if (mMonitorEnabled) { ui.kcfg_MonitorFile->setEnabled(true); } ui.statusLabel->setText(QString()); // The read-only checkbox used to be disabled if the file is read-only, // but it is then impossible to know at a later date if the file // permissions change, whether the user actually wanted the resource to be // read-only or not. So just leave the read-only checkbox untouched. mOkButton->setEnabled(true); } else { // Not a local file. if (mLocalFileOnly) { mOkButton->setEnabled(false); return; } if (mMonitorEnabled) { ui.kcfg_MonitorFile->setEnabled(false); } ui.statusLabel->setText(i18nc("@info:status", "Checking file information...")); if (mStatJob) { mStatJob->kill(); } mStatJob = KIO::stat(currentUrl, KIO::DefaultFlags | KIO::HideProgressInfo); mStatJob->setDetails(2); // All details. mStatJob->setSide(KIO::StatJob::SourceSide); connect(mStatJob, &KIO::StatJob::result, this, &SingleFileResourceConfigDialogBase::slotStatJobResult); // Allow the OK button to be disabled until the MetaJob is finished. mOkButton->setEnabled(false); } } void SingleFileResourceConfigDialogBase::slotStatJobResult(KJob *job) { if (job->error() == KIO::ERR_DOES_NOT_EXIST && !mDirUrlChecked) { // The file did not exist, so let's see if the directory the file should // reside in supports writing. QUrl dirUrl(ui.kcfg_Path->url()); dirUrl = KIO::upUrl(dirUrl); mStatJob = KIO::stat(dirUrl, KIO::DefaultFlags | KIO::HideProgressInfo); mStatJob->setDetails(2); // All details. mStatJob->setSide(KIO::StatJob::SourceSide); connect(mStatJob, &KIO::StatJob::result, this, &SingleFileResourceConfigDialogBase::slotStatJobResult); // Make sure we don't check the whole path upwards. mDirUrlChecked = true; return; } else if (job->error()) { // It doesn't seem possible to read nor write from the location so leave the // ok button disabled ui.statusLabel->setText(QString()); mOkButton->setEnabled(false); mDirUrlChecked = false; mStatJob = nullptr; return; } ui.statusLabel->setText(QString()); mOkButton->setEnabled(true); mDirUrlChecked = false; mStatJob = nullptr; } SingleFileValidatingWidget::SingleFileValidatingWidget(QWidget *parent) : QWidget(parent) { }