File indexing completed on 2025-01-19 03:56:02

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2006-09-15
0007  * Description : Exiv2 library interface.
0008  *               Internal merge helper.
0009  *
0010  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #ifndef DIGIKAM_META_ENGINE_MERGE_HELPER_H
0018 #define DIGIKAM_META_ENGINE_MERGE_HELPER_H
0019 
0020 #include "metaengine_p.h"
0021 
0022 namespace Digikam
0023 {
0024 
0025 template <class Data, class Key, class KeyString, class KeyStringList = QList<KeyString> >
0026 
0027 class Q_DECL_HIDDEN MetaEngineMergeHelper
0028 {
0029 public:
0030 
0031     KeyStringList keys;
0032 
0033 public:
0034 
0035     MetaEngineMergeHelper& operator<<(const KeyString& key)
0036     {
0037         keys << key;
0038 
0039         return *this;
0040     }
0041 
0042     /**
0043      * Merge two (Exif,IPTC,Xmp) Data packages, where the result is stored in dest
0044      * and fields from src take precedence over existing data from dest.
0045      */
0046     void mergeAll(const Data& src, Data& dest)
0047     {
0048         for (typename Data::const_iterator it = src.begin() ; it != src.end() ; ++it)
0049         {
0050             typename Data::iterator destIt = dest.findKey(Key(it->key()));
0051 
0052             if (destIt == dest.end())
0053             {
0054                 dest.add(*it);
0055             }
0056             else
0057             {
0058                 *destIt = *it;
0059             }
0060         }
0061     }
0062 
0063     /**
0064      * Merge two (Exif,IPTC,Xmp) Data packages, the result is stored in dest.
0065      * Only keys in keys are considered for merging.
0066      * Fields from src take precedence over existing data from dest.
0067      */
0068     void mergeFields(const Data& src, Data& dest)
0069     {
0070         Q_FOREACH (const KeyString& keyString, keys)
0071         {
0072             Key key(keyString.latin1());
0073             typename Data::const_iterator it = src.findKey(key);
0074 
0075             if (it == src.end())
0076             {
0077                 continue;
0078             }
0079 
0080             typename Data::iterator destIt = dest.findKey(key);
0081 
0082             if (destIt == dest.end())
0083             {
0084                 dest.add(*it);
0085             }
0086             else
0087             {
0088                 *destIt = *it;
0089             }
0090         }
0091     }
0092 
0093     /**
0094      * Merge two (Exif,IPTC,Xmp) Data packages, the result is stored in dest.
0095      * The following steps apply only to keys in "keys":
0096      * The result is determined by src.
0097      * Keys must exist in src to kept in dest.
0098      * Fields from src take precedence over existing data from dest.
0099      */
0100     void exclusiveMerge(const Data& src, Data& dest)
0101     {
0102         Q_FOREACH (const KeyString& keyString, keys)
0103         {
0104             Key key(keyString.latin1());
0105             typename Data::const_iterator it = src.findKey(key);
0106             typename Data::iterator destIt   = dest.findKey(key);
0107 
0108             if (destIt == dest.end())
0109             {
0110                 if (it != src.end())
0111                 {
0112                     dest.add(*it);
0113                 }
0114             }
0115             else
0116             {
0117                 if (it == src.end())
0118                 {
0119                     dest.erase(destIt);
0120                 }
0121                 else
0122                 {
0123                     *destIt = *it;
0124                 }
0125             }
0126         }
0127     }
0128 };
0129 
0130 class Q_DECL_HIDDEN ExifMetaEngineMergeHelper
0131     : public MetaEngineMergeHelper<Exiv2::ExifData, Exiv2::ExifKey, QLatin1String>
0132 {
0133 };
0134 
0135 class Q_DECL_HIDDEN IptcMetaEngineMergeHelper
0136     : public MetaEngineMergeHelper<Exiv2::IptcData, Exiv2::IptcKey, QLatin1String>
0137 {
0138 };
0139 
0140 #ifdef _XMP_SUPPORT_
0141 
0142 class Q_DECL_HIDDEN XmpMetaEngineMergeHelper
0143     : public MetaEngineMergeHelper<Exiv2::XmpData, Exiv2::XmpKey, QLatin1String>
0144 {
0145 };
0146 
0147 #endif
0148 
0149 } // namespace Digikam
0150 
0151 #endif // DIGIKAM_META_ENGINE_MERGE_HELPER_H