1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2015-08-17
7  * Description : Helper class for Image Description Editor Tab
8  *
9  * Copyright (C) 2015 by Veaceslav Munteanu <veaceslav dot munteanu90 at gmail dot com>
10  *
11  * This program is free software; you can redistribute it
12  * and/or modify it under the terms of the GNU General
13  * Public License as published by the Free Software Foundation;
14  * either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * ============================================================ */
23 
24 #include "disjointmetadata_p.h"
25 
26 namespace Digikam
27 {
28 
DisjointMetadata()29 DisjointMetadata::DisjointMetadata()
30     : QObject(),
31       d      (new Private())
32 {
33     d->makeConnections(this);
34 }
35 
DisjointMetadata(const DisjointMetadata & other)36 DisjointMetadata::DisjointMetadata(const DisjointMetadata& other)
37     : QObject(other.parent()),
38       d      (new Private(*other.d))
39 {
40     d->makeConnections(this);
41 }
42 
~DisjointMetadata()43 DisjointMetadata::~DisjointMetadata()
44 {
45     delete d;
46 }
47 
operator =(const DisjointMetadata & other)48 DisjointMetadata& DisjointMetadata::operator=(const DisjointMetadata& other)
49 {
50     if (this != &other)
51     {
52         delete d;
53         d = new Private(*other.d);
54     }
55 
56     return *this;
57 }
58 
reset()59 void DisjointMetadata::reset()
60 {
61     delete d;
62     d = new Private();
63 }
64 
load(const ItemInfo & info)65 void DisjointMetadata::load(const ItemInfo& info)
66 {
67     Template metadataTemplate;
68     CaptionsMap commentMap;
69     CaptionsMap titleMap;
70     QDateTime dateTime;
71     int colorLabel;
72     int pickLabel;
73     int rating;
74 
75     if (d->dateTimeStatus == DisjointMetadataDataFields::MetadataDisjoint)
76     {
77         dateTime = d->dateTime;
78     }
79     else
80     {
81         dateTime = info.dateTime();
82     }
83 
84     if ((d->titlesStatus   == DisjointMetadataDataFields::MetadataDisjoint) &&
85         (d->commentsStatus == DisjointMetadataDataFields::MetadataDisjoint))
86     {
87         commentMap = d->comments;
88         titleMap   = d->titles;
89     }
90     else
91     {
92         CoreDbAccess access;
93         ItemComments comments = info.imageComments(access);
94         commentMap            = comments.toCaptionsMap();
95         titleMap              = comments.toCaptionsMap(DatabaseComment::Title);
96     }
97 
98     if (d->colorLabelStatus == DisjointMetadataDataFields::MetadataDisjoint)
99     {
100         colorLabel = d->colorLabel;
101     }
102     else
103     {
104         colorLabel = info.colorLabel();
105     }
106 
107     if (d->pickLabelStatus == DisjointMetadataDataFields::MetadataDisjoint)
108     {
109         pickLabel = d->pickLabel;
110     }
111     else
112     {
113         pickLabel = info.pickLabel();
114     }
115 
116     if (d->ratingStatus == DisjointMetadataDataFields::MetadataDisjoint)
117     {
118         rating = d->rating;
119     }
120     else
121     {
122         rating = info.rating();
123     }
124 
125     if (d->templateStatus == DisjointMetadataDataFields::MetadataDisjoint)
126     {
127         metadataTemplate = d->metadataTemplate;
128     }
129     else
130     {
131         Template tref    = info.metadataTemplate();
132         Template t       = TemplateManager::defaultManager()->findByContents(tref);
133 /*
134         qCDebug(DIGIKAM_GENERAL_LOG) << "Found Metadata Template: " << t.templateTitle();
135 */
136         metadataTemplate = t.isNull() ? tref : t;
137     }
138 
139     load(dateTime,
140          titleMap,
141          commentMap,
142          colorLabel,
143          pickLabel,
144          rating,
145          metadataTemplate);
146 
147     loadTags(info.tagIds());
148 }
149 
150 //-----------------------------Status -------------------------
151 
dateTimeStatus() const152 DisjointMetadataDataFields::Status DisjointMetadata::dateTimeStatus() const
153 {
154     return d->dateTimeStatus;
155 }
156 
titlesStatus() const157 DisjointMetadataDataFields::Status DisjointMetadata::titlesStatus() const
158 {
159     return d->titlesStatus;
160 }
161 
commentsStatus() const162 DisjointMetadataDataFields::Status DisjointMetadata::commentsStatus() const
163 {
164     return d->commentsStatus;
165 }
166 
pickLabelStatus() const167 DisjointMetadataDataFields::Status DisjointMetadata::pickLabelStatus() const
168 {
169     return d->pickLabelStatus;
170 }
171 
colorLabelStatus() const172 DisjointMetadataDataFields::Status DisjointMetadata::colorLabelStatus() const
173 {
174     return d->colorLabelStatus;
175 }
176 
ratingStatus() const177 DisjointMetadataDataFields::Status DisjointMetadata::ratingStatus() const
178 {
179     return d->ratingStatus;
180 }
181 
templateStatus() const182 DisjointMetadataDataFields::Status DisjointMetadata::templateStatus() const
183 {
184     return d->templateStatus;
185 }
186 
tagStatus(int albumId) const187 DisjointMetadataDataFields::Status DisjointMetadata::tagStatus(int albumId) const
188 {
189     return d->tags.value(albumId, DisjointMetadataDataFields::DisjointMetadataDataFields::MetadataInvalid);
190 }
191 
tagStatus(const QString & tagPath) const192 DisjointMetadataDataFields::Status DisjointMetadata::tagStatus(const QString& tagPath) const
193 {
194     return tagStatus(TagsCache::instance()->tagForPath(tagPath));
195 }
196 
197 //---- Changed status ---------------------
198 
dateTimeChanged() const199 bool DisjointMetadata::dateTimeChanged() const
200 {
201     return d->dateTimeChanged;
202 }
203 
titlesChanged() const204 bool DisjointMetadata::titlesChanged() const
205 {
206     return d->titlesChanged;
207 }
208 
commentsChanged() const209 bool DisjointMetadata::commentsChanged() const
210 {
211     return d->commentsChanged;
212 }
213 
pickLabelChanged() const214 bool DisjointMetadata::pickLabelChanged() const
215 {
216     return d->pickLabelChanged;
217 }
218 
colorLabelChanged() const219 bool DisjointMetadata::colorLabelChanged() const
220 {
221     return d->colorLabelChanged;
222 }
223 
ratingChanged() const224 bool DisjointMetadata::ratingChanged() const
225 {
226     return d->ratingChanged;
227 }
228 
templateChanged() const229 bool DisjointMetadata::templateChanged() const
230 {
231     return d->templateChanged;
232 }
233 
tagsChanged() const234 bool DisjointMetadata::tagsChanged() const
235 {
236     return d->tagsChanged;
237 }
238 
setDateTime(const QDateTime & dateTime,DisjointMetadataDataFields::Status status)239 void DisjointMetadata::setDateTime(const QDateTime& dateTime, DisjointMetadataDataFields::Status status)
240 {
241     d->dateTimeStatus  = status;
242     d->dateTime        = dateTime;
243     d->dateTimeChanged = true;
244 }
245 
setTitles(const CaptionsMap & titles,DisjointMetadataDataFields::Status status)246 void DisjointMetadata::setTitles(const CaptionsMap& titles, DisjointMetadataDataFields::Status status)
247 {
248     d->titlesStatus  = status;
249     d->titles        = titles;
250     d->titlesChanged = true;
251 }
252 
setComments(const CaptionsMap & comments,DisjointMetadataDataFields::Status status)253 void DisjointMetadata::setComments(const CaptionsMap& comments, DisjointMetadataDataFields::Status status)
254 {
255     d->commentsStatus  = status;
256     d->comments        = comments;
257     d->commentsChanged = true;
258 }
259 
setPickLabel(int pickId,DisjointMetadataDataFields::Status status)260 void DisjointMetadata::setPickLabel(int pickId, DisjointMetadataDataFields::Status status)
261 {
262     d->pickLabelStatus  = status;
263     d->pickLabel        = pickId;
264     d->pickLabelChanged = true;
265 }
266 
setColorLabel(int colorId,DisjointMetadataDataFields::Status status)267 void DisjointMetadata::setColorLabel(int colorId, DisjointMetadataDataFields::Status status)
268 {
269     d->colorLabelStatus  = status;
270     d->colorLabel        = colorId;
271     d->colorLabelChanged = true;
272 }
273 
setRating(int rating,DisjointMetadataDataFields::Status status)274 void DisjointMetadata::setRating(int rating, DisjointMetadataDataFields::Status status)
275 {
276     d->ratingStatus   = status;
277     d->rating         = rating;
278     d->ratingChanged  = true;
279 }
280 
setMetadataTemplate(const Template & t,DisjointMetadataDataFields::Status status)281 void DisjointMetadata::setMetadataTemplate(const Template& t, DisjointMetadataDataFields::Status status)
282 {
283     d->templateStatus   = status;
284     d->metadataTemplate = t;
285     d->templateChanged  = true;
286 }
287 
setTag(int albumID,DisjointMetadataDataFields::Status status)288 void DisjointMetadata::setTag(int albumID, DisjointMetadataDataFields::Status status)
289 {
290     d->tags[albumID] = status;
291     d->tagsChanged   = true;
292 }
293 
resetChanged()294 void DisjointMetadata::resetChanged()
295 {
296     d->dateTimeChanged   = false;
297     d->titlesChanged     = false;
298     d->commentsChanged   = false;
299     d->pickLabelChanged  = false;
300     d->colorLabelChanged = false;
301     d->ratingChanged     = false;
302     d->templateChanged   = false;
303     d->tagsChanged       = false;
304 }
305 
write(ItemInfo info,WriteMode writeMode)306 bool DisjointMetadata::write(ItemInfo info, WriteMode writeMode)
307 {
308     applyChangeNotifications();
309 
310     bool changed        = false;
311 
312     // find out in advance if we have something to write - needed for FullWriteIfChanged mode
313 
314     bool saveTitle      = (d->titlesStatus     == DisjointMetadataDataFields::MetadataAvailable);
315     bool saveComment    = (d->commentsStatus   == DisjointMetadataDataFields::MetadataAvailable);
316     bool saveDateTime   = (d->dateTimeStatus   == DisjointMetadataDataFields::MetadataAvailable);
317     bool savePickLabel  = (d->pickLabelStatus  == DisjointMetadataDataFields::MetadataAvailable);
318     bool saveColorLabel = (d->colorLabelStatus == DisjointMetadataDataFields::MetadataAvailable);
319     bool saveRating     = (d->ratingStatus     == DisjointMetadataDataFields::MetadataAvailable);
320     bool saveTemplate   = (d->templateStatus   == DisjointMetadataDataFields::MetadataAvailable);
321     bool saveTags       = true;
322 
323     bool writeAllFields;
324 
325     if      (writeMode == FullWrite)
326     {
327         writeAllFields = true;
328     }
329     else if (writeMode == FullWriteIfChanged)
330     {
331         writeAllFields = (
332                              (saveTitle      && d->titlesChanged)     ||
333                              (saveComment    && d->commentsChanged)   ||
334                              (saveDateTime   && d->dateTimeChanged)   ||
335                              (savePickLabel  && d->pickLabelChanged)  ||
336                              (saveColorLabel && d->colorLabelChanged) ||
337                              (saveRating     && d->ratingChanged)     ||
338                              (saveTemplate   && d->templateChanged)   ||
339                              (saveTags       && d->tagsChanged)
340                          );
341     }
342     else // PartialWrite
343     {
344         writeAllFields = false;
345     }
346 
347     if (saveTitle && (writeAllFields || d->titlesChanged))
348     {
349         CoreDbAccess access;
350         ItemComments comments = info.imageComments(access);
351         comments.replaceComments(d->titles, DatabaseComment::Title);
352         changed               = true;
353     }
354 
355     if (saveComment && (writeAllFields || d->commentsChanged))
356     {
357         CoreDbAccess access;
358         ItemComments comments = info.imageComments(access);
359         comments.replaceComments(d->comments);
360         changed               = true;
361     }
362 
363     if (saveDateTime && (writeAllFields || d->dateTimeChanged))
364     {
365         info.setDateTime(d->dateTime);
366         changed = true;
367     }
368 
369     if (savePickLabel && (writeAllFields || d->pickLabelChanged))
370     {
371         info.setPickLabel(d->pickLabel);
372         changed = true;
373     }
374 
375     if (saveColorLabel && (writeAllFields || d->colorLabelChanged))
376     {
377         info.setColorLabel(d->colorLabel);
378         changed = true;
379     }
380 
381     if (saveRating && (writeAllFields || d->ratingChanged))
382     {
383         info.setRating(d->rating);
384         changed = true;
385     }
386 
387     if (saveTemplate && writeAllFields)
388     {
389         QString title = d->metadataTemplate.templateTitle();
390 
391         if (title == Template::removeTemplateTitle())
392         {
393             info.removeMetadataTemplate();
394         }
395 
396         if (title.isEmpty())
397         {
398             // Nothing to do.
399         }
400         else
401         {
402             info.setMetadataTemplate(d->metadataTemplate);
403         }
404 
405         changed = true;
406     }
407 
408     if (writeAllFields || d->tagsChanged)
409     {
410         QList<int> keys = d->tags.keys();
411 
412         foreach (int key, keys)
413         {
414             if (d->tags.value(key) == DisjointMetadataDataFields::DisjointMetadataDataFields::MetadataAvailable)
415             {
416                 info.setTag(key);
417                 changed = true;
418             }
419 
420             if (d->tags.value(key) == DisjointMetadataDataFields::DisjointMetadataDataFields::MetadataInvalid)
421             {
422                 info.removeTag(key);
423                 changed = true;
424             }
425         }
426     }
427 
428     return changed;
429 }
430 
willWriteMetadata(DisjointMetadata::WriteMode writeMode,const MetaEngineSettingsContainer & settings) const431 bool DisjointMetadata::willWriteMetadata(DisjointMetadata::WriteMode writeMode,
432                                          const MetaEngineSettingsContainer& settings) const
433 {
434     // This is the same logic as in write(DMetadata) but without actually writing.
435     // Adapt if the method above changes
436 
437     bool saveTitle      = (settings.saveComments   && (d->titlesStatus     == DisjointMetadataDataFields::MetadataAvailable));
438     bool saveComment    = (settings.saveComments   && (d->commentsStatus   == DisjointMetadataDataFields::MetadataAvailable));
439     bool saveDateTime   = (settings.saveDateTime   && (d->dateTimeStatus   == DisjointMetadataDataFields::MetadataAvailable));
440     bool savePickLabel  = (settings.savePickLabel  && (d->pickLabelStatus  == DisjointMetadataDataFields::MetadataAvailable));
441     bool saveColorLabel = (settings.saveColorLabel && (d->colorLabelStatus == DisjointMetadataDataFields::MetadataAvailable));
442     bool saveRating     = (settings.saveRating     && (d->ratingStatus     == DisjointMetadataDataFields::MetadataAvailable));
443     bool saveTemplate   = (settings.saveTemplate   && (d->templateStatus   == DisjointMetadataDataFields::MetadataAvailable));
444     bool saveTags       = (settings.saveTags || settings.saveFaceTags);
445 
446     bool writeAllFields;
447 
448     if      (writeMode == FullWrite)
449     {
450         writeAllFields = true;
451     }
452     else if (writeMode == FullWriteIfChanged)
453     {
454         writeAllFields = (
455                              (saveTitle      && d->titlesChanged)     ||
456                              (saveComment    && d->commentsChanged)   ||
457                              (saveDateTime   && d->dateTimeChanged)   ||
458                              (savePickLabel  && d->pickLabelChanged)  ||
459                              (saveColorLabel && d->colorLabelChanged) ||
460                              (saveRating     && d->ratingChanged)     ||
461                              (saveTemplate   && d->templateChanged)   ||
462                              (saveTags       && d->tagsChanged)
463                          );
464     }
465     else // PartialWrite
466     {
467         writeAllFields = false;
468     }
469 
470     return (
471                (saveTitle      && (writeAllFields || d->titlesChanged))     ||
472                (saveComment    && (writeAllFields || d->commentsChanged))   ||
473                (saveDateTime   && (writeAllFields || d->dateTimeChanged))   ||
474                (savePickLabel  && (writeAllFields || d->pickLabelChanged))  ||
475                (saveColorLabel && (writeAllFields || d->colorLabelChanged)) ||
476                (saveRating     && (writeAllFields || d->ratingChanged))     ||
477                (saveTags       && (writeAllFields || d->tagsChanged))       ||
478                (saveTemplate   && (writeAllFields || d->templateChanged))
479            );
480 }
481 
changedFlags()482 int DisjointMetadata::changedFlags()
483 {
484     int value = 0;
485 
486     if (d->titlesChanged)
487     {
488         value |= MetadataHub::WRITE_TITLE;
489     }
490 
491     if (d->commentsChanged)
492     {
493         value |= MetadataHub::WRITE_COMMENTS;
494     }
495 
496     if (d->dateTimeChanged)
497     {
498         value |= MetadataHub::WRITE_DATETIME;
499     }
500 
501     if (d->pickLabelChanged)
502     {
503         value |= MetadataHub::WRITE_PICKLABEL;
504     }
505 
506     if (d->colorLabelChanged)
507     {
508         value |= MetadataHub::WRITE_COLORLABEL;
509     }
510 
511     if (d->ratingChanged)
512     {
513         value |= MetadataHub::WRITE_RATING;
514     }
515 
516     if (d->tagsChanged)
517     {
518         value |= MetadataHub::WRITE_TAGS;
519     }
520 
521     if (d->templateChanged)
522     {
523         value |= MetadataHub::WRITE_TEMPLATE;
524     }
525 
526     return value;
527 }
528 
load(const QDateTime & dateTime,const CaptionsMap & titles,const CaptionsMap & comment,int colorLabel,int pickLabel,int rating,const Template & t)529 void DisjointMetadata::load(const QDateTime& dateTime,const CaptionsMap& titles,
530                             const CaptionsMap& comment, int colorLabel,
531                             int pickLabel, int rating, const Template& t)
532 {
533     if (dateTime.isValid())
534     {
535         d->loadSingleValue<QDateTime>(dateTime, d->dateTime, d->dateTimeStatus);
536     }
537 
538     d->loadSingleValue<int>(pickLabel, d->pickLabel, d->pickLabelStatus);
539 
540     d->loadSingleValue<int>(colorLabel, d->colorLabel, d->colorLabelStatus);
541 
542     d->loadSingleValue<int>(rating, d->rating, d->ratingStatus);
543 
544     d->loadSingleValue<CaptionsMap>(titles, d->titles, d->titlesStatus);
545 
546     d->loadSingleValue<CaptionsMap>(comment, d->comments, d->commentsStatus);
547 
548     d->loadSingleValue<Template>(t, d->metadataTemplate, d->templateStatus);
549 }
550 
loadTags(const QList<int> & tagIds)551 void DisjointMetadata::loadTags(const QList<int>& tagIds)
552 {
553     QList<int> loadedTagIds;
554 
555     foreach (int tagId, tagIds)
556     {
557         if (!TagsCache::instance()->isInternalTag(tagId))
558         {
559             loadedTagIds << tagId;
560         }
561     }
562 
563     if (loadedTagIds.isEmpty())
564     {
565         if (!d->withoutTags)
566         {
567             QMap<int, DisjointMetadataDataFields::Status>::iterator it;
568 
569             for (it = d->tags.begin() ; it != d->tags.end() ; ++it)
570             {
571                 it.value() = DisjointMetadataDataFields::MetadataDisjoint;
572             }
573 
574             d->withoutTags = true;
575         }
576 
577         return;
578     }
579 
580     // If tags map is empty, set them all as Available
581 
582     if (d->tags.isEmpty())
583     {
584         foreach (int tagId, loadedTagIds)
585         {
586             if (d->withoutTags)
587             {
588                 d->tags[tagId] = DisjointMetadataDataFields::MetadataDisjoint;
589             }
590             else
591             {
592                 d->tags[tagId] = DisjointMetadataDataFields::MetadataAvailable;
593             }
594         }
595 
596         return;
597     }
598 
599     std::sort(loadedTagIds.begin(), loadedTagIds.end());
600 
601     // We search for metadata available tags, and
602     // it is not present in current list, set it to
603     // disjoint
604 
605     QMap<int, DisjointMetadataDataFields::Status>::iterator it;
606 
607     for (it = d->tags.begin() ; it != d->tags.end() ; ++it)
608     {
609         if (it.value() == DisjointMetadataDataFields::MetadataAvailable)
610         {
611             if (!std::binary_search(loadedTagIds.begin(), loadedTagIds.end(), it.key()))
612             {
613                 it.value() = DisjointMetadataDataFields::MetadataDisjoint;
614             }
615         }
616     }
617 
618     // new tags which are not yet in the set,
619     // are added as Disjoint
620 
621     foreach (int tagId, loadedTagIds)
622     {
623         if (!d->tags.contains(tagId))
624         {
625             d->tags[tagId] = DisjointMetadataDataFields::MetadataDisjoint;
626         }
627     }
628 }
629 
notifyTagDeleted(int id)630 void DisjointMetadata::notifyTagDeleted(int id)
631 {
632     d->tags.remove(id);
633 }
634 
slotTagDeleted(int tagId)635 void DisjointMetadata::slotTagDeleted(int tagId)
636 {
637     QMutexLocker locker(&d->mutex);
638     d->tagIds << tagId;
639 }
640 
slotInvalidate()641 void DisjointMetadata::slotInvalidate()
642 {
643     QMutexLocker locker(&d->mutex);
644     d->invalid = true;
645 }
646 
applyChangeNotifications()647 void DisjointMetadata::applyChangeNotifications()
648 {
649     if (d->invalid)
650     {
651         reset();
652     }
653 
654     QList<int> tagIds;
655     {
656         QMutexLocker locker(&d->mutex);
657         tagIds = d->tagIds;
658         d->tagIds.clear();
659     }
660 
661     foreach (int tagId, tagIds)
662     {
663         notifyTagDeleted(tagId);
664     }
665 }
666 
dateTime() const667 QDateTime DisjointMetadata::dateTime() const
668 {
669     return d->dateTime;
670 }
671 
titles() const672 CaptionsMap DisjointMetadata::titles() const
673 {
674     return d->titles;
675 }
676 
comments() const677 CaptionsMap DisjointMetadata::comments() const
678 {
679     return d->comments;
680 }
681 
pickLabel() const682 int DisjointMetadata::pickLabel() const
683 {
684     return d->pickLabel;
685 }
686 
colorLabel() const687 int DisjointMetadata::colorLabel() const
688 {
689     return d->colorLabel;
690 }
691 
rating() const692 int DisjointMetadata::rating() const
693 {
694     return d->rating;
695 }
696 
metadataTemplate() const697 Template DisjointMetadata::metadataTemplate() const
698 {
699     return d->metadataTemplate;
700 }
701 
dateTimeInterval(QDateTime & lowest,QDateTime & highest) const702 void DisjointMetadata::dateTimeInterval(QDateTime& lowest, QDateTime& highest) const
703 {
704     switch (d->dateTimeStatus)
705     {
706         case DisjointMetadataDataFields::MetadataInvalid:
707         {
708             lowest  = QDateTime();
709             highest = QDateTime();
710             break;
711         }
712 
713         case DisjointMetadataDataFields::MetadataAvailable:
714         {
715             lowest  = d->dateTime;
716             highest = d->dateTime;
717             break;
718         }
719 
720         case DisjointMetadataDataFields::MetadataDisjoint:
721         {
722             lowest  = d->dateTime;
723             highest = d->lastDateTime;
724             break;
725         }
726     }
727 }
728 
pickLabelInterval(int & lowest,int & highest) const729 void DisjointMetadata::pickLabelInterval(int& lowest, int& highest) const
730 {
731     switch (d->pickLabelStatus)
732     {
733         case DisjointMetadataDataFields::MetadataInvalid:
734         {
735             lowest  = -1;
736             highest = -1;
737             break;
738         }
739 
740         case DisjointMetadataDataFields::MetadataAvailable:
741         {
742             lowest  = d->pickLabel;
743             highest = d->pickLabel;
744             break;
745         }
746 
747         case DisjointMetadataDataFields::MetadataDisjoint:
748         {
749             lowest  = d->pickLabel;
750             highest = d->highestPickLabel;
751             break;
752         }
753     }
754 }
755 
colorLabelInterval(int & lowest,int & highest) const756 void DisjointMetadata::colorLabelInterval(int& lowest, int& highest) const
757 {
758     switch (d->colorLabelStatus)
759     {
760         case DisjointMetadataDataFields::MetadataInvalid:
761         {
762             lowest  = -1;
763             highest = -1;
764             break;
765         }
766 
767         case DisjointMetadataDataFields::MetadataAvailable:
768         {
769             lowest  = d->colorLabel;
770             highest = d->colorLabel;
771             break;
772         }
773 
774         case DisjointMetadataDataFields::MetadataDisjoint:
775         {
776             lowest  = d->colorLabel;
777             highest = d->highestColorLabel;
778             break;
779         }
780     }
781 }
782 
ratingInterval(int & lowest,int & highest) const783 void DisjointMetadata::ratingInterval(int& lowest, int& highest) const
784 {
785     switch (d->ratingStatus)
786     {
787         case DisjointMetadataDataFields::MetadataInvalid:
788         {
789             lowest  = -1;
790             highest = -1;
791             break;
792         }
793 
794         case DisjointMetadataDataFields::MetadataAvailable:
795         {
796             lowest  = d->rating;
797             highest = d->rating;
798             break;
799         }
800 
801         case DisjointMetadataDataFields::MetadataDisjoint:
802         {
803             lowest  = d->rating;
804             highest = d->highestRating;
805             break;
806         }
807     }
808 }
809 
keywords() const810 QStringList DisjointMetadata::keywords() const
811 {
812     QStringList tagList;
813 
814     QList<int> keys = d->tags.keys();
815 
816     foreach (int key, keys)
817     {
818         if (d->tags.value(key) == DisjointMetadataDataFields::MetadataAvailable)
819         {
820             tagList.append(TagsCache::instance()->tagPath(key, TagsCache::NoLeadingSlash));
821         }
822     }
823 
824     return tagList;
825 }
826 
tags() const827 QMap<int, DisjointMetadataDataFields::Status> DisjointMetadata::tags() const
828 {
829     // DatabaseMode == ManagedTags is assumed
830 
831     return d->tags;
832 }
833 
dataFields() const834 DisjointMetadataDataFields DisjointMetadata::dataFields() const
835 {
836     DisjointMetadataDataFields data(*d);
837 
838     return data;
839 }
840 
setDataFields(const DisjointMetadataDataFields & data)841 void DisjointMetadata::setDataFields(const DisjointMetadataDataFields& data)
842 {
843     if (d)
844     {
845         delete d;
846     }
847 
848     d = new Private(data);
849     d->makeConnections(this);
850 }
851 
852 } // namespace Digikam
853