From fb0d78fb3bcfce5bd4ff7f51e4cd1405693e0275 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Tue, 19 Sep 2023 17:04:13 +0200 Subject: [PATCH] Revert "Revert "Use config plugin instead of out of process config dialog"" This reverts commit f33496a346f49e95caaf7f664ef2f91e4b7f3ddb. (cherry picked from commit a17ef55dbe31e2020e96f66cd7021578ed8b5444) --- resources/google-groupware/CMakeLists.txt | 93 ++++-- resources/google-groupware/googleconfig.cpp | 43 +++ resources/google-groupware/googleconfig.json | 5 + resources/google-groupware/googleresource.cpp | 95 ++---- resources/google-groupware/googleresource.h | 4 +- resources/google-groupware/googlescopes.cpp | 19 ++ resources/google-groupware/googlescopes.h | 10 + resources/google-groupware/googlesettings.cpp | 22 +- resources/google-groupware/googlesettings.h | 11 +- .../google-groupware/googlesettingsdialog.cpp | 305 ------------------ .../google-groupware/googlesettingswidget.cpp | 288 +++++++++++++++++ ...ettingsdialog.h => googlesettingswidget.h} | 29 +- ...tingsdialog.ui => googlesettingswidget.ui} | 2 +- resources/google-groupware/settingsbase.kcfg | 2 +- 14 files changed, 505 insertions(+), 423 deletions(-) create mode 100644 resources/google-groupware/googleconfig.cpp create mode 100644 resources/google-groupware/googleconfig.json create mode 100644 resources/google-groupware/googlescopes.cpp create mode 100644 resources/google-groupware/googlescopes.h delete mode 100644 resources/google-groupware/googlesettingsdialog.cpp create mode 100644 resources/google-groupware/googlesettingswidget.cpp rename resources/google-groupware/{googlesettingsdialog.h => googlesettingswidget.h} (53%) rename resources/google-groupware/{googlesettingsdialog.ui => googlesettingswidget.ui} (99%) diff --git a/resources/google-groupware/CMakeLists.txt b/resources/google-groupware/CMakeLists.txt index babf58a953..2f2b46aded 100644 --- a/resources/google-groupware/CMakeLists.txt +++ b/resources/google-groupware/CMakeLists.txt @@ -1,67 +1,75 @@ add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_google_resource\") -set(googleresource_SRCS - googleresource.cpp +set(googleresource_common_SRCS googlesettings.cpp - googlesettingsdialog.cpp - defaultreminderattribute.cpp - googleresourcestate.cpp - generichandler.cpp - calendarhandler.cpp - taskhandler.cpp - peopleconversionjob.cpp - personhandler.cpp - googleresource.h googlesettings.h - googlesettingsdialog.h - defaultreminderattribute.h - googleresourcestate.h - generichandler.h - calendarhandler.h - taskhandler.h - peopleconversionjob.h - personhandler.h - ) + googlescopes.h + googlescopes.cpp +) -ecm_qt_declare_logging_category(googleresource_SRCS +ecm_qt_declare_logging_category(googleresource_common_SRCS HEADER googleresource_debug.h IDENTIFIER GOOGLE_LOG CATEGORY_NAME org.kde.pim.google DESCRIPTION "resource google (kdepim-runtime)" EXPORT KDEPIMRUNTIME) -ecm_qt_declare_logging_category(googleresource_SRCS +ecm_qt_declare_logging_category(googleresource_common_SRCS HEADER googlecalendar_debug.h IDENTIFIER GOOGLE_CALENDAR_LOG CATEGORY_NAME org.kde.pim.google.calendar DESCRIPTION "resource google calendar (kdepim-runtime)" EXPORT KDEPIMRUNTIME) -ecm_qt_declare_logging_category(googleresource_SRCS +ecm_qt_declare_logging_category(googleresource_common_SRCS HEADER googletasks_debug.h IDENTIFIER GOOGLE_TASKS_LOG CATEGORY_NAME org.kde.pim.google.tasks DESCRIPTION "resource google tasks (kdepim-runtime)" EXPORT KDEPIMRUNTIME) -ecm_qt_declare_logging_category(googleresource_SRCS +ecm_qt_declare_logging_category(googleresource_common_SRCS HEADER googlepeople_debug.h IDENTIFIER GOOGLE_PEOPLE_LOG CATEGORY_NAME org.kde.pim.google.people DESCRIPTION "resource google people (kdepim-runtime)" EXPORT KDEPIMRUNTIME) -ki18n_wrap_ui(googleresource_SRCS googlesettingsdialog.ui) -kconfig_add_kcfg_files(googleresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) +kconfig_add_kcfg_files(googleresource_common_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) kcfg_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfg org.kde.Akonadi.Google.Settings ) -qt_add_dbus_adaptor(googleresource_SRCS +qt_add_dbus_adaptor(googleresource_common_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Google.Settings.xml ${CMAKE_CURRENT_SOURCE_DIR}/googlesettings.h GoogleSettings ) +############################# Resource ################################# +set(googleresource_SRCS + googleresource.cpp + defaultreminderattribute.cpp + googleresourcestate.cpp + generichandler.cpp + calendarhandler.cpp + taskhandler.cpp + peopleconversionjob.cpp + personhandler.cpp + googleresource.h + googlesettings.h + defaultreminderattribute.h + googleresourcestate.h + generichandler.h + calendarhandler.h + taskhandler.h + peopleconversionjob.h + personhandler.h + ${googleresource_common_SRCS} +) + +ki18n_wrap_ui(googleresource_SRCS googlesettingswidget.ui) + + add_executable(akonadi_google_resource ${googleresource_SRCS}) if (COMPILE_WITH_UNITY_CMAKE_SUPPORT) set_target_properties(akonadi_google_resource PROPERTIES UNITY_BUILD ON) @@ -112,3 +120,34 @@ install( FILES akonadi_google_resource.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR} ) + +################################ Config plugin ############################### + +kcoreaddons_add_plugin(googleconfig + INSTALL_NAMESPACE "pim${QT_MAJOR_VERSION}/akonadi/config" +) +target_sources(googleconfig +PRIVATE + googleconfig.cpp + googlesettingswidget.cpp + googlesettingswidget.h + ${googleresource_common_SRCS} +) +target_link_libraries(googleconfig + KPim${KF_MAJOR_VERSION}::AkonadiCore + KPim${KF_MAJOR_VERSION}::AkonadiCalendar + KPim${KF_MAJOR_VERSION}::AkonadiCore + KPim${KF_MAJOR_VERSION}::AkonadiAgentBase + KF${KF_MAJOR_VERSION}::CalendarCore + KF${KF_MAJOR_VERSION}::Contacts + KF${KF_MAJOR_VERSION}::Wallet + KF${KF_MAJOR_VERSION}::I18n + KF${KF_MAJOR_VERSION}::WindowSystem + KF${KF_MAJOR_VERSION}::TextWidgets + KF${KF_MAJOR_VERSION}::Notifications + KPim${KF_MAJOR_VERSION}::GAPICalendar + KPim${KF_MAJOR_VERSION}::GAPIPeople + KPim${KF_MAJOR_VERSION}::GAPICore + KPim${KF_MAJOR_VERSION}::GAPITasks + qt${KF_MAJOR_VERSION}keychain +) diff --git a/resources/google-groupware/googleconfig.cpp b/resources/google-groupware/googleconfig.cpp new file mode 100644 index 0000000000..2eb6ab2efa --- /dev/null +++ b/resources/google-groupware/googleconfig.cpp @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2018 Daniel Vrátil + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include + +#include "googlesettings.h" +#include "googlesettingswidget.h" + +class GoogleConfig : public Akonadi::AgentConfigurationBase +{ + Q_OBJECT + +public: + explicit GoogleConfig(const KSharedConfigPtr &config, QWidget *parent, const QVariantList &list) + : Akonadi::AgentConfigurationBase(config, parent, list) + , mSettings(config, GoogleSettings::Option::NoOption) + , mWidget(mSettings, identifier(), parent) + { + connect(&mWidget, &GoogleSettingsWidget::okEnabled, this, &Akonadi::AgentConfigurationBase::enableOkButton); + } + + void load() override + { + Akonadi::AgentConfigurationBase::load(); + mWidget.loadSettings(); + } + + Q_REQUIRED_RESULT bool save() const override + { + const_cast(this)->mWidget.saveSettings(); + return Akonadi::AgentConfigurationBase::save(); + } + + GoogleSettings mSettings; + GoogleSettingsWidget mWidget; +}; + +AKONADI_AGENTCONFIG_FACTORY(GoogleConfigFactory, "googleconfig.json", GoogleConfig) + +#include "googleconfig.moc" diff --git a/resources/google-groupware/googleconfig.json b/resources/google-groupware/googleconfig.json new file mode 100644 index 0000000000..69c76f583f --- /dev/null +++ b/resources/google-groupware/googleconfig.json @@ -0,0 +1,5 @@ +{ + "X-Akonadi-PluginType": "AgentConfig", + "X-Akonadi-Library": "googleconfig", + "X-Akonadi-AgentConfig-Type": "akonadi_google_resource" +} \ No newline at end of file diff --git a/resources/google-groupware/googleresource.cpp b/resources/google-groupware/googleresource.cpp index b40f093dde..47a7e0c8d5 100644 --- a/resources/google-groupware/googleresource.cpp +++ b/resources/google-groupware/googleresource.cpp @@ -9,8 +9,9 @@ #include "googleresource.h" #include "googleresource_debug.h" #include "googleresourcestate.h" +#include "googlescopes.h" #include "googlesettings.h" -#include "googlesettingsdialog.h" +#include "googlesettingswidget.h" #include "settingsadaptor.h" #include "personhandler.h" @@ -67,8 +68,11 @@ bool accountIsValid(const KGAPI2::AccountPtr &account) GoogleResource::GoogleResource(const QString &id) : ResourceBase(id) , AgentBase::ObserverV3() + , m_settings(KSharedConfig::openConfig()) , m_iface(new GoogleResourceState(this)) { + m_settings.setResourceId(identifier()); + AttributeFactory::registerAttribute(); connect(this, &GoogleResource::reloadConfiguration, this, &GoogleResource::reloadConfig); @@ -83,9 +87,7 @@ GoogleResource::GoogleResource(const QString &id) Q_EMIT status(NotConfigured, i18n("Fetching password...")); - m_settings = new GoogleSettings(); - m_settings->setWindowId(winIdForDialogs()); - connect(m_settings, &GoogleSettings::accountReady, this, [this](bool ready) { + connect(&m_settings, &GoogleSettings::accountReady, this, [this](bool ready) { if (accountId() > 0) { return; } @@ -94,7 +96,7 @@ GoogleResource::GoogleResource(const QString &id) return; } - const auto account = m_settings->accountPtr(); + const auto account = m_settings.accountPtr(); if (account.isNull()) { Q_EMIT status(NotConfigured); return; @@ -107,18 +109,15 @@ GoogleResource::GoogleResource(const QString &id) synchronize(); } }); - m_settings->init(); + m_settings.init(); updateResourceName(); - m_freeBusyHandler = std::make_unique(m_iface, m_settings); + m_freeBusyHandler = std::make_unique(m_iface, &m_settings); m_handlers.clear(); - m_handlers.push_back(GenericHandler::Ptr(new CalendarHandler(m_iface, m_settings))); - m_handlers.push_back(GenericHandler::Ptr(new PersonHandler(m_iface, m_settings))); - m_handlers.push_back(GenericHandler::Ptr(new TaskHandler(m_iface, m_settings))); - - new SettingsAdaptor(m_settings); - QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), m_settings, QDBusConnection::ExportAdaptors); + m_handlers.push_back(GenericHandler::Ptr(new CalendarHandler(m_iface, &m_settings))); + m_handlers.push_back(GenericHandler::Ptr(new PersonHandler(m_iface, &m_settings))); + m_handlers.push_back(GenericHandler::Ptr(new TaskHandler(m_iface, &m_settings))); } GoogleResource::~GoogleResource() @@ -128,7 +127,7 @@ GoogleResource::~GoogleResource() void GoogleResource::cleanup() { - m_settings->cleanup(); + m_settings.cleanup(); ResourceBase::cleanup(); } @@ -137,65 +136,30 @@ void GoogleResource::emitReadyStatus() Q_EMIT status(Idle, i18nc("@info:status", "Ready")); } -void GoogleResource::configure(WId windowId) -{ - if (!m_settings->isReady() || m_isConfiguring) { - Q_EMIT configurationDialogAccepted(); - return; - } - - m_isConfiguring = true; - - QScopedPointer settingsDialog(new GoogleSettingsDialog(this, m_settings, windowId)); - settingsDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("im-google"))); - if (settingsDialog->exec() == QDialog::Accepted) { - updateResourceName(); - - Q_EMIT configurationDialogAccepted(); - - if (m_settings->accountPtr().isNull()) { - Q_EMIT status(NotConfigured, i18n("Configured account does not exist")); - m_isConfiguring = false; - return; - } - - emitReadyStatus(); - synchronize(); - } else { - updateResourceName(); - - Q_EMIT configurationDialogRejected(); - } - - m_isConfiguring = false; -} - QList GoogleResource::scopes() const { // TODO: determine it based on what user wants? - const QList scopes = { - Account::accountInfoScopeUrl(), - Account::calendarScopeUrl(), - Account::peopleScopeUrl(), - Account::tasksScopeUrl(), - }; - return scopes; + return googleScopes(); } void GoogleResource::updateResourceName() { - const QString accountName = m_settings->account(); + const QString accountName = m_settings.account(); setName(i18nc("%1 is account name (user@gmail.com)", "Google Groupware (%1)", accountName.isEmpty() ? i18n("not configured") : accountName)); } void GoogleResource::reloadConfig() { - const AccountPtr account = m_settings->accountPtr(); + updateResourceName(); + + const AccountPtr account = m_settings.accountPtr(); if (account.isNull() || account->accountName().isEmpty()) { Q_EMIT status(NotConfigured, i18n("Configured account does not exist")); - } else { - emitReadyStatus(); + return; } + + emitReadyStatus(); + synchronize(); } bool GoogleResource::handleError(KGAPI2::Job *job, bool _cancelTask) @@ -231,7 +195,7 @@ bool GoogleResource::handleError(KGAPI2::Job *job, bool _cancelTask) void GoogleResource::runAuthJob(const KGAPI2::AccountPtr &account, const QVariant &args) { - auto authJob = new AuthJob(account, m_settings->clientId(), m_settings->clientSecret(), this); + auto authJob = new AuthJob(account, m_settings.clientId(), m_settings.clientSecret(), this); authJob->setProperty(JOB_PROPERTY, args); connect(authJob, &AuthJob::finished, this, &GoogleResource::slotAuthJobFinished); } @@ -264,7 +228,7 @@ void GoogleResource::requestAuthenticationFromUser(const KGAPI2::AccountPtr &acc bool GoogleResource::canPerformTask() { - if (!m_settings->accountPtr() && accountId() == 0) { + if (!m_settings.accountPtr() && accountId() == 0) { cancelTask(i18nc("@info:status", "Resource is not configured")); Q_EMIT status(NotConfigured, i18nc("@info:status", "Resource is not configured")); return false; @@ -289,10 +253,11 @@ void GoogleResource::slotAuthJobFinished(KGAPI2::Job *job) auto authJob = qobject_cast(job); AccountPtr account = authJob->account(); - auto writeJob = m_settings->storeAccount(account); + auto writeJob = m_settings.storeAccount(account); connect(writeJob, &WritePasswordJob::finished, this, [job, account, writeJob]() { if (writeJob->error()) { qCWarning(GOOGLE_LOG) << "Failed to store account's password in secret storage" << writeJob->errorString(); + return; } auto otherJob = job->property(JOB_PROPERTY).value(); @@ -375,22 +340,22 @@ void GoogleResource::retrieveCollections() setCollectionStreamingEnabled(true); CachePolicy cachePolicy; - if (m_settings->enableIntervalCheck()) { + if (m_settings.enableIntervalCheck()) { cachePolicy.setInheritFromParent(false); - cachePolicy.setIntervalCheckTime(m_settings->intervalCheckTime()); + cachePolicy.setIntervalCheckTime(m_settings.intervalCheckTime()); } // Setting up root collection m_rootCollection = Collection(); m_rootCollection.setContentMimeTypes({Collection::mimeType(), Collection::virtualMimeType()}); m_rootCollection.setRemoteId(ROOT_COLLECTION_REMOTEID); - m_rootCollection.setName(m_settings->accountPtr()->accountName()); + m_rootCollection.setName(m_settings.accountPtr()->accountName()); m_rootCollection.setParentCollection(Collection::root()); m_rootCollection.setRights(Collection::CanCreateCollection); m_rootCollection.setCachePolicy(cachePolicy); auto attr = m_rootCollection.attribute(Collection::AddIfMissing); - attr->setDisplayName(m_settings->accountPtr()->accountName()); + attr->setDisplayName(m_settings.accountPtr()->accountName()); attr->setIconName(QStringLiteral("im-google")); collectionsRetrieved({m_rootCollection}); diff --git a/resources/google-groupware/googleresource.h b/resources/google-groupware/googleresource.h index 4609572756..75708afca4 100644 --- a/resources/google-groupware/googleresource.h +++ b/resources/google-groupware/googleresource.h @@ -14,6 +14,7 @@ #include "calendarhandler.h" #include "generichandler.h" +#include "googlesettings.h" #define JOB_PROPERTY "_KGAPI2Job" @@ -37,7 +38,6 @@ public: void cleanup() override; public Q_SLOTS: - void configure(WId windowId) override; void reloadConfig(); protected: @@ -83,7 +83,7 @@ protected Q_SLOTS: private: bool m_isConfiguring = false; - GoogleSettings *m_settings = nullptr; + GoogleSettings m_settings; Akonadi::Collection m_rootCollection; GoogleResourceState *const m_iface; diff --git a/resources/google-groupware/googlescopes.cpp b/resources/google-groupware/googlescopes.cpp new file mode 100644 index 0000000000..9e565f7e33 --- /dev/null +++ b/resources/google-groupware/googlescopes.cpp @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2011 Daniel Vrátil +// SPDX-FileCopyrightText: 2023 Carl Schwan +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "googlescopes.h" +#include + +using namespace KGAPI2; + +QList googleScopes() +{ + // TODO: determine it based on what user wants? + return { + Account::accountInfoScopeUrl(), + Account::calendarScopeUrl(), + Account::peopleScopeUrl(), + Account::tasksScopeUrl(), + }; +} diff --git a/resources/google-groupware/googlescopes.h b/resources/google-groupware/googlescopes.h new file mode 100644 index 0000000000..33bf579a89 --- /dev/null +++ b/resources/google-groupware/googlescopes.h @@ -0,0 +1,10 @@ +/* + SPDX-FileCopyrightText: 2011 Daniel Vrátil + SPDX-FileCopyrightText: 2023 Carl Schwan + SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#include +#include + +QList googleScopes(); diff --git a/resources/google-groupware/googlesettings.cpp b/resources/google-groupware/googlesettings.cpp index 6a1785fcf9..aa94cad1ab 100644 --- a/resources/google-groupware/googlesettings.cpp +++ b/resources/google-groupware/googlesettings.cpp @@ -8,6 +8,8 @@ #include "googlesettings.h" #include "googleresource_debug.h" +#include "googlescopes.h" +#include "settingsadaptor.h" #include #include @@ -27,8 +29,16 @@ using namespace KGAPI2; static const QString googleWalletFolder = QStringLiteral("Akonadi Google"); -GoogleSettings::GoogleSettings() +GoogleSettings::GoogleSettings(const KSharedConfigPtr &config, Options options) + : SettingsBase(config) { + qDebug() << config; + if (options & Option::ExportToDBus) { + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + this, + QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); + } } void GoogleSettings::init() @@ -82,15 +92,17 @@ WritePasswordJob *GoogleSettings::storeAccount(AccountPtr account) m_account = account; QStringList scopes; - const QList urlScopes = m_account->scopes(); + const QList urlScopes = googleScopes(); scopes.reserve(urlScopes.count()); for (const QUrl &url : urlScopes) { scopes << url.toString(); } - const QMap map = {{QStringLiteral("accessToken"), m_account->accessToken()}, - {QStringLiteral("refreshToken"), m_account->refreshToken()}, - {QStringLiteral("scopes"), scopes.join(QLatin1Char(','))}}; + const QMap map = { + {QStringLiteral("accessToken"), m_account->accessToken()}, + {QStringLiteral("refreshToken"), m_account->refreshToken()}, + {QStringLiteral("scopes"), scopes.join(QLatin1Char(','))}, + }; // Legacy: store the map exactly like kwallet is doing it QByteArray mapData; diff --git a/resources/google-groupware/googlesettings.h b/resources/google-groupware/googlesettings.h index f689dc7748..0ec4c3c34e 100644 --- a/resources/google-groupware/googlesettings.h +++ b/resources/google-groupware/googlesettings.h @@ -33,7 +33,14 @@ class GoogleSettings : public SettingsBase Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.Google.ExtendedSettings") public: - GoogleSettings(); + enum class Option { + NoOption = 0, + ExportToDBus = 1, + }; + Q_DECLARE_FLAGS(Options, Option) + + explicit GoogleSettings(const KSharedConfigPtr &config, Options options = Option::ExportToDBus); + void init(); void setWindowId(WId id); void setResourceId(const QString &resourceIdentifier); @@ -50,9 +57,11 @@ public: bool isReady() const; QKeychain::WritePasswordJob *storeAccount(KGAPI2::AccountPtr account); void cleanup(); + Q_SIGNALS: void accountReady(bool ready); void accountChanged(); + void okEnabled(bool enabled); private: void slotWalletOpened(bool success); diff --git a/resources/google-groupware/googlesettingsdialog.cpp b/resources/google-groupware/googlesettingsdialog.cpp deleted file mode 100644 index d418652d6f..0000000000 --- a/resources/google-groupware/googlesettingsdialog.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - SPDX-FileCopyrightText: 2013 Daniel Vrátil - SPDX-FileCopyrightText: 2020 Igor Poboiko - - SPDX-License-Identifier: GPL-3.0-or-later -*/ - -#include "googlesettingsdialog.h" -#include "googleresource.h" -#include "googleresource_debug.h" -#include "googlesettings.h" -#include "ui_googlesettingsdialog.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#else -#include -#endif - -using namespace QKeychain; -using namespace KGAPI2; - -GoogleSettingsDialog::GoogleSettingsDialog(GoogleResource *resource, GoogleSettings *settings, WId wId) - : QDialog() - , m_resource(resource) - , m_settings(settings) - , m_ui(new Ui::GoogleSettingsDialog) -{ - if (wId) { - setAttribute(Qt::WA_NativeWindow, true); - kwindowsystem::setMainWindow(windowHandle(), wId); - } - auto mainLayout = new QVBoxLayout(this); - - auto mainWidget = new QWidget(this); - mainLayout->addWidget(mainWidget); - - auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); - QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); - okButton->setDefault(true); - okButton->setShortcut(Qt::CTRL | Qt::Key_Return); - mainLayout->addWidget(buttonBox); - - m_ui->setupUi(mainWidget); - - m_ui->refreshSpinBox->setSuffix(ki18np(" minute", " minutes")); - m_ui->enableRefresh->setChecked(m_settings->enableIntervalCheck()); - m_ui->refreshSpinBox->setEnabled(m_settings->enableIntervalCheck()); - m_ui->refreshSpinBox->setValue(m_settings->intervalCheckTime()); - - m_ui->eventsLimitCombo->setMaximumDate(QDate::currentDate()); - m_ui->eventsLimitCombo->setMinimumDate(QDate::fromString(QStringLiteral("2000-01-01"), Qt::ISODate)); - m_ui->eventsLimitCombo->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::WarnOnInvalid); - if (m_settings->eventsSince().isEmpty()) { - const QString ds = QStringLiteral("%1-01-01").arg(QString::number(QDate::currentDate().year() - 3)); - m_ui->eventsLimitCombo->setDate(QDate::fromString(ds, Qt::ISODate)); - } else { - m_ui->eventsLimitCombo->setDate(QDate::fromString(m_settings->eventsSince(), Qt::ISODate)); - } - - connect(buttonBox, &QDialogButtonBox::accepted, this, &GoogleSettingsDialog::slotSaveSettings); - connect(buttonBox, &QDialogButtonBox::rejected, this, &GoogleSettingsDialog::reject); - connect(m_ui->reloadCalendarsBtn, &QPushButton::clicked, this, &GoogleSettingsDialog::slotReloadCalendars); - connect(m_ui->reloadTaskListsBtn, &QPushButton::clicked, this, &GoogleSettingsDialog::slotReloadTaskLists); - connect(m_ui->configureBtn, &QPushButton::clicked, this, &GoogleSettingsDialog::slotConfigure); - if (m_settings->isReady()) { - m_account = m_settings->accountPtr(); - } - connect(m_settings, &GoogleSettings::accountReady, this, [this](bool ready) { - if (ready) { - m_account = m_settings->accountPtr(); - accountChanged(); - } - }); - QMetaObject::invokeMethod(this, &GoogleSettingsDialog::accountChanged, Qt::QueuedConnection); -} - -GoogleSettingsDialog::~GoogleSettingsDialog() -{ - delete m_ui; -} - -bool GoogleSettingsDialog::handleError(KGAPI2::Job *job) -{ - if ((job->error() == KGAPI2::NoError) || (job->error() == KGAPI2::OK)) { - return true; - } - - if (job->error() == KGAPI2::Unauthorized) { - qCDebug(GOOGLE_LOG) << job << job->errorString(); - const QList resourceScopes = m_resource->scopes(); - for (const QUrl &scope : resourceScopes) { - if (!m_account->scopes().contains(scope)) { - m_account->addScope(scope); - } - } - - auto authJob = new AuthJob(m_account, m_settings->clientId(), m_settings->clientSecret(), this); - authJob->setProperty(JOB_PROPERTY, QVariant::fromValue(job)); - connect(authJob, &AuthJob::finished, this, &GoogleSettingsDialog::slotAuthJobFinished); - - return false; - } - - KMessageBox::error(this, job->errorString()); - return false; -} - -void GoogleSettingsDialog::accountChanged() -{ - if (!m_account) { - m_ui->accountLabel->setText(i18n("not configured")); - m_ui->calendarsList->setDisabled(true); - m_ui->reloadCalendarsBtn->setDisabled(true); - m_ui->calendarsList->clear(); - m_ui->taskListsList->setDisabled(true); - m_ui->reloadTaskListsBtn->setDisabled(true); - m_ui->taskListsList->clear(); - return; - } - m_ui->accountLabel->setText(QStringLiteral("%1").arg(m_account->accountName())); - slotReloadCalendars(); - slotReloadTaskLists(); -} - -void GoogleSettingsDialog::slotConfigure() -{ - const QString username = m_account && !m_account->accountName().isEmpty() ? m_account->accountName() : QString(); - m_account = AccountPtr(new Account()); - const QList resourceScopes = m_resource->scopes(); - for (const QUrl &scope : resourceScopes) { - if (!m_account->scopes().contains(scope)) { - m_account->addScope(scope); - } - } - auto authJob = new AuthJob(m_account, m_settings->clientId(), m_settings->clientSecret()); - authJob->setUsername(username); - connect(authJob, &AuthJob::finished, this, &GoogleSettingsDialog::slotAuthJobFinished); -} - -void GoogleSettingsDialog::slotAuthJobFinished(KGAPI2::Job *job) -{ - auto authJob = qobject_cast(job); - m_account = authJob->account(); - if (authJob->error() != KGAPI2::NoError) { - KMessageBox::error(this, authJob->errorString()); - return; - } - accountChanged(); - - auto otherJob = job->property(JOB_PROPERTY).value(); - if (otherJob) { - otherJob->setAccount(m_account); - otherJob->restart(); - } -} - -void GoogleSettingsDialog::slotSaveSettings() -{ - auto reset = [this] { - m_settings->setAccount({}); - m_settings->setEnableIntervalCheck(m_ui->enableRefresh->isChecked()); - m_settings->setIntervalCheckTime(m_ui->refreshSpinBox->value()); - m_settings->setCalendars({}); - m_settings->setTaskLists({}); - m_settings->setEventsSince({}); - m_settings->save(); - }; - - if (!m_account) { - reset(); - return; - } - - auto writeJob = m_settings->storeAccount(m_account); - connect(writeJob, &WritePasswordJob::finished, this, [this, reset, writeJob]() { - if (writeJob->error()) { - qCWarning(GOOGLE_LOG) << "Failed to store account's password in secret storage" << writeJob->errorString(); - reset(); - return; - } - - m_settings->setAccount(m_account->accountName()); - m_settings->setEnableIntervalCheck(m_ui->enableRefresh->isChecked()); - m_settings->setIntervalCheckTime(m_ui->refreshSpinBox->value()); - - QStringList calendars; - for (int i = 0; i < m_ui->calendarsList->count(); i++) { - QListWidgetItem *item = m_ui->calendarsList->item(i); - - if (item->checkState() == Qt::Checked) { - calendars.append(item->data(Qt::UserRole).toString()); - } - } - m_settings->setCalendars(calendars); - - if (m_ui->eventsLimitCombo->isValid()) { - m_settings->setEventsSince(m_ui->eventsLimitCombo->date().toString(Qt::ISODate)); - } - - QStringList taskLists; - for (int i = 0; i < m_ui->taskListsList->count(); i++) { - QListWidgetItem *item = m_ui->taskListsList->item(i); - - if (item->checkState() == Qt::Checked) { - taskLists.append(item->data(Qt::UserRole).toString()); - } - } - m_settings->setTaskLists(taskLists); - m_settings->save(); - - accept(); - }); -} - -void GoogleSettingsDialog::slotReloadCalendars() -{ - m_ui->calendarsList->setDisabled(true); - m_ui->reloadCalendarsBtn->setDisabled(true); - m_ui->calendarsList->clear(); - - if (!m_account) { - return; - } - - auto fetchJob = new CalendarFetchJob(m_account, this); - connect(fetchJob, &CalendarFetchJob::finished, this, [this](KGAPI2::Job *job) { - if (!handleError(job) || !m_account) { - m_ui->calendarsList->setEnabled(false); - m_ui->reloadCalendarsBtn->setEnabled(false); - return; - } - - const ObjectsList objects = qobject_cast(job)->items(); - - QStringList activeCalendars; - if (m_account->accountName() == m_settings->account()) { - activeCalendars = m_settings->calendars(); - } - m_ui->calendarsList->clear(); - for (const ObjectPtr &object : objects) { - const CalendarPtr calendar = object.dynamicCast(); - - auto item = new QListWidgetItem(calendar->title()); - item->setData(Qt::UserRole, calendar->uid()); - item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); - item->setCheckState((activeCalendars.isEmpty() || activeCalendars.contains(calendar->uid())) ? Qt::Checked : Qt::Unchecked); - m_ui->calendarsList->addItem(item); - } - - m_ui->calendarsList->setEnabled(true); - m_ui->reloadCalendarsBtn->setEnabled(true); - }); -} - -void GoogleSettingsDialog::slotReloadTaskLists() -{ - if (!m_account) { - return; - } - - m_ui->taskListsList->setDisabled(true); - m_ui->reloadTaskListsBtn->setDisabled(true); - m_ui->taskListsList->clear(); - - auto job = new TaskListFetchJob(m_account, this); - connect(job, &TaskListFetchJob::finished, this, [this](KGAPI2::Job *job) { - if (!handleError(job) || !m_account) { - m_ui->taskListsList->setDisabled(true); - m_ui->reloadTaskListsBtn->setDisabled(true); - return; - } - - const ObjectsList objects = qobject_cast(job)->items(); - - QStringList activeTaskLists; - if (m_account->accountName() == m_settings->account()) { - activeTaskLists = m_settings->taskLists(); - } - m_ui->taskListsList->clear(); - for (const ObjectPtr &object : objects) { - const TaskListPtr taskList = object.dynamicCast(); - - auto item = new QListWidgetItem(taskList->title()); - item->setData(Qt::UserRole, taskList->uid()); - item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); - item->setCheckState((activeTaskLists.isEmpty() || activeTaskLists.contains(taskList->uid())) ? Qt::Checked : Qt::Unchecked); - m_ui->taskListsList->addItem(item); - } - - m_ui->taskListsList->setEnabled(true); - m_ui->reloadTaskListsBtn->setEnabled(true); - }); -} diff --git a/resources/google-groupware/googlesettingswidget.cpp b/resources/google-groupware/googlesettingswidget.cpp new file mode 100644 index 0000000000..2543c4c6b8 --- /dev/null +++ b/resources/google-groupware/googlesettingswidget.cpp @@ -0,0 +1,288 @@ +/* + SPDX-FileCopyrightText: 2013 Daniel Vrátil + SPDX-FileCopyrightText: 2020 Igor Poboiko + + SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#include "googlesettingswidget.h" +#include "googleresource.h" +#include "googleresource_debug.h" +#include "googlescopes.h" +#include "googlesettings.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include +#else +#include +#endif + +using namespace QKeychain; +using namespace KGAPI2; + +GoogleSettingsWidget::GoogleSettingsWidget(GoogleSettings &settings, const QString &identifier, QWidget *parent) + : QWidget(parent) + , m_settings(settings) + , m_identifier(identifier) +{ + qDebug() << m_settings.account(); + auto mainLayout = new QVBoxLayout(this); + + auto mainWidget = new QWidget(this); + mainLayout->addWidget(mainWidget); + setupUi(mainWidget); + + refreshSpinBox->setSuffix(ki18np(" minute", " minutes")); + enableRefresh->setChecked(m_settings.enableIntervalCheck()); + refreshSpinBox->setEnabled(m_settings.enableIntervalCheck()); + refreshSpinBox->setValue(m_settings.intervalCheckTime()); + + eventsLimitCombo->setMaximumDate(QDate::currentDate()); + eventsLimitCombo->setMinimumDate(QDate::fromString(QStringLiteral("2000-01-01"), Qt::ISODate)); + eventsLimitCombo->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::WarnOnInvalid); + if (m_settings.eventsSince().isEmpty()) { + const QString ds = QStringLiteral("%1-01-01").arg(QString::number(QDate::currentDate().year() - 3)); + eventsLimitCombo->setDate(QDate::fromString(ds, Qt::ISODate)); + } else { + eventsLimitCombo->setDate(QDate::fromString(m_settings.eventsSince(), Qt::ISODate)); + } + connect(reloadCalendarsBtn, &QPushButton::clicked, this, &GoogleSettingsWidget::slotReloadCalendars); + connect(reloadTaskListsBtn, &QPushButton::clicked, this, &GoogleSettingsWidget::slotReloadTaskLists); + connect(configureBtn, &QPushButton::clicked, this, &GoogleSettingsWidget::loadSettings); + if (m_settings.isReady()) { + m_account = m_settings.accountPtr(); + } + connect(&m_settings, &GoogleSettings::accountReady, this, [this](bool ready) { + if (ready) { + m_account = m_settings.accountPtr(); + accountChanged(); + } + }); + QMetaObject::invokeMethod(this, &GoogleSettingsWidget::accountChanged, Qt::QueuedConnection); +} + +GoogleSettingsWidget::~GoogleSettingsWidget() +{ +} + +bool GoogleSettingsWidget::handleError(KGAPI2::Job *job) +{ + if ((job->error() == KGAPI2::NoError) || (job->error() == KGAPI2::OK)) { + return true; + } + + if (job->error() == KGAPI2::Unauthorized) { + qCDebug(GOOGLE_LOG) << job << job->errorString(); + const QList resourceScopes = googleScopes(); + for (const QUrl &scope : resourceScopes) { + if (!m_account->scopes().contains(scope)) { + m_account->addScope(scope); + } + } + + auto authJob = new AuthJob(m_account, m_settings.clientId(), m_settings.clientSecret(), this); + authJob->setProperty(JOB_PROPERTY, QVariant::fromValue(job)); + connect(authJob, &AuthJob::finished, this, &GoogleSettingsWidget::slotAuthJobFinished); + + return false; + } + + KMessageBox::error(this, job->errorString()); + return false; +} + +void GoogleSettingsWidget::accountChanged() +{ + if (!m_account) { + accountLabel->setText(i18n("not configured")); + calendarsList->setDisabled(true); + reloadCalendarsBtn->setDisabled(true); + calendarsList->clear(); + taskListsList->setDisabled(true); + reloadTaskListsBtn->setDisabled(true); + taskListsList->clear(); + return; + } + accountLabel->setText(QStringLiteral("%1").arg(m_account->accountName())); + slotReloadCalendars(); + slotReloadTaskLists(); +} + +void GoogleSettingsWidget::loadSettings() +{ + const QString username = m_account && !m_account->accountName().isEmpty() ? m_account->accountName() : QString(); + m_account = AccountPtr(new Account()); + const QList resourceScopes = googleScopes(); + for (const QUrl &scope : resourceScopes) { + if (!m_account->scopes().contains(scope)) { + m_account->addScope(scope); + } + } + auto authJob = new AuthJob(m_account, m_settings.clientId(), m_settings.clientSecret()); + authJob->setUsername(username); + connect(authJob, &AuthJob::finished, this, &GoogleSettingsWidget::slotAuthJobFinished); +} + +void GoogleSettingsWidget::slotAuthJobFinished(KGAPI2::Job *job) +{ + auto authJob = qobject_cast(job); + m_account = authJob->account(); + if (authJob->error() != KGAPI2::NoError) { + KMessageBox::error(this, authJob->errorString()); + return; + } + accountChanged(); + + auto otherJob = job->property(JOB_PROPERTY).value(); + if (otherJob) { + otherJob->setAccount(m_account); + otherJob->restart(); + } +} + +void GoogleSettingsWidget::saveSettings() +{ + auto reset = [this] { + m_settings.setAccount({}); + m_settings.setEnableIntervalCheck(enableRefresh->isChecked()); + m_settings.setIntervalCheckTime(refreshSpinBox->value()); + m_settings.setCalendars({}); + m_settings.setTaskLists({}); + m_settings.setEventsSince({}); + m_settings.save(); + }; + + if (!m_account) { + reset(); + return; + } + + auto writeJob = m_settings.storeAccount(m_account); + connect(writeJob, &WritePasswordJob::finished, this, [this, reset, writeJob]() { + if (writeJob->error()) { + qCWarning(GOOGLE_LOG) << "Failed to store account's password in secret storage" << writeJob->errorString(); + reset(); + return; + } + + m_settings.setAccount(m_account->accountName()); + m_settings.setEnableIntervalCheck(enableRefresh->isChecked()); + m_settings.setIntervalCheckTime(refreshSpinBox->value()); + + QStringList calendars; + for (int i = 0; i < calendarsList->count(); i++) { + QListWidgetItem *item = calendarsList->item(i); + + if (item->checkState() == Qt::Checked) { + calendars.append(item->data(Qt::UserRole).toString()); + } + } + m_settings.setCalendars(calendars); + + if (eventsLimitCombo->isValid()) { + m_settings.setEventsSince(eventsLimitCombo->date().toString(Qt::ISODate)); + } + + QStringList taskLists; + for (int i = 0; i < taskListsList->count(); i++) { + QListWidgetItem *item = taskListsList->item(i); + + if (item->checkState() == Qt::Checked) { + taskLists.append(item->data(Qt::UserRole).toString()); + } + } + m_settings.setTaskLists(taskLists); + m_settings.save(); + }); +} + +void GoogleSettingsWidget::slotReloadCalendars() +{ + calendarsList->setDisabled(true); + reloadCalendarsBtn->setDisabled(true); + calendarsList->clear(); + + if (!m_account) { + return; + } + + auto fetchJob = new CalendarFetchJob(m_account, this); + connect(fetchJob, &CalendarFetchJob::finished, this, [this](KGAPI2::Job *job) { + if (!handleError(job) || !m_account) { + calendarsList->setEnabled(false); + reloadCalendarsBtn->setEnabled(false); + return; + } + + const ObjectsList objects = qobject_cast(job)->items(); + + QStringList activeCalendars; + if (m_account->accountName() == m_settings.account()) { + activeCalendars = m_settings.calendars(); + } + calendarsList->clear(); + for (const ObjectPtr &object : objects) { + const CalendarPtr calendar = object.dynamicCast(); + + auto item = new QListWidgetItem(calendar->title()); + item->setData(Qt::UserRole, calendar->uid()); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + item->setCheckState((activeCalendars.isEmpty() || activeCalendars.contains(calendar->uid())) ? Qt::Checked : Qt::Unchecked); + calendarsList->addItem(item); + } + + calendarsList->setEnabled(true); + reloadCalendarsBtn->setEnabled(true); + }); +} + +void GoogleSettingsWidget::slotReloadTaskLists() +{ + if (!m_account) { + return; + } + + taskListsList->setDisabled(true); + reloadTaskListsBtn->setDisabled(true); + taskListsList->clear(); + + auto job = new TaskListFetchJob(m_account, this); + connect(job, &TaskListFetchJob::finished, this, [this](KGAPI2::Job *job) { + if (!handleError(job) || !m_account) { + taskListsList->setDisabled(true); + reloadTaskListsBtn->setDisabled(true); + return; + } + + const ObjectsList objects = qobject_cast(job)->items(); + + QStringList activeTaskLists; + if (m_account->accountName() == m_settings.account()) { + activeTaskLists = m_settings.taskLists(); + } + taskListsList->clear(); + for (const ObjectPtr &object : objects) { + const TaskListPtr taskList = object.dynamicCast(); + + auto item = new QListWidgetItem(taskList->title()); + item->setData(Qt::UserRole, taskList->uid()); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + item->setCheckState((activeTaskLists.isEmpty() || activeTaskLists.contains(taskList->uid())) ? Qt::Checked : Qt::Unchecked); + taskListsList->addItem(item); + } + + taskListsList->setEnabled(true); + reloadTaskListsBtn->setEnabled(true); + }); +} diff --git a/resources/google-groupware/googlesettingsdialog.h b/resources/google-groupware/googlesettingswidget.h similarity index 53% rename from resources/google-groupware/googlesettingsdialog.h rename to resources/google-groupware/googlesettingswidget.h index a7d6ca0c92..4226a39d2d 100644 --- a/resources/google-groupware/googlesettingsdialog.h +++ b/resources/google-groupware/googlesettingswidget.h @@ -7,40 +7,37 @@ #pragma once +#include "googlesettings.h" +#include "ui_googlesettingswidget.h" #include -#include -namespace Ui -{ -class GoogleSettingsDialog; -} namespace KGAPI2 { class Job; } -class GoogleResource; -class GoogleSettings; - -class GoogleSettingsDialog : public QDialog +class GoogleSettingsWidget : public QWidget, private Ui::GoogleSettingsWidget { Q_OBJECT public: - explicit GoogleSettingsDialog(GoogleResource *resource, GoogleSettings *settings, WId wId); - ~GoogleSettingsDialog() override; + explicit GoogleSettingsWidget(GoogleSettings &settings, const QString &identifier, QWidget *parent); + ~GoogleSettingsWidget() override; + + void loadSettings(); + void saveSettings(); + +Q_SIGNALS: + void okEnabled(bool enabled); protected: bool handleError(KGAPI2::Job *job); void accountChanged(); private: - void slotConfigure(); void slotAuthJobFinished(KGAPI2::Job *job); - void slotSaveSettings(); void slotReloadCalendars(); void slotReloadTaskLists(); - GoogleResource *const m_resource; - GoogleSettings *const m_settings; - Ui::GoogleSettingsDialog *const m_ui; + GoogleSettings &m_settings; KGAPI2::AccountPtr m_account; + const QString m_identifier; }; diff --git a/resources/google-groupware/googlesettingsdialog.ui b/resources/google-groupware/googlesettingswidget.ui similarity index 99% rename from resources/google-groupware/googlesettingsdialog.ui rename to resources/google-groupware/googlesettingswidget.ui index 9ff9bc93b4..75fdfd24f1 100644 --- a/resources/google-groupware/googlesettingsdialog.ui +++ b/resources/google-groupware/googlesettingswidget.ui @@ -1,6 +1,6 @@ - GoogleSettingsDialog + GoogleSettingsWidget diff --git a/resources/google-groupware/settingsbase.kcfg b/resources/google-groupware/settingsbase.kcfg index ac58395d71..7dfe8dfe92 100644 --- a/resources/google-groupware/settingsbase.kcfg +++ b/resources/google-groupware/settingsbase.kcfg @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > - + -- GitLab