File indexing completed on 2025-03-09 03:55:28

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-07-15
0007  * Description : Model for central Map view
0008  *
0009  * SPDX-FileCopyrightText: 2010      by Gabriel Voicu <ping dot gabi at gmail dot com>
0010  * SPDX-FileCopyrightText: 2010-2011 by Michael G. Hansen <mike at mghansen dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "itemgpsmodelhelper.h"
0017 
0018 namespace Digikam
0019 {
0020 
0021 class Q_DECL_HIDDEN ItemGPSModelHelper::Private
0022 {
0023 public:
0024 
0025     explicit Private()
0026       : itemModel          (nullptr),
0027         itemSelectionModel (nullptr),
0028         thumbnailLoadThread(nullptr)
0029     {
0030     }
0031 
0032     QStandardItemModel*  itemModel;
0033     QItemSelectionModel* itemSelectionModel;
0034     ThumbnailLoadThread* thumbnailLoadThread;
0035 };
0036 
0037 ItemGPSModelHelper::ItemGPSModelHelper(QStandardItemModel* const itemModel, QObject* const parent)
0038     : GeoModelHelper(parent),
0039       d             (new Private())
0040 {
0041 
0042     d->itemModel           = itemModel;
0043     d->itemSelectionModel  = new QItemSelectionModel(d->itemModel);
0044     d->thumbnailLoadThread = new ThumbnailLoadThread(this);
0045 
0046     connect(d->thumbnailLoadThread, SIGNAL(signalThumbnailLoaded(LoadingDescription,QPixmap)),
0047             this, SLOT(slotThumbnailLoaded(LoadingDescription,QPixmap)));
0048 
0049     connect(d->itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
0050             this, SIGNAL(signalModelChangedDrastically()));
0051 }
0052 
0053 ItemGPSModelHelper::~ItemGPSModelHelper()
0054 {
0055     delete d;
0056 }
0057 
0058 QAbstractItemModel* ItemGPSModelHelper::model() const
0059 {
0060     return d->itemModel;
0061 }
0062 
0063 QItemSelectionModel* ItemGPSModelHelper::selectionModel() const
0064 {
0065     return d->itemSelectionModel;
0066 }
0067 
0068 bool ItemGPSModelHelper::itemCoordinates(const QModelIndex& index,
0069                                          GeoCoordinates* const coordinates) const
0070 {
0071     const GPSItemInfo currentGPSItemInfo = index.data(RoleGPSItemInfo).value<GPSItemInfo>();
0072     *coordinates                         = currentGPSItemInfo.coordinates;
0073 
0074     if (currentGPSItemInfo.coordinates.hasCoordinates())
0075     {
0076         return true;
0077     }
0078     else
0079     {
0080         return false;
0081     }
0082 }
0083 
0084 QPixmap ItemGPSModelHelper::pixmapFromRepresentativeIndex(const QPersistentModelIndex& index,
0085                                                           const QSize& size)
0086 {
0087     if (!index.isValid())
0088     {
0089         return QPixmap();
0090     }
0091 
0092     const QModelIndex currentIndex(index);
0093     const GPSItemInfo currentGPSItemInfo = currentIndex.data(RoleGPSItemInfo).value<GPSItemInfo>();
0094 
0095     QPixmap thumbnail;
0096     ThumbnailIdentifier thumbId;
0097     thumbId.filePath = currentGPSItemInfo.url.toLocalFile();
0098     thumbId.id       = currentGPSItemInfo.id;
0099 
0100     if (d->thumbnailLoadThread->find(thumbId, thumbnail, qMax(size.width(), size.height())))
0101     {
0102         // digikam returns thumbnails with a border around them,
0103         // but the geolocation interface expects them without a border.
0104 
0105         return thumbnail.copy(1, 1, thumbnail.size().width()-2, thumbnail.size().height()-2);
0106     }
0107     else
0108     {
0109         return QPixmap();
0110     }
0111 }
0112 
0113 QPersistentModelIndex ItemGPSModelHelper::bestRepresentativeIndexFromList(const QList<QPersistentModelIndex>& list,
0114                                                                           const int sortKey)
0115 {
0116     QModelIndex bestIndex       = list.first();
0117     GPSItemInfo bestGPSItemInfo = bestIndex.data(RoleGPSItemInfo).value<GPSItemInfo>();
0118 
0119     for (int i = 1 ; i < list.count() ; ++i)
0120     {
0121         const QModelIndex currentIndex(list.at(i));
0122         const GPSItemInfo currentGPSItemInfo = currentIndex.data(RoleGPSItemInfo).value<GPSItemInfo>();
0123         const bool currentFitsBetter         = GPSItemInfoSorter::fitsBetter(bestGPSItemInfo,
0124                                                                              SelectedNone,
0125                                                                              currentGPSItemInfo,
0126                                                                              SelectedNone,
0127                                                                              SelectedNone,
0128                                                                              GPSItemInfoSorter::SortOptions(sortKey));
0129 
0130         if (currentFitsBetter)
0131         {
0132             bestGPSItemInfo = currentGPSItemInfo;
0133             bestIndex       = currentIndex;
0134         }
0135     }
0136 
0137     return QPersistentModelIndex(bestIndex);
0138 }
0139 
0140 void ItemGPSModelHelper::slotThumbnailLoaded(const LoadingDescription& loadingDescription,
0141                                              const QPixmap& thumb)
0142 {
0143     for (int i = 0 ; i < d->itemModel->rowCount() ; ++i)
0144     {
0145         const QStandardItem* const item      = static_cast<QStandardItem*>(d->itemModel->item(i));
0146         const GPSItemInfo currentGPSItemInfo = item->data(RoleGPSItemInfo).value<GPSItemInfo>();
0147 
0148         if (currentGPSItemInfo.url.toLocalFile() == loadingDescription.filePath)
0149         {
0150             const QPersistentModelIndex goodIndex(d->itemModel->index(i, 0));
0151 
0152             Q_EMIT signalThumbnailAvailableForIndex(goodIndex, thumb);
0153         }
0154     }
0155 }
0156 
0157 } // namespace Digikam
0158 
0159 #include "moc_itemgpsmodelhelper.cpp"