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

0001 /*============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2011-03-14
0007  * Description : a DConfigDlgWdg to edit IPTC metadata
0008  *
0009  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2011 by Victor Dodon <dodon dot victor at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "iptceditwidget.h"
0017 
0018 // Qt includes
0019 
0020 #include <QMenu>
0021 #include <QCloseEvent>
0022 #include <QKeyEvent>
0023 #include <QUrl>
0024 #include <QApplication>
0025 #include <QFileInfo>
0026 
0027 // KDE includes
0028 
0029 #include <ksharedconfig.h>
0030 #include <kconfiggroup.h>
0031 #include <klocalizedstring.h>
0032 
0033 // Local includes
0034 
0035 #include "digikam_debug.h"
0036 #include "metadataeditdialog.h"
0037 #include "metaenginesettings.h"
0038 #include "iptccategories.h"
0039 #include "iptccontent.h"
0040 #include "iptccredits.h"
0041 #include "iptcenvelope.h"
0042 #include "iptckeywords.h"
0043 #include "iptcorigin.h"
0044 #include "iptcproperties.h"
0045 #include "iptcstatus.h"
0046 #include "iptcsubjects.h"
0047 #include "dmetadata.h"
0048 
0049 namespace DigikamGenericMetadataEditPlugin
0050 {
0051 
0052 class Q_DECL_HIDDEN IPTCEditWidget::Private
0053 {
0054 
0055 public:
0056 
0057     explicit Private()
0058     {
0059         modified        = false;
0060         isReadOnly      = false;
0061         page_content    = nullptr;
0062         page_properties = nullptr;
0063         page_subjects   = nullptr;
0064         page_keywords   = nullptr;
0065         page_categories = nullptr;
0066         page_credits    = nullptr;
0067         page_status     = nullptr;
0068         page_origin     = nullptr;
0069         page_envelope   = nullptr;
0070         contentPage     = nullptr;
0071         propertiesPage  = nullptr;
0072         subjectsPage    = nullptr;
0073         keywordsPage    = nullptr;
0074         categoriesPage  = nullptr;
0075         creditsPage     = nullptr;
0076         statusPage      = nullptr;
0077         originPage      = nullptr;
0078         envelopePage    = nullptr;
0079         dlg             = nullptr;
0080     }
0081 
0082     bool                  modified;
0083     bool                  isReadOnly;
0084 
0085     DConfigDlgWdgItem*    page_content;
0086     DConfigDlgWdgItem*    page_properties;
0087     DConfigDlgWdgItem*    page_subjects;
0088     DConfigDlgWdgItem*    page_keywords;
0089     DConfigDlgWdgItem*    page_categories;
0090     DConfigDlgWdgItem*    page_credits;
0091     DConfigDlgWdgItem*    page_status;
0092     DConfigDlgWdgItem*    page_origin;
0093     DConfigDlgWdgItem*    page_envelope;
0094 
0095     IPTCContent*          contentPage;
0096     IPTCProperties*       propertiesPage;
0097     IPTCSubjects*         subjectsPage;
0098     IPTCKeywords*         keywordsPage;
0099     IPTCCategories*       categoriesPage;
0100     IPTCCredits*          creditsPage;
0101     IPTCStatus*           statusPage;
0102     IPTCOrigin*           originPage;
0103     IPTCEnvelope*         envelopePage;
0104 
0105     MetadataEditDialog*   dlg;
0106 };
0107 
0108 IPTCEditWidget::IPTCEditWidget(MetadataEditDialog* const parent)
0109     : DConfigDlgWdg(parent),
0110       d            (new Private)
0111 {
0112     d->dlg           = parent;
0113 
0114     d->contentPage   = new IPTCContent(this);
0115     d->page_content  = addPage(d->contentPage, i18nc("@item: iptc", "Content"));
0116     d->page_content->setIcon(QIcon::fromTheme(QLatin1String("draw-text")));
0117 
0118     d->originPage  = new IPTCOrigin(this);
0119     d->page_origin = addPage(d->originPage, i18nc("@item: iptc", "Origin"));
0120     d->page_origin->setIcon(QIcon::fromTheme(QLatin1String("globe")));
0121 
0122     d->creditsPage  = new IPTCCredits(this);
0123     d->page_credits = addPage(d->creditsPage, i18nc("@item: iptc", "Credits"));
0124     d->page_credits->setIcon(QIcon::fromTheme(QLatin1String("address-book-new")));
0125 
0126     d->subjectsPage  = new IPTCSubjects(this);
0127     d->page_subjects = addPage(d->subjectsPage, i18nc("@item: iptc", "Subjects"));
0128     d->page_subjects->setIcon(QIcon::fromTheme(QLatin1String("feed-subscribe")));
0129 
0130     d->keywordsPage  = new IPTCKeywords(this);
0131     d->page_keywords = addPage(d->keywordsPage, i18nc("@item: iptc", "Keywords"));
0132     d->page_keywords->setIcon(QIcon::fromTheme(QLatin1String("bookmark-new")));
0133 
0134     d->categoriesPage  = new IPTCCategories(this);
0135     d->page_categories = addPage(d->categoriesPage, i18nc("@item: iptc", "Categories"));
0136     d->page_categories->setIcon(QIcon::fromTheme(QLatin1String("folder-pictures")));
0137 
0138     d->statusPage  = new IPTCStatus(this);
0139     d->page_status = addPage(d->statusPage, i18nc("@item: iptc", "Status"));
0140     d->page_status->setIcon(QIcon::fromTheme(QLatin1String("view-task")));
0141 
0142     d->propertiesPage  = new IPTCProperties(this);
0143     d->page_properties = addPage(d->propertiesPage, i18nc("@item: iptc", "Properties"));
0144     d->page_properties->setIcon(QIcon::fromTheme(QLatin1String("draw-freehand")));
0145 
0146     d->envelopePage  = new IPTCEnvelope(this);
0147     d->page_envelope = addPage(d->envelopePage, i18nc("@item: iptc", "Envelope"));
0148     d->page_envelope->setIcon(QIcon::fromTheme(QLatin1String("mail-mark-unread")));
0149 
0150     // ---------------------------------------------------------------
0151 
0152     connect(d->contentPage, SIGNAL(signalModified()),
0153             this, SLOT(slotModified()));
0154 
0155     connect(d->propertiesPage, SIGNAL(signalModified()),
0156             this, SLOT(slotModified()));
0157 
0158     connect(d->subjectsPage, SIGNAL(signalModified()),
0159             this, SLOT(slotModified()));
0160 
0161     connect(d->keywordsPage, SIGNAL(signalModified()),
0162             this, SLOT(slotModified()));
0163 
0164     connect(d->categoriesPage, SIGNAL(signalModified()),
0165             this, SLOT(slotModified()));
0166 
0167     connect(d->creditsPage, SIGNAL(signalModified()),
0168             this, SLOT(slotModified()));
0169 
0170     connect(d->statusPage, SIGNAL(signalModified()),
0171             this, SLOT(slotModified()));
0172 
0173     connect(d->originPage, SIGNAL(signalModified()),
0174             this, SLOT(slotModified()));
0175 
0176     connect(d->envelopePage, SIGNAL(signalModified()),
0177             this, SLOT(slotModified()));
0178 
0179     // ------------------------------------------------------------
0180 
0181     readSettings();
0182     slotItemChanged();
0183 }
0184 
0185 IPTCEditWidget::~IPTCEditWidget()
0186 {
0187     delete d;
0188 }
0189 
0190 void IPTCEditWidget::readSettings()
0191 {
0192     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0193     KConfigGroup group        = config->group(QLatin1String("All Metadata Edit Settings"));
0194     showPage(group.readEntry(QLatin1String("All IPTC Edit Page"), 0));
0195     d->contentPage->setCheckedSyncJFIFComment(group.readEntry(QLatin1String("All Sync JFIF Comment"), true));
0196     d->contentPage->setCheckedSyncEXIFComment(group.readEntry(QLatin1String("All Sync EXIF Comment"), true));
0197     d->originPage->setCheckedSyncEXIFDate(group.readEntry(QLatin1String("All Sync EXIF Date"), true));
0198 }
0199 
0200 void IPTCEditWidget::saveSettings()
0201 {
0202     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0203     KConfigGroup group        = config->group(QLatin1String("All Metadata Edit Settings"));
0204     group.writeEntry(QLatin1String("All IPTC Edit Page"),    activePageIndex());
0205     group.writeEntry(QLatin1String("All Sync JFIF Comment"), d->contentPage->syncJFIFCommentIsChecked());
0206     group.writeEntry(QLatin1String("All Sync EXIF Comment"), d->contentPage->syncEXIFCommentIsChecked());
0207     group.writeEntry(QLatin1String("All Sync EXIF Date"),    d->originPage->syncEXIFDateIsChecked());
0208     config->sync();
0209 }
0210 
0211 void IPTCEditWidget::slotItemChanged()
0212 {
0213     d->page_content->setHeader(d->dlg->currentItemTitleHeader(
0214                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0215                                        .arg(i18nc("@title", "Content Information"))
0216                                        .arg(i18nc("@title", "Describe the visual content of the item"))));
0217 
0218     d->page_origin->setHeader(d->dlg->currentItemTitleHeader(
0219                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0220                                        .arg(i18nc("@title", "Origin Information"))
0221                                        .arg(i18nc("@title", "Formal descriptive information about the item"))));
0222 
0223     d->page_credits->setHeader(d->dlg->currentItemTitleHeader(
0224                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0225                                        .arg(i18nc("@title", "Credit Information"))
0226                                        .arg(i18nc("@title", "Record copyright information about the item"))));
0227 
0228     d->page_subjects->setHeader(d->dlg->currentItemTitleHeader(
0229                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0230                                        .arg(i18nc("@title", "Subject Information"))
0231                                        .arg(i18nc("@title", "Record subject information about the item"))));
0232 
0233     d->page_keywords->setHeader(d->dlg->currentItemTitleHeader(
0234                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0235                                        .arg(i18nc("@title", "Keyword Information"))
0236                                        .arg(i18nc("@title", "Record keywords relevant to the item"))));
0237 
0238     d->page_categories->setHeader(d->dlg->currentItemTitleHeader(
0239                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0240                                        .arg(i18nc("@title", "Category Information"))
0241                                        .arg(i18nc("@title", "Record categories relevant to the item"))));
0242 
0243     d->page_status->setHeader(d->dlg->currentItemTitleHeader(
0244                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0245                                        .arg(i18nc("@title", "Status Information"))
0246                                        .arg(i18nc("@title", "Record workflow information"))));
0247 
0248     d->page_properties->setHeader(d->dlg->currentItemTitleHeader(
0249                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0250                                        .arg(i18nc("@title", "Status Properties"))
0251                                        .arg(i18nc("@title", "Record workflow properties"))));
0252 
0253     d->page_envelope->setHeader(d->dlg->currentItemTitleHeader(
0254                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0255                                        .arg(i18nc("@title", "Envelope Information"))
0256                                        .arg(i18nc("@title", "Record editorial details"))));
0257 
0258     QScopedPointer<DMetadata> meta(new DMetadata);
0259     meta->load((*d->dlg->currentItem()).toLocalFile());
0260 
0261     d->contentPage->readMetadata(*meta);
0262     d->originPage->readMetadata(*meta);
0263     d->creditsPage->readMetadata(*meta);
0264     d->subjectsPage->readMetadata(*meta);
0265     d->keywordsPage->readMetadata(*meta);
0266     d->categoriesPage->readMetadata(*meta);
0267     d->statusPage->readMetadata(*meta);
0268     d->propertiesPage->readMetadata(*meta);
0269     d->envelopePage->readMetadata(*meta);
0270 
0271     d->isReadOnly = (
0272                      (MetaEngineSettings::instance()->settings().metadataWritingMode == DMetadata::WRITE_TO_FILE_ONLY) &&
0273                      !QFileInfo((*d->dlg->currentItem()).toLocalFile()).isWritable()
0274                     );
0275 
0276     Q_EMIT signalSetReadOnly(d->isReadOnly);
0277 
0278     d->page_content->setEnabled(!d->isReadOnly);
0279     d->page_origin->setEnabled(!d->isReadOnly);
0280     d->page_credits->setEnabled(!d->isReadOnly);
0281     d->page_subjects->setEnabled(!d->isReadOnly);
0282     d->page_keywords->setEnabled(!d->isReadOnly);
0283     d->page_categories->setEnabled(!d->isReadOnly);
0284     d->page_status->setEnabled(!d->isReadOnly);
0285     d->page_properties->setEnabled(!d->isReadOnly);
0286     d->page_envelope->setEnabled(!d->isReadOnly);
0287 }
0288 
0289 void IPTCEditWidget::apply()
0290 {
0291     if (d->modified && !d->isReadOnly)
0292     {
0293         QScopedPointer<DMetadata> meta(new DMetadata);
0294         meta->load((*d->dlg->currentItem()).toLocalFile());
0295 
0296         d->contentPage->applyMetadata(*meta);
0297         d->originPage->applyMetadata(*meta);
0298         d->creditsPage->applyMetadata(*meta);
0299         d->subjectsPage->applyMetadata(*meta);
0300         d->keywordsPage->applyMetadata(*meta);
0301         d->categoriesPage->applyMetadata(*meta);
0302         d->statusPage->applyMetadata(*meta);
0303         d->propertiesPage->applyMetadata(*meta);
0304         d->envelopePage->applyMetadata(*meta);
0305 
0306         meta->applyChanges();
0307 
0308         d->modified = false;
0309     }
0310 }
0311 
0312 void IPTCEditWidget::slotModified()
0313 {
0314     if (!d->isReadOnly)
0315     {
0316         d->modified = true;
0317         Q_EMIT signalModified();
0318     }
0319 }
0320 
0321 void IPTCEditWidget::showPage(int page)
0322 {
0323     switch (page)
0324     {
0325         case 0:
0326             setCurrentPage(d->page_content);
0327             break;
0328         case 1:
0329             setCurrentPage(d->page_origin);
0330             break;
0331         case 2:
0332             setCurrentPage(d->page_credits);
0333             break;
0334         case 3:
0335             setCurrentPage(d->page_subjects);
0336             break;
0337         case 4:
0338             setCurrentPage(d->page_keywords);
0339             break;
0340         case 5:
0341             setCurrentPage(d->page_categories);
0342             break;
0343         case 6:
0344             setCurrentPage(d->page_status);
0345             break;
0346         case 7:
0347             setCurrentPage(d->page_properties);
0348             break;
0349         case 8:
0350             setCurrentPage(d->page_envelope);
0351             break;
0352         default:
0353             setCurrentPage(d->page_content);
0354             break;
0355     }
0356 }
0357 
0358 int IPTCEditWidget::activePageIndex() const
0359 {
0360     DConfigDlgWdgItem* const cur = currentPage();
0361 
0362     if (cur == d->page_content)    return 0;
0363     if (cur == d->page_origin)     return 1;
0364     if (cur == d->page_credits)    return 2;
0365     if (cur == d->page_subjects)   return 3;
0366     if (cur == d->page_keywords)   return 4;
0367     if (cur == d->page_categories) return 5;
0368     if (cur == d->page_status)     return 6;
0369     if (cur == d->page_properties) return 7;
0370     if (cur == d->page_envelope)   return 8;
0371 
0372     return 0;
0373 }
0374 
0375 bool IPTCEditWidget::isModified() const
0376 {
0377     return d->modified;
0378 }
0379 
0380 } // namespace DigikamGenericMetadataEditPlugin
0381 
0382 #include "moc_iptceditwidget.cpp"