Beispiel #1
0
void Cache::setEntry(const Entry &entry)
{
	QMutableListIterator<Entry> it(m_entries);
	while (it.hasNext()) {
		Entry e = it.next();
		if (e.url == entry.url) {
			it.setValue(entry);
			writeCacheFile();
			return;
		}
	}
	m_entries.append(entry);
	writeCacheFile();
}
QImage NemoThumbnailProvider::generateThumbnail(const QString &id, const QByteArray &hashData, const QSize &requestedSize, bool crop)
{
    QImage img;
    QSize originalSize;
    QByteArray format;

    // image was not in cache thus we read it
    QImageReader ir(id);
    if (!ir.canRead())
        return img;

    originalSize = ir.size();
    format = ir.format();

    if (originalSize != requestedSize && originalSize.isValid()) {
        if (crop) {
            // scales arbitrary sized source image to requested size scaling either up or down
            // keeping aspect ratio of the original image intact by maximizing either width or height
            // and cropping the rest of the image away
            QSize scaledSize(originalSize);

            // now scale it filling the original rectangle by keeping aspect ratio, but expand if needed.
            scaledSize.scale(requestedSize, Qt::KeepAspectRatioByExpanding);

            // set the adjusted clipping rectangle in the center of the scaled image
            QPoint center((scaledSize.width() - 1) / 2, (scaledSize.height() - 1) / 2);
            QRect cr(0,0,requestedSize.width(), requestedSize.height());
            cr.moveCenter(center);
            ir.setScaledClipRect(cr);

            // set requested target size of a thumbnail
            ir.setScaledSize(scaledSize);
        } else {
            // Maintains correct aspect ratio without cropping, as such the final image may
            // be smaller than requested in one dimension.
            QSize scaledSize(originalSize);
            scaledSize.scale(requestedSize, Qt::KeepAspectRatio);
            ir.setScaledSize(scaledSize);
        }
    }
    img = ir.read();

    NemoImageMetadata meta(id, format);
    if (meta.orientation() != NemoImageMetadata::TopLeft)
        img = rotate(img, meta.orientation());

    // write the scaled image to cache
    if (meta.orientation() != NemoImageMetadata::TopLeft ||
        (originalSize != requestedSize && originalSize.isValid())) {
        writeCacheFile(hashData, img);
    }

    TDEBUG() << Q_FUNC_INFO << "Wrote " << id << " to cache";
    return img;
}
Beispiel #3
0
void Document::cache()
{
	if (m_cache_outdated) {
		m_cache_outdated = false;
		DocumentWriter* writer = new DocumentWriter;
		writer->setType(!m_filename.isEmpty() ? m_filename.section(QLatin1Char('.'), -1) : "odt");
		writer->setEncoding(m_encoding);
		writer->setWriteByteOrderMark(Preferences::instance().writeByteOrderMark());
		writer->setDocument(m_text->document()->clone());
		emit writeCacheFile(this, writer);
	}
}
Beispiel #4
0
void Cache::cleanCache(const QList<QUrl> &in)
{
	// purge entries that don't exist in 'in'
	{
		QList<Entry> entriesToRemove;
		for (const auto entry : m_entries) {
			if (!in.contains(entry.url)) {
				// this entry doesn't exist anymore, so remove it
				entriesToRemove += entry;
			}
		}
		for (auto entry : entriesToRemove) {
			removeEntry(entry);
		}
	}
	// remove directories, as that's not something we put there
	for (const QFileInfo &info : m_dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
		FS::remove(info);
	}
	// remove files that we don't know anything of
	for (const QFileInfo &info : m_dir.entryInfoList(QStringList() << "*.cache", QDir::Files)) {
		if (info.fileName() == ".cache.json") {
			continue;
		}
		bool found = false;
		for (const auto entry : m_entries) {
			if (absoluteFilename(entry) == info.absoluteFilePath()) {
				found = true;
				break;
			}
		}
		// it doesn't exist in the cache metadata, so we remove it
		if (!found) {
			FS::remove(info);
		}
	}
	// remove cache entries where the file isn't existing anymore
	{
		QMutableListIterator<Entry> it(m_entries);
		while (it.hasNext()) {
			if (!QFileInfo(absoluteFilename(it.next())).exists()) {
				it.remove();
			}
		}
	}
	writeCacheFile();
}
QImage FileThumbnailImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
    setupCache();

    // needed for stupid things like gallery model, which pass us a url
    if (id.startsWith("file://")) {
        qWarning() << Q_FUNC_INFO << "Removing file:// prefix, before: " << id;
        QString &nid = const_cast<QString &>(id);
        nid = nid.remove(0, 7);
    }

    qDebug() << Q_FUNC_INFO << "Requested image: " << id << " with size " << requestedSize;

    // sourceSize should indicate what size thumbnail you want. i.e. if you want a 120x120px thumbnail,
    // set sourceSize: Qt.size(120, 120).
    if (!requestedSize.isValid())
        qFatal("You must request a sourceSize whenever you use nemoThumbnail");

    if (size)
        *size = requestedSize;

    QByteArray hashData = cacheKey(id, requestedSize);
    QImage img = attemptCachedServe(hashData);
    if (!img.isNull()) {
        qDebug() << Q_FUNC_INFO << "Read " << id << " from cache";
        return img;
    }

    // cache couldn't satisfy us.
    // step 1: read source image in
    QImageReader ir(id);
    img = ir.read();

    // don't pollute the cache with false positives
    if (img.isNull())
        return QImage();

    if (img.size() == requestedSize)
        return img;

    // step 2: scale to target size
    if (img.height() == img.width()) {
        // in the case of a squared image, there's no need to crop
        img = img.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    } else  if (img.height() >= requestedSize.height() && img.width() >= requestedSize.width()) {
        // if the image is larger than the desired size (on both dimensions)
        // then crop, and scale down
        if (img.width() < img.height()) {
            int cropPosition = (img.height() - img.width()) / 2;
            img = img.copy(0, cropPosition, img.width(), img.width());
            img = img.scaledToWidth(requestedSize.width(), Qt::SmoothTransformation);
        } else {
            int cropPosition = (img.width() - img.height()) / 2;
            img = img.copy(cropPosition, 0, img.height(), img.height());
            img = img.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation);
        }
    } else if ((img.width() <= requestedSize.width() && img.height() >= requestedSize.height()) ||
               (img.width() >= requestedSize.width() && img.height() <= requestedSize.height())) {
        // if the image is smaller than the desired size on one dimension, scale it up,
        // then crop down to thumbnail size.
        if (img.width() <= requestedSize.width() && img.height() >= requestedSize.height()) {
            img = img.scaledToWidth(requestedSize.width(), Qt::SmoothTransformation);
            int cropPosition = (img.height() - img.width()) / 2;
            img = img.copy(0, cropPosition, img.width(), img.width());
        } else {
            img = img.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation);
            int cropPosition = (img.width() - img.height()) / 2;
            img = img.copy(cropPosition, 0, img.height(), img.height());
        }
    } else {
        // if the image is smaller on both dimensions, scale it up, and use the requested
        // size to do the cropping
        if (img.width() < img.height()) {
            img = img.scaledToWidth(requestedSize.width(), Qt::SmoothTransformation);
            int cropPosition = (img.height() - requestedSize.height()) / 2;
            img = img.copy(0, cropPosition, img.width(), img.width());
        } else {
            img = img.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation);
            int cropPosition = (img.width() - requestedSize.width()) / 2;
            img = img.copy(cropPosition, 0, img.height(), img.height());
        }
    }

    // step 3: write to cache for next time
    writeCacheFile(hashData, img);
    qDebug() << Q_FUNC_INFO << "Wrote " << id << " to cache";
    return img;
}