File indexing completed on 2024-04-21 03:51:05

0001 /*
0002     SPDX-FileCopyrightText: 2010 Daniel Laidig <laidig@kde.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "imagecache.h"
0007 
0008 #include <QDataStream>
0009 #include <QDir>
0010 #include <QFileInfo>
0011 
0012 #include <QDebug>
0013 
0014 using namespace Practice;
0015 
0016 const char *identifier = "parleyimagecache2";
0017 
0018 void ImageCache::setFilenames(const QStringList &filenames)
0019 {
0020     m_timestamps.clear();
0021     for (const QString &filename : filenames) {
0022         QFileInfo info(filename);
0023         m_timestamps.append(info.lastModified());
0024     }
0025     m_images.clear();
0026     m_filenames = filenames;
0027     if (!m_saveFilename.isNull()) {
0028         openCache();
0029     }
0030 }
0031 
0032 void ImageCache::updateImage(const QString &id, const QImage &image)
0033 {
0034     m_images[id] = image;
0035 }
0036 
0037 QSize ImageCache::imageSize(const QString &id)
0038 {
0039     if (!m_images.contains(id)) {
0040         return QSize();
0041     }
0042     return m_images.value(id).size();
0043 }
0044 
0045 QImage ImageCache::getImage(const QString &id)
0046 {
0047     if (!m_images.contains(id)) {
0048         return QImage();
0049     }
0050     return m_images.value(id);
0051 }
0052 
0053 void ImageCache::setSaveFilename(const QString &filename)
0054 {
0055     m_saveFilename = filename;
0056     QDir fileDir = QFileInfo(filename).absoluteDir();
0057     if (!fileDir.exists() && !fileDir.mkpath(QStringLiteral("."))) {
0058         qWarning() << QStringLiteral("Couldn't create image cache path: ") << fileDir.absolutePath();
0059     }
0060 }
0061 
0062 void ImageCache::openCache()
0063 {
0064     QFile file(m_saveFilename);
0065     if (!file.open(QIODevice::ReadOnly)) {
0066         // If cache is used for the first time it's normal to fail here,
0067         // because cache file doesn't exist at this time.
0068         return;
0069     }
0070     QDataStream stream(&file);
0071     // check identifier
0072     QString temp;
0073     stream >> temp;
0074     if (temp != QString(identifier)) {
0075         // qDebug() << "not loading cache because the identifier doesn't match";
0076         return;
0077     }
0078     // check filename and timestamp, no need to load images for the wrong file or outdated images
0079     QStringList filenames;
0080     QList<QDateTime> timestamps;
0081     stream >> filenames >> timestamps;
0082     if (filenames != m_filenames || timestamps != m_timestamps) {
0083         // qDebug() << "not loading cache because it contains the wrong theme or the timestamp has changed";
0084         return;
0085     }
0086     // finally load data
0087     stream >> m_images;
0088     QHashIterator<QString, QImage> i(m_images); // TODO: do on demand
0089     while (i.hasNext()) {
0090         i.next();
0091         m_images[i.key()] = i.value().convertToFormat(QImage::Format_ARGB32_Premultiplied);
0092     }
0093     // qDebug() << "opened cache:" << m_saveFilename;
0094     // qDebug() << *this;
0095 }
0096 
0097 void ImageCache::saveCache()
0098 {
0099     // qDebug() << "save cache to:" << m_saveFilename;
0100     // qDebug() << *this;
0101     QFile file(m_saveFilename);
0102     file.open(QIODevice::WriteOnly);
0103     QDataStream stream(&file);
0104     stream << QString(identifier) << m_filenames << m_timestamps << m_images;
0105 }
0106 
0107 QDebug Practice::operator<<(QDebug dbg, const ImageCache &c)
0108 {
0109     dbg.nospace() << "(ImageCache, " << c.m_filenames << ", " << c.m_timestamps << ")";
0110     int pixels = 0;
0111     QHashIterator<QString, QImage> i(c.m_images);
0112     while (i.hasNext()) {
0113         i.next();
0114         dbg.nospace() << "\n\tcontains: " << qPrintable(i.key().leftJustified(35)) << ": " << i.value().size();
0115         pixels += i.value().size().width() * i.value().height();
0116     }
0117 
0118     dbg.nospace() << "\n\ttotal pixel count: " << pixels << " (approx. " << double(pixels) * 4 / 1024 / 1024 << " MiB)";
0119     return dbg.space();
0120 }