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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2015-08-12
0007  * Description : metadata Settings Container.
0008  *
0009  * SPDX-FileCopyrightText: 2015      by Veaceslav Munteanu <veaceslav dot munteanu90 at gmail dot com>
0010  * SPDX-FileCopyrightText: 2015-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 "dmetadatasettingscontainer.h"
0017 
0018 // KDE includes
0019 
0020 #include <kconfiggroup.h>
0021 #include <klocalizedstring.h>
0022 
0023 // Local includes
0024 
0025 #include "dmetadatasettings.h"
0026 #include "digikam_debug.h"
0027 #include "digikam_globals_p.h"      // For KF6::Ki18n deprecated
0028 
0029 namespace Digikam
0030 {
0031 
0032 static const struct NameSpaceDefinition
0033 {
0034     NamespaceEntry::NamespaceType type;
0035 
0036 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0037 
0038     const KLazyLocalizedString    title;
0039 
0040 #else
0041 
0042     const char*                   context;
0043     const char*                   title;
0044 
0045 #endif
0046 
0047 }
0048 namespaceTitleDefinitions[] =
0049 {
0050     {
0051         NamespaceEntry::TAGS,
0052         I18NC_NOOP("@title: xmp namespace for tags container",        "Tags")
0053     },
0054     {
0055         NamespaceEntry::TITLE,
0056         I18NC_NOOP("@title: xmp namespace for title container",       "Title")
0057     },
0058     {
0059         NamespaceEntry::RATING,
0060         I18NC_NOOP("@title: xmp namespace for rating container",      "Rating")
0061     },
0062     {
0063         NamespaceEntry::COMMENT,
0064         I18NC_NOOP("@title: xmp namespace for comment container",     "Caption")
0065     },
0066     {
0067         NamespaceEntry::PICKLABEL,
0068         I18NC_NOOP("@title: xmp namespace for pick-label container",  "Pick label")
0069     },
0070     {
0071         NamespaceEntry::COLORLABEL,
0072         I18NC_NOOP("@title: xmp namespace for color-label container", "Color label")
0073     },
0074 };
0075 
0076 QString NamespaceEntry::DM_TAG_CONTAINER()
0077 {
0078 
0079 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0080 
0081     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::TAGS].title.untranslatedText());
0082 
0083 #else
0084 
0085     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::TAGS].title);
0086 
0087 #endif
0088 
0089 }
0090 
0091 QString NamespaceEntry::DM_TITLE_CONTAINER()
0092 {
0093 
0094 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0095 
0096     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::TITLE].title.untranslatedText());
0097 
0098 #else
0099 
0100     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::TITLE].title);
0101 
0102 #endif
0103 
0104 }
0105 
0106 QString NamespaceEntry::DM_RATING_CONTAINER()
0107 {
0108 
0109 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0110 
0111     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::RATING].title.untranslatedText());
0112 
0113 #else
0114 
0115     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::RATING].title);
0116 
0117 #endif
0118 
0119 }
0120 
0121 QString NamespaceEntry::DM_COMMENT_CONTAINER()
0122 {
0123 
0124 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0125 
0126     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::COMMENT].title.untranslatedText());
0127 
0128 #else
0129 
0130     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::COMMENT].title);
0131 
0132 #endif
0133 
0134 }
0135 
0136 QString NamespaceEntry::DM_PICKLABEL_CONTAINER()
0137 {
0138 
0139 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0140 
0141     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::PICKLABEL].title.untranslatedText());
0142 
0143 #else
0144 
0145     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::PICKLABEL].title);
0146 
0147 #endif
0148 
0149 }
0150 
0151 QString NamespaceEntry::DM_COLORLABEL_CONTAINER()
0152 {
0153 
0154 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0155 
0156     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::COLORLABEL].title.untranslatedText());
0157 
0158 #else
0159 
0160     return QString::fromUtf8(namespaceTitleDefinitions[NamespaceEntry::COLORLABEL].title);
0161 
0162 #endif
0163 
0164 }
0165 
0166 // ------------------------------------------------------------
0167 
0168 bool s_dmcompare(const NamespaceEntry& e1, const NamespaceEntry& e2)
0169 {
0170     return (e1.index < e2.index);
0171 }
0172 
0173 QDebug operator<<(QDebug dbg, const NamespaceEntry& inf)
0174 {
0175     dbg.nospace() << "[NamespaceEntry] nsType("
0176                   << inf.nsType << "), ";
0177     dbg.nospace() << "subspace("
0178                   << inf.subspace << "), ";
0179     dbg.nospace() << "isDefault("
0180                   << inf.isDefault << "), ";
0181     dbg.nospace() << "isDisabled("
0182                   << inf.isDisabled << "), ";
0183     dbg.nospace() << "index("
0184                   << inf.index << "), ";
0185     dbg.nospace() << "namespaceName("
0186                   << inf.namespaceName << "), ";
0187     dbg.nospace() << "alternativeName("
0188                   << inf.alternativeName << "), ";
0189     dbg.nospace() << "tagPaths("
0190                   << inf.tagPaths << "), ";
0191     dbg.nospace() << "separator("
0192                   << inf.separator << "), ";
0193     dbg.nospace() << "convertRatio("
0194                   << inf.convertRatio << "), ";
0195     dbg.nospace() << "specialOpts("
0196                   << inf.specialOpts << "), ";
0197     dbg.nospace() << "secondNameOpts("
0198                   << inf.secondNameOpts << ")";
0199 
0200     return dbg.space();
0201 }
0202 
0203 // -------------------------------------------------------------------------------------------------
0204 
0205 class Q_DECL_HIDDEN DMetadataSettingsContainer::Private
0206 {
0207 public:
0208 
0209     explicit Private()
0210       : unifyReadWrite(false),
0211         readingAllTags(false)
0212     {
0213     }
0214 
0215 public:
0216 
0217     QMap<QString, QList<NamespaceEntry> > readMappings;
0218     QMap<QString, QList<NamespaceEntry> > writeMappings;
0219     bool                                  unifyReadWrite;
0220     bool                                  readingAllTags;
0221 };
0222 
0223 // -------------------------------------------------------------------------------------------------
0224 
0225 DMetadataSettingsContainer::DMetadataSettingsContainer()
0226     : d(new Private)
0227 {
0228     addMapping(NamespaceEntry::DM_TAG_CONTAINER());
0229     addMapping(NamespaceEntry::DM_TITLE_CONTAINER());
0230     addMapping(NamespaceEntry::DM_RATING_CONTAINER());
0231     addMapping(NamespaceEntry::DM_COMMENT_CONTAINER());
0232     addMapping(NamespaceEntry::DM_COLORLABEL_CONTAINER());
0233 }
0234 
0235 DMetadataSettingsContainer::DMetadataSettingsContainer(const DMetadataSettingsContainer& other)
0236     : d(new Private)
0237 {
0238     *d = *other.d;
0239 }
0240 
0241 DMetadataSettingsContainer& DMetadataSettingsContainer::operator=(const DMetadataSettingsContainer& other)
0242 {
0243     *d = *other.d;
0244 
0245     return *this;
0246 }
0247 
0248 DMetadataSettingsContainer::~DMetadataSettingsContainer()
0249 {
0250     delete d;
0251 }
0252 
0253 bool DMetadataSettingsContainer::unifyReadWrite() const
0254 {
0255     return d->unifyReadWrite;
0256 }
0257 
0258 void DMetadataSettingsContainer::setUnifyReadWrite(bool b)
0259 {
0260     d->unifyReadWrite = b;
0261 }
0262 
0263 bool DMetadataSettingsContainer::readingAllTags() const
0264 {
0265     return d->readingAllTags;
0266 }
0267 
0268 void DMetadataSettingsContainer::setReadingAllTags(bool b)
0269 {
0270     d->readingAllTags = b;
0271 }
0272 
0273 void DMetadataSettingsContainer::readFromConfig(KConfigGroup& group)
0274 {
0275     bool valid                   = true;
0276     const QString readNameSpace  = QLatin1String("read%1Namespaces");
0277     const QString writeNameSpace = QLatin1String("write%1Namespaces");
0278 
0279     Q_FOREACH (const QString& str, mappingKeys())
0280     {
0281         if (!group.hasGroup(readNameSpace.arg(str)))
0282         {
0283             valid = false;
0284             qCDebug(DIGIKAM_GENERAL_LOG) << "Does not contain " << str << " Namespace";
0285             break;
0286         }
0287 
0288         if (!group.hasGroup(writeNameSpace.arg(str)))
0289         {
0290             valid = false;
0291             qCDebug(DIGIKAM_GENERAL_LOG) << "Does not contain " << str << " Namespace";
0292             break;
0293         }
0294     }
0295 
0296     if (valid)
0297     {
0298         Q_FOREACH (const QString& str, mappingKeys())
0299         {
0300             readOneGroup(group, readNameSpace.arg(str), getReadMapping(str));
0301             readOneGroup(group, writeNameSpace.arg(str), getWriteMapping(str));
0302         }
0303     }
0304     else
0305     {
0306         defaultValues();
0307     }
0308 
0309     d->unifyReadWrite = group.readEntry(QLatin1String("unifyReadWrite"), true);
0310     d->readingAllTags = group.readEntry(QLatin1String("readingAllTags"), false);
0311 }
0312 
0313 void DMetadataSettingsContainer::writeToConfig(KConfigGroup& group) const
0314 {
0315     const QString readNameSpace  = QLatin1String("read%1Namespaces");
0316     const QString writeNameSpace = QLatin1String("write%1Namespaces");
0317 
0318     // Remove all old group elements.
0319 
0320     Q_FOREACH (const QString& groupKey, group.groupList())
0321     {
0322         group.deleteGroup(groupKey);
0323     }
0324 
0325     Q_FOREACH (const QString& str, mappingKeys())
0326     {
0327         writeOneGroup(group, readNameSpace.arg(str), getReadMapping(str));
0328         writeOneGroup(group, writeNameSpace.arg(str), getWriteMapping(str));
0329     }
0330 
0331     group.writeEntry(QLatin1String("unifyReadWrite"), d->unifyReadWrite);
0332     group.writeEntry(QLatin1String("readingAllTags"), d->readingAllTags);
0333     group.sync();
0334 }
0335 
0336 void DMetadataSettingsContainer::defaultValues()
0337 {
0338     d->unifyReadWrite = true;
0339     d->readingAllTags = false;
0340     d->writeMappings.clear();
0341     d->readMappings.clear();
0342 
0343     defaultTagValues();
0344     defaultTitleValues();
0345     defaultRatingValues();
0346     defaultCommentValues();
0347     defaultColorLabelValues();
0348 }
0349 
0350 void DMetadataSettingsContainer::addMapping(const QString& key)
0351 {
0352     d->readMappings[key]  = QList<NamespaceEntry>();
0353     d->writeMappings[key] = QList<NamespaceEntry>();
0354 }
0355 
0356 QList<NamespaceEntry>& DMetadataSettingsContainer::getReadMapping(const QString& key) const
0357 {
0358     return d->readMappings[key];
0359 }
0360 
0361 QList<NamespaceEntry>& DMetadataSettingsContainer::getWriteMapping(const QString& key) const
0362 {
0363     return d->writeMappings[key];
0364 }
0365 
0366 QList<QString> DMetadataSettingsContainer::mappingKeys() const
0367 {
0368     return d->readMappings.keys();
0369 }
0370 
0371 void DMetadataSettingsContainer::defaultTagValues()
0372 {
0373     // Default tag namespaces
0374 
0375     NamespaceEntry tagNs1;
0376     tagNs1.namespaceName    = QLatin1String("Xmp.digiKam.TagsList");
0377     tagNs1.tagPaths         = NamespaceEntry::TAGPATH;
0378     tagNs1.separator        = QLatin1Char('/');
0379     tagNs1.nsType           = NamespaceEntry::TAGS;
0380     tagNs1.index            = 0;
0381     tagNs1.specialOpts      = NamespaceEntry::TAG_XMPSEQ;
0382     tagNs1.subspace         = NamespaceEntry::XMP;
0383 
0384     NamespaceEntry tagNs2;
0385     tagNs2.namespaceName    = QLatin1String("Xmp.MicrosoftPhoto.LastKeywordXMP");
0386     tagNs2.tagPaths         = NamespaceEntry::TAGPATH;
0387     tagNs2.separator        = QLatin1Char('/');
0388     tagNs2.nsType           = NamespaceEntry::TAGS;
0389     tagNs2.index            = 1;
0390     tagNs2.specialOpts      = NamespaceEntry::TAG_XMPBAG;
0391     tagNs2.subspace         = NamespaceEntry::XMP;
0392 
0393     NamespaceEntry tagNs3;
0394     tagNs3.namespaceName    = QLatin1String("Xmp.lr.hierarchicalSubject");
0395     tagNs3.tagPaths         = NamespaceEntry::TAGPATH;
0396     tagNs3.separator        = QLatin1Char('|');
0397     tagNs3.nsType           = NamespaceEntry::TAGS;
0398     tagNs3.index            = 2;
0399     tagNs3.specialOpts      = NamespaceEntry::TAG_XMPBAG;
0400     tagNs3.subspace         = NamespaceEntry::XMP;
0401     tagNs3.alternativeName  = QLatin1String("Xmp.lr.HierarchicalSubject");
0402     tagNs3.secondNameOpts   = NamespaceEntry::TAG_XMPSEQ;
0403 
0404     NamespaceEntry tagNs4;
0405     tagNs4.namespaceName    = QLatin1String("Xmp.mediapro.CatalogSets");
0406     tagNs4.tagPaths         = NamespaceEntry::TAGPATH;
0407     tagNs4.separator        = QLatin1Char('|');
0408     tagNs4.nsType           = NamespaceEntry::TAGS;
0409     tagNs4.index            = 3;
0410     tagNs4.specialOpts      = NamespaceEntry::TAG_XMPBAG;
0411     tagNs4.subspace         = NamespaceEntry::XMP;
0412 
0413     NamespaceEntry tagNs5;
0414     tagNs5.namespaceName    = QLatin1String("Xmp.acdsee.categories");
0415     tagNs5.tagPaths         = NamespaceEntry::TAGPATH;
0416     tagNs5.separator        = QLatin1Char('/');
0417     tagNs5.nsType           = NamespaceEntry::TAGS;
0418     tagNs5.index            = 4;
0419     tagNs5.specialOpts      = NamespaceEntry::TAG_ACDSEE;
0420     tagNs5.subspace         = NamespaceEntry::XMP;
0421 
0422     NamespaceEntry tagNs6;
0423     tagNs6.namespaceName    = QLatin1String("Xmp.dc.subject");
0424     tagNs6.tagPaths         = NamespaceEntry::TAG;
0425     tagNs6.separator        = QLatin1Char('/');
0426     tagNs6.nsType           = NamespaceEntry::TAGS;
0427     tagNs6.index            = 5;
0428     tagNs6.specialOpts      = NamespaceEntry::TAG_XMPBAG;
0429     tagNs6.subspace         = NamespaceEntry::XMP;
0430 
0431     NamespaceEntry tagNs7;
0432     tagNs7.namespaceName    = QLatin1String("Iptc.Application2.Keywords");
0433     tagNs7.tagPaths         = NamespaceEntry::TAG;
0434     tagNs7.nsType           = NamespaceEntry::TAGS;
0435     tagNs7.index            = 6;
0436     tagNs7.subspace         = NamespaceEntry::IPTC;
0437 
0438     NamespaceEntry tagNs8;
0439     tagNs8.namespaceName    = QLatin1String("Exif.Image.XPKeywords");
0440     tagNs8.tagPaths         = NamespaceEntry::TAG;
0441     tagNs8.separator        = QLatin1Char(';');
0442     tagNs8.nsType           = NamespaceEntry::TAGS;
0443     tagNs8.index            = 7;
0444     tagNs8.subspace         = NamespaceEntry::EXIF;
0445 
0446     getReadMapping(NamespaceEntry::DM_TAG_CONTAINER()) << tagNs1
0447                                                        << tagNs2
0448                                                        << tagNs3
0449                                                        << tagNs4
0450                                                        << tagNs5
0451                                                        << tagNs6
0452                                                        << tagNs7
0453                                                        << tagNs8;
0454 
0455     d->writeMappings[NamespaceEntry::DM_TAG_CONTAINER()]
0456         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_TAG_CONTAINER()));
0457 }
0458 
0459 void DMetadataSettingsContainer::defaultTitleValues()
0460 {
0461     NamespaceEntry titleNs1;
0462     titleNs1.namespaceName  = QLatin1String("Xmp.dc.title");
0463     titleNs1.nsType         = NamespaceEntry::TITLE;
0464     titleNs1.specialOpts    = NamespaceEntry::COMMENT_ATLLANGLIST;
0465     titleNs1.index          = 0;
0466     titleNs1.subspace       = NamespaceEntry::XMP;
0467 
0468     NamespaceEntry titleNs2;
0469     titleNs2.namespaceName  = QLatin1String("Xmp.acdsee.caption");
0470     titleNs2.nsType         = NamespaceEntry::TITLE;
0471     titleNs2.specialOpts    = NamespaceEntry::COMMENT_XMP;
0472     titleNs2.index          = 1;
0473     titleNs2.subspace       = NamespaceEntry::XMP;
0474 
0475     NamespaceEntry titleNs3;
0476     titleNs3.namespaceName  = QLatin1String("Iptc.Application2.ObjectName");
0477     titleNs3.nsType         = NamespaceEntry::TITLE;
0478     titleNs3.specialOpts    = NamespaceEntry::NO_OPTS;
0479     titleNs3.index          = 2;
0480     titleNs3.subspace       = NamespaceEntry::IPTC;
0481 
0482     NamespaceEntry titleNs4;
0483     titleNs4.namespaceName  = QLatin1String("Exif.Image.XPTitle");
0484     titleNs4.nsType         = NamespaceEntry::TITLE;
0485     titleNs4.specialOpts    = NamespaceEntry::NO_OPTS;
0486     titleNs4.index          = 3;
0487     titleNs4.subspace       = NamespaceEntry::EXIF;
0488 
0489     getReadMapping(NamespaceEntry::DM_TITLE_CONTAINER()) << titleNs1
0490                                                          << titleNs2
0491                                                          << titleNs3
0492                                                          << titleNs4;
0493 
0494     d->writeMappings[NamespaceEntry::DM_TITLE_CONTAINER()]
0495         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_TITLE_CONTAINER()));
0496 }
0497 
0498 void DMetadataSettingsContainer::defaultRatingValues()
0499 {
0500     QList<int> defaultVal;
0501     QList<int> microsoftMappings;
0502 
0503     defaultVal        << 0 << 1 << 2  << 3  << 4  << 5;
0504     microsoftMappings << 0 << 1 << 25 << 50 << 75 << 99;
0505 
0506     NamespaceEntry ratingNs1;
0507     ratingNs1.namespaceName = QLatin1String("Xmp.xmp.Rating");
0508     ratingNs1.convertRatio  = defaultVal;
0509     ratingNs1.nsType        = NamespaceEntry::RATING;
0510     ratingNs1.index         = 0;
0511     ratingNs1.subspace      = NamespaceEntry::XMP;
0512 
0513     NamespaceEntry ratingNs2;
0514     ratingNs2.namespaceName = QLatin1String("Xmp.acdsee.rating");
0515     ratingNs2.convertRatio  = defaultVal;
0516     ratingNs2.nsType        = NamespaceEntry::RATING;
0517     ratingNs2.index         = 1;
0518     ratingNs2.subspace      = NamespaceEntry::XMP;
0519 
0520     NamespaceEntry ratingNs3;
0521     ratingNs3.namespaceName = QLatin1String("Xmp.MicrosoftPhoto.Rating");
0522     ratingNs3.convertRatio  = microsoftMappings;
0523     ratingNs3.nsType        = NamespaceEntry::RATING;
0524     ratingNs3.index         = 2;
0525     ratingNs3.subspace      = NamespaceEntry::XMP;
0526 
0527     NamespaceEntry ratingNs4;
0528     ratingNs4.namespaceName = QLatin1String("Exif.Image.Rating");
0529     ratingNs4.convertRatio  = defaultVal;
0530     ratingNs4.nsType        = NamespaceEntry::RATING;
0531     ratingNs4.index         = 3;
0532     ratingNs4.subspace      = NamespaceEntry::EXIF;
0533 
0534     NamespaceEntry ratingNs5;
0535     ratingNs5.namespaceName = QLatin1String("Exif.Image.RatingPercent");
0536     ratingNs5.convertRatio  = microsoftMappings;
0537     ratingNs5.nsType        = NamespaceEntry::RATING;
0538     ratingNs5.index         = 4;
0539     ratingNs5.subspace      = NamespaceEntry::EXIF;
0540 
0541     getReadMapping(NamespaceEntry::DM_RATING_CONTAINER()) << ratingNs1
0542                                                           << ratingNs2
0543                                                           << ratingNs3
0544                                                           << ratingNs4
0545                                                           << ratingNs5;
0546 
0547     d->writeMappings[NamespaceEntry::DM_RATING_CONTAINER()]
0548         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_RATING_CONTAINER()));
0549 }
0550 
0551 void DMetadataSettingsContainer::defaultCommentValues()
0552 {
0553     NamespaceEntry commNs1;
0554     commNs1.namespaceName   = QLatin1String("Xmp.dc.description");
0555     commNs1.nsType          = NamespaceEntry::COMMENT;
0556     commNs1.specialOpts     = NamespaceEntry::COMMENT_ATLLANGLIST;
0557     commNs1.index           = 0;
0558     commNs1.subspace        = NamespaceEntry::XMP;
0559 
0560     NamespaceEntry commNs2;
0561     commNs2.namespaceName   = QLatin1String("Xmp.exif.UserComment");
0562     commNs2.nsType          = NamespaceEntry::COMMENT;
0563     commNs2.specialOpts     = NamespaceEntry::COMMENT_ALTLANG;
0564     commNs2.index           = 1;
0565     commNs2.subspace        = NamespaceEntry::XMP;
0566 
0567     NamespaceEntry commNs3;
0568     commNs3.namespaceName   = QLatin1String("Xmp.tiff.ImageDescription");
0569     commNs3.nsType          = NamespaceEntry::COMMENT;
0570     commNs3.specialOpts     = NamespaceEntry::COMMENT_ALTLANG;
0571     commNs3.index           = 2;
0572     commNs3.subspace        = NamespaceEntry::XMP;
0573 
0574     NamespaceEntry commNs4;
0575     commNs4.namespaceName   = QLatin1String("Xmp.acdsee.notes");
0576     commNs4.nsType          = NamespaceEntry::COMMENT;
0577     commNs4.specialOpts     = NamespaceEntry::COMMENT_XMP;
0578     commNs4.index           = 3;
0579     commNs4.subspace        = NamespaceEntry::XMP;
0580 
0581     NamespaceEntry commNs5;
0582     commNs5.namespaceName   = QLatin1String("JPEG/TIFF Comments");
0583     commNs5.nsType          = NamespaceEntry::COMMENT;
0584     commNs5.specialOpts     = NamespaceEntry::COMMENT_JPEG;
0585     commNs5.index           = 4;
0586     commNs5.subspace        = NamespaceEntry::XMP;
0587 
0588     NamespaceEntry commNs6;
0589     commNs6.namespaceName   = QLatin1String("Exif.Image.ImageDescription");
0590     commNs6.nsType          = NamespaceEntry::COMMENT;
0591     commNs6.specialOpts     = NamespaceEntry::NO_OPTS;
0592     commNs6.index           = 5;
0593     commNs6.subspace        = NamespaceEntry::EXIF;
0594 
0595     NamespaceEntry commNs7;
0596     commNs7.namespaceName   = QLatin1String("Exif.Photo.UserComment");
0597     commNs7.nsType          = NamespaceEntry::COMMENT;
0598     commNs7.specialOpts     = NamespaceEntry::NO_OPTS;
0599     commNs7.index           = 6;
0600     commNs7.subspace        = NamespaceEntry::EXIF;
0601 
0602     NamespaceEntry commNs8;
0603     commNs8.namespaceName   = QLatin1String("Exif.Image.XPComment");
0604     commNs8.nsType          = NamespaceEntry::COMMENT;
0605     commNs8.specialOpts     = NamespaceEntry::NO_OPTS;
0606     commNs8.index           = 7;
0607     commNs8.subspace        = NamespaceEntry::EXIF;
0608 
0609     NamespaceEntry commNs9;
0610     commNs9.namespaceName   = QLatin1String("Iptc.Application2.Caption");
0611     commNs9.nsType          = NamespaceEntry::COMMENT;
0612     commNs9.specialOpts     = NamespaceEntry::NO_OPTS;
0613     commNs9.index           = 8;
0614     commNs9.subspace        = NamespaceEntry::IPTC;
0615 
0616     getReadMapping(NamespaceEntry::DM_COMMENT_CONTAINER()) << commNs1
0617                                                            << commNs2
0618                                                            << commNs3
0619                                                            << commNs4
0620                                                            << commNs5
0621                                                            << commNs6
0622                                                            << commNs7
0623                                                            << commNs8
0624                                                            << commNs9;
0625 
0626     d->writeMappings[NamespaceEntry::DM_COMMENT_CONTAINER()]
0627         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_COMMENT_CONTAINER()));
0628 }
0629 
0630 void DMetadataSettingsContainer::defaultColorLabelValues()
0631 {
0632     NamespaceEntry colorNs1;
0633     colorNs1.namespaceName   = QLatin1String("Xmp.digiKam.ColorLabel");
0634     colorNs1.nsType          = NamespaceEntry::COLORLABEL;
0635     colorNs1.specialOpts     = NamespaceEntry::NO_OPTS;
0636     colorNs1.index           = 0;
0637     colorNs1.subspace        = NamespaceEntry::XMP;
0638 
0639     NamespaceEntry colorNs2;
0640     colorNs2.namespaceName   = QLatin1String("Xmp.xmp.Label");
0641     colorNs2.nsType          = NamespaceEntry::COLORLABEL;
0642     colorNs2.specialOpts     = NamespaceEntry::NO_OPTS;
0643     colorNs2.index           = 1;
0644     colorNs2.subspace        = NamespaceEntry::XMP;
0645 
0646     NamespaceEntry colorNs3;
0647     colorNs3.namespaceName   = QLatin1String("Xmp.photoshop.Urgency");
0648     colorNs3.nsType          = NamespaceEntry::COLORLABEL;
0649     colorNs3.specialOpts     = NamespaceEntry::NO_OPTS;
0650     colorNs3.index           = 2;
0651     colorNs3.subspace        = NamespaceEntry::XMP;
0652 
0653     getReadMapping(NamespaceEntry::DM_COLORLABEL_CONTAINER()) << colorNs1
0654                                                               << colorNs2
0655                                                               << colorNs3;
0656 
0657     d->writeMappings[NamespaceEntry::DM_COLORLABEL_CONTAINER()]
0658         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_COLORLABEL_CONTAINER()));
0659 }
0660 
0661 void DMetadataSettingsContainer::readOneGroup(KConfigGroup& group, const QString& name, QList<NamespaceEntry>& container)
0662 {
0663     KConfigGroup myItems = group.group(name);
0664 
0665     Q_FOREACH (const QString& element, myItems.groupList())
0666     {
0667         KConfigGroup gr      = myItems.group(element);
0668         NamespaceEntry ns;
0669 
0670         if (element.startsWith(QLatin1Char('#')))
0671         {
0672             ns.namespaceName = gr.readEntry("namespaceName");
0673         }
0674         else
0675         {
0676             ns.namespaceName = element;
0677         }
0678 
0679         ns.tagPaths          = (NamespaceEntry::TagType)gr.readEntry("tagPaths").toInt();
0680         ns.separator         = gr.readEntry("separator", QString());
0681         ns.nsType            = (NamespaceEntry::NamespaceType)gr.readEntry("nsType").toInt();
0682         ns.index             = gr.readEntry("index").toInt();
0683         ns.subspace          = (NamespaceEntry::NsSubspace)gr.readEntry("subspace").toInt();
0684         ns.alternativeName   = gr.readEntry("alternativeName", QString());
0685         ns.specialOpts       = (NamespaceEntry::SpecialOptions)gr.readEntry("specialOpts").toInt();
0686         ns.secondNameOpts    = (NamespaceEntry::SpecialOptions)gr.readEntry("secondNameOpts").toInt();
0687         ns.isDefault         = gr.readEntry(QLatin1String("isDefault"), QVariant(true)).toBool();
0688         ns.isDisabled        = gr.readEntry(QLatin1String("isDisabled"), QVariant(false)).toBool();
0689         QString conversion   = gr.readEntry("convertRatio", QString());
0690 
0691         if (!conversion.isEmpty() || (ns.nsType == NamespaceEntry::RATING))
0692         {
0693             Q_FOREACH (const QString& str, conversion.split(QLatin1String(",")))
0694             {
0695                 ns.convertRatio.append(str.toInt());
0696             }
0697 
0698             if (ns.convertRatio.size() != 6)
0699             {
0700                 qCWarning(DIGIKAM_METAENGINE_LOG) << "Wrong size of rating conversion values in the config!";
0701 
0702                 // fallback to default rating conversion values
0703 
0704                 ns.convertRatio = QList<int>({0, 1, 2, 3, 4, 5});
0705             }
0706         }
0707 
0708         container.append(ns);
0709     }
0710 
0711     std::sort(container.begin(), container.end(), Digikam::s_dmcompare);
0712 }
0713 
0714 void DMetadataSettingsContainer::writeOneGroup(KConfigGroup& group, const QString& name, QList<NamespaceEntry>& container) const
0715 {
0716     KConfigGroup namespacesGroup = group.group(name);
0717     int index                    = 0;
0718 
0719     Q_FOREACH (const NamespaceEntry& e, container)
0720     {
0721         QString groupNumber = QString::fromLatin1("#%1")
0722                               .arg(index++, 4, 10, QLatin1Char('0'));
0723 
0724         KConfigGroup tmp = namespacesGroup.group(groupNumber);
0725         tmp.writeEntry("namespaceName",   e.namespaceName);
0726 
0727         if (!e.alternativeName.isEmpty())
0728         {
0729             tmp.writeEntry("alternativeName", e.alternativeName);
0730         }
0731 
0732         tmp.writeEntry("subspace",         (int)e.subspace);
0733         tmp.writeEntry("tagPaths",         (int)e.tagPaths);
0734 
0735         if (!e.separator.isEmpty())
0736         {
0737             tmp.writeEntry("separator",    e.separator);
0738         }
0739 
0740         tmp.writeEntry("nsType",           (int)e.nsType);
0741 
0742         if (!e.convertRatio.isEmpty())
0743         {
0744             tmp.writeEntry("convertRatio", e.convertRatio);
0745         }
0746 
0747         tmp.writeEntry("specialOpts",      (int)e.specialOpts);
0748         tmp.writeEntry("secondNameOpts",   (int)e.secondNameOpts);
0749         tmp.writeEntry("index",            e.index);
0750         tmp.writeEntry("isDisabled",       e.isDisabled);
0751         tmp.writeEntry("isDefault",        e.isDefault);
0752     }
0753 }
0754 
0755 QString DMetadataSettingsContainer::translateMappingKey(const QString& key) const
0756 {
0757 
0758 #if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0)
0759 
0760     if      (NamespaceEntry::DM_TAG_CONTAINER() == key)
0761     {
0762         return namespaceTitleDefinitions[NamespaceEntry::TAGS].title.toString();
0763     }
0764     else if (NamespaceEntry::DM_TITLE_CONTAINER() == key)
0765     {
0766         return namespaceTitleDefinitions[NamespaceEntry::TITLE].title.toString();
0767     }
0768     else if (NamespaceEntry::DM_RATING_CONTAINER() == key)
0769     {
0770         return namespaceTitleDefinitions[NamespaceEntry::RATING].title.toString();
0771     }
0772     else if (NamespaceEntry::DM_COMMENT_CONTAINER() == key)
0773     {
0774         return namespaceTitleDefinitions[NamespaceEntry::COMMENT].title.toString();
0775     }
0776     else if (NamespaceEntry::DM_PICKLABEL_CONTAINER() == key)
0777     {
0778         return namespaceTitleDefinitions[NamespaceEntry::PICKLABEL].title.toString();
0779     }
0780     else if (NamespaceEntry::DM_COLORLABEL_CONTAINER() == key)
0781     {
0782         return namespaceTitleDefinitions[NamespaceEntry::COLORLABEL].title.toString();
0783     }
0784 
0785 #else
0786 
0787     if      (NamespaceEntry::DM_TAG_CONTAINER() == key)
0788     {
0789         return i18nc(namespaceTitleDefinitions[NamespaceEntry::TAGS].context,
0790                      namespaceTitleDefinitions[NamespaceEntry::TAGS].title);
0791     }
0792     else if (NamespaceEntry::DM_TITLE_CONTAINER() == key)
0793     {
0794         return i18nc(namespaceTitleDefinitions[NamespaceEntry::TITLE].context,
0795                      namespaceTitleDefinitions[NamespaceEntry::TITLE].title);
0796     }
0797     else if (NamespaceEntry::DM_RATING_CONTAINER() == key)
0798     {
0799         return i18nc(namespaceTitleDefinitions[NamespaceEntry::RATING].context,
0800                      namespaceTitleDefinitions[NamespaceEntry::RATING].title);
0801     }
0802     else if (NamespaceEntry::DM_COMMENT_CONTAINER() == key)
0803     {
0804         return i18nc(namespaceTitleDefinitions[NamespaceEntry::COMMENT].context,
0805                      namespaceTitleDefinitions[NamespaceEntry::COMMENT].title);
0806     }
0807     else if (NamespaceEntry::DM_PICKLABEL_CONTAINER() == key)
0808     {
0809         return i18nc(namespaceTitleDefinitions[NamespaceEntry::PICKLABEL].context,
0810                      namespaceTitleDefinitions[NamespaceEntry::PICKLABEL].title);
0811     }
0812     else if (NamespaceEntry::DM_COLORLABEL_CONTAINER() == key)
0813     {
0814         return i18nc(namespaceTitleDefinitions[NamespaceEntry::COLORLABEL].context,
0815                      namespaceTitleDefinitions[NamespaceEntry::COLORLABEL].title);
0816     }
0817 
0818 #endif
0819 
0820     return key;
0821 }
0822 
0823 QDebug operator<<(QDebug dbg, const DMetadataSettingsContainer& inf)
0824 {
0825     dbg.nospace() << "[DMetadataSettingsContainer] readMappings(";
0826 
0827     Q_FOREACH (const QString& str, inf.mappingKeys())
0828     {
0829         dbg.nospace() << inf.getReadMapping(str) << "), ";
0830     }
0831 
0832     dbg.nospace() << "writeMappings(";
0833 
0834     Q_FOREACH (const QString& str, inf.mappingKeys())
0835     {
0836         dbg.nospace() << inf.getWriteMapping(str) << "), ";
0837     }
0838 
0839     dbg.nospace() << "unifyReadWrite("
0840                   << inf.unifyReadWrite() << ")";
0841 
0842     return dbg.space();
0843 }
0844 
0845 } // namespace Digikam