1 #include "ItemRegistry.h"
3 #include <QQuickWindow>
4 #include "PluginRegistry.h"
6 Q_LOGGING_CATEGORY(PLUGIN_ITEM_REGISTRY,
"dekko.plugman.itemregistry")
9 m_loadMode(LoadAll), m_asynchronous(true)
13 QQuickItem* ItemRegistry::target()
const
18 QString ItemRegistry::location()
const
23 QQmlListProperty<QQuickItem> ItemRegistry::defaultItems()
25 return QQmlListProperty<QQuickItem>(
this, m_defaultItems);
28 ItemRegistry::LoadMode ItemRegistry::loadMode()
const
33 bool ItemRegistry::asynchronous()
const
35 return m_asynchronous;
38 QString ItemRegistry::findFirstEnabled(
const QString &location)
40 if (location.isEmpty()) {
43 auto plugins = PluginRegistry::instance()->getByLocation(location);
44 if (plugins.isEmpty()) {
47 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Found first enabled plugin";
48 auto firstplugin = qobject_cast<DekkoPlugin *>(plugins.first());
49 return firstplugin->component();
52 void ItemRegistry::setTarget(QQuickItem *target)
54 if (m_target == target)
58 emit targetChanged(target);
62 void ItemRegistry::setLocation(QString location)
64 if (m_location == location)
67 m_location = location;
68 emit locationChanged(location);
72 void ItemRegistry::setLoadMode(ItemRegistry::LoadMode loadMode)
74 if (m_loadMode == loadMode)
77 m_loadMode = loadMode;
78 emit loadModeChanged(loadMode);
81 void ItemRegistry::setAsynchronous(
bool asynchronous)
83 if (m_asynchronous == asynchronous)
86 m_asynchronous = asynchronous;
87 emit asyncChanged(asynchronous);
90 void ItemRegistry::loadIfPossible()
92 if (m_location.isEmpty() || m_target.isNull()) {
96 auto plugins = PluginRegistry::instance()->getByLocation(m_location);
101 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Loading default items only";
102 reparentItemsToTarget(m_defaultItems);
105 case LoadFirstEnabled:
107 if (plugins.isEmpty()) {
108 setLoadMode(DefaultOnly);
112 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Loading first enabled plugin";
113 auto firstplugin = qobject_cast<DekkoPlugin *>(plugins.first());
114 if (m_asynchronous) {
115 createItemAsync(firstplugin->component());
117 QQuickItem *firstItem = createItemFromUrl(firstplugin->component());
118 reparentItemToTarget(firstItem);
122 case LoadLastEnabled:
124 if (plugins.isEmpty()) {
125 setLoadMode(DefaultOnly);
129 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Loading last enabled plugin";
130 auto lastplugin = qobject_cast<DekkoPlugin *>(plugins.last());
131 if (m_asynchronous) {
132 createItemAsync(lastplugin->component());
134 QQuickItem *lastItem = createItemFromUrl(lastplugin->component());
135 reparentItemToTarget(lastItem);
141 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Loading all plugins and default items";
142 reparentItemsToTarget(m_defaultItems);
143 for (
auto plugin : plugins) {
144 if (
auto dp = qobject_cast<DekkoPlugin *>(plugin)) {
145 if (m_asynchronous) {
146 createItemAsync(dp->component());
148 QQuickItem *item = createItemFromUrl(dp->component());
149 reparentItemToTarget(item);
157 if (plugins.isEmpty()) {
158 setLoadMode(DefaultOnly);
162 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Looking for plugin with id: " << m_pluginId;
163 QQuickItem *item = Q_NULLPTR;
164 for (
auto plugin : plugins) {
165 if (plugin->pluginId() == m_pluginId) {
166 if (
auto dp = qobject_cast<DekkoPlugin *>(plugin)) {
167 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Found plugin with id: " << m_pluginId;
168 item = createItemFromUrl(dp->component());
173 reparentItemToTarget(item);
175 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"No plugin found with id: " << m_pluginId;
176 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Falling back to default items";
177 reparentItemsToTarget(m_defaultItems);
184 void ItemRegistry::reparentItemToTarget(QQuickItem *item)
187 item->setParentItem(m_target);
188 item->setVisible(
true);
190 qCWarning(PLUGIN_ITEM_REGISTRY) <<
"Invalid item";
194 void ItemRegistry::reparentItemsToTarget(QList<QQuickItem *> items)
196 for (
auto item : items) {
197 reparentItemToTarget(item);
201 QQuickItem *ItemRegistry::createItemFromUrl(
const QString &itemUrl)
203 if (itemUrl.isEmpty()) {
204 qCWarning(PLUGIN_ITEM_REGISTRY) <<
"Invalid component url";
207 auto engine = qmlEngine(
this);
208 QQmlComponent itemComponent(engine, QUrl::fromLocalFile(itemUrl), m_target);
209 if (itemComponent.isError()) {
210 for (
auto error : itemComponent.errors()) {
211 qCDebug(PLUGIN_ITEM_REGISTRY) <<
"Failed loading plugin with error:";
212 qCDebug(PLUGIN_ITEM_REGISTRY) << error.toString();
217 return qobject_cast<QQuickItem *>(itemComponent.create(engine->contextForObject(
this)));
220 void ItemRegistry::createItemAsync(
const QString &itemUrl)
222 if (itemUrl.isEmpty()) {
223 qCWarning(PLUGIN_ITEM_REGISTRY) <<
"Invalid component url";
227 connect(incubator, &PluginIncubator::objectReady,
this, &ItemRegistry::asyncItemReady);
228 connect(incubator, &PluginIncubator::error,
this, &ItemRegistry::handleIncubatorError);
229 incubator->setSourceUrl(qmlEngine(
this), QUrl::fromLocalFile(itemUrl));
230 m_incubators << incubator;
233 void ItemRegistry::asyncItemReady()
235 PluginIncubator *incubator = qobject_cast<PluginIncubator *>(sender());
236 if (incubator->status() == QQmlIncubator::Ready) {
237 QObject *itemObject = incubator->object();
240 if (itemObject->metaObject()->className() == QByteArrayLiteral(
"QQuickWindowQmlImpl")) {
241 QQuickWindow *window = qobject_cast<QQuickWindow *>(itemObject);
244 QQuickItem *item = qobject_cast<QQuickItem *>(itemObject);
246 reparentItemToTarget(item);
248 qCWarning(PLUGIN_ITEM_REGISTRY) <<
"Failed casting plugin to qquickitem";
249 incubator->deleteLater();
253 incubator->deleteLater();
257 void ItemRegistry::handleIncubatorError()