From ddfaa63a24d60521d71c84ef22378ff781e64758 Mon Sep 17 00:00:00 2001 From: blue Date: Mon, 17 May 2021 23:32:44 +0300 Subject: [PATCH] big image preview optimisations, preview positioning fix, memory leaks fix --- shared/global.cpp | 4 +- ui/widgets/messageline/messagedelegate.cpp | 2 + ui/widgets/messageline/preview.cpp | 53 +++++++++++++++------- ui/widgets/messageline/preview.h | 4 +- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/shared/global.cpp b/shared/global.cpp index 0330a00..67e74d1 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -128,12 +128,12 @@ Shared::Global::FileInfo Shared::Global::getFileInfo(const QString& path) QSize size; if (big == "image") { QMovie mov(path); - if (mov.isValid()) { + if (mov.isValid() && mov.frameCount() > 1) { p = FileInfo::Preview::animation; } else { p = FileInfo::Preview::picture; } - QImage img(path); + QImageReader img(path); size = img.size(); // } else if (big == "video") { // p = FileInfo::Preview::movie; diff --git a/ui/widgets/messageline/messagedelegate.cpp b/ui/widgets/messageline/messagedelegate.cpp index 81018ac..9b46b7a 100644 --- a/ui/widgets/messageline/messagedelegate.cpp +++ b/ui/widgets/messageline/messagedelegate.cpp @@ -289,6 +289,8 @@ void MessageDelegate::initializeFonts(const QFont& font) bodyMetrics = QFontMetrics(bodyFont); nickMetrics = QFontMetrics(nickFont); dateMetrics = QFontMetrics(dateFont); + + Preview::initializeFont(bodyFont); } bool MessageDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) diff --git a/ui/widgets/messageline/preview.cpp b/ui/widgets/messageline/preview.cpp index 8c56cbc..a64c036 100644 --- a/ui/widgets/messageline/preview.cpp +++ b/ui/widgets/messageline/preview.cpp @@ -22,7 +22,6 @@ constexpr int margin = 6; constexpr int maxAttachmentHeight = 500; -bool Preview::fontInitialized = false; QFont Preview::font; QFontMetrics Preview::metrics(Preview::font); @@ -41,12 +40,6 @@ Preview::Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos, actualPreview(false), right(pRight) { - if (!fontInitialized) { - font.setBold(true); - font.setPixelSize(14); - metrics = QFontMetrics(font); - fontInitialized = true; - } initializeElements(); if (fileReachable) { @@ -54,6 +47,13 @@ Preview::Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos, } } +void Preview::initializeFont(const QFont& newFont) +{ + font = newFont; + font.setBold(true); + metrics = QFontMetrics(font); +} + Preview::~Preview() { clean(); @@ -104,6 +104,9 @@ void Preview::actualize(const QString& newPath, const QSize& newSize, const QPoi } } else if (maxSizeChanged) { applyNewMaxSize(); + if (right) { + positionChanged = true; + } } if (positionChanged || !actualPreview) { positionElements(); @@ -132,6 +135,9 @@ void Preview::setSize(const QSize& newSize) } if (maxSizeChanged || !actualPreview) { applyNewMaxSize(); + if (right) { + positionElements(); + } } } } @@ -140,13 +146,14 @@ void Preview::applyNewSize() { switch (info.preview) { case Shared::Global::FileInfo::Preview::picture: { - QPixmap img(path); - if (img.isNull()) { + QImageReader img(path); + if (!img.canRead()) { + delete widget; fileReachable = false; } else { - img = img.scaled(actualSize, Qt::KeepAspectRatio); + img.setScaledSize(actualSize); widget->resize(actualSize); - widget->setPixmap(img); + widget->setPixmap(QPixmap::fromImage(img.read())); } } break; @@ -172,7 +179,7 @@ void Preview::applyNewMaxSize() default: { int labelWidth = maxSize.width() - actualSize.width() - margin; QString elidedName = metrics.elidedText(info.name, Qt::ElideMiddle, labelWidth); - cachedLabelSize = metrics.size(0, elidedName); + cachedLabelSize = metrics.boundingRect(elidedName).size(); label->setText(elidedName); label->resize(cachedLabelSize); } @@ -225,20 +232,23 @@ void Preview::initializeElements() { switch (info.preview) { case Shared::Global::FileInfo::Preview::picture: { - QPixmap img(path); - if (img.isNull()) { + QImageReader img(path); + if (!img.canRead()) { fileReachable = false; } else { actualPreview = true; - img = img.scaled(actualSize, Qt::KeepAspectRatio); + img.setScaledSize(actualSize); widget = new QLabel(parent); - widget->setPixmap(img); + widget->setPixmap(QPixmap::fromImage(img.read())); widget->show(); } } break; case Shared::Global::FileInfo::Preview::animation:{ movie = new QMovie(path); + QObject::connect(movie, &QMovie::error, + std::bind(&Preview::handleQMovieError, this, std::placeholders::_1) + ); if (!movie->isValid()) { fileReachable = false; delete movie; @@ -262,7 +272,7 @@ void Preview::initializeElements() label->setFont(font); int labelWidth = maxSize.width() - actualSize.width() - margin; QString elidedName = metrics.elidedText(info.name, Qt::ElideMiddle, labelWidth); - cachedLabelSize = metrics.size(0, elidedName); + cachedLabelSize = metrics.boundingRect(elidedName).size(); label->setText(elidedName); label->show(); } @@ -302,3 +312,12 @@ QSize Preview::constrainAttachSize(QSize src, QSize bounds) return src; } + +void Preview::handleQMovieError(QImageReader::ImageReaderError error) +{ + if (error == QImageReader::FileNotFoundError) { + fileReachable = false; + movie->deleteLater(); + widget->deleteLater(); + } +} diff --git a/ui/widgets/messageline/preview.h b/ui/widgets/messageline/preview.h index 3d560d3..004ed45 100644 --- a/ui/widgets/messageline/preview.h +++ b/ui/widgets/messageline/preview.h @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -47,9 +48,9 @@ public: bool isFileReachable() const; QSize size() const; + static void initializeFont(const QFont& newFont); static QSize constrainAttachSize(QSize src, QSize bounds); static QSize calculateAttachSize(const QString& path, const QRect& bounds); - static bool fontInitialized; static QFont font; static QFontMetrics metrics; @@ -59,6 +60,7 @@ private: void clean(); void applyNewSize(); void applyNewMaxSize(); + void handleQMovieError(QImageReader::ImageReaderError error); private: Shared::Global::FileInfo info;