uipluginsmanager.cpp 5.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*************************************************************************************
 *  Copyright (C) 2015 by Martin Klapetek <mklapetek@kde.org>                        *
 *                                                                                   *
 *  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"

21
#include "kaccountsuiplugin.h"
22 23 24 25 26 27 28

#include <QHash>
#include <QStringList>
#include <QDebug>
#include <QCoreApplication>
#include <QDir>
#include <QPluginLoader>
29 30
#include <QGuiApplication>
#include <QWindow>
31 32 33 34 35 36 37 38 39 40 41

using namespace KAccounts;

class UiPluginsManagerPrivate
{
public:
    UiPluginsManagerPrivate();
    ~UiPluginsManagerPrivate();

    void loadPlugins();

42
    QHash<QString, KAccountsUiPlugin*> pluginsForNames;
43 44 45 46 47
    QHash<QString, KAccountsUiPlugin*> pluginsForServices;
    bool pluginsLoaded;

};

48
Q_GLOBAL_STATIC(UiPluginsManagerPrivate, s_instance)
49 50 51 52 53 54 55 56

UiPluginsManagerPrivate::UiPluginsManagerPrivate()
    : pluginsLoaded(false)
{
}

UiPluginsManagerPrivate::~UiPluginsManagerPrivate()
{
57
    qDeleteAll(pluginsForNames.values());
58 59 60 61 62 63
}

void UiPluginsManagerPrivate::loadPlugins()
{
    QString pluginPath;

Nicolas Fella's avatar
Nicolas Fella committed
64 65
    const QStringList paths = QCoreApplication::libraryPaths();
    for (const QString &libraryPath : paths) {
66 67 68 69 70 71 72
        QString path(libraryPath + QStringLiteral("/kaccounts/ui"));
        QDir dir(path);

        if (!dir.exists()) {
            continue;
        }

Nicolas Fella's avatar
Nicolas Fella committed
73 74
        const QStringList entryList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
        for (const QString &fileName : entryList) {
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
            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<KAccountsUiPlugin*>(obj);
                if (!ui) {
                    qDebug() << "Plugin could not be converted to an KAccountsUiPlugin";
                    qDebug() << pluginPath;
                    continue;
                }

92
                qDebug() << "Adding plugin" << ui << fileName;
93 94 95 96 97 98 99
                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";
                }
100

101 102 103
                // When the plugin has finished building the UI, show it right away
                QObject::connect(ui, &KAccountsUiPlugin::uiReady, ui, &KAccountsUiPlugin::showNewAccountDialog, Qt::UniqueConnection);

104
                pluginsForNames.insert(fileName, ui);
Nicolas Fella's avatar
Nicolas Fella committed
105 106
                const auto services = ui->supportedServicesForConfig();
                for (const QString &service : services) {
107 108 109 110 111 112 113 114 115 116 117 118 119
                    qDebug() << " Adding service" << service;
                    pluginsForServices.insert(service, ui);
                }
            } else {
                qDebug() << "Plugin could not creaate instance" << pluginPath;
            }

        }
    }

    pluginsLoaded = true;
}

120

121 122 123 124 125 126
QList<KAccountsUiPlugin*> UiPluginsManager::uiPlugins()
{
    if (!s_instance->pluginsLoaded) {
        s_instance->loadPlugins();
    }

127 128 129 130 131 132 133 134 135
    return s_instance->pluginsForNames.values();
}

KAccountsUiPlugin* UiPluginsManager::pluginForName(const QString &name)
{
    if (!s_instance->pluginsLoaded) {
        s_instance->loadPlugins();
    }

Nicolas Fella's avatar
Nicolas Fella committed
136
    return s_instance->pluginsForNames.value(name + QStringLiteral(".so"));
137 138 139 140 141 142 143 144 145 146
}

KAccountsUiPlugin* UiPluginsManager::pluginForService(const QString &service)
{
    if (!s_instance->pluginsLoaded) {
        s_instance->loadPlugins();
    }

    return s_instance->pluginsForServices.value(service);
}