File indexing completed on 2024-12-01 13:08:21

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Martin Klapetek <mklapetek@kde.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "uipluginsmanager.h"
0008 
0009 #include "kaccountsuiplugin.h"
0010 
0011 #include <KPluginMetaData>
0012 #include <QCoreApplication>
0013 #include <QDebug>
0014 #include <QDir>
0015 #include <QGuiApplication>
0016 #include <QHash>
0017 #include <QPluginLoader>
0018 #include <QStringList>
0019 #include <QWindow>
0020 
0021 namespace KAccounts
0022 {
0023 
0024 class UiPluginsManagerPrivate
0025 {
0026 public:
0027     UiPluginsManagerPrivate();
0028     ~UiPluginsManagerPrivate();
0029 
0030     void loadPlugins();
0031 
0032     QHash<QString, KAccountsUiPlugin *> pluginsForNames;
0033     QHash<QString, KAccountsUiPlugin *> pluginsForServices;
0034     bool pluginsLoaded;
0035 };
0036 
0037 Q_GLOBAL_STATIC(UiPluginsManagerPrivate, s_instance)
0038 
0039 UiPluginsManagerPrivate::UiPluginsManagerPrivate()
0040     : pluginsLoaded(false)
0041 {
0042 }
0043 
0044 UiPluginsManagerPrivate::~UiPluginsManagerPrivate()
0045 {
0046     qDeleteAll(pluginsForNames.values());
0047 }
0048 
0049 void UiPluginsManagerPrivate::loadPlugins()
0050 {
0051     const auto availablePlugins = KPluginMetaData::findPlugins(QStringLiteral("kaccounts/ui"), {}, KPluginMetaData::AllowEmptyMetaData);
0052     for (const KPluginMetaData &plugin : availablePlugins) {
0053         QPluginLoader loader(plugin.fileName());
0054 
0055         if (!loader.load()) {
0056             qWarning() << "Could not create KAccountsUiPlugin: " << plugin.fileName();
0057             qWarning() << loader.errorString();
0058             continue;
0059         }
0060 
0061         if (QObject *obj = loader.instance()) {
0062             KAccountsUiPlugin *ui = qobject_cast<KAccountsUiPlugin *>(obj);
0063             if (!ui) {
0064                 qDebug() << "Plugin could not be converted to an KAccountsUiPlugin";
0065                 qDebug() << plugin.fileName();
0066                 continue;
0067             }
0068 
0069             qDebug() << "Adding plugin" << ui << plugin.fileName();
0070             const QWindowList topLevelWindows = QGuiApplication::topLevelWindows();
0071             if (topLevelWindows.size() == 1) {
0072                 QWindow *topLevelWindow = topLevelWindows.at(0);
0073                 obj->setProperty("transientParent", QVariant::fromValue(topLevelWindow));
0074             } else {
0075                 qWarning() << "Unexpected topLevelWindows found:" << topLevelWindows.size() << "please report a bug";
0076             }
0077 
0078             // When the plugin has finished building the UI, show it right away
0079             QObject::connect(ui, &KAccountsUiPlugin::uiReady, ui, &KAccountsUiPlugin::showNewAccountDialog, Qt::UniqueConnection);
0080 
0081             pluginsForNames.insert(plugin.pluginId(), ui);
0082             const auto services = ui->supportedServicesForConfig();
0083             for (const QString &service : services) {
0084                 qDebug() << " Adding service" << service;
0085                 pluginsForServices.insert(service, ui);
0086             }
0087         } else {
0088             qDebug() << "Plugin could not create instance" << plugin.fileName();
0089         }
0090     }
0091 
0092     pluginsLoaded = true;
0093 }
0094 
0095 QList<KAccountsUiPlugin *> UiPluginsManager::uiPlugins()
0096 {
0097     if (!s_instance->pluginsLoaded) {
0098         s_instance->loadPlugins();
0099     }
0100 
0101     return s_instance->pluginsForNames.values();
0102 }
0103 
0104 KAccountsUiPlugin *UiPluginsManager::pluginForName(const QString &name)
0105 {
0106     if (!s_instance->pluginsLoaded) {
0107         s_instance->loadPlugins();
0108     }
0109 
0110     return s_instance->pluginsForNames.value(name);
0111 }
0112 
0113 KAccountsUiPlugin *UiPluginsManager::pluginForService(const QString &service)
0114 {
0115     if (!s_instance->pluginsLoaded) {
0116         s_instance->loadPlugins();
0117     }
0118 
0119     return s_instance->pluginsForServices.value(service);
0120 }
0121 
0122 };