File indexing completed on 2025-01-05 03:56:25

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2006-02-23
0007  * Description : item metadata interface - template helpers.
0008  *
0009  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  * SPDX-FileCopyrightText: 2011      by Leif Huhn <leif at dkstat dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "dmetadata.h"
0018 
0019 // Qt includes
0020 
0021 #include <QLocale>
0022 
0023 // Local includes
0024 
0025 #include "metaenginesettings.h"
0026 #include "template.h"
0027 #include "digikam_version.h"
0028 #include "digikam_globals.h"
0029 #include "digikam_debug.h"
0030 
0031 namespace Digikam
0032 {
0033 
0034 bool DMetadata::setMetadataTemplate(const Template& t) const
0035 {
0036     if (t.isEmpty())
0037     {
0038         return false;
0039     }
0040 
0041     QStringList authors               = t.authors();
0042     QString authorsPosition           = t.authorsPosition();
0043     QString credit                    = t.credit();
0044     QString source                    = t.source();
0045     MetaEngine::AltLangMap copyright  = t.copyright();
0046     MetaEngine::AltLangMap rightUsage = t.rightUsageTerms();
0047     QString instructions              = t.instructions();
0048 
0049     //qCDebug(DIGIKAM_METAENGINE_LOG) << "Applying Metadata Template: " << t.templateTitle() << " :: " << authors;
0050 
0051     // Set XMP tags. XMP<->IPTC Schema from Photoshop 7.0
0052 
0053     if (supportXmp())
0054     {
0055         if (!authors.isEmpty())
0056         {
0057             if (!setXmpTagStringSeq("Xmp.dc.creator", authors))
0058             {
0059                 return false;
0060             }
0061 
0062             if (!setXmpTagStringSeq("Xmp.tiff.Artist", authors))
0063             {
0064                 return false;
0065             }
0066         }
0067 
0068         if (!authorsPosition.isEmpty())
0069         {
0070             if (!setXmpTagString("Xmp.photoshop.AuthorsPosition", authorsPosition))
0071             {
0072                 return false;
0073             }
0074         }
0075 
0076         if (!credit.isEmpty())
0077         {
0078             if (!setXmpTagString("Xmp.photoshop.Credit", credit))
0079             {
0080                 return false;
0081             }
0082         }
0083 
0084         if (!source.isEmpty())
0085         {
0086             if (!setXmpTagString("Xmp.photoshop.Source", source))
0087             {
0088                 return false;
0089             }
0090 
0091             if (!setXmpTagString("Xmp.dc.source", source))
0092             {
0093                 return false;
0094             }
0095         }
0096 
0097         if (!copyright.isEmpty())
0098         {
0099             if (!setXmpTagStringListLangAlt("Xmp.dc.rights", copyright))
0100             {
0101                 return false;
0102             }
0103 
0104             if (!setXmpTagStringListLangAlt("Xmp.tiff.Copyright", copyright))
0105             {
0106                 return false;
0107             }
0108         }
0109 
0110         if (!rightUsage.isEmpty())
0111         {
0112             if (!setXmpTagStringListLangAlt("Xmp.xmpRights.UsageTerms", rightUsage))
0113             {
0114                 return false;
0115             }
0116         }
0117 
0118         if (!instructions.isEmpty())
0119         {
0120             if (!setXmpTagString("Xmp.photoshop.Instructions", instructions))
0121             {
0122                 return false;
0123             }
0124         }
0125     }
0126 
0127     // Set IPTC tags.
0128 
0129     if (!authors.isEmpty())
0130     {
0131         if (!setIptcTagsStringList("Iptc.Application2.Byline", 32,
0132                                    getIptcTagsStringList("Iptc.Application2.Byline"),
0133                                    authors))
0134         {
0135             return false;
0136         }
0137     }
0138 
0139     if (!authorsPosition.isEmpty())
0140     {
0141         if (!setIptcTag(authorsPosition,        32,  "Authors Title", "Iptc.Application2.BylineTitle"))
0142         {
0143             return false;
0144         }
0145     }
0146 
0147     if (!credit.isEmpty())
0148     {
0149         if (!setIptcTag(credit,                 32,  "Credit",        "Iptc.Application2.Credit"))
0150         {
0151             return false;
0152         }
0153     }
0154 
0155     if (!source.isEmpty())
0156     {
0157         if (!setIptcTag(source,                 32,  "Source",        "Iptc.Application2.Source"))
0158         {
0159             return false;
0160         }
0161     }
0162 
0163     if (!copyright[QLatin1String("x-default")].isEmpty())
0164     {
0165         if (!setIptcTag(copyright[QLatin1String("x-default")], 128, "Copyright",     "Iptc.Application2.Copyright"))
0166         {
0167             return false;
0168         }
0169     }
0170 
0171     if (!instructions.isEmpty())
0172     {
0173         if (!setIptcTag(instructions,           256, "Instructions",  "Iptc.Application2.SpecialInstructions"))
0174         {
0175             return false;
0176         }
0177     }
0178 
0179     if (!setIptcCoreLocation(t.locationInfo()))
0180     {
0181         return false;
0182     }
0183 
0184     if (!setCreatorContactInfo(t.contactInfo()))
0185     {
0186         return false;
0187     }
0188 
0189     if (supportXmp())
0190     {
0191         if (!t.IptcSubjects().isEmpty())
0192         {
0193             if (!setXmpSubjects(t.IptcSubjects()))
0194             {
0195                 return false;
0196             }
0197         }
0198     }
0199 
0200     // Synchronize Iptc subjects tags with Xmp subjects tags.
0201 
0202     if (!t.IptcSubjects().isEmpty())
0203     {
0204         QStringList list = t.IptcSubjects();
0205         QStringList newList;
0206 
0207         Q_FOREACH (QString str, list) // krazy:exclude=foreach
0208         {
0209             if (str.startsWith(QLatin1String("XMP")))
0210             {
0211                 str.replace(0, 3, QLatin1String("IPTC"));
0212             }
0213 
0214             newList.append(str);
0215         }
0216 
0217         if (!setIptcSubjects(getIptcSubjects(), newList))
0218         {
0219             return false;
0220         }
0221     }
0222 
0223     return true;
0224 }
0225 
0226 bool DMetadata::removeMetadataTemplate() const
0227 {
0228     // Remove Rights info.
0229 
0230     removeXmpTag("Xmp.dc.creator");
0231     removeXmpTag("Xmp.tiff.Artist");
0232     removeXmpTag("Xmp.photoshop.AuthorsPosition");
0233     removeXmpTag("Xmp.photoshop.Credit");
0234     removeXmpTag("Xmp.photoshop.Source");
0235     removeXmpTag("Xmp.dc.source");
0236     removeXmpTag("Xmp.dc.rights");
0237     removeXmpTag("Xmp.tiff.Copyright");
0238     removeXmpTag("Xmp.xmpRights.UsageTerms");
0239     removeXmpTag("Xmp.photoshop.Instructions");
0240 
0241     removeIptcTag("Iptc.Application2.Byline");
0242     removeIptcTag("Iptc.Application2.BylineTitle");
0243     removeIptcTag("Iptc.Application2.Credit");
0244     removeIptcTag("Iptc.Application2.Source");
0245     removeIptcTag("Iptc.Application2.Copyright");
0246     removeIptcTag("Iptc.Application2.SpecialInstructions");
0247 
0248     // Remove Location info.
0249 
0250     removeXmpTag("Xmp.photoshop.Country");
0251     removeXmpTag("Xmp.iptc.CountryCode");
0252     removeXmpTag("Xmp.photoshop.City");
0253     removeXmpTag("Xmp.iptc.Location");
0254     removeXmpTag("Xmp.photoshop.State");
0255 
0256     removeIptcTag("Iptc.Application2.CountryName");
0257     removeIptcTag("Iptc.Application2.CountryCode");
0258     removeIptcTag("Iptc.Application2.City");
0259     removeIptcTag("Iptc.Application2.SubLocation");
0260     removeIptcTag("Iptc.Application2.ProvinceState");
0261 
0262     // Remove Contact info.
0263 
0264     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiAdrCity");
0265     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiAdrCtry");
0266     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiAdrExtadr");
0267     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiAdrPcode");
0268     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiAdrRegion");
0269     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiEmailWork");
0270     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiTelWork");
0271     removeXmpTag("Xmp.iptc.CreatorContactInfo/Iptc4xmpCore:CiUrlWork");
0272 
0273     // Remove IPTC Subjects.
0274 
0275     removeXmpTag("Xmp.iptc.SubjectCode");
0276     removeIptcTag("Iptc.Application2.Subject");
0277 
0278     return true;
0279 }
0280 
0281 Template DMetadata::getMetadataTemplate() const
0282 {
0283     Template t;
0284 
0285     getCopyrightInformation(t);
0286 
0287     t.setLocationInfo(getIptcCoreLocation());
0288     t.setIptcSubjects(getIptcCoreSubjects()); // get from XMP or Iptc
0289 
0290     return t;
0291 }
0292 
0293 bool DMetadata::getCopyrightInformation(Template& t) const
0294 {
0295     MetadataFields fields;
0296     fields << MetadataInfo::IptcCoreCopyrightNotice
0297            << MetadataInfo::IptcCoreCreator
0298            << MetadataInfo::IptcCoreProvider
0299            << MetadataInfo::IptcCoreRightsUsageTerms
0300            << MetadataInfo::IptcCoreSource
0301            << MetadataInfo::IptcCoreCreatorJobTitle
0302            << MetadataInfo::IptcCoreInstructions;
0303 
0304     QVariantList metadataInfos      = getMetadataFields(fields);
0305     IptcCoreContactInfo contactInfo = getCreatorContactInfo();
0306 
0307     if (!hasValidField(metadataInfos) && contactInfo.isNull())
0308     {
0309         return false;
0310     }
0311 
0312     t.setCopyright(toAltLangMap(metadataInfos.at(0)));
0313     t.setAuthors(metadataInfos.at(1).toStringList());
0314     t.setCredit(metadataInfos.at(2).toString());
0315     t.setRightUsageTerms(toAltLangMap(metadataInfos.at(3)));
0316     t.setSource(metadataInfos.at(4).toString());
0317     t.setAuthorsPosition(metadataInfos.at(5).toString());
0318     t.setInstructions(metadataInfos.at(6).toString());
0319 
0320     t.setContactInfo(contactInfo);
0321 
0322     return true;
0323 }
0324 
0325 } // namespace Digikam