File indexing completed on 2025-01-19 03:51:25

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-10-18
0007  * Description : XMP content settings page.
0008  *
0009  * SPDX-FileCopyrightText: 2007-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "xmpcontent.h"
0016 
0017 // Qt includes
0018 
0019 #include <QCheckBox>
0020 #include <QGroupBox>
0021 #include <QGridLayout>
0022 #include <QApplication>
0023 #include <QStyle>
0024 
0025 // KDE includes
0026 
0027 #include <klocalizedstring.h>
0028 
0029 // Local includes
0030 
0031 #include "dlayoutbox.h"
0032 #include "altlangstringedit.h"
0033 #include "dexpanderbox.h"
0034 #include "dtextedit.h"
0035 
0036 namespace DigikamGenericMetadataEditPlugin
0037 {
0038 
0039 class Q_DECL_HIDDEN XMPContent::Private
0040 {
0041 public:
0042 
0043     explicit Private()
0044       : headlineCheck         (nullptr),
0045         syncJFIFCommentCheck  (nullptr),
0046         syncEXIFCommentCheck  (nullptr),
0047         syncEXIFCopyrightCheck(nullptr),
0048         writerCheck           (nullptr),
0049         headlineEdit          (nullptr),
0050         writerEdit            (nullptr),
0051         captionEdit           (nullptr),
0052         copyrightEdit         (nullptr),
0053         usageTermsEdit        (nullptr)
0054     {
0055     }
0056 
0057     QCheckBox*          headlineCheck;
0058     QCheckBox*          syncJFIFCommentCheck;
0059     QCheckBox*          syncEXIFCommentCheck;
0060     QCheckBox*          syncEXIFCopyrightCheck;
0061     QCheckBox*          writerCheck;
0062 
0063     DTextEdit*          headlineEdit;
0064     DTextEdit*          writerEdit;
0065 
0066     AltLangStringsEdit* captionEdit;
0067     AltLangStringsEdit* copyrightEdit;
0068     AltLangStringsEdit* usageTermsEdit;
0069 };
0070 
0071 XMPContent::XMPContent(QWidget* const parent)
0072     : MetadataEditPage(parent),
0073       d               (new Private)
0074 {
0075     int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0076                        QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0077 
0078     QGridLayout* const grid = new QGridLayout(widget());
0079 
0080     // --------------------------------------------------------
0081 
0082     d->headlineCheck = new QCheckBox(i18n("Headline:"), this);
0083     d->headlineEdit  = new DTextEdit(this);
0084     d->headlineEdit->setPlaceholderText(i18n("Set here the content synopsis."));
0085 
0086     // --------------------------------------------------------
0087 
0088     d->captionEdit          = new AltLangStringsEdit(this, i18nc("content description", "Captions:"),
0089                                                      i18n("Set here the content descriptions."));
0090 
0091     QGroupBox* const syncOptions  = new QGroupBox(i18n("Default Language Caption Options"), this);
0092     QVBoxLayout* const vlay       = new QVBoxLayout(syncOptions);
0093 
0094     d->syncJFIFCommentCheck = new QCheckBox(i18n("Sync JFIF Comment section"), syncOptions);
0095     d->syncEXIFCommentCheck = new QCheckBox(i18n("Sync Exif Comment"), syncOptions);
0096 
0097     vlay->setContentsMargins(spacing, spacing, spacing, spacing);
0098     vlay->setSpacing(spacing);
0099     vlay->addWidget(d->syncJFIFCommentCheck);
0100     vlay->addWidget(d->syncEXIFCommentCheck);
0101 
0102     // --------------------------------------------------------
0103 
0104     d->writerCheck = new QCheckBox(i18n("Caption Writer:"), this);
0105     d->writerEdit  = new DTextEdit(this);
0106     d->writerEdit->setPlaceholderText(i18n("Set here the name of the caption author."));
0107 
0108     // --------------------------------------------------------
0109 
0110     d->copyrightEdit          = new AltLangStringsEdit(this, i18n("Copyright:"),
0111                                                        i18n("Set here the necessary copyright notice."));
0112 
0113     d->syncEXIFCopyrightCheck = new QCheckBox(i18n("Sync Exif Copyright"), this);
0114 
0115     d->usageTermsEdit         = new AltLangStringsEdit(this, i18n("Right Usage Terms:"),
0116                                                        i18n("Set here the instructions on how a "
0117                                                             "resource can be legally used here."));
0118 
0119     // --------------------------------------------------------
0120 
0121     grid->addWidget(d->headlineCheck,                      0, 0, 1, 3);
0122     grid->addWidget(d->headlineEdit,                       1, 0, 1, 3);
0123     grid->addWidget(new DLineWidget(Qt::Horizontal, this), 2, 0, 1, 3);
0124     grid->addWidget(d->captionEdit,                        3, 0, 1, 3);
0125     grid->addWidget(syncOptions,                           4, 0, 1, 3);
0126     grid->addWidget(d->writerCheck,                        5, 0, 1, 3);
0127     grid->addWidget(d->writerEdit,                         6, 1, 1, 3);
0128     grid->addWidget(d->copyrightEdit,                      7, 0, 1, 3);
0129     grid->addWidget(d->syncEXIFCopyrightCheck,             8, 0, 1, 3);
0130     grid->addWidget(d->usageTermsEdit,                     9, 0, 1, 3);
0131     grid->setRowStretch(10, 10);
0132     grid->setColumnStretch(2, 10);
0133     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0134     grid->setSpacing(spacing);
0135 
0136     // --------------------------------------------------------
0137 
0138     connect(d->captionEdit, SIGNAL(signalDefaultLanguageEnabled(bool)),
0139             this, SLOT(slotSyncCaptionOptionsEnabled(bool)));
0140 
0141     connect(d->headlineCheck, SIGNAL(toggled(bool)),
0142             d->headlineEdit, SLOT(setEnabled(bool)));
0143 
0144     connect(d->writerCheck, SIGNAL(toggled(bool)),
0145             d->writerEdit, SLOT(setEnabled(bool)));
0146 
0147     // --------------------------------------------------------
0148 
0149     connect(d->captionEdit, SIGNAL(signalToggled(bool)),
0150             this, SIGNAL(signalModified()));
0151 
0152     connect(d->copyrightEdit, SIGNAL(signalToggled(bool)),
0153             this, SIGNAL(signalModified()));
0154 
0155     connect(d->usageTermsEdit, SIGNAL(signalToggled(bool)),
0156             this, SIGNAL(signalModified()));
0157 
0158     connect(d->copyrightEdit, SIGNAL(signalDefaultLanguageEnabled(bool)),
0159             this, SLOT(slotSyncCopyrightOptionsEnabled(bool)));
0160 
0161     connect(d->writerCheck, SIGNAL(toggled(bool)),
0162             this, SIGNAL(signalModified()));
0163 
0164     connect(d->headlineCheck, SIGNAL(toggled(bool)),
0165             this, SIGNAL(signalModified()));
0166 
0167     // --------------------------------------------------------
0168 
0169     connect(d->captionEdit, SIGNAL(signalModified()),
0170             this, SIGNAL(signalModified()));
0171 
0172     connect(d->copyrightEdit, SIGNAL(signalModified()),
0173             this, SIGNAL(signalModified()));
0174 
0175     connect(d->usageTermsEdit, SIGNAL(signalModified()),
0176             this, SIGNAL(signalModified()));
0177 
0178     connect(d->headlineEdit, SIGNAL(textChanged()),
0179             this, SIGNAL(signalModified()));
0180 
0181     connect(d->writerEdit, SIGNAL(textChanged()),
0182             this, SIGNAL(signalModified()));
0183 }
0184 
0185 XMPContent::~XMPContent()
0186 {
0187     delete d;
0188 }
0189 
0190 bool XMPContent::syncJFIFCommentIsChecked() const
0191 {
0192     return d->syncJFIFCommentCheck->isChecked();
0193 }
0194 
0195 bool XMPContent::syncEXIFCommentIsChecked() const
0196 {
0197     return d->syncEXIFCommentCheck->isChecked();
0198 }
0199 
0200 bool XMPContent::syncEXIFCopyrightIsChecked() const
0201 {
0202     return d->syncEXIFCopyrightCheck->isChecked();
0203 }
0204 
0205 QString XMPContent::getXMPCaption() const
0206 {
0207     return d->captionEdit->defaultAltLang();
0208 }
0209 
0210 QString XMPContent::getXMPCopyright() const
0211 {
0212     return d->copyrightEdit->defaultAltLang();
0213 }
0214 
0215 void XMPContent::setCheckedSyncJFIFComment(bool c)
0216 {
0217     d->syncJFIFCommentCheck->setChecked(c);
0218 }
0219 
0220 void XMPContent::setCheckedSyncEXIFComment(bool c)
0221 {
0222     d->syncEXIFCommentCheck->setChecked(c);
0223 }
0224 
0225 void XMPContent::setCheckedSyncEXIFCopyright(bool c)
0226 {
0227     d->syncEXIFCopyrightCheck->setChecked(c);
0228 }
0229 
0230 void XMPContent::readMetadata(const DMetadata& meta)
0231 {
0232     blockSignals(true);
0233 
0234     DMetadata::AltLangMap map;
0235     QString data;
0236 
0237     d->headlineEdit->clear();
0238     d->headlineCheck->setChecked(false);
0239     data = meta.getXmpTagString("Xmp.photoshop.Headline", false);
0240 
0241     if (!data.isNull())
0242     {
0243         d->headlineEdit->setText(data);
0244         d->headlineCheck->setChecked(true);
0245     }
0246 
0247     d->headlineEdit->setEnabled(d->headlineCheck->isChecked());
0248 
0249     d->captionEdit->setValues(map);
0250     d->captionEdit->setValid(false);
0251     map = meta.getXmpTagStringListLangAlt("Xmp.dc.description", false);
0252 
0253     if (!map.isEmpty())
0254     {
0255         d->captionEdit->setValues(map);
0256         d->captionEdit->setValid(true);
0257     }
0258 
0259     d->writerEdit->clear();
0260     d->writerCheck->setChecked(false);
0261     data = meta.getXmpTagString("Xmp.photoshop.CaptionWriter", false);
0262 
0263     if (!data.isNull())
0264     {
0265         d->writerEdit->setText(data);
0266         d->writerCheck->setChecked(true);
0267     }
0268 
0269     d->writerEdit->setEnabled(d->writerCheck->isChecked());
0270 
0271     map.clear();
0272     d->copyrightEdit->setValues(map);
0273     d->copyrightEdit->setValid(false);
0274     map = meta.getXmpTagStringListLangAlt("Xmp.dc.rights", false);
0275 
0276     if (!map.isEmpty())
0277     {
0278         d->copyrightEdit->setValues(map);
0279         d->copyrightEdit->setValid(true);
0280     }
0281 
0282     map.clear();
0283     d->usageTermsEdit->setValues(map);
0284     d->usageTermsEdit->setValid(false);
0285     map = meta.getXmpTagStringListLangAlt("Xmp.xmpRights.UsageTerms", false);
0286 
0287     if (!map.isEmpty())
0288     {
0289         d->usageTermsEdit->setValues(map);
0290         d->usageTermsEdit->setValid(true);
0291     }
0292 
0293     blockSignals(false);
0294 }
0295 
0296 void XMPContent::applyMetadata(const DMetadata& meta)
0297 {
0298     if (d->headlineCheck->isChecked())
0299     {
0300         meta.setXmpTagString("Xmp.photoshop.Headline", d->headlineEdit->text());
0301     }
0302     else
0303     {
0304         meta.removeXmpTag("Xmp.photoshop.Headline");
0305     }
0306 
0307     DMetadata::AltLangMap oldAltLangMap, newAltLangMap;
0308 
0309     if      (d->captionEdit->getValues(oldAltLangMap, newAltLangMap))
0310     {
0311         meta.setXmpTagStringListLangAlt("Xmp.dc.description", newAltLangMap);
0312 
0313         if (syncEXIFCommentIsChecked())
0314         {
0315             meta.setExifComment(getXMPCaption());
0316         }
0317 
0318         if (syncJFIFCommentIsChecked())
0319         {
0320             meta.setComments(getXMPCaption().toUtf8());
0321         }
0322     }
0323     else if (d->captionEdit->isValid())
0324     {
0325         meta.removeXmpTag("Xmp.dc.description");
0326     }
0327 
0328     if (d->writerCheck->isChecked())
0329     {
0330         meta.setXmpTagString("Xmp.photoshop.CaptionWriter", d->writerEdit->text());
0331     }
0332     else
0333     {
0334         meta.removeXmpTag("Xmp.photoshop.CaptionWriter");
0335     }
0336 
0337     if      (d->copyrightEdit->getValues(oldAltLangMap, newAltLangMap))
0338     {
0339         meta.setXmpTagStringListLangAlt("Xmp.dc.rights", newAltLangMap);
0340 
0341         if (syncEXIFCopyrightIsChecked())
0342         {
0343             meta.removeExifTag("Exif.Image.Copyright");
0344             meta.setExifTagString("Exif.Image.Copyright", getXMPCopyright());
0345         }
0346     }
0347     else if (d->copyrightEdit->isValid())
0348     {
0349         meta.removeXmpTag("Xmp.dc.rights");
0350     }
0351 
0352     if (d->usageTermsEdit->getValues(oldAltLangMap, newAltLangMap))
0353     {
0354         meta.setXmpTagStringListLangAlt("Xmp.xmpRights.UsageTerms", newAltLangMap);
0355     }
0356     else if (d->usageTermsEdit->isValid())
0357     {
0358         meta.removeXmpTag("Xmp.xmpRights.UsageTerms");
0359     }
0360 }
0361 
0362 void XMPContent::slotSyncCaptionOptionsEnabled(bool defaultLangAlt)
0363 {
0364     bool cond = defaultLangAlt & d->captionEdit->isValid();
0365     d->syncJFIFCommentCheck->setEnabled(cond);
0366     d->syncEXIFCommentCheck->setEnabled(cond);
0367 }
0368 
0369 void XMPContent::slotSyncCopyrightOptionsEnabled(bool defaultLangAlt)
0370 {
0371     bool cond = defaultLangAlt & d->copyrightEdit->isValid();
0372     d->syncEXIFCopyrightCheck->setEnabled(cond);
0373 }
0374 
0375 } // namespace DigikamGenericMetadataEditPlugin
0376 
0377 #include "moc_xmpcontent.cpp"