#include "ui/SessionImages.h" #include #include #include #include "cst_attach.h" namespace app { namespace { /* "img-1a2b3c4d.png?w=160": the stored name, then what the view asked for. * The size comes from the QML side as sourceSize, which Qt passes in as * requestedSize; the query string is accepted too, so a plain URL can ask. */ QString relOf(const QString &id) { const int q = id.indexOf(QLatin1Char('?')); return q < 0 ? id : id.left(q); } } // namespace SessionImages::SessionImages() : QQuickImageProvider(QQuickImageProvider::Image) {} void SessionImages::setDir(const QString &dir) { QMutexLocker lock(&m_mu); m_dir = dir; } QImage SessionImages::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { const QString rel = relOf(id); if (!cst_attach_rel_ok(rel.toUtf8().constData())) return QImage(); /* QML sees Image.Error and falls back to the name */ QString dir; { QMutexLocker lock(&m_mu); dir = m_dir; } if (dir.isEmpty()) return QImage(); const QString path = dir + QLatin1Char('/') + rel; if (!QFileInfo::exists(path)) return QImage(); QImageReader reader(path); reader.setAutoTransform(true); const QSize full = reader.size(); if (!full.isValid()) { /* No size in the header (or not a picture at all): hand back what Qt * makes of it and let the view scale it. */ const QImage img = reader.read(); if (size) *size = img.size(); return img; } /* Shrink to what the view shows, never up: a screenshot is decoded at the * size of its thumbnail instead of at 4K. */ const bool smaller = requestedSize.isValid() && requestedSize.width() > 0 && requestedSize.height() > 0 && (full.width() > requestedSize.width() || full.height() > requestedSize.height()); if (smaller) { const QSize scaled = full.scaled(requestedSize, Qt::KeepAspectRatio); reader.setScaledSize(scaled); if (size) *size = scaled; } else if (size) { *size = full; } return reader.read(); } SessionImages *installSessionImages(QQmlApplicationEngine *engine) { SessionImages *images = new SessionImages; if (engine) engine->addImageProvider(QStringLiteral("cstattach"), images); return images; } } // namespace app