23 #include <QtCore/QString>
24 #include <QtGui/QPixmap>
25 #include <QtCore/QFile>
26 #include <QtCore/QDataStream>
27 #include <QtCore/QFileInfo>
28 #include <QtCore/QDateTime>
29 #include <QtGui/QPixmapCache>
30 #include <QtCore/QtGlobal>
31 #include <QtGui/QPainter>
32 #include <QtCore/QQueue>
33 #include <QtCore/QTimer>
34 #include <QtCore/QMutex>
35 #include <QtCore/QMutexLocker>
36 #include <QtCore/QList>
52 #include <sys/types.h>
55 #if defined(HAVE_MADVISE)
63 extern "C" int madvise(caddr_t addr,
size_t len,
int advice);
67 #define KPIXMAPCACHE_VERSION 0x000208
74 KPCLockFile(
const QString& filename)
80 for (
int i = 0; i < 5; i++) {
90 kError() <<
"Failed to lock file" << filename <<
", last result =" << result;
107 bool isValid()
const {
return mValid; }
121 static const char KPC_MAGIC[] =
"KDE PIXMAP CACHE DEUX";
122 struct KPixmapCacheDataHeader
126 char magic[
sizeof(KPC_MAGIC) - 1];
131 struct KPixmapCacheIndexHeader
135 char magic[
sizeof(KPC_MAGIC) - 1];
148 virtual ~KPCMemoryDevice();
150 virtual qint64 size()
const {
return *mSize; }
151 void setSize(
quint32 s) { *mSize = s; }
152 virtual bool seek(
qint64 pos);
156 virtual qint64 writeData(
const char* data,
qint64 maxSize);
160 KPixmapCacheIndexHeader *mHeader;
170 mHeader =
reinterpret_cast<KPixmapCacheIndexHeader *
>(start);
172 mAvailable = available;
175 this->
open(QIODevice::ReadWrite);
178 *mSize = mHeader->size;
180 mInitialSize = *mSize;
183 KPCMemoryDevice::~KPCMemoryDevice()
185 if (*mSize != mInitialSize) {
187 mHeader->size = *mSize;
191 bool KPCMemoryDevice::seek(
qint64 pos)
193 if (pos < 0 || pos > *mSize) {
197 return QIODevice::seek(pos);
200 qint64 KPCMemoryDevice::readData(
char* data,
qint64 len)
202 len = qMin(len,
qint64(*mSize) - mPos);
206 memcpy(data, mMemory + mPos, len);
211 qint64 KPCMemoryDevice::writeData(
const char* data,
qint64 len)
213 if (mPos + len > mAvailable) {
214 kError() <<
"Overflow of" << mPos+len - mAvailable;
217 memcpy(mMemory + mPos, (uchar*)data, len);
219 *mSize = qMax(*mSize, mPos);
243 void invalidateMmapFiles();
248 static unsigned kpcNumber;
250 int findOffset(
const QString& key);
251 int binarySearchKey(QDataStream& stream,
const QString& key,
int start);
252 void writeIndexEntry(QDataStream& stream,
const QString& key,
int dataoffset);
254 bool checkLockFile();
255 bool checkFileVersion(
const QString& filename);
256 bool loadIndexHeader();
257 bool loadDataHeader();
260 bool scheduleRemoveEntries(
int newsize);
263 bool loadData(
int offset, QPixmap& pix);
264 int writeData(
const QString& key,
const QPixmap& pix);
265 void writeIndex(
const QString& key,
int offset);
291 bool mUseQPixmapCache:4;
300 MmapInfo() { file = 0; indexHeader = 0; }
304 KPixmapCacheIndexHeader *indexHeader;
309 MmapInfo mIndexMmapInfo;
310 MmapInfo mDataMmapInfo;
312 bool mmapFile(
const QString& filename, MmapInfo* info,
int newsize);
313 void unmmapFile(MmapInfo* info);
317 class KPixmapCacheEntry
320 KPixmapCacheEntry(
int indexoffset_,
const QString& key_,
int dataoffset_,
322 : indexoffset(indexoffset_),
324 dataoffset(dataoffset_),
326 timesused(timesused_),
341 static bool compareEntriesByAge(
const KPixmapCacheEntry& a,
const KPixmapCacheEntry& b)
343 return a.pos > b.pos;
345 static bool compareEntriesByTimesUsed(
const KPixmapCacheEntry& a,
const KPixmapCacheEntry& b)
347 return a.timesused > b.timesused;
349 static bool compareEntriesByLastUsed(
const KPixmapCacheEntry& a,
const KPixmapCacheEntry& b)
351 return a.lastused > b.lastused;
358 unsigned KPixmapCache::Private::kpcNumber = 0;
363 mCaches.append(
this);
364 mThisString =
QString(
"%1").arg(kpcNumber++);
367 KPixmapCache::Private::~Private()
369 mCaches.removeAll(
this);
372 bool KPixmapCache::Private::mmapFiles()
380 int cacheLimit = mCacheLimit > 0 ? mCacheLimit : 100 * 1024;
381 if (!mmapFile(mIndexFile, &mIndexMmapInfo, (
int)(cacheLimit * 0.4 + 100) * 1024)) {
386 if (!mmapFile(mDataFile, &mDataMmapInfo, (
int)(cacheLimit * 1.5 + 500) * 1024)) {
387 unmmapFile(&mIndexMmapInfo);
395 void KPixmapCache::Private::unmmapFiles()
397 unmmapFile(&mIndexMmapInfo);
398 unmmapFile(&mDataMmapInfo);
401 void KPixmapCache::Private::invalidateMmapFiles()
406 if (mIndexMmapInfo.file) {
407 kDebug(264) <<
"Invalidating cache";
408 mIndexMmapInfo.indexHeader->cacheId = 0;
412 bool KPixmapCache::Private::mmapFile(
const QString& filename, MmapInfo* info,
int newsize)
414 info->file =
new QFile(filename);
415 if (!info->file->open(QIODevice::ReadWrite)) {
416 kDebug(264) <<
"Couldn't open" << filename;
423 info->size = info->file->size();
425 info->available = newsize;
429 if (info->file->size() < info->available && !info->file->resize(info->available)) {
430 kError(264) <<
"Couldn't resize" << filename <<
"to" << newsize;
437 void *indexMem = info->file->map(0, info->available);
439 kError() <<
"mmap failed for" << filename;
444 info->indexHeader =
reinterpret_cast<KPixmapCacheIndexHeader *
>(indexMem);
446 posix_madvise(indexMem, info->size, POSIX_MADV_WILLNEED);
453 if(0 == info->indexHeader->size) {
456 info->indexHeader->size = mHeaderSize;
457 info->size = info->indexHeader->size;
463 void KPixmapCache::Private::unmmapFile(MmapInfo* info)
466 info->file->unmap(reinterpret_cast<uchar*>(info->indexHeader));
467 info->indexHeader = 0;
477 QIODevice* KPixmapCache::Private::indexDevice()
481 if (mIndexMmapInfo.file) {
483 QFileInfo fi(mIndexFile);
485 if (!fi.exists() || fi.size() != mIndexMmapInfo.available) {
486 kDebug(264) <<
"File size has changed, re-initializing.";
487 q->recreateCacheFiles();
491 if(fi.exists() && fi.size() == mIndexMmapInfo.available) {
493 device =
new KPCMemoryDevice(
494 reinterpret_cast<char*>(mIndexMmapInfo.indexHeader),
495 &mIndexMmapInfo.size, mIndexMmapInfo.available);
507 QFile* file =
new QFile(mIndexFile);
508 if (!file->exists() || (size_t) file->size() <
sizeof(KPixmapCacheIndexHeader)) {
509 q->recreateCacheFiles();
512 if (!q->isValid() || !file->open(QIODevice::ReadWrite)) {
513 kDebug(264) <<
"Couldn't open index file" << mIndexFile;
522 KPixmapCacheIndexHeader indexHeader;
524 int numRead = device->read(reinterpret_cast<char *>(&indexHeader),
sizeof indexHeader);
525 if (
sizeof indexHeader != numRead) {
526 kError(264) <<
"Unable to read header from pixmap cache index.";
531 if (indexHeader.cacheId != mCacheId) {
532 kDebug(264) <<
"Cache has changed, reloading";
539 return indexDevice();
546 QIODevice* KPixmapCache::Private::dataDevice()
548 if (mDataMmapInfo.file) {
550 QFileInfo fi(mDataFile);
552 if (!fi.exists() || fi.size() != mDataMmapInfo.available) {
553 kDebug(264) <<
"File size has changed, re-initializing.";
554 q->recreateCacheFiles();
562 if (fi.exists() && fi.size() == mDataMmapInfo.available) {
564 return new KPCMemoryDevice(
565 reinterpret_cast<char*>(mDataMmapInfo.indexHeader),
566 &mDataMmapInfo.size, mDataMmapInfo.available);
572 QFile* file =
new QFile(mDataFile);
573 if (!file->exists() || (size_t) file->size() <
sizeof(KPixmapCacheDataHeader)) {
574 q->recreateCacheFiles();
580 if (!file->open(QIODevice::ReadWrite)) {
581 kDebug(264) <<
"Couldn't open data file" << mDataFile;
588 int KPixmapCache::Private::binarySearchKey(QDataStream& stream,
const QString& key,
int start)
590 stream.device()->seek(start);
595 qint32 leftchild, rightchild;
596 stream >> fkey >> foffset >> timesused >> lastused >> leftchild >> rightchild;
598 if (fkey.isEmpty()) {
604 return binarySearchKey(stream, key, leftchild);
606 }
else if (key == fkey) {
608 }
else if (rightchild) {
609 return binarySearchKey(stream, key, rightchild);
615 int KPixmapCache::Private::findOffset(
const QString& key)
622 device->seek(mIndexRootOffset);
623 QDataStream stream(device);
628 if (!stream.atEnd()) {
635 if (fkey.isEmpty()) {
640 int nodeoffset = binarySearchKey(stream, key, mIndexRootOffset);
643 device->seek(nodeoffset);
650 stream >> foffset >> timesused;
653 lastused = ::time(0);
654 stream.device()->seek(stream.device()->pos() -
sizeof(
quint32));
655 stream << timesused << lastused;
666 bool KPixmapCache::Private::checkLockFile()
669 if (QFile::exists(mLockFileName)) {
671 kError() <<
"Couldn't remove lockfile" << mLockFileName;
678 bool KPixmapCache::Private::checkFileVersion(
const QString& filename)
684 if (QFile::exists(filename)) {
687 if (!f.open(QIODevice::ReadOnly)) {
688 kError() <<
"Couldn't open file" << filename;
694 KPixmapCacheIndexHeader indexHeader;
697 if(
sizeof indexHeader != f.read(reinterpret_cast<char*>(&indexHeader),
sizeof indexHeader) ||
698 qstrncmp(indexHeader.magic, KPC_MAGIC,
sizeof(indexHeader.magic)) != 0)
700 kDebug(264) <<
"File" << filename <<
"is not KPixmapCache file, or is";
701 kDebug(264) <<
"version <= 0x000207, will recreate...";
702 return q->recreateCacheFiles();
711 kDebug(264) <<
"File" << filename <<
"has newer version, disabling cache";
715 kDebug(264) <<
"File" << filename <<
"is outdated, will recreate...";
718 return q->recreateCacheFiles();
721 bool KPixmapCache::Private::loadDataHeader()
724 QFile file(mDataFile);
725 if (!file.open(QIODevice::ReadOnly)) {
729 KPixmapCacheDataHeader dataHeader;
730 if(
sizeof dataHeader != file.read(reinterpret_cast<char*>(&dataHeader),
sizeof dataHeader)) {
731 kDebug(264) <<
"Unable to read from data file" << mDataFile;
735 mDataMmapInfo.size = dataHeader.size;
739 bool KPixmapCache::Private::loadIndexHeader()
742 QFile file(mIndexFile);
743 if (!file.open(QIODevice::ReadOnly)) {
747 KPixmapCacheIndexHeader indexHeader;
748 if(
sizeof indexHeader != file.read(reinterpret_cast<char*>(&indexHeader),
sizeof indexHeader)) {
749 kWarning(264) <<
"Failed to read index file's header";
750 q->recreateCacheFiles();
754 mCacheId = indexHeader.cacheId;
755 mTimestamp = indexHeader.timestamp;
756 mIndexMmapInfo.size = indexHeader.size;
758 QDataStream stream(&file);
761 if (!q->loadCustomIndexHeader(stream)) {
765 mHeaderSize = file.pos();
766 mIndexRootOffset = file.pos();
773 const QByteArray latin1 = key.toLatin1();
774 return QString(
"%1%2").arg((ushort)qChecksum(latin1.data(), latin1.size()), 4, 16, QLatin1Char(
'0')).arg(key);
780 return mThisString + key;
783 void KPixmapCache::Private::writeIndexEntry(QDataStream& stream,
const QString& key,
int dataoffset)
786 qint32 offset = stream.device()->size();
788 int parentoffset = binarySearchKey(stream, key, mIndexRootOffset);
789 if (parentoffset != stream.device()->size()) {
792 stream.device()->seek(parentoffset);
796 if (key == fkey || fkey.isEmpty()) {
798 offset = parentoffset;
802 stream.device()->seek(offset);
804 stream << key << (
qint32)dataoffset;
813 if (parentoffset != offset) {
814 stream.device()->seek(parentoffset);
818 stream >> fkey >> foffset >> timesused >> lastused;
830 bool KPixmapCache::Private::removeEntries(
int newsize)
832 KPCLockFile lock(mLockFileName);
833 if (!lock.isValid()) {
834 kDebug(264) <<
"Couldn't lock cache" << mName;
837 QMutexLocker mutexlocker(&mMutex);
840 QFile indexfile(mIndexFile);
841 if (!indexfile.open(QIODevice::ReadOnly)) {
842 kDebug(264) <<
"Couldn't open old index file";
845 QDataStream istream(&indexfile);
846 QFile datafile(mDataFile);
847 if (!datafile.open(QIODevice::ReadOnly)) {
848 kDebug(264) <<
"Couldn't open old data file";
851 if (datafile.size() <= newsize*1024) {
852 kDebug(264) <<
"Cache size is already within limit (" << datafile.size() <<
" <= " << newsize*1024 <<
")";
855 QDataStream dstream(&datafile);
857 QFile newindexfile(mIndexFile +
".new");
858 if (!newindexfile.open(QIODevice::ReadWrite)) {
859 kDebug(264) <<
"Couldn't open new index file";
862 QDataStream newistream(&newindexfile);
863 QFile newdatafile(mDataFile +
".new");
864 if (!newdatafile.open(QIODevice::WriteOnly)) {
865 kDebug(264) <<
"Couldn't open new data file";
868 QDataStream newdstream(&newdatafile);
871 char*
header =
new char[mHeaderSize];
872 if (istream.readRawData(header, mHeaderSize) != (int)mHeaderSize) {
873 kDebug(264) <<
"Couldn't read index header";
879 reinterpret_cast<KPixmapCacheIndexHeader *
>(header)->size = 0;
880 newistream.writeRawData(header, mHeaderSize);
883 int dataheaderlen =
sizeof(KPixmapCacheDataHeader);
887 if (dstream.readRawData(header, dataheaderlen) != dataheaderlen) {
888 kDebug(264) <<
"Couldn't read data header";
894 reinterpret_cast<KPixmapCacheDataHeader *
>(header)->size = 0;
895 newdstream.writeRawData(header, dataheaderlen);
902 open.enqueue(mIndexRootOffset);
903 while (!open.isEmpty()) {
904 int indexoffset = open.dequeue();
905 indexfile.seek(indexoffset);
909 qint32 leftchild, rightchild;
910 istream >> fkey >> foffset >> timesused >> lastused >> leftchild >> rightchild;
911 entries.append(KPixmapCacheEntry(indexoffset, fkey, foffset, entries.count(), timesused, lastused));
913 open.enqueue(leftchild);
916 open.enqueue(rightchild);
922 if (q->removeEntryStrategy() == RemoveOldest) {
923 qSort(entries.begin(), entries.end(), compareEntriesByAge);
924 }
else if (q->removeEntryStrategy() == RemoveSeldomUsed) {
925 qSort(entries.begin(), entries.end(), compareEntriesByTimesUsed);
927 qSort(entries.begin(), entries.end(), compareEntriesByLastUsed);
931 int entrieswritten = 0;
932 for (entrieswritten = 0; entrieswritten < entries.count(); entrieswritten++) {
933 const KPixmapCacheEntry& entry = entries[entrieswritten];
935 datafile.seek(entry.dataoffset);
936 int entrysize = -datafile.pos();
942 dstream >> format >> w >> h >> bpl;
943 QByteArray imgdatacompressed;
944 dstream >> imgdatacompressed;
946 if (!q->loadCustomData(dstream)) {
950 entrysize += datafile.pos();
953 if (newdatafile.size() + entrysize > newsize*1024) {
958 int newdataoffset = newdatafile.pos();
960 newdstream << format << w << h << bpl;
961 newdstream << imgdatacompressed;
962 q->writeCustomData(newdstream);
965 writeIndexEntry(newistream, entry.key, newdataoffset);
971 newindexfile.rename(mIndexFile);
972 newdatafile.rename(mDataFile);
973 invalidateMmapFiles();
975 kDebug(264) <<
"Wrote back" << entrieswritten <<
"of" << entries.count() <<
"entries";
984 :d(new Private(this))
987 d->mUseQPixmapCache =
true;
988 d->mCacheLimit = 3 * 1024;
1002 void KPixmapCache::Private::init()
1006 #ifdef DISABLE_PIXMAPCACHE
1007 mValid = mEnabled =
false;
1017 mEnabled &= checkLockFile();
1018 mEnabled &= checkFileVersion(mDataFile);
1019 mEnabled &= checkFileVersion(mIndexFile);
1021 kDebug(264) <<
"Pixmap cache" << mName <<
"is disabled";
1025 q->setValid(loadIndexHeader());
1057 return d->mEnabled && d->mValid;
1069 return d->mTimestamp;
1078 KPCLockFile lock(d->mLockFileName);
1079 if (!lock.isValid()) {
1089 KPixmapCacheIndexHeader header;
1091 if(
sizeof header != device->read(reinterpret_cast<char*>(&header),
sizeof header)) {
1096 header.timestamp = ts;
1098 device->write(reinterpret_cast<char *>(&header),
sizeof header);
1106 if (d->mDataMmapInfo.file) {
1107 return d->mDataMmapInfo.size / 1024;
1109 return QFileInfo(d->mDataFile).size() / 1024;
1114 d->mUseQPixmapCache = use;
1119 return d->mUseQPixmapCache;
1124 return d->mCacheLimit;
1134 d->mCacheLimit = kbytes;
1138 if (d->mInited && d->mCacheLimit &&
size() > d->mCacheLimit) {
1139 if (
size() > (
int)(d->mCacheLimit)) {
1141 d->removeEntries(d->mCacheLimit * 0.65);
1148 return d->mRemoveStrategy;
1153 d->mRemoveStrategy = strategy;
1162 KPCLockFile lock(d->mLockFileName);
1165 d->invalidateMmapFiles();
1166 d->mEnabled =
false;
1170 if (!indexfile.
open(QIODevice::WriteOnly)) {
1171 kError() <<
"Couldn't create index file" << d->mIndexFile;
1175 d->mCacheId = ::time(0);
1176 d->mTimestamp = ::time(0);
1180 KPixmapCacheIndexHeader indexHeader = { {0},
KPIXMAPCACHE_VERSION, 0, d->mCacheId, d->mTimestamp };
1181 memcpy(indexHeader.magic, KPC_MAGIC,
sizeof(indexHeader.magic));
1183 indexfile.write(reinterpret_cast<char*>(&indexHeader),
sizeof indexHeader);
1187 if (!datafile.
open(QIODevice::WriteOnly)) {
1188 kError() <<
"Couldn't create data file" << d->mDataFile;
1193 memcpy(dataHeader.magic, KPC_MAGIC,
sizeof(dataHeader.magic));
1195 datafile.write(reinterpret_cast<char*>(&dataHeader),
sizeof dataHeader);
1199 QDataStream istream(&indexfile);
1201 d->mHeaderSize = indexfile.pos();
1203 d->mIndexRootOffset = d->mHeaderSize;
1232 KPCLockFile lock(d->mLockFileName);
1233 if(!lock.isValid()) {
1234 kError(264) <<
"Unable to lock pixmap cache when trying to discard it";
1240 kError(264) <<
"Unable to access index when trying to discard cache";
1244 device->seek(d->mIndexRootOffset);
1245 QDataStream stream(device);
1251 if (d->mUseQPixmapCache) {
1261 newsize = d->mCacheLimit;
1269 d->removeEntries(newsize);
1286 KPCLockFile lock(d->mLockFileName);
1287 if (!lock.isValid()) {
1292 QString indexkey = d->indexKey(key);
1293 int offset = d->findOffset(indexkey);
1300 bool ret = d->loadData(offset, pix);
1301 if (ret && d->mUseQPixmapCache) {
1308 bool KPixmapCache::Private::loadData(
int offset, QPixmap& pix)
1316 if (!device->seek(offset)) {
1317 kError() <<
"Couldn't seek to pos" << offset;
1321 QDataStream stream(device);
1328 qint32 format, w, h, bpl;
1329 stream >> format >> w >> h >> bpl;
1330 QByteArray imgdatacompressed;
1331 stream >> imgdatacompressed;
1337 QByteArray imgdata = qUncompress(imgdatacompressed);
1338 if (!imgdata.isEmpty()) {
1339 QImage img((
const uchar*)imgdata.constData(), w, h, bpl, (QImage::Format)format);
1341 pix = QPixmap::fromImage(img);
1343 pix = QPixmap(w, h);
1346 if (!q->loadCustomData(stream)) {
1353 kError() <<
"stream is bad :-( status=" << stream.status();
1375 if (d->mUseQPixmapCache) {
1379 KPCLockFile lock(d->mLockFileName);
1380 if (!lock.isValid()) {
1385 QString indexkey = d->indexKey(key);
1386 int offset = d->writeData(key, pix);
1392 d->writeIndex(indexkey, offset);
1395 if (d->mCacheLimit &&
size() > d->mCacheLimit) {
1397 if (
size() > (
int)(d->mCacheLimit)) {
1399 d->removeEntries(d->mCacheLimit * 0.65);
1404 int KPixmapCache::Private::writeData(
const QString& key,
const QPixmap& pix)
1411 int offset = device->size();
1412 device->seek(offset);
1413 QDataStream stream(device);
1418 QImage img = pix.toImage();
1419 QByteArray imgdatacompressed = qCompress(img.bits(), img.numBytes());
1421 stream << imgdatacompressed;
1423 q->writeCustomData(stream);
1434 void KPixmapCache::Private::writeIndex(
const QString& key,
int dataoffset)
1441 QDataStream stream(device);
1443 writeIndexEntry(stream, key, dataoffset);
1449 QFileInfo fi(filename);
1452 }
else if (fi.lastModified().toTime_t() >
timestamp()) {
1458 QString key(
"file:" + filename);
1459 if (!
find(key, pix)) {
1461 pix = QPixmap(filename);
1475 QFileInfo fi(filename);
1478 }
else if (fi.lastModified().toTime_t() >
timestamp()) {
1484 QString key =
QString(
"file:%1_%2_%3").arg(filename).arg(size.width()).arg(size.height());
1485 if (!
find(key, pix)) {
1488 if (!svg.load(filename)) {
1491 QSize pixSize = size.isValid() ? size : svg.defaultSize();
1492 pix = QPixmap(pixSize);
1493 pix.fill(Qt::transparent);
1496 svg.render(&p, QRectF(QPointF(), pixSize));
void setValid(bool valid)
Sets whether this cache is valid or not.
virtual void insert(const QString &key, const QPixmap &pix)
Inserts the pixmap pix into the cache, associated with the key key.
virtual bool loadCustomData(QDataStream &stream)
Can be used by subclasses to load custom data from the stream.
virtual bool open(OpenMode flags=QIODevice::ReadWrite)
bool useQPixmapCache() const
Whether QPixmapCache should be used to cache pixmaps in memory in addition to caching them on the dis...
const char * name(StandardAction id)
This will return the internal name of a given standard action.
void ensureInited() const
Makes sure that the cache is initialized correctly, including the loading of the cache index and data...
unsigned int timestamp() const
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
General-purpose pixmap cache for KDE.
least recently used entries are removed first.
KAction * find(const QObject *recvr, const char *slot, QObject *parent)
Initiate a 'find' request in the current document.
QPixmap loadFromFile(const QString &filename)
Loads a pixmap from given file, using the cache.
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
bool recreateCacheFiles()
This function causes the cache files to be recreate by invalidating the cache.
int open(const QString &pathname, int flags, mode_t mode)
virtual void writeCustomIndexHeader(QDataStream &stream)
Can be used by subclasses to write custom data into cache's header.
KPixmapCache(const QString &name)
Constucts the pixmap cache object.
virtual bool find(const QString &key, QPixmap &pix)
Tries to load pixmap with the specified key from cache.
KGuiItem remove()
Returns the 'Remove' gui item.
virtual bool loadCustomIndexHeader(QDataStream &stream)
Can be used by subclasses to load custom data from cache's header.
void setUseQPixmapCache(bool use)
Sets whether QPixmapCache (memory caching) should be used in addition to disk cache.
const KShortcut & insert()
Toggle insert/overwrite (with visual feedback, e.g.
RemoveStrategy removeEntryStrategy() const
KAction * clear(const QObject *recvr, const char *slot, QObject *parent)
Clear the content of the focus widget.
static void deleteCache(const QString &name)
Deletes a pixmap cache.
void setTimestamp(unsigned int time)
Sets the timestamp of app-specific cache.
#define KPIXMAPCACHE_VERSION
void removeEntries(int newsize=0)
Removes some of the entries in the cache according to current removeEntryStrategy().
void setRemoveEntryStrategy(RemoveStrategy strategy)
Sets the removeEntryStrategy used when removing entries.
void discard()
Deletes all entries and reinitializes this cache.
virtual bool writeCustomData(QDataStream &stream)
Can be used by subclasses to write custom data into the stream.
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
int madvise(caddr_t addr, size_t len, int advice)
void setCacheLimit(int kbytes)
Sets the maximum size of the cache (in kilobytes).
bool isEnabled() const
Cache will be disabled when e.g.
QPixmap loadFromSvg(const QString &filename, const QSize &size=QSize())
Same as loadFromFile(), but using an SVG file instead.
RemoveStrategy
Describes which entries will be removed first during cache cleanup.