diff --git a/ext/libclementine-common/core/closure.h b/ext/libclementine-common/core/closure.h index d52370757..32cf8e7ac 100644 --- a/ext/libclementine-common/core/closure.h +++ b/ext/libclementine-common/core/closure.h @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include #include @@ -189,13 +191,22 @@ _detail::ClosureBase* NewClosure(QObject* sender, const char* signal, return NewClosure(sender, signal, std::bind(callback, receiver, args...)); } +template +_detail::ClosureBase* NewClosure(QFuture future, QObject* receiver, + const char* slot, const Args&... args) { + QFutureWatcher* watcher = new QFutureWatcher; + watcher->setFuture(future); + QObject::connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); + return NewClosure(watcher, SIGNAL(finished()), receiver, slot, args...); +} + void DoAfter(QObject* receiver, const char* slot, int msec); void DoAfter(std::function callback, std::chrono::milliseconds msec); void DoInAMinuteOrSo(QObject* receiver, const char* slot); template -void DoAfter( - std::function callback, std::chrono::duration duration) { +void DoAfter(std::function callback, + std::chrono::duration duration) { QTimer* timer = new QTimer; timer->setSingleShot(true); NewClosure(timer, SIGNAL(timeout()), callback); diff --git a/src/widgets/prettyimage.cpp b/src/widgets/prettyimage.cpp index 3a758af56..dbb22de00 100644 --- a/src/widgets/prettyimage.cpp +++ b/src/widgets/prettyimage.cpp @@ -16,7 +16,6 @@ */ #include "prettyimage.h" -#include "ui/iconloader.h" #include #include @@ -24,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +32,9 @@ #include #include +#include "core/closure.h" +#include "ui/iconloader.h" + const int PrettyImage::kTotalHeight = 200; const int PrettyImage::kReflectionHeight = 40; const int PrettyImage::kImageHeight = @@ -60,8 +61,9 @@ void PrettyImage::LazyLoad() { // Start fetching the image QNetworkReply* reply = network_->get(QNetworkRequest(url_)); - connect(reply, SIGNAL(finished()), SLOT(ImageFetched())); state_ = State_Fetching; + NewClosure(reply, SIGNAL(finished()), this, + SLOT(ImageFetched(QNetworkReply*)), reply); } QSize PrettyImage::image_size() const { @@ -76,8 +78,7 @@ QSize PrettyImage::sizeHint() const { return QSize(image_size().width(), kTotalHeight); } -void PrettyImage::ImageFetched() { - QNetworkReply* reply = qobject_cast(sender()); +void PrettyImage::ImageFetched(QNetworkReply* reply) { reply->deleteLater(); QImage image = QImage::fromData(reply->readAll()); @@ -90,20 +91,12 @@ void PrettyImage::ImageFetched() { QFuture future = QtConcurrent::run(image_, &QImage::scaled, image_size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); - - QFutureWatcher* watcher = new QFutureWatcher(this); - watcher->setFuture(future); - connect(watcher, SIGNAL(finished()), SLOT(ImageScaled())); + NewClosure(future, this, SLOT(ImageScaled(QFuture)), future); } } -void PrettyImage::ImageScaled() { - QFutureWatcher* watcher = - reinterpret_cast*>(sender()); - if (!watcher) return; - watcher->deleteLater(); - - thumbnail_ = QPixmap::fromImage(watcher->result()); +void PrettyImage::ImageScaled(QFuture future) { + thumbnail_ = QPixmap::fromImage(future.result()); state_ = State_Finished; updateGeometry(); @@ -179,7 +172,7 @@ void PrettyImage::contextMenuEvent(QContextMenuEvent* e) { if (!menu_) { menu_ = new QMenu(this); - menu_->addAction(IconLoader::Load("zoom-in", IconLoader::Base), + menu_->addAction(IconLoader::Load("zoom-in", IconLoader::Base), tr("Show fullsize..."), this, SLOT(ShowFullsize())); menu_->addAction(IconLoader::Load("document-save", IconLoader::Base), tr("Save image") + "...", this, SLOT(SaveAs())); diff --git a/src/widgets/prettyimage.h b/src/widgets/prettyimage.h index 1467e5850..ceee4a1de 100644 --- a/src/widgets/prettyimage.h +++ b/src/widgets/prettyimage.h @@ -18,6 +18,7 @@ #ifndef PRETTYIMAGE_H #define PRETTYIMAGE_H +#include #include #include @@ -56,8 +57,8 @@ signals: void paintEvent(QPaintEvent*); private slots: - void ImageFetched(); - void ImageScaled(); + void ImageFetched(QNetworkReply* reply); + void ImageScaled(QFuture future); private: enum State {