1/*
2 * SPDX-FileCopyrightText: 2009 Alan Alpert <alan.alpert@nokia.com>
3 * SPDX-FileCopyrightText: 2010 Ménard Alexis <menard@kde.org>
4 * SPDX-FileCopyrightText: 2010 Marco Martin <mart@kde.org>
5 *
6 * SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8
9#include "kirigamiplugin.h"
10
11#include <QIcon>
12#if defined(Q_OS_ANDROID)
13#include <QResource>
14#endif
15#include <QQmlContext>
16#include <QQuickItem>
17
18#include "platform/styleselector.h"
19
20#ifdef KIRIGAMI_BUILD_TYPE_STATIC
21#include "loggingcategory.h"
22#include <QDebug>
23#endif
24
25// This is required for declarative registration to work on Windows.
26// This is normally generated by Qt but since we need a manually written plugin
27// file, we need to include this ourselves.
28extern void qml_register_types_org_kde_kirigami();
29Q_GHS_KEEP_REFERENCE(qml_register_types_org_kde_kirigami)
30
31// we can't do this in the plugin object directly, as that can live in a different thread
32// and event filters are only allowed in the same thread as the filtered object
33class LanguageChangeEventFilter : public QObject
34{
35 Q_OBJECT
36public:
37 bool eventFilter(QObject *receiver, QEvent *event) override
38 {
39 if (event->type() == QEvent::LanguageChange && receiver == QCoreApplication::instance()) {
40 Q_EMIT languageChangeEvent();
41 }
42 return QObject::eventFilter(watched: receiver, event);
43 }
44
45Q_SIGNALS:
46 void languageChangeEvent();
47};
48
49KirigamiPlugin::KirigamiPlugin(QObject *parent)
50 : QQmlExtensionPlugin(parent)
51{
52 // See above.
53 volatile auto registration = &qml_register_types_org_kde_kirigami;
54 Q_UNUSED(registration)
55
56 auto filter = new LanguageChangeEventFilter;
57 filter->moveToThread(thread: QCoreApplication::instance()->thread());
58 QCoreApplication::instance()->installEventFilter(filterObj: filter);
59 QMetaObject::invokeMethod(
60 object: QCoreApplication::instance(),
61 function: [filter] {
62 filter->setParent(QCoreApplication::instance());
63 },
64 type: Qt::QueuedConnection);
65 connect(sender: filter, signal: &LanguageChangeEventFilter::languageChangeEvent, context: this, slot: &KirigamiPlugin::languageChangeEvent);
66}
67
68QUrl KirigamiPlugin::componentUrl(const QString &fileName) const
69{
70 return Kirigami::Platform::StyleSelector::componentUrl(fileName);
71}
72
73void KirigamiPlugin::registerTypes(const char *uri)
74{
75#if defined(Q_OS_ANDROID)
76 QResource::registerResource(QStringLiteral("assets:/android_rcc_bundle.rcc"));
77#endif
78
79 Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kirigami"));
80
81 Kirigami::Platform::StyleSelector::setBaseUrl(baseUrl());
82
83 if (QIcon::themeName().isEmpty() && !qEnvironmentVariableIsSet(varName: "XDG_CURRENT_DESKTOP")) {
84#if defined(Q_OS_ANDROID)
85 QIcon::setThemeSearchPaths({QStringLiteral("assets:/qml/org/kde/kirigami"), QStringLiteral(":/icons")});
86#else
87 QIcon::setThemeSearchPaths({Kirigami::Platform::StyleSelector::resolveFilePath(QStringLiteral(".")), QStringLiteral(":/icons")});
88#endif
89 QIcon::setThemeName(QStringLiteral("breeze-internal"));
90 } else {
91 QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << Kirigami::Platform::StyleSelector::resolveFilePath(QStringLiteral("icons")));
92 }
93
94 qmlRegisterType(url: componentUrl(QStringLiteral("Action.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "Action");
95 qmlRegisterType(url: componentUrl(QStringLiteral("AbstractApplicationHeader.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "AbstractApplicationHeader");
96 qmlRegisterType(url: componentUrl(QStringLiteral("AbstractApplicationWindow.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "AbstractApplicationWindow");
97 qmlRegisterType(url: componentUrl(QStringLiteral("ApplicationWindow.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "ApplicationWindow");
98 qmlRegisterType(url: componentUrl(QStringLiteral("OverlayDrawer.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "OverlayDrawer");
99 qmlRegisterType(url: componentUrl(QStringLiteral("ContextDrawer.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "ContextDrawer");
100 qmlRegisterType(url: componentUrl(QStringLiteral("GlobalDrawer.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "GlobalDrawer");
101 qmlRegisterType(url: componentUrl(QStringLiteral("Heading.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "Heading");
102 qmlRegisterType(url: componentUrl(QStringLiteral("PageRow.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "PageRow");
103
104 qmlRegisterType(url: componentUrl(QStringLiteral("OverlaySheet.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "OverlaySheet");
105 qmlRegisterType(url: componentUrl(QStringLiteral("Page.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "Page");
106 qmlRegisterType(url: componentUrl(QStringLiteral("ScrollablePage.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "ScrollablePage");
107 qmlRegisterType(url: componentUrl(QStringLiteral("SwipeListItem.qml")), uri, versionMajor: 2, versionMinor: 0, qmlName: "SwipeListItem");
108
109 // 2.1
110 qmlRegisterType(url: componentUrl(QStringLiteral("AbstractApplicationItem.qml")), uri, versionMajor: 2, versionMinor: 1, qmlName: "AbstractApplicationItem");
111 qmlRegisterType(url: componentUrl(QStringLiteral("ApplicationItem.qml")), uri, versionMajor: 2, versionMinor: 1, qmlName: "ApplicationItem");
112
113 // 2.4
114 qmlRegisterType(url: componentUrl(QStringLiteral("AbstractCard.qml")), uri, versionMajor: 2, versionMinor: 4, qmlName: "AbstractCard");
115 qmlRegisterType(url: componentUrl(QStringLiteral("Card.qml")), uri, versionMajor: 2, versionMinor: 4, qmlName: "Card");
116 qmlRegisterType(url: componentUrl(QStringLiteral("CardsListView.qml")), uri, versionMajor: 2, versionMinor: 4, qmlName: "CardsListView");
117 qmlRegisterType(url: componentUrl(QStringLiteral("CardsLayout.qml")), uri, versionMajor: 2, versionMinor: 4, qmlName: "CardsLayout");
118 qmlRegisterType(url: componentUrl(QStringLiteral("InlineMessage.qml")), uri, versionMajor: 2, versionMinor: 4, qmlName: "InlineMessage");
119
120 // 2.5
121 qmlRegisterType(url: componentUrl(QStringLiteral("ListItemDragHandle.qml")), uri, versionMajor: 2, versionMinor: 5, qmlName: "ListItemDragHandle");
122 qmlRegisterType(url: componentUrl(QStringLiteral("ActionToolBar.qml")), uri, versionMajor: 2, versionMinor: 5, qmlName: "ActionToolBar");
123
124 // 2.6
125 qmlRegisterType(url: componentUrl(QStringLiteral("AboutPage.qml")), uri, versionMajor: 2, versionMinor: 6, qmlName: "AboutPage");
126 qmlRegisterType(url: componentUrl(QStringLiteral("LinkButton.qml")), uri, versionMajor: 2, versionMinor: 6, qmlName: "LinkButton");
127 qmlRegisterType(url: componentUrl(QStringLiteral("UrlButton.qml")), uri, versionMajor: 2, versionMinor: 6, qmlName: "UrlButton");
128
129 // 2.7
130 qmlRegisterType(url: componentUrl(QStringLiteral("ActionTextField.qml")), uri, versionMajor: 2, versionMinor: 7, qmlName: "ActionTextField");
131
132 // 2.8
133 qmlRegisterType(url: componentUrl(QStringLiteral("SearchField.qml")), uri, versionMajor: 2, versionMinor: 8, qmlName: "SearchField");
134 qmlRegisterType(url: componentUrl(QStringLiteral("PasswordField.qml")), uri, versionMajor: 2, versionMinor: 8, qmlName: "PasswordField");
135
136 // 2.10
137 qmlRegisterType(url: componentUrl(QStringLiteral("ListSectionHeader.qml")), uri, versionMajor: 2, versionMinor: 10, qmlName: "ListSectionHeader");
138
139 // 2.11
140 qmlRegisterType(url: componentUrl(QStringLiteral("PagePoolAction.qml")), uri, versionMajor: 2, versionMinor: 11, qmlName: "PagePoolAction");
141
142 // 2.12
143 qmlRegisterType(url: componentUrl(QStringLiteral("PlaceholderMessage.qml")), uri, versionMajor: 2, versionMinor: 12, qmlName: "PlaceholderMessage");
144
145 // 2.14
146 qmlRegisterType(url: componentUrl(QStringLiteral("FlexColumn.qml")), uri, versionMajor: 2, versionMinor: 14, qmlName: "FlexColumn");
147
148 // 2.19
149 qmlRegisterType(url: componentUrl(QStringLiteral("AboutItem.qml")), uri, versionMajor: 2, versionMinor: 19, qmlName: "AboutItem");
150 qmlRegisterType(url: componentUrl(QStringLiteral("NavigationTabBar.qml")), uri, versionMajor: 2, versionMinor: 19, qmlName: "NavigationTabBar");
151 qmlRegisterType(url: componentUrl(QStringLiteral("NavigationTabButton.qml")), uri, versionMajor: 2, versionMinor: 19, qmlName: "NavigationTabButton");
152 qmlRegisterType(url: componentUrl(QStringLiteral("Chip.qml")), uri, versionMajor: 2, versionMinor: 19, qmlName: "Chip");
153 qmlRegisterType(url: componentUrl(QStringLiteral("LoadingPlaceholder.qml")), uri, versionMajor: 2, versionMinor: 19, qmlName: "LoadingPlaceholder");
154
155 // 2.20
156 qmlRegisterType(url: componentUrl(QStringLiteral("SelectableLabel.qml")), uri, versionMajor: 2, versionMinor: 20, qmlName: "SelectableLabel");
157 qmlRegisterType(url: componentUrl(QStringLiteral("InlineViewHeader.qml")), uri, versionMajor: 2, versionMinor: 20, qmlName: "InlineViewHeader");
158 qmlRegisterType(url: componentUrl(QStringLiteral("ContextualHelpButton.qml")), uri, versionMajor: 2, versionMinor: 20, qmlName: "ContextualHelpButton");
159}
160
161void KirigamiPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
162{
163 Q_UNUSED(uri);
164 connect(sender: this, signal: &KirigamiPlugin::languageChangeEvent, context: engine, slot: &QQmlEngine::retranslate);
165}
166
167#ifdef KIRIGAMI_BUILD_TYPE_STATIC
168KirigamiPlugin &KirigamiPlugin::getInstance()
169{
170 static KirigamiPlugin instance;
171 return instance;
172}
173
174void KirigamiPlugin::registerTypes(QQmlEngine *engine)
175{
176 if (engine) {
177 engine->addImportPath(QLatin1String(":/"));
178 } else {
179 qCWarning(KirigamiLog)
180 << "Registering Kirigami on a null QQmlEngine instance - you likely want to pass a valid engine, or you will want to manually add the "
181 "qrc root path :/ to your import paths list so the engine is able to load the plugin";
182 }
183}
184#endif
185
186#include "kirigamiplugin.moc"
187#include "moc_kirigamiplugin.cpp"
188

source code of kirigami/src/kirigamiplugin.cpp