File indexing completed on 2024-11-24 04:53:27
0001 /* Copyright (C) 2006 - 2015 Jan Kundrát <jkt@kde.org> 0002 Copyright (C) 2016 Luís Pereira <luis.artur.pereira@gmail.com> 0003 0004 This file is part of the Trojita Qt IMAP e-mail client, 0005 http://trojita.flaska.net/ 0006 0007 This program is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU General Public License as 0009 published by the Free Software Foundation; either version 2 of 0010 the License or (at your option) version 3 or any later version 0011 accepted by the membership of KDE e.V. (or its successor approved 0012 by the membership of KDE e.V.), which shall act as a proxy 0013 defined in Section 14 of version 3 of the license. 0014 0015 This program is distributed in the hope that it will be useful, 0016 but WITHOUT ANY WARRANTY; without even the implied warranty of 0017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0018 GNU General Public License for more details. 0019 0020 You should have received a copy of the GNU General Public License 0021 along with this program. If not, see <http://www.gnu.org/licenses/>. 0022 */ 0023 0024 #include "IconLoader.h" 0025 #include <QCoreApplication> 0026 #include <QFileInfo> 0027 #include <QHash> 0028 0029 namespace UiUtils { 0030 0031 static void cleanup_icon_cache(); 0032 namespace { 0033 struct Cache : public QHash<QString, QIcon> 0034 { 0035 Cache() 0036 { 0037 qAddPostRoutine(cleanup_icon_cache); 0038 } 0039 }; 0040 } 0041 0042 Q_GLOBAL_STATIC(Cache, iconDict) 0043 0044 static void cleanup_icon_cache() 0045 { 0046 iconDict()->clear(); 0047 } 0048 0049 0050 /** @short Wrapper around the QIcon::fromTheme with sane fallback 0051 * 0052 * The issue with the QIcon::fromTheme is that it does not really work on non-X11 0053 * platforms, unless you ship your own theme index and specify your theme name. 0054 * In Trojitá, we do not really want to hardcode anything, because the 0055 * preference is to use whatever is available from the current theme, but *also* 0056 * provide an icon as a fallback. And that is exactly why this function is here. 0057 * */ 0058 QIcon loadIcon(const QString &name) 0059 { 0060 auto it = iconDict()->constFind(name); 0061 if (it != iconDict()->constEnd()) 0062 return *it; 0063 0064 auto overrideIcon = QStringLiteral(":/icons/%1/%2.svg").arg(QIcon::themeName(), name); 0065 if (QFileInfo(overrideIcon).exists()) { 0066 QIcon icon(overrideIcon); 0067 iconDict()->insert(name, icon); 0068 return icon; 0069 } 0070 0071 // A QIcon(QString) constructor creates non-null QIcons, even though the resulting icon will 0072 // not ever return a valid and usable pixmap. This means that we have to actually look at the 0073 // icon's pixmap to find out what to return. 0074 // If we do not do that, the GUI shows empty pixmaps instead of a text fallback, which is 0075 // clearly suboptimal. 0076 QIcon res = QIcon::fromTheme(name, QIcon(QStringLiteral(":/icons/%1").arg(name))); 0077 if (res.pixmap(QSize(16, 16)).isNull()) { 0078 res = QIcon(); 0079 } 0080 iconDict()->insert(name, res); 0081 return res; 0082 } 0083 0084 }