File indexing completed on 2024-05-12 16:02:27
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_icon_utils.h" 0008 0009 #include <QApplication> 0010 #include <QAction> 0011 #include <QAbstractButton> 0012 #include <QComboBox> 0013 #include <QTabBar> 0014 #include <QTabWidget> 0015 #include <QIcon> 0016 #include <QFile> 0017 #include <QPair> 0018 #include <QDebug> 0019 0020 #include <KoIcon.h> 0021 #include "kis_debug.h" 0022 0023 namespace KisIconUtils 0024 { 0025 0026 static QMap<QString, QIcon> s_cache; 0027 static QMap<qint64, QString> s_icons; 0028 0029 QIcon loadIcon(const QString &name) 0030 { 0031 QMap<QString, QIcon>::const_iterator cached = s_cache.constFind(name); 0032 if (cached != s_cache.constEnd()) { 0033 return cached.value(); 0034 } 0035 0036 // try load themed icon 0037 const char * const prefix = useDarkIcons() ? "dark_" : "light_"; 0038 0039 QString realName = QLatin1String(prefix) + name; 0040 0041 // Dark and light, no size specified 0042 const QStringList names = { ":/pics/" + realName + ".png", 0043 ":/pics/" + realName + ".svg", 0044 ":/pics/" + realName + ".svgz", 0045 ":/pics/" + name + ".png", 0046 ":/pics/" + name + ".svg", 0047 ":/pics/" + name + ".svgz", 0048 ":/" + realName + ".png", 0049 ":/" + realName + ".svg", 0050 ":/" + realName + ".svgz", 0051 ":/" + name, 0052 ":/" + name + ".png", 0053 ":/" + name + ".svg", 0054 ":/" + name + ".svgz"}; 0055 0056 for (const QString &resname : names) { 0057 if (QFile(resname).exists()) { 0058 QIcon icon(resname); 0059 s_icons.insert(icon.cacheKey(), name); 0060 s_cache.insert(name, icon); 0061 return icon; 0062 } 0063 } 0064 0065 // Now check for icons with sizes 0066 QStringList sizes = QStringList() << "16_" << "22_" << "32_" << "48_" << "64_" << "128_" << "256_" << "512_" << "1024_"; 0067 QVector<QPair<QString, QString> > icons; 0068 Q_FOREACH (const QString &size, sizes) { 0069 const QStringList names = { ":/pics/" + size + realName + ".png", 0070 ":/pics/" + size + realName + ".svg", 0071 ":/pics/" + size + realName + ".svgz", 0072 ":/pics/" + size + name + ".png", 0073 ":/pics/" + size + name + ".svg", 0074 ":/pics/" + size + name + ".svgz", 0075 ":/" + size + realName + ".png", 0076 ":/" + size + realName + ".svg", 0077 ":/" + size + realName + ".svgz", 0078 ":/" + size + name, 0079 ":/" + size + name + ".png", 0080 ":/" + size + name + ".svg", 0081 ":/" + size + name + ".svgz"}; 0082 0083 for (const QString &resname : names) { 0084 if (QFile(resname).exists()) { 0085 icons << qMakePair(size, resname); 0086 } 0087 } 0088 } 0089 0090 if (!icons.isEmpty()) { 0091 QIcon icon; 0092 Q_FOREACH (auto p, icons) { 0093 QString sz = p.first; 0094 sz.chop(1); 0095 int size = sz.toInt(); 0096 icon.addFile(p.second, QSize(size, size)); 0097 } 0098 s_icons.insert(icon.cacheKey(), name); 0099 s_cache.insert(name, icon); 0100 return icon; 0101 } 0102 0103 QIcon icon = QIcon::fromTheme(name); 0104 //qDebug() << "falling back on QIcon::FromTheme:" << name; 0105 s_icons.insert(icon.cacheKey(), name); 0106 s_cache.insert(name, icon); 0107 return icon; 0108 } 0109 0110 0111 0112 0113 bool useDarkIcons() { 0114 QColor background = qApp->palette().window().color(); 0115 return background.value() > 100; 0116 } 0117 0118 bool adjustIcon(QIcon *icon) 0119 { 0120 bool result = false; 0121 0122 QString iconName = icon->name(); 0123 if (iconName.isNull()) { 0124 if (s_icons.contains(icon->cacheKey())) { 0125 iconName = s_icons[icon->cacheKey()]; 0126 } else { 0127 return false; 0128 } 0129 } 0130 0131 QString realIconName = iconName; 0132 0133 if (iconName.startsWith("dark_")) { 0134 realIconName = iconName.mid(5); 0135 } 0136 0137 if (iconName.startsWith("light_")) { 0138 realIconName = iconName.mid(6); 0139 } 0140 0141 if (!realIconName.isNull()) { 0142 *icon = loadIcon(realIconName); 0143 result = !icon->isNull(); 0144 s_icons.insert(icon->cacheKey(), iconName); 0145 } 0146 0147 return result; 0148 } 0149 0150 void updateIconCommon(QObject *object) 0151 { 0152 QAbstractButton* button = qobject_cast<QAbstractButton*>(object); 0153 if (button) { 0154 updateIcon(button); 0155 return; 0156 } 0157 0158 QComboBox* comboBox = qobject_cast<QComboBox*>(object); 0159 if (comboBox) { 0160 updateIcon(comboBox); 0161 return; 0162 } 0163 0164 QAction* action = qobject_cast<QAction*>(object); 0165 if (action) { 0166 updateIcon(action); 0167 return; 0168 } 0169 0170 QTabBar* tabBar = qobject_cast<QTabBar*>(object); 0171 if (tabBar) { 0172 updateIcon(tabBar); 0173 return; 0174 } 0175 } 0176 0177 void clearIconCache() { 0178 s_cache.clear(); 0179 } 0180 0181 void updateIcon(QAbstractButton *button) 0182 { 0183 KIS_SAFE_ASSERT_RECOVER_RETURN(button); 0184 0185 QIcon icon = button->icon(); 0186 0187 if (adjustIcon(&icon)) { 0188 button->setIcon(icon); 0189 } 0190 } 0191 0192 void updateIcon(QComboBox *comboBox) 0193 { 0194 for (int i = 0; i < comboBox->count(); i++) { 0195 QIcon icon = comboBox->itemIcon(i); 0196 if (adjustIcon(&icon)) { 0197 comboBox->setItemIcon(i, icon); 0198 } 0199 } 0200 } 0201 0202 void updateIcon(QAction *action) 0203 { 0204 QIcon icon = action->icon(); 0205 0206 if (adjustIcon(&icon)) { 0207 action->setIcon(icon); 0208 } 0209 } 0210 0211 void updateIcon(QTabBar *tabBar) 0212 { 0213 for (int i = 0; i < tabBar->count(); i++) { 0214 QIcon icon = tabBar->tabIcon(i); 0215 if (adjustIcon(&icon)) { 0216 tabBar->setTabIcon(i, icon); 0217 } 0218 } 0219 } 0220 0221 }