File indexing completed on 2025-01-19 03:50:58
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-03-04 0007 * Description : a tool to adjust date time stamp of images 0008 * 0009 * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "timeadjust.h" 0016 0017 // Qt includes 0018 0019 #include <QLabel> 0020 #include <QWidget> 0021 #include <QFile> 0022 #include <QScopedPointer> 0023 0024 // KDE includes 0025 0026 #include <klocalizedstring.h> 0027 0028 // Local includes 0029 0030 #include "dimg.h" 0031 #include "dmetadata.h" 0032 #include "dlayoutbox.h" 0033 #include "dfileoperations.h" 0034 0035 namespace DigikamBqmTimeAdjustPlugin 0036 { 0037 0038 TimeAdjust::TimeAdjust(QObject* const parent) 0039 : BatchTool(QLatin1String("TimeAdjust"), MetadataTool, parent), 0040 m_taWidget (nullptr), 0041 m_changeSettings(true) 0042 { 0043 setToolTitle(i18n("Time Adjust")); 0044 setToolDescription(i18n("Adjust Date Time Stamp of Image")); 0045 setToolIconName(QLatin1String("appointment-new")); 0046 } 0047 0048 TimeAdjust::~TimeAdjust() 0049 { 0050 } 0051 0052 BatchTool* TimeAdjust::clone(QObject* const parent) const 0053 { 0054 return new TimeAdjust(parent); 0055 } 0056 0057 void TimeAdjust::registerSettingsWidget() 0058 { 0059 DVBox* const vbox = new DVBox; 0060 m_taWidget = new TimeAdjustSettings(vbox); 0061 m_settingsWidget = vbox; 0062 0063 connect(m_taWidget, SIGNAL(signalSettingsChanged()), 0064 this, SLOT(slotSettingsChanged())); 0065 0066 BatchTool::registerSettingsWidget(); 0067 } 0068 0069 BatchToolSettings TimeAdjust::defaultSettings() 0070 { 0071 BatchToolSettings settings; 0072 TimeAdjustContainer prm; 0073 0074 settings.insert(QLatin1String("Custom Date"), prm.customDate); 0075 settings.insert(QLatin1String("Custom Time"), prm.customTime); 0076 0077 settings.insert(QLatin1String("Adjustment Type"), prm.adjustmentType); 0078 settings.insert(QLatin1String("Adjustment Days"), prm.adjustmentDays); 0079 settings.insert(QLatin1String("Adjustment Time"), prm.adjustmentTime); 0080 0081 settings.insert(QLatin1String("Update Only If Available Time"), prm.updIfAvailable); 0082 settings.insert(QLatin1String("Update File Modification Time"), prm.updFileModDate); 0083 settings.insert(QLatin1String("Update EXIF Modification Time"), prm.updEXIFModDate); 0084 settings.insert(QLatin1String("Update EXIF Original Time"), prm.updEXIFOriDate); 0085 settings.insert(QLatin1String("Update EXIF Digitization Time"), prm.updEXIFDigDate); 0086 settings.insert(QLatin1String("Update EXIF Thumbnail Time"), prm.updEXIFThmDate); 0087 settings.insert(QLatin1String("Update IPTC Time"), prm.updIPTCDate); 0088 settings.insert(QLatin1String("Update XMP Video Time"), prm.updXMPVideo); 0089 settings.insert(QLatin1String("Update XMP Creation Time"), prm.updXMPDate); 0090 0091 settings.insert(QLatin1String("Use Timestamp Type"), prm.dateSource); 0092 settings.insert(QLatin1String("Meta Timestamp Type"), prm.metadataSource); 0093 settings.insert(QLatin1String("File Timestamp Type"), prm.fileDateSource); 0094 0095 return settings; 0096 } 0097 0098 void TimeAdjust::slotAssignSettings2Widget() 0099 { 0100 m_changeSettings = false; 0101 0102 TimeAdjustContainer prm; 0103 0104 prm.customDate = settings()[QLatin1String("Custom Date")].toDateTime(); 0105 prm.customTime = settings()[QLatin1String("Custom Time")].toDateTime(); 0106 0107 prm.adjustmentType = settings()[QLatin1String("Adjustment Type")].toInt(); 0108 prm.adjustmentDays = settings()[QLatin1String("Adjustment Days")].toInt(); 0109 prm.adjustmentTime = settings()[QLatin1String("Adjustment Time")].toDateTime(); 0110 0111 prm.updIfAvailable = settings()[QLatin1String("Update Only If Available Time")].toBool(); 0112 prm.updFileModDate = settings()[QLatin1String("Update File Modification Time")].toBool(); 0113 prm.updEXIFModDate = settings()[QLatin1String("Update EXIF Modification Time")].toBool(); 0114 prm.updEXIFOriDate = settings()[QLatin1String("Update EXIF Original Time")].toBool(); 0115 prm.updEXIFDigDate = settings()[QLatin1String("Update EXIF Digitization Time")].toBool(); 0116 prm.updEXIFThmDate = settings()[QLatin1String("Update EXIF Thumbnail Time")].toBool(); 0117 prm.updIPTCDate = settings()[QLatin1String("Update IPTC Time")].toBool(); 0118 prm.updXMPVideo = settings()[QLatin1String("Update XMP Video Time")].toBool(); 0119 prm.updXMPDate = settings()[QLatin1String("Update XMP Creation Time")].toBool(); 0120 0121 prm.dateSource = settings()[QLatin1String("Use Timestamp Type")].toInt(); 0122 prm.metadataSource = settings()[QLatin1String("Meta Timestamp Type")].toInt(); 0123 prm.fileDateSource = settings()[QLatin1String("File Timestamp Type")].toInt(); 0124 0125 m_taWidget->setSettings(prm); 0126 0127 m_changeSettings = true; 0128 } 0129 0130 void TimeAdjust::slotSettingsChanged() 0131 { 0132 if (m_changeSettings) 0133 { 0134 TimeAdjustContainer prm = m_taWidget->settings(); 0135 BatchToolSettings settings; 0136 0137 settings.insert(QLatin1String("Custom Date"), prm.customDate); 0138 settings.insert(QLatin1String("Custom Time"), prm.customTime); 0139 0140 settings.insert(QLatin1String("Adjustment Type"), prm.adjustmentType); 0141 settings.insert(QLatin1String("Adjustment Days"), prm.adjustmentDays); 0142 settings.insert(QLatin1String("Adjustment Time"), prm.adjustmentTime); 0143 0144 settings.insert(QLatin1String("Update Only If Available Time"), prm.updIfAvailable); 0145 settings.insert(QLatin1String("Update File Modification Time"), prm.updFileModDate); 0146 settings.insert(QLatin1String("Update EXIF Modification Time"), prm.updEXIFModDate); 0147 settings.insert(QLatin1String("Update EXIF Original Time"), prm.updEXIFOriDate); 0148 settings.insert(QLatin1String("Update EXIF Digitization Time"), prm.updEXIFDigDate); 0149 settings.insert(QLatin1String("Update EXIF Thumbnail Time"), prm.updEXIFThmDate); 0150 settings.insert(QLatin1String("Update IPTC Time"), prm.updIPTCDate); 0151 settings.insert(QLatin1String("Update XMP Video Time"), prm.updXMPVideo); 0152 settings.insert(QLatin1String("Update XMP Creation Time"), prm.updXMPDate); 0153 0154 settings.insert(QLatin1String("Use Timestamp Type"), prm.dateSource); 0155 settings.insert(QLatin1String("Meta Timestamp Type"), prm.metadataSource); 0156 settings.insert(QLatin1String("File Timestamp Type"), prm.fileDateSource); 0157 0158 BatchTool::slotSettingsChanged(settings); 0159 } 0160 } 0161 0162 bool TimeAdjust::toolOperations() 0163 { 0164 bool metaLoadState = true; 0165 QScopedPointer<DMetadata> meta(new DMetadata); 0166 0167 if (image().isNull()) 0168 { 0169 metaLoadState = meta->load(inputUrl().toLocalFile()); 0170 } 0171 else 0172 { 0173 meta->setData(image().getMetadata()); 0174 } 0175 0176 TimeAdjustContainer prm; 0177 0178 bool metadataChanged = false; 0179 0180 prm.customDate = settings()[QLatin1String("Custom Date")].toDateTime(); 0181 prm.customTime = settings()[QLatin1String("Custom Time")].toDateTime(); 0182 0183 prm.adjustmentType = settings()[QLatin1String("Adjustment Type")].toInt(); 0184 prm.adjustmentDays = settings()[QLatin1String("Adjustment Days")].toInt(); 0185 prm.adjustmentTime = settings()[QLatin1String("Adjustment Time")].toDateTime(); 0186 0187 prm.updIfAvailable = settings()[QLatin1String("Update Only If Available Time")].toBool(); 0188 prm.updFileModDate = settings()[QLatin1String("Update File Modification Time")].toBool(); 0189 prm.updEXIFModDate = settings()[QLatin1String("Update EXIF Modification Time")].toBool(); 0190 prm.updEXIFOriDate = settings()[QLatin1String("Update EXIF Original Time")].toBool(); 0191 prm.updEXIFDigDate = settings()[QLatin1String("Update EXIF Digitization Time")].toBool(); 0192 prm.updEXIFThmDate = settings()[QLatin1String("Update EXIF Thumbnail Time")].toBool(); 0193 prm.updIPTCDate = settings()[QLatin1String("Update IPTC Time")].toBool(); 0194 prm.updXMPVideo = settings()[QLatin1String("Update XMP Video Time")].toBool(); 0195 prm.updXMPDate = settings()[QLatin1String("Update XMP Creation Time")].toBool(); 0196 0197 prm.dateSource = settings()[QLatin1String("Use Timestamp Type")].toInt(); 0198 prm.metadataSource = settings()[QLatin1String("Meta Timestamp Type")].toInt(); 0199 prm.fileDateSource = settings()[QLatin1String("File Timestamp Type")].toInt(); 0200 0201 QString exifDateTimeFormat = QLatin1String("yyyy:MM:dd hh:mm:ss"); 0202 QString xmpDateTimeFormat = QLatin1String("yyyy-MM-ddThh:mm:ss"); 0203 0204 const QMap<QString, bool>& tagsMap = prm.getDateTimeTagsMap(); 0205 QMap<QString, bool>::const_iterator it; 0206 0207 QDateTime orgDateTime; 0208 0209 switch (prm.dateSource) 0210 { 0211 case TimeAdjustContainer::METADATADATE: 0212 { 0213 switch (prm.metadataSource) 0214 { 0215 case TimeAdjustContainer::EXIFIPTCXMP: 0216 { 0217 orgDateTime = meta->getItemDateTime(); 0218 break; 0219 } 0220 0221 case TimeAdjustContainer::EXIFCREATED: 0222 { 0223 orgDateTime = QDateTime::fromString(meta->getExifTagString("Exif.Image.DateTime"), 0224 exifDateTimeFormat); 0225 break; 0226 } 0227 0228 case TimeAdjustContainer::EXIFORIGINAL: 0229 { 0230 orgDateTime = QDateTime::fromString(meta->getExifTagString("Exif.Photo.DateTimeOriginal"), 0231 exifDateTimeFormat); 0232 break; 0233 } 0234 0235 case TimeAdjustContainer::EXIFDIGITIZED: 0236 { 0237 orgDateTime = QDateTime::fromString(meta->getExifTagString("Exif.Photo.DateTimeDigitized"), 0238 exifDateTimeFormat); 0239 break; 0240 } 0241 0242 case TimeAdjustContainer::IPTCCREATED: 0243 { 0244 orgDateTime = QDateTime(QDate::fromString(meta->getIptcTagString("Iptc.Application2.DateCreated"), 0245 Qt::ISODate), 0246 QTime::fromString(meta->getIptcTagString("Iptc.Application2.TimeCreated"), 0247 Qt::ISODate)); 0248 break; 0249 } 0250 0251 case TimeAdjustContainer::XMPCREATED: 0252 { 0253 orgDateTime = QDateTime::fromString(meta->getXmpTagString("Xmp.xmp.CreateDate"), 0254 xmpDateTimeFormat); 0255 break; 0256 } 0257 0258 case TimeAdjustContainer::FUZZYCREATED: 0259 { 0260 orgDateTime = prm.getDateTimeFromString(meta->getExifTagString("Exif.Image.DateTime")); 0261 break; 0262 } 0263 0264 case TimeAdjustContainer::FUZZYORIGINAL: 0265 { 0266 orgDateTime = prm.getDateTimeFromString(meta->getExifTagString("Exif.Photo.DateTimeOriginal")); 0267 break; 0268 } 0269 0270 case TimeAdjustContainer::FUZZYDIGITIZED: 0271 { 0272 orgDateTime = prm.getDateTimeFromString(meta->getExifTagString("Exif.Photo.DateTimeDigitized")); 0273 break; 0274 } 0275 0276 default: 0277 { 0278 // orgDateTime stays invalid 0279 break; 0280 } 0281 }; 0282 0283 break; 0284 } 0285 0286 case TimeAdjustContainer::CUSTOMDATE: 0287 { 0288 orgDateTime = QDateTime(prm.customDate.date(), prm.customTime.time()); 0289 break; 0290 } 0291 0292 case TimeAdjustContainer::FILENAME: 0293 { 0294 orgDateTime = prm.getDateTimeFromString(inputUrl().fileName()); 0295 break; 0296 } 0297 0298 case TimeAdjustContainer::FILEDATE: 0299 { 0300 orgDateTime = imageInfo().modDateTime(); 0301 break; 0302 } 0303 0304 default: // TimeAdjustContainer::APPDATE 0305 { 0306 orgDateTime = imageInfo().dateTime(); 0307 break; 0308 } 0309 } 0310 0311 if (!metaLoadState && (prm.dateSource != TimeAdjustContainer::CUSTOMDATE)) 0312 { 0313 orgDateTime = imageInfo().modDateTime(); 0314 } 0315 0316 QDateTime dt = prm.calculateAdjustedDate(orgDateTime); 0317 0318 if (!dt.isValid()) 0319 { 0320 return false; 0321 } 0322 0323 if (metaLoadState) 0324 { 0325 for (it = tagsMap.constBegin() ; it != tagsMap.constEnd() ; ++it) 0326 { 0327 if (!it.value()) 0328 { 0329 continue; 0330 } 0331 0332 if (it.key().startsWith(QLatin1String("Exif."))) 0333 { 0334 if (!prm.updIfAvailable || 0335 !meta->getExifTagString(it.key().toLatin1().constData()).isEmpty()) 0336 { 0337 meta->setExifTagString(it.key().toLatin1().constData(), 0338 dt.toString(exifDateTimeFormat)); 0339 0340 metadataChanged = true; 0341 } 0342 } 0343 else if (it.key().startsWith(QLatin1String("Iptc."))) 0344 { 0345 if (!prm.updIfAvailable || 0346 !meta->getIptcTagString(it.key().toLatin1().constData()).isEmpty()) 0347 { 0348 if (it.key().contains(QLatin1String("Date"))) 0349 { 0350 meta->setIptcTagString(it.key().toLatin1().constData(), 0351 dt.date().toString(Qt::ISODate)); 0352 0353 metadataChanged = true; 0354 } 0355 else if (it.key().contains(QLatin1String("Time"))) 0356 { 0357 meta->setIptcTagString(it.key().toLatin1().constData(), 0358 dt.time().toString(Qt::ISODate)); 0359 0360 metadataChanged = true; 0361 } 0362 } 0363 } 0364 else if (it.key().startsWith(QLatin1String("Xmp.")) && meta->supportXmp()) 0365 { 0366 if (!prm.updIfAvailable || 0367 !meta->getXmpTagString(it.key().toLatin1().constData()).isEmpty()) 0368 { 0369 meta->setXmpTagString(it.key().toLatin1().constData(), 0370 dt.toString(xmpDateTimeFormat)); 0371 0372 metadataChanged = true; 0373 } 0374 } 0375 } 0376 } 0377 0378 bool ret = true; 0379 0380 if (image().isNull()) 0381 { 0382 QFile::remove(outputUrl().toLocalFile()); 0383 ret = DFileOperations::copyFile(inputUrl().toLocalFile(), outputUrl().toLocalFile()); 0384 0385 if (ret && metadataChanged && metaLoadState) 0386 { 0387 ret = meta->save(outputUrl().toLocalFile()); 0388 } 0389 } 0390 else 0391 { 0392 if (metadataChanged) 0393 { 0394 image().setMetadata(meta->data()); 0395 } 0396 0397 ret = savefromDImg(); 0398 } 0399 0400 if (ret && prm.updFileModDate) 0401 { 0402 ret = DFileOperations::setModificationTime(outputUrl().toLocalFile(), dt); 0403 } 0404 0405 return ret; 0406 } 0407 0408 } // namespace DigikamBqmTimeAdjustPlugin 0409 0410 #include "moc_timeadjust.cpp"