4#include <private/qiconloader_p.h>
6#include <private/qguiapplication_p.h>
7#include <private/qicon_p.h>
9#include <QtGui/QIconEnginePlugin>
10#include <QtGui/QPixmapCache>
11#include <qpa/qplatformtheme.h>
12#include <QtGui/QIconEngine>
13#include <QtGui/QPalette>
14#include <QtCore/qmath.h>
15#include <QtCore/QList>
17#include <QtCore/qloggingcategory.h>
18#if QT_CONFIG(settings)
19#include <QtCore/QSettings>
21#include <QtGui/QPainter>
23#include <private/qhexstring_p.h>
29using namespace
Qt::StringLiterals;
45 m_themeKey(1), m_supportsSvg(
false), m_initialized(
false)
51 const auto override =
qgetenv(
"QT_QPA_SYSTEM_ICON_THEME");
52 if (!
override.isEmpty())
97 qCDebug(lcIconLoader) <<
"Initialized icon loader with system theme"
98 << m_systemTheme <<
"and SVG support" << m_supportsSvg;
115 return iconLoaderInstance();
122 const QString currentSystemTheme = m_systemTheme;
126 if (m_systemTheme != currentSystemTheme)
127 qCDebug(lcIconLoader) <<
"Updated system theme to" << m_systemTheme;
144 return m_userTheme.
isEmpty() ? m_systemTheme : m_userTheme;
172 qCDebug(lcIconLoader) <<
"Setting theme search path to" << searchPaths;
173 m_iconDirs = searchPaths;
180 if (m_iconDirs.isEmpty()) {
183 m_iconDirs.append(
":/icons"_L1);
190 qCDebug(lcIconLoader) <<
"Setting fallback search path to" << searchPaths;
191 m_fallbackDirs = searchPaths;
197 if (m_fallbackDirs.isEmpty()) {
200 return m_fallbackDirs;
218 const unsigned char *m_data;
251 m_size = m_file.
size();
262 quint32 dirListOffset = read32(8);
263 quint32 dirListLen = read32(dirListOffset);
264 for (
uint i = 0;
i < dirListLen; ++
i) {
266 if (!m_isValid ||
offset >= m_size || lastModified <
QFileInfo(dirName + u
'/'
276 quint32 h =
static_cast<signed char>(*p);
277 for (
p += 1; *
p !=
'\0';
p++)
278 h = (
h << 5) -
h + *
p;
296 quint32 hashOffset = read32(4);
297 quint32 hashBucketCount = read32(hashOffset);
299 if (!
isValid() || hashBucketCount == 0) {
305 quint32 bucketOffset = read32(hashOffset + 4 + bucketIndex * 4);
306 while (bucketOffset > 0 && bucketOffset <= m_size - 12) {
307 quint32 nameOff = read32(bucketOffset + 4);
308 if (nameOff < m_size && strcmp(
reinterpret_cast<const char*
>(
m_data + nameOff), nameUtf8) == 0) {
309 quint32 dirListOffset = read32(8);
310 quint32 dirListLen = read32(dirListOffset);
312 quint32 listOffset = read32(bucketOffset+8);
313 quint32 listLen = read32(listOffset);
315 if (!m_isValid || listOffset + 4 + 8 * listLen > m_size) {
320 ret.reserve(listLen);
321 for (
uint j = 0;
j < listLen && m_isValid; ++
j) {
322 quint32 dirIndex = read16(listOffset + 4 + 8 *
j);
323 quint32 o = read32(dirListOffset + 4 + dirIndex*4);
324 if (!m_isValid || dirIndex >= dirListLen ||
o >= m_size) {
328 ret.append(
reinterpret_cast<const char*
>(
m_data) +
o);
332 bucketOffset = read32(bucketOffset);
343 for (
int i = 0 ;
i < iconDirs.size() ; ++
i) {
344 QDir iconDir(iconDirs[
i]);
348 if (themeDirInfo.
isDir()) {
349 m_contentDirs << themeDir;
350 m_gtkCaches << QSharedPointer<QIconCacheGtkReader>::create(themeDir);
354 themeIndex.
setFileName(themeDir +
"/index.theme"_L1);
359#if QT_CONFIG(settings)
360 if (themeIndex.
exists()) {
364 if (
key.endsWith(
"/Size"_L1)) {
373 if (
type ==
"Fixed"_L1)
375 else if (
type ==
"Scalable"_L1)
388 dirInfo.
scale = indexReader.
value(directoryKey +
"/Scale"_L1, 1).
toInt();
389 m_keyList.
append(dirInfo);
396 m_parents.removeAll(
QString());
412 result.removeAll(
"hicolor"_L1);
429 qCDebug(lcIconLoader) <<
"Finding icon" << iconName <<
"in theme" <<
themeName;
451 while (
info.entries.empty()) {
452 const QString svgIconName = iconNameFallback +
".svg"_L1;
453 const QString pngIconName = iconNameFallback +
".png"_L1;
456 for (
int i = 0;
i < contentDirs.size(); ++
i) {
462 if (
cache->isValid()) {
463 const auto result =
cache->lookup(iconNameFallback);
464 if (
cache->isValid()) {
470 auto it = std::find_if(subDirsCopy.
cbegin(), subDirsCopy.
cend(),
472 return info.path == path; } );
473 if (
it != subDirsCopy.
cend()) {
480 QString contentDir = contentDirs.at(
i) + u
'/';
481 for (
int j = 0;
j < subDirs.
size() ; ++
j) {
484 const QString pngPath = subDir + pngIconName;
486 auto iconEntry = std::make_unique<PixmapEntry>();
488 iconEntry->filename = pngPath;
491 info.entries.insert(
info.entries.begin(), std::move(iconEntry));
492 }
else if (m_supportsSvg) {
493 const QString svgPath = subDir + svgIconName;
495 auto iconEntry = std::make_unique<ScalableEntry>();
497 iconEntry->filename = svgPath;
498 info.entries.push_back(std::move(iconEntry));
504 if (!
info.entries.empty()) {
505 info.iconName = iconNameFallback.toString();
510 const int indexOfDash = iconNameFallback.lastIndexOf(u
'-');
511 if (indexOfDash == -1)
514 iconNameFallback.truncate(indexOfDash);
517 if (
info.entries.empty()) {
519 qCDebug(lcIconLoader) <<
"Did not find matching icons in theme;"
520 <<
"trying parent themes" << parents
521 <<
"skipping visited" << visited;
524 for (
int i = 0 ;
i < parents.size() ; ++
i) {
526 const QString parentTheme = parents.at(
i).trimmed();
528 if (!visited.contains(parentTheme))
529 info = findIconHelper(parentTheme, iconName, visited);
531 if (!
info.entries.empty())
541 qCDebug(lcIconLoader) <<
"Looking up fallback icon" << iconName;
545 const QString pngIconName = iconName +
".png"_L1;
546 const QString xpmIconName = iconName +
".xpm"_L1;
547 const QString svgIconName = iconName +
".svg"_L1;
550 for (
const QString &iconDir: searchPaths) {
551 QDir currentDir(iconDir);
552 std::unique_ptr<QIconLoaderEngineEntry> iconEntry;
553 if (currentDir.exists(pngIconName)) {
554 iconEntry = std::make_unique<PixmapEntry>();
556 iconEntry->filename = currentDir.filePath(pngIconName);
557 }
else if (currentDir.exists(xpmIconName)) {
558 iconEntry = std::make_unique<PixmapEntry>();
560 iconEntry->filename = currentDir.filePath(xpmIconName);
561 }
else if (m_supportsSvg &&
562 currentDir.exists(svgIconName)) {
563 iconEntry = std::make_unique<ScalableEntry>();
565 iconEntry->filename = currentDir.filePath(svgIconName);
568 info.entries.push_back(std::move(iconEntry));
573 if (!
info.entries.empty())
574 info.iconName = iconName;
592 iconInfo = lookupFallbackIcon(
name);
594 qCDebug(lcIconLoader) <<
"Resulting icon entries" << iconInfo.
entries;
598#ifndef QT_NO_DEBUG_STREAM
605 debug << static_cast<const void *>(
engine);
612 debug <<
"QIconEngine(nullptr)";
620 qCDebug(lcIconLoader) <<
"Resolving icon engine for icon" << iconName;
647 , m_iconName(iconName)
653 , m_iconName(
other.m_iconName)
662 return u
"QThemeIconEngine"_s;
684 auto mostRecentThemeKey = iconLoader->themeKey();
685 if (mostRecentThemeKey != m_themeKey) {
686 qCDebug(lcIconLoader) <<
"Theme key" << mostRecentThemeKey <<
"is different"
687 <<
"than cached key" << m_themeKey <<
"for icon" << m_iconName;
688 m_proxiedEngine.reset(iconLoader->iconEngine(m_iconName));
689 m_themeKey = mostRecentThemeKey;
691 return m_proxiedEngine.get();
706 : m_iconName(iconName)
707 , m_info(
QIconLoader::instance()->loadIcon(m_iconName))
719bool QIconLoaderEngine::hasIcon()
const
721 return !(m_info.
entries.empty());
737 if (
dir.scale != iconscale)
744 return iconsize <=
dir.maxSize &&
745 iconsize >=
dir.minSize;
748 return iconsize >=
dir.
size -
dir.threshold &&
764 const int scaledIconSize = iconsize * iconscale;
769 if (scaledIconSize <
dir.minSize *
dir.scale)
770 return dir.minSize *
dir.scale - scaledIconSize;
771 else if (scaledIconSize >
dir.maxSize *
dir.scale)
772 return scaledIconSize -
dir.maxSize *
dir.scale;
778 return dir.minSize *
dir.scale - scaledIconSize;
779 else if (scaledIconSize > (
dir.
size +
dir.threshold) *
dir.scale)
780 return scaledIconSize -
dir.maxSize *
dir.scale;
805 int minimalSize = INT_MAX;
906 return u
"QIconLoaderEngine"_s;
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
QString path() const
Returns the path.
uchar * map(qint64 offset, qint64 size, MemoryMapFlags flags=NoOptions)
Maps size bytes of the file into memory starting at offset.
\inmodule QtCore \reentrant
QDateTime lastModified() const
Returns the date and time when the file was last modified.
QString absoluteFilePath() const
Returns an absolute path including the file name.
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
bool exists() const
Returns true if the file exists; otherwise returns false.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
void setFileName(const QString &name)
Sets the name of the file.
QString fileName() const override
Returns the name set by setFileName() or to the QFile constructors.
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
qint64 size() const override
\reimp
static QPlatformTheme * platformTheme()
static QPalette palette()
Returns the current application palette.
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
QIconCacheGtkReader(const QString &themeDir)
QList< const char * > lookup(QStringView)
The QIconEngine class provides an abstract base class for QIcon renderers.
An icon engine based on icon entries collected by QIconLoader.
QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) override
Returns the actual size of the icon the engine provides for the requested size, mode and state.
static Q_GUI_EXPORT QIconLoaderEngineEntry * entryForSize(const QThemeIconInfo &info, const QSize &size, int scale=1)
QString key() const override
\variable QIconEngine::ScaledPixmapArgument::size
QPixmap scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) override
QIconLoaderEngine(const QString &iconName=QString())
QString iconName() override
QList< QSize > availableSizes(QIcon::Mode mode, QIcon::State state) override
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override
Uses the given painter to paint the icon with the required mode and state into the rectangle rect.
QIconEngine * clone() const override
Reimplement this method to return a clone of this icon engine.
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override
Returns the icon as a pixmap with the required size, mode, and state.
QThemeIconInfo loadIcon(const QString &iconName) const
void setFallbackThemeName(const QString &themeName)
bool hasUserTheme() const
QStringList fallbackSearchPaths() const
void setFallbackSearchPaths(const QStringList &searchPaths)
QIconDirInfo dirInfo(int dirindex)
void setThemeSearchPath(const QStringList &searchPaths)
static QIconLoader * instance()
QString fallbackThemeName() const
QStringList themeSearchPaths() const
QIconEngine * iconEngine(const QString &iconName) const
QString themeName() const
void setThemeName(const QString &themeName)
QStringList contentDirs()
QStringList parents() const
QList< QIconDirInfo > keyList()
QList< QSharedPointer< QIconCacheGtkReader > > m_gtkCaches
The QIcon class provides scalable icons in different modes and states.
static QStringList fallbackSearchPaths()
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Mode
This enum type describes the mode for which a pixmap is intended to be used.
QList< QSize > availableSizes(Mode mode=Normal, State state=Off) const
State
This enum describes the state for which a pixmap is intended to be used.
static QStringList themeSearchPaths()
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
const_iterator cend() const noexcept
void append(parameter_type t)
const_iterator cbegin() const noexcept
static QObjectPrivate * get(QObject *o)
qreal devicePixelRatio() const
The QPainter class performs low-level painting on widgets and other paint devices.
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or \nullptr if the painter is n...
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
QSize size() const
Returns the size of the pixmap.
bool load(const QString &fileName, const char *format=nullptr, Qt::ImageConversionFlags flags=Qt::AutoColor)
Loads a pixmap from the file with the given fileName.
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
qint64 cacheKey() const
Returns a number that identifies this QPixmap.
\inmodule QtCore\reentrant
QVariant value(QAnyStringView key, const QVariant &defaultValue) const
Returns the value for setting key.
QStringList allKeys() const
Returns a list of all keys, including subkeys, that can be read using the QSettings object.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
void scale(int w, int h, Qt::AspectRatioMode mode) noexcept
Scales the size to a rectangle with the given width and height, according to the specified mode:
constexpr bool isNull() const noexcept
Returns true if both the width and height is 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype size() const
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString & append(QChar c)
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
A named-based icon engine for providing theme icons.
QThemeIconEngine(const QString &iconName=QString())
QString key() const override
\variable QIconEngine::ScaledPixmapArgument::size
bool write(QDataStream &out) const override
Writes the contents of this engine to the QDataStream out.
bool read(QDataStream &in) override
Reads icon engine contents from the QDataStream in.
QIconEngine * clone() const override
Reimplement this method to return a clone of this icon engine.
QIconEngine * proxiedEngine() const override
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QStringList toStringList() const
Returns the variant as a QStringList if the variant has userType() \l QMetaType::QStringList,...
QHash< int, QWidget * > hash
[35multi]
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
static QStringList systemIconSearchPaths()
QFactoryLoader * qt_iconEngineFactoryLoader()
QDebug operator<<(QDebug debug, const std::unique_ptr< QIconLoaderEngineEntry > &entry)
static QStringList systemFallbackSearchPaths()
static int directorySizeDistance(const QIconDirInfo &dir, int iconsize, int iconscale)
static QString systemThemeName()
static QString systemFallbackThemeName()
static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize, int iconscale)
static quint32 icon_name_hash(const char *p)
static int closestMatch(QRgb pixel, const QList< QRgb > &clut)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr T qAbs(const T &t)
static QString themeName()
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLsizei GLfloat distance
GLenum GLuint GLintptr offset
GLfloat GLfloat GLfloat GLfloat h
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
GLsizei const GLchar *const * path
GLenum GLenum GLenum GLenum GLenum scale
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
unsigned long long quint64
static const struct @437 keyMap[]
QFileInfo info(fileName)
[8]
QTextStream out(stdout)
[7]
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override
QThemeIconEntries entries
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override