File indexing completed on 2025-01-19 03:56:58

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2012-04-19
0007  * Description : time adjust settings container.
0008  *
0009  * SPDX-FileCopyrightText: 2012-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 "timeadjustcontainer.h"
0016 
0017 // Qt includes
0018 
0019 #include <QRegularExpression>
0020 
0021 namespace Digikam
0022 {
0023 
0024 TimeAdjustContainer::TimeAdjustContainer()
0025     : customDate    (QDateTime::currentDateTime()),
0026       customTime    (QDateTime::currentDateTime()),
0027       adjustmentTime(QDateTime()),
0028       updIfAvailable(true),
0029       updEXIFModDate(false),
0030       updEXIFOriDate(false),
0031       updEXIFDigDate(false),
0032       updEXIFThmDate(false),
0033       updIPTCDate   (false),
0034       updXMPVideo   (false),
0035       updXMPDate    (false),
0036       updFileModDate(false),
0037       dateSource    (APPDATE),
0038       metadataSource(EXIFIPTCXMP),
0039       fileDateSource(FILELASTMOD),
0040       adjustmentType(COPYVALUE),
0041       adjustmentDays(0)
0042 {
0043 }
0044 
0045 TimeAdjustContainer::~TimeAdjustContainer()
0046 {
0047 }
0048 
0049 bool TimeAdjustContainer::atLeastOneUpdateToProcess() const
0050 {
0051     return (
0052             updFileModDate ||
0053             updEXIFModDate ||
0054             updEXIFOriDate ||
0055             updEXIFDigDate ||
0056             updEXIFThmDate ||
0057             updIPTCDate    ||
0058             updXMPVideo    ||
0059             updXMPDate
0060            );
0061 }
0062 
0063 QDateTime TimeAdjustContainer::calculateAdjustedDate(const QDateTime& originalTime, int index)
0064 {
0065     int sign          = 0;
0066     QDateTime newTime = originalTime;
0067 
0068     int seconds       = adjustmentTime.time().second();
0069     seconds          += 60*adjustmentTime.time().minute();
0070     seconds          += 60*60*adjustmentTime.time().hour();
0071     seconds          += 24*60*60*adjustmentDays;
0072 
0073     switch (adjustmentType)
0074     {
0075         case ADDVALUE:
0076             sign = 1;
0077             break;
0078 
0079         case SUBVALUE:
0080             sign = -1;
0081             break;
0082 
0083         case INTERVAL:
0084         {
0085             newTime = newTime.addSecs(index * seconds);
0086 
0087             return newTime;
0088         }
0089         default: // COPYVALUE
0090             return originalTime;
0091     }
0092 
0093     newTime = newTime.addSecs(sign * seconds);
0094 
0095     return newTime;
0096 }
0097 
0098 QDateTime TimeAdjustContainer::getDateTimeFromString(const QString& dateStr) const
0099 {
0100     if (dateStr.isEmpty())
0101     {
0102         return QDateTime();
0103     }
0104 
0105     QStringList regExpStrings;
0106 
0107     // Do not change the order of the list.
0108 
0109     regExpStrings << QLatin1String("(.*?)([0-9]{4}[-_:\\/]?[0-9]{2}[-_:\\/]?[0-9]{2})"
0110                                    "(.+)?([0-9]{2}[hH][0-9]{2})(.+)?");
0111     regExpStrings << QLatin1String("(.*?)([0-9]{8}[T-_ ][0-9]{6})(.+)?");
0112     regExpStrings << QLatin1String("(.*?)([0-9]{4}[-_:\\/]?[0-9]{2}[-_:\\/]?[0-9]{2})"
0113                                    "(.+)?([0-9]{2}[-_:.]?[0-9]{2}[-_:.]?[0-9]{2}"
0114                                    "[-_:.]?[0-9]{3})(.+)?");
0115     regExpStrings << QLatin1String("(.*?)([0-9]{4}[-_:\\/]?[0-9]{2}[-_:\\/]?[0-9]{2})"
0116                                    "(.+)?([0-9]{2}[-_:.]?[0-9]{2}[-_:.]?[0-9]{2})(.+)?");
0117     regExpStrings << QLatin1String("(.*?)([0-9]{2}[-_:\\/.]?[0-9]{2}[-_:\\/.]?[0-9]{4})"
0118                                    "(.+)?([0-9]{2}[-_:.]?[0-9]{2}[-_:.]?[0-9]{2})(.+)?");
0119     regExpStrings << QLatin1String("(.*?)([0-9]{2}[-_:\\/.]?[0-9]{2}[-_:\\/.]?[0-9]{4})"
0120                                    "(.+)?([0-9]{2}[-_:.]?[0-9]{2})(.+)?");
0121     regExpStrings << QLatin1String("(.*?)([0-9]{2}-[0-9]{2}-[0-9]{2})"
0122                                    "[ -]?([0-9]{2}[0-9]{2})(.+)?");
0123     regExpStrings << QLatin1String("(.*?)([0-9]{4}[-_:\\/]?[0-9]{2}[-_:\\/]?[0-9]{2})(.+)?");
0124     regExpStrings << QLatin1String("(.*?)([0-9]{2}[-_:\\/.]?[0-9]{2}[-_:\\/.]?[0-9]{4})(.+)?");
0125     regExpStrings << QLatin1String("(.*?)([0-9]{2}[0-9]{2}[0-9]{4})([0-9]{3})(.+)?");
0126     regExpStrings << QLatin1String("(.*?)([0-9]{2}_[0-9]{2} [0-9]{2})(.+)?");
0127 
0128     QList <QPair<QString, QString> > formatStrings;
0129     formatStrings << qMakePair(QLatin1String("yyyyMMddhhmm"),      QString());
0130     formatStrings << qMakePair(QLatin1String("yyyyMMddhhmmss"),    QString());
0131     formatStrings << qMakePair(QLatin1String("yyyyMMddhhmmsszzz"), QString());
0132     formatStrings << qMakePair(QLatin1String("yyyyMMddhhmmss"),    QString());
0133     formatStrings << qMakePair(QLatin1String("ddMMyyyyhhmmss"),    QLatin1String("MMddyyyyhhmmss"));
0134     formatStrings << qMakePair(QLatin1String("ddMMyyyyhhmm"),      QLatin1String("MMddyyyyhhmm"));
0135     formatStrings << qMakePair(QLatin1String("ddMMyyhhmm"),        QString());
0136     formatStrings << qMakePair(QLatin1String("yyyyMMdd"),          QString());
0137     formatStrings << qMakePair(QLatin1String("ddMMyyyy"),          QLatin1String("MMddyyyy"));
0138     formatStrings << qMakePair(QLatin1String("ddMMyyyy"),          QLatin1String("MMddyyyy"));
0139     formatStrings << qMakePair(QLatin1String("ddMM yy"),           QString());
0140 
0141     QDateTime dateTime;
0142 
0143     for (int index = 0 ; index < regExpStrings.count() ; ++index)
0144     {
0145         QRegularExpression dateRegExp(QRegularExpression::anchoredPattern(regExpStrings.at(index)));
0146         QRegularExpressionMatch match = dateRegExp.match(dateStr);
0147 
0148         if (match.hasMatch())
0149         {
0150             QString dateString   = match.captured(2);
0151             QString format       = formatStrings.at(index).first;
0152             QString secondFormat = formatStrings.at(index).second;
0153 
0154             if (format.contains(QLatin1String("hhmm")))
0155             {
0156                 dateString.append(match.captured(4));
0157             }
0158 
0159             dateString.remove(QLatin1Char(' '));
0160             dateString.remove(QLatin1Char('-'));
0161             dateString.remove(QLatin1Char('_'));
0162             dateString.remove(QLatin1Char(':'));
0163             dateString.remove(QLatin1Char('.'));
0164             dateString.remove(QLatin1Char('/'));
0165             dateString.remove(QLatin1Char('T'));
0166             dateString.remove(QLatin1Char('h'));
0167             dateString.remove(QLatin1Char('H'));
0168 
0169             dateTime = QDateTime::fromString(dateString, format);
0170             dateTime.setTimeSpec(Qt::UTC);
0171 
0172             if (!dateTime.isValid() && !secondFormat.isEmpty())
0173             {
0174                 format   = secondFormat;
0175                 dateTime = QDateTime::fromString(dateString, format);
0176                 dateTime.setTimeSpec(Qt::UTC);
0177             }
0178 
0179             if (dateTime.isValid() && (format.count(QLatin1Char('y')) == 2))
0180             {
0181                 if (dateTime.date().year() < 1970)
0182                 {
0183                     dateTime.setDate(dateTime.date().addYears(100));
0184                 }
0185             }
0186 
0187             if (!dateTime.isValid()             ||
0188                 (dateTime.date().year() < 1800) ||
0189                 (dateTime.date().year() > 2200))
0190             {
0191                 dateTime = QDateTime();
0192             }
0193             else
0194             {
0195                 break;
0196             }
0197         }
0198     }
0199 
0200     return dateTime;
0201 }
0202 
0203 QMap<QString, bool> TimeAdjustContainer::getDateTimeTagsMap() const
0204 {
0205     QMap<QString, bool> tagsMap;
0206 
0207     tagsMap.insert(QLatin1String("Exif.Image.DateTime"),           updEXIFModDate);
0208     tagsMap.insert(QLatin1String("Exif.Photo.DateTimeOriginal"),   updEXIFOriDate);
0209     tagsMap.insert(QLatin1String("Exif.Photo.DateTimeDigitized"),  updEXIFDigDate);
0210     tagsMap.insert(QLatin1String("Exif.Image.PreviewDateTime"),    updEXIFThmDate);
0211 
0212     tagsMap.insert(QLatin1String("Iptc.Application2.DateCreated"), updIPTCDate);
0213     tagsMap.insert(QLatin1String("Iptc.Application2.TimeCreated"), updIPTCDate);
0214 
0215     tagsMap.insert(QLatin1String("Xmp.exif.DateTimeOriginal"),     updXMPDate);
0216     tagsMap.insert(QLatin1String("Xmp.photoshop.DateCreated"),     updXMPDate);
0217     tagsMap.insert(QLatin1String("Xmp.xmp.MetadataDate"),          updXMPDate);
0218     tagsMap.insert(QLatin1String("Xmp.xmp.CreateDate"),            updXMPDate);
0219     tagsMap.insert(QLatin1String("Xmp.xmp.ModifyDate"),            updXMPDate);
0220     tagsMap.insert(QLatin1String("Xmp.tiff.DateTime"),             updXMPDate);
0221 
0222     tagsMap.insert(QLatin1String("Xmp.video.DateTimeOriginal"),    updXMPVideo);
0223     tagsMap.insert(QLatin1String("Xmp.video.DateTimeDigitized"),   updXMPVideo);
0224     tagsMap.insert(QLatin1String("Xmp.video.ModificationDate"),    updXMPVideo);
0225     tagsMap.insert(QLatin1String("Xmp.video.DateUTC"),             updXMPVideo);
0226 
0227     tagsMap.insert(QLatin1String("Xmp.xmpDM.shotDate"),            updXMPVideo);
0228 
0229     return tagsMap;
0230 }
0231 // -------------------------------------------------------------------
0232 
0233 DeltaTime::DeltaTime()
0234     : deltaNegative(false),
0235       deltaDays    (0),
0236       deltaHours   (0),
0237       deltaMinutes (0),
0238       deltaSeconds (0)
0239 {
0240 }
0241 
0242 DeltaTime::~DeltaTime()
0243 {
0244 }
0245 
0246 bool DeltaTime::isNull() const
0247 {
0248     return (
0249             (deltaDays    == 0) &&
0250             (deltaHours   == 0) &&
0251             (deltaMinutes == 0) &&
0252             (deltaSeconds == 0)
0253            );
0254 }
0255 
0256 } // namespace Digikam