Changeset View
Changeset View
Standalone View
Standalone View
src/kiconloader.cpp
Show First 20 Lines • Show All 244 Lines • ▼ Show 20 Line(s) | 208 | public: | |||
---|---|---|---|---|---|
245 | */ | 245 | */ | ||
246 | bool initIconThemes(); | 246 | bool initIconThemes(); | ||
247 | 247 | | |||
248 | /** | 248 | /** | ||
249 | * @internal | 249 | * @internal | ||
250 | * tries to find an icon with the name. It tries some extension and | 250 | * tries to find an icon with the name. It tries some extension and | ||
251 | * match strategies | 251 | * match strategies | ||
252 | */ | 252 | */ | ||
253 | QString findMatchingIcon(const QString &name, int size) const; | 253 | QString findMatchingIcon(const QString &name, int size, qreal scale) const; | ||
254 | 254 | | |||
255 | /** | 255 | /** | ||
256 | * @internal | 256 | * @internal | ||
257 | * tries to find an icon with the name. | 257 | * tries to find an icon with the name. | ||
258 | * This is one layer above findMatchingIcon -- it also implements generic fallbacks | 258 | * This is one layer above findMatchingIcon -- it also implements generic fallbacks | ||
259 | * such as generic icons for mimetypes. | 259 | * such as generic icons for mimetypes. | ||
260 | */ | 260 | */ | ||
261 | QString findMatchingIconWithGenericFallbacks(const QString &name, int size) const; | 261 | QString findMatchingIconWithGenericFallbacks(const QString &name, int size, qreal scale) const; | ||
262 | 262 | | |||
263 | /** | 263 | /** | ||
264 | * @internal | 264 | * @internal | ||
265 | * Adds themes installed in the application's directory. | 265 | * Adds themes installed in the application's directory. | ||
266 | **/ | 266 | **/ | ||
267 | void addAppThemes(const QString &appname, const QString &themeBaseDir = QString()); | 267 | void addAppThemes(const QString &appname, const QString &themeBaseDir = QString()); | ||
268 | 268 | | |||
269 | /** | 269 | /** | ||
Show All 23 Lines | |||||
293 | * the list of icon themes. | 293 | * the list of icon themes. | ||
294 | */ | 294 | */ | ||
295 | void addExtraDesktopThemes(); | 295 | void addExtraDesktopThemes(); | ||
296 | 296 | | |||
297 | /** | 297 | /** | ||
298 | * @internal | 298 | * @internal | ||
299 | * return the path for the unknown icon in that size | 299 | * return the path for the unknown icon in that size | ||
300 | */ | 300 | */ | ||
301 | QString unknownIconPath(int size) const; | 301 | QString unknownIconPath(int size, qreal scale) const; | ||
302 | 302 | | |||
303 | /** | 303 | /** | ||
304 | * Checks if name ends in one of the supported icon formats (i.e. .png) | 304 | * Checks if name ends in one of the supported icon formats (i.e. .png) | ||
305 | * and returns the name without the extension if it does. | 305 | * and returns the name without the extension if it does. | ||
306 | */ | 306 | */ | ||
307 | QString removeIconExtension(const QString &name) const; | 307 | QString removeIconExtension(const QString &name) const; | ||
308 | 308 | | |||
309 | /** | 309 | /** | ||
310 | * @internal | 310 | * @internal | ||
311 | * Used with KIconLoader::loadIcon to convert the given name, size, group, | 311 | * Used with KIconLoader::loadIcon to convert the given name, size, group, | ||
312 | * and icon state information to valid states. All parameters except the | 312 | * and icon state information to valid states. All parameters except the | ||
313 | * name can be modified as well to be valid. | 313 | * name can be modified as well to be valid. | ||
314 | */ | 314 | */ | ||
315 | void normalizeIconMetadata(KIconLoader::Group &group, int &size, int &state) const; | 315 | void normalizeIconMetadata(KIconLoader::Group &group, int &size, int &state) const; | ||
316 | 316 | | |||
317 | /** | 317 | /** | ||
318 | * @internal | 318 | * @internal | ||
319 | * Used with KIconLoader::loadIcon to get a base key name from the given | 319 | * Used with KIconLoader::loadIcon to get a base key name from the given | ||
320 | * icon metadata. Ensure the metadata is normalized first. | 320 | * icon metadata. Ensure the metadata is normalized first. | ||
321 | */ | 321 | */ | ||
322 | QString makeCacheKey(const QString &name, KIconLoader::Group group, const QStringList &overlays, | 322 | QString makeCacheKey(const QString &name, KIconLoader::Group group, const QStringList &overlays, | ||
323 | int size, int state) const; | 323 | int size, qreal scale, int state) const; | ||
324 | 324 | | |||
325 | /** | 325 | /** | ||
326 | * @internal | 326 | * @internal | ||
327 | * If the icon is an SVG file, process it generating a stylesheet | 327 | * If the icon is an SVG file, process it generating a stylesheet | ||
328 | * following the current color scheme. in this case the icon can use named colors | 328 | * following the current color scheme. in this case the icon can use named colors | ||
329 | * as text color, background color, highlight color, positive/neutral/negative color | 329 | * as text color, background color, highlight color, positive/neutral/negative color | ||
330 | * @see KColorScheme | 330 | * @see KColorScheme | ||
331 | */ | 331 | */ | ||
332 | QByteArray processSvg(const QString &path, KIconLoader::States state) const; | 332 | QByteArray processSvg(const QString &path, KIconLoader::States state) const; | ||
333 | 333 | | |||
334 | /** | 334 | /** | ||
335 | * @internal | 335 | * @internal | ||
336 | * Creates the QImage for @p path, using SVG rendering as appropriate. | 336 | * Creates the QImage for @p path, using SVG rendering as appropriate. | ||
337 | * @p size is only used for scalable images, but if non-zero non-scalable | 337 | * @p size is only used for scalable images, but if non-zero non-scalable | ||
338 | * images will be resized anyways. | 338 | * images will be resized anyways. | ||
339 | */ | 339 | */ | ||
340 | QImage createIconImage(const QString &path, int size = 0, KIconLoader::States state = KIconLoader::DefaultState); | 340 | QImage createIconImage(const QString &path, int size = 0, qreal scale = 1.0, KIconLoader::States state = KIconLoader::DefaultState); | ||
341 | 341 | | |||
342 | /** | 342 | /** | ||
343 | * @internal | 343 | * @internal | ||
344 | * Adds an QPixmap with its associated path to the shared icon cache. | 344 | * Adds an QPixmap with its associated path to the shared icon cache. | ||
345 | */ | 345 | */ | ||
346 | void insertCachedPixmapWithPath(const QString &key, const QPixmap &data, const QString &path); | 346 | void insertCachedPixmapWithPath(const QString &key, const QPixmap &data, const QString &path); | ||
347 | 347 | | |||
348 | /** | 348 | /** | ||
▲ Show 20 Lines • Show All 503 Lines • ▼ Show 20 Line(s) | 851 | if (group < 0) { | |||
852 | qWarning() << "Neither size nor group specified!"; | 852 | qWarning() << "Neither size nor group specified!"; | ||
853 | group = KIconLoader::Desktop; | 853 | group = KIconLoader::Desktop; | ||
854 | } | 854 | } | ||
855 | size = mpGroups[group].size; | 855 | size = mpGroups[group].size; | ||
856 | } | 856 | } | ||
857 | } | 857 | } | ||
858 | 858 | | |||
859 | QString KIconLoaderPrivate::makeCacheKey(const QString &name, KIconLoader::Group group, | 859 | QString KIconLoaderPrivate::makeCacheKey(const QString &name, KIconLoader::Group group, | ||
860 | const QStringList &overlays, int size, int state) const | 860 | const QStringList &overlays, int size, qreal scale, int state) const | ||
861 | { | 861 | { | ||
862 | // The KSharedDataCache is shared so add some namespacing. The following code | 862 | // The KSharedDataCache is shared so add some namespacing. The following code | ||
863 | // uses QStringBuilder (new in Qt 4.6) | 863 | // uses QStringBuilder (new in Qt 4.6) | ||
cfeck: Please use some rounding here. Scaling factors such as 1.4 cannot be represented exactly. | |||||
Just checked that the default precision is 6 digits, so maybe not that important. cfeck: Just checked that the default precision is 6 digits, so maybe not that important. | |||||
864 | 864 | | |||
865 | return (group == KIconLoader::User | 865 | return (group == KIconLoader::User | ||
866 | ? QLatin1Literal("$kicou_") | 866 | ? QLatin1Literal("$kicou_") | ||
867 | : QLatin1Literal("$kico_")) | 867 | : QLatin1Literal("$kico_")) | ||
868 | % name | 868 | % name | ||
869 | % QLatin1Char('_') | 869 | % QLatin1Char('_') | ||
870 | % QString::number(size) | 870 | % QString::number(size) | ||
871 | % QLatin1Char('@') | ||||
872 | % QString::number(scale, 'f', 1) | ||||
871 | % QLatin1Char('_') | 873 | % QLatin1Char('_') | ||
872 | % overlays.join(QStringLiteral("_")) | 874 | % overlays.join(QStringLiteral("_")) | ||
873 | % (group >= 0 ? mpEffect.fingerprint(group, state) | 875 | % (group >= 0 ? mpEffect.fingerprint(group, state) | ||
874 | : NULL_EFFECT_FINGERPRINT()) | 876 | : NULL_EFFECT_FINGERPRINT()) | ||
875 | % QLatin1Char('_') | 877 | % QLatin1Char('_') | ||
876 | % paletteId(mCustomPalette ? mPalette : qApp->palette()) | 878 | % paletteId(mCustomPalette ? mPalette : qApp->palette()) | ||
877 | % (q->theme() && q->theme()->followsColorScheme() && state == KIconLoader::SelectedState ? QStringLiteral("_selected") : QString()); | 879 | % (q->theme() && q->theme()->followsColorScheme() && state == KIconLoader::SelectedState ? QStringLiteral("_selected") : QString()); | ||
878 | } | 880 | } | ||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Line(s) | 923 | } else if (reader.tokenType() != QXmlStreamReader::Invalid) { | |||
922 | writer.writeCurrentToken(reader); | 924 | writer.writeCurrentToken(reader); | ||
923 | } | 925 | } | ||
924 | } | 926 | } | ||
925 | buffer.close(); | 927 | buffer.close(); | ||
926 | 928 | | |||
927 | return processedContents; | 929 | return processedContents; | ||
928 | } | 930 | } | ||
929 | 931 | | |||
930 | QImage KIconLoaderPrivate::createIconImage(const QString &path, int size, KIconLoader::States state) | 932 | QImage KIconLoaderPrivate::createIconImage(const QString &path, int size, qreal scale, KIconLoader::States state) | ||
931 | { | 933 | { | ||
932 | //TODO: metadata in the theme to make it do this only if explicitly supported? | 934 | //TODO: metadata in the theme to make it do this only if explicitly supported? | ||
933 | QScopedPointer<QImageReader> reader; | 935 | QScopedPointer<QImageReader> reader; | ||
934 | QBuffer buffer; | 936 | QBuffer buffer; | ||
935 | 937 | | |||
936 | if (q->theme()->followsColorScheme() && (path.endsWith(QLatin1String("svg")) || path.endsWith(QLatin1String("svgz")))) { | 938 | if (q->theme()->followsColorScheme() && (path.endsWith(QLatin1String("svg")) || path.endsWith(QLatin1String("svgz")))) { | ||
937 | buffer.setData(processSvg(path, state)); | 939 | buffer.setData(processSvg(path, state)); | ||
938 | reader.reset(new QImageReader(&buffer)); | 940 | reader.reset(new QImageReader(&buffer)); | ||
939 | } else { | 941 | } else { | ||
940 | reader.reset(new QImageReader(path)); | 942 | reader.reset(new QImageReader(path)); | ||
941 | } | 943 | } | ||
942 | 944 | | |||
943 | if (!reader->canRead()) { | 945 | if (!reader->canRead()) { | ||
944 | return QImage(); | 946 | return QImage(); | ||
945 | } | 947 | } | ||
946 | 948 | | |||
947 | if (size != 0) { | 949 | if (size != 0) { | ||
948 | reader->setScaledSize(QSize(size, size)); | 950 | reader->setScaledSize(QSize(size * scale, size * scale)); | ||
949 | } | 951 | } | ||
950 | 952 | | |||
951 | return reader->read(); | 953 | return reader->read(); | ||
952 | } | 954 | } | ||
953 | 955 | | |||
954 | void KIconLoaderPrivate::insertCachedPixmapWithPath( | 956 | void KIconLoaderPrivate::insertCachedPixmapWithPath( | ||
955 | const QString &key, | 957 | const QString &key, | ||
956 | const QPixmap &data, | 958 | const QPixmap &data, | ||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Line(s) | 1024 | if (inputStream.status() == QDataStream::Ok) { | |||
1032 | 1034 | | |||
1033 | return true; | 1035 | return true; | ||
1034 | } | 1036 | } | ||
1035 | } | 1037 | } | ||
1036 | 1038 | | |||
1037 | return false; | 1039 | return false; | ||
1038 | } | 1040 | } | ||
1039 | 1041 | | |||
1040 | QString KIconLoaderPrivate::findMatchingIconWithGenericFallbacks(const QString &name, int size) const | 1042 | QString KIconLoaderPrivate::findMatchingIconWithGenericFallbacks(const QString &name, int size, qreal scale) const | ||
1041 | { | 1043 | { | ||
1042 | QString path = findMatchingIcon(name, size); | 1044 | QString path = findMatchingIcon(name, size, scale); | ||
1043 | if (!path.isEmpty()) { | 1045 | if (!path.isEmpty()) { | ||
1044 | return path; | 1046 | return path; | ||
1045 | } | 1047 | } | ||
1046 | 1048 | | |||
1047 | const QString genericIcon = s_globalData()->genericIconFor(name); | 1049 | const QString genericIcon = s_globalData()->genericIconFor(name); | ||
1048 | if (!genericIcon.isEmpty()) { | 1050 | if (!genericIcon.isEmpty()) { | ||
1049 | path = findMatchingIcon(genericIcon, size); | 1051 | path = findMatchingIcon(genericIcon, size, scale); | ||
1050 | } | 1052 | } | ||
1051 | return path; | 1053 | return path; | ||
1052 | } | 1054 | } | ||
1053 | 1055 | | |||
1054 | QString KIconLoaderPrivate::findMatchingIcon(const QString &name, int size) const | 1056 | QString KIconLoaderPrivate::findMatchingIcon(const QString &name, int size, qreal scale) const | ||
1055 | { | 1057 | { | ||
1056 | const_cast<KIconLoaderPrivate *>(this)->initIconThemes(); | 1058 | const_cast<KIconLoaderPrivate *>(this)->initIconThemes(); | ||
1057 | 1059 | | |||
1058 | // Do two passes through themeNodes. | 1060 | // Do two passes through themeNodes. | ||
1059 | // | 1061 | // | ||
1060 | // The first pass looks for an exact match in each themeNode one after the other. | 1062 | // The first pass looks for an exact match in each themeNode one after the other. | ||
1061 | // If one is found and it is an app icon then return that icon. | 1063 | // If one is found and it is an app icon then return that icon. | ||
1062 | // | 1064 | // | ||
1063 | // In the next pass (assuming the first pass failed), it looks for | 1065 | // In the next pass (assuming the first pass failed), it looks for | ||
1064 | // generic fallbacks in each themeNode one after the other. | 1066 | // generic fallbacks in each themeNode one after the other. | ||
1065 | 1067 | | |||
1066 | // In theory we should only do this for mimetype icons, not for app icons, | 1068 | // In theory we should only do this for mimetype icons, not for app icons, | ||
1067 | // but that would require different APIs. The long term solution is under | 1069 | // but that would require different APIs. The long term solution is under | ||
1068 | // development for Qt >= 5.8, QFileIconProvider calling QPlatformTheme::fileIcon, | 1070 | // development for Qt >= 5.8, QFileIconProvider calling QPlatformTheme::fileIcon, | ||
1069 | // using QMimeType::genericIconName() to get the proper -x-generic fallback. | 1071 | // using QMimeType::genericIconName() to get the proper -x-generic fallback. | ||
1070 | // Once everone uses that to look up mimetype icons, we can kill the fallback code | 1072 | // Once everone uses that to look up mimetype icons, we can kill the fallback code | ||
1071 | // from this method. | 1073 | // from this method. | ||
1072 | 1074 | | |||
1073 | foreach (KIconThemeNode *themeNode, links) { | 1075 | foreach (KIconThemeNode *themeNode, links) { | ||
1074 | const QString path = themeNode->theme->iconPathByName(name, size, KIconLoader::MatchBest); | 1076 | const QString path = themeNode->theme->iconPathByName(name, size, KIconLoader::MatchBest, scale); | ||
1075 | if (!path.isEmpty()) { | 1077 | if (!path.isEmpty()) { | ||
1076 | return path; | 1078 | return path; | ||
1077 | } | 1079 | } | ||
1078 | } | 1080 | } | ||
1079 | 1081 | | |||
1080 | if (name.endsWith(QLatin1String("-x-generic"))) { | 1082 | if (name.endsWith(QLatin1String("-x-generic"))) { | ||
1081 | return QString(); // no further fallback | 1083 | return QString(); // no further fallback | ||
1082 | } | 1084 | } | ||
Show All 33 Lines | 1103 | } else { | |||
1116 | } | 1118 | } | ||
1117 | } | 1119 | } | ||
1118 | 1120 | | |||
1119 | if (currentName.isEmpty()) { | 1121 | if (currentName.isEmpty()) { | ||
1120 | break; | 1122 | break; | ||
1121 | } | 1123 | } | ||
1122 | 1124 | | |||
1123 | //qCDebug(KICONTHEMES) << "Looking up" << currentName; | 1125 | //qCDebug(KICONTHEMES) << "Looking up" << currentName; | ||
1124 | path = themeNode->theme->iconPathByName(currentName, size, KIconLoader::MatchBest); | 1126 | path = themeNode->theme->iconPathByName(currentName, size, KIconLoader::MatchBest, scale); | ||
1125 | if (!path.isEmpty()) { | 1127 | if (!path.isEmpty()) { | ||
1126 | return path; | 1128 | return path; | ||
1127 | } | 1129 | } | ||
1128 | } | 1130 | } | ||
1129 | } | 1131 | } | ||
1130 | return path; | 1132 | return path; | ||
1131 | } | 1133 | } | ||
1132 | 1134 | | |||
1133 | inline QString KIconLoaderPrivate::unknownIconPath(int size) const | 1135 | inline QString KIconLoaderPrivate::unknownIconPath(int size, qreal scale) const | ||
1134 | { | 1136 | { | ||
1135 | QString path = findMatchingIcon(QStringLiteral("unknown"), size); | 1137 | QString path = findMatchingIcon(QStringLiteral("unknown"), size, scale); | ||
1136 | if (path.isEmpty()) { | 1138 | if (path.isEmpty()) { | ||
1137 | qCDebug(KICONTHEMES) << "Warning: could not find \"unknown\" icon for size" << size; | 1139 | qCDebug(KICONTHEMES) << "Warning: could not find \"unknown\" icon for size" << size << "at scale" << scale; | ||
1138 | return QString(); | 1140 | return QString(); | ||
1139 | } | 1141 | } | ||
1140 | return path; | 1142 | return path; | ||
1141 | } | 1143 | } | ||
1142 | 1144 | | |||
1143 | QString KIconLoaderPrivate::locate(const QString &fileName) | 1145 | QString KIconLoaderPrivate::locate(const QString &fileName) | ||
1144 | { | 1146 | { | ||
1145 | Q_FOREACH (const QString &dir, searchPaths) { | 1147 | Q_FOREACH (const QString &dir, searchPaths) { | ||
Show All 12 Lines | |||||
1158 | return QString(); | 1160 | return QString(); | ||
1159 | } | 1161 | } | ||
1160 | 1162 | | |||
1161 | // Finds the absolute path to an icon. | 1163 | // Finds the absolute path to an icon. | ||
1162 | 1164 | | |||
1163 | QString KIconLoader::iconPath(const QString &_name, int group_or_size, | 1165 | QString KIconLoader::iconPath(const QString &_name, int group_or_size, | ||
1164 | bool canReturnNull) const | 1166 | bool canReturnNull) const | ||
1165 | { | 1167 | { | ||
1168 | return iconPath(_name, group_or_size, canReturnNull, 1 /*scale*/); | ||||
1169 | } | ||||
1170 | | ||||
1171 | QString KIconLoader::iconPath(const QString &_name, int group_or_size, | ||||
1172 | bool canReturnNull, qreal scale) const | ||||
1173 | { | ||||
1166 | if (!d->initIconThemes()) { | 1174 | if (!d->initIconThemes()) { | ||
1167 | return QString(); | 1175 | return QString(); | ||
1168 | } | 1176 | } | ||
1169 | 1177 | | |||
1170 | if (_name.isEmpty() || !pathIsRelative(_name)) { | 1178 | if (_name.isEmpty() || !pathIsRelative(_name)) { | ||
1171 | // we have either an absolute path or nothing to work with | 1179 | // we have either an absolute path or nothing to work with | ||
1172 | return _name; | 1180 | return _name; | ||
1173 | } | 1181 | } | ||
Show All 26 Lines | |||||
1200 | } else { | 1208 | } else { | ||
1201 | size = -group_or_size; | 1209 | size = -group_or_size; | ||
1202 | } | 1210 | } | ||
1203 | 1211 | | |||
1204 | if (_name.isEmpty()) { | 1212 | if (_name.isEmpty()) { | ||
1205 | if (canReturnNull) { | 1213 | if (canReturnNull) { | ||
1206 | return QString(); | 1214 | return QString(); | ||
1207 | } else { | 1215 | } else { | ||
1208 | return d->unknownIconPath(size); | 1216 | return d->unknownIconPath(size, scale); | ||
1209 | } | 1217 | } | ||
1210 | } | 1218 | } | ||
1211 | 1219 | | |||
1212 | path = d->findMatchingIconWithGenericFallbacks(name, size); | 1220 | path = d->findMatchingIconWithGenericFallbacks(name, size, scale); | ||
1213 | 1221 | | |||
1214 | if (path.isEmpty()) { | 1222 | if (path.isEmpty()) { | ||
1215 | // Try "User" group too. | 1223 | // Try "User" group too. | ||
1216 | path = iconPath(name, KIconLoader::User, true); | 1224 | path = iconPath(name, KIconLoader::User, true); | ||
1217 | if (!path.isEmpty() || canReturnNull) { | 1225 | if (!path.isEmpty() || canReturnNull) { | ||
1218 | return path; | 1226 | return path; | ||
1219 | } | 1227 | } | ||
1220 | 1228 | | |||
1221 | return d->unknownIconPath(size); | 1229 | return d->unknownIconPath(size, scale); | ||
1222 | } | 1230 | } | ||
1223 | return path; | 1231 | return path; | ||
1224 | } | 1232 | } | ||
1225 | 1233 | | |||
1226 | QPixmap KIconLoader::loadMimeTypeIcon(const QString &_iconName, KIconLoader::Group group, int size, | 1234 | QPixmap KIconLoader::loadMimeTypeIcon(const QString &_iconName, KIconLoader::Group group, int size, | ||
1227 | int state, const QStringList &overlays, QString *path_store) const | 1235 | int state, const QStringList &overlays, QString *path_store) const | ||
1228 | { | 1236 | { | ||
1229 | QString iconName = _iconName; | 1237 | QString iconName = _iconName; | ||
Show All 12 Lines | |||||
1242 | const QPixmap pixmap = loadIcon(iconName, group, size, state, overlays, path_store, true); | 1250 | const QPixmap pixmap = loadIcon(iconName, group, size, state, overlays, path_store, true); | ||
1243 | if (pixmap.isNull()) { | 1251 | if (pixmap.isNull()) { | ||
1244 | // Icon not found, fallback to application/octet-stream | 1252 | // Icon not found, fallback to application/octet-stream | ||
1245 | return loadIcon(QStringLiteral("application-octet-stream"), group, size, state, overlays, path_store, false); | 1253 | return loadIcon(QStringLiteral("application-octet-stream"), group, size, state, overlays, path_store, false); | ||
1246 | } | 1254 | } | ||
1247 | return pixmap; | 1255 | return pixmap; | ||
1248 | } | 1256 | } | ||
1249 | 1257 | | |||
1258 | | ||||
1259 | | ||||
1250 | QPixmap KIconLoader::loadIcon(const QString &_name, KIconLoader::Group group, int size, | 1260 | QPixmap KIconLoader::loadIcon(const QString &_name, KIconLoader::Group group, int size, | ||
1251 | int state, const QStringList &overlays, | 1261 | int state, const QStringList &overlays, | ||
1252 | QString *path_store, bool canReturnNull) const | 1262 | QString *path_store, bool canReturnNull) const | ||
1253 | { | 1263 | { | ||
1264 | return loadScaledIcon(_name, group, 1.0 /*scale*/, size, state, overlays, path_store, canReturnNull); | ||||
cfeck: indent | |||||
1265 | } | ||||
1266 | | ||||
1267 | QPixmap KIconLoader::loadScaledIcon(const QString &_name, KIconLoader::Group group, qreal scale, | ||||
1268 | int size, int state, const QStringList &overlays, | ||||
1269 | QString *path_store, bool canReturnNull) const | ||||
1270 | { | ||||
1254 | QString name = _name; | 1271 | QString name = _name; | ||
1255 | bool favIconOverlay = false; | 1272 | bool favIconOverlay = false; | ||
1256 | 1273 | | |||
1257 | if (size < 0 || _name.isEmpty()) { | 1274 | if (size < 0 || _name.isEmpty()) { | ||
1258 | return QPixmap(); | 1275 | return QPixmap(); | ||
1259 | } | 1276 | } | ||
1260 | 1277 | | |||
1261 | /* | 1278 | /* | ||
1262 | * This method works in a kind of pipeline, with the following steps: | 1279 | * This method works in a kind of pipeline, with the following steps: | ||
1263 | * 1. Sanity checks. | 1280 | * 1. Sanity checks. | ||
1264 | * 2. Convert _name, group, size, etc. to a key name. | 1281 | * 2. Convert _name, group, size, etc. to a key name. | ||
1265 | * 3. Check if the key is already cached. | 1282 | * 3. Check if the key is already cached. | ||
1266 | * 4. If not, initialize the theme and find/load the icon. | 1283 | * 4. If not, initialize the theme and find/load the icon. | ||
1267 | * 4a Apply overlays | 1284 | * 4a Apply overlays | ||
1268 | * 4b Re-add to cache. | 1285 | * 4b Re-add to cache. | ||
1269 | */ | 1286 | */ | ||
1270 | 1287 | | |||
1271 | // Special case for absolute path icons. | 1288 | // Special case for absolute path icons. | ||
1272 | if (name.startsWith(QLatin1String("favicons/"))) { | 1289 | if (name.startsWith(QLatin1String("favicons/"))) { | ||
1273 | favIconOverlay = true; | 1290 | favIconOverlay = true; | ||
1274 | name = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1Char('/') + name + QStringLiteral(".png"); | 1291 | name = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1Char('/') + name + QStringLiteral(".png"); | ||
1275 | } | 1292 | } | ||
1276 | 1293 | | |||
1277 | bool absolutePath = !pathIsRelative(name); | 1294 | bool absolutePath = !pathIsRelative(name); | ||
davidedmundson: I don't think you need this? | |||||
1278 | if (!absolutePath) { | 1295 | if (!absolutePath) { | ||
1279 | name = d->removeIconExtension(name); | 1296 | name = d->removeIconExtension(name); | ||
1280 | } | 1297 | } | ||
1281 | 1298 | | |||
1282 | // Don't bother looking for an icon with no name. | 1299 | // Don't bother looking for an icon with no name. | ||
cfeck: Is this a left-over change from disabling this check? | |||||
1283 | if (name.isEmpty()) { | 1300 | if (name.isEmpty()) { | ||
1284 | return QPixmap(); | 1301 | return QPixmap(); | ||
1285 | } | 1302 | } | ||
1286 | 1303 | | |||
1287 | // May modify group, size, or state. This function puts them into sane | 1304 | // May modify group, size, or state. This function puts them into sane | ||
1288 | // states. | 1305 | // states. | ||
1289 | d->normalizeIconMetadata(group, size, state); | 1306 | d->normalizeIconMetadata(group, size, state); | ||
1290 | 1307 | | |||
1291 | // See if the image is already cached. | 1308 | // See if the image is already cached. | ||
1292 | QString key = d->makeCacheKey(name, group, overlays, size, state); | 1309 | QString key = d->makeCacheKey(name, group, overlays, size, scale, state); | ||
1293 | QPixmap pix; | 1310 | QPixmap pix; | ||
1311 | | ||||
1294 | bool iconWasUnknown = false; | 1312 | bool iconWasUnknown = false; | ||
1295 | QString path; | 1313 | QString path; | ||
1296 | 1314 | | |||
1297 | if (d->findCachedPixmapWithPath(key, pix, path)) { | 1315 | if (d->findCachedPixmapWithPath(key, pix, path)) { | ||
1316 | pix.setDevicePixelRatio(scale); | ||||
1317 | | ||||
1298 | if (path_store) { | 1318 | if (path_store) { | ||
1299 | *path_store = path; | 1319 | *path_store = path; | ||
1300 | } | 1320 | } | ||
1301 | 1321 | | |||
1302 | if (!path.isEmpty()) { | 1322 | if (!path.isEmpty()) { | ||
1303 | return pix; | 1323 | return pix; | ||
1304 | } else { | 1324 | } else { | ||
1305 | // path is empty for "unknown" icons, which should be searched for | 1325 | // path is empty for "unknown" icons, which should be searched for | ||
Show All 12 Lines | |||||
1318 | favIconOverlay = favIconOverlay && size > 22; | 1338 | favIconOverlay = favIconOverlay && size > 22; | ||
1319 | 1339 | | |||
1320 | // First we look for non-User icons. If we don't find one we'd search in | 1340 | // First we look for non-User icons. If we don't find one we'd search in | ||
1321 | // the User space anyways... | 1341 | // the User space anyways... | ||
1322 | if (group != KIconLoader::User) { | 1342 | if (group != KIconLoader::User) { | ||
1323 | if (absolutePath && !favIconOverlay) { | 1343 | if (absolutePath && !favIconOverlay) { | ||
1324 | path = name; | 1344 | path = name; | ||
1325 | } else { | 1345 | } else { | ||
1326 | path = d->findMatchingIconWithGenericFallbacks(favIconOverlay ? QStringLiteral("text-html") : name, size); | 1346 | path = d->findMatchingIconWithGenericFallbacks(favIconOverlay ? QStringLiteral("text-html") : name, size, scale); | ||
1327 | } | 1347 | } | ||
1328 | } | 1348 | } | ||
1329 | 1349 | | |||
1330 | if (path.isEmpty()) { | 1350 | if (path.isEmpty()) { | ||
1331 | // We do have a "User" icon, or we couldn't find the non-User one. | 1351 | // We do have a "User" icon, or we couldn't find the non-User one. | ||
1332 | path = (absolutePath) ? name : | 1352 | path = (absolutePath) ? name : | ||
1333 | iconPath(name, KIconLoader::User, canReturnNull); | 1353 | iconPath(name, KIconLoader::User, canReturnNull); | ||
1334 | } | 1354 | } | ||
1335 | 1355 | | |||
1336 | // Still can't find it? Use "unknown" if we can't return null. | 1356 | // Still can't find it? Use "unknown" if we can't return null. | ||
1337 | // We keep going in the function so we can ensure this result gets cached. | 1357 | // We keep going in the function so we can ensure this result gets cached. | ||
1338 | if (path.isEmpty() && !canReturnNull) { | 1358 | if (path.isEmpty() && !canReturnNull) { | ||
1339 | path = d->unknownIconPath(size); | 1359 | path = d->unknownIconPath(size, scale); | ||
1340 | iconWasUnknown = true; | 1360 | iconWasUnknown = true; | ||
1341 | } | 1361 | } | ||
1342 | 1362 | | |||
1343 | QImage img; | 1363 | QImage img; | ||
1344 | if (!path.isEmpty()) { | 1364 | if (!path.isEmpty()) { | ||
1345 | img = d->createIconImage(path, size, static_cast<KIconLoader::States>(state)); | 1365 | img = d->createIconImage(path, size, scale, static_cast<KIconLoader::States>(state)); | ||
1346 | } | 1366 | } | ||
1347 | 1367 | | |||
1348 | if (group >= 0 && group < KIconLoader::LastGroup) { | 1368 | if (group >= 0 && group < KIconLoader::LastGroup) { | ||
Why this line reverts D12002? volkov: Why this line reverts D12002? | |||||
broulik: Dunno, probably oversight or forgotten to rebase.. | |||||
Looks like a rebase: https://phabricator.kde.org/D6313?vs=31197&id=34779&whitespace=ignore-most#toc volkov: Looks like a rebase: https://phabricator.kde.org/D6313?vs=31197&id=34779&whitespace=ignore… | |||||
broulik: Feel free to submit a patch to restore this | |||||
1349 | img = d->mpEffect.apply(img, group, state); | 1369 | img = d->mpEffect.apply(img, group, state); | ||
1350 | } | 1370 | } | ||
1351 | 1371 | | |||
1352 | if (favIconOverlay) { | 1372 | if (favIconOverlay) { | ||
1353 | QImage favIcon(name, "PNG"); | 1373 | QImage favIcon(name, "PNG"); | ||
1354 | if (!favIcon.isNull()) { // if favIcon not there yet, don't try to blend it | 1374 | if (!favIcon.isNull()) { // if favIcon not there yet, don't try to blend it | ||
1355 | QPainter p(&img); | 1375 | QPainter p(&img); | ||
1356 | 1376 | | |||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Line(s) | 1482 | { | |||
1479 | 1499 | | |||
1480 | QString file = name + QStringLiteral("/0001"); | 1500 | QString file = name + QStringLiteral("/0001"); | ||
1481 | if (group == KIconLoader::User) { | 1501 | if (group == KIconLoader::User) { | ||
1482 | file = d->locate(file + QStringLiteral(".png")); | 1502 | file = d->locate(file + QStringLiteral(".png")); | ||
1483 | } else { | 1503 | } else { | ||
1484 | if (size == 0) { | 1504 | if (size == 0) { | ||
1485 | size = d->mpGroups[group].size; | 1505 | size = d->mpGroups[group].size; | ||
1486 | } | 1506 | } | ||
1487 | file = d->findMatchingIcon(file, size); | 1507 | file = d->findMatchingIcon(file, size, 1); // FIXME scale | ||
1488 | } | 1508 | } | ||
1489 | if (file.isEmpty()) { | 1509 | if (file.isEmpty()) { | ||
1490 | return lst; | 1510 | return lst; | ||
1491 | } | 1511 | } | ||
1492 | 1512 | | |||
1493 | QString path = file.left(file.length() - 8); | 1513 | QString path = file.left(file.length() - 8); | ||
1494 | QDir dir(QFile::encodeName(path)); | 1514 | QDir dir(QFile::encodeName(path)); | ||
1495 | if (!dir.exists()) { | 1515 | if (!dir.exists()) { | ||
▲ Show 20 Lines • Show All 351 Lines • Show Last 20 Lines |
Please use some rounding here. Scaling factors such as 1.4 cannot be represented exactly.
Either add some formatting specifiers, e.g. for three decimal places, or use qRound(scale * 1000).