File indexing completed on 2025-01-19 03:55:35
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2017-05-06 0007 * Description : interface to item information for shared tools 0008 * based on DMetadata. This interface is used in all cases 0009 * where no database is available (aka Showfoto). 0010 * 0011 * SPDX-FileCopyrightText: 2017-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0012 * SPDX-FileCopyrightText: 2019-2020 by Minh Nghia Duong <minhnghiaduong997 at gmail dot com> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "dmetainfoiface.h" 0019 0020 // Qt includes 0021 0022 #include <QFileInfo> 0023 #include <QStandardPaths> 0024 #include <QScopedPointer> 0025 0026 // KDE includes 0027 0028 #include <klocalizedstring.h> 0029 0030 // Local includes 0031 0032 #include "dmetadata.h" 0033 #include "photoinfocontainer.h" 0034 #include "videoinfocontainer.h" 0035 #include "template.h" 0036 #include "dfileselector.h" 0037 #include "digikam_debug.h" 0038 0039 namespace Digikam 0040 { 0041 0042 class Q_DECL_HIDDEN DMetaInfoIface::Private 0043 { 0044 public: 0045 0046 explicit Private() 0047 : dirSelector(nullptr) 0048 { 0049 } 0050 0051 DFileSelector* dirSelector; 0052 QList<QUrl> urls; 0053 }; 0054 0055 DMetaInfoIface::DMetaInfoIface(QObject* const parent, const QList<QUrl>& lst) 0056 : DInfoInterface(parent), 0057 d (new Private) 0058 { 0059 d->urls = lst; 0060 } 0061 0062 DMetaInfoIface::~DMetaInfoIface() 0063 { 0064 delete d; 0065 } 0066 0067 void DMetaInfoIface::slotDateTimeForUrl(const QUrl& url, const QDateTime& /*dt*/, bool /*updModDate*/) 0068 { 0069 Q_EMIT signalItemChanged(url); 0070 } 0071 0072 void DMetaInfoIface::slotMetadataChangedForUrl(const QUrl& url) 0073 { 0074 Q_EMIT signalItemChanged(url); 0075 } 0076 0077 void DMetaInfoIface::parseAlbumItemsRecursive() 0078 { 0079 Q_EMIT signalAlbumItemsRecursiveCompleted(d->urls); 0080 } 0081 0082 QList<QUrl> DMetaInfoIface::currentAlbumItems() const 0083 { 0084 return d->urls; 0085 } 0086 0087 QList<QUrl> DMetaInfoIface::currentSelectedItems() const 0088 { 0089 // No multiple items selection is available in this interface. 0090 0091 return currentAlbumItems(); 0092 } 0093 0094 QList<QUrl> DMetaInfoIface::allAlbumItems() const 0095 { 0096 // No album management is available in this interface. 0097 0098 return currentAlbumItems(); 0099 } 0100 0101 DMetaInfoIface::DInfoMap DMetaInfoIface::itemInfo(const QUrl& url) const 0102 { 0103 DInfoMap map; 0104 0105 if (d->urls.contains(url)) 0106 { 0107 QScopedPointer<DMetadata> meta(new DMetadata(url.toLocalFile())); 0108 QString def = QLatin1String("x-default"); 0109 QFileInfo info(url.toLocalFile()); 0110 0111 map.insert(QLatin1String("name"), info.fileName()); 0112 map.insert(QLatin1String("title"), meta->getItemTitles()[def].caption); 0113 map.insert(QLatin1String("comment"), meta->getItemComments()[def].caption); 0114 map.insert(QLatin1String("orientation"), (int)meta->getItemOrientation()); 0115 map.insert(QLatin1String("datetime"), meta->getItemDateTime()); 0116 map.insert(QLatin1String("rating"), meta->getItemRating()); 0117 map.insert(QLatin1String("colorlabel"), meta->getItemColorLabel()); 0118 map.insert(QLatin1String("picklabel"), meta->getItemPickLabel()); 0119 map.insert(QLatin1String("filesize"), (qlonglong)info.size()); 0120 map.insert(QLatin1String("dimensions"), meta->getItemDimensions()); 0121 0122 // Get digiKam Tags Path list of picture from metadata. 0123 // Ex.: "City/Paris/Monuments/Notre Dame" 0124 0125 QStringList tagsPath; 0126 meta->getItemTagsPath(tagsPath); 0127 map.insert(QLatin1String("tagspath"), tagsPath); 0128 0129 // Get digiKam Tags name (keywords) list of picture from metadata. 0130 // Ex.: "Notre Dame" 0131 0132 QStringList keywords = meta->getMetadataField(MetadataInfo::Keywords).toStringList(); 0133 map.insert(QLatin1String("keywords"), keywords); 0134 0135 // Get GPS location of picture from metadata. 0136 0137 double lat = 0.0; 0138 double lng = 0.0; 0139 double alt = 0.0; 0140 0141 if (meta->getGPSInfo(lat, lng, alt)) 0142 { 0143 map.insert(QLatin1String("latitude"), lat); 0144 map.insert(QLatin1String("longitude"), lng); 0145 map.insert(QLatin1String("altitude"), alt); 0146 } 0147 0148 // Get Copyright information of picture from metadata. 0149 0150 Template temp; 0151 meta->getCopyrightInformation(temp); 0152 0153 map.insert(QLatin1String("creators"), temp.authors()); 0154 map.insert(QLatin1String("credit"), temp.credit()); 0155 map.insert(QLatin1String("rights"), temp.copyright().value(def)); 0156 map.insert(QLatin1String("source"), temp.source()); 0157 0158 PhotoInfoContainer photoInfo = meta->getPhotographInformation(); 0159 map.insert(QLatin1String("lens"), photoInfo.lens); 0160 map.insert(QLatin1String("make"), photoInfo.make); 0161 map.insert(QLatin1String("model"), photoInfo.model); 0162 map.insert(QLatin1String("exposuretime"), photoInfo.exposureTime); 0163 map.insert(QLatin1String("sensitivity"), photoInfo.sensitivity); 0164 map.insert(QLatin1String("aperture"), photoInfo.aperture); 0165 map.insert(QLatin1String("focallength"), photoInfo.focalLength); 0166 map.insert(QLatin1String("focalLength35mm"), photoInfo.focalLength35mm); 0167 0168 // Get Video information from metadata 0169 0170 VideoInfoContainer videoInfo = meta->getVideoInformation(); 0171 map.insert(QLatin1String("videocodec"), videoInfo.videoCodec); 0172 0173 // TODO: add more video metadata as needed 0174 0175 // Get complex text containers. 0176 0177 CaptionsMap titles = meta->getItemTitles(); 0178 map.insert(QLatin1String("titles"), QVariant::fromValue(titles)); 0179 CaptionsMap captions = meta->getItemComments(); 0180 map.insert(QLatin1String("captions"), QVariant::fromValue(captions)); 0181 0182 Template tpl = meta->getMetadataTemplate(); 0183 DMetadata::AltLangMap copyrights = tpl.copyright(); 0184 map.insert(QLatin1String("copyrights"), QVariant::fromValue(copyrights)); 0185 DMetadata::AltLangMap notices = tpl.rightUsageTerms(); 0186 map.insert(QLatin1String("copyrightnotices"), QVariant::fromValue(notices)); 0187 } 0188 0189 return map; 0190 } 0191 0192 void DMetaInfoIface::setItemInfo(const QUrl& url, const DInfoMap& map) 0193 { 0194 QScopedPointer<DMetadata> meta(new DMetadata(url.toLocalFile())); 0195 QStringList keys = map.keys(); 0196 0197 if (map.contains(QLatin1String("orientation"))) 0198 { 0199 meta->setItemOrientation((DMetadata::ImageOrientation)map[QLatin1String("orientation")].toInt()); 0200 keys.removeAll(QLatin1String("orientation")); 0201 } 0202 0203 if (map.contains(QLatin1String("rating"))) 0204 { 0205 meta->setItemRating(map[QLatin1String("rating")].toInt()); 0206 keys.removeAll(QLatin1String("rating")); 0207 } 0208 0209 if (map.contains(QLatin1String("colorlabel"))) 0210 { 0211 meta->setItemColorLabel(map[QLatin1String("colorlabel")].toInt()); 0212 keys.removeAll(QLatin1String("colorlabel")); 0213 } 0214 0215 if (map.contains(QLatin1String("picklabel"))) 0216 { 0217 meta->setItemPickLabel(map[QLatin1String("picklabel")].toInt()); 0218 keys.removeAll(QLatin1String("picklabel")); 0219 } 0220 0221 if (map.contains(QLatin1String("titles"))) 0222 { 0223 meta->setItemTitles(qvariant_cast<CaptionsMap>(map[QLatin1String("titles")])); 0224 keys.removeAll(QLatin1String("titles")); 0225 } 0226 0227 if (map.contains(QLatin1String("captions"))) 0228 { 0229 meta->setItemComments(qvariant_cast<CaptionsMap>(map[QLatin1String("captions")])); 0230 keys.removeAll(QLatin1String("captions")); 0231 } 0232 0233 if (map.contains(QLatin1String("copyrights"))) 0234 { 0235 Template tpl = meta->getMetadataTemplate(); 0236 tpl.setCopyright(qvariant_cast<DMetadata::AltLangMap>(map[QLatin1String("copyrights")])); 0237 meta->setMetadataTemplate(tpl); 0238 keys.removeAll(QLatin1String("copyrights")); 0239 } 0240 0241 if (map.contains(QLatin1String("copyrightnotices"))) 0242 { 0243 Template tpl = meta->getMetadataTemplate(); 0244 tpl.setRightUsageTerms(qvariant_cast<DMetadata::AltLangMap>(map[QLatin1String("copyrightnotices")])); 0245 meta->setMetadataTemplate(tpl); 0246 keys.removeAll(QLatin1String("copyrightnotices")); 0247 } 0248 0249 if (!keys.isEmpty()) 0250 { 0251 qCWarning(DIGIKAM_GENERAL_LOG) << "Keys not yet supported in DMetaInfoIface::setItemInfo():" << keys; 0252 } 0253 0254 Q_EMIT signalItemChanged(url); 0255 } 0256 0257 bool DMetaInfoIface::supportAlbums() const 0258 { 0259 return false; 0260 } 0261 0262 QWidget* DMetaInfoIface::uploadWidget(QWidget* const parent) const 0263 { 0264 if (!d->dirSelector) 0265 { 0266 d->dirSelector = new DFileSelector(parent); 0267 d->dirSelector->setFileDlgMode(QFileDialog::Directory); 0268 d->dirSelector->setFileDlgOptions(QFileDialog::ShowDirsOnly); 0269 d->dirSelector->setFileDlgTitle(i18nc("@title:window", "Destination Folder")); 0270 d->dirSelector->lineEdit()->setPlaceholderText(i18n("Output Destination Path")); 0271 0272 connect(d->dirSelector, SIGNAL(signalUrlSelected(QUrl)), 0273 this, SIGNAL(signalUploadUrlChanged())); 0274 } 0275 0276 QFileInfo info(!d->urls.isEmpty() ? d->urls[0].toLocalFile() : QString()); 0277 d->dirSelector->setFileDlgPath(info.absolutePath()); 0278 0279 return d->dirSelector; 0280 } 0281 0282 QUrl DMetaInfoIface::uploadUrl() const 0283 { 0284 return QUrl::fromLocalFile(d->dirSelector->fileDlgPath()); 0285 } 0286 0287 QUrl DMetaInfoIface::defaultUploadUrl() const 0288 { 0289 QUrl place = QUrl::fromLocalFile(QDir::homePath()); 0290 QStringList pics = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); 0291 0292 if (!pics.isEmpty()) 0293 { 0294 place = QUrl::fromLocalFile(pics.first()); 0295 } 0296 0297 QList<QUrl> lst = currentAlbumItems(); 0298 0299 if (!lst.isEmpty()) 0300 { 0301 QUrl trg = lst.first().adjusted(QUrl::RemoveFilename); 0302 0303 if (!trg.isEmpty()) 0304 { 0305 place = trg; 0306 } 0307 } 0308 0309 return place; 0310 } 0311 0312 void DMetaInfoIface::deleteImage(const QUrl& url) 0313 { 0314 0315 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) 0316 0317 QFile::moveToTrash(url.toLocalFile()); 0318 0319 #else 0320 0321 QFile::remove(url.toLocalFile()); 0322 0323 #endif 0324 0325 Q_EMIT signalRemoveImageFromAlbum(url); 0326 } 0327 0328 #ifdef HAVE_GEOLOCATION 0329 0330 QList<GPSItemContainer*> DMetaInfoIface::currentGPSItems() const 0331 { 0332 QList<GPSItemContainer*> items; 0333 0334 Q_FOREACH (const QUrl& url, currentSelectedItems()) 0335 { 0336 items << new GPSItemContainer(url); 0337 } 0338 0339 return items; 0340 } 0341 0342 #endif 0343 0344 } // namespace Digikam 0345 0346 #include "moc_dmetainfoiface.cpp"