// Queries the system theme and invalidates existing // icons if the theme has changed. void QIconLoader::updateSystemTheme() { // Only change if this is not explicitly set by the user if (m_userTheme.isEmpty()) { QString theme = systemThemeName(); if (theme.isEmpty()) theme = fallbackTheme(); if (theme != m_systemTheme) { m_systemTheme = theme; invalidateKey(); } } }
void QIconLoader::ensureInitialized() { if (!m_initialized) { m_initialized = true; Q_ASSERT(qApp); m_systemTheme = systemThemeName(); if (m_systemTheme.isEmpty()) m_systemTheme = fallbackTheme(); #ifndef QT_NO_LIBRARY if (qt_iconEngineFactoryLoader()->keyMap().key(QLatin1String("svg"), -1) != -1) m_supportsSvg = true; #endif //QT_NO_LIBRARY } }
// We lazily initialize the loader to make static icons // work. Though we do not officially support this. void QIconLoader::ensureInitialized() { if (!m_initialized) { m_initialized = true; Q_ASSERT(qApp); m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName(); if (m_systemTheme.isEmpty()) m_systemTheme = fallbackTheme(); #ifndef QT_NO_LIBRARY QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive); if (iconFactoryLoader.keys().contains(QLatin1String("svg"))) m_supportsSvg = true; #endif //QT_NO_LIBRARY } }
void QIconLoader::ensureInitialized() { if (!m_initialized) { m_initialized = true; Q_ASSERT(qApp); m_systemTheme = systemThemeName(); if (m_systemTheme.isEmpty()) m_systemTheme = fallbackTheme(); #ifndef QT_NO_LIBRARY QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive); if (iconFactoryLoader.keyMap().key(QLatin1String("svg"), -1) != -1) m_supportsSvg = true; #endif //QT_NO_LIBRARY } }
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; }
QIconTheme::QIconTheme(const QString &themeName) : m_valid(false) { QFile themeIndex; QList <QIconDirInfo> keyList; QStringList iconDirs = QIcon::themeSearchPaths(); for ( int i = 0 ; i < iconDirs.size() ; ++i) { QDir iconDir(iconDirs[i]); QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); if (themeIndex.exists()) { m_contentDir = themeDir; m_valid = true; break; } } #ifndef QT_NO_SETTINGS if (themeIndex.exists()) { const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); QStringListIterator keyIterator(indexReader.allKeys()); while (keyIterator.hasNext()) { const QString key = keyIterator.next(); if (key.endsWith(QLatin1String("/Size"))) { // Note the QSettings ini-format does not accept // slashes in key names, hence we have to cheat if (int size = indexReader.value(key).toInt()) { QString directoryKey = key.left(key.size() - 5); QIconDirInfo dirInfo(directoryKey); dirInfo.size = size; QString type = indexReader.value(directoryKey + QLatin1String("/Type") ).toString(); if (type == QLatin1String("Fixed")) dirInfo.type = QIconDirInfo::Fixed; else if (type == QLatin1String("Scalable")) dirInfo.type = QIconDirInfo::Scalable; else dirInfo.type = QIconDirInfo::Threshold; dirInfo.threshold = indexReader.value(directoryKey + QLatin1String("/Threshold"), 2).toInt(); dirInfo.minSize = indexReader.value(directoryKey + QLatin1String("/MinSize"), size).toInt(); dirInfo.maxSize = indexReader.value(directoryKey + QLatin1String("/MaxSize"), size).toInt(); m_keyList.append(dirInfo); } } } // Parent themes provide fallbacks for missing icons m_parents = indexReader.value( QLatin1String("Icon Theme/Inherits")).toStringList(); // Ensure a default platform fallback for all themes if (m_parents.isEmpty()) { const QString fallback = fallbackTheme(); if (!fallback.isEmpty()) m_parents.append(fallback); } // Ensure that all themes fall back to hicolor if (!m_parents.contains(QLatin1String("hicolor"))) m_parents.append(QLatin1String("hicolor")); } #endif //QT_NO_SETTINGS }
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; }