File indexing completed on 2025-01-19 03:59:25

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2012-06-13
0007  * Description : Qt item model for camera thumbnails entries
0008  *
0009  * SPDX-FileCopyrightText: 2012 by Islam Wazery <wazery at ubuntu dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "importthumbnailmodel.h"
0016 
0017 // Qt includes
0018 
0019 #include <QCache>
0020 #include <QReadWriteLock>
0021 
0022 // Local includes
0023 
0024 #include "digikam_debug.h"
0025 #include "cameracontroller.h"
0026 
0027 namespace Digikam
0028 {
0029 
0030 class Q_DECL_HIDDEN ImportThumbnailModel::Private
0031 {
0032 public:
0033 
0034     explicit Private()
0035       : thumbsCtrl         (nullptr),
0036         thumbSize          (0),
0037         lastGlobalThumbSize(0),
0038         emitDataChanged    (true)
0039     {
0040     }
0041 
0042     CameraThumbsCtrl* thumbsCtrl;
0043 
0044     ThumbnailSize     thumbSize;
0045     ThumbnailSize     lastGlobalThumbSize;
0046     bool              emitDataChanged;
0047 };
0048 
0049 ImportThumbnailModel::ImportThumbnailModel(QObject* const parent)
0050     : ImportItemModel(parent),
0051       d              (new Private)
0052 {
0053     setKeepsFileUrlCache(true);
0054 }
0055 
0056 ImportThumbnailModel::~ImportThumbnailModel()
0057 {
0058     delete d;
0059 }
0060 
0061 void ImportThumbnailModel::setCameraThumbsController(CameraThumbsCtrl* const thumbsCtrl)
0062 {
0063     d->thumbsCtrl = thumbsCtrl;
0064 
0065     connect(d->thumbsCtrl, SIGNAL(signalThumbInfoReady(CamItemInfo)),
0066             this, SLOT(slotThumbInfoReady(CamItemInfo)));
0067 
0068     ImportItemModel::setCameraThumbsController(d->thumbsCtrl);
0069 }
0070 
0071 ThumbnailSize ImportThumbnailModel::thumbnailSize() const
0072 {
0073     return d->thumbSize;
0074 }
0075 
0076 void ImportThumbnailModel::setEmitDataChanged(bool emitSignal)
0077 {
0078     d->emitDataChanged = emitSignal;
0079 }
0080 
0081 QVariant ImportThumbnailModel::data(const QModelIndex& index, int role) const
0082 {
0083     if (role == ThumbnailRole && d->thumbsCtrl && index.isValid())
0084     {
0085         CamItemInfo info = camItemInfo(index);
0086         QString     path = info.url().toLocalFile();
0087         CachedItem  item;
0088 
0089         // use mimetype thumbnail also if the mime is set to something else than to image
0090         // this is to avoid querying the device for previews with unsupported file formats
0091         // at least gphoto2 doesn't really like it and will error a lot and slow down
0092 
0093         bool thumbnailPossible = (info.previewPossible                                       ||
0094                                   d->thumbsCtrl->cameraController()->cameraThumbnailSupport());
0095 
0096         if (info.isNull() || path.isEmpty() || !thumbnailPossible)
0097         {
0098             return QVariant(d->thumbsCtrl->cameraController()->mimeTypeThumbnail(path).pixmap(d->thumbSize.size()));
0099         }
0100 
0101         if (d->thumbsCtrl->getThumbInfo(info, item))
0102         {
0103             return QVariant(item.second.scaled(d->thumbSize.size(), d->thumbSize.size(), Qt::KeepAspectRatio));
0104         }
0105 
0106         return QVariant(d->thumbsCtrl->cameraController()->mimeTypeThumbnail(path).pixmap(d->thumbSize.size()));
0107     }
0108 
0109     return ImportItemModel::data(index, role);
0110 }
0111 
0112 bool ImportThumbnailModel::setData(const QModelIndex& index, const QVariant& value, int role)
0113 {
0114     if (role == ThumbnailRole)
0115     {
0116 
0117 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0118 
0119         switch (value.typeId())
0120 
0121 #else
0122 
0123         switch (value.type())
0124 
0125 #endif
0126 
0127         {
0128             case QVariant::Invalid:
0129             {
0130                 d->thumbSize  = d->lastGlobalThumbSize;
0131                 break;
0132             }
0133 
0134             case QVariant::Int:
0135             {
0136                 if (value.isNull())
0137                 {
0138                     d->thumbSize = d->lastGlobalThumbSize;
0139                 }
0140                 else
0141                 {
0142                     d->lastGlobalThumbSize = d->thumbSize;
0143                     d->thumbSize           = ThumbnailSize(value.toInt());
0144                 }
0145 
0146                 break;
0147             }
0148 
0149             default:
0150             {
0151                 break;
0152             }
0153         }
0154     }
0155 
0156     return ImportItemModel::setData(index, value, role);
0157 }
0158 
0159 void ImportThumbnailModel::slotThumbInfoReady(const CamItemInfo& info)
0160 {
0161     CachedItem  item;
0162     d->thumbsCtrl->getThumbInfo(info, item);
0163 
0164     // In case of multiple occurrence, we currently do not know which thumbnail is this. Signal change on all.
0165 
0166     Q_FOREACH (const QModelIndex& index, indexesForUrl(info.url()))
0167     {
0168         if (item.second.isNull())
0169         {
0170             Q_EMIT thumbnailFailed(index, d->thumbSize.size());
0171         }
0172         else
0173         {
0174             Q_EMIT thumbnailAvailable(index, d->thumbSize.size());
0175 
0176             if (d->emitDataChanged)
0177             {
0178                 Q_EMIT dataChanged(index, index);
0179             }
0180         }
0181     }
0182 }
0183 
0184 } // namespace Digikam
0185 
0186 #include "moc_importthumbnailmodel.cpp"