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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2006-10-12
0007  * Description : IPTC content settings page.
0008  *
0009  * SPDX-FileCopyrightText: 2006-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 "iptccontent.h"
0016 
0017 // Qt includes
0018 
0019 #include <QCheckBox>
0020 #include <QLabel>
0021 #include <QGridLayout>
0022 #include <QApplication>
0023 #include <QStyle>
0024 #include <QLineEdit>
0025 #include <QToolTip>
0026 
0027 // KDE includes
0028 
0029 #include <klocalizedstring.h>
0030 
0031 // Local includes
0032 
0033 #include "dlayoutbox.h"
0034 #include "multistringsedit.h"
0035 #include "dexpanderbox.h"
0036 #include "dtextedit.h"
0037 
0038 namespace DigikamGenericMetadataEditPlugin
0039 {
0040 
0041 class Q_DECL_HIDDEN IPTCContent::Private
0042 {
0043 public:
0044 
0045     explicit Private()
0046       : captionCheck         (nullptr),
0047         headlineCheck        (nullptr),
0048         syncJFIFCommentCheck (nullptr),
0049         syncEXIFCommentCheck (nullptr),
0050         captionNote          (nullptr),
0051         captionEdit          (nullptr),
0052         headlineEdit         (nullptr),
0053         writerEdit           (nullptr)
0054     {
0055     }
0056 
0057     QCheckBox*        captionCheck;
0058     QCheckBox*        headlineCheck;
0059     QCheckBox*        syncJFIFCommentCheck;
0060     QCheckBox*        syncEXIFCommentCheck;
0061 
0062     QLabel*           captionNote;
0063     DPlainTextEdit*   captionEdit;
0064 
0065     DPlainTextEdit*   headlineEdit;
0066 
0067     MultiStringsEdit* writerEdit;
0068 };
0069 
0070 IPTCContent::IPTCContent(QWidget* const parent)
0071     : MetadataEditPage(parent),
0072       d               (new Private)
0073 {
0074     QGridLayout* const grid = new QGridLayout(widget());
0075 
0076     // --------------------------------------------------------
0077 
0078     d->headlineCheck = new QCheckBox(i18n("Headline:"), this);
0079     d->headlineEdit  = new DPlainTextEdit(this);
0080     d->headlineEdit->setMaxLength(256);
0081     d->headlineEdit->setPlaceholderText(i18n("Set here the content synopsis"));
0082     d->headlineEdit->setWhatsThis(i18n("Enter here the content synopsis. This field is limited "
0083                                        "to 256 characters."));
0084 
0085     // --------------------------------------------------------
0086 
0087     DHBox* const captionHeader = new DHBox(this);
0088     d->captionCheck            = new QCheckBox(i18nc("content description", "Caption:"), captionHeader);
0089     d->captionNote             = new QLabel(captionHeader);
0090     captionHeader->setStretchFactor(d->captionCheck, 10);
0091 
0092     d->captionEdit             = new DPlainTextEdit(this);
0093     d->captionEdit->setLinesVisible(4);
0094     d->syncJFIFCommentCheck    = new QCheckBox(i18n("Sync JFIF Comment section"), this);
0095     d->syncEXIFCommentCheck    = new QCheckBox(i18n("Sync Exif Comment"), this);
0096     d->captionEdit->setMaxLength(2000);
0097     d->captionEdit->setPlaceholderText(i18n("Set here the content description"));
0098     d->captionEdit->setWhatsThis(i18n("Enter the content description. This field is limited "
0099                                       "to 2000 characters."));
0100 
0101     // --------------------------------------------------------
0102 
0103     d->writerEdit  = new MultiStringsEdit(this, i18n("Caption Writer:"),
0104                                           i18n("Enter the name of the caption author."),
0105                                           32);
0106 
0107     // --------------------------------------------------------
0108 
0109     QLabel* const note = new QLabel(i18n("<b>Note: "
0110                  "<a href='https://en.wikipedia.org/wiki/IPTC_Information_Interchange_Model'>IPTC</a> "
0111                  "text tags are limited string sizes. Use contextual help for details. "
0112                  "Consider to use <a href='https://en.wikipedia.org/wiki/Extensible_Metadata_Platform'>XMP</a> instead.</b>"),
0113                  this);
0114     note->setOpenExternalLinks(true);
0115     note->setWordWrap(true);
0116     note->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
0117 
0118     // --------------------------------------------------------
0119 
0120     grid->addWidget(d->headlineCheck,                       0, 0, 1, 3);
0121     grid->addWidget(d->headlineEdit,                        1, 0, 1, 3);
0122     grid->addWidget(captionHeader,                          2, 0, 1, 3);
0123     grid->addWidget(d->captionEdit,                         3, 0, 1, 3);
0124     grid->addWidget(d->syncJFIFCommentCheck,                4, 0, 1, 3);
0125     grid->addWidget(d->syncEXIFCommentCheck,                6, 0, 1, 3);
0126     grid->addWidget(new DLineWidget(Qt::Horizontal, this),  7, 0, 1, 3);
0127     grid->addWidget(d->writerEdit,                          8, 0, 1, 3);
0128     grid->addWidget(note,                                   9, 0, 1, 3);
0129     grid->setRowStretch(10, 10);
0130     grid->setColumnStretch(2, 10);
0131 
0132     int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0133                        QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0134 
0135     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0136     grid->setSpacing(spacing);
0137 
0138     // --------------------------------------------------------
0139 
0140     connect(d->captionCheck, SIGNAL(toggled(bool)),
0141             d->captionEdit, SLOT(setEnabled(bool)));
0142 
0143     connect(d->captionCheck, SIGNAL(toggled(bool)),
0144             d->syncJFIFCommentCheck, SLOT(setEnabled(bool)));
0145 
0146     connect(d->captionCheck, SIGNAL(toggled(bool)),
0147             d->syncEXIFCommentCheck, SLOT(setEnabled(bool)));
0148 
0149     connect(d->headlineCheck, SIGNAL(toggled(bool)),
0150             d->headlineEdit, SLOT(setEnabled(bool)));
0151 
0152     // --------------------------------------------------------
0153 
0154     connect(d->captionCheck, SIGNAL(toggled(bool)),
0155             this, SIGNAL(signalModified()));
0156 
0157     connect(d->writerEdit, SIGNAL(signalModified()),
0158             this, SIGNAL(signalModified()));
0159 
0160     connect(d->headlineCheck, SIGNAL(toggled(bool)),
0161             this, SIGNAL(signalModified()));
0162 
0163     // --------------------------------------------------------
0164 
0165     connect(d->captionEdit, SIGNAL(textChanged()),
0166             this, SIGNAL(signalModified()));
0167 
0168     connect(d->headlineEdit, SIGNAL(textChanged()),
0169             this, SIGNAL(signalModified()));
0170 }
0171 
0172 IPTCContent::~IPTCContent()
0173 {
0174     delete d;
0175 }
0176 
0177 bool IPTCContent::syncJFIFCommentIsChecked() const
0178 {
0179     return d->syncJFIFCommentCheck->isChecked();
0180 }
0181 
0182 bool IPTCContent::syncEXIFCommentIsChecked() const
0183 {
0184     return d->syncEXIFCommentCheck->isChecked();
0185 }
0186 
0187 QString IPTCContent::getIPTCCaption() const
0188 {
0189     return d->captionEdit->toPlainText();
0190 }
0191 
0192 void IPTCContent::setCheckedSyncJFIFComment(bool c)
0193 {
0194     d->syncJFIFCommentCheck->setChecked(c);
0195 }
0196 
0197 void IPTCContent::setCheckedSyncEXIFComment(bool c)
0198 {
0199     d->syncEXIFCommentCheck->setChecked(c);
0200 }
0201 
0202 void IPTCContent::readMetadata(const DMetadata& meta)
0203 {
0204     blockSignals(true);
0205 
0206     QString     data;
0207     QStringList list;
0208 
0209     d->captionEdit->clear();
0210     d->captionCheck->setChecked(false);
0211     data = meta.getIptcTagString("Iptc.Application2.Caption", false);
0212     if (!data.isNull())
0213     {
0214         d->captionEdit->setPlainText(data);
0215         d->captionCheck->setChecked(true);
0216     }
0217     d->captionEdit->setEnabled(d->captionCheck->isChecked());
0218     d->syncJFIFCommentCheck->setEnabled(d->captionCheck->isChecked());
0219     d->syncEXIFCommentCheck->setEnabled(d->captionCheck->isChecked());
0220 
0221     list = meta.getIptcTagsStringList("Iptc.Application2.Writer", false);
0222     d->writerEdit->setValues(list);
0223 
0224     d->headlineEdit->clear();
0225     d->headlineCheck->setChecked(false);
0226     data = meta.getIptcTagString("Iptc.Application2.Headline", false);
0227     if (!data.isNull())
0228     {
0229         d->headlineEdit->setPlainText(data);
0230         d->headlineCheck->setChecked(true);
0231     }
0232     d->headlineEdit->setEnabled(d->headlineCheck->isChecked());
0233 
0234     blockSignals(false);
0235 }
0236 
0237 void IPTCContent::applyMetadata(const DMetadata& meta)
0238 {
0239     if (d->captionCheck->isChecked())
0240     {
0241         meta.setIptcTagString("Iptc.Application2.Caption", d->captionEdit->toPlainText());
0242 
0243         if (syncEXIFCommentIsChecked())
0244             meta.setExifComment(getIPTCCaption());
0245 
0246         if (syncJFIFCommentIsChecked())
0247             meta.setComments(getIPTCCaption().toUtf8());
0248     }
0249     else
0250         meta.removeIptcTag("Iptc.Application2.Caption");
0251 
0252     QStringList oldList, newList;
0253 
0254     if (d->writerEdit->getValues(oldList, newList))
0255         meta.setIptcTagsStringList("Iptc.Application2.Writer", 32, oldList, newList);
0256     else
0257         meta.removeIptcTag("Iptc.Application2.Writer");
0258 
0259     if (d->headlineCheck->isChecked())
0260         meta.setIptcTagString("Iptc.Application2.Headline", d->headlineEdit->text());
0261     else
0262         meta.removeIptcTag("Iptc.Application2.Headline");
0263 }
0264 
0265 } // namespace DigikamGenericMetadataEditPlugin
0266 
0267 #include "moc_iptccontent.cpp"