File indexing completed on 2025-04-27 03:57:25

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2015-08-17
0007  * Description : Helper class for Image Description Editor Tab
0008  *
0009  * SPDX-FileCopyrightText: 2015 by Veaceslav Munteanu <veaceslav dot munteanu90 at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "disjointmetadata_p.h"
0016 
0017 namespace Digikam
0018 {
0019 
0020 DisjointMetadata::DisjointMetadata()
0021     : QObject(),
0022       d      (new Private())
0023 {
0024     d->makeConnections(this);
0025 }
0026 
0027 DisjointMetadata::DisjointMetadata(const DisjointMetadata& other)
0028     : QObject(other.parent()),
0029       d      (new Private(*other.d))
0030 {
0031     d->makeConnections(this);
0032 }
0033 
0034 DisjointMetadata::~DisjointMetadata()
0035 {
0036     delete d;
0037 }
0038 
0039 DisjointMetadata& DisjointMetadata::operator=(const DisjointMetadata& other)
0040 {
0041     if (this != &other)
0042     {
0043         delete d;
0044         d = new Private(*other.d);
0045     }
0046 
0047     return *this;
0048 }
0049 
0050 void DisjointMetadata::reset()
0051 {
0052     delete d;
0053     d = new Private();
0054 }
0055 
0056 void DisjointMetadata::load(const ItemInfo& info)
0057 {
0058     Template metadataTemplate;
0059     CaptionsMap commentMap;
0060     CaptionsMap titleMap;
0061     QDateTime dateTime;
0062     int colorLabel;
0063     int pickLabel;
0064     int rating;
0065 
0066     if (d->dateTimeStatus == DisjointMetadataDataFields::MetadataDisjoint)
0067     {
0068         dateTime = d->dateTime;
0069     }
0070     else
0071     {
0072         dateTime = info.dateTime();
0073     }
0074 
0075     if ((d->titlesStatus   == DisjointMetadataDataFields::MetadataDisjoint) &&
0076         (d->commentsStatus == DisjointMetadataDataFields::MetadataDisjoint))
0077     {
0078         commentMap = d->comments;
0079         titleMap   = d->titles;
0080     }
0081     else
0082     {
0083         CoreDbAccess access;
0084         ItemComments comments = info.imageComments(access);
0085         commentMap            = comments.toCaptionsMap();
0086         titleMap              = comments.toCaptionsMap(DatabaseComment::Title);
0087     }
0088 
0089     if (d->colorLabelStatus == DisjointMetadataDataFields::MetadataDisjoint)
0090     {
0091         colorLabel = d->colorLabel;
0092     }
0093     else
0094     {
0095         colorLabel = info.colorLabel();
0096     }
0097 
0098     if (d->pickLabelStatus == DisjointMetadataDataFields::MetadataDisjoint)
0099     {
0100         pickLabel = d->pickLabel;
0101     }
0102     else
0103     {
0104         pickLabel = info.pickLabel();
0105     }
0106 
0107     if (d->ratingStatus == DisjointMetadataDataFields::MetadataDisjoint)
0108     {
0109         rating = d->rating;
0110     }
0111     else
0112     {
0113         rating = info.rating();
0114     }
0115 
0116     if (d->templateStatus == DisjointMetadataDataFields::MetadataDisjoint)
0117     {
0118         metadataTemplate = d->metadataTemplate;
0119     }
0120     else
0121     {
0122         Template tref    = info.metadataTemplate();
0123         Template t       = TemplateManager::defaultManager()->findByContents(tref);
0124 /*
0125         qCDebug(DIGIKAM_GENERAL_LOG) << "Found Metadata Template:" << t.templateTitle();
0126 */
0127         metadataTemplate = t.isNull() ? tref : t;
0128     }
0129 
0130     load(dateTime,
0131          titleMap,
0132          commentMap,
0133          colorLabel,
0134          pickLabel,
0135          rating,
0136          metadataTemplate);
0137 
0138     loadTags(info.tagIds());
0139 }
0140 
0141 //-----------------------------Status -------------------------
0142 
0143 DisjointMetadataDataFields::Status DisjointMetadata::dateTimeStatus() const
0144 {
0145     return d->dateTimeStatus;
0146 }
0147 
0148 DisjointMetadataDataFields::Status DisjointMetadata::titlesStatus() const
0149 {
0150     return d->titlesStatus;
0151 }
0152 
0153 DisjointMetadataDataFields::Status DisjointMetadata::commentsStatus() const
0154 {
0155     return d->commentsStatus;
0156 }
0157 
0158 DisjointMetadataDataFields::Status DisjointMetadata::pickLabelStatus() const
0159 {
0160     return d->pickLabelStatus;
0161 }
0162 
0163 DisjointMetadataDataFields::Status DisjointMetadata::colorLabelStatus() const
0164 {
0165     return d->colorLabelStatus;
0166 }
0167 
0168 DisjointMetadataDataFields::Status DisjointMetadata::ratingStatus() const
0169 {
0170     return d->ratingStatus;
0171 }
0172 
0173 DisjointMetadataDataFields::Status DisjointMetadata::templateStatus() const
0174 {
0175     return d->templateStatus;
0176 }
0177 
0178 DisjointMetadataDataFields::Status DisjointMetadata::tagStatus(int albumId) const
0179 {
0180     return d->tags.value(albumId, DisjointMetadataDataFields::DisjointMetadataDataFields::MetadataInvalid);
0181 }
0182 
0183 DisjointMetadataDataFields::Status DisjointMetadata::tagStatus(const QString& tagPath) const
0184 {
0185     return tagStatus(TagsCache::instance()->tagForPath(tagPath));
0186 }
0187 
0188 //---- Changed status ---------------------
0189 
0190 bool DisjointMetadata::dateTimeChanged() const
0191 {
0192     return d->dateTimeChanged;
0193 }
0194 
0195 bool DisjointMetadata::titlesChanged() const
0196 {
0197     return d->titlesChanged;
0198 }
0199 
0200 bool DisjointMetadata::commentsChanged() const
0201 {
0202     return d->commentsChanged;
0203 }
0204 
0205 bool DisjointMetadata::pickLabelChanged() const
0206 {
0207     return d->pickLabelChanged;
0208 }
0209 
0210 bool DisjointMetadata::colorLabelChanged() const
0211 {
0212     return d->colorLabelChanged;
0213 }
0214 
0215 bool DisjointMetadata::ratingChanged() const
0216 {
0217     return d->ratingChanged;
0218 }
0219 
0220 bool DisjointMetadata::templateChanged() const
0221 {
0222     return d->templateChanged;
0223 }
0224 
0225 bool DisjointMetadata::tagsChanged() const
0226 {
0227     return d->tagsChanged;
0228 }
0229 
0230 void DisjointMetadata::setDateTime(const QDateTime& dateTime, DisjointMetadataDataFields::Status status)
0231 {
0232     d->dateTimeStatus  = status;
0233     d->dateTime        = dateTime;
0234     d->dateTimeChanged = true;
0235 }
0236 
0237 void DisjointMetadata::setTitles(const CaptionsMap& titles, DisjointMetadataDataFields::Status status)
0238 {
0239     d->titlesStatus  = status;
0240     d->titles        = titles;
0241     d->titlesChanged = true;
0242 }
0243 
0244 void DisjointMetadata::setComments(const CaptionsMap& comments, DisjointMetadataDataFields::Status status)
0245 {
0246     d->commentsStatus  = status;
0247     d->comments        = comments;
0248     d->commentsChanged = true;
0249 }
0250 
0251 void DisjointMetadata::setPickLabel(int pickId, DisjointMetadataDataFields::Status status)
0252 {
0253     d->pickLabelStatus  = status;
0254     d->pickLabel        = pickId;
0255     d->pickLabelChanged = true;
0256 }
0257 
0258 void DisjointMetadata::setColorLabel(int colorId, DisjointMetadataDataFields::Status status)
0259 {
0260     d->colorLabelStatus  = status;
0261     d->colorLabel        = colorId;
0262     d->colorLabelChanged = true;
0263 }
0264 
0265 void DisjointMetadata::setRating(int rating, DisjointMetadataDataFields::Status status)
0266 {
0267     d->ratingStatus   = status;
0268     d->rating         = rating;
0269     d->ratingChanged  = true;
0270 }
0271 
0272 void DisjointMetadata::setMetadataTemplate(const Template& t, DisjointMetadataDataFields::Status status)
0273 {
0274     d->templateStatus   = status;
0275     d->metadataTemplate = t;
0276     d->templateChanged  = true;
0277 }
0278 
0279 void DisjointMetadata::setTag(int albumID, DisjointMetadataDataFields::Status status)
0280 {
0281     d->tags[albumID] = status;
0282     d->tagsChanged   = true;
0283 }
0284 
0285 void DisjointMetadata::replaceColorLabel(int colorId)
0286 {
0287     d->colorLabelStatus  = DisjointMetadataDataFields::MetadataAvailable;
0288     d->colorLabel        = colorId;
0289     d->colorLabelChanged = false;
0290 }
0291 
0292 void DisjointMetadata::replacePickLabel(int pickId)
0293 {
0294     d->pickLabelStatus  = DisjointMetadataDataFields::MetadataAvailable;
0295     d->pickLabel        = pickId;
0296     d->pickLabelChanged = false;
0297 }
0298 
0299 void DisjointMetadata::replaceRating(int rating)
0300 {
0301     d->ratingStatus   = DisjointMetadataDataFields::MetadataAvailable;
0302     d->rating         = rating;
0303     d->ratingChanged  = false;
0304 }
0305 
0306 void DisjointMetadata::resetChanged()
0307 {
0308     d->dateTimeChanged   = false;
0309     d->titlesChanged     = false;
0310     d->commentsChanged   = false;
0311     d->pickLabelChanged  = false;
0312     d->colorLabelChanged = false;
0313     d->ratingChanged     = false;
0314     d->templateChanged   = false;
0315     d->tagsChanged       = false;
0316 }
0317 
0318 bool DisjointMetadata::write(ItemInfo info, WriteMode writeMode)
0319 {
0320     applyChangeNotifications();
0321 
0322     bool changed        = false;
0323 
0324     // find out in advance if we have something to write - needed for FullWriteIfChanged mode
0325 
0326     bool saveTitle      = (d->titlesStatus     == DisjointMetadataDataFields::MetadataAvailable);
0327     bool saveComment    = (d->commentsStatus   == DisjointMetadataDataFields::MetadataAvailable);
0328     bool saveDateTime   = (d->dateTimeStatus   == DisjointMetadataDataFields::MetadataAvailable);
0329     bool savePickLabel  = (d->pickLabelStatus  == DisjointMetadataDataFields::MetadataAvailable);
0330     bool saveColorLabel = (d->colorLabelStatus == DisjointMetadataDataFields::MetadataAvailable);
0331     bool saveRating     = (d->ratingStatus     == DisjointMetadataDataFields::MetadataAvailable);
0332     bool saveTemplate   = (d->templateStatus   == DisjointMetadataDataFields::MetadataAvailable);
0333     bool saveTags       = true;
0334 
0335     bool writeAllFields;
0336 
0337     if      (writeMode == FullWrite)
0338     {
0339         writeAllFields = true;
0340     }
0341     else if (writeMode == FullWriteIfChanged)
0342     {
0343         writeAllFields = (
0344                              (saveTitle      && d->titlesChanged)     ||
0345                              (saveComment    && d->commentsChanged)   ||
0346                              (saveDateTime   && d->dateTimeChanged)   ||
0347                              (savePickLabel  && d->pickLabelChanged)  ||
0348                              (saveColorLabel && d->colorLabelChanged) ||
0349                              (saveRating     && d->ratingChanged)     ||
0350                              (saveTemplate   && d->templateChanged)   ||
0351                              (saveTags       && d->tagsChanged)
0352                          );
0353     }
0354     else // PartialWrite
0355     {
0356         writeAllFields = false;
0357     }
0358 
0359     if (saveTitle && (writeAllFields || d->titlesChanged))
0360     {
0361         CoreDbAccess access;
0362         ItemComments comments = info.imageComments(access);
0363         comments.replaceComments(d->titles, DatabaseComment::Title);
0364         changed               = true;
0365     }
0366 
0367     if (saveComment && (writeAllFields || d->commentsChanged))
0368     {
0369         CoreDbAccess access;
0370         ItemComments comments = info.imageComments(access);
0371         comments.replaceComments(d->comments);
0372         changed               = true;
0373     }
0374 
0375     if (saveDateTime && (writeAllFields || d->dateTimeChanged))
0376     {
0377         info.setDateTime(d->dateTime);
0378         changed = true;
0379     }
0380 
0381     if (savePickLabel && (writeAllFields || d->pickLabelChanged))
0382     {
0383         info.setPickLabel(d->pickLabel);
0384         changed = true;
0385     }
0386 
0387     if (saveColorLabel && (writeAllFields || d->colorLabelChanged))
0388     {
0389         info.setColorLabel(d->colorLabel);
0390         changed = true;
0391     }
0392 
0393     if (saveRating && (writeAllFields || d->ratingChanged))
0394     {
0395         info.setRating(d->rating);
0396         changed = true;
0397     }
0398 
0399     if (saveTemplate && writeAllFields)
0400     {
0401         QString title = d->metadataTemplate.templateTitle();
0402 
0403         if      (title == Template::removeTemplateTitle())
0404         {
0405             info.removeMetadataTemplate();
0406         }
0407         else if (!d->metadataTemplate.isEmpty())
0408         {
0409             info.setMetadataTemplate(d->metadataTemplate);
0410         }
0411 
0412         changed = true;
0413     }
0414 
0415     if (writeAllFields || d->tagsChanged)
0416     {
0417         QList<int> keys = d->tags.keys();
0418 
0419         Q_FOREACH (int key, keys)
0420         {
0421             if (d->tags.value(key) == DisjointMetadataDataFields::DisjointMetadataDataFields::MetadataAvailable)
0422             {
0423                 info.setTag(key);
0424                 changed = true;
0425             }
0426 
0427             if (d->tags.value(key) == DisjointMetadataDataFields::DisjointMetadataDataFields::MetadataInvalid)
0428             {
0429                 if (FaceTags::isPerson(key))
0430                 {
0431                     FaceTagsEditor editor;
0432 
0433                     Q_FOREACH (const FaceTagsIface& face, editor.databaseFaces(info.id()))
0434                     {
0435                         if (face.tagId() == key)
0436                         {
0437                             editor.changeTag(face, FaceTags::unknownPersonTagId());
0438                         }
0439                     }
0440                 }
0441 
0442                 info.removeTag(key);
0443                 changed = true;
0444             }
0445         }
0446     }
0447 
0448     return changed;
0449 }
0450 
0451 bool DisjointMetadata::willWriteMetadata(DisjointMetadata::WriteMode writeMode,
0452                                          const MetaEngineSettingsContainer& settings) const
0453 {
0454     // This is the same logic as in write(DMetadata) but without actually writing.
0455     // Adapt if the method above changes
0456 
0457     bool saveTitle      = (settings.saveComments   && (d->titlesStatus     == DisjointMetadataDataFields::MetadataAvailable));
0458     bool saveComment    = (settings.saveComments   && (d->commentsStatus   == DisjointMetadataDataFields::MetadataAvailable));
0459     bool saveDateTime   = (settings.saveDateTime   && (d->dateTimeStatus   == DisjointMetadataDataFields::MetadataAvailable));
0460     bool savePickLabel  = (settings.savePickLabel  && (d->pickLabelStatus  == DisjointMetadataDataFields::MetadataAvailable));
0461     bool saveColorLabel = (settings.saveColorLabel && (d->colorLabelStatus == DisjointMetadataDataFields::MetadataAvailable));
0462     bool saveRating     = (settings.saveRating     && (d->ratingStatus     == DisjointMetadataDataFields::MetadataAvailable));
0463     bool saveTemplate   = (settings.saveTemplate   && (d->templateStatus   == DisjointMetadataDataFields::MetadataAvailable));
0464     bool saveTags       = (settings.saveTags || settings.saveFaceTags);
0465 
0466     bool writeAllFields;
0467 
0468     if      (writeMode == FullWrite)
0469     {
0470         writeAllFields = true;
0471     }
0472     else if (writeMode == FullWriteIfChanged)
0473     {
0474         writeAllFields = (
0475                              (saveTitle      && d->titlesChanged)     ||
0476                              (saveComment    && d->commentsChanged)   ||
0477                              (saveDateTime   && d->dateTimeChanged)   ||
0478                              (savePickLabel  && d->pickLabelChanged)  ||
0479                              (saveColorLabel && d->colorLabelChanged) ||
0480                              (saveRating     && d->ratingChanged)     ||
0481                              (saveTemplate   && d->templateChanged)   ||
0482                              (saveTags       && d->tagsChanged)
0483                          );
0484     }
0485     else // PartialWrite
0486     {
0487         writeAllFields = false;
0488     }
0489 
0490     return (
0491                (saveTitle      && (writeAllFields || d->titlesChanged))     ||
0492                (saveComment    && (writeAllFields || d->commentsChanged))   ||
0493                (saveDateTime   && (writeAllFields || d->dateTimeChanged))   ||
0494                (savePickLabel  && (writeAllFields || d->pickLabelChanged))  ||
0495                (saveColorLabel && (writeAllFields || d->colorLabelChanged)) ||
0496                (saveRating     && (writeAllFields || d->ratingChanged))     ||
0497                (saveTags       && (writeAllFields || d->tagsChanged))       ||
0498                (saveTemplate   && (writeAllFields || d->templateChanged))
0499            );
0500 }
0501 
0502 int DisjointMetadata::changedFlags()
0503 {
0504     int value = 0;
0505 
0506     if (d->titlesChanged)
0507     {
0508         value |= MetadataHub::WRITE_TITLE;
0509     }
0510 
0511     if (d->commentsChanged)
0512     {
0513         value |= MetadataHub::WRITE_COMMENTS;
0514     }
0515 
0516     if (d->dateTimeChanged)
0517     {
0518         value |= MetadataHub::WRITE_DATETIME;
0519     }
0520 
0521     if (d->pickLabelChanged)
0522     {
0523         value |= MetadataHub::WRITE_PICKLABEL;
0524     }
0525 
0526     if (d->colorLabelChanged)
0527     {
0528         value |= MetadataHub::WRITE_COLORLABEL;
0529     }
0530 
0531     if (d->ratingChanged)
0532     {
0533         value |= MetadataHub::WRITE_RATING;
0534     }
0535 
0536     if (d->tagsChanged)
0537     {
0538         value |= MetadataHub::WRITE_TAGS;
0539     }
0540 
0541     if (d->templateChanged)
0542     {
0543         value |= MetadataHub::WRITE_TEMPLATE;
0544     }
0545 
0546     return value;
0547 }
0548 
0549 void DisjointMetadata::load(const QDateTime& dateTime,const CaptionsMap& titles,
0550                             const CaptionsMap& comment, int colorLabel,
0551                             int pickLabel, int rating, const Template& t)
0552 {
0553     if (dateTime.isValid())
0554     {
0555         d->loadSingleValue<QDateTime>(dateTime, d->dateTime, d->dateTimeStatus);
0556     }
0557 
0558     d->loadSingleValue<int>(pickLabel, d->pickLabel, d->pickLabelStatus);
0559 
0560     d->loadSingleValue<int>(colorLabel, d->colorLabel, d->colorLabelStatus);
0561 
0562     d->loadSingleValue<int>(rating, d->rating, d->ratingStatus);
0563 
0564     d->loadSingleValue<CaptionsMap>(titles, d->titles, d->titlesStatus);
0565 
0566     d->loadSingleValue<CaptionsMap>(comment, d->comments, d->commentsStatus);
0567 
0568     d->loadSingleValue<Template>(t, d->metadataTemplate, d->templateStatus);
0569 }
0570 
0571 void DisjointMetadata::loadTags(const QList<int>& tagIds)
0572 {
0573     QList<int> loadedTagIds;
0574 
0575     Q_FOREACH (int tagId, tagIds)
0576     {
0577         if (!TagsCache::instance()->isInternalTag(tagId))
0578         {
0579             loadedTagIds << tagId;
0580         }
0581     }
0582 
0583     if (loadedTagIds.isEmpty())
0584     {
0585         if (!d->withoutTags)
0586         {
0587             QMap<int, DisjointMetadataDataFields::Status>::iterator it;
0588 
0589             for (it = d->tags.begin() ; it != d->tags.end() ; ++it)
0590             {
0591                 it.value() = DisjointMetadataDataFields::MetadataDisjoint;
0592             }
0593 
0594             d->withoutTags = true;
0595         }
0596 
0597         return;
0598     }
0599 
0600     // If tags map is empty, set them all as Available
0601 
0602     if (d->tags.isEmpty())
0603     {
0604         Q_FOREACH (int tagId, loadedTagIds)
0605         {
0606             if (d->withoutTags)
0607             {
0608                 d->tags[tagId] = DisjointMetadataDataFields::MetadataDisjoint;
0609             }
0610             else
0611             {
0612                 d->tags[tagId] = DisjointMetadataDataFields::MetadataAvailable;
0613             }
0614         }
0615 
0616         return;
0617     }
0618 
0619     std::sort(loadedTagIds.begin(), loadedTagIds.end());
0620 
0621     // We search for metadata available tags, and
0622     // it is not present in current list, set it to
0623     // disjoint
0624 
0625     QMap<int, DisjointMetadataDataFields::Status>::iterator it;
0626 
0627     for (it = d->tags.begin() ; it != d->tags.end() ; ++it)
0628     {
0629         if (it.value() == DisjointMetadataDataFields::MetadataAvailable)
0630         {
0631             if (!std::binary_search(loadedTagIds.begin(), loadedTagIds.end(), it.key()))
0632             {
0633                 it.value() = DisjointMetadataDataFields::MetadataDisjoint;
0634             }
0635         }
0636     }
0637 
0638     // new tags which are not yet in the set,
0639     // are added as Disjoint
0640 
0641     Q_FOREACH (int tagId, loadedTagIds)
0642     {
0643         if (!d->tags.contains(tagId))
0644         {
0645             d->tags[tagId] = DisjointMetadataDataFields::MetadataDisjoint;
0646         }
0647     }
0648 }
0649 
0650 void DisjointMetadata::notifyTagDeleted(int id)
0651 {
0652     d->tags.remove(id);
0653 }
0654 
0655 void DisjointMetadata::slotTagDeleted(int tagId)
0656 {
0657     QMutexLocker locker(&d->mutex);
0658     d->tagIds << tagId;
0659 }
0660 
0661 void DisjointMetadata::slotInvalidate()
0662 {
0663     QMutexLocker locker(&d->mutex);
0664     d->invalid = true;
0665 }
0666 
0667 void DisjointMetadata::applyChangeNotifications()
0668 {
0669     if (d->invalid)
0670     {
0671         reset();
0672     }
0673 
0674     QList<int> tagIds;
0675     {
0676         QMutexLocker locker(&d->mutex);
0677         tagIds = d->tagIds;
0678         d->tagIds.clear();
0679     }
0680 
0681     Q_FOREACH (int tagId, tagIds)
0682     {
0683         notifyTagDeleted(tagId);
0684     }
0685 }
0686 
0687 QDateTime DisjointMetadata::dateTime() const
0688 {
0689     return d->dateTime;
0690 }
0691 
0692 CaptionsMap DisjointMetadata::titles() const
0693 {
0694     return d->titles;
0695 }
0696 
0697 CaptionsMap DisjointMetadata::comments() const
0698 {
0699     return d->comments;
0700 }
0701 
0702 int DisjointMetadata::pickLabel() const
0703 {
0704     return d->pickLabel;
0705 }
0706 
0707 int DisjointMetadata::colorLabel() const
0708 {
0709     return d->colorLabel;
0710 }
0711 
0712 int DisjointMetadata::rating() const
0713 {
0714     return d->rating;
0715 }
0716 
0717 Template DisjointMetadata::metadataTemplate() const
0718 {
0719     return d->metadataTemplate;
0720 }
0721 
0722 void DisjointMetadata::dateTimeInterval(QDateTime& lowest, QDateTime& highest) const
0723 {
0724     switch (d->dateTimeStatus)
0725     {
0726         case DisjointMetadataDataFields::MetadataInvalid:
0727         {
0728             lowest  = QDateTime();
0729             highest = QDateTime();
0730             break;
0731         }
0732 
0733         case DisjointMetadataDataFields::MetadataAvailable:
0734         {
0735             lowest  = d->dateTime;
0736             highest = d->dateTime;
0737             break;
0738         }
0739 
0740         case DisjointMetadataDataFields::MetadataDisjoint:
0741         {
0742             lowest  = d->dateTime;
0743             highest = d->lastDateTime;
0744             break;
0745         }
0746     }
0747 }
0748 
0749 void DisjointMetadata::pickLabelInterval(int& lowest, int& highest) const
0750 {
0751     switch (d->pickLabelStatus)
0752     {
0753         case DisjointMetadataDataFields::MetadataInvalid:
0754         {
0755             lowest  = -1;
0756             highest = -1;
0757             break;
0758         }
0759 
0760         case DisjointMetadataDataFields::MetadataAvailable:
0761         {
0762             lowest  = d->pickLabel;
0763             highest = d->pickLabel;
0764             break;
0765         }
0766 
0767         case DisjointMetadataDataFields::MetadataDisjoint:
0768         {
0769             lowest  = d->pickLabel;
0770             highest = d->highestPickLabel;
0771             break;
0772         }
0773     }
0774 }
0775 
0776 void DisjointMetadata::colorLabelInterval(int& lowest, int& highest) const
0777 {
0778     switch (d->colorLabelStatus)
0779     {
0780         case DisjointMetadataDataFields::MetadataInvalid:
0781         {
0782             lowest  = -1;
0783             highest = -1;
0784             break;
0785         }
0786 
0787         case DisjointMetadataDataFields::MetadataAvailable:
0788         {
0789             lowest  = d->colorLabel;
0790             highest = d->colorLabel;
0791             break;
0792         }
0793 
0794         case DisjointMetadataDataFields::MetadataDisjoint:
0795         {
0796             lowest  = d->colorLabel;
0797             highest = d->highestColorLabel;
0798             break;
0799         }
0800     }
0801 }
0802 
0803 void DisjointMetadata::ratingInterval(int& lowest, int& highest) const
0804 {
0805     switch (d->ratingStatus)
0806     {
0807         case DisjointMetadataDataFields::MetadataInvalid:
0808         {
0809             lowest  = -1;
0810             highest = -1;
0811             break;
0812         }
0813 
0814         case DisjointMetadataDataFields::MetadataAvailable:
0815         {
0816             lowest  = d->rating;
0817             highest = d->rating;
0818             break;
0819         }
0820 
0821         case DisjointMetadataDataFields::MetadataDisjoint:
0822         {
0823             lowest  = d->rating;
0824             highest = d->highestRating;
0825             break;
0826         }
0827     }
0828 }
0829 
0830 QStringList DisjointMetadata::keywords() const
0831 {
0832     QStringList tagList;
0833 
0834     QList<int> keys = d->tags.keys();
0835 
0836     Q_FOREACH (int key, keys)
0837     {
0838         if (d->tags.value(key) == DisjointMetadataDataFields::MetadataAvailable)
0839         {
0840             tagList.append(TagsCache::instance()->tagPath(key, TagsCache::NoLeadingSlash));
0841         }
0842     }
0843 
0844     return tagList;
0845 }
0846 
0847 QMap<int, DisjointMetadataDataFields::Status> DisjointMetadata::tags() const
0848 {
0849     // DatabaseMode == ManagedTags is assumed
0850 
0851     return d->tags;
0852 }
0853 
0854 DisjointMetadataDataFields DisjointMetadata::dataFields() const
0855 {
0856     DisjointMetadataDataFields data(*d);
0857 
0858     return data;
0859 }
0860 
0861 void DisjointMetadata::setDataFields(const DisjointMetadataDataFields& data)
0862 {
0863     if (d)
0864     {
0865         delete d;
0866     }
0867 
0868     d = new Private(data);
0869     d->makeConnections(this);
0870 }
0871 
0872 } // namespace Digikam
0873 
0874 #include "moc_disjointmetadata.cpp"