From 4bf7f9095936acf6fabcf33d887b2e124c91d2c6 Mon Sep 17 00:00:00 2001 From: Rmys Date: Thu, 21 Sep 2023 14:29:45 +0300 Subject: [PATCH] kdepim-runtime --- .../kdepim-runtime/files/2fd3604a.patch | 60 + .../kdepim-runtime/files/c99afc75.patch | 120 ++ .../kdepim-runtime/files/fb0d78fb.patch | 1302 +++++++++++++++++ .../files/fix-data-loss-bug-in-ical.patch | 23 - .../kdepim-runtime/files/qt5.patch | 62 - .../kde/applications/kdepim-runtime/pspec.xml | 11 +- 6 files changed, 1492 insertions(+), 86 deletions(-) create mode 100644 desktop/kde/applications/kdepim-runtime/files/2fd3604a.patch create mode 100644 desktop/kde/applications/kdepim-runtime/files/c99afc75.patch create mode 100644 desktop/kde/applications/kdepim-runtime/files/fb0d78fb.patch delete mode 100755 desktop/kde/applications/kdepim-runtime/files/fix-data-loss-bug-in-ical.patch delete mode 100755 desktop/kde/applications/kdepim-runtime/files/qt5.patch diff --git a/desktop/kde/applications/kdepim-runtime/files/2fd3604a.patch b/desktop/kde/applications/kdepim-runtime/files/2fd3604a.patch new file mode 100644 index 0000000000..afb20a8ddb --- /dev/null +++ b/desktop/kde/applications/kdepim-runtime/files/2fd3604a.patch @@ -0,0 +1,60 @@ +From 2fd3604ad6a9594b9dd8b0f1529f4f4589fe831f Mon Sep 17 00:00:00 2001 +From: Carl Schwan +Date: Tue, 19 Sep 2023 17:04:36 +0200 +Subject: [PATCH] Revert "Revert "Fix race condition when building"" + +This reverts commit d3f20b3dab530065f9cff9d73e4ca1076af55a29. + +(cherry picked from commit f9f262b9289f7b1c34e55205fa0c5cde915bc652) +--- + resources/google-groupware/CMakeLists.txt | 7 ++++--- + resources/google-groupware/googleresource.cpp | 1 - + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/resources/google-groupware/CMakeLists.txt b/resources/google-groupware/CMakeLists.txt +index 2f2b46aded..0ac6f2db8e 100644 +--- a/resources/google-groupware/CMakeLists.txt ++++ b/resources/google-groupware/CMakeLists.txt +@@ -67,9 +67,6 @@ set(googleresource_SRCS + ${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) +@@ -126,6 +123,7 @@ install( + kcoreaddons_add_plugin(googleconfig + INSTALL_NAMESPACE "pim${QT_MAJOR_VERSION}/akonadi/config" + ) ++ + target_sources(googleconfig + PRIVATE + googleconfig.cpp +@@ -133,6 +131,9 @@ PRIVATE + googlesettingswidget.h + ${googleresource_common_SRCS} + ) ++ ++ki18n_wrap_ui(googleconfig googlesettingswidget.ui) ++ + target_link_libraries(googleconfig + KPim${KF_MAJOR_VERSION}::AkonadiCore + KPim${KF_MAJOR_VERSION}::AkonadiCalendar +diff --git a/resources/google-groupware/googleresource.cpp b/resources/google-groupware/googleresource.cpp +index 47a7e0c8d5..d51c1e4a7c 100644 +--- a/resources/google-groupware/googleresource.cpp ++++ b/resources/google-groupware/googleresource.cpp +@@ -11,7 +11,6 @@ + #include "googleresourcestate.h" + #include "googlescopes.h" + #include "googlesettings.h" +-#include "googlesettingswidget.h" + #include "settingsadaptor.h" + + #include "personhandler.h" +-- +GitLab + diff --git a/desktop/kde/applications/kdepim-runtime/files/c99afc75.patch b/desktop/kde/applications/kdepim-runtime/files/c99afc75.patch new file mode 100644 index 0000000000..80593ef226 --- /dev/null +++ b/desktop/kde/applications/kdepim-runtime/files/c99afc75.patch @@ -0,0 +1,120 @@ +From c99afc75a503fff6ca83df2f47a5d5d951579524 Mon Sep 17 00:00:00 2001 +From: Carl Schwan +Date: Tue, 19 Sep 2023 18:58:54 +0200 +Subject: [PATCH] Actually start job to read secret key + +BUG: 470820 +(cherry picked from commit 8393e92d56ecb31b2dd65d15d046f8e02565f5e3) +--- + resources/google-groupware/googleconfig.cpp | 8 +++++++- + resources/google-groupware/googlesettings.cpp | 15 +++++++++------ + .../google-groupware/googlesettingswidget.cpp | 3 +-- + 3 files changed, 17 insertions(+), 9 deletions(-) + +diff --git a/resources/google-groupware/googleconfig.cpp b/resources/google-groupware/googleconfig.cpp +index 2eb6ab2efa..1af177c81f 100644 +--- a/resources/google-groupware/googleconfig.cpp ++++ b/resources/google-groupware/googleconfig.cpp +@@ -6,6 +6,7 @@ + + #include + ++#include "googleresource_debug.h" + #include "googlesettings.h" + #include "googlesettingswidget.h" + +@@ -25,7 +26,12 @@ public: + void load() override + { + Akonadi::AgentConfigurationBase::load(); +- mWidget.loadSettings(); ++ mSettings.init(); ++ connect(&mSettings, &GoogleSettings::accountReady, this, [this](bool ready) { ++ if (ready) { ++ mWidget.loadSettings(); ++ } ++ }); + } + + Q_REQUIRED_RESULT bool save() const override +diff --git a/resources/google-groupware/googlesettings.cpp b/resources/google-groupware/googlesettings.cpp +index aa94cad1ab..23a9979895 100644 +--- a/resources/google-groupware/googlesettings.cpp ++++ b/resources/google-groupware/googlesettings.cpp +@@ -32,7 +32,6 @@ static const QString googleWalletFolder = QStringLiteral("Akonadi Google"); + GoogleSettings::GoogleSettings(const KSharedConfigPtr &config, Options options) + : SettingsBase(config) + { +- qDebug() << config; + if (options & Option::ExportToDBus) { + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), +@@ -44,9 +43,11 @@ GoogleSettings::GoogleSettings(const KSharedConfigPtr &config, Options options) + void GoogleSettings::init() + { + // First read from QtKeyChain +- auto job = new QKeychain::ReadPasswordJob(googleWalletFolder); ++ auto job = new QKeychain::ReadPasswordJob(googleWalletFolder, this); ++ job->setKey(account()); + connect(job, &QKeychain::Job::finished, this, [this, job]() { + if (job->error() != QKeychain::Error::NoError) { ++ qCWarning(GOOGLE_LOG) << "Unable to read password" << job->error(); + Q_EMIT accountReady(false); + return; + } +@@ -54,18 +55,19 @@ void GoogleSettings::init() + // Found something with QtKeyChain + if (!account().isEmpty()) { + m_account = fetchAccountFromKeychain(account(), job); ++ m_isReady = true; ++ Q_EMIT accountReady(true); + } +- m_isReady = true; +- Q_EMIT accountReady(true); + }); ++ job->start(); + } + + KGAPI2::AccountPtr GoogleSettings::fetchAccountFromKeychain(const QString &accountName, QKeychain::ReadPasswordJob *job) + { + QMap map; + auto value = job->binaryData(); +- if (!value.isEmpty()) { +- qCDebug(GOOGLE_LOG) << "Account" << accountName << "not found in KWallet"; ++ if (value.isEmpty()) { ++ qCWarning(GOOGLE_LOG) << "Account" << accountName << "not found in KWallet"; + return {}; + } + +@@ -116,6 +118,7 @@ WritePasswordJob *GoogleSettings::storeAccount(AccountPtr account) + + connect(writeJob, &WritePasswordJob::finished, this, [this, writeJob]() { + if (writeJob->error()) { ++ qCWarning(GOOGLE_LOG) << "Unable to write password" << writeJob->error(); + return; + } + SettingsBase::setAccount(m_account->accountName()); +diff --git a/resources/google-groupware/googlesettingswidget.cpp b/resources/google-groupware/googlesettingswidget.cpp +index 2543c4c6b8..8e84cfbabd 100644 +--- a/resources/google-groupware/googlesettingswidget.cpp ++++ b/resources/google-groupware/googlesettingswidget.cpp +@@ -36,7 +36,6 @@ GoogleSettingsWidget::GoogleSettingsWidget(GoogleSettings &settings, const QStri + , m_settings(settings) + , m_identifier(identifier) + { +- qDebug() << m_settings.account(); + auto mainLayout = new QVBoxLayout(this); + + auto mainWidget = new QWidget(this); +@@ -83,7 +82,7 @@ bool GoogleSettingsWidget::handleError(KGAPI2::Job *job) + } + + if (job->error() == KGAPI2::Unauthorized) { +- qCDebug(GOOGLE_LOG) << job << job->errorString(); ++ qWarning() << job << job->errorString(); + const QList resourceScopes = googleScopes(); + for (const QUrl &scope : resourceScopes) { + if (!m_account->scopes().contains(scope)) { +-- +GitLab + diff --git a/desktop/kde/applications/kdepim-runtime/files/fb0d78fb.patch b/desktop/kde/applications/kdepim-runtime/files/fb0d78fb.patch new file mode 100644 index 0000000000..d1838d9680 --- /dev/null +++ b/desktop/kde/applications/kdepim-runtime/files/fb0d78fb.patch @@ -0,0 +1,1302 @@ +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 + diff --git a/desktop/kde/applications/kdepim-runtime/files/fix-data-loss-bug-in-ical.patch b/desktop/kde/applications/kdepim-runtime/files/fix-data-loss-bug-in-ical.patch deleted file mode 100755 index e4767b5b48..0000000000 --- a/desktop/kde/applications/kdepim-runtime/files/fix-data-loss-bug-in-ical.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git a/resources/shared/singlefileresource/singlefileresource.h b/resources/shared/singlefileresource/singlefileresource.h -index f3c19aa..3f41499 100644 ---- a/resources/shared/singlefileresource/singlefileresource.h -+++ b/resources/shared/singlefileresource/singlefileresource.h -@@ -55,7 +55,7 @@ public: - , mSettings(new Settings(config())) - { - // The resource needs network when the path refers to a non local file. -- setNeedsNetwork(!QUrl(mSettings->path()).isLocalFile()); -+ setNeedsNetwork(!QUrl::fromUserInput(mSettings->path()).isLocalFile()); - } - ~SingleFileResource() - { -@@ -82,7 +82,7 @@ public: - return; - } - -- mCurrentUrl = QUrl(mSettings->path()); // path already has scheme -+ mCurrentUrl = QUrl::fromUserInput(mSettings->path()); // the string contains the scheme if remote, doesn't if local path - if (mCurrentHash.isEmpty()) - { - // First call to readFile() lets see if there is a hash stored in a --- diff --git a/desktop/kde/applications/kdepim-runtime/files/qt5.patch b/desktop/kde/applications/kdepim-runtime/files/qt5.patch deleted file mode 100755 index 3bfae7e501..0000000000 --- a/desktop/kde/applications/kdepim-runtime/files/qt5.patch +++ /dev/null @@ -1,62 +0,0 @@ -diff -Nuar a/CMakeLists.txt b/CMakeLists.txt ---- a/CMakeLists.txt 2017-12-14 14:08:44.000000000 +0300 -+++ b/CMakeLists.txt 2017-12-17 22:28:41.525681257 +0300 -@@ -62,7 +62,7 @@ - include(ECMCoverageOption) - - --set(QT_REQUIRED_VERSION "5.8.0") -+set(QT_REQUIRED_VERSION "5.7.1") - - set(KDEPIMRUNTIME_LIB_VERSION "${KDEPIM_RUNTIME_VERSION_NUMBER}") - set(KDEPIMRUNTIME_LIB_SOVERSION "5") -diff -Nuar a/resources/tomboynotes/tomboyitemuploadjob.cpp b/resources/tomboynotes/tomboyitemuploadjob.cpp ---- a/resources/tomboynotes/tomboyitemuploadjob.cpp 2017-12-13 15:11:13.000000000 +0300 -+++ b/resources/tomboynotes/tomboyitemuploadjob.cpp 2017-12-17 22:30:50.749671933 +0300 -@@ -65,7 +65,9 @@ - case JobType::AddItem: - jsonNote[QLatin1String("create-date")] = getCurrentISOTime(); - // Missing break is intended -+#if QT_VERSION >= QT_VERSION_CHECK(5,8,0) - Q_FALLTHROUGH(); -+#endif - case JobType::ModifyItem: - jsonNote[QLatin1String("title")] = mNoteContent->headerByType("subject")->asUnicodeString(); - jsonNote[QLatin1String("note-content")] = mNoteContent->mainBodyPart()->decodedText(); -diff -Nuar a/resources/imap/searchtask.cpp b/resources/imap/searchtask.cpp ---- a/resources/imap/searchtask.cpp 2017-12-13 15:11:13.000000000 +0300 -+++ b/resources/imap/searchtask.cpp 2017-12-17 22:48:51.475593953 +0300 -@@ -104,12 +104,16 @@ - switch (term.condition()) { - case Akonadi::SearchTerm::CondGreaterOrEqual: - value--; -+#if QT_VERSION >= QT_VERSION_CHECK(5,8,0) - Q_FALLTHROUGH(); -+#endif - case Akonadi::SearchTerm::CondGreaterThan: - return KIMAP::Term(KIMAP::Term::Larger, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondLessOrEqual: - value++; -+#if QT_VERSION >= QT_VERSION_CHECK(5,8,0) - Q_FALLTHROUGH(); -+#endif - case Akonadi::SearchTerm::CondLessThan: - return KIMAP::Term(KIMAP::Term::Smaller, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondEqual: -@@ -128,12 +132,16 @@ - switch (term.condition()) { - case Akonadi::SearchTerm::CondGreaterOrEqual: - value = value.addDays(-1); -+#if QT_VERSION >= QT_VERSION_CHECK(5,8,0) - Q_FALLTHROUGH(); -+#endif - case Akonadi::SearchTerm::CondGreaterThan: - return KIMAP::Term(KIMAP::Term::SentSince, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondLessOrEqual: - value = value.addDays(1); -+#if QT_VERSION >= QT_VERSION_CHECK(5,8,0) - Q_FALLTHROUGH(); -+#endif - case Akonadi::SearchTerm::CondLessThan: - return KIMAP::Term(KIMAP::Term::SentBefore, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondEqual: diff --git a/desktop/kde/applications/kdepim-runtime/pspec.xml b/desktop/kde/applications/kdepim-runtime/pspec.xml index fc3169bc90..3a557254aa 100755 --- a/desktop/kde/applications/kdepim-runtime/pspec.xml +++ b/desktop/kde/applications/kdepim-runtime/pspec.xml @@ -63,7 +63,9 @@ qt5-keychain-devel - + 2fd3604a.patch + c99afc75.patch + fb0d78fb.patch @@ -140,6 +142,13 @@ + + 2023-09-21 + 23.08.1 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2023-09-14 23.08.1