QThemeIconEntries QIconLoader::loadIcon(const QString &name) const { if (!themeName().isEmpty()) { QStringList visited; return findIconHelper(themeName(), name, visited); } return QThemeIconEntries(); }
static QString findIconHelper(const QString &pathName, const QString &icon) { QStringList extensions; extensions << ""; extensions << ".png"; extensions << ".svg"; // qDebug() << "Trying " << pathName << " for " << icon; foreach (const QString &extension, extensions) { if (QFile::exists(pathName + QDir::separator() + icon + extension)) return pathName + QDir::separator() + icon + extension; } QStringList entryList = QDir(pathName).entryList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot); foreach (const QString &dir, entryList) { QString retval = findIconHelper(QDir(pathName).absoluteFilePath(dir), icon); if (!retval.isNull()) return retval; }
QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, const QString &iconName, QStringList &visited) const { QThemeIconEntries entries; Q_ASSERT(!themeName.isEmpty()); QPixmap pixmap; // Used to protect against potential recursions visited << themeName; QIconTheme theme = themeList.value(themeName); if (!theme.isValid()) { theme = QIconTheme(themeName); if (!theme.isValid()) theme = QIconTheme(fallbackTheme()); themeList.insert(themeName, theme); } QString contentDir = theme.contentDir() + QLatin1Char('/'); QList<QIconDirInfo> subDirs = theme.keyList(); const QString svgext(QLatin1String(".svg")); const QString pngext(QLatin1String(".png")); // Add all relevant files for (int i = 0; i < subDirs.size() ; ++i) { const QIconDirInfo &dirInfo = subDirs.at(i); QString subdir = dirInfo.path; QDir currentDir(contentDir + subdir); if (currentDir.exists(iconName + pngext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + pngext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards entries.prepend(iconEntry); } else if (m_supportsSvg && currentDir.exists(iconName + svgext)) { ScalableEntry *iconEntry = new ScalableEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + svgext); entries.append(iconEntry); } } if (entries.isEmpty()) { const QStringList parents = theme.parents(); // Search recursively through inherited themes for (int i = 0 ; i < parents.size() ; ++i) { const QString parentTheme = parents.at(i).trimmed(); if (!visited.contains(parentTheme)) // guard against recursion entries = findIconHelper(parentTheme, iconName, visited); if (!entries.isEmpty()) // success break; } } return entries; }
QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, const QString &iconName, QStringList &visited) const { QThemeIconEntries entries; Q_ASSERT(!themeName.isEmpty()); QPixmap pixmap; // Used to protect against potential recursions visited << themeName; QIconTheme theme = themeList.value(themeName); if (!theme.isValid()) { theme = QIconTheme(themeName); if (!theme.isValid()) theme = QIconTheme(QIcon::themeName());//fallbackTheme()); themeList.insert(themeName, theme); } QString contentDir = theme.contentDir() + QLatin1Char('/'); QList<QIconDirInfo> subDirs = theme.keyList(); const QString svgext(QLatin1String(".svg")); const QString pngext(QLatin1String(".png")); const QString xpmext(QLatin1String(".xpm")); // Add all relevant files for (int i = 0; i < subDirs.size() ; ++i) { const QIconDirInfo &dirInfo = subDirs.at(i); QString subdir = dirInfo.path; QDir currentDir(contentDir + subdir); if (currentDir.exists(iconName + pngext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + pngext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards entries.prepend(iconEntry); } else if (m_supportsSvg && currentDir.exists(iconName + svgext)) { ScalableEntry *iconEntry = new ScalableEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + svgext); entries.append(iconEntry); } else if (currentDir.exists(iconName + xpmext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + xpmext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards entries.append(iconEntry); } } if (entries.isEmpty()) { const QStringList parents = theme.parents(); // Search recursively through inherited themes for (int i = 0 ; i < parents.size() ; ++i) { const QString parentTheme = parents.at(i).trimmed(); if (!visited.contains(parentTheme)) // guard against recursion entries = findIconHelper(parentTheme, iconName, visited); if (!entries.isEmpty()) // success break; } } /********************************************************************* Author: Kaitlin Rupert <*****@*****.**> Date: Aug 12, 2010 Description: Make it so that the QIcon loader honors /usr/share/pixmaps directory. This is a valid directory per the Freedesktop.org icon theme specification. Bug: https://bugreports.qt.nokia.com/browse/QTBUG-12874 *********************************************************************/ #ifdef Q_OS_LINUX /* Freedesktop standard says to look in /usr/share/pixmaps last */ if (entries.isEmpty()) { const QString pixmaps(QLatin1String("/usr/share/pixmaps")); QDir currentDir(pixmaps); if (currentDir.exists(iconName + pngext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = pixmaps; iconEntry->filename = currentDir.filePath(iconName + pngext); // Notice we ensure that pixmap entries allways come before // scalable to preserve search order afterwards entries.prepend(iconEntry); } else if (m_supportsSvg && currentDir.exists(iconName + svgext)) { ScalableEntry *iconEntry = new ScalableEntry; iconEntry->dir = pixmaps; iconEntry->filename = currentDir.filePath(iconName + svgext); entries.append(iconEntry); } else if (currentDir.exists(iconName + xpmext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = pixmaps; iconEntry->filename = currentDir.filePath(iconName + xpmext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards entries.append(iconEntry); } } #endif return entries; }
QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, const QString &iconName, QStringList &visited) const { QThemeIconInfo info; Q_ASSERT(!themeName.isEmpty()); QPixmap pixmap; // Used to protect against potential recursions visited << themeName; QIconTheme theme = themeList.value(themeName); if (!theme.isValid()) { theme = QIconTheme(themeName); if (!theme.isValid()) theme = QIconTheme(fallbackTheme()); themeList.insert(themeName, theme); } const QStringList contentDirs = theme.contentDirs(); const QVector<QIconDirInfo> subDirs = theme.keyList(); QString iconNameFallback = iconName; // Iterate through all icon's fallbacks in current theme while (info.entries.isEmpty()) { const QString svgIconName = iconNameFallback + QLatin1String(".svg"); const QString pngIconName = iconNameFallback + QLatin1String(".png"); // Add all relevant files for (int i = 0; i < contentDirs.size(); ++i) { QString contentDir = contentDirs.at(i) + QLatin1Char('/'); for (int j = 0; j < subDirs.size() ; ++j) { const QIconDirInfo &dirInfo = subDirs.at(j); QString subdir = dirInfo.path; QDir currentDir(contentDir + subdir); if (currentDir.exists(pngIconName)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(pngIconName); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards info.entries.prepend(iconEntry); } else if (m_supportsSvg && currentDir.exists(svgIconName)) { ScalableEntry *iconEntry = new ScalableEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(svgIconName); info.entries.append(iconEntry); } } } if (!info.entries.isEmpty()) { info.iconName = iconNameFallback; break; } // If it's possible - find next fallback for the icon const int indexOfDash = iconNameFallback.lastIndexOf(QLatin1Char('-')); if (indexOfDash == -1) break; iconNameFallback.truncate(indexOfDash); } if (info.entries.isEmpty()) { const QStringList parents = theme.parents(); // Search recursively through inherited themes for (int i = 0 ; i < parents.size() ; ++i) { const QString parentTheme = parents.at(i).trimmed(); if (!visited.contains(parentTheme)) // guard against recursion info = findIconHelper(parentTheme, iconName, visited); if (!info.entries.isEmpty()) // success break; } } return info; }