Kirigami2

kirigamiplugin.cpp
1 /*
2  * SPDX-FileCopyrightText: 2009 Alan Alpert <[email protected]>
3  * SPDX-FileCopyrightText: 2010 Ménard Alexis <[email protected]>
4  * SPDX-FileCopyrightText: 2010 Marco Martin <[email protected]>
5  *
6  * SPDX-License-Identifier: LGPL-2.0-or-later
7  */
8 
9 #include "kirigamiplugin.h"
10 #include "avatar.h"
11 #include "colorutils.h"
12 #include "columnview.h"
13 #include "delegaterecycler.h"
14 #include "enums.h"
15 #include "formlayoutattached.h"
16 #include "icon.h"
17 #include "imagecolors.h"
18 #include "inputmethod.h"
19 #include "mnemonicattached.h"
20 #include "pagepool.h"
21 #include "pagerouter.h"
22 #include "scenepositionattached.h"
23 #include "settings.h"
24 #include "shadowedrectangle.h"
25 #include "shadowedtexture.h"
26 #include "sizegroup.h"
27 #include "spellcheckinghint.h"
28 #include "toolbarlayout.h"
29 #include "units.h"
30 #include "wheelhandler.h"
31 
32 #include <QClipboard>
33 #include <QGuiApplication>
34 #include <QQmlContext>
35 #include <QQuickItem>
36 #include <QQuickStyle>
37 
38 #include "libkirigami/basictheme_p.h"
39 #include "libkirigami/platformtheme.h"
40 #include "libkirigami/styleselector_p.h"
41 #include "loggingcategory.h"
42 #include "libkirigami/basictheme_p.h"
43 #include "libkirigami/kirigamipluginfactory.h"
44 
45 static QString s_selectedStyle;
46 
47 #ifdef KIRIGAMI_BUILD_TYPE_STATIC
48 #include "loggingcategory.h"
49 #include <QDebug>
50 #endif
51 
52 class CopyHelperPrivate : public QObject
53 {
54  Q_OBJECT
55 public:
56  Q_INVOKABLE static void copyTextToClipboard(const QString &text)
57  {
58  qGuiApp->clipboard()->setText(text);
59  }
60 };
61 
62 // we can't do this in the plugin object directly, as that can live in a different thread
63 // and event filters are only allowed in the same thread as the filtered object
64 class LanguageChangeEventFilter : public QObject
65 {
66  Q_OBJECT
67 public:
68  bool eventFilter(QObject *receiver, QEvent *event) override
69  {
70  if (event->type() == QEvent::LanguageChange && receiver == QCoreApplication::instance()) {
71  Q_EMIT languageChangeEvent();
72  }
73  return QObject::eventFilter(receiver, event);
74  }
75 
76 Q_SIGNALS:
77  void languageChangeEvent();
78 };
79 
80 KirigamiPlugin::KirigamiPlugin(QObject *parent)
81  : QQmlExtensionPlugin(parent)
82 {
83  auto filter = new LanguageChangeEventFilter;
84  filter->moveToThread(QCoreApplication::instance()->thread());
86  connect(filter, &LanguageChangeEventFilter::languageChangeEvent, this, &KirigamiPlugin::languageChangeEvent);
87 }
88 
89 QUrl KirigamiPlugin::componentUrl(const QString &fileName) const
90 {
91  return Kirigami::StyleSelector::componentUrl(fileName);
92 }
93 
94 using SingletonCreationFunction = QObject *(*)(QQmlEngine *, QJSEngine *);
95 
96 template<class T>
97 inline SingletonCreationFunction singleton()
98 {
99  static_assert(std::is_base_of<QObject, T>::value);
100  return [](QQmlEngine *engine, QJSEngine *) -> QObject * {
101  auto x = new T;
102  x->setParent(engine);
103  return x;
104  };
105 }
106 
107 void KirigamiPlugin::registerTypes(const char *uri)
108 {
109 #if defined(Q_OS_ANDROID)
110  QResource::registerResource(QStringLiteral("assets:/android_rcc_bundle.rcc"));
111 #endif
112 
113  Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kirigami"));
114 
115  Kirigami::StyleSelector::setBaseUrl(baseUrl());
116 
117  if (QIcon::themeName().isEmpty() && !qEnvironmentVariableIsSet("XDG_CURRENT_DESKTOP")) {
118  QIcon::setThemeSearchPaths({Kirigami::StyleSelector::resolveFilePath(QStringLiteral(".")), QStringLiteral(":/icons")});
119  QIcon::setThemeName(QStringLiteral("breeze-internal"));
120  }
121 
122  qmlRegisterSingletonType<Settings>(uri, 2, 0, "Settings", [](QQmlEngine *e, QJSEngine *) -> QObject * {
123  Settings *settings = Settings::self();
124  // singleton managed internally, qml should never delete it
126  settings->setStyle(Kirigami::StyleSelector::style());
127  return settings;
128  });
129 
130  qmlRegisterUncreatableType<ApplicationHeaderStyle>(uri,
131  2,
132  0,
133  "ApplicationHeaderStyle",
134  QStringLiteral("Cannot create objects of type ApplicationHeaderStyle"));
135 
136  // old legacy retrocompatible Theme
137  qmlRegisterSingletonType<Kirigami::BasicThemeDefinition>(uri, 2, 0, "Theme", [](QQmlEngine *, QJSEngine *) {
138  qCWarning(KirigamiLog) << "The Theme singleton is deprecated (since 5.39). Import Kirigami 2.2 or higher and use the attached property instead.";
139  return new Kirigami::BasicThemeDefinition{};
140  });
141 
142  qmlRegisterSingletonType<Kirigami::Units>(uri, 2, 0, "Units", [] (QQmlEngine *engine, QJSEngine *) {
143 #ifndef KIRIGAMI_BUILD_TYPE_STATIC
145  if (plugin) {
146  // Check if the plugin implements units
147  auto pluginV2 = qobject_cast<Kirigami::KirigamiPluginFactoryV2 *>(plugin);
148  if (pluginV2) {
149  auto units = pluginV2->createUnits(engine);
150  if (units) {
151  return units;
152  } else {
153  qWarning(KirigamiLog) << "The style returned a nullptr Units*, falling back to defaults";
154  }
155  } else {
156  qWarning(KirigamiLog) << "The style does not provide a C++ Units implementation."
157  << "QML Units implementations are no longer supported.";
158  }
159  } else {
160  qWarning(KirigamiLog) << "Failed to find a Kirigami platform plugin";
161  }
162 #endif
163  // Fall back to the default units implementation
164  return new Kirigami::Units(engine);
165  });
166 
167  qmlRegisterType(componentUrl(QStringLiteral("Action.qml")), uri, 2, 0, "Action");
168  qmlRegisterType(componentUrl(QStringLiteral("AbstractApplicationHeader.qml")), uri, 2, 0, "AbstractApplicationHeader");
169  qmlRegisterType(componentUrl(QStringLiteral("AbstractApplicationWindow.qml")), uri, 2, 0, "AbstractApplicationWindow");
170  qmlRegisterType(componentUrl(QStringLiteral("AbstractListItem.qml")), uri, 2, 0, "AbstractListItem");
171  qmlRegisterType(componentUrl(QStringLiteral("ApplicationHeader.qml")), uri, 2, 0, "ApplicationHeader");
172  qmlRegisterType(componentUrl(QStringLiteral("ToolBarApplicationHeader.qml")), uri, 2, 0, "ToolBarApplicationHeader");
173  qmlRegisterType(componentUrl(QStringLiteral("ApplicationWindow.qml")), uri, 2, 0, "ApplicationWindow");
174  qmlRegisterType(componentUrl(QStringLiteral("BasicListItem.qml")), uri, 2, 0, "BasicListItem");
175  qmlRegisterType(componentUrl(QStringLiteral("OverlayDrawer.qml")), uri, 2, 0, "OverlayDrawer");
176  qmlRegisterType(componentUrl(QStringLiteral("ContextDrawer.qml")), uri, 2, 0, "ContextDrawer");
177  qmlRegisterType(componentUrl(QStringLiteral("GlobalDrawer.qml")), uri, 2, 0, "GlobalDrawer");
178  qmlRegisterType(componentUrl(QStringLiteral("Heading.qml")), uri, 2, 0, "Heading");
179  qmlRegisterType(componentUrl(QStringLiteral("Separator.qml")), uri, 2, 0, "Separator");
180  qmlRegisterType(componentUrl(QStringLiteral("PageRow.qml")), uri, 2, 0, "PageRow");
181 
182  qmlRegisterType<Icon>(uri, 2, 0, "Icon");
183 
184  qmlRegisterType(componentUrl(QStringLiteral("Label.qml")), uri, 2, 0, "Label");
185  // TODO: uncomment for 2.3 release
186  // qmlRegisterTypeNotAvailable(uri, 2, 3, "Label", "Label type not supported anymore, use QtQuick.Controls.Label 2.0 instead");
187  qmlRegisterType(componentUrl(QStringLiteral("OverlaySheet.qml")), uri, 2, 0, "OverlaySheet");
188  qmlRegisterType(componentUrl(QStringLiteral("Page.qml")), uri, 2, 0, "Page");
189  qmlRegisterType(componentUrl(QStringLiteral("ScrollablePage.qml")), uri, 2, 0, "ScrollablePage");
190  qmlRegisterType(componentUrl(QStringLiteral("SplitDrawer.qml")), uri, 2, 0, "SplitDrawer");
191  qmlRegisterType(componentUrl(QStringLiteral("SwipeListItem.qml")), uri, 2, 0, "SwipeListItem");
192 
193  // 2.1
194  qmlRegisterType(componentUrl(QStringLiteral("AbstractItemViewHeader.qml")), uri, 2, 1, "AbstractItemViewHeader");
195  qmlRegisterType(componentUrl(QStringLiteral("ItemViewHeader.qml")), uri, 2, 1, "ItemViewHeader");
196  qmlRegisterType(componentUrl(QStringLiteral("AbstractApplicationItem.qml")), uri, 2, 1, "AbstractApplicationItem");
197  qmlRegisterType(componentUrl(QStringLiteral("ApplicationItem.qml")), uri, 2, 1, "ApplicationItem");
198 
199  // 2.2
200  // Theme changed from a singleton to an attached property
201  qmlRegisterUncreatableType<Kirigami::PlatformTheme>(uri,
202  2,
203  2,
204  "Theme",
205  QStringLiteral("Cannot create objects of type Theme, use it as an attached property"));
206 
207  // 2.3
208  qmlRegisterType(componentUrl(QStringLiteral("FormLayout.qml")), uri, 2, 3, "FormLayout");
209  qmlRegisterUncreatableType<FormLayoutAttached>(uri,
210  2,
211  3,
212  "FormData",
213  QStringLiteral("Cannot create objects of type FormData, use it as an attached property"));
214  qmlRegisterUncreatableType<MnemonicAttached>(uri,
215  2,
216  3,
217  "MnemonicData",
218  QStringLiteral("Cannot create objects of type MnemonicData, use it as an attached property"));
219 
220  // 2.4
221  qmlRegisterType(componentUrl(QStringLiteral("AbstractCard.qml")), uri, 2, 4, "AbstractCard");
222  qmlRegisterType(componentUrl(QStringLiteral("Card.qml")), uri, 2, 4, "Card");
223  qmlRegisterType(componentUrl(QStringLiteral("CardsListView.qml")), uri, 2, 4, "CardsListView");
224  qmlRegisterType(componentUrl(QStringLiteral("CardsGridView.qml")), uri, 2, 4, "CardsGridView");
225  qmlRegisterType(componentUrl(QStringLiteral("CardsLayout.qml")), uri, 2, 4, "CardsLayout");
226  qmlRegisterType(componentUrl(QStringLiteral("InlineMessage.qml")), uri, 2, 4, "InlineMessage");
227  qmlRegisterUncreatableType<MessageType>(uri, 2, 4, "MessageType", QStringLiteral("Cannot create objects of type MessageType"));
228  qmlRegisterType<DelegateRecycler>(uri, 2, 4, "DelegateRecycler");
229 
230  // 2.5
231  qmlRegisterType(componentUrl(QStringLiteral("ListItemDragHandle.qml")), uri, 2, 5, "ListItemDragHandle");
232  qmlRegisterType(componentUrl(QStringLiteral("ActionToolBar.qml")), uri, 2, 5, "ActionToolBar");
233  qmlRegisterUncreatableType<ScenePositionAttached>(uri,
234  2,
235  5,
236  "ScenePosition",
237  QStringLiteral("Cannot create objects of type ScenePosition, use it as an attached property"));
238 
239  // 2.6
240  qmlRegisterType(componentUrl(QStringLiteral("AboutPage.qml")), uri, 2, 6, "AboutPage");
241  qmlRegisterType(componentUrl(QStringLiteral("LinkButton.qml")), uri, 2, 6, "LinkButton");
242  qmlRegisterType(componentUrl(QStringLiteral("UrlButton.qml")), uri, 2, 6, "UrlButton");
243  qmlRegisterSingletonType<CopyHelperPrivate>("org.kde.kirigami.private", 2, 6, "CopyHelperPrivate", singleton<CopyHelperPrivate>());
244 
245  // 2.7
246  qmlRegisterType<ColumnView>(uri, 2, 7, "ColumnView");
247  qmlRegisterType(componentUrl(QStringLiteral("ActionTextField.qml")), uri, 2, 7, "ActionTextField");
248 
249  // 2.8
250  qmlRegisterType(componentUrl(QStringLiteral("SearchField.qml")), uri, 2, 8, "SearchField");
251  qmlRegisterType(componentUrl(QStringLiteral("PasswordField.qml")), uri, 2, 8, "PasswordField");
252 
253  // 2.9
254  qmlRegisterType<WheelHandler>(uri, 2, 9, "WheelHandler");
255  qmlRegisterUncreatableType<KirigamiWheelEvent>(uri, 2, 9, "WheelEvent", QStringLiteral("Cannot create objects of type WheelEvent."));
256 
257  // 2.10
258  qmlRegisterType(componentUrl(QStringLiteral("ListSectionHeader.qml")), uri, 2, 10, "ListSectionHeader");
259 
260  // 2.11
261  qmlRegisterType<PagePool>(uri, 2, 11, "PagePool");
262  qmlRegisterType(componentUrl(QStringLiteral("PagePoolAction.qml")), uri, 2, 11, "PagePoolAction");
263 
264  // TODO: remove
265  qmlRegisterType(componentUrl(QStringLiteral("SwipeListItem2.qml")), uri, 2, 11, "SwipeListItem2");
266 
267  // 2.12
268  qmlRegisterType<ShadowedRectangle>(uri, 2, 12, "ShadowedRectangle");
269  qmlRegisterType<ShadowedTexture>(uri, 2, 12, "ShadowedTexture");
270  qmlRegisterType(componentUrl(QStringLiteral("ShadowedImage.qml")), uri, 2, 12, "ShadowedImage");
271  qmlRegisterType(componentUrl(QStringLiteral("PlaceholderMessage.qml")), uri, 2, 12, "PlaceholderMessage");
272 
273  qmlRegisterUncreatableType<BorderGroup>(uri, 2, 12, "BorderGroup", QStringLiteral("Used as grouped property"));
274  qmlRegisterUncreatableType<ShadowGroup>(uri, 2, 12, "ShadowGroup", QStringLiteral("Used as grouped property"));
275  qmlRegisterSingletonType<ColorUtils>(uri, 2, 12, "ColorUtils", singleton<ColorUtils>());
276 
277  qmlRegisterUncreatableType<CornersGroup>(uri, 2, 12, "CornersGroup", QStringLiteral("Used as grouped property"));
278  qmlRegisterType<PageRouter>(uri, 2, 12, "PageRouter");
279  qmlRegisterType<PageRoute>(uri, 2, 12, "PageRoute");
280  qmlRegisterUncreatableType<PageRouterAttached>(uri, 2, 12, "PageRouterAttached", QStringLiteral("PageRouterAttached cannot be created"));
281  qmlRegisterType(componentUrl(QStringLiteral("RouterWindow.qml")), uri, 2, 12, "RouterWindow");
282 
283  // 2.13
284  qmlRegisterType<ImageColors>(uri, 2, 13, "ImageColors");
285  qmlRegisterType(componentUrl(QStringLiteral("Avatar.qml")), uri, 2, 13, "Avatar");
286  qmlRegisterType(componentUrl(QStringLiteral("swipenavigator/SwipeNavigator.qml")), uri, 2, 13, "SwipeNavigator");
287 
288  // 2.14
289  qmlRegisterUncreatableType<PreloadRouteGroup>(uri, 2, 14, "PreloadRouteGroup", QStringLiteral("PreloadRouteGroup cannot be created"));
290  qmlRegisterType(componentUrl(QStringLiteral("FlexColumn.qml")), uri, 2, 14, "FlexColumn");
291  qmlRegisterType<ToolBarLayout>(uri, 2, 14, "ToolBarLayout");
292  qmlRegisterSingletonType<DisplayHint>(uri, 2, 14, "DisplayHint", singleton<DisplayHint>());
293  qmlRegisterType<SizeGroup>(uri, 2, 14, "SizeGroup");
294  qmlRegisterType<AvatarGroup>("org.kde.kirigami.private", 2, 14, "AvatarGroup");
295  qmlRegisterType(componentUrl(QStringLiteral("CheckableListItem.qml")), uri, 2, 14, "CheckableListItem");
296  qmlRegisterSingletonType<NameUtils>(uri, 2, 14, "NameUtils", singleton<NameUtils>());
297 
298  qmlRegisterType(componentUrl(QStringLiteral("Hero.qml")), uri, 2, 15, "Hero");
299 
300  // 2.16
301  qmlRegisterType<Kirigami::BasicThemeDefinition>(uri, 2, 16, "BasicThemeDefinition");
302 
303  // 2.17
304  qmlRegisterType(componentUrl(QStringLiteral("swipenavigator/TabViewLayout.qml")), uri, 2, 17, "TabViewLayout");
305  qmlRegisterType(componentUrl(QStringLiteral("swipenavigator/PageTab.qml")), uri, 2, 17, "PageTab");
306 
307  // 2.18
308  qmlRegisterType<SpellCheckingAttached>(uri, 2, 18, "SpellChecking");
309  qmlRegisterType(componentUrl(QStringLiteral("settingscomponents/CategorizedSettings.qml")), uri, 2, 18, "CategorizedSettings");
310  qmlRegisterType(componentUrl(QStringLiteral("settingscomponents/GenericSettingsPage.qml")), uri, 2, 18, "GenericSettingsPage");
311  qmlRegisterType(componentUrl(QStringLiteral("settingscomponents/SettingAction.qml")), uri, 2, 18, "SettingAction");
312 
313  // 2.19
314  qmlRegisterType(componentUrl(QStringLiteral("AboutItem.qml")), uri, 2, 19, "AboutItem");
315  qmlRegisterType(componentUrl(QStringLiteral("NavigationTabBar.qml")), uri, 2, 19, "NavigationTabBar");
316  qmlRegisterType(componentUrl(QStringLiteral("NavigationTabButton.qml")), uri, 2, 19, "NavigationTabButton");
317  qmlRegisterType(componentUrl(QStringLiteral("Dialog.qml")), uri, 2, 19, "Dialog");
318  qmlRegisterType(componentUrl(QStringLiteral("MenuDialog.qml")), uri, 2, 19, "MenuDialog");
319  qmlRegisterType(componentUrl(QStringLiteral("PromptDialog.qml")), uri, 2, 19, "PromptDialog");
320  qmlRegisterType(componentUrl(QStringLiteral("AbstractChip.qml")), uri, 2, 19, "AbstractChip");
321  qmlRegisterType(componentUrl(QStringLiteral("Chip.qml")), uri, 2, 19, "Chip");
322  qmlRegisterType(componentUrl(QStringLiteral("LoadingPlaceholder.qml")), uri, 2, 19, "LoadingPlaceholder");
323 
324  qmlRegisterSingletonType<InputMethod>(uri, 2, 19, "InputMethod", [](QQmlEngine *, QJSEngine *) {
325  return new InputMethod{};
326  });
327 
328  // 2.20
329  qmlRegisterType(componentUrl(QStringLiteral("SelectableLabel.qml")), uri, 2, 20, "SelectableLabel");
330 
331  qmlProtectModule(uri, 2);
332 }
333 
334 void KirigamiPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
335 {
336  Q_UNUSED(uri);
337  connect(this, &KirigamiPlugin::languageChangeEvent, engine, &QQmlEngine::retranslate);
338 }
339 
340 #ifdef KIRIGAMI_BUILD_TYPE_STATIC
341 KirigamiPlugin& KirigamiPlugin::getInstance()
342 {
343  static KirigamiPlugin instance;
344  return instance;
345 }
346 
347 void KirigamiPlugin::registerTypes(QQmlEngine* engine)
348 {
349  Q_INIT_RESOURCE(shaders);
350  Q_INIT_RESOURCE(KirigamiPlugin);
351 
352  if (engine) {
353  engine->addImportPath(QLatin1String(":/"));
354  }
355  else {
356  qCWarning(KirigamiLog)
357  << "Registering Kirigami on a null QQmlEngine instance - you likely want to pass a valid engine, or you will want to manually add the "
358  "qrc root path :/ to your import paths list so the engine is able to load the plugin";
359  }
360 }
361 #endif
362 
363 #include "kirigamiplugin.moc"
Q_OBJECTQ_OBJECT
This class contains global kirigami settings about the current device setup It is exposed to QML as t...
Definition: settings.h:16
bool registerResource(const QString &rccFileName, const QString &mapRoot)
Q_EMITQ_EMIT
void retranslate()
void setThemeSearchPaths(const QStringList &paths)
virtual bool eventFilter(QObject *watched, QEvent *event)
void setThemeName(const QString &name)
void installEventFilter(QObject *filterObj)
QString themeName()
QCoreApplication * instance()
QFuture< void > filter(Sequence &sequence, KeepFunctor filterFunction)
This exposes information about the current used input method.
Definition: inputmethod.h:17
void setObjectOwnership(QObject *object, QQmlEngine::ObjectOwnership ownership)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
Q_INVOKABLEQ_INVOKABLE
Q_SIGNALSQ_SIGNALS
void addImportPath(const QString &path)
void setParent(QObject *parent)
static KirigamiPluginFactory * findPlugin()
finds the plugin providing units and platformtheme for the current style The plugin pointer is cached...
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:14:23 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.