diff options
Diffstat (limited to 'src/gui/image/qiconloader.cpp')
-rw-r--r-- | src/gui/image/qiconloader.cpp | 124 |
1 files changed, 75 insertions, 49 deletions
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 06491f1155..4510125816 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -172,11 +172,15 @@ QIconTheme::QIconTheme(const QString &themeName) 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; + QFileInfo themeDirInfo(themeDir); + + if (themeDirInfo.isDir()) + m_contentDirs << themeDir; + + if (!m_valid) { + themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); + if (themeIndex.exists()) + m_valid = true; } } #ifndef QT_NO_SETTINGS @@ -239,11 +243,11 @@ QIconTheme::QIconTheme(const QString &themeName) #endif //QT_NO_SETTINGS } -QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, - const QString &iconName, - QStringList &visited) const +QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, + const QString &iconName, + QStringList &visited) const { - QThemeIconEntries entries; + QThemeIconInfo info; Q_ASSERT(!themeName.isEmpty()); QPixmap pixmap; @@ -260,34 +264,54 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, themeList.insert(themeName, theme); } - QString contentDir = theme.contentDir() + QLatin1Char('/'); + const QStringList contentDirs = theme.contentDirs(); const QVector<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); + 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 (entries.isEmpty()) { + if (info.entries.isEmpty()) { const QStringList parents = theme.parents(); // Search recursively through inherited themes for (int i = 0 ; i < parents.size() ; ++i) { @@ -295,23 +319,23 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, const QString parentTheme = parents.at(i).trimmed(); if (!visited.contains(parentTheme)) // guard against recursion - entries = findIconHelper(parentTheme, iconName, visited); + info = findIconHelper(parentTheme, iconName, visited); - if (!entries.isEmpty()) // success + if (!info.entries.isEmpty()) // success break; } } - return entries; + return info; } -QThemeIconEntries QIconLoader::loadIcon(const QString &name) const +QThemeIconInfo QIconLoader::loadIcon(const QString &name) const { if (!themeName().isEmpty()) { QStringList visited; return findIconHelper(themeName(), name, visited); } - return QThemeIconEntries(); + return QThemeIconInfo(); } @@ -325,7 +349,7 @@ QIconLoaderEngine::QIconLoaderEngine(const QString& iconName) QIconLoaderEngine::~QIconLoaderEngine() { - qDeleteAll(m_entries); + qDeleteAll(m_info.entries); } QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other) @@ -353,17 +377,19 @@ bool QIconLoaderEngine::write(QDataStream &out) const bool QIconLoaderEngine::hasIcon() const { - return !(m_entries.isEmpty()); + return !(m_info.entries.isEmpty()); } // Lazily load the icon void QIconLoaderEngine::ensureLoaded() { if (!(QIconLoader::instance()->themeKey() == m_key)) { + qDeleteAll(m_info.entries); + m_info.entries.clear(); + m_info.iconName.clear(); - qDeleteAll(m_entries); - - m_entries = QIconLoader::instance()->loadIcon(m_iconName); + Q_ASSERT(m_info.entries.size() == 0); + m_info = QIconLoader::instance()->loadIcon(m_iconName); m_key = QIconLoader::instance()->themeKey(); } } @@ -433,14 +459,14 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size) { int iconsize = qMin(size.width(), size.height()); - // Note that m_entries are sorted so that png-files + // Note that m_info.entries are sorted so that png-files // come first - const int numEntries = m_entries.size(); + const int numEntries = m_info.entries.size(); // Search for exact matches first for (int i = 0; i < numEntries; ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); + QIconLoaderEngineEntry *entry = m_info.entries.at(i); if (directoryMatchesSize(entry->dir, iconsize)) { return entry; } @@ -450,7 +476,7 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size) int minimalSize = INT_MAX; QIconLoaderEngineEntry *closestMatch = 0; for (int i = 0; i < numEntries; ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); + QIconLoaderEngineEntry *entry = m_info.entries.at(i); int distance = directorySizeDistance(entry->dir, iconsize); if (distance < minimalSize) { minimalSize = distance; @@ -554,13 +580,13 @@ void QIconLoaderEngine::virtual_hook(int id, void *data) { QIconEngine::AvailableSizesArgument &arg = *reinterpret_cast<QIconEngine::AvailableSizesArgument*>(data); - const int N = m_entries.size(); + const int N = m_info.entries.size(); QList<QSize> sizes; sizes.reserve(N); // Gets all sizes from the DirectoryInfo entries for (int i = 0; i < N; ++i) { - int size = m_entries.at(i)->dir.size; + int size = m_info.entries.at(i)->dir.size; sizes.append(QSize(size, size)); } arg.sizes.swap(sizes); // commit @@ -569,7 +595,7 @@ void QIconLoaderEngine::virtual_hook(int id, void *data) case QIconEngine::IconNameHook: { QString &name = *reinterpret_cast<QString*>(data); - name = m_iconName; + name = m_info.iconName; } break; default: |