Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qandroidplatformiconengine.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#ifndef QT_NO_ICON
8
10
11#include <QtCore/qdebug.h>
12#include <QtCore/qjniarray.h>
13#include <QtCore/qjniobject.h>
14#include <QtCore/qloggingcategory.h>
15#include <QtCore/qfile.h>
16#include <QtCore/qset.h>
17
18#include <QtGui/qfontdatabase.h>
19#include <QtGui/qpainter.h>
20#include <QtGui/qpalette.h>
21
23
24using namespace Qt::StringLiterals;
25Q_STATIC_LOGGING_CATEGORY(lcIconEngineFontDownload, "qt.qpa.iconengine.fontdownload")
26
27// the primary types to work with the FontRequest API
28Q_DECLARE_JNI_CLASS(FontRequest, "androidx/core/provider/FontRequest")
29Q_DECLARE_JNI_CLASS(FontsContractCompat, "androidx/core/provider/FontsContractCompat")
30Q_DECLARE_JNI_CLASS(FontFamilyResult, "androidx/core/provider/FontsContractCompat$FontFamilyResult")
31Q_DECLARE_JNI_CLASS(FontInfo, "androidx/core/provider/FontsContractCompat$FontInfo")
32
33// various utility types
34Q_DECLARE_JNI_CLASS(List, "java/util/List"); // List is just an Interface
35Q_DECLARE_JNI_CLASS(HashSet, "java/util/HashSet");
36Q_DECLARE_JNI_CLASS(CancellationSignal, "android/os/CancellationSignal")
37Q_DECLARE_JNI_CLASS(ParcelFileDescriptor, "android/os/ParcelFileDescriptor")
38Q_DECLARE_JNI_CLASS(PackageManager, "android/content/pm/PackageManager")
39Q_DECLARE_JNI_CLASS(ProviderInfo, "android/content/pm/ProviderInfo")
40Q_DECLARE_JNI_CLASS(PackageInfo, "android/content/pm/PackageInfo")
41Q_DECLARE_JNI_CLASS(Signature, "android/content/pm/Signature")
42
43namespace FontProvider {
44
45static QString fetchFont(const QString &query)
46{
47 using namespace QtJniTypes;
48
49 static QMap<QString, QString> triedFonts;
50 const auto it = triedFonts.find(query);
51 if (it != triedFonts.constEnd())
52 return it.value();
53
54 QString fontFamily;
55 triedFonts[query] = fontFamily; // mark as tried
56
57 QStringList loadedFamilies;
58 if (QFile file(query); file.open(QIODevice::ReadOnly)) {
59 qCDebug(lcIconEngineFontDownload) << "Loading font from resource" << query;
60 const QByteArray fontData = file.readAll();
61 int fontId = QFontDatabase::addApplicationFontFromData(fontData);
62 loadedFamilies << QFontDatabase::applicationFontFamilies(fontId);
63 } else if (!query.startsWith(u":/"_s)) {
64 const QString package = u"com.google.android.gms"_s;
65 const QString authority = u"com.google.android.gms.fonts"_s;
66
67 // First we access the content provider to get the signatures of the authority for the package
68 const auto context = QtAndroidPrivate::context();
69
70 auto packageManager = context.callMethod<PackageManager>("getPackageManager");
71 if (!packageManager.isValid()) {
72 qCWarning(lcIconEngineFontDownload, "Failed to instantiate PackageManager");
73 return fontFamily;
74 }
75 const int signaturesField = PackageManager::getStaticField<int>("GET_SIGNATURES");
76 auto providerInfo = packageManager.callMethod<ProviderInfo>("resolveContentProvider",
77 authority, 0);
78 if (!providerInfo.isValid()) {
79 qCWarning(lcIconEngineFontDownload, "Failed to resolve content provider");
80 return fontFamily;
81 }
82 const QString packageName = providerInfo.getField<QString>("packageName");
83 if (packageName != package) {
84 qCWarning(lcIconEngineFontDownload, "Mismatched provider package - expected '%s', got '%s'",
85 package.toUtf8().constData(), packageName.toUtf8().constData());
86 return fontFamily;
87 }
88 auto packageInfo = packageManager.callMethod<PackageInfo>("getPackageInfo",
89 package, signaturesField);
90 if (!packageInfo.isValid()) {
91 qCWarning(lcIconEngineFontDownload, "Failed to get package info with signature field %d",
92 signaturesField);
93 return fontFamily;
94 }
95 const auto signatures = packageInfo.getField<Signature[]>("signatures");
96 if (!signatures.isValid()) {
97 qCWarning(lcIconEngineFontDownload, "Failed to get signature array from package info");
98 return fontFamily;
99 }
100
101 // FontRequest wants a list of sets for the certificates
102 ArrayList outerList;
103 HashSet innerSet;
104 Q_ASSERT(outerList.isValid() && innerSet.isValid());
105
106 for (const auto &signature : signatures) {
107 const QJniArray<jbyte> byteArray = signature.callMethod<jbyte[]>("toByteArray");
108
109 // add takes an Object, not an Array
110 if (!innerSet.callMethod<jboolean>("add", byteArray.object<jobject>()))
111 qCWarning(lcIconEngineFontDownload, "Failed to add signature to set");
112 }
113 // Add the set to the list
114 if (!outerList.callMethod<jboolean>("add", innerSet.object()))
115 qCWarning(lcIconEngineFontDownload, "Failed to add set to certificate list");
116
117 // FontRequest constructor wants a List interface, not an ArrayList
118 FontRequest fontRequest(authority, package, query, outerList.object<List>());
119 if (!fontRequest.isValid()) {
120 qCWarning(lcIconEngineFontDownload, "Failed to create font request for '%s'",
121 query.toUtf8().constData());
122 return fontFamily;
123 }
124
125 // Call FontsContractCompat::fetchFonts with the FontRequest object
126 auto fontFamilyResult = FontsContractCompat::callStaticMethod<FontFamilyResult>(
127 "fetchFonts",
128 context,
129 CancellationSignal(nullptr),
130 fontRequest);
131 if (!fontFamilyResult.isValid()) {
132 qCWarning(lcIconEngineFontDownload, "Failed to fetch fonts for query '%s'",
133 query.toUtf8().constData());
134 return fontFamily;
135 }
136
137 enum class StatusCode {
138 OK = 0,
139 UNEXPECTED_DATA_PROVIDED = 1,
140 WRONG_CERTIFICATES = 2,
141 };
142
143 const StatusCode statusCode = fontFamilyResult.callMethod<StatusCode>("getStatusCode");
144 switch (statusCode) {
145 case StatusCode::OK:
146 break;
147 case StatusCode::UNEXPECTED_DATA_PROVIDED:
148 qCWarning(lcIconEngineFontDownload, "Provider returned unexpected data for query '%s'",
149 query.toUtf8().constData());
150 return fontFamily;
151 case StatusCode::WRONG_CERTIFICATES:
152 qCWarning(lcIconEngineFontDownload, "Wrong Certificates provided in query '%s'",
153 query.toUtf8().constData());
154 return fontFamily;
155 }
156
157 const auto fontInfos = fontFamilyResult.callMethod<FontInfo[]>("getFonts");
158 if (!fontInfos.isValid()) {
159 qCWarning(lcIconEngineFontDownload, "FontFamilyResult::getFonts returned null object for '%s'",
160 query.toUtf8().constData());
161 return fontFamily;
162 }
163
164 auto contentResolver = context.callMethod<ContentResolver>("getContentResolver");
165
166 for (QJniObject fontInfo : fontInfos) {
167 if (!fontInfo.isValid()) {
168 qCDebug(lcIconEngineFontDownload, "Received null-fontInfo object, skipping");
169 continue;
170 }
171 enum class ResultCode {
172 OK = 0,
173 FONT_NOT_FOUND = 1,
174 FONT_UNAVAILABLE = 2,
175 MALFORMED_QUERY = 3,
176 };
177 const ResultCode resultCode = fontInfo.callMethod<ResultCode>("getResultCode");
178 switch (resultCode) {
179 case ResultCode::OK:
180 break;
181 case ResultCode::FONT_NOT_FOUND:
182 qCWarning(lcIconEngineFontDownload, "Font '%s' could not be found",
183 query.toUtf8().constData());
184 return fontFamily;
185 case ResultCode::FONT_UNAVAILABLE:
186 qCWarning(lcIconEngineFontDownload, "Font '%s' is unavailable at",
187 query.toUtf8().constData());
188 return fontFamily;
189 case ResultCode::MALFORMED_QUERY:
190 qCWarning(lcIconEngineFontDownload, "Query string '%s' is malformed",
191 query.toUtf8().constData());
192 return fontFamily;
193 }
194 auto fontUri = fontInfo.callMethod<Uri>("getUri");
195 // in this case the Font URI is always a content scheme file, made
196 // so the app requesting it has permissions to open
197 auto fileDescriptor = contentResolver.callMethod<ParcelFileDescriptor>("openFileDescriptor",
198 fontUri, u"r"_s);
199 if (!fileDescriptor.isValid()) {
200 qCWarning(lcIconEngineFontDownload, "Font file '%s' not accessible",
201 fontUri.toString().toUtf8().constData());
202 continue;
203 }
204
205 int fd = fileDescriptor.callMethod<int>("detachFd");
206 QFile file;
207 if (!file.open(fd, QFile::OpenModeFlag::ReadOnly,
208 QFile::FileHandleFlag::AutoCloseHandle)) {
209 qCWarning(lcIconEngineFontDownload, "Font file '%ls' cannot be opened: %ls",
210 qUtf16Printable(fontUri.toString()),
211 qUtf16Printable(file.errorString()));
212 continue;
213 }
214 const QByteArray fontData = file.readAll();
215 qCDebug(lcIconEngineFontDownload) << "Font file read:" << fontData.size() << "bytes";
216 int fontId = QFontDatabase::addApplicationFontFromData(fontData);
217 loadedFamilies << QFontDatabase::applicationFontFamilies(fontId);
218 }
219 }
220
221 qCDebug(lcIconEngineFontDownload) << "Query '" << query << "' added families" << loadedFamilies;
222 if (!loadedFamilies.isEmpty())
223 fontFamily = loadedFamilies.first();
224 triedFonts[query] = fontFamily;
225 return fontFamily;
226}
227
229{
230 QString fontFamily;
231 // The MaterialIcons-*.ttf and MaterialSymbols* font files are available from
232 // https://github.com/google/material-design-icons/tree/master. If one of them is
233 // packaged as a resource with the application, then we use it. We prioritize
234 // a variable font.
235 const QStringList fontCandidates = {
236 "MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf",
237 "MaterialSymbolsRounded[FILL,GRAD,opsz,wght].ttf",
238 "MaterialSymbolsSharp[FILL,GRAD,opsz,wght].ttf",
239 "MaterialIcons-Regular.ttf",
240 "MaterialIconsOutlined-Regular.otf",
241 "MaterialIconsRound-Regular.otf",
242 "MaterialIconsSharp-Regular.otf",
243 "MaterialIconsTwoTone-Regular.otf",
244 };
245 for (const auto &fontCandidate : fontCandidates) {
246 fontFamily = FontProvider::fetchFont(u":/qt-project.org/icons/%1"_s.arg(fontCandidate));
247 if (!fontFamily.isEmpty())
248 break;
249 }
250
251 // Otherwise we try to download the Outlined version of Material Symbols
252 const QString key = qEnvironmentVariable("QT_GOOGLE_FONTS_KEY");
253 if (fontFamily.isEmpty() && !key.isEmpty())
254 fontFamily = FontProvider::fetchFont(u"key=%1&name=Material+Symbols+Outlined"_s.arg(key));
255
256 // last resort - use any Material Icons
257 if (fontFamily.isEmpty())
258 fontFamily = u"Material Icons"_s;
259 QFont font(fontFamily);
260 font.setStyleStrategy(QFont::NoFontMerging);
261 return font;
262}
263
264} // namespace FontProvider
265
266static QString getGlyphs(QStringView iconName)
267{
268 static constexpr std::pair<QLatin1StringView, QStringView> glyphMap[] = {
269 {"address-book-new"_L1, u"\ue0e0"},
270 {"application-exit"_L1, u"\ue5cd"},
271 {"appointment-new"_L1, u"\ue878"},
272 {"call-start"_L1, u"\ue0b0"},
273 {"call-stop"_L1, u"\ue0b1"},
274 {"contact-new"_L1, u"\uf22e"},
275 {"document-new"_L1, u"\ue89c"},
276 {"document-open"_L1, u"\ue2c8"},
277 {"document-open-recent"_L1, u"\ue4a7"},
278 {"document-page-setup"_L1, u"\uf88c"},
279 {"document-print"_L1, u"\ue8ad"},
280 {"document-print-preview"_L1, u"\uefb2"},
281 {"document-properties"_L1, u"\uf775"},
282 {"document-revert"_L1, u"\ue929"},
283 {"document-save"_L1, u"\ue161"},
284 {"document-save-as"_L1, u"\ueb60"},
285 {"document-send"_L1, u"\uf09b"},
286 {"edit-clear"_L1, u"\ue872"},
287 {"edit-copy"_L1, u"\ue14d"},
288 {"edit-cut"_L1, u"\ue14e"},
289 {"edit-delete"_L1, u"\ue14a"},
290 {"edit-find"_L1, u"\ue8b6"},
291 {"edit-find-replace"_L1, u"\ue881"},
292 {"edit-paste"_L1, u"\ue14f"},
293 {"edit-redo"_L1, u"\ue15a"},
294 {"edit-select-all"_L1, u"\ue162"},
295 {"edit-undo"_L1, u"\ue166"},
296 {"folder-new"_L1, u"\ue2cc"},
297 {"format-indent-less"_L1, u"\ue23d"},
298 {"format-indent-more"_L1, u"\ue23e"},
299 {"format-justify-center"_L1, u"\ue234"},
300 {"format-justify-fill"_L1, u"\ue235"},
301 {"format-justify-left"_L1, u"\ue236"},
302 {"format-justify-right"_L1, u"\ue237"},
303 {"format-text-direction-ltr"_L1, u"\ue247"},
304 {"format-text-direction-rtl"_L1, u"\ue248"},
305 {"format-text-bold"_L1, u"\ue238"},
306 {"format-text-italic"_L1, u"\ue23f"},
307 {"format-text-underline"_L1, u"\ue249"},
308 {"format-text-strikethrough"_L1, u"\ue246"},
309 {"go-bottom"_L1,u"\ue258"},
310 {"go-down"_L1,u"\uf1e3"},
311 {"go-first"_L1, u"\ue5dc"},
312 {"go-home"_L1, u"\ue88a"},
313 {"go-jump"_L1, u"\uf719"},
314 {"go-last"_L1, u"\ue5dd"},
315 {"go-next"_L1, u"\ue5c8"},
316 {"go-previous"_L1, u"\ue5c4"},
317 {"go-top"_L1, u"\ue25a"},
318 {"go-up"_L1, u"\uf1e0"},
319 {"help-about"_L1, u"\ue88e"},
320 {"help-contents"_L1, u"\ue8de"},
321 {"help-faq"_L1, u"\uf04c"},
322 {"insert-image"_L1, u"\ue43e"},
323 {"insert-link"_L1, u"\ue178"},
324 //{"insert-object"_L1, u"\u"},
325 {"insert-text"_L1, u"\uf827"},
326 {"list-add"_L1, u"\ue145"},
327 {"list-remove"_L1, u"\ue15b"},
328 {"mail-forward"_L1, u"\ue154"},
329 {"mail-mark-important"_L1, u"\ue937"},
330 //{"mail-mark-junk"_L1, u"\u"},
331 //{"mail-mark-notjunk"_L1, u"\u"},
332 {"mail-mark-read"_L1, u"\uf18c"},
333 {"mail-mark-unread"_L1, u"\ue9bc"},
334 {"mail-message-new"_L1, u"\ue3c9"},
335 {"mail-reply-all"_L1, u"\ue15f"},
336 {"mail-reply-sender"_L1, u"\ue15e"},
337 {"mail-send"_L1, u"\ue163"},
338 //{"mail-send-receive"_L1, u"\u"},
339 {"media-eject"_L1, u"\ue8fb"},
340 {"media-playback-pause"_L1, u"\ue034"},
341 {"media-playback-start"_L1, u"\ue037"},
342 {"media-playback-stop"_L1, u"\ue047"},
343 {"media-record"_L1, u"\uf679"},
344 {"media-seek-backward"_L1, u"\ue020"},
345 {"media-seek-forward"_L1, u"\ue01f"},
346 {"media-skip-backward"_L1, u"\ue045"},
347 {"media-skip-forward"_L1, u"\ue044"},
348 //{"object-flip-horizontal"_L1, u"\u"},
349 //{"object-flip-vertical"_L1, u"\u"},
350 {"object-rotate-left"_L1, u"\ue419"},
351 {"object-rotate-right"_L1, u"\ue41a"},
352 {"process-stop"_L1, u"\ue5c9"},
353 {"system-lock-screen"_L1, u"\ue897"},
354 {"system-log-out"_L1, u"\ue9ba"},
355 //{"system-run"_L1, u"\u"},
356 {"system-search"_L1, u"\uef70"},
357 {"system-reboot"_L1, u"\uf053"},
358 {"system-shutdown"_L1, u"\ue8ac"},
359 {"tools-check-spelling"_L1, u"\ue8ce"},
360 {"view-fullscreen"_L1, u"\ue5d0"},
361 {"view-refresh"_L1, u"\ue5d5"},
362 {"view-restore"_L1, u"\uf1cf"},
363 {"view-sort-ascending"_L1, u"\ue25a"},
364 {"view-sort-descending"_L1, u"\ue258"},
365 {"window-close"_L1, u"\ue5cd"},
366 {"window-new"_L1, u"\uf710"},
367 {"zoom-fit-best"_L1, u"\uea10"},
368 {"zoom-in"_L1, u"\ue8ff"},
369 {"zoom-original"_L1, u"\ue5d1"},
370 {"zoom-out"_L1, u"\ue900"},
371 {"process-working"_L1, u"\uef64"},
372 {"accessories-calculator"_L1, u"\uea5f"},
373 {"accessories-character-map"_L1, u"\uf8a3"},
374 {"accessories-dictionary"_L1, u"\uf539"},
375 {"accessories-text-editor"_L1, u"\ue262"},
376 {"help-browser"_L1, u"\ue887"},
377 {"multimedia-volume-control"_L1, u"\ue050"},
378 {"preferences-desktop-accessibility"_L1, u"\uf05d"},
379 {"preferences-desktop-font"_L1, u"\ue165"},
380 {"preferences-desktop-keyboard"_L1, u"\ue312"},
381 //{"preferences-desktop-locale"_L1, u"\u"},
382 {"preferences-desktop-multimedia"_L1, u"\uea75"},
383 //{"preferences-desktop-screensaver"_L1, u"\u"},
384 {"preferences-desktop-theme"_L1, u"\uf560"},
385 {"preferences-desktop-wallpaper"_L1, u"\ue1bc"},
386 {"system-file-manager"_L1, u"\ue2c7"},
387 {"system-software-install"_L1, u"\ueb71"},
388 {"system-software-update"_L1, u"\ue8d7"},
389 {"utilities-system-monitor"_L1, u"\uef5b"},
390 {"utilities-terminal"_L1, u"\ueb8e"},
391 //{"applications-accessories"_L1, u"\u"},
392 {"applications-development"_L1, u"\ue720"},
393 {"applications-engineering"_L1, u"\uea3d"},
394 {"applications-games"_L1, u"\uf135"},
395 //{"applications-graphics"_L1, u"\u"},
396 {"applications-internet"_L1, u"\ue80b"},
397 {"applications-multimedia"_L1, u"\uf06a"},
398 //{"applications-office"_L1, u"\u"},
399 //{"applications-other"_L1, u"\u"},
400 {"applications-science"_L1, u"\uea4b"},
401 //{"applications-system"_L1, u"\u"},
402 //{"applications-utilities"_L1, u"\u"},
403 {"preferences-desktop"_L1, u"\ueb97"},
404 //{"preferences-desktop-peripherals"_L1, u"\u"},
405 {"preferences-desktop-personal"_L1, u"\uf835"},
406 //{"preferences-other"_L1, u"\u"},
407 {"preferences-system"_L1, u"\ue8b8"},
408 {"preferences-system-network"_L1, u"\ue894"},
409 {"system-help"_L1, u"\ue887"},
410 //{"audio-card"_L1, u"\u"},
411 {"audio-input-microphone"_L1, u"\ue029"},
412 {"battery"_L1, u"\ue1a4"},
413 {"camera-photo"_L1, u"\ue412"},
414 {"camera-video"_L1, u"\ue04b"},
415 {"camera-web"_L1, u"\uf7a6"},
416 {"computer"_L1, u"\ue30a"},
417 {"drive-harddisk"_L1, u"\uf80e"},
418 {"drive-optical"_L1, u"\ue019"}, // same as media-optical
419 //{"drive-removable-media"_L1, u"\u"},
420 {"input-gaming"_L1, u"\uf5ee"},
421 {"input-keyboard"_L1, u"\ue312"},
422 {"input-mouse"_L1, u"\ue323"},
423 //{"input-tablet"_L1, u"\u"},
424 //{"media-flash"_L1, u"\u"},
425 //{"media-floppy"_L1, u"\u"},
426 {"media-optical"_L1, u"\ue019"},
427 //{"media-tape"_L1, u"\u"},
428 //{"modem"_L1, u"\u"},
429 //{"multimedia-player"_L1, u"\u"},
430 //{"network-wired"_L1, u"\u"},
431 {"network-wireless"_L1, u"\ue63e"},
432 //{"pda"_L1, u"\u"},
433 {"phone"_L1, u"\ue32c"},
434 {"printer"_L1, u"\ue8ad"},
435 {"scanner"_L1, u"\ue329"},
436 {"video-display"_L1, u"\uf06a"},
437 //{"emblem-default"_L1, u"\u"},
438 {"emblem-documents"_L1, u"\ue873"},
439 {"emblem-downloads"_L1, u"\uf090"},
440 {"emblem-favorite"_L1, u"\uf090"},
441 {"emblem-important"_L1, u"\ue645"},
442 {"emblem-mail"_L1, u"\ue158"},
443 {"emblem-photos"_L1, u"\ue413"},
444 //{"emblem-readonly"_L1, u"\u"},
445 {"emblem-shared"_L1, u"\ue413"},
446 //{"emblem-symbolic-link"_L1, u"\u"},
447 //{"emblem-synchronized"_L1, u"\u"},
448 {"emblem-system"_L1, u"\ue8b8"},
449 //{"emblem-unreadable"_L1, u"\u"},
450 {"folder"_L1, u"\ue2c7"},
451 {"text-x-generic"_L1, u"\ue66d"},
452 //{"folder-remote"_L1, u"\u"},
453 {"network-server"_L1, u"\ue875"},
454 {"network-workgroup"_L1, u"\ue1a0"},
455 {"start-here"_L1, u"\ue089"},
456 {"user-bookmarks"_L1, u"\ue98b"},
457 {"user-desktop"_L1, u"\ue30a"},
458 {"user-home"_L1, u"\ue88a"},
459 {"user-trash"_L1, u"\ue872"},
460 {"appointment-missed"_L1, u"\ue615"},
461 {"appointment-soon"_L1, u"\uf540"},
462 {"audio-volume-high"_L1, u"\ue050"},
463 {"audio-volume-low"_L1, u"\ue04d"},
464 //{"audio-volume-medium"_L1, u"\u"},
465 {"audio-volume-muted"_L1, u"\ue04e"},
466 {"battery-caution"_L1, u"\ue19c"},
467 {"battery-low"_L1, u"\uf147"},
468 {"dialog-error"_L1, u"\ue000"},
469 {"dialog-information"_L1, u"\ue88e"},
470 {"dialog-password"_L1, u"\uf042"},
471 {"dialog-question"_L1, u"\ueb8b"},
472 {"dialog-warning"_L1, u"\ue002"},
473 {"folder-drag-accept"_L1, u"\ue9a3"},
474 {"folder-open"_L1, u"\ue2c8"},
475 {"folder-visiting"_L1, u"\ue8a7"},
476 {"image-loading"_L1, u"\ue41a"},
477 {"image-missing"_L1, u"\ue3ad"},
478 {"mail-attachment"_L1, u"\ue2bc"},
479 {"mail-unread"_L1, u"\uf18a"},
480 {"mail-read"_L1, u"\uf18c"},
481 //{"mail-replied"_L1, u"\u"},
482 //{"mail-signed"_L1, u"\u"},
483 //{"mail-signed-verified"_L1, u"\u"},
484 {"media-playlist-repeat"_L1, u"\ue040"},
485 {"media-playlist-shuffle"_L1, u"\ue043"},
486 {"network-error"_L1, u"\uead9"},
487 {"network-idle"_L1, u"\ue51f"},
488 {"network-offline"_L1, u"\uf239"},
489 {"network-receive"_L1, u"\ue2c0"},
490 {"network-transmit"_L1, u"\ue2c3"},
491 {"network-transmit-receive"_L1, u"\uea18"},
492 {"printer-error"_L1, u"\uf7a0"},
493 {"printer-printing"_L1, u"\uf7a1"},
494 {"security-high"_L1, u"\ue32a"},
495 {"security-medium"_L1, u"\ue9e0"},
496 {"security-low"_L1, u"\uf012"},
497 {"software-update-available"_L1, u"\ue923"},
498 {"software-update-urgent"_L1, u"\uf05a"},
499 {"sync-error"_L1, u"\ue629"},
500 {"sync-synchronizing"_L1, u"\ue627"},
501 //{"task-due"_L1, u"\u"},
502 //{"task-past-due"_L1, u"\u"},
503 {"user-available"_L1, u"\uf565"},
504 {"user-away"_L1, u"\ue510"},
505 //{"user-idle"_L1, u"\u"},
506 {"user-offline"_L1, u"\uf7b3"},
507 {"user-trash-full"_L1, u"\ue872"}, //delete
508 //{"user-trash-full"_L1, u"\ue92b"}, //delete_forever
509 {"weather-clear"_L1, u"\uf157"},
510 {"weather-clear-night"_L1, u"\uf159"},
511 {"weather-few-clouds"_L1, u"\uf172"},
512 {"weather-few-clouds-night"_L1, u"\uf174"},
513 {"weather-fog"_L1, u"\ue818"},
514 //{"weather-overcast"_L1, u"\u"},
515 {"weather-severe-alert"_L1, u"\ue002"}, //warning
516 //{"weather-severe-alert"_L1, u"\uebd3"},//severe_cold
517 {"weather-showers"_L1, u"\uf176"},
518 //{"weather-showers-scattered"_L1, u"\u"},
519 {"weather-snow"_L1, u"\ue80f"}, //snowing
520 //{"weather-snow"_L1, u"\ue2cd"}, //weather_snowy
521 //{"weather-snow"_L1, u"\ue810"},//cloudy_snowing
522 {"weather-storm"_L1, u"\uf070"},
523 };
524
525 const auto it = std::find_if(std::begin(glyphMap),
526 std::end(glyphMap), [iconName](const auto &c){
527 return c.first == iconName;
528 });
529 return it != std::end(glyphMap) ? it->second.toString()
530 : (iconName.length() == 1 ? iconName.toString() : QString());
531}
532
533QAndroidPlatformIconEngine::QAndroidPlatformIconEngine(const QString &iconName)
534 : QFontIconEngine(iconName, FontProvider::selectFont())
535 , m_glyphs(getGlyphs(iconName))
536{
537}
538
539QAndroidPlatformIconEngine::~QAndroidPlatformIconEngine() = default;
540
541QString QAndroidPlatformIconEngine::key() const
542{
543 return u"QAndroidPlatformIconEngine"_s;
544}
545
546QIconEngine *QAndroidPlatformIconEngine::clone() const
547{
548 QAndroidPlatformIconEngine *that = const_cast<QAndroidPlatformIconEngine *>(this);
549 return new QAndroidPlatformIconEngine(that->iconName());
550}
551
552QString QAndroidPlatformIconEngine::string() const
553{
554 return m_glyphs;
555}
556
557QT_END_NAMESPACE
558
559#endif // QT_NO_ICON
static QString fetchFont(const QString &query)
Combined button and popup list for selecting options.
static QString getGlyphs(QStringView iconName)
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
Q_DECLARE_JNI_CLASS(MotionEvent, "android/view/MotionEvent")