1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KPARTS_PARTLOADER_H
9#define KPARTS_PARTLOADER_H
10
11#include <KPluginFactory>
12#include <KPluginMetaData>
13#include <QList>
14#include <QObject>
15#include <kparts/kparts_export.h>
16
17namespace KParts
18{
19Q_NAMESPACE_EXPORT(KPARTS_EXPORT)
20
21/*!
22 * Enum for standardized capabilities of KParts
23 *
24 * \code
25 * {
26 * "KPlugin": {...},
27 * "KParts": {
28 * "Capabilities": [
29 * "ReadOnly"
30 * ],
31 * "InitialPreference": 42
32 * }
33 * }
34 * \endcode
35 *
36 * \value ReadOnly
37 * \value ReadWrite
38 * \value BrowserView
39 */
40enum class PartCapability {
41 ReadOnly = 1,
42 ReadWrite = 2,
43 BrowserView = 4,
44};
45Q_ENUM_NS(PartCapability)
46Q_DECLARE_FLAGS(PartCapabilities, PartCapability)
47Q_FLAG_NS(PartCapabilities)
48Q_DECLARE_OPERATORS_FOR_FLAGS(PartCapabilities)
49
50/*!
51 * \namespace KParts::PartLoader
52 * \inheaderfile KParts/PartLoader
53 * \inmodule KParts
54 *
55 * \brief Helper methods for locating and loading parts.
56 *
57 * This is based upon KPluginFactory, but it takes
58 * care of querying by mimetype, sorting the available parts by builtin
59 * preference and by user preference.
60 * \since KParts 5.69
61 */
62namespace PartLoader
63{
64namespace Private
65{
66
67enum ErrorType {
68 CouldNotLoadPlugin,
69 NoPartFoundForMimeType,
70 NoPartInstantiatedForMimeType,
71};
72
73/*!
74 * \internal
75 * \a errorString translated, user-visible error string
76 * \a errorText untranslated error text
77 * \a argument argument for the text
78 */
79KPARTS_EXPORT void getErrorStrings(QString *errorString, QString *errorText, const QString &argument, ErrorType type);
80
81}
82
83/*!
84 * Parses the associated capabilities from the KPart. This parses the deprecated "ServiceTypes" array of the "KPlugin" object
85 *
86 * \since KParts 6.4
87 */
88KPARTS_EXPORT PartCapabilities partCapabilities(const KPluginMetaData &data);
89
90/*!
91 * Locate all available KParts using KPluginMetaData::findPlugins for a mimetype.
92 * Returns a list of plugin metadata, sorted by preference.
93 * This takes care both of the builtin preference (set by developers)
94 * and of user preference (stored in mimeapps.list).
95 *
96 * To load a part from one of the KPluginMetaData instances returned here,
97 * use instantiatePart()
98 *
99 * \since 5.69
100 */
101KPARTS_EXPORT QList<KPluginMetaData> partsForMimeType(const QString &mimeType);
102
103/*!
104 * Attempts to create a KPart from the given metadata.
105 *
106 * \code
107 * if (auto result = KParts::PartLoader::instantiatePart<MyPart>(metaData, parentWidget, parent, args)) {
108 * // result.plugin is valid and can be accessed
109 * } else {
110 * // result contains information about the error
111 * }
112 * \endcode
113 *
114 * \a data KPluginMetaData from which the plugin should be loaded
115 *
116 * \a parentWidget The parent widget
117 *
118 * \a parent The parent object
119 *
120 * \a args A list of arguments to be passed to the part
121 *
122 * Returns a Result object which contains the plugin instance and potentially error information
123 *
124 * \since 5.100
125 */
126template<typename T>
127static KPluginFactory::Result<T>
128instantiatePart(const KPluginMetaData &data, QWidget *parentWidget = nullptr, QObject *parent = nullptr, const QVariantList &args = {})
129{
130 KPluginFactory::Result<T> result;
131 KPluginFactory::Result<KPluginFactory> factoryResult = KPluginFactory::loadFactory(data);
132 if (!factoryResult.plugin) {
133 result.errorString = factoryResult.errorString;
134 result.errorReason = factoryResult.errorReason;
135 return result;
136 }
137 T *instance = factoryResult.plugin->create<T>(parentWidget, parent, args);
138 if (!instance) {
139 const QString fileName = data.fileName();
140 Private::getErrorStrings(errorString: &result.errorString, errorText: &result.errorText, argument: fileName, type: Private::CouldNotLoadPlugin);
141 result.errorReason = KPluginFactory::INVALID_KPLUGINFACTORY_INSTANTIATION;
142 } else {
143 result.plugin = instance;
144 }
145 return result;
146}
147
148/*!
149 * Use this method to create a KParts part. It will try to create an object which inherits
150 * \a T.
151 *
152 * \code
153 * if (auto result = KParts::PartLoader::instantiatePartForMimeType<KParts::ReadOnlyPart>(mimeType, parentWidget, parent, args)) {
154 * // result.plugin is valid and can be accessed
155 * } else {
156 * // result contains information about the error
157 * }
158 * \endcode
159 *
160 * \a T The interface for which an object should be created. The object will inherit \a T.
161 *
162 * \a mimeType The mimetype for which we need a KParts.
163 *
164 * \a parentWidget The parent widget for the part's widget.
165 *
166 * \a parent The parent of the part.
167 *
168 * Returns a Result object which contains the plugin instance and potentially error information
169 *
170 * \since 5.100
171 */
172template<class T>
173static KPluginFactory::Result<T>
174instantiatePartForMimeType(const QString &mimeType, QWidget *parentWidget = nullptr, QObject *parent = nullptr, const QVariantList &args = {})
175{
176 const QList<KPluginMetaData> plugins = KParts::PartLoader::partsForMimeType(mimeType);
177 if (plugins.isEmpty()) {
178 KPluginFactory::Result<T> errorResult;
179 errorResult.errorReason = KPluginFactory::ResultErrorReason::INVALID_PLUGIN;
180 Private::getErrorStrings(errorString: &errorResult.errorString, errorText: &errorResult.errorText, argument: mimeType, type: Private::NoPartFoundForMimeType);
181
182 return errorResult;
183 }
184
185 for (const KPluginMetaData &plugin : plugins) {
186 if (const auto result = instantiatePart<T>(plugin, parentWidget, parent, args)) {
187 return result;
188 }
189 }
190
191 KPluginFactory::Result<T> errorResult;
192 errorResult.errorReason = KPluginFactory::ResultErrorReason::INVALID_PLUGIN;
193 Private::getErrorStrings(errorString: &errorResult.errorString, errorText: &errorResult.errorText, argument: mimeType, type: Private::NoPartInstantiatedForMimeType);
194
195 return errorResult;
196}
197
198} // namespace
199} // namespace
200
201Q_DECLARE_METATYPE(KParts::PartCapabilities)
202
203#endif
204

source code of kparts/src/partloader.h