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. |
28 | extern void qml_register_types_org_kde_kirigami(); |
29 | Q_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 |
33 | class LanguageChangeEventFilter : public QObject |
34 | { |
35 | Q_OBJECT |
36 | public: |
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 | |
45 | Q_SIGNALS: |
46 | void languageChangeEvent(); |
47 | }; |
48 | |
49 | KirigamiPlugin::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 | connect(sender: filter, signal: &LanguageChangeEventFilter::languageChangeEvent, context: this, slot: &KirigamiPlugin::languageChangeEvent); |
60 | } |
61 | |
62 | QUrl KirigamiPlugin::componentUrl(const QString &fileName) const |
63 | { |
64 | return Kirigami::Platform::StyleSelector::componentUrl(fileName); |
65 | } |
66 | |
67 | void KirigamiPlugin::registerTypes(const char *uri) |
68 | { |
69 | #if defined(Q_OS_ANDROID) |
70 | QResource::registerResource(QStringLiteral("assets:/android_rcc_bundle.rcc" )); |
71 | #endif |
72 | |
73 | Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kirigami" )); |
74 | |
75 | Kirigami::Platform::StyleSelector::setBaseUrl(baseUrl()); |
76 | |
77 | if (QIcon::themeName().isEmpty() && !qEnvironmentVariableIsSet(varName: "XDG_CURRENT_DESKTOP" )) { |
78 | #if defined(Q_OS_ANDROID) |
79 | QIcon::setThemeSearchPaths({QStringLiteral("assets:/qml/org/kde/kirigami" ), QStringLiteral(":/icons" )}); |
80 | #else |
81 | QIcon::setThemeSearchPaths({Kirigami::Platform::StyleSelector::resolveFilePath(QStringLiteral("." )), QStringLiteral(":/icons" )}); |
82 | #endif |
83 | QIcon::setThemeName(QStringLiteral("breeze-internal" )); |
84 | } else { |
85 | QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << Kirigami::Platform::StyleSelector::resolveFilePath(QStringLiteral("icons" ))); |
86 | } |
87 | |
88 | qmlRegisterType(url: componentUrl(QStringLiteral("Action.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "Action" ); |
89 | qmlRegisterType(url: componentUrl(QStringLiteral("AbstractApplicationHeader.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "AbstractApplicationHeader" ); |
90 | qmlRegisterType(url: componentUrl(QStringLiteral("AbstractApplicationWindow.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "AbstractApplicationWindow" ); |
91 | qmlRegisterType(url: componentUrl(QStringLiteral("ApplicationWindow.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "ApplicationWindow" ); |
92 | qmlRegisterType(url: componentUrl(QStringLiteral("OverlayDrawer.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "OverlayDrawer" ); |
93 | qmlRegisterType(url: componentUrl(QStringLiteral("ContextDrawer.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "ContextDrawer" ); |
94 | qmlRegisterType(url: componentUrl(QStringLiteral("GlobalDrawer.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "GlobalDrawer" ); |
95 | qmlRegisterType(url: componentUrl(QStringLiteral("Heading.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "Heading" ); |
96 | qmlRegisterType(url: componentUrl(QStringLiteral("Separator.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "Separator" ); |
97 | qmlRegisterType(url: componentUrl(QStringLiteral("PageRow.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "PageRow" ); |
98 | |
99 | qmlRegisterType(url: componentUrl(QStringLiteral("OverlaySheet.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "OverlaySheet" ); |
100 | qmlRegisterType(url: componentUrl(QStringLiteral("Page.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "Page" ); |
101 | qmlRegisterType(url: componentUrl(QStringLiteral("ScrollablePage.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "ScrollablePage" ); |
102 | qmlRegisterType(url: componentUrl(QStringLiteral("SwipeListItem.qml" )), uri, versionMajor: 2, versionMinor: 0, qmlName: "SwipeListItem" ); |
103 | |
104 | // 2.1 |
105 | qmlRegisterType(url: componentUrl(QStringLiteral("AbstractApplicationItem.qml" )), uri, versionMajor: 2, versionMinor: 1, qmlName: "AbstractApplicationItem" ); |
106 | qmlRegisterType(url: componentUrl(QStringLiteral("ApplicationItem.qml" )), uri, versionMajor: 2, versionMinor: 1, qmlName: "ApplicationItem" ); |
107 | |
108 | // 2.3 |
109 | qmlRegisterType(url: componentUrl(QStringLiteral("FormLayout.qml" )), uri, versionMajor: 2, versionMinor: 3, qmlName: "FormLayout" ); |
110 | |
111 | // 2.4 |
112 | qmlRegisterType(url: componentUrl(QStringLiteral("AbstractCard.qml" )), uri, versionMajor: 2, versionMinor: 4, qmlName: "AbstractCard" ); |
113 | qmlRegisterType(url: componentUrl(QStringLiteral("Card.qml" )), uri, versionMajor: 2, versionMinor: 4, qmlName: "Card" ); |
114 | qmlRegisterType(url: componentUrl(QStringLiteral("CardsListView.qml" )), uri, versionMajor: 2, versionMinor: 4, qmlName: "CardsListView" ); |
115 | qmlRegisterType(url: componentUrl(QStringLiteral("CardsLayout.qml" )), uri, versionMajor: 2, versionMinor: 4, qmlName: "CardsLayout" ); |
116 | qmlRegisterType(url: componentUrl(QStringLiteral("InlineMessage.qml" )), uri, versionMajor: 2, versionMinor: 4, qmlName: "InlineMessage" ); |
117 | |
118 | // 2.5 |
119 | qmlRegisterType(url: componentUrl(QStringLiteral("ListItemDragHandle.qml" )), uri, versionMajor: 2, versionMinor: 5, qmlName: "ListItemDragHandle" ); |
120 | qmlRegisterType(url: componentUrl(QStringLiteral("ActionToolBar.qml" )), uri, versionMajor: 2, versionMinor: 5, qmlName: "ActionToolBar" ); |
121 | |
122 | // 2.6 |
123 | qmlRegisterType(url: componentUrl(QStringLiteral("AboutPage.qml" )), uri, versionMajor: 2, versionMinor: 6, qmlName: "AboutPage" ); |
124 | qmlRegisterType(url: componentUrl(QStringLiteral("LinkButton.qml" )), uri, versionMajor: 2, versionMinor: 6, qmlName: "LinkButton" ); |
125 | qmlRegisterType(url: componentUrl(QStringLiteral("UrlButton.qml" )), uri, versionMajor: 2, versionMinor: 6, qmlName: "UrlButton" ); |
126 | |
127 | // 2.7 |
128 | qmlRegisterType(url: componentUrl(QStringLiteral("ActionTextField.qml" )), uri, versionMajor: 2, versionMinor: 7, qmlName: "ActionTextField" ); |
129 | |
130 | // 2.8 |
131 | qmlRegisterType(url: componentUrl(QStringLiteral("SearchField.qml" )), uri, versionMajor: 2, versionMinor: 8, qmlName: "SearchField" ); |
132 | qmlRegisterType(url: componentUrl(QStringLiteral("PasswordField.qml" )), uri, versionMajor: 2, versionMinor: 8, qmlName: "PasswordField" ); |
133 | |
134 | // 2.10 |
135 | qmlRegisterType(url: componentUrl(QStringLiteral("ListSectionHeader.qml" )), uri, versionMajor: 2, versionMinor: 10, qmlName: "ListSectionHeader" ); |
136 | |
137 | // 2.11 |
138 | qmlRegisterType(url: componentUrl(QStringLiteral("PagePoolAction.qml" )), uri, versionMajor: 2, versionMinor: 11, qmlName: "PagePoolAction" ); |
139 | |
140 | // 2.12 |
141 | qmlRegisterType(url: componentUrl(QStringLiteral("ShadowedImage.qml" )), uri, versionMajor: 2, versionMinor: 12, qmlName: "ShadowedImage" ); |
142 | qmlRegisterType(url: componentUrl(QStringLiteral("PlaceholderMessage.qml" )), uri, versionMajor: 2, versionMinor: 12, qmlName: "PlaceholderMessage" ); |
143 | |
144 | // 2.14 |
145 | qmlRegisterType(url: componentUrl(QStringLiteral("FlexColumn.qml" )), uri, versionMajor: 2, versionMinor: 14, qmlName: "FlexColumn" ); |
146 | |
147 | // 2.19 |
148 | qmlRegisterType(url: componentUrl(QStringLiteral("AboutItem.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "AboutItem" ); |
149 | qmlRegisterType(url: componentUrl(QStringLiteral("NavigationTabBar.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "NavigationTabBar" ); |
150 | qmlRegisterType(url: componentUrl(QStringLiteral("NavigationTabButton.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "NavigationTabButton" ); |
151 | qmlRegisterType(url: componentUrl(QStringLiteral("Dialog.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "Dialog" ); |
152 | qmlRegisterType(url: componentUrl(QStringLiteral("MenuDialog.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "MenuDialog" ); |
153 | qmlRegisterType(url: componentUrl(QStringLiteral("PromptDialog.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "PromptDialog" ); |
154 | qmlRegisterType(url: componentUrl(QStringLiteral("Chip.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "Chip" ); |
155 | qmlRegisterType(url: componentUrl(QStringLiteral("LoadingPlaceholder.qml" )), uri, versionMajor: 2, versionMinor: 19, qmlName: "LoadingPlaceholder" ); |
156 | |
157 | // 2.20 |
158 | qmlRegisterType(url: componentUrl(QStringLiteral("SelectableLabel.qml" )), uri, versionMajor: 2, versionMinor: 20, qmlName: "SelectableLabel" ); |
159 | qmlRegisterType(url: componentUrl(QStringLiteral("InlineViewHeader.qml" )), uri, versionMajor: 2, versionMinor: 20, qmlName: "InlineViewHeader" ); |
160 | qmlRegisterType(url: componentUrl(QStringLiteral("ContextualHelpButton.qml" )), uri, versionMajor: 2, versionMinor: 20, qmlName: "ContextualHelpButton" ); |
161 | } |
162 | |
163 | void KirigamiPlugin::initializeEngine(QQmlEngine *engine, const char *uri) |
164 | { |
165 | Q_UNUSED(uri); |
166 | connect(sender: this, signal: &KirigamiPlugin::languageChangeEvent, context: engine, slot: &QQmlEngine::retranslate); |
167 | } |
168 | |
169 | #ifdef KIRIGAMI_BUILD_TYPE_STATIC |
170 | KirigamiPlugin &KirigamiPlugin::getInstance() |
171 | { |
172 | static KirigamiPlugin instance; |
173 | return instance; |
174 | } |
175 | |
176 | void KirigamiPlugin::registerTypes(QQmlEngine *engine) |
177 | { |
178 | if (engine) { |
179 | engine->addImportPath(QLatin1String(":/" )); |
180 | } else { |
181 | qCWarning(KirigamiLog) |
182 | << "Registering Kirigami on a null QQmlEngine instance - you likely want to pass a valid engine, or you will want to manually add the " |
183 | "qrc root path :/ to your import paths list so the engine is able to load the plugin" ; |
184 | } |
185 | } |
186 | #endif |
187 | |
188 | #include "kirigamiplugin.moc" |
189 | #include "moc_kirigamiplugin.cpp" |
190 | |