File indexing completed on 2025-03-09 03:52:55
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-09-19 0007 * Description : Scanning a single item. 0008 * 0009 * SPDX-FileCopyrightText: 2007-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "itemscanner_p.h" 0017 0018 namespace Digikam 0019 { 0020 0021 ItemScanner::ItemScanner(const QFileInfo& info, const ItemScanInfo& scanInfo) 0022 : d(new Private) 0023 { 0024 d->fileInfo = info; 0025 d->scanInfo = scanInfo; 0026 } 0027 0028 ItemScanner::ItemScanner(const QFileInfo& info) 0029 : d(new Private) 0030 { 0031 d->fileInfo = info; 0032 } 0033 0034 ItemScanner::ItemScanner(qlonglong imageid) 0035 : d(new Private) 0036 { 0037 ItemShortInfo shortInfo; 0038 { 0039 CoreDbAccess access; 0040 shortInfo = access.db()->getItemShortInfo(imageid); 0041 d->scanInfo = access.db()->getItemScanInfo(imageid); 0042 } 0043 0044 QString albumRootPath = CollectionManager::instance()->albumRootPath(shortInfo.albumRootID); 0045 d->fileInfo = QFileInfo(CoreDbUrl::fromAlbumAndName(shortInfo.itemName, 0046 shortInfo.album, QUrl::fromLocalFile(albumRootPath), shortInfo.albumRootID).fileUrl().toLocalFile()); 0047 } 0048 0049 ItemScanner::~ItemScanner() 0050 { 0051 qCDebug(DIGIKAM_DATABASE_LOG) << "Finishing took" << d->timer.elapsed() << "ms"; 0052 delete d; 0053 } 0054 0055 void ItemScanner::setCategory(DatabaseItem::Category category) 0056 { 0057 // we don't have the necessary information in this class, but in CollectionScanner 0058 0059 d->scanInfo.category = category; 0060 } 0061 0062 const ItemScanInfo& ItemScanner::itemScanInfo() const 0063 { 0064 return d->scanInfo; 0065 } 0066 0067 bool ItemScanner::lessThanForIdentity(const ItemScanInfo& a, const ItemScanInfo& b) 0068 { 0069 if (a.status != b.status) 0070 { 0071 // First: sort by status 0072 0073 // put UndefinedStatus to back 0074 0075 if (a.status == DatabaseItem::UndefinedStatus) 0076 { 0077 return false; 0078 } 0079 0080 // enum values are in the order we want it 0081 0082 return a.status < b.status; 0083 } 0084 else 0085 { 0086 // Second: sort by modification date, descending 0087 return a.modificationDate > b.modificationDate; 0088 } 0089 } 0090 0091 bool ItemScanner::hasValidField(const QVariantList& list) 0092 { 0093 for (QVariantList::const_iterator it = list.constBegin() ; 0094 it != list.constEnd() ; ++it) 0095 { 0096 if (!(*it).isNull()) 0097 { 0098 return true; 0099 } 0100 } 0101 0102 return false; 0103 } 0104 0105 void ItemScanner::sortByProximity(QList<ItemInfo>& list, const ItemInfo& subject) 0106 { 0107 if (!list.isEmpty() && !subject.isNull()) 0108 { 0109 std::stable_sort(list.begin(), list.end(), LessThanByProximityToSubject(subject)); 0110 } 0111 } 0112 0113 void ItemScanner::loadFromDisk() 0114 { 0115 if (d->loadedFromDisk) 0116 { 0117 return; 0118 } 0119 0120 d->loadedFromDisk = true; 0121 d->metadata->registerMetadataSettings(); 0122 d->hasMetadata = d->metadata->load(d->fileInfo.filePath()); 0123 0124 if (d->scanInfo.category == DatabaseItem::Image) 0125 { 0126 d->hasImage = d->img.loadItemInfo(d->fileInfo.filePath(), false, false, false, false); 0127 } 0128 else 0129 { 0130 d->hasImage = false; 0131 } 0132 0133 MetaEngineSettingsContainer settings = MetaEngineSettings::instance()->settings(); 0134 QDateTime modificationDate = d->fileInfo.lastModified(); 0135 modificationDate.setTimeSpec(Qt::UTC); 0136 0137 if (settings.useXMPSidecar4Reading && 0138 DMetadata::hasSidecar(d->fileInfo.filePath())) 0139 { 0140 QString filePath = DMetadata::sidecarPath(d->fileInfo.filePath()); 0141 QDateTime sidecarDate = QFileInfo(filePath).lastModified(); 0142 sidecarDate.setTimeSpec(Qt::UTC); 0143 0144 if (sidecarDate > modificationDate) 0145 { 0146 modificationDate = sidecarDate; 0147 } 0148 } 0149 0150 d->scanInfo.itemName = d->fileInfo.fileName(); 0151 d->scanInfo.fileSize = d->fileInfo.size(); 0152 d->scanInfo.modificationDate = modificationDate; 0153 0154 // category is set by setCategory 0155 // NOTE: call uniqueHash after loading the image above, else it will fail 0156 0157 d->scanInfo.uniqueHash = uniqueHash(); 0158 0159 // faster than loading twice from disk 0160 0161 if (d->hasMetadata) 0162 { 0163 d->img.setMetadata(d->metadata->data()); 0164 } 0165 } 0166 0167 QString ItemScanner::formatToString(const QString& format) 0168 { 0169 // image ------------------------------------------------------------------- 0170 0171 if (format == QLatin1String("JPG")) 0172 { 0173 return QLatin1String("JPEG"); 0174 } 0175 else if (format == QLatin1String("PNG")) 0176 { 0177 return format; 0178 } 0179 else if (format == QLatin1String("TIFF")) 0180 { 0181 return format; 0182 } 0183 else if (format == QLatin1String("PPM")) 0184 { 0185 return format; 0186 } 0187 else if ((format == QLatin1String("JP2")) || (format == QLatin1String("JP2k")) || (format == QLatin1String("JP2K"))) 0188 { 0189 return QLatin1String("JPEG 2000"); 0190 } 0191 else if (format.startsWith(QLatin1String("RAW-"))) 0192 { 0193 return i18nc("RAW image file (), the parentheses contain the file suffix, like MRW", 0194 "RAW image file (%1)", 0195 format.mid(4)); 0196 } 0197 0198 // video ------------------------------------------------------------------- 0199 0200 else if (format == QLatin1String("MPEG")) 0201 { 0202 return format; 0203 } 0204 else if (format == QLatin1String("AVI")) 0205 { 0206 return format; 0207 } 0208 else if (format == QLatin1String("MOV")) 0209 { 0210 return QLatin1String("Quicktime"); 0211 } 0212 else if (format == QLatin1String("WMF")) 0213 { 0214 return QLatin1String("Windows MetaFile"); 0215 } 0216 else if (format == QLatin1String("WMV")) 0217 { 0218 return QLatin1String("Windows Media Video"); 0219 } 0220 else if (format == QLatin1String("MP4")) 0221 { 0222 return QLatin1String("MPEG-4"); 0223 } 0224 else if (format == QLatin1String("3GP")) 0225 { 0226 return QLatin1String("3GPP"); 0227 } 0228 0229 // audio ------------------------------------------------------------------- 0230 0231 else if (format == QLatin1String("OGG")) 0232 { 0233 return QLatin1String("Ogg"); 0234 } 0235 else if (format == QLatin1String("MP3")) 0236 { 0237 return format; 0238 } 0239 else if (format == QLatin1String("WMA")) 0240 { 0241 return QLatin1String("Windows Media Audio"); 0242 } 0243 else if (format == QLatin1String("WAV")) 0244 { 0245 return QLatin1String("WAVE"); 0246 } 0247 else 0248 { 0249 return format; 0250 } 0251 } 0252 0253 } // namespace Digikam