/* * SPDX-FileCopyrightText: 2017 Marco Martin * * SPDX-License-Identifier: LGPL-2.0-or-later */ #include "platformpluginfactory.h" #include #include #include #include #include #include "kirigamiplatform_logging.h" namespace Kirigami { namespace Platform { PlatformPluginFactory::PlatformPluginFactory(QObject *parent) : QObject(parent) { } PlatformPluginFactory::~PlatformPluginFactory() = default; PlatformPluginFactory *PlatformPluginFactory::findPlugin(const QString &preferredName) { static QHash factories = QHash(); QString pluginName = preferredName.isEmpty() ? QQuickStyle::name() : preferredName; // check for the plugin only once: it's an heavy operation if (auto it = factories.constFind(pluginName); it != factories.constEnd()) { return it.value(); } // Even plugins that aren't found are in the map, so we know we shouldn't check again withthis expensive operation factories[pluginName] = nullptr; #ifdef KIRIGAMI_BUILD_TYPE_STATIC for (QObject *staticPlugin : QPluginLoader::staticInstances()) { PlatformPluginFactory *factory = qobject_cast(staticPlugin); if (factory) { factories[pluginName] = factory; break; } } #else const auto libraryPaths = QCoreApplication::libraryPaths(); for (const QString &path : libraryPaths) { #ifdef Q_OS_ANDROID const QDir dir(path); #else const QDir dir(path + QStringLiteral("/kf6/kirigami/platform")); #endif const auto fileNames = dir.entryList(QDir::Files); for (const QString &fileName : fileNames) { #ifdef Q_OS_ANDROID if (fileName.startsWith(QStringLiteral("libplugins_kf6_kirigami_platform_")) && QLibrary::isLibrary(fileName)) { #endif if (!pluginName.isEmpty() && fileName.contains(pluginName)) { // TODO: env variable too? QPluginLoader loader(dir.absoluteFilePath(fileName)); QObject *plugin = loader.instance(); // TODO: load actually a factory as plugin qCDebug(KirigamiPlatform) << "Loading style plugin from" << dir.absoluteFilePath(fileName); if (auto factory = qobject_cast(plugin)) { factories[pluginName] = factory; break; } } #ifdef Q_OS_ANDROID } #endif } // Ensure we only load the first plugin from the first plugin location. // If we do not break here, we may end up loading a different plugin // in place of the first one. if (factories.value(pluginName) != nullptr) { break; } } #endif PlatformPluginFactory *factory = factories.value(pluginName); if (factory == nullptr) { qWarning(KirigamiPlatform) << "Failed to find a Kirigami platform plugin for style" << QQuickStyle::name(); } return factory; } } } #include "moc_platformpluginfactory.cpp"