File indexing completed on 2024-04-28 15:39:41

0001 /* SPDX-FileCopyrightText: 2014 Jesper K. Pedersen <blackie@kde.org>
0002 
0003    SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "ImageStore.h"
0007 #include "RemoteInterface.h"
0008 #include "Settings.h"
0009 
0010 #include "RemoteImage.h"
0011 #include <QMutexLocker>
0012 #include <QTimer>
0013 
0014 namespace RemoteControl
0015 {
0016 
0017 ImageStore &ImageStore::instance()
0018 {
0019     static ImageStore instance;
0020     return instance;
0021 }
0022 
0023 ImageStore::ImageStore()
0024 {
0025     connect(&Settings::instance(), &Settings::thumbnailSizeChanged, this, &ImageStore::reset);
0026     connect(&Settings::instance(), &Settings::categoryItemSizeChanged, this, &ImageStore::reset);
0027 }
0028 
0029 void ImageStore::requestImage(RemoteImage *client, ImageId imageId, const QSize &size, ViewType type)
0030 {
0031     // This method is call from the painting thread.
0032     QMutexLocker locker(&m_mutex);
0033 
0034     // This code is executed from paint, which is on the QML thread, we therefore need to get it on the GUI thread
0035     // where out TCPSocket is located.
0036     QTimer *timer = new QTimer;
0037     timer->setSingleShot(true);
0038 
0039     // There seems to be a path through QML where the client is deleted right after this request is send,
0040     // therefore, have client as the third parameter to the connect below, as that will prevent the request in that setup.
0041     connect(timer, &QTimer::timeout, client, [imageId, size, type, timer, client, this]() {
0042         ThumbnailRequest request(imageId, size, type);
0043 
0044         RemoteInterface::instance().sendCommand(request);
0045 
0046         RequestType key = qMakePair(imageId, type);
0047         m_requestMap.insert(key, client);
0048         m_reverseRequestMap.insert(client, key);
0049 
0050         connect(client, &QObject::destroyed, this, &ImageStore::clientDeleted);
0051         timer->deleteLater();
0052     });
0053     timer->start(0);
0054 }
0055 
0056 void ImageStore::updateImage(ImageId imageId, const QImage &image, const QString &label, ViewType type)
0057 {
0058     QMutexLocker locker(&m_mutex);
0059     RequestType key = qMakePair(imageId, type);
0060     if (m_requestMap.contains(key)) {
0061         RemoteImage *client = m_requestMap[key];
0062 
0063         client->setImage(image);
0064         client->setLabel(label);
0065 
0066         m_requestMap.remove(key);
0067         m_reverseRequestMap.remove(client);
0068     }
0069 }
0070 
0071 void RemoteControl::ImageStore::reset()
0072 {
0073     QList<RemoteImage *> keys = m_reverseRequestMap.keys();
0074     m_reverseRequestMap.clear();
0075     m_requestMap.clear();
0076 }
0077 
0078 void ImageStore::clientDeleted()
0079 {
0080     RemoteImage *remoteImage = static_cast<RemoteImage *>(sender());
0081 
0082     QMutexLocker locker(&m_mutex);
0083     if (m_reverseRequestMap.contains(remoteImage)) {
0084         RequestType key = m_reverseRequestMap[remoteImage];
0085         m_reverseRequestMap.remove(remoteImage);
0086         m_requestMap.remove(key);
0087 
0088         if (key.second == ViewType::Thumbnails)
0089             RemoteInterface::instance().sendCommand(ThumbnailCancelRequest(key.first, key.second));
0090     }
0091 }
0092 
0093 } // namespace RemoteControl
0094 
0095 #include "moc_ImageStore.cpp"