File indexing completed on 2025-01-19 03:53:37

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2005-04-21
0007  * Description : Handling access to one item and associated data
0008  *
0009  * SPDX-FileCopyrightText: 2005      by Renchi Raju <renchi dot raju at gmail dot com>
0010  * SPDX-FileCopyrightText: 2007-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  * SPDX-FileCopyrightText: 2013      by Michael G. Hansen <mike at mghansen dot de>
0013  *
0014  * SPDX-License-Identifier: GPL-2.0-or-later
0015  *
0016  * ============================================================ */
0017 
0018 #include "iteminfo_p.h"
0019 
0020 namespace Digikam
0021 {
0022 
0023 ItemInfo::ItemInfo()
0024     : m_data(nullptr)
0025 {
0026 }
0027 
0028 ItemInfo::ItemInfo(const ItemListerRecord& record)
0029 {
0030     // cppcheck-suppress useInitializationList
0031     m_data                         = ItemInfoStatic::cache()->infoForId(record.imageID);
0032 
0033     ItemInfoWriteLocker lock;
0034     bool newlyCreated              = (m_data->albumId == -1);
0035 
0036     m_data->albumId                = record.albumID;
0037     m_data->albumRootId            = record.albumRootID;
0038     m_data->name                   = record.name;
0039 
0040     m_data->rating                 = record.rating;
0041     m_data->category               = record.category;
0042     m_data->format                 = record.format;
0043     m_data->creationDate           = record.creationDate;
0044     m_data->modificationDate       = record.modificationDate;
0045     m_data->fileSize               = record.fileSize;
0046     m_data->imageSize              = record.imageSize;
0047     m_data->currentSimilarity      = record.currentSimilarity;
0048     m_data->currentReferenceImage  = record.currentFuzzySearchReferenceImage;
0049 
0050     m_data->ratingCached           = true;
0051     m_data->categoryCached         = true;
0052     m_data->formatCached           = true;
0053     m_data->creationDateCached     = true;
0054     m_data->modificationDateCached = true;
0055     m_data->fileSizeCached         = true;
0056     m_data->imageSizeCached        = true;
0057     m_data->videoMetadataCached    = DatabaseFields::VideoMetadataNone;
0058     m_data->imageMetadataCached    = DatabaseFields::ImageMetadataNone;
0059     m_data->hasVideoMetadata       = true;
0060     m_data->hasImageMetadata       = true;
0061     m_data->databaseFieldsHashRaw.clear();
0062 
0063     if (newlyCreated)
0064     {
0065         ItemInfoStatic::cache()->cacheByName(m_data);
0066     }
0067 }
0068 
0069 ItemInfo::ItemInfo(qlonglong ID)
0070 {
0071     // cppcheck-suppress useInitializationList
0072     m_data = ItemInfoStatic::cache()->infoForId(ID);
0073 
0074     // is this a newly created structure, need to populate?
0075 
0076     if (m_data->albumId == -1)
0077     {
0078         // retrieve immutable values now, the rest on demand
0079 
0080         ItemShortInfo info = CoreDbAccess().db()->getItemShortInfo(ID);
0081 
0082         if (info.id)
0083         {
0084             ItemInfoWriteLocker lock;
0085             m_data->albumId     = info.albumID;
0086             m_data->albumRootId = info.albumRootID;
0087             m_data->name        = info.itemName;
0088             ItemInfoStatic::cache()->cacheByName(m_data);
0089         }
0090         else
0091         {
0092             // invalid image id
0093 
0094             ItemInfoStatic::cache()->dropInfo(m_data);
0095         }
0096     }
0097 }
0098 
0099 ItemInfo::~ItemInfo()
0100 {
0101     ItemInfoStatic::cache()->dropInfo(m_data);
0102 }
0103 
0104 ItemInfo::ItemInfo(const ItemInfo& info)
0105     : m_data(info.m_data)
0106 {
0107 }
0108 
0109 ItemInfo& ItemInfo::operator=(const ItemInfo& info)
0110 {
0111     if (m_data == info.m_data)
0112     {
0113         return *this;
0114     }
0115 
0116     ItemInfoStatic::cache()->dropInfo(m_data);
0117     m_data = info.m_data;
0118 
0119     return *this;
0120 }
0121 
0122 bool ItemInfo::operator==(const ItemInfo& info) const
0123 {
0124     if (m_data && info.m_data)
0125     {
0126         // not null, compare id
0127         return (m_data->id == info.m_data->id);
0128     }
0129     else
0130     {
0131         // both null?
0132         return (m_data == info.m_data);
0133     }
0134 }
0135 
0136 bool ItemInfo::operator!=(const ItemInfo& info) const
0137 {
0138     return (!operator==(info));
0139 }
0140 
0141 bool ItemInfo::operator<(const ItemInfo& info) const
0142 {
0143     if (m_data)
0144     {
0145         if (info.m_data)
0146         {
0147             // both not null, sort by id
0148             return (m_data->id < info.m_data->id);
0149         }
0150         else
0151         {
0152             // only other is null, this is greater than
0153             return false;
0154         }
0155     }
0156     else
0157     {
0158         // this is less than if the other is not null
0159         return info.m_data;
0160     }
0161 }
0162 
0163 ItemInfo ItemInfo::fromUrl(const QUrl& url)
0164 {
0165     return fromLocalFile(url.toLocalFile());
0166 }
0167 
0168 ItemInfo ItemInfo::fromLocalFile(const QString& path)
0169 {
0170     CollectionLocation location = CollectionManager::instance()->locationForPath(path);
0171 
0172     if (location.isNull())
0173     {
0174         qCWarning(DIGIKAM_DATABASE_LOG) << "No location could be retrieved for" << path;
0175         return ItemInfo();
0176     }
0177 
0178     QUrl url      = QUrl::fromLocalFile(path);
0179     QString album = CollectionManager::instance()->album(url.adjusted(QUrl::RemoveFilename |
0180                                                                       QUrl::StripTrailingSlash).toLocalFile());
0181     QString name  = url.fileName();
0182 
0183     return fromLocationAlbumAndName(location.id(), album, name);
0184 }
0185 
0186 ItemInfo ItemInfo::fromLocationAlbumAndName(int locationId, const QString& album, const QString& name)
0187 {
0188     if (!locationId || album.isEmpty() || name.isEmpty())
0189     {
0190         return ItemInfo();
0191     }
0192 
0193     ItemInfo info;
0194 
0195     // Cached ?
0196     info.m_data = ItemInfoStatic::cache()->infoForPath(locationId, album, name);
0197 
0198     if (!info.m_data)
0199     {
0200 
0201         ItemShortInfo shortInfo  = CoreDbAccess().db()->getItemShortInfo(locationId, album, name);
0202 
0203         if (!shortInfo.id)
0204         {
0205             qCWarning(DIGIKAM_DATABASE_LOG) << "No itemShortInfo could be retrieved from the database for image" << name;
0206 
0207             return info;
0208         }
0209 
0210         info.m_data              = ItemInfoStatic::cache()->infoForId(shortInfo.id);
0211 
0212         ItemInfoWriteLocker lock;
0213         info.m_data->albumId     = shortInfo.albumID;
0214         info.m_data->albumRootId = shortInfo.albumRootID;
0215         info.m_data->name        = shortInfo.itemName;
0216 
0217         ItemInfoStatic::cache()->cacheByName(info.m_data);
0218     }
0219 
0220     return info;
0221 }
0222 
0223 ItemInfo ItemInfo::copyItem(int dstAlbumID, const QString& dstFileName)
0224 {
0225     if (!m_data)
0226     {
0227         return ItemInfo();
0228     }
0229 
0230     {
0231         ItemInfoReadLocker lock;
0232 
0233         if ((dstAlbumID == m_data->albumId) && (dstFileName == m_data->name))
0234         {
0235             return (*this);
0236         }
0237     }
0238 
0239     qlonglong id = CoreDbAccess().db()->copyItem(m_data->albumId, m_data->name, dstAlbumID, dstFileName);
0240 
0241     if (id == -1)
0242     {
0243         return ItemInfo();
0244     }
0245 
0246     return ItemInfo(id);
0247 }
0248 
0249 bool ItemInfo::isLocationAvailable() const
0250 {
0251     if (!m_data)
0252     {
0253         return false;
0254     }
0255 
0256     return CollectionManager::instance()->locationForAlbumRootId(m_data->albumRootId).isAvailable();
0257 }
0258 
0259 QDebug operator<<(QDebug stream, const ItemInfo& info)
0260 {
0261     return stream << "ItemInfo [id = " << info.id() << ", path = "
0262                   << info.filePath() << "]";
0263 }
0264 
0265 } // namespace Digikam