summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qiconloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image/qiconloader.cpp')
-rw-r--r--src/gui/image/qiconloader.cpp142
1 files changed, 84 insertions, 58 deletions
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 06491f1155..fa14c84e83 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@@ -10,9 +10,9 @@
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@@ -47,7 +47,7 @@
#include <QtCore/QSettings>
#include <QtGui/QPainter>
-#ifdef Q_WS_MAC
+#ifdef Q_DEAD_CODE_FROM_QT4_MAC
#include <private/qt_cocoa_helpers_mac_p.h>
#endif
@@ -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();
}
}
@@ -372,7 +398,7 @@ void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
QIcon::Mode mode, QIcon::State state)
{
QSize pixmapSize = rect.size();
-#if defined(Q_WS_MAC)
+#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
pixmapSize *= qt_mac_get_scalefactor();
#endif
painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
@@ -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: