diff --git a/CMakeLists.txt b/CMakeLists.txt index a5f5ac5..5d63eb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,64 +1,58 @@ project(KAccounts) cmake_minimum_required(VERSION 2.8.12) set(QT_REQUIRED_VERSION "5.7.0") set(KF5_MIN_VERSION "5.4.0") - find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) -enable_testing() - set(RELEASE_SERVICE_VERSION_MAJOR "20") set(RELEASE_SERVICE_VERSION_MINOR "03") set(RELEASE_SERVICE_VERSION_MICRO "70") set(KACCOUNTS_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}") set(KACCOUNTS_SOVERSION "1") set(ACCOUNTSQT_DEP_VERSION "1.13") set(SIGNONQT_DEP_VERSION "8.55") set(ACCOUNTSGLIB_DEP_VERSION "1.21") find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Core Widgets) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED KCMUtils I18n CoreAddons DBusAddons Declarative) find_package(AccountsQt5 ${ACCOUNTSQT_DEP_VERSION} CONFIG) set_package_properties(AccountsQt5 PROPERTIES DESCRIPTION "Accounts management library for Qt applications" URL "https://gitlab.com/accounts-sso/libaccounts-qt" TYPE REQUIRED PURPOSE "Required for building this module") find_package(SignOnQt5 ${SIGNONQT_DEP_VERSION} CONFIG) set_package_properties(SignOnQt5 PROPERTIES DESCRIPTION "D-Bus service which performs user authentication on behalf of its clients" URL "https://gitlab.com/accounts-sso/signond" TYPE REQUIRED PURPOSE "Required for building this module") -add_definitions ( - -DQT_NO_KEYWORDS) +add_definitions (-DTRANSLATION_DOMAIN=\"kaccounts-integration\" -DQT_NO_KEYWORDS -DQT_NO_FOREACH) -add_definitions(-DTRANSLATION_DOMAIN=\"kaccounts-integration\") -add_definitions(-DQT_NO_FOREACH) if (EXISTS "${CMAKE_SOURCE_DIR}/.git" AND AccountsQt5_VERSION VERSION_GREATER 1.15) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x060000) endif() include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(FeatureSummary) - -kde_enable_exceptions() +include(ECMSetupVersion) +include(ECMGenerateHeaders) +include(GenerateExportHeader) +include(ECMPackageConfigHelpers) include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS}) -remove_definitions(-DQT_NO_CAST_FROM_ASCII) - add_subdirectory(src) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/example/accounts.qml b/example/accounts.qml index ffa48fd..7324b68 100644 --- a/example/accounts.qml +++ b/example/accounts.qml @@ -1,67 +1,67 @@ import QtQuick 2.3 import QtQuick.Controls 1.2 import QtQuick.Layouts 1.1 import Ubuntu.OnlineAccounts 0.1 as OA import org.kde.kaccounts 1.0 ApplicationWindow { StackView { id: stack anchors.fill: parent initialItem: ListView { Layout.fillWidth: true Layout.fillHeight: true header: Label { font.pointSize: 20 text: "Accounts" } footer: Button { text: "Add new Account" onClicked: stack.push(addProviderComponent) } model: OA.AccountServiceModel { id: accountsModel service: "global" includeDisabled: true } delegate: Label { text: displayName } } } Component { id: addProviderComponent ListView { Layout.fillWidth: true Layout.fillHeight: true header: Label { anchors.horizontalCenter: parent.horizontalCenter font.pointSize: 20 text: "Available Accounts" } model: OA.ProviderModel {} delegate: Button { anchors.horizontalCenter: parent.horizontalCenter text: displayName Component { id: jobComponent - CreateAccount {} + CreateAccountJob {} } onClicked: { var job = jobComponent.createObject(stack, { providerName: providerId}) job.start() } } } } } diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index f037684..45fb03b 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -1,19 +1,14 @@ include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -set(accounts_daemon_SRCS - daemon.cpp +kcoreaddons_add_plugin( + kded_accounts + SOURCES daemon.cpp + JSON kded_accounts.json + INSTALL_NAMESPACE "kf5/kded" ) -add_library(kded_accounts MODULE - ${accounts_daemon_SRCS} -) -kcoreaddons_desktop_to_json(kded_accounts accounts.desktop) - target_link_libraries(kded_accounts Qt5::Core KF5::DBusAddons kaccounts ) - -set_target_properties(kded_accounts PROPERTIES OUTPUT_NAME accounts) -install(TARGETS kded_accounts DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kded) diff --git a/src/daemon/accounts.desktop b/src/daemon/accounts.desktop deleted file mode 100644 index 2428f4f..0000000 --- a/src/daemon/accounts.desktop +++ /dev/null @@ -1,88 +0,0 @@ -[Desktop Entry] -Name=Accounts -Name[ar]=الحسابات -Name[ca]=Comptes -Name[ca@valencia]=Comptes -Name[cs]=Účty -Name[da]=Konti -Name[de]=Zugänge -Name[el]=Λογαριασμοί -Name[en_GB]=Accounts -Name[es]=Cuentas -Name[et]=Kontod -Name[eu]=Kontuak -Name[fi]=Tilit -Name[fr]=Comptes -Name[gl]=Contas -Name[hu]=Fiókok -Name[ia]=Contos -Name[it]=Account -Name[ko]=계정 -Name[lt]=Paskyros -Name[nl]=Accounts -Name[nn]=Kontoar -Name[pl]=Konta -Name[pt]=Contas -Name[pt_BR]=Contas -Name[ro]=Conturi -Name[ru]=Учётные записи в Интернете -Name[sk]=Účty -Name[sl]=Računi -Name[sr]=Налози -Name[sr@ijekavian]=Налози -Name[sr@ijekavianlatin]=Nalozi -Name[sr@latin]=Nalozi -Name[sv]=Konton -Name[tr]=Hesaplar -Name[uk]=Облікові записи -Name[x-test]=xxAccountsxx -Name[zh_CN]=帐户 -Name[zh_TW]=帳號 -Comment=Accounts management -Comment[ar]=إدارة الحساباتل -Comment[ca]=Gestor de comptes -Comment[ca@valencia]=Gestor de comptes -Comment[cs]=Správa účtů -Comment[da]=Håndtering af konti -Comment[de]=Zugangs-Verwaltung -Comment[el]=Διαχείριση λογαριασμών -Comment[en_GB]=Accounts management -Comment[es]=Gestión de cuentas -Comment[et]=Kontode haldus -Comment[eu]=Kontuen kudeaketa -Comment[fi]=Tilienhallinta -Comment[fr]=Gestion des comptes -Comment[gl]=Xestión das contas -Comment[hu]=Fiókkezelés -Comment[ia]=Gestion de contos -Comment[it]=Gestione account -Comment[ko]=계정 관리 -Comment[lt]=Paskyrų tvarkymas -Comment[nl]=Accountbeheer -Comment[nn]=Konto­handsaming -Comment[pl]=Zarządzanie kontami -Comment[pt]=Gestão de contas -Comment[pt_BR]=Gerenciamento de contas -Comment[ro]=Gestiune conturi -Comment[ru]=Управление учётными записями в интернет-службах -Comment[sk]=Správa účtov -Comment[sl]=Upravljanje računov -Comment[sr]=Управљање налозима -Comment[sr@ijekavian]=Управљање налозима -Comment[sr@ijekavianlatin]=Upravljanje nalozima -Comment[sr@latin]=Upravljanje nalozima -Comment[sv]=Kontohantering -Comment[tr]=Hesap yönetimi -Comment[uk]=Керування обліковими записами -Comment[x-test]=xxAccounts managementxx -Comment[zh_CN]=账户管理 -Comment[zh_TW]=帳號管理 - -Type=Service -Icon=preferences-system-power-management -X-KDE-ServiceTypes=KDEDModule -X-KDE-Library=accounts -X-KDE-DBus-ModuleName=accounts -X-KDE-Kded-autoload=true -X-KDE-Kded-load-on-demand=false -X-KDE-Kded-phase=1 diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 386072f..4769e52 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -1,143 +1,143 @@ /************************************************************************************* * Copyright (C) 2013 by Alejandro Fiestas Olivares * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "daemon.h" #include "src/lib/kaccountsdplugin.h" #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(AccountsDaemonFactory, "accounts.json", registerPlugin();) AccountsDaemon::AccountsDaemon(QObject *parent, const QList&) : KDEDModule(parent) { QMetaObject::invokeMethod(this, "startDaemon", Qt::QueuedConnection); connect(KAccounts::accountsManager(), &Accounts::Manager::accountCreated, this, &AccountsDaemon::accountCreated); connect(KAccounts::accountsManager(), &Accounts::Manager::accountRemoved, this, &AccountsDaemon::accountRemoved); const QVector data = KPluginLoader::findPlugins(QStringLiteral("kaccounts/daemonplugins")); for (const KPluginMetaData& metadata : data) { if (!metadata.isValid()) { qDebug() << "Invalid metadata" << metadata.name(); continue; } KPluginLoader loader(metadata.fileName()); KPluginFactory* factory = loader.factory(); if (!factory) { qDebug() << "KPluginFactory could not load the plugin:" << metadata.pluginId() << loader.errorString(); continue; } - KAccountsDPlugin* plugin = factory->create(this, {}); + KAccountsDPlugin* plugin = factory->create(this, QVariantList()); if (!plugin) { qDebug() << "Error loading plugin" << metadata.name() << loader.errorString(); continue; } m_plugins << plugin; } } AccountsDaemon::~AccountsDaemon() { qDeleteAll(m_plugins); } void AccountsDaemon::startDaemon() { qDebug(); const Accounts::AccountIdList accList = KAccounts::accountsManager()->accountList(); for (const Accounts::AccountId &id : accList) { monitorAccount(id); } } void AccountsDaemon::monitorAccount(const Accounts::AccountId id) { qDebug() << id; Accounts::Account *acc = KAccounts::accountsManager()->account(id); const Accounts::ServiceList services = acc->services(); for (const Accounts::Service &service : services) { acc->selectService(service); } acc->selectService(); connect(acc, &Accounts::Account::enabledChanged, this, &AccountsDaemon::enabledChanged); } void AccountsDaemon::accountCreated(const Accounts::AccountId id) { qDebug() << id; monitorAccount(id); const Accounts::Account *acc = KAccounts::accountsManager()->account(id); const Accounts::ServiceList services = acc->enabledServices(); for (KAccountsDPlugin *plugin : qAsConst(m_plugins)) { plugin->onAccountCreated(id, services); } } void AccountsDaemon::accountRemoved(const Accounts::AccountId id) { qDebug() << id; for (KAccountsDPlugin *plugin : qAsConst(m_plugins)) { plugin->onAccountRemoved(id); } } void AccountsDaemon::enabledChanged(const QString &serviceName, bool enabled) { qDebug(); if (serviceName.isEmpty()) { qDebug() << "ServiceName is Empty"; return; } const Accounts::AccountId accId = qobject_cast(sender())->id(); const Accounts::Service service = KAccounts::accountsManager()->service(serviceName); if (!enabled) { for (KAccountsDPlugin *plugin : qAsConst(m_plugins)) { plugin->onServiceDisabled(accId, service); } } else { for (KAccountsDPlugin *plugin : qAsConst(m_plugins)) { plugin->onServiceEnabled(accId, service); } } } #include "daemon.moc" diff --git a/src/daemon/kded_accounts.json b/src/daemon/kded_accounts.json new file mode 100644 index 0000000..df462ab --- /dev/null +++ b/src/daemon/kded_accounts.json @@ -0,0 +1,11 @@ +{ + "KPlugin": { + "Description": "Accounts management", + "Name": "Accounts" + }, + "OnlyShowIn": "KDE;", + "X-KDE-Kded-autoload": true, + "X-KDE-Kded-phase": 1, + "X-KDE-ModuleType": "Library" +} + diff --git a/src/declarative/CMakeLists.txt b/src/declarative/CMakeLists.txt index 6a24a5b..e202cdf 100644 --- a/src/declarative/CMakeLists.txt +++ b/src/declarative/CMakeLists.txt @@ -1,13 +1,11 @@ -include_directories(${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/..) - add_library(kaccountsdeclarativeplugin SHARED kaccountsdeclarativeplugin.cpp) target_link_libraries(kaccountsdeclarativeplugin Qt5::Qml KF5::I18n kaccounts ${SIGNONQT_LIBRARIES}) target_include_directories(kaccountsdeclarativeplugin PRIVATE "${SIGNONQT_INCLUDE_DIRS}") install(TARGETS kaccountsdeclarativeplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kaccounts) install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kaccounts) diff --git a/src/declarative/kaccountsdeclarativeplugin.cpp b/src/declarative/kaccountsdeclarativeplugin.cpp index 86b1079..4460793 100644 --- a/src/declarative/kaccountsdeclarativeplugin.cpp +++ b/src/declarative/kaccountsdeclarativeplugin.cpp @@ -1,35 +1,37 @@ /************************************************************************************* * Copyright (C) 2015 by Aleix Pol * * Copyright (C) 2020 by Dan Leinir Turthra Jensen * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "kaccountsdeclarativeplugin.h" -#include "../jobs/createaccountjob.h" -#include "../jobs/accountservicetogglejob.h" -#include "../jobs/removeaccountjob.h" +#include "createaccountjob.h" +#include "accountservicetogglejob.h" +#include "removeaccountjob.h" #include "accountsmodel.h" #include "servicesmodel.h" #include void KAccountsDeclarativePlugin::registerTypes(const char* uri) { qmlRegisterType(uri, 1, 0, "CreateAccount"); qmlRegisterType(uri, 1, 1, "AccountServiceToggle"); qmlRegisterType(uri, 1, 2, "RemoveAccount"); qmlRegisterType(uri, 1, 2, "AccountsModel"); qmlRegisterType(uri, 1, 2, "ServicesModel"); + qmlRegisterType(uri, 1, 0, "CreateAccountJob"); + qmlRegisterType(uri, 1, 1, "AccountServiceToggleJob"); } diff --git a/src/kcm/accounts.cpp b/src/kcm/accounts.cpp index 4efbfc9..f56bd91 100644 --- a/src/kcm/accounts.cpp +++ b/src/kcm/accounts.cpp @@ -1,39 +1,39 @@ /*************************************************************************** * * * Copyright 2019 Nicolas Fella * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "accounts.h" #include #include #include K_PLUGIN_CLASS_WITH_JSON(AccountsSettings, "kcm_kaccounts.json") AccountsSettings::AccountsSettings(QObject* parent, const QVariantList& args) : KQuickAddons::ConfigModule(parent, args) { - KAboutData* about = new KAboutData("kcm_kaccounts", i18n("Accounts"), - "1.0", QString(), KAboutLicense::LGPL); - about->addAuthor(i18n("Sebastian Kügler"), QString(), "sebas@kde.org"); - about->addAuthor(i18n("Dan Leinir Turthra Jensen"), QString(), "sebas@kde.org", QString(), "leinir"); + KAboutData* about = new KAboutData(QStringLiteral("kcm_kaccounts"), i18n("Accounts"), + QStringLiteral("1.0"), QString(), KAboutLicense::LGPL); + about->addAuthor(i18n("Sebastian Kügler"), QString(), QStringLiteral("sebas@kde.org")); + about->addAuthor(i18n("Dan Leinir Turthra Jensen"), QString(), QStringLiteral("admin@leinir.dk"), QString(), QStringLiteral("leinir")); setAboutData(about); } #include "accounts.moc" diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 61ec23d..6f3cbd1 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,103 +1,83 @@ -project (kaccounts-support-library) - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} -) - set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KAccounts") -include(ECMGenerateHeaders) -include(ECMPackageConfigHelpers) -include(ECMSetupVersion) -include(CMakePackageConfigHelpers) -include(WriteBasicConfigVersionFile) -include(KDECMakeSettings) -include(GenerateExportHeader) - ecm_setup_version(${KACCOUNTS_VERSION} VARIABLE_PREFIX KACCOUNTS VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kaccounts_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KAccountsConfigVersion.cmake" SOVERSION ${KACCOUNTS_SOVERSION}) set (kaccountslib_SRCS accountsmodel.cpp core.cpp - getcredentialsjob.cpp kaccountsdplugin.cpp kaccountsuiplugin.cpp servicesmodel.cpp uipluginsmanager.cpp - ../jobs/accountservicetogglejob.cpp - ../jobs/createaccountjob.cpp - ../jobs/removeaccountjob.cpp + + accountservicetogglejob.cpp + createaccountjob.cpp + getcredentialsjob.cpp + removeaccountjob.cpp ) ecm_generate_headers(kaccountslib_HEADERS HEADER_NAMES AccountsModel Core - GetCredentialsJob KAccountsUiPlugin KAccountsDPlugin ServicesModel - REQUIRED_HEADERS kaccountslib_HEADERS -) -ecm_generate_headers(kaccountslib_jobs_HEADERS - HEADER_NAMES + AccountServiceToggleJob + GetCredentialsJob CreateAccountJob RemoveAccountJob - RELATIVE ../jobs - REQUIRED_HEADERS kaccountslib_jobs_HEADERS + REQUIRED_HEADERS kaccountslib_HEADERS ) -add_library (kaccounts SHARED - ${kaccountslib_SRCS} -) +add_library(kaccounts ${kaccountslib_SRCS}) generate_export_header(kaccounts BASE_NAME kaccounts) target_link_libraries (kaccounts PUBLIC KF5::CoreAddons KF5::I18n ${ACCOUNTSQT_LIBRARIES} Qt5::Xml Qt5::Gui PRIVATE ${SIGNONQT_LIBRARIES} ) target_include_directories(kaccounts INTERFACE "$" PUBLIC "${ACCOUNTSQT_INCLUDE_DIRS}" PRIVATE "${SIGNONQT_INCLUDE_DIRS}") set_target_properties(kaccounts PROPERTIES VERSION ${KACCOUNTS_VERSION} SOVERSION ${KACCOUNTS_SOVERSION} EXPORT_NAME KAccounts ) ecm_configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KAccountsConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KAccountsConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "KAccountsMacros.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KAccountsConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KAccountsConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(TARGETS kaccounts EXPORT KAccountsTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) install(EXPORT KAccountsTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KAccountsTargets.cmake ) #NAMESPACE KF5:: install (FILES ${CMAKE_CURRENT_BINARY_DIR}/kaccounts_export.h ${kaccountslib_HEADERS} - ${kaccountslib_jobs_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/kaccounts_version.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/KAccounts COMPONENT Devel ) add_subdirectory(cmake) diff --git a/src/jobs/accountservicetogglejob.cpp b/src/lib/accountservicetogglejob.cpp similarity index 100% rename from src/jobs/accountservicetogglejob.cpp rename to src/lib/accountservicetogglejob.cpp diff --git a/src/jobs/accountservicetogglejob.h b/src/lib/accountservicetogglejob.h similarity index 98% rename from src/jobs/accountservicetogglejob.h rename to src/lib/accountservicetogglejob.h index 8f0a06e..80f44df 100644 --- a/src/jobs/accountservicetogglejob.h +++ b/src/lib/accountservicetogglejob.h @@ -1,56 +1,57 @@ /************************************************************************************* * Copyright (C) 2020 by Dan Leinir Turthra Jensen * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #ifndef ACCOUNTSERVICETOGGLE_H #define ACCOUNTSERVICETOGGLE_H +#include "kaccounts_export.h" #include "kaccounts_export.h" #include #include class KACCOUNTS_EXPORT AccountServiceToggleJob : public KJob { Q_OBJECT Q_PROPERTY(QString accountId READ accountId WRITE setAccountId NOTIFY accountIdChanged) Q_PROPERTY(QString serviceId READ serviceId WRITE setServiceId NOTIFY serviceIdChanged) Q_PROPERTY(bool serviceEnabled READ serviceEnabled WRITE setServiceEnabled NOTIFY serviceEnabledChanged) public: explicit AccountServiceToggleJob(QObject* parent = nullptr); virtual ~AccountServiceToggleJob(); void start() override; QString accountId() const; void setAccountId(const QString& accountId); Q_SIGNAL void accountIdChanged(); QString serviceId() const; void setServiceId(const QString& serviceId); Q_SIGNAL void serviceIdChanged(); bool serviceEnabled() const; void setServiceEnabled(bool serviceEnabled); Q_SIGNAL void serviceEnabledChanged(); private: class Private; Private* d; }; #endif//ACCOUNTSERVICETOGGLE_H diff --git a/src/lib/accountsmodel.cpp b/src/lib/accountsmodel.cpp index 2068cbd..bf0b5fa 100644 --- a/src/lib/accountsmodel.cpp +++ b/src/lib/accountsmodel.cpp @@ -1,207 +1,207 @@ /************************************************************************************* * Copyright (C) 2012 by Alejandro Fiestas Olivares * * Copyright (C) 2020 by Dan Leinir Turthra Jensen * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "accountsmodel.h" #include "core.h" #include "servicesmodel.h" #include #include #include #include #include #include class AccountsModel::Private : public QObject { public: Private(AccountsModel *model) : accountsManager(KAccounts::accountsManager()) , q(model) { accountIDs = accountsManager->accountList(); connect(accountsManager, SIGNAL(accountCreated(Accounts::AccountId)), q, SLOT(accountCreated(Accounts::AccountId))); connect(accountsManager, SIGNAL(accountRemoved(Accounts::AccountId)), q, SLOT(accountRemoved(Accounts::AccountId))); }; virtual ~Private() { qDeleteAll(accounts); }; Accounts::Manager *accountsManager; Accounts::AccountIdList accountIDs; QHash accounts; QHash servicesModels; Accounts::Account* accountById(int id); void removeAccount(Accounts::AccountId accountId); private: AccountsModel* q; }; Accounts::Account* AccountsModel::Private::accountById(int id) { if (accounts.contains(id)) { return accounts.value(id); } Accounts::Account* account = accountsManager->account(id); if (!account) { qDebug() << "\t Failed to get the account from manager"; return nullptr; } connect(account, SIGNAL(displayNameChanged(QString)), q, SLOT(accountUpdated())); accounts[id] = account; return account; } void AccountsModel::Private::removeAccount(Accounts::AccountId accountId) { accountIDs.removeOne(accountId); delete accounts.take(accountId); } AccountsModel::AccountsModel(QObject* parent) : QAbstractListModel(parent) , d(new AccountsModel::Private(this)) { } AccountsModel::~AccountsModel() { delete d; } QHash AccountsModel::roleNames() const { static QHash roles{ {IdRole, "id"}, {ServicesRole, "services"}, {EnabledRole, "enabled"}, {CredentialsIdRole, "credentialsId"}, {DisplayNameRole, "displayName"}, {ProviderNameRole, "providerName"}, {IconNameRole, "iconName"}, {DataObjectRole, "dataObject"} }; return roles; } int AccountsModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } return d->accountIDs.count(); } QVariant AccountsModel::data(const QModelIndex& index, int role) const { QVariant data; if(checkIndex(index)) { Accounts::AccountId accountId = d->accountIDs.value(index.row()); Accounts::Account *account = d->accountById(accountId); if (account) { switch (role) { case IdRole: data.setValue(account->id()); break; case ServicesRole: { ServicesModel* servicesModel{nullptr}; if (d->servicesModels.contains(account)) { servicesModel = d->servicesModels.value(account); } else { // Not parenting to the account itself, so we can avoid it suddenly // disappearing. Just to be on the safe side servicesModel = new ServicesModel(d->accountsManager); servicesModel->setAccount(account); d->servicesModels[account] = servicesModel; } data.setValue(servicesModel); break; } case EnabledRole: data.setValue(account->enabled()); break; case CredentialsIdRole: data.setValue(account->credentialsId()); break; case DisplayNameRole: data.setValue(account->displayName()); break; case ProviderNameRole: data.setValue(account->providerName()); break; case IconNameRole: { - QString iconName{"unknown"}; + QString iconName = QString::fromLatin1("unknown"); if (account->provider().isValid() && !account->provider().iconName().isEmpty()) { iconName = account->provider().iconName(); } data.setValue(iconName); break; } case DataObjectRole: data.setValue(account); break; } } } return data; } void AccountsModel::accountCreated(Accounts::AccountId accountId) { qDebug() << "AccountsModel::accountCreated: " << accountId; int row = d->accountIDs.count(); beginInsertRows(QModelIndex(), row, row); d->accountIDs.insert(row, accountId); endInsertRows(); } void AccountsModel::accountRemoved(Accounts::AccountId accountId) { qDebug() << "AccountsModel::accountRemoved: " << accountId; beginRemoveRows(QModelIndex(), d->accountIDs.indexOf(accountId), d->accountIDs.indexOf(accountId)); d->removeAccount(accountId); endRemoveRows(); } void AccountsModel::accountUpdated() { Accounts::Account *acc = qobject_cast(sender()); Accounts::AccountId accountId = acc->id(); qDebug() << "Account updated: " << accountId; QModelIndex accountIndex = index(d->accountIDs.indexOf(accountId), 0); Q_EMIT dataChanged(accountIndex, accountIndex); } diff --git a/src/jobs/createaccountjob.cpp b/src/lib/createaccountjob.cpp similarity index 94% rename from src/jobs/createaccountjob.cpp rename to src/lib/createaccountjob.cpp index 965d8b0..44e0de6 100644 --- a/src/jobs/createaccountjob.cpp +++ b/src/lib/createaccountjob.cpp @@ -1,240 +1,240 @@ /************************************************************************************* * Copyright (C) 2013 by Alejandro Fiestas Olivares * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "createaccountjob.h" #include "kaccountsuiplugin.h" #include "core.h" #include "uipluginsmanager.h" #include #include #include #include #include #include #include #include CreateAccountJob::CreateAccountJob(QObject* parent) : CreateAccountJob(QString(), parent) { } CreateAccountJob::CreateAccountJob(const QString &providerName, QObject* parent) : KJob(parent) , m_providerName(providerName) , m_manager(new Accounts::Manager(this)) , m_account(nullptr) , m_accInfo(nullptr) , m_identity(nullptr) , m_done(false) { } void CreateAccountJob::start() { qDebug() << m_providerName; QMetaObject::invokeMethod(this, "processSession"); } void CreateAccountJob::processSession() { m_account = m_manager->createAccount(m_providerName); Accounts::Service service; if (m_account->services().size() == 1) { service = m_account->services().at(0); } m_accInfo = new Accounts::AccountService(m_account, service, this); const QString pluginName = m_account->provider().pluginName(); qDebug() << "Looking for plugin" << pluginName; if (!pluginName.isEmpty()) { loadPluginAndShowDialog(pluginName); } else { SignOn::IdentityInfo info; info.setCaption(m_providerName); - info.setAccessControlList(QStringList("*")); + info.setAccessControlList({QStringLiteral("*")}); info.setType(SignOn::IdentityInfo::Application); info.setStoreSecret(true); m_identity = SignOn::Identity::newIdentity(info, this); m_identity->storeCredentials(); connect(m_identity, &SignOn::Identity::info, this, &CreateAccountJob::info); connect(m_identity, &SignOn::Identity::error, [=](const SignOn::Error &err) { qDebug() << "Error storing identity:" << err.message(); }); QVariantMap data = m_accInfo->authData().parameters(); - data.insert("Embedded", false); + data.insert(QStringLiteral("Embedded"), false); SignOn::SessionData sessionData(data); SignOn::AuthSessionP session = m_identity->createSession(m_accInfo->authData().method()); qDebug() << "Starting auth session with" << m_accInfo->authData().method(); connect(session, &SignOn::AuthSession::error, this, &CreateAccountJob::sessionError); connect(session, &SignOn::AuthSession::response, this, &CreateAccountJob::sessionResponse); session->process(sessionData, m_accInfo->authData().mechanism()); } } void CreateAccountJob::loadPluginAndShowDialog(const QString &pluginName) { KAccountsUiPlugin *ui = KAccounts::UiPluginsManager::pluginForName(pluginName); if (!ui) { qDebug() << "Plugin could not be loaded"; pluginError(i18nc("The %1 is for plugin name, eg. Could not load UI plugin", "Could not load %1 plugin, please check your installation", pluginName)); return; } connect(ui, &KAccountsUiPlugin::success, this, &CreateAccountJob::pluginFinished, Qt::UniqueConnection); connect(ui, &KAccountsUiPlugin::error, this, &CreateAccountJob::pluginError, Qt::UniqueConnection); ui->setProviderName(m_providerName); ui->init(KAccountsUiPlugin::NewAccountDialog); } void CreateAccountJob::pluginFinished(const QString &screenName, const QString &secret, const QVariantMap &data) { // Set up the new identity SignOn::IdentityInfo info; info.setStoreSecret(true); info.setUserName(screenName); info.setSecret(secret, true); info.setCaption(m_providerName); info.setAccessControlList(QStringList(QLatin1String("*"))); info.setType(SignOn::IdentityInfo::Application); const auto keys = data.keys(); for (const QString &key : keys) { // If a key with __service/ prefix exists and its value is false, // add it to m_disabledServices which will later be used for disabling // the services contained in that list if (key.startsWith(QLatin1String("__service/")) && !data.value(key).toBool()) { m_disabledServices << key.mid(10); } m_account->setValue(key, data.value(key).toString()); } m_identity = SignOn::Identity::newIdentity(info, this); connect(m_identity, &SignOn::Identity::info, this, &CreateAccountJob::info); m_done = true; connect(m_identity, &SignOn::Identity::credentialsStored, m_identity, &SignOn::Identity::queryInfo); m_identity->storeCredentials(); } void CreateAccountJob::pluginError(const QString &error) { if (error.isEmpty()) { setError(-1); } else { setError(KJob::UserDefinedError); } setErrorText(error); // Delete the dialog emitResult(); } void CreateAccountJob::sessionResponse(const SignOn::SessionData &/*data*/) { qDebug() << "Received session response"; m_done = true; m_identity->queryInfo(); } void CreateAccountJob::info(const SignOn::IdentityInfo &info) { qDebug() << "Info:"; qDebug() << "\tId:" << info.id(); qDebug() << "\tcaption:" << info.caption(); qDebug() << "\towner:" << info.owner(); qDebug() << "\tuserName:" << info.userName(); if (!m_done) { return; } m_account->selectService(); if (m_account->displayName().isEmpty()) { m_account->setDisplayName(info.userName()); } - m_account->setValue("username", info.userName()); + m_account->setValue(QStringLiteral("username"), info.userName()); m_account->setCredentialsId(info.id()); Accounts::AuthData authData = m_accInfo->authData(); - m_account->setValue("auth/mechanism", authData.mechanism()); - m_account->setValue("auth/method", authData.method()); + m_account->setValue(QStringLiteral("auth/mechanism"), authData.mechanism()); + m_account->setValue(QStringLiteral("auth/method"), authData.method()); - QString base("auth/"); + QString base = QStringLiteral("auth/"); base.append(authData.method()); - base.append("/"); + base.append(QLatin1Char('/')); base.append(authData.mechanism()); - base.append("/"); + base.append(QLatin1Char('/')); QVariantMap data = authData.parameters(); QMapIterator i(data); while (i.hasNext()) { i.next(); m_account->setValue(base + i.key(), i.value()); } const Accounts::ServiceList services = m_account->services(); for (const Accounts::Service &service : services) { m_account->selectService(service); m_account->setEnabled(m_disabledServices.contains(service.name()) ? false : true); } m_account->selectService(); m_account->setEnabled(true); m_account->sync(); connect(m_account, &Accounts::Account::synced, this, &CreateAccountJob::emitResult); } void CreateAccountJob::sessionError(const SignOn::Error &signOnError) { if (error()) { // Guard against SignOn sending two error() signals return; } qWarning() << "Error:"; qWarning() << "\t" << signOnError.message(); setError(KJob::UserDefinedError); setErrorText(i18n("There was an error while trying to process the request: %1", signOnError.message())); emitResult(); } void CreateAccountJob::setProviderName(const QString &name) { if (m_providerName != name) { m_providerName = name; Q_EMIT providerNameChanged(); } } diff --git a/src/jobs/createaccountjob.h b/src/lib/createaccountjob.h similarity index 100% rename from src/jobs/createaccountjob.h rename to src/lib/createaccountjob.h diff --git a/src/lib/getcredentialsjob.cpp b/src/lib/getcredentialsjob.cpp index 0997cca..6a6f9c0 100644 --- a/src/lib/getcredentialsjob.cpp +++ b/src/lib/getcredentialsjob.cpp @@ -1,154 +1,154 @@ /************************************************************************************* * Copyright (C) 2013 by Alejandro Fiestas Olivares * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; see the file COPYING.LIB. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * *************************************************************************************/ #include "getcredentialsjob.h" #include "core.h" #include #include #include #include #include #include class GetCredentialsJob::Private { public: Private(GetCredentialsJob *job) { q = job; } QString serviceType; QString authMechanism; QString authMethod; Accounts::AccountId id; QVariantMap authData; Accounts::Manager *manager; SignOn::SessionData sessionData; uint repeatedTries; GetCredentialsJob *q; void getCredentials(); }; void GetCredentialsJob::Private::getCredentials() { Accounts::Account *acc = manager->account(id); if (!acc) { qWarning() << "Unable to find account for id" << id; if (repeatedTries < 3) { qDebug() << "Retrying in 2s"; QTimer::singleShot(2000, q, SLOT(getCredentials())); repeatedTries++; } else { qDebug() << repeatedTries << "ending with error"; q->setError(KJob::UserDefinedError); q->setErrorText(QLatin1String("Could not find account")); q->emitResult(); } return; } Accounts::AccountService *service = new Accounts::AccountService(acc, manager->service(serviceType), q); Accounts::AuthData serviceAuthData = service->authData(); authData = serviceAuthData.parameters(); SignOn::Identity *identity = SignOn::Identity::existingIdentity(acc->credentialsId(), q); if (!identity) { qWarning() << "Unable to find identity for account id" << id; q->setError(KJob::UserDefinedError); q->setErrorText(QLatin1String("Could not find credentials")); q->emitResult(); return; } - authData["AccountUsername"] = acc->value(QLatin1String("username")).toString(); + authData[QStringLiteral("AccountUsername")] = acc->value(QLatin1String("username")).toString(); QPointer authSession = identity->createSession(authMethod.isEmpty() ? serviceAuthData.method() : authMethod); if (!authSession) { qWarning() << "Unable to create auth session for" << authMethod << serviceAuthData.method(); q->setError(KJob::UserDefinedError); q->setErrorText(QLatin1String("Could not create auth session")); q->emitResult(); return; } QObject::connect(authSession.data(), &SignOn::AuthSession::response, [this](const SignOn::SessionData &data) { sessionData = data; q->emitResult(); }); QObject::connect(authSession.data(), &SignOn::AuthSession::error, [this](const SignOn::Error &error) { qDebug() << error.message(); q->setError(KJob::UserDefinedError); q->setErrorText(error.message()); q->emitResult(); }); authSession->process(serviceAuthData.parameters(), authMechanism.isEmpty() ? serviceAuthData.mechanism() : authMechanism); } GetCredentialsJob::GetCredentialsJob(const Accounts::AccountId &id, QObject *parent) : KJob(parent) , d(new Private(this)) { d->id = id; d->manager = KAccounts::accountsManager(); d->repeatedTries = 0; d->serviceType = QString(); } GetCredentialsJob::GetCredentialsJob(const Accounts::AccountId &id, const QString &authMethod, const QString &authMechanism, QObject *parent) : KJob(parent) , d(new Private(this)) { d->id = id; d->manager = KAccounts::accountsManager(); d->authMechanism = authMechanism; d->authMethod = authMethod; d->repeatedTries = 0; d->serviceType = QString(); } void GetCredentialsJob::start() { QMetaObject::invokeMethod(this, "getCredentials", Qt::QueuedConnection); } void GetCredentialsJob::setServiceType(const QString& serviceType) { d->serviceType = serviceType; } Accounts::AccountId GetCredentialsJob::accountId() const { return d->id; } QVariantMap GetCredentialsJob::credentialsData() const { return d->sessionData.toMap().unite(d->authData); } #include "moc_getcredentialsjob.cpp" diff --git a/src/jobs/removeaccountjob.cpp b/src/lib/removeaccountjob.cpp similarity index 100% rename from src/jobs/removeaccountjob.cpp rename to src/lib/removeaccountjob.cpp diff --git a/src/jobs/removeaccountjob.h b/src/lib/removeaccountjob.h similarity index 100% rename from src/jobs/removeaccountjob.h rename to src/lib/removeaccountjob.h diff --git a/src/lib/servicesmodel.cpp b/src/lib/servicesmodel.cpp index d072107..6c83a3e 100644 --- a/src/lib/servicesmodel.cpp +++ b/src/lib/servicesmodel.cpp @@ -1,190 +1,190 @@ /************************************************************************************* * Copyright (C) 2012 by Alejandro Fiestas Olivares * * Copyright (C) 2020 by Dan Leinir Turthra Jensen * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "servicesmodel.h" #include "core.h" #include #include #include #include #include class ServicesModel::Private : public QObject { public: Private(ServicesModel *model) : q(model) { }; virtual ~Private() { }; Accounts::ServiceList services; Accounts::Account* account{nullptr}; private: ServicesModel* q; }; ServicesModel::ServicesModel(QObject* parent) : QAbstractListModel(parent) , d(new ServicesModel::Private(this)) { } ServicesModel::~ServicesModel() { delete d; } QHash ServicesModel::roleNames() const { static QHash roles{ {NameRole, "name"}, {DescriptionRole, "description"}, {DisplayNameRole, "displayName"}, {ServiceTypeRole, "servieType"}, {ProviderNameRole, "providerName"}, {IconNameRole, "iconName"}, {TagsRole, "tags"}, {EnabledRole, "enabled"} }; return roles; } int ServicesModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } return d->services.count(); } QVariant ServicesModel::data(const QModelIndex& index, int role) const { QVariant data; if(checkIndex(index)) { const Accounts::Service& service = d->services.value(index.row()); if (service.isValid()) { switch (role) { case NameRole: data.setValue(service.name()); break; case DescriptionRole: data.setValue(service.description()); break; case DisplayNameRole: data.setValue(service.displayName()); break; case ServiceTypeRole: data.setValue(service.serviceType()); break; case ProviderNameRole: data.setValue(service.provider()); break; case IconNameRole: data.setValue(service.iconName()); break; case TagsRole: data.setValue(service.tags().values()); break; case EnabledRole: data.setValue(d->account->enabledServices().contains(service)); break; } } } return data; } void ServicesModel::setAccount(QObject* account) { if (d->account != account) { beginResetModel(); d->services.clear(); if (d->account) { disconnect(d->account, nullptr, this, nullptr); } d->account = qobject_cast(account); if (d->account) { connect(d->account, &Accounts::Account::enabledChanged, this, [this](const QString& serviceName, bool /*enabled*/){ int i{0}; for (const Accounts::Service& service : d->services) { if (service.name() == serviceName) { break; } ++i; } dataChanged(index(i), index(i)); }); connect(d->account, &QObject::destroyed, this, [this](){ beginResetModel(); d->account = nullptr; Q_EMIT accountChanged(); d->services.clear(); endResetModel(); }); d->services = d->account->services(); } endResetModel(); Q_EMIT accountChanged(); } } QObject * ServicesModel::account() const { return d->account; } quint32 ServicesModel::accountId() const { if (d->account) { return d->account->id(); } return -1; } QString ServicesModel::accountDisplayName() const { if (d->account) { return d->account->displayName(); } return QString{}; } QString ServicesModel::accountProviderName() const { if (d->account) { return d->account->providerName(); } return QString{}; } QString ServicesModel::accountIconName() const { - if (d->account && !d->account->provider().iconName().isEmpty()) { + if (d->account && d->account->provider().isValid() && !d->account->provider().iconName().isEmpty()) { return d->account->provider().iconName(); } - return QString{"unknown"}; + return QString::fromLatin1("unknown"); } diff --git a/src/lib/uipluginsmanager.cpp b/src/lib/uipluginsmanager.cpp index af8d48c..d237944 100644 --- a/src/lib/uipluginsmanager.cpp +++ b/src/lib/uipluginsmanager.cpp @@ -1,146 +1,146 @@ /************************************************************************************* * Copyright (C) 2015 by Martin Klapetek * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "uipluginsmanager.h" #include "kaccountsuiplugin.h" #include #include #include #include #include #include #include #include using namespace KAccounts; class UiPluginsManagerPrivate { public: UiPluginsManagerPrivate(); ~UiPluginsManagerPrivate(); void loadPlugins(); QHash pluginsForNames; QHash pluginsForServices; bool pluginsLoaded; }; Q_GLOBAL_STATIC(UiPluginsManagerPrivate, s_instance) UiPluginsManagerPrivate::UiPluginsManagerPrivate() : pluginsLoaded(false) { } UiPluginsManagerPrivate::~UiPluginsManagerPrivate() { qDeleteAll(pluginsForNames.values()); } void UiPluginsManagerPrivate::loadPlugins() { QString pluginPath; const QStringList paths = QCoreApplication::libraryPaths(); for (const QString &libraryPath : paths) { QString path(libraryPath + QStringLiteral("/kaccounts/ui")); QDir dir(path); if (!dir.exists()) { continue; } const QStringList entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); for (const QString &fileName : entryList) { QPluginLoader loader(dir.absoluteFilePath(fileName)); if (!loader.load()) { qWarning() << "Could not create KAccountsUiPlugin: " << pluginPath; qWarning() << loader.errorString(); continue; } QObject *obj = loader.instance(); if (obj) { KAccountsUiPlugin *ui = qobject_cast(obj); if (!ui) { qDebug() << "Plugin could not be converted to an KAccountsUiPlugin"; qDebug() << pluginPath; continue; } qDebug() << "Adding plugin" << ui << fileName; const QWindowList topLevelWindows = QGuiApplication::topLevelWindows(); if (topLevelWindows.size() == 1) { QWindow *topLevelWindow = topLevelWindows.at(0); obj->setProperty("transientParent", QVariant::fromValue(topLevelWindow)); } else { qWarning() << "Unexpected topLevelWindows found:" << topLevelWindows.size() << "please report a bug"; } // When the plugin has finished building the UI, show it right away QObject::connect(ui, &KAccountsUiPlugin::uiReady, ui, &KAccountsUiPlugin::showNewAccountDialog, Qt::UniqueConnection); pluginsForNames.insert(fileName, ui); const auto services = ui->supportedServicesForConfig(); for (const QString &service : services) { qDebug() << " Adding service" << service; pluginsForServices.insert(service, ui); } } else { qDebug() << "Plugin could not creaate instance" << pluginPath; } } } pluginsLoaded = true; } QList UiPluginsManager::uiPlugins() { if (!s_instance->pluginsLoaded) { s_instance->loadPlugins(); } return s_instance->pluginsForNames.values(); } KAccountsUiPlugin* UiPluginsManager::pluginForName(const QString &name) { if (!s_instance->pluginsLoaded) { s_instance->loadPlugins(); } - return s_instance->pluginsForNames.value(name + ".so"); + return s_instance->pluginsForNames.value(name + QStringLiteral(".so")); } KAccountsUiPlugin* UiPluginsManager::pluginForService(const QString &service) { if (!s_instance->pluginsLoaded) { s_instance->loadPlugins(); } return s_instance->pluginsForServices.value(service); }