File indexing completed on 2025-01-05 03:59:46
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2011-08-03 0007 * Description : digital camera thumbnails controller 0008 * 0009 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "camerathumbsctrl.h" 0017 0018 // Qt includes 0019 0020 #include <QCache> 0021 #include <QPair> 0022 0023 // Local includes 0024 0025 #include "digikam_debug.h" 0026 #include "cameracontroller.h" 0027 #include "thumbnailsize.h" 0028 #include "iccsettings.h" 0029 #include "iccmanager.h" 0030 #include "iccprofile.h" 0031 0032 namespace Digikam 0033 { 0034 0035 class Q_DECL_HIDDEN CameraThumbsCtrlStaticPriv 0036 { 0037 public: 0038 0039 CameraThumbsCtrlStaticPriv() 0040 : profile(IccProfile::sRGB()) 0041 { 0042 } 0043 0044 public: 0045 0046 IccProfile profile; 0047 }; 0048 0049 Q_GLOBAL_STATIC(CameraThumbsCtrlStaticPriv, static_d) 0050 0051 // ------------------------------------------------------------------------------------------ 0052 0053 class Q_DECL_HIDDEN CameraThumbsCtrl::Private 0054 { 0055 0056 public: 0057 0058 explicit Private() 0059 : controller(nullptr) 0060 { 0061 } 0062 0063 QCache<QUrl, CachedItem> cache; // Camera info/thumb cache based on item url keys. 0064 0065 QMap<QUrl, CameraCommand*> pendingItems; 0066 0067 CameraController* controller; 0068 }; 0069 0070 // -------------------------------------------------------- 0071 0072 CameraThumbsCtrl::CameraThumbsCtrl(CameraController* const ctrl, QWidget* const parent) 0073 : QObject(parent), 0074 d (new Private) 0075 { 0076 d->controller = ctrl; 0077 static_d->profile = IccManager::displayProfile(parent); 0078 0079 connect(d->controller, SIGNAL(signalThumbInfo(QString,QString,CamItemInfo,QImage)), 0080 this, SLOT(slotThumbInfo(QString,QString,CamItemInfo,QImage))); 0081 0082 connect(d->controller, SIGNAL(signalThumbInfoFailed(QString,QString,CamItemInfo)), 0083 this, SLOT(slotThumbInfoFailed(QString,QString,CamItemInfo))); 0084 0085 setCacheSize(200); 0086 } 0087 0088 CameraThumbsCtrl::~CameraThumbsCtrl() 0089 { 0090 clearCache(); 0091 } 0092 0093 CameraController* CameraThumbsCtrl::cameraController() const 0094 { 0095 return d->controller; 0096 } 0097 0098 bool CameraThumbsCtrl::getThumbInfo(const CamItemInfo& info, CachedItem& item) const 0099 { 0100 if (hasItemFromCache(info.url())) 0101 { 0102 // We look if items are not in cache. 0103 0104 item = *retrieveItemFromCache(info.url()); 0105 0106 return true; 0107 } 0108 else if (d->pendingItems.contains(info.url())) 0109 { 0110 d->controller->moveThumbsInfo(d->pendingItems.value(info.url())); 0111 } 0112 else 0113 { 0114 // We look if items are not in pending list. 0115 0116 CameraCommand* const cmd = d->controller->getThumbsInfo(CamItemInfoList() << info, 0117 ThumbnailSize::maxThumbsSize()); 0118 d->pendingItems.insert(info.url(), cmd); 0119 } 0120 0121 item = CachedItem(info, d->controller->mimeTypeThumbnail(info.name).pixmap(ThumbnailSize::maxThumbsSize())); 0122 0123 return false; 0124 } 0125 0126 void CameraThumbsCtrl::updateThumbInfoFromCache(const CamItemInfo& info) 0127 { 0128 removeItemFromCache(info.url()); 0129 CachedItem item; 0130 getThumbInfo(info, item); 0131 } 0132 0133 void CameraThumbsCtrl::slotThumbInfo(const QString&, const QString& file, const CamItemInfo& info, const QImage& thumb) 0134 { 0135 QImage thumbnail = thumb; 0136 0137 if (thumb.isNull()) 0138 { 0139 thumbnail = d->controller->mimeTypeThumbnail(file).pixmap(ThumbnailSize::maxThumbsSize()).toImage(); 0140 } 0141 0142 // Color Managed view rules. 0143 0144 if (IccSettings::instance()->useManagedPreviews()) 0145 { 0146 IccManager::transformForDisplay(thumbnail, static_d->profile); 0147 } 0148 0149 putItemToCache(info.url(), info, QPixmap::fromImage(thumbnail)); 0150 d->pendingItems.remove(info.url()); 0151 Q_EMIT signalThumbInfoReady(info); 0152 } 0153 0154 void CameraThumbsCtrl::slotThumbInfoFailed(const QString& /*folder*/, const QString& file, const CamItemInfo& info) 0155 { 0156 QPixmap pix = d->controller->mimeTypeThumbnail(file).pixmap(ThumbnailSize::maxThumbsSize()); 0157 putItemToCache(info.url(), info, pix); 0158 d->pendingItems.remove(info.url()); 0159 Q_EMIT signalThumbInfoReady(info); 0160 } 0161 0162 // -- Cache management methods ------------------------------------------------------------ 0163 0164 const CachedItem* CameraThumbsCtrl::retrieveItemFromCache(const QUrl& url) const 0165 { 0166 return d->cache[url]; 0167 } 0168 0169 bool CameraThumbsCtrl::hasItemFromCache(const QUrl& url) const 0170 { 0171 return d->cache.contains(url); 0172 } 0173 0174 void CameraThumbsCtrl::putItemToCache(const QUrl& url, const CamItemInfo& info, const QPixmap& thumb) 0175 { 0176 int infoCost = sizeof(info); 0177 int thumbCost = thumb.width() * thumb.height() * thumb.depth() / 8; 0178 d->cache.insert(url, new CachedItem(info, thumb), infoCost + thumbCost); 0179 } 0180 0181 void CameraThumbsCtrl::removeItemFromCache(const QUrl& url) 0182 { 0183 d->cache.remove(url); 0184 } 0185 0186 void CameraThumbsCtrl::clearCache() 0187 { 0188 d->cache.clear(); 0189 } 0190 0191 void CameraThumbsCtrl::setCacheSize(int numberOfItems) 0192 { 0193 d->cache.setMaxCost(numberOfItems * (ThumbnailSize::maxThumbsSize() * ThumbnailSize::maxThumbsSize() * 0194 QPixmap(1, 1).depth() / 8) + (numberOfItems * sizeof(CamItemInfo))); 0195 } 0196 0197 } // namespace Digikam 0198 0199 #include "moc_camerathumbsctrl.cpp"