Kirigami2

platformpluginfactory.cpp
1/*
2 * SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "platformpluginfactory.h"
8
9#include <QCoreApplication>
10#include <QDebug>
11#include <QDir>
12#include <QPluginLoader>
13#include <QQuickStyle>
14
15#include "kirigamiplatform_logging.h"
16
17namespace Kirigami
18{
19namespace Platform
20{
21
22PlatformPluginFactory::PlatformPluginFactory(QObject *parent)
23 : QObject(parent)
24{
25}
26
27PlatformPluginFactory::~PlatformPluginFactory() = default;
28
29PlatformPluginFactory *PlatformPluginFactory::findPlugin(const QString &preferredName)
30{
32
33 QString pluginName = preferredName.isEmpty() ? QQuickStyle::name() : preferredName;
34 // check for the plugin only once: it's an heavy operation
35 if (auto it = factories.constFind(pluginName); it != factories.constEnd()) {
36 return it.value();
37 }
38
39 // Even plugins that aren't found are in the map, so we know we shouldn't check again withthis expensive operation
40 factories[pluginName] = nullptr;
41
42#ifdef KIRIGAMI_BUILD_TYPE_STATIC
43 for (QObject *staticPlugin : QPluginLoader::staticInstances()) {
44 PlatformPluginFactory *factory = qobject_cast<PlatformPluginFactory *>(staticPlugin);
45 if (factory) {
46 factories[pluginName] = factory;
47 break;
48 }
49 }
50#else
51 const auto libraryPaths = QCoreApplication::libraryPaths();
52 for (const QString &path : libraryPaths) {
53
54#ifdef Q_OS_ANDROID
55 const QDir dir(path);
56#else
57 const QDir dir(path + QStringLiteral("/kf6/kirigami/platform"));
58#endif
59
60 const auto fileNames = dir.entryList(QDir::Files);
61
62 for (const QString &fileName : fileNames) {
63
64#ifdef Q_OS_ANDROID
65 if (fileName.startsWith(QStringLiteral("libplugins_kf6_kirigami_platform_")) && QLibrary::isLibrary(fileName)) {
66#endif
67 if (!pluginName.isEmpty() && fileName.contains(pluginName)) {
68 // TODO: env variable too?
69 QPluginLoader loader(dir.absoluteFilePath(fileName));
70 QObject *plugin = loader.instance();
71 // TODO: load actually a factory as plugin
72
73 qCDebug(KirigamiPlatform) << "Loading style plugin from" << dir.absoluteFilePath(fileName);
74
75 if (auto factory = qobject_cast<PlatformPluginFactory *>(plugin)) {
76 factories[pluginName] = factory;
77 break;
78 }
79 }
80#ifdef Q_OS_ANDROID
81 }
82#endif
83 }
84
85 // Ensure we only load the first plugin from the first plugin location.
86 // If we do not break here, we may end up loading a different plugin
87 // in place of the first one.
88 if (factories.value(pluginName) != nullptr) {
89 break;
90 }
91 }
92#endif
93
94 PlatformPluginFactory *factory = factories.value(pluginName);
95
96 if (factory == nullptr) {
97 qWarning(KirigamiPlatform) << "Failed to find a Kirigami platform plugin for style" << QQuickStyle::name();
98 }
99
100 return factory;
101}
102
103}
104}
105
106#include "moc_platformpluginfactory.cpp"
This class is reimpleented by plugins to provide different implementations of PlatformTheme.
QStringList libraryPaths()
const_iterator constEnd() const const
const_iterator constFind(const Key &key) const const
T value(const Key &key) const const
bool isLibrary(const QString &fileName)
QObject * instance()
QObjectList staticInstances()
QString name()
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:21 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.