Rework our plugin loading code
[trojita.git] / src / Plugins / PluginManager.cpp
blob1689c7e6806537dd523759f0cb6d2b16a1e1078e
1 /* Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
3 This file is part of the Trojita Qt IMAP e-mail client,
4 http://trojita.flaska.net/
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License or (at your option) version 3 or any later version
10 accepted by the membership of KDE e.V. (or its successor approved
11 by the membership of KDE e.V.), which shall act as a proxy
12 defined in Section 14 of version 3 of the license.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <QCoreApplication>
24 #include <QDebug>
25 #include <QDir>
26 #include <QFileInfo>
27 #include <QLibraryInfo>
28 #include <QMap>
29 #include <QPluginLoader>
30 #include <QSettings>
31 #include <QString>
32 #include <QStringList>
34 #include "PluginManager.h"
35 #include "configure.cmake.h"
36 #include "Common/InvokeMethod.h"
37 #include "Plugins/AddressbookPlugin.h"
38 #include "Plugins/PasswordPlugin.h"
39 #include "Plugins/PluginInterface.h"
42 namespace Plugins {
44 PluginManager::PluginManager(QObject *parent, QSettings *settings, const QString &addressbookKey, const QString &passwordKey) : QObject(parent),
45 m_settings(settings), m_addressbookKey(addressbookKey), m_passwordKey(passwordKey)
47 m_addressbookName = m_settings->value(m_addressbookKey, QLatin1String("abookaddressbook")).toString();
48 m_passwordName = m_settings->value(m_passwordKey, QLatin1String("cleartextpassword")).toString();
49 CALL_LATER_NOARG(this, loadPlugins)
52 void PluginManager::loadPlugins()
54 QStringList pluginDirs;
55 pluginDirs << qApp->applicationDirPath();
57 auto pluginDir = QStringLiteral(PLUGIN_DIR);
58 if (!pluginDirs.contains(pluginDir))
59 pluginDirs << pluginDir;
61 #ifdef PLUGIN_DEBUG
62 qDebug() << "Number of static linked plugins:" << QPluginLoader::staticInstances().size();
63 #endif
65 #ifdef PLUGIN_DEBUG
66 qDebug() << "Searching for plugins in:" << pluginDirs;
67 #endif
69 QStringList absoluteFilePaths;
71 Q_FOREACH(const QString &dirName, pluginDirs) {
72 QDir dir(dirName);
73 Q_FOREACH(const QString &fileName, dir.entryList(QStringList() << QLatin1String("trojita_plugin_*"), QDir::Files)) {
74 const QString &absoluteFilePath = QFileInfo(dir.absoluteFilePath(fileName)).canonicalFilePath();
75 if (absoluteFilePaths.contains(absoluteFilePath)) {
76 continue;
78 absoluteFilePaths << absoluteFilePath;
79 if (!QLibrary::isLibrary(absoluteFilePath)) {
80 continue;
82 #ifdef PLUGIN_DEBUG
83 qDebug() << "Opening file" << absoluteFilePath;
84 #endif
85 QPluginLoader *loader = new QPluginLoader(absoluteFilePath, this);
86 loadPlugin(loader->instance(), loader);
90 Q_FOREACH(QObject *pluginInstance, QPluginLoader::staticInstances()) {
91 loadPlugin(pluginInstance, nullptr);
94 emit pluginsChanged();
97 PluginManager::~PluginManager()
101 void PluginManager::loadPlugin(QObject *pluginInstance, QPluginLoader *loader)
103 Q_ASSERT(pluginInstance);
105 if (auto abookPlugin = qobject_cast<AddressbookPluginInterface *>(pluginInstance)) {
106 const QString &name = abookPlugin->name();
107 Q_ASSERT(!name.isEmpty());
108 Q_ASSERT(!m_availableAddressbookPlugins.contains(name));
109 m_availableAddressbookPlugins[name] = abookPlugin;
110 #ifdef PLUGIN_DEBUG
111 qDebug() << "Found addressbook plugin" << name << ":" << abookPlugin->description();
112 #endif
113 if (name == m_addressbookName) {
114 #ifdef PLUGIN_DEBUG
115 qDebug() << "Will activate new default plugin" << name;
116 #endif
117 setAddressbookPlugin(name);
121 if (auto passwordPlugin = qobject_cast<PasswordPluginInterface *>(pluginInstance)) {
122 const QString &name = passwordPlugin->name();
123 Q_ASSERT(!name.isEmpty());
124 Q_ASSERT(!m_availablePasswordPlugins.contains(name));
125 m_availablePasswordPlugins[name] = passwordPlugin;
126 #ifdef PLUGIN_DEBUG
127 qDebug() << "Found password plugin" << name << ":" << passwordPlugin->description();
128 #endif
129 if (name == m_passwordName) {
130 #ifdef PLUGIN_DEBUG
131 qDebug() << "Will activate new default plugin" << name;
132 #endif
133 setPasswordPlugin(name);
138 QMap<QString, QString> PluginManager::availableAddressbookPlugins() const
140 QMap<QString, QString> res;
141 for (auto plugin: m_availableAddressbookPlugins) {
142 res[plugin->name()] = plugin->description();
144 return res;
147 QMap<QString, QString> PluginManager::availablePasswordPlugins() const
149 QMap<QString, QString> res;
150 for (auto plugin: m_availablePasswordPlugins) {
151 res[plugin->name()] = plugin->description();
153 return res;
156 QString PluginManager::addressbookPlugin() const
158 return m_addressbookName;
161 QString PluginManager::passwordPlugin() const
163 return m_passwordName;
166 void PluginManager::setAddressbookPlugin(const QString &name)
168 m_addressbookName = name;
169 m_settings->setValue(m_addressbookKey, name);
171 if (m_addressbook) {
172 delete m_addressbook;
175 auto plugin = m_availableAddressbookPlugins.find(name);
176 if (plugin != m_availableAddressbookPlugins.end()) {
177 #ifdef PLUGIN_DEBUG
178 qDebug() << "Setting new address book plugin:" << (*plugin)->name();
179 #endif
180 m_addressbook = (*plugin)->create(this, m_settings);
183 emit pluginsChanged();
186 void PluginManager::setPasswordPlugin(const QString &name)
188 m_passwordName = name;
189 m_settings->setValue(m_passwordKey, name);
191 if (m_password) {
192 delete m_password;
195 auto plugin = m_availablePasswordPlugins.find(name);
196 if (plugin != m_availablePasswordPlugins.end()) {
197 #ifdef PLUGIN_DEBUG
198 qDebug() << "Setting new password plugin:" << (*plugin)->name();
199 #endif
200 m_password = (*plugin)->create(this, m_settings);
203 emit pluginsChanged();
206 Plugins::AddressbookPlugin *PluginManager::addressbook() const
208 return m_addressbook;
211 Plugins::PasswordPlugin *PluginManager::password() const
213 return m_password;
216 } //namespace Common
218 // vim: set et ts=4 sts=4 sw=4