File indexing completed on 2024-04-14 04:53:13
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2000 Carsten Pfeiffer <pfeiffer@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "konqpixmapprovider.h" 0008 0009 #include <QMimeDatabase> 0010 #include <QMimeType> 0011 #include <QIcon> 0012 #include "konqdebug.h" 0013 0014 #include <KIO/FavIconRequestJob> 0015 #include <kio/global.h> 0016 #include <kprotocolinfo.h> 0017 #include <kconfiggroup.h> 0018 #include <KIconLoader> 0019 0020 class KonqPixmapProviderSingleton 0021 { 0022 public: 0023 KonqPixmapProvider self; 0024 }; 0025 Q_GLOBAL_STATIC(KonqPixmapProviderSingleton, globalPixmapProvider) 0026 0027 KonqPixmapProvider *KonqPixmapProvider::self() 0028 { 0029 return &globalPixmapProvider->self; 0030 } 0031 0032 KonqPixmapProvider::KonqPixmapProvider() 0033 : QObject() 0034 { 0035 } 0036 0037 KonqPixmapProvider::~KonqPixmapProvider() 0038 { 0039 } 0040 0041 void KonqPixmapProvider::downloadHostIcon(const QUrl &hostUrl) 0042 { 0043 //Only attempt to download icon for http(s) URLs 0044 if (!hostUrl.scheme().startsWith(QLatin1String("http"))) { 0045 return; 0046 } 0047 KIO::FavIconRequestJob *job = new KIO::FavIconRequestJob(hostUrl); 0048 connect(job, &KIO::FavIconRequestJob::result, this, [job, this](KJob *) { 0049 bool modified = false; 0050 const QUrl _hostUrl = job->hostUrl(); 0051 QMap<QUrl, QString>::iterator itEnd = iconMap.end(); 0052 for (QMap<QUrl, QString>::iterator it = iconMap.begin(); it != itEnd; ++it) { 0053 const QUrl url(it.key()); 0054 if (url.host() == _hostUrl.host()) { 0055 // For host default-icons still query the favicon manager to get 0056 // the correct icon for pages that have an own one. 0057 const QString icon = KIO::favIconForUrl(url); 0058 if (!icon.isEmpty() && *it != icon) { 0059 *it = icon; 0060 modified = true; 0061 } 0062 } 0063 } 0064 if (modified) { 0065 emit changed(); 0066 } 0067 }); 0068 } 0069 0070 void KonqPixmapProvider::setIconForUrl(const QUrl &hostUrl, const QUrl &iconUrl) 0071 { 0072 KIO::FavIconRequestJob *job = new KIO::FavIconRequestJob(hostUrl); 0073 job->setIconUrl(iconUrl); 0074 connect(job, &KIO::FavIconRequestJob::result, this, [job, this](KJob *) { 0075 bool modified = false; 0076 const QUrl _hostUrl = job->hostUrl(); 0077 QMap<QUrl, QString>::iterator itEnd = iconMap.end(); 0078 for (QMap<QUrl, QString>::iterator it = iconMap.begin(); it != itEnd; ++it) { 0079 const QUrl url(it.key()); 0080 if (url.host() == _hostUrl.host() && url.path() == _hostUrl.path()) { 0081 const QString icon = job->iconFile(); 0082 if (!icon.isEmpty() && *it != icon) { 0083 *it = icon; 0084 modified = true; 0085 } 0086 } 0087 } 0088 if (modified) { 0089 emit changed(); 0090 } 0091 }); 0092 } 0093 0094 // at first, tries to find the iconname in the cache 0095 // if not available, tries to find the pixmap for the mimetype of url 0096 // if that fails, gets the icon for the protocol 0097 // finally, inserts the url/icon pair into the cache 0098 QString KonqPixmapProvider::iconNameFor(const QUrl &url) 0099 { 0100 QMap<QUrl, QString>::iterator it = iconMap.find(url); 0101 QString icon; 0102 if (it != iconMap.end()) { 0103 icon = it.value(); 0104 if (!icon.isEmpty()) { 0105 return icon; 0106 } 0107 } 0108 0109 if (url.url().isEmpty()) { 0110 // Use the Konqueror icon for the empty URL 0111 icon = "konqueror"; 0112 } else { 0113 icon = KIO::iconNameForUrl(url); 0114 Q_ASSERT(!icon.isEmpty()); 0115 } 0116 0117 // cache the icon found for url 0118 iconMap.insert(url, icon); 0119 0120 return icon; 0121 } 0122 0123 QPixmap KonqPixmapProvider::pixmapFor(const QString &url, int size) 0124 { 0125 return loadIcon(iconNameFor(QUrl::fromUserInput(url)), size); 0126 } 0127 0128 void KonqPixmapProvider::load(KConfigGroup &kc, const QString &key) 0129 { 0130 iconMap.clear(); 0131 const QStringList list = kc.readPathEntry(key, QStringList()); 0132 QStringList::const_iterator it = list.begin(); 0133 QStringList::const_iterator itEnd = list.end(); 0134 while (it != itEnd) { 0135 const QString url(*it); 0136 if ((++it) == itEnd) { 0137 break; 0138 } 0139 const QString icon(*it); 0140 iconMap.insert(QUrl::fromUserInput(url), icon); 0141 ++it; 0142 } 0143 } 0144 0145 // only saves the cache for the given list of items to prevent the cache 0146 // from growing forever. 0147 void KonqPixmapProvider::save(KConfigGroup &kc, const QString &key, 0148 const QStringList &items) 0149 { 0150 QStringList list; 0151 QStringList::const_iterator itEnd = items.end(); 0152 for (QStringList::const_iterator it = items.begin(); it != itEnd; ++it) { 0153 QMap<QUrl, QString>::const_iterator mit = iconMap.constFind(QUrl::fromUserInput(*it)); 0154 if (mit != iconMap.constEnd()) { 0155 list.append(mit.key().url()); 0156 list.append(mit.value()); 0157 } 0158 } 0159 kc.writePathEntry(key, list); 0160 } 0161 0162 void KonqPixmapProvider::clear() 0163 { 0164 iconMap.clear(); 0165 } 0166 0167 QPixmap KonqPixmapProvider::loadIcon(const QString &icon, int size) 0168 { 0169 if (size == 0) { 0170 size = KIconLoader::SizeSmall; 0171 } 0172 return QIcon::fromTheme(icon).pixmap(size); 0173 } 0174 0175 QIcon KonqPixmapProvider::iconForUrl(const QUrl &url) 0176 { 0177 return QIcon::fromTheme(iconNameFor(url)); 0178 } 0179 0180 QIcon KonqPixmapProvider::iconForUrl(const QString &url_str) 0181 { 0182 return iconForUrl(QUrl::fromUserInput(url_str)); 0183 } 0184