KDEUI
kimagecache.cpp
Go to the documentation of this file.
00001 /* 00002 * This file is part of the KDE project. 00003 * Copyright © 2010 Michael Pyne <mpyne@kde.org> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License version 2 as published by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public License 00015 * along with this library; see the file COPYING.LIB. If not, write to 00016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 * Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kimagecache.h" 00021 00022 #include <QtGui/QPixmap> 00023 #include <QtGui/QImage> 00024 #include <QtCore/QBuffer> 00025 #include <QtCore/QCache> 00026 #include <QtCore/QCoreApplication> 00027 00028 #include <time.h> 00029 00034 class KImageCache::Private : public QObject 00035 { 00036 Q_OBJECT 00037 00038 public: 00039 Private(QObject *parent = 0) 00040 : QObject(parent) 00041 , timestamp(::time(0)) 00042 , enablePixmapCaching(true) 00043 { 00044 QObject::connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), 00045 this, SLOT(clearPixmaps())); 00046 } 00047 00052 bool insertPixmap(const QString &key, QPixmap *pixmap) 00053 { 00054 if (enablePixmapCaching && pixmap && !pixmap->isNull()) { 00055 // "cost" parameter is based on both image size and depth to make cost 00056 // based on size in bytes instead of area on-screen. 00057 return pixmapCache.insert(key, pixmap, 00058 pixmap->width() * pixmap->height() * pixmap->depth() / 8); 00059 } 00060 00061 return false; 00062 } 00063 00064 public slots: 00065 void clearPixmaps() 00066 { 00067 pixmapCache.clear(); 00068 } 00069 00070 public: 00071 time_t timestamp; 00072 00077 QCache<QString, QPixmap> pixmapCache; 00078 00079 bool enablePixmapCaching; 00080 }; 00081 00082 KImageCache::KImageCache(const QString &cacheName, 00083 unsigned defaultCacheSize, 00084 unsigned expectedItemSize) 00085 : KSharedDataCache(cacheName, defaultCacheSize, expectedItemSize) 00086 , d(new Private) 00087 { 00088 // Use at least 16 KiB for the pixmap cache 00089 d->pixmapCache.setMaxCost(qMax(defaultCacheSize / 8, (unsigned int) 16384)); 00090 } 00091 00092 KImageCache::~KImageCache() 00093 { 00094 delete d; 00095 } 00096 00097 bool KImageCache::insertImage(const QString &key, const QImage &image) 00098 { 00099 QBuffer buffer; 00100 buffer.open(QBuffer::WriteOnly); 00101 image.save(&buffer, "PNG"); 00102 00103 if (this->insert(key, buffer.buffer())) { 00104 d->timestamp = ::time(0); 00105 return true; 00106 } 00107 00108 return false; 00109 } 00110 00111 bool KImageCache::insertPixmap(const QString &key, const QPixmap &pixmap) 00112 { 00113 d->insertPixmap(key, new QPixmap(pixmap)); 00114 00115 // One thing to think about is only inserting things to the shared cache 00116 // that are frequently used. But that would require tracking the use count 00117 // in our local cache too, which I think is probably too much work. 00118 00119 return insertImage(key, pixmap.toImage()); 00120 } 00121 00122 bool KImageCache::findImage(const QString &key, QImage *destination) const 00123 { 00124 QByteArray cachedData; 00125 if (!this->find(key, &cachedData) || cachedData.isNull()) { 00126 return false; 00127 } 00128 00129 if (destination) { 00130 destination->loadFromData(cachedData, "PNG"); 00131 } 00132 00133 return true; 00134 } 00135 00136 bool KImageCache::findPixmap(const QString &key, QPixmap *destination) const 00137 { 00138 if (d->enablePixmapCaching) { 00139 QPixmap *cachedPixmap = d->pixmapCache.object(key); 00140 if (cachedPixmap) { 00141 if (destination) { 00142 *destination = *cachedPixmap; 00143 } 00144 00145 return true; 00146 } 00147 } 00148 00149 QByteArray cachedData; 00150 if (!this->find(key, &cachedData) || cachedData.isNull()) { 00151 return false; 00152 } 00153 00154 if (destination) { 00155 destination->loadFromData(cachedData, "PNG"); 00156 00157 // Manually re-insert to pixmap cache if we'll be using this one. 00158 d->insertPixmap(key, new QPixmap(*destination)); 00159 } 00160 00161 return true; 00162 } 00163 00164 void KImageCache::clear() 00165 { 00166 d->pixmapCache.clear(); 00167 KSharedDataCache::clear(); 00168 } 00169 00170 time_t KImageCache::lastModifiedTime() const 00171 { 00172 return d->timestamp; 00173 } 00174 00175 bool KImageCache::pixmapCaching() const 00176 { 00177 return d->enablePixmapCaching; 00178 } 00179 00180 void KImageCache::setPixmapCaching(bool enable) 00181 { 00182 if (enable != d->enablePixmapCaching) { 00183 d->enablePixmapCaching = enable; 00184 if (!enable) { 00185 d->pixmapCache.clear(); 00186 } 00187 } 00188 } 00189 00190 int KImageCache::pixmapCacheLimit() const 00191 { 00192 return d->pixmapCache.maxCost(); 00193 } 00194 00195 void KImageCache::setPixmapCacheLimit(int size) 00196 { 00197 d->pixmapCache.setMaxCost(size); 00198 } 00199 00200 #include "kimagecache.moc"
KDE 4.6 API Reference