11#include "private/qfactoryloader_p.h"
12#include "private/qiconloader_p.h"
15#if QT_CONFIG(mimetype)
16#include <qmimedatabase.h>
27#include "private/qhexstring_p.h"
28#include "private/qguiapplication_p.h"
29#include "private/qoffsetstringarray_p.h"
30#include "qpa/qplatformtheme.h"
35using namespace Qt::StringLiterals;
41 ImageReader(
const QString &fileName, QSize size)
45 if (m_reader.supportsOption(QImageIOHandler::ScaledSize)) {
47 const QSize imageSize = m_reader.size();
48 m_reader.setScaledSize(!imageSize.isEmpty() && !size.isEmpty()
49 ? imageSize.scaled(size, Qt::KeepAspectRatio)
54 QByteArray format()
const {
return m_reader.format(); }
55 bool supportsReadSize()
const {
return m_reader.supportsOption(QImageIOHandler::Size); }
56 QSize size()
const {
return m_reader.size(); }
57 bool jumpToNextImage() {
return m_reader.jumpToNextImage(); }
58 void jumpToImage(
int index) { m_reader.jumpToImage(index); }
60 bool read(QImage *image)
64 *image = m_reader.read();
65 if (!image->size().isValid()) {
69 m_atEnd = !m_reader.jumpToNextImage();
74 QImageReader m_reader;
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
103
104
105
106
107
108
109
110
114 Q_CONSTINIT
static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0);
115 return 1 + serial.fetchAndAddRelaxed(1);
120 struct IconCache :
public QCache<QString, QIcon>
130Q_GLOBAL_STATIC(IconCache, qtIconCache)
134 qtIconCache()->clear();
151
152
153
154
155
156
157
158
159
160
161qreal
QIconPrivate::pixmapDevicePixelRatio(qreal displayDevicePixelRatio,
const QSize &requestedSize,
const QSize &actualSize)
163 QSize targetSize = requestedSize * displayDevicePixelRatio;
164 if ((actualSize.width() == targetSize.width() && actualSize.height() <= targetSize.height()) ||
165 (actualSize.width() <= targetSize.width() && actualSize.height() == targetSize.height())) {
167 return displayDevicePixelRatio;
169 qreal scale = 0.5 * (qreal(actualSize.width()) / qreal(targetSize.width()) +
170 qreal(actualSize.height()) / qreal(targetSize.height()));
171 qreal dpr = qMax(qreal(1.0), displayDevicePixelRatio * scale);
172 return qRound(dpr * 100) / 100.0;
175QPixmapIconEngine::QPixmapIconEngine()
179QPixmapIconEngine::QPixmapIconEngine(
const QPixmapIconEngine &other)
180 : QIconEngine(other), pixmaps(other.pixmaps)
184QPixmapIconEngine::~QPixmapIconEngine()
188void QPixmapIconEngine::paint(QPainter *painter,
const QRect &rect, QIcon::Mode mode, QIcon::State state)
190 auto paintDevice = painter->device();
191 qreal dpr = paintDevice ? paintDevice->devicePixelRatio() : qApp->devicePixelRatio();
192 QPixmap px = scaledPixmap(rect.size(), mode, state, dpr);
193 painter->drawPixmap(rect, px);
196static inline qint64 area(
const QSize &s) {
return qint64(s.width()) * s.height(); }
206 const auto scaleA = pa->pixmap.devicePixelRatio();
207 const auto scaleB = pb->pixmap.devicePixelRatio();
209 if (scaleA != scaleB) {
214 qreal ascore = scaleA - scale;
215 qreal bscore = scaleB - scale;
218 if ((ascore < 0) != (bscore < 0))
219 return bscore < 0 ? pa : pb;
221 return (qAbs(ascore) < qAbs(bscore)) ? pa : pb;
224 qint64 s = area(size * scale);
225 if (pa->size == QSize() && pa->pixmap.isNull()) {
226 pa->pixmap = QPixmap(pa->fileName);
227 pa->size = pa->pixmap.size();
229 qint64 a = area(pa->size);
230 if (pb->size == QSize() && pb->pixmap.isNull()) {
231 pb->pixmap = QPixmap(pb->fileName);
232 pb->size = pb->pixmap.size();
234 qint64 b = area(pb->size);
245QPixmapIconEngineEntry *QPixmapIconEngine::tryMatch(
const QSize &size, qreal scale, QIcon::Mode mode, QIcon::State state)
247 QPixmapIconEngineEntry *pe =
nullptr;
248 for (
auto &entry : pixmaps) {
249 if (entry.mode == mode && entry.state == state) {
251 pe = bestSizeScaleMatch(size, scale, &entry, pe);
260QPixmapIconEngineEntry *QPixmapIconEngine::bestMatch(
const QSize &size, qreal scale, QIcon::Mode mode, QIcon::State state)
262 QPixmapIconEngineEntry *pe = tryMatch(size, scale, mode, state);
264 QIcon::State oppositeState = (state == QIcon::On) ? QIcon::Off : QIcon::On;
265 if (mode == QIcon::Disabled || mode == QIcon::Selected) {
266 QIcon::Mode oppositeMode = (mode == QIcon::Disabled) ? QIcon::Selected : QIcon::Disabled;
267 if ((pe = tryMatch(size, scale, QIcon::Normal, state)))
269 if ((pe = tryMatch(size, scale, QIcon::Active, state)))
271 if ((pe = tryMatch(size, scale, mode, oppositeState)))
273 if ((pe = tryMatch(size, scale, QIcon::Normal, oppositeState)))
275 if ((pe = tryMatch(size, scale, QIcon::Active, oppositeState)))
277 if ((pe = tryMatch(size, scale, oppositeMode, state)))
279 if ((pe = tryMatch(size, scale, oppositeMode, oppositeState)))
282 QIcon::Mode oppositeMode = (mode == QIcon::Normal) ? QIcon::Active : QIcon::Normal;
283 if ((pe = tryMatch(size, scale, oppositeMode, state)))
285 if ((pe = tryMatch(size, scale, mode, oppositeState)))
287 if ((pe = tryMatch(size, scale, oppositeMode, oppositeState)))
289 if ((pe = tryMatch(size, scale, QIcon::Disabled, state)))
291 if ((pe = tryMatch(size, scale, QIcon::Selected, state)))
293 if ((pe = tryMatch(size, scale, QIcon::Disabled, oppositeState)))
295 if ((pe = tryMatch(size, scale, QIcon::Selected, oppositeState)))
303 if (pe->pixmap.isNull()) {
305 QImage image, prevImage;
306 const QSize realSize = size * scale;
307 ImageReader imageReader(pe->fileName, realSize);
308 bool fittingImageFound =
false;
309 if (imageReader.supportsReadSize()) {
312 fittingImageFound = imageReader.size() == realSize;
313 }
while (!fittingImageFound && imageReader.jumpToNextImage());
315 if (!fittingImageFound) {
316 imageReader.jumpToImage(0);
317 while (imageReader.read(&image) && image.size() != realSize)
322 imageReader.read(&image);
324 if (!image.isNull()) {
325 if (pe->pixmap.convertFromImage(image))
326 pe->size = pe->pixmap.size();
328 if (!pe->size.isValid()) {
329 removePixmapEntry(pe);
337QPixmap QPixmapIconEngine::pixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state)
339 return scaledPixmap(size, mode, state, 1.0);
342QPixmap QPixmapIconEngine::scaledPixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale)
344 QPixmapIconEngineEntry *pe = bestMatch(size, scale, mode, state);
348 if (pe->pixmap.isNull()) {
349 removePixmapEntry(pe);
352 return scaledPixmap(size, mode, state, scale);
355 const auto actualSize = adjustSize(size * scale, pe->pixmap.size());
356 const auto calculatedDpr = QIconPrivate::pixmapDevicePixelRatio(scale, size, actualSize);
357 const QString key = u"qt_"
358 % HexString<quint64>(pe->pixmap.cacheKey())
359 % HexString<quint8>(pe->mode)
360 % HexString<quint64>(QGuiApplication::palette().cacheKey())
361 % HexString<uint>(actualSize.width())
362 % HexString<uint>(actualSize.height())
363 % HexString<quint16>(qRound(calculatedDpr * 1000))
364 % HexString<quint8>(mode);
366 if (QPixmapCache::find(key, &pm))
370 if (pm.size() != actualSize)
371 pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
373 if (pe->mode != mode && mode != QIcon::Normal) {
374 if (
const QGuiApplication *guiApp = qobject_cast<
const QGuiApplication *>(qApp)) {
375 const auto guiAppPrivate =
376 static_cast<
const QGuiApplicationPrivate *>(QObjectPrivate::get(guiApp));
377 const QPixmap generated = guiAppPrivate->applyQIconStyleHelper(mode, pm);
378 if (!generated.isNull())
382 pm.setDevicePixelRatio(calculatedDpr);
383 QPixmapCache::insert(key, pm);
387QSize QPixmapIconEngine::actualSize(
const QSize &size, QIcon::Mode mode, QIcon::State state)
396 if (QPixmapIconEngineEntry *pe = bestMatch(size, scale, mode, state))
397 actualSize = pe->size;
399 return adjustSize(size, actualSize);
402QList<QSize> QPixmapIconEngine::availableSizes(QIcon::Mode mode, QIcon::State state)
405 for (QPixmapIconEngineEntry &pe : pixmaps) {
406 if (pe.mode != mode || pe.state != state)
408 if (pe.size.isEmpty() && pe.pixmap.isNull()) {
409 pe.pixmap = QPixmap(pe.fileName);
410 pe.size = pe.pixmap.size();
412 if (!pe.size.isEmpty() && !sizes.contains(pe.size))
413 sizes.push_back(pe.size);
418void QPixmapIconEngine::addPixmap(
const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state)
420 if (!pixmap.isNull()) {
421 QPixmapIconEngineEntry *pe = tryMatch(pixmap.size() / pixmap.devicePixelRatio(),
422 pixmap.devicePixelRatio(), mode, state);
423 if (pe && pe->size == pixmap.size() && pe->pixmap.devicePixelRatio() == pixmap.devicePixelRatio()) {
425 pe->fileName.clear();
427 pixmaps.emplace_back(pixmap, mode, state);
435 const QString s = image.text(QStringLiteral(
"_q_icoOrigDepth"));
436 return s.isEmpty() ? 32 : s.toInt();
439static inline int findBySize(
const QList<QImage> &images,
const QSize &size)
441 for (qsizetype i = 0; i < images.size(); ++i) {
442 if (images.at(i).size() == size)
448void QPixmapIconEngine::addFile(
const QString &fileName,
const QSize &size, QIcon::Mode mode, QIcon::State state)
450 if (fileName.isEmpty())
452 const QString abs = fileName.startsWith(u':') ? fileName : QFileInfo(fileName).absoluteFilePath();
453 const bool ignoreSize = !size.isValid();
454 ImageReader imageReader(abs, size);
455 const QByteArray format = imageReader.format();
456 if (format.isEmpty())
459 if (format !=
"ico") {
461 if (imageReader.supportsReadSize()) {
463 pixmaps.emplace_back(abs, imageReader.size(), mode, state);
464 }
while (imageReader.jumpToNextImage());
466 while (imageReader.read(&image))
467 pixmaps.emplace_back(abs, image, mode, state);
470 pixmaps.emplace_back(abs, size, mode, state);
478 QList<QImage> icoImages;
479 while (imageReader.read(&image)) {
480 if (ignoreSize || image.size() == size) {
481 const int position = findBySize(icoImages, image.size());
483 if (origIcoDepth(image) > origIcoDepth(icoImages.at(position)))
484 icoImages[position] = image;
486 icoImages.append(image);
490 for (
const QImage &i : std::as_const(icoImages))
491 pixmaps.emplace_back(abs, i, mode, state);
492 if (icoImages.empty() && !ignoreSize)
493 pixmaps.emplace_back(abs, size, mode, state);
496bool QPixmapIconEngine::isNull()
498 return pixmaps.empty();
501QString QPixmapIconEngine::key()
const
503 return "QPixmapIconEngine"_L1;
506QIconEngine *QPixmapIconEngine::clone()
const
508 return new QPixmapIconEngine(*
this);
511bool QPixmapIconEngine::read(QDataStream &in)
521 for (
int i=0; i < num_entries; ++i) {
532 addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
534 QPixmapIconEngineEntry pe(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
536 pixmaps.push_back(std::move(pe));
542bool QPixmapIconEngine::write(QDataStream &out)
const
544 int num_entries = pixmaps.size();
546 for (
int i=0; i < num_entries; ++i) {
547 if (pixmaps.at(i).pixmap.isNull())
548 out << QPixmap(pixmaps.at(i).fileName);
550 out << pixmaps.at(i).pixmap;
551 out << pixmaps.at(i).fileName;
552 out << pixmaps.at(i).size;
553 out << (uint) pixmaps.at(i).mode;
554 out << (uint) pixmaps.at(i).state;
562QFactoryLoader *qt_iconEngineFactoryLoader()
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
749
750
751QIcon::QIcon()
noexcept
757
758
759QIcon::QIcon(
const QPixmap &pixmap)
766
767
768QIcon::QIcon(
const QIcon &other)
776
777
778
779
780
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800QIcon::QIcon(
const QString &fileName)
808
809
810
811QIcon::QIcon(QIconEngine *engine)
812 :d(
new QIconPrivate(engine))
817
818
821 if (d && !d->ref.deref())
826
827
828
829QIcon &QIcon::operator=(
const QIcon &other)
833 if (d && !d->ref.deref())
840
841
842
843
844
845
848
849
850
853
854
855QIcon::operator QVariant()
const
857 return QVariant::fromValue(*
this);
861
862
863
864
865
866
867
868
869
870
871
872qint64 QIcon::cacheKey()
const
876 return (((qint64) d->serialNum) << 32) | ((qint64) (d->detach_no));
880
881
882
883
884
885
886
887QPixmap QIcon::pixmap(
const QSize &size, Mode mode, State state)
const
891 const qreal dpr = -1;
892 return pixmap(size, dpr, mode, state);
896
897
898
899
900
901
902
903
906
907
908
909
910
911
912
913
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932QPixmap QIcon::pixmap(
const QSize &size, qreal devicePixelRatio, Mode mode, State state)
const
938 if (devicePixelRatio == -1)
939 devicePixelRatio = qApp->devicePixelRatio();
941 QPixmap pixmap = d->engine->scaledPixmap(size, mode, state, devicePixelRatio);
945 pixmap.setDevicePixelRatio(d->pixmapDevicePixelRatio(devicePixelRatio, size, pixmap.size()));
949#if QT_DEPRECATED_SINCE(6
, 0
)
951
952
953
954
955
956
957
958
959
960
961
962
964QPixmap QIcon::pixmap(QWindow *window,
const QSize &size, Mode mode, State state)
const
969 qreal devicePixelRatio = window ? window->devicePixelRatio() : qApp->devicePixelRatio();
970 return pixmap(size, devicePixelRatio, mode, state);
976
977
978
979
980
981
982QSize QIcon::actualSize(
const QSize &size, Mode mode, State state)
const
987 const qreal devicePixelRatio = qApp->devicePixelRatio();
990 if (!(devicePixelRatio > 1.0))
991 return d->engine->actualSize(size, mode, state);
993 const QSize actualSize = d->engine->actualSize(size * devicePixelRatio, mode, state);
994 return actualSize / d->pixmapDevicePixelRatio(devicePixelRatio, size, actualSize);
997#if QT_DEPRECATED_SINCE(6
, 0
)
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1011QSize QIcon::actualSize(QWindow *window,
const QSize &size, Mode mode, State state)
const
1016 qreal devicePixelRatio = window ? window->devicePixelRatio() : qApp->devicePixelRatio();
1019 if (!(devicePixelRatio > 1.0))
1020 return d->engine->actualSize(size, mode, state);
1022 QSize actualSize = d->engine->actualSize(size * devicePixelRatio, mode, state);
1023 return actualSize / d->pixmapDevicePixelRatio(devicePixelRatio, size, actualSize);
1028
1029
1030
1031
1032
1033void QIcon::paint(QPainter *painter,
const QRect &rect, Qt::Alignment alignment, Mode mode, State state)
const
1039 const QSize size = d->engine->actualSize(rect.size(), mode, state);
1040 alignment = QGuiApplicationPrivate::visualAlignment(painter->layoutDirection(), alignment);
1043 int w = size.width();
1044 int h = size.height();
1045 if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
1046 y += rect.size().height()/2 - h/2;
1047 else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
1048 y += rect.size().height() - h;
1049 if ((alignment & Qt::AlignRight) == Qt::AlignRight)
1050 x += rect.size().width() - w;
1051 else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
1052 x += rect.size().width()/2 - w/2;
1053 QRect alignedRect(x, y, w, h);
1055 d->engine->paint(painter, alignedRect, mode, state);
1059
1060
1061
1062
1063
1064
1065
1068
1069
1070
1071
1072
1073
1074
1075bool QIcon::isNull()
const
1077 return !d || d->engine->isNull();
1081
1082bool QIcon::isDetached()
const
1084 return !d || d->ref.loadRelaxed() == 1;
1088
1092 if (d->engine->isNull()) {
1093 if (!d->ref.deref())
1097 }
else if (d->ref.loadRelaxed() != 1) {
1098 QIconPrivate *x =
new QIconPrivate(d->engine->clone());
1099 if (!d->ref.deref())
1108
1109
1110
1111
1112
1113
1114
1115
1116void QIcon::addPixmap(
const QPixmap &pixmap, Mode mode, State state)
1118 if (pixmap.isNull())
1122 d =
new QIconPrivate(
new QPixmapIconEngine);
1123 d->engine->addPixmap(pixmap, mode, state);
1128 if (!suffix.isEmpty()) {
1129 const int index = iceLoader()->indexOf(suffix);
1131 if (QIconEnginePlugin *factory = qobject_cast<QIconEnginePlugin*>(iceLoader()->instance(index))) {
1132 return factory->create(fileName);
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169void QIcon::addFile(
const QString &fileName,
const QSize &size, Mode mode, State state)
1171 if (fileName.isEmpty())
1174 bool alreadyAdded =
false;
1177 QFileInfo info(fileName);
1178 QString suffix = info.suffix();
1179#if QT_CONFIG(mimetype)
1180 if (suffix.isEmpty())
1181 suffix = QMimeDatabase().mimeTypeForFile(info).preferredSuffix();
1183 QIconEngine *engine = iconEngineFromSuffix(fileName, suffix);
1185 alreadyAdded = !engine->isNull();
1186 d =
new QIconPrivate(engine ? engine :
new QPixmapIconEngine);
1189 d->engine->addFile(fileName, size, mode, state);
1191 if (d->engine->key() ==
"svg"_L1)
1195 QVarLengthArray<
int, 4> devicePixelRatios;
1196 const auto screens = qApp->screens();
1197 for (
const auto *screen : screens) {
1198 const auto dpr = qCeil(screen->devicePixelRatio());
1199 if (dpr >= 1 && !devicePixelRatios.contains(dpr))
1200 devicePixelRatios.push_back(dpr);
1202 std::sort(devicePixelRatios.begin(), devicePixelRatios.end(), std::greater<
int>());
1203 qreal sourceDevicePixelRatio = std::numeric_limits<qreal>::max();
1204 for (
const auto dpr : std::as_const(devicePixelRatios)) {
1205 if (dpr >= sourceDevicePixelRatio)
1207 const QString atNxFileName = qt_findAtNxFile(fileName, dpr, &sourceDevicePixelRatio);
1208 if (atNxFileName != fileName)
1209 d->engine->addFile(atNxFileName, size, mode, state);
1214
1215
1216
1217QList<QSize> QIcon::availableSizes(Mode mode, State state)
const
1219 if (!d || !d->engine)
1220 return QList<QSize>();
1221 return d->engine->availableSizes(mode, state);
1225
1226
1227
1228
1229
1230
1231
1232QString QIcon::name()
const
1234 if (!d || !d->engine)
1236 return d->engine->iconName();
1240
1241
1242
1243
1244
1245
1246
1247void QIcon::setThemeSearchPaths(
const QStringList &paths)
1249 QIconLoader::instance()->setThemeSearchPath(paths);
1253
1254
1255
1256
1257
1258
1259
1260QStringList QIcon::themeSearchPaths()
1262 return QIconLoader::instance()->themeSearchPaths();
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280QStringList QIcon::fallbackSearchPaths()
1282 return QIconLoader::instance()->fallbackSearchPaths();
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301void QIcon::setFallbackSearchPaths(
const QStringList &paths)
1303 QIconLoader::instance()->setFallbackSearchPaths(paths);
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322void QIcon::setThemeName(
const QString &name)
1324 QIconLoader::instance()->setThemeName(name);
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340QString QIcon::themeName()
1342 return QIconLoader::instance()->themeName();
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359QString QIcon::fallbackThemeName()
1361 return QIconLoader::instance()->fallbackThemeName();
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382void QIcon::setFallbackThemeName(
const QString &name)
1384 QIconLoader::instance()->setFallbackThemeName(name);
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408QIcon QIcon::fromTheme(
const QString &name)
1413 if (QIcon *cachedIcon = qtIconCache()->object(name))
1416 if (QDir::isAbsolutePath(name))
1419 QIcon icon(
new QThemeIconEngine(name));
1420 qtIconCache()->insert(name,
new QIcon(icon));
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448QIcon QIcon::fromTheme(
const QString &name,
const QIcon &fallback)
1450 QIcon icon = fromTheme(name);
1452 if (icon.isNull() || icon.availableSizes().isEmpty())
1459
1460
1461
1462
1463
1464
1465bool QIcon::hasThemeIcon(
const QString &name)
1467 QIcon icon = fromTheme(name);
1469 return icon.name() == name;
1481 "document-open-recent",
1482 "document-page-setup",
1484 "document-print-preview",
1485 "document-properties",
1500 "format-indent-less",
1501 "format-indent-more",
1502 "format-justify-center",
1503 "format-justify-fill",
1504 "format-justify-left",
1505 "format-justify-right",
1506 "format-text-direction-ltr",
1507 "format-text-direction-rtl",
1509 "format-text-italic",
1510 "format-text-underline",
1511 "format-text-strikethrough",
1525 "mail-mark-important",
1530 "mail-reply-sender",
1533 "media-playback-pause",
1534 "media-playback-start",
1535 "media-playback-stop",
1537 "media-seek-backward",
1538 "media-seek-forward",
1539 "media-skip-backward",
1540 "media-skip-forward",
1541 "object-rotate-left",
1542 "object-rotate-right",
1544 "system-lock-screen",
1549 "tools-check-spelling",
1560 "audio-input-microphone",
1575 "multimedia-player",
1583 "appointment-missed",
1585 "audio-volume-high",
1587 "audio-volume-medium",
1588 "audio-volume-muted",
1592 "dialog-information",
1596 "folder-drag-accept",
1605 "media-playlist-repeat",
1606 "media-playlist-shuffle",
1611 "software-update-available",
1612 "software-update-urgent",
1614 "sync-synchronizing",
1618 "weather-clear-night",
1619 "weather-few-clouds",
1620 "weather-few-clouds-night",
1626static_assert(QIcon::ThemeIcon::NThemeIcons == QIcon::ThemeIcon(themeIconMapping.count()));
1630 using ThemeIconIndex = std::underlying_type_t<QIcon::ThemeIcon>;
1631 const auto index =
static_cast<ThemeIconIndex>(icon);
1632 Q_ASSERT(index < themeIconMapping.count());
1633 return QLatin1StringView(themeIconMapping.viewAt(index));
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829bool QIcon::hasThemeIcon(QIcon::ThemeIcon icon)
1831 return hasThemeIcon(themeIconName(icon));
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857QIcon QIcon::fromTheme(QIcon::ThemeIcon icon)
1859 return fromTheme(themeIconName(icon));
1862QIcon QIcon::fromTheme(QIcon::ThemeIcon icon,
const QIcon &fallback)
1864 return fromTheme(themeIconName(icon), fallback);
1868
1869
1870
1871
1872
1873
1874void QIcon::setIsMask(
bool isMask)
1876 if (isMask == (d && d->is_mask))
1881 d =
new QIconPrivate(
new QPixmapIconEngine);
1882 d->is_mask = isMask;
1886
1887
1888
1889
1890
1891
1892
1893
1894bool QIcon::isMask()
const
1902
1903
1904#if !defined(QT_NO_DATASTREAM)
1906
1907
1908
1909
1910
1911
1912
1913
1915QDataStream &operator<<(QDataStream &s,
const QIcon &icon)
1917 if (s.version() >= QDataStream::Qt_4_3) {
1918 if (icon.isNull()) {
1921 s << icon.d->engine->key();
1922 icon.d->engine->write(s);
1924 }
else if (s.version() == QDataStream::Qt_4_2) {
1925 if (icon.isNull()) {
1928 QPixmapIconEngine *engine =
static_cast<QPixmapIconEngine *>(icon.d->engine);
1929 int num_entries = engine->pixmaps.size();
1931 for (
int i=0; i < num_entries; ++i) {
1932 s << engine->pixmaps.at(i).pixmap;
1933 s << engine->pixmaps.at(i).fileName;
1934 s << engine->pixmaps.at(i).size;
1935 s << (uint) engine->pixmaps.at(i).mode;
1936 s << (uint) engine->pixmaps.at(i).state;
1940 s << QPixmap(icon.pixmap(22,22));
1946
1947
1948
1949
1950
1951
1955 if (s.version() >= QDataStream::Qt_4_3) {
1959 if (key ==
"QPixmapIconEngine"_L1) {
1960 icon.d =
new QIconPrivate(
new QPixmapIconEngine);
1961 icon.d->engine->read(s);
1962 }
else if (key ==
"QIconLoaderEngine"_L1 || key ==
"QThemeIconEngine"_L1) {
1963 icon.d =
new QIconPrivate(
new QThemeIconEngine);
1964 icon.d->engine->read(s);
1966 const int index = iceLoader()->indexOf(key);
1968 if (QIconEnginePlugin *factory = qobject_cast<QIconEnginePlugin*>(iceLoader()->instance(index))) {
1969 if (QIconEngine *engine= factory->create()) {
1976 }
else if (s.version() == QDataStream::Qt_4_2) {
1986 for (
int i=0; i < num_entries; ++i) {
1993 icon.addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
1995 icon.addPixmap(pm, QIcon::Mode(mode), QIcon::State(state));
2007#ifndef QT_NO_DEBUG_STREAM
2010 QDebugStateSaver saver(dbg);
2017 if (!i.name().isEmpty())
2018 dbg << i.name() <<
',';
2019 dbg <<
"availableSizes[normal,Off]=" << i.availableSizes()
2020 <<
",cacheKey=" << Qt::showbase << Qt::hex << i.cacheKey() << Qt::dec << Qt::noshowbase;
2028
2029
2030
2033
2034
2035
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2050 qreal *sourceDevicePixelRatio)
2052 if (sourceDevicePixelRatio)
2053 *sourceDevicePixelRatio = 1;
2054 if (targetDevicePixelRatio <= 1.0)
2055 return baseFileName;
2057 static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty(
"QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
2058 if (disableNxImageLoading)
2059 return baseFileName;
2061 int dotIndex = baseFileName.lastIndexOf(u'.');
2062 if (dotIndex == -1) {
2063 dotIndex = baseFileName.size();
2064 }
else if (dotIndex >= 2 && baseFileName[dotIndex - 1] == u'9'
2065 && baseFileName[dotIndex - 2] == u'.') {
2070 QString atNxfileName = baseFileName;
2071 atNxfileName.insert(dotIndex,
"@2x"_L1);
2073 for (
int n = qMin(qCeil(targetDevicePixelRatio), 9); n > 1; --n) {
2074 atNxfileName[dotIndex + 1] = QLatin1Char(
'0' + n);
2075 if (QFile::exists(atNxfileName)) {
2076 if (sourceDevicePixelRatio)
2077 *sourceDevicePixelRatio = n;
2078 return atNxfileName;
2082 return baseFileName;
QIconPrivate(QIconEngine *e)
static void clearIconCache()
QString fileName() const
If the currently assigned device is a QFile, or if setFileName() has been called, this function retur...
\macro QT_RESTRICTED_CAST_FROM_ASCII
Combined button and popup list for selecting options.
QDataStream & operator>>(QDataStream &s, QKeyCombination &combination)
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
static void qt_cleanup_icon_cache()
static constexpr auto themeIconMapping
static int origIcoDepth(const QImage &image)
static qint64 area(const QSize &s)
static int nextSerialNumCounter()
static QIconEngine * iconEngineFromSuffix(const QString &fileName, const QString &suffix)
QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio, qreal *sourceDevicePixelRatio)
static int findBySize(const QList< QImage > &images, const QSize &size)
static QPixmapIconEngineEntry * bestSizeScaleMatch(const QSize &size, qreal scale, QPixmapIconEngineEntry *pa, QPixmapIconEngineEntry *pb)
static constexpr QLatin1StringView themeIconName(QIcon::ThemeIcon icon)
#define QIconEngineFactoryInterface_iid
Q_GLOBAL_STATIC_WITH_ARGS(PermissionStatusHash, g_permissionStatusHash,({ { qMetaTypeId< QCameraPermission >(), Qt::PermissionStatus::Undetermined }, { qMetaTypeId< QMicrophonePermission >(), Qt::PermissionStatus::Undetermined }, { qMetaTypeId< QBluetoothPermission >(), Qt::PermissionStatus::Undetermined }, { qMetaTypeId< QContactsPermission >(), Qt::PermissionStatus::Undetermined }, { qMetaTypeId< QCalendarPermission >(), Qt::PermissionStatus::Undetermined }, { qMetaTypeId< QLocationPermission >(), Qt::PermissionStatus::Undetermined } }))