1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2015-08-12
7  * Description : metadata Settings Container.
8  *
9  * Copyright (C) 2015      by Veaceslav Munteanu <veaceslav dot munteanu90 at gmail dot com>
10  * Copyright (C) 2015-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11  *
12  * This program is free software; you can redistribute it
13  * and/or modify it under the terms of the GNU General
14  * Public License as published by the Free Software Foundation;
15  * either version 2, or (at your option)
16  * any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * ============================================================ */
24 
25 #include "dmetadatasettingscontainer.h"
26 
27 // KDE includes
28 
29 #include <klocalizedstring.h>
30 #include <kconfiggroup.h>
31 
32 // Local includes
33 
34 #include "dmetadatasettings.h"
35 #include "digikam_debug.h"
36 
37 namespace Digikam
38 {
39 
DM_TAG_CONTAINER()40 QString NamespaceEntry::DM_TAG_CONTAINER()
41 {
42     return QString::fromUtf8(I18N_NOOP("Tags"));
43 }
44 
DM_TITLE_CONTAINER()45 QString NamespaceEntry::DM_TITLE_CONTAINER()
46 {
47     return QString::fromUtf8(I18N_NOOP("Title"));
48 }
49 
DM_RATING_CONTAINER()50 QString NamespaceEntry::DM_RATING_CONTAINER()
51 {
52     return QString::fromUtf8(I18N_NOOP("Rating"));
53 }
54 
DM_COMMENT_CONTAINER()55 QString NamespaceEntry::DM_COMMENT_CONTAINER()
56 {
57     return QString::fromUtf8(I18N_NOOP("Caption"));
58 }
59 
DM_COLORLABEL_CONTAINER()60 QString NamespaceEntry::DM_COLORLABEL_CONTAINER()
61 {
62     return QString::fromUtf8(I18N_NOOP("Color label"));
63 }
64 
65 // ------------------------------------------------------------
66 
s_dmcompare(const NamespaceEntry & e1,const NamespaceEntry & e2)67 bool s_dmcompare(const NamespaceEntry& e1, const NamespaceEntry& e2)
68 {
69     return (e1.index < e2.index);
70 }
71 
operator <<(QDebug dbg,const NamespaceEntry & inf)72 QDebug operator<<(QDebug dbg, const NamespaceEntry& inf)
73 {
74     dbg.nospace() << "[NamespaceEntry] nsType("
75                   << inf.nsType << "), ";
76     dbg.nospace() << "subspace("
77                   << inf.subspace << "), ";
78     dbg.nospace() << "isDefault("
79                   << inf.isDefault << "), ";
80     dbg.nospace() << "isDisabled("
81                   << inf.isDisabled << "), ";
82     dbg.nospace() << "index("
83                   << inf.index << "), ";
84     dbg.nospace() << "namespaceName("
85                   << inf.namespaceName << "), ";
86     dbg.nospace() << "alternativeName("
87                   << inf.alternativeName << "), ";
88     dbg.nospace() << "tagPaths("
89                   << inf.tagPaths << "), ";
90     dbg.nospace() << "separator("
91                   << inf.separator << "), ";
92     dbg.nospace() << "convertRatio("
93                   << inf.convertRatio << "), ";
94     dbg.nospace() << "specialOpts("
95                   << inf.specialOpts << "), ";
96     dbg.nospace() << "secondNameOpts("
97                   << inf.secondNameOpts << ")";
98 
99     return dbg.space();
100 }
101 
102 // -------------------------------------------------------------------------------------------------
103 
104 class Q_DECL_HIDDEN DMetadataSettingsContainer::Private
105 {
106 public:
107 
Private()108     explicit Private()
109       : unifyReadWrite(false)
110     {
111     }
112 
113 public:
114 
115     QMap<QString, QList<NamespaceEntry> > readMappings;
116     QMap<QString, QList<NamespaceEntry> > writeMappings;
117     bool                                  unifyReadWrite;
118 };
119 
120 // -------------------------------------------------------------------------------------------------
121 
DMetadataSettingsContainer()122 DMetadataSettingsContainer::DMetadataSettingsContainer()
123     : d(new Private)
124 {
125     addMapping(NamespaceEntry::DM_TAG_CONTAINER());
126     addMapping(NamespaceEntry::DM_TITLE_CONTAINER());
127     addMapping(NamespaceEntry::DM_RATING_CONTAINER());
128     addMapping(NamespaceEntry::DM_COMMENT_CONTAINER());
129     addMapping(NamespaceEntry::DM_COLORLABEL_CONTAINER());
130 }
131 
DMetadataSettingsContainer(const DMetadataSettingsContainer & other)132 DMetadataSettingsContainer::DMetadataSettingsContainer(const DMetadataSettingsContainer& other)
133     : d(new Private)
134 {
135     *d = *other.d;
136 }
137 
operator =(const DMetadataSettingsContainer & other)138 DMetadataSettingsContainer& DMetadataSettingsContainer::operator=(const DMetadataSettingsContainer& other)
139 {
140     *d = *other.d;
141 
142     return *this;
143 }
144 
~DMetadataSettingsContainer()145 DMetadataSettingsContainer::~DMetadataSettingsContainer()
146 {
147     delete d;
148 }
149 
unifyReadWrite() const150 bool DMetadataSettingsContainer::unifyReadWrite() const
151 {
152     return d->unifyReadWrite;
153 }
154 
setUnifyReadWrite(bool b)155 void DMetadataSettingsContainer::setUnifyReadWrite(bool b)
156 {
157     d->unifyReadWrite = b;
158 }
159 
readFromConfig(KConfigGroup & group)160 void DMetadataSettingsContainer::readFromConfig(KConfigGroup& group)
161 {
162     bool valid                   = true;
163     const QString readNameSpace  = QLatin1String("read%1Namespaces");
164     const QString writeNameSpace = QLatin1String("write%1Namespaces");
165 
166     foreach (const QString& str, mappingKeys())
167     {
168         if (!group.hasGroup(readNameSpace.arg(str)))
169         {
170             valid = false;
171             qCDebug(DIGIKAM_GENERAL_LOG) << "Does not contain " << str << " Namespace";
172             break;
173         }
174 
175         if (!group.hasGroup(writeNameSpace.arg(str)))
176         {
177             valid = false;
178             qCDebug(DIGIKAM_GENERAL_LOG) << "Does not contain " << str << " Namespace";
179             break;
180         }
181     }
182 
183     if (valid)
184     {
185         foreach (const QString& str, mappingKeys())
186         {
187             readOneGroup(group, readNameSpace.arg(str), getReadMapping(str));
188             readOneGroup(group, writeNameSpace.arg(str), getWriteMapping(str));
189         }
190     }
191     else
192     {
193         defaultValues();
194     }
195 
196     d->unifyReadWrite = group.readEntry(QLatin1String("unifyReadWrite"), true);
197 }
198 
writeToConfig(KConfigGroup & group) const199 void DMetadataSettingsContainer::writeToConfig(KConfigGroup& group) const
200 {
201    const QString readNameSpace  = QLatin1String("read%1Namespaces");
202    const QString writeNameSpace = QLatin1String("write%1Namespaces");
203 
204     foreach (const QString& str, mappingKeys())
205     {
206         // Remove all old group elements.
207 
208         group.group(readNameSpace.arg(str)).deleteGroup();
209         group.group(writeNameSpace.arg(str)).deleteGroup();
210 
211         writeOneGroup(group, readNameSpace.arg(str), getReadMapping(str));
212         writeOneGroup(group, writeNameSpace.arg(str), getWriteMapping(str));
213     }
214 
215     group.writeEntry(QLatin1String("unifyReadWrite"), d->unifyReadWrite);
216     group.sync();
217 }
218 
defaultValues()219 void DMetadataSettingsContainer::defaultValues()
220 {
221     d->unifyReadWrite = true;
222     d->writeMappings.clear();
223     d->readMappings.clear();
224 
225     defaultTagValues();
226     defaultTitleValues();
227     defaultRatingValues();
228     defaultCommentValues();
229     defaultColorLabelValues();
230 }
231 
addMapping(const QString & key)232 void DMetadataSettingsContainer::addMapping(const QString& key)
233 {
234     d->readMappings[key]  = QList<NamespaceEntry>();
235     d->writeMappings[key] = QList<NamespaceEntry>();
236 }
237 
getReadMapping(const QString & key) const238 QList<NamespaceEntry>& DMetadataSettingsContainer::getReadMapping(const QString& key) const
239 {
240     return d->readMappings[key];
241 }
242 
getWriteMapping(const QString & key) const243 QList<NamespaceEntry>& DMetadataSettingsContainer::getWriteMapping(const QString& key) const
244 {
245     return d->writeMappings[key];
246 }
247 
mappingKeys() const248 QList<QString> DMetadataSettingsContainer::mappingKeys() const
249 {
250     return d->readMappings.keys();
251 }
252 
defaultTagValues()253 void DMetadataSettingsContainer::defaultTagValues()
254 {
255     // Default tag namespaces
256 
257     NamespaceEntry tagNs1;
258     tagNs1.namespaceName    = QLatin1String("Xmp.digiKam.TagsList");
259     tagNs1.tagPaths         = NamespaceEntry::TAGPATH;
260     tagNs1.separator        = QLatin1Char('/');
261     tagNs1.nsType           = NamespaceEntry::TAGS;
262     tagNs1.index            = 0;
263     tagNs1.specialOpts      = NamespaceEntry::TAG_XMPSEQ;
264     tagNs1.subspace         = NamespaceEntry::XMP;
265 
266     NamespaceEntry tagNs2;
267     tagNs2.namespaceName    = QLatin1String("Xmp.MicrosoftPhoto.LastKeywordXMP");
268     tagNs2.tagPaths         = NamespaceEntry::TAGPATH;
269     tagNs2.separator        = QLatin1Char('/');
270     tagNs2.nsType           = NamespaceEntry::TAGS;
271     tagNs2.index            = 1;
272     tagNs2.specialOpts      = NamespaceEntry::TAG_XMPBAG;
273     tagNs2.subspace         = NamespaceEntry::XMP;
274 
275     NamespaceEntry tagNs3;
276     tagNs3.namespaceName    = QLatin1String("Xmp.lr.hierarchicalSubject");
277     tagNs3.tagPaths         = NamespaceEntry::TAGPATH;
278     tagNs3.separator        = QLatin1Char('|');
279     tagNs3.nsType           = NamespaceEntry::TAGS;
280     tagNs3.index            = 2;
281     tagNs3.specialOpts      = NamespaceEntry::TAG_XMPBAG;
282     tagNs3.subspace         = NamespaceEntry::XMP;
283     tagNs3.alternativeName  = QLatin1String("Xmp.lr.HierarchicalSubject");
284     tagNs3.secondNameOpts   = NamespaceEntry::TAG_XMPSEQ;
285 
286     NamespaceEntry tagNs4;
287     tagNs4.namespaceName    = QLatin1String("Xmp.mediapro.CatalogSets");
288     tagNs4.tagPaths         = NamespaceEntry::TAGPATH;
289     tagNs4.separator        = QLatin1Char('|');
290     tagNs4.nsType           = NamespaceEntry::TAGS;
291     tagNs4.index            = 3;
292     tagNs4.specialOpts      = NamespaceEntry::TAG_XMPBAG;
293     tagNs4.subspace         = NamespaceEntry::XMP;
294 
295     NamespaceEntry tagNs5;
296     tagNs5.namespaceName    = QLatin1String("Xmp.acdsee.categories");
297     tagNs5.tagPaths         = NamespaceEntry::TAGPATH;
298     tagNs5.separator        = QLatin1Char('/');
299     tagNs5.nsType           = NamespaceEntry::TAGS;
300     tagNs5.index            = 4;
301     tagNs5.specialOpts      = NamespaceEntry::TAG_ACDSEE;
302     tagNs5.subspace         = NamespaceEntry::XMP;
303 
304     NamespaceEntry tagNs6;
305     tagNs6.namespaceName    = QLatin1String("Xmp.dc.subject");
306     tagNs6.tagPaths         = NamespaceEntry::TAG;
307     tagNs6.separator        = QLatin1Char('/');
308     tagNs6.nsType           = NamespaceEntry::TAGS;
309     tagNs6.index            = 5;
310     tagNs6.specialOpts      = NamespaceEntry::TAG_XMPBAG;
311     tagNs6.subspace         = NamespaceEntry::XMP;
312 
313     NamespaceEntry tagNs7;
314     tagNs7.namespaceName    = QLatin1String("Iptc.Application2.Keywords");
315     tagNs7.tagPaths         = NamespaceEntry::TAGPATH;
316     tagNs7.separator        = QLatin1Char(',');
317     tagNs7.nsType           = NamespaceEntry::TAGS;
318     tagNs7.index            = 6;
319     tagNs7.subspace         = NamespaceEntry::IPTC;
320 
321     NamespaceEntry tagNs8;
322     tagNs8.namespaceName    = QLatin1String("Exif.Image.XPKeywords");
323     tagNs8.tagPaths         = NamespaceEntry::TAGPATH;
324     tagNs8.separator        = QLatin1Char(';');
325     tagNs8.nsType           = NamespaceEntry::TAGS;
326     tagNs8.index            = 7;
327     tagNs8.subspace         = NamespaceEntry::EXIF;
328 
329     getReadMapping(NamespaceEntry::DM_TAG_CONTAINER()) << tagNs1
330                                                        << tagNs2
331                                                        << tagNs3
332                                                        << tagNs4
333                                                        << tagNs5
334                                                        << tagNs6
335                                                        << tagNs7
336                                                        << tagNs8;
337 
338     d->writeMappings[NamespaceEntry::DM_TAG_CONTAINER()]
339         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_TAG_CONTAINER()));
340 }
341 
defaultTitleValues()342 void DMetadataSettingsContainer::defaultTitleValues()
343 {
344     NamespaceEntry titleNs1;
345     titleNs1.namespaceName  = QLatin1String("Xmp.dc.title");
346     titleNs1.nsType         = NamespaceEntry::TITLE;
347     titleNs1.specialOpts    = NamespaceEntry::COMMENT_ATLLANGLIST;
348     titleNs1.index          = 0;
349     titleNs1.subspace       = NamespaceEntry::XMP;
350 
351     NamespaceEntry titleNs2;
352     titleNs2.namespaceName  = QLatin1String("Xmp.acdsee.caption");
353     titleNs2.nsType         = NamespaceEntry::TITLE;
354     titleNs2.specialOpts    = NamespaceEntry::COMMENT_XMP;
355     titleNs2.index          = 1;
356     titleNs2.subspace       = NamespaceEntry::XMP;
357 
358     NamespaceEntry titleNs3;
359     titleNs3.namespaceName  = QLatin1String("Iptc.Application2.ObjectName");
360     titleNs3.nsType         = NamespaceEntry::TITLE;
361     titleNs3.specialOpts    = NamespaceEntry::NO_OPTS;
362     titleNs3.index          = 2;
363     titleNs3.subspace       = NamespaceEntry::IPTC;
364 
365     getReadMapping(NamespaceEntry::DM_TITLE_CONTAINER()) << titleNs1
366                                                          << titleNs2
367                                                          << titleNs3;
368 
369     d->writeMappings[NamespaceEntry::DM_TITLE_CONTAINER()]
370         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_TITLE_CONTAINER()));
371 }
372 
defaultRatingValues()373 void DMetadataSettingsContainer::defaultRatingValues()
374 {
375     QList<int> defaultVal;
376     QList<int> microsoftMappings;
377     QList<int> iptcMappings;
378 
379     defaultVal        << 0 << 1 << 2  << 3  << 4  << 5;
380     microsoftMappings << 0 << 1 << 25 << 50 << 75 << 99;
381     iptcMappings      << 8 << 6 << 5  << 4  << 2  << 1;
382 
383     NamespaceEntry ratingNs1;
384     ratingNs1.namespaceName = QLatin1String("Xmp.xmp.Rating");
385     ratingNs1.convertRatio  = defaultVal;
386     ratingNs1.nsType        = NamespaceEntry::RATING;
387     ratingNs1.index         = 0;
388     ratingNs1.subspace      = NamespaceEntry::XMP;
389 
390     NamespaceEntry ratingNs2;
391     ratingNs2.namespaceName = QLatin1String("Xmp.acdsee.rating");
392     ratingNs2.convertRatio  = defaultVal;
393     ratingNs2.nsType        = NamespaceEntry::RATING;
394     ratingNs2.index         = 1;
395     ratingNs2.subspace      = NamespaceEntry::XMP;
396 
397     NamespaceEntry ratingNs3;
398     ratingNs3.namespaceName = QLatin1String("Xmp.MicrosoftPhoto.Rating");
399     ratingNs3.convertRatio  = microsoftMappings;
400     ratingNs3.nsType        = NamespaceEntry::RATING;
401     ratingNs3.index         = 2;
402     ratingNs3.subspace      = NamespaceEntry::XMP;
403 
404     NamespaceEntry ratingNs4;
405     ratingNs4.namespaceName = QLatin1String("Exif.Image.Rating");
406     ratingNs4.convertRatio  = defaultVal;
407     ratingNs4.nsType        = NamespaceEntry::RATING;
408     ratingNs4.index         = 3;
409     ratingNs4.subspace      = NamespaceEntry::EXIF;
410 
411     NamespaceEntry ratingNs5;
412     ratingNs5.namespaceName = QLatin1String("Exif.Image.RatingPercent");
413     ratingNs5.convertRatio  = microsoftMappings;
414     ratingNs5.nsType        = NamespaceEntry::RATING;
415     ratingNs5.index         = 4;
416     ratingNs5.subspace      = NamespaceEntry::EXIF;
417 
418     NamespaceEntry ratingNs6;
419     ratingNs6.namespaceName = QLatin1String("Iptc.Application2.Urgency");
420     ratingNs6.convertRatio  = iptcMappings;
421     ratingNs6.nsType        = NamespaceEntry::RATING;
422     ratingNs6.index         = 5;
423     ratingNs6.subspace      = NamespaceEntry::IPTC;
424 
425     getReadMapping(NamespaceEntry::DM_RATING_CONTAINER()) << ratingNs1
426                                                           << ratingNs2
427                                                           << ratingNs3
428                                                           << ratingNs4
429                                                           << ratingNs5
430                                                           << ratingNs6;
431 
432     d->writeMappings[NamespaceEntry::DM_RATING_CONTAINER()]
433         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_RATING_CONTAINER()));
434 }
435 
defaultCommentValues()436 void DMetadataSettingsContainer::defaultCommentValues()
437 {
438     NamespaceEntry commNs1;
439     commNs1.namespaceName   = QLatin1String("Xmp.dc.description");
440     commNs1.nsType          = NamespaceEntry::COMMENT;
441     commNs1.specialOpts     = NamespaceEntry::COMMENT_ATLLANGLIST;
442     commNs1.index           = 0;
443     commNs1.subspace        = NamespaceEntry::XMP;
444 
445     NamespaceEntry commNs2;
446     commNs2.namespaceName   = QLatin1String("Xmp.exif.UserComment");
447     commNs2.nsType          = NamespaceEntry::COMMENT;
448     commNs2.specialOpts     = NamespaceEntry::COMMENT_ALTLANG;
449     commNs2.index           = 1;
450     commNs2.subspace        = NamespaceEntry::XMP;
451 
452     NamespaceEntry commNs3;
453     commNs3.namespaceName   = QLatin1String("Xmp.tiff.ImageDescription");
454     commNs3.nsType          = NamespaceEntry::COMMENT;
455     commNs3.specialOpts     = NamespaceEntry::COMMENT_ALTLANG;
456     commNs3.index           = 2;
457     commNs3.subspace        = NamespaceEntry::XMP;
458 
459     NamespaceEntry commNs4;
460     commNs4.namespaceName   = QLatin1String("Xmp.acdsee.notes");
461     commNs4.nsType          = NamespaceEntry::COMMENT;
462     commNs4.specialOpts     = NamespaceEntry::COMMENT_XMP;
463     commNs4.index           = 3;
464     commNs4.subspace        = NamespaceEntry::XMP;
465 
466     NamespaceEntry commNs5;
467     commNs5.namespaceName   = QLatin1String("JPEG/TIFF Comments");
468     commNs5.nsType          = NamespaceEntry::COMMENT;
469     commNs5.specialOpts     = NamespaceEntry::COMMENT_JPEG;
470     commNs5.index           = 4;
471     commNs5.subspace        = NamespaceEntry::XMP;
472 
473     NamespaceEntry commNs6;
474     commNs6.namespaceName   = QLatin1String("Exif.Image.ImageDescription");
475     commNs6.nsType          = NamespaceEntry::COMMENT;
476     commNs6.specialOpts     = NamespaceEntry::NO_OPTS;
477     commNs6.index           = 5;
478     commNs6.alternativeName = QLatin1String("Exif.Photo.UserComment");
479     commNs6.subspace        = NamespaceEntry::EXIF;
480 
481     NamespaceEntry commNs7;
482     commNs7.namespaceName   = QLatin1String("Iptc.Application2.Caption");
483     commNs7.nsType          = NamespaceEntry::COMMENT;
484     commNs7.specialOpts     = NamespaceEntry::NO_OPTS;
485     commNs7.index           = 6;
486     commNs7.subspace        = NamespaceEntry::IPTC;
487 
488     getReadMapping(NamespaceEntry::DM_COMMENT_CONTAINER()) << commNs1
489                                                            << commNs2
490                                                            << commNs3
491                                                            << commNs4
492                                                            << commNs5
493                                                            << commNs6
494                                                            << commNs7;
495 
496     d->writeMappings[NamespaceEntry::DM_COMMENT_CONTAINER()]
497         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_COMMENT_CONTAINER()));
498 }
499 
defaultColorLabelValues()500 void DMetadataSettingsContainer::defaultColorLabelValues()
501 {
502     NamespaceEntry commNs1;
503     commNs1.namespaceName   = QLatin1String("Xmp.digiKam.ColorLabel");
504     commNs1.nsType          = NamespaceEntry::COLORLABEL;
505     commNs1.specialOpts     = NamespaceEntry::NO_OPTS;
506     commNs1.index           = 0;
507     commNs1.subspace        = NamespaceEntry::XMP;
508 
509     NamespaceEntry commNs2;
510     commNs2.namespaceName   = QLatin1String("Xmp.xmp.Label");
511     commNs2.nsType          = NamespaceEntry::COLORLABEL;
512     commNs2.specialOpts     = NamespaceEntry::NO_OPTS;
513     commNs2.index           = 1;
514     commNs2.subspace        = NamespaceEntry::XMP;
515 
516     NamespaceEntry commNs3;
517     commNs3.namespaceName   = QLatin1String("Xmp.photoshop.Urgency");
518     commNs3.nsType          = NamespaceEntry::COLORLABEL;
519     commNs3.specialOpts     = NamespaceEntry::NO_OPTS;
520     commNs3.index           = 2;
521     commNs3.subspace        = NamespaceEntry::XMP;
522 
523     getReadMapping(NamespaceEntry::DM_COLORLABEL_CONTAINER()) << commNs1
524                                                               << commNs2
525                                                               << commNs3;
526 
527     d->writeMappings[NamespaceEntry::DM_COLORLABEL_CONTAINER()]
528         = QList<NamespaceEntry>(getReadMapping(NamespaceEntry::DM_COLORLABEL_CONTAINER()));
529 }
530 
readOneGroup(KConfigGroup & group,const QString & name,QList<NamespaceEntry> & container)531 void DMetadataSettingsContainer::readOneGroup(KConfigGroup& group, const QString& name, QList<NamespaceEntry>& container)
532 {
533     KConfigGroup myItems = group.group(name);
534 
535     foreach (const QString& element, myItems.groupList())
536     {
537         KConfigGroup gr      = myItems.group(element);
538         NamespaceEntry ns;
539 
540         if (element.startsWith(QLatin1Char('#')))
541         {
542             ns.namespaceName = gr.readEntry("namespaceName");
543         }
544         else
545         {
546             ns.namespaceName = element;
547         }
548 
549         ns.tagPaths          = (NamespaceEntry::TagType)gr.readEntry("tagPaths").toInt();
550         ns.separator         = gr.readEntry("separator");
551         ns.nsType            = (NamespaceEntry::NamespaceType)gr.readEntry("nsType").toInt();
552         ns.index             = gr.readEntry("index").toInt();
553         ns.subspace          = (NamespaceEntry::NsSubspace)gr.readEntry("subspace").toInt();
554         ns.alternativeName   = gr.readEntry("alternativeName");
555         ns.specialOpts       = (NamespaceEntry::SpecialOptions)gr.readEntry("specialOpts").toInt();
556         ns.secondNameOpts    = (NamespaceEntry::SpecialOptions)gr.readEntry("secondNameOpts").toInt();
557         ns.isDefault         = gr.readEntry(QLatin1String("isDefault"), QVariant(true)).toBool();
558         ns.isDisabled        = gr.readEntry(QLatin1String("isDisabled"), QVariant(false)).toBool();
559         QStringList convList = gr.readEntry("convertRatio").split(QLatin1String(","));
560 
561         if (ns.nsType == NamespaceEntry::RATING)
562         {
563             if (convList.size() == 6)
564             {
565                 foreach (const QString& str, convList)
566                 {
567                     ns.convertRatio.append(str.toInt());
568                 }
569             }
570             else
571             {
572                 qCWarning(DIGIKAM_METAENGINE_LOG) << "Wrong count of rating conversion values in the config!";
573 
574                 // fallback to default rating conversion values
575 
576                 ns.convertRatio = QList<int>({0, 1, 2, 3, 4, 5});
577             }
578         }
579 
580         container.append(ns);
581     }
582 
583     std::sort(container.begin(), container.end(), Digikam::s_dmcompare);
584 }
585 
writeOneGroup(KConfigGroup & group,const QString & name,QList<NamespaceEntry> & container) const586 void DMetadataSettingsContainer::writeOneGroup(KConfigGroup& group, const QString& name, QList<NamespaceEntry>& container) const
587 {
588     KConfigGroup namespacesGroup = group.group(name);
589     int index                    = 0;
590 
591     foreach (const NamespaceEntry& e, container)
592     {
593         QString groupNumber = QString::fromLatin1("#%1")
594                               .arg(index++, 4, 10, QLatin1Char('0'));
595 
596         KConfigGroup tmp = namespacesGroup.group(groupNumber);
597         tmp.writeEntry("namespaceName",   e.namespaceName);
598         tmp.writeEntry("alternativeName", e.alternativeName);
599         tmp.writeEntry("subspace",        (int)e.subspace);
600         tmp.writeEntry("tagPaths",        (int)e.tagPaths);
601         tmp.writeEntry("separator",       e.separator);
602         tmp.writeEntry("nsType",          (int)e.nsType);
603         tmp.writeEntry("convertRatio",    e.convertRatio);
604         tmp.writeEntry("specialOpts",     (int)e.specialOpts);
605         tmp.writeEntry("secondNameOpts",  (int)e.secondNameOpts);
606         tmp.writeEntry("index",           e.index);
607         tmp.writeEntry("isDisabled",      e.isDisabled);
608         tmp.writeEntry("isDefault",       e.isDefault);
609     }
610 }
611 
operator <<(QDebug dbg,const DMetadataSettingsContainer & inf)612 QDebug operator<<(QDebug dbg, const DMetadataSettingsContainer& inf)
613 {
614     dbg.nospace() << "[DMetadataSettingsContainer] readMappings(";
615 
616     foreach (const QString& str, inf.mappingKeys())
617     {
618         dbg.nospace() << inf.getReadMapping(str) << "), ";
619     }
620 
621     dbg.nospace() << "writeMappings(";
622 
623     foreach (const QString& str, inf.mappingKeys())
624     {
625         dbg.nospace() << inf.getWriteMapping(str) << "), ";
626     }
627 
628     dbg.nospace() << "unifyReadWrite("
629                   << inf.unifyReadWrite() << ")";
630 
631     return dbg.space();
632 }
633 
634 } // namespace Digikam
635