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        : 2011-03-14
0007  * Description : a widget to edit EXIF 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 "exifeditwidget.h"
0017 
0018 // Qt includes
0019 
0020 #include <QCloseEvent>
0021 #include <QKeyEvent>
0022 #include <QApplication>
0023 #include <QMenu>
0024 #include <QUrl>
0025 #include <QFileInfo>
0026 
0027 // KDE includes
0028 
0029 #include <ksharedconfig.h>
0030 #include <klocalizedstring.h>
0031 #include <kconfiggroup.h>
0032 
0033 // Local includes
0034 
0035 #include "metadataeditdialog.h"
0036 #include "metaenginesettings.h"
0037 #include "exifadjust.h"
0038 #include "exifcaption.h"
0039 #include "exifdatetime.h"
0040 #include "exifdevice.h"
0041 #include "exiflens.h"
0042 #include "exiflight.h"
0043 #include "digikam_debug.h"
0044 #include "dmetadata.h"
0045 
0046 namespace DigikamGenericMetadataEditPlugin
0047 {
0048 
0049 class Q_DECL_HIDDEN EXIFEditWidget::Private
0050 {
0051 
0052 public:
0053 
0054     explicit Private()
0055     {
0056         modified      = false;
0057         isReadOnly    = false;
0058         page_caption  = nullptr;
0059         page_datetime = nullptr;
0060         page_lens     = nullptr;
0061         page_device   = nullptr;
0062         page_light    = nullptr;
0063         page_adjust   = nullptr;
0064         captionPage   = nullptr;
0065         datetimePage  = nullptr;
0066         lensPage      = nullptr;
0067         devicePage    = nullptr;
0068         lightPage     = nullptr;
0069         adjustPage    = nullptr;
0070         dlg           = nullptr;
0071     }
0072 
0073     bool                modified;
0074     bool                isReadOnly;
0075 
0076     DConfigDlgWdgItem*  page_caption;
0077     DConfigDlgWdgItem*  page_datetime;
0078     DConfigDlgWdgItem*  page_lens;
0079     DConfigDlgWdgItem*  page_device;
0080     DConfigDlgWdgItem*  page_light;
0081     DConfigDlgWdgItem*  page_adjust;
0082 
0083     EXIFCaption*        captionPage;
0084     EXIFDateTime*       datetimePage;
0085     EXIFLens*           lensPage;
0086     EXIFDevice*         devicePage;
0087     EXIFLight*          lightPage;
0088     EXIFAdjust*         adjustPage;
0089 
0090     MetadataEditDialog* dlg;
0091 };
0092 
0093 EXIFEditWidget::EXIFEditWidget(MetadataEditDialog* const parent)
0094     : DConfigDlgWdg(parent),
0095       d            (new Private)
0096 {
0097     d->dlg           = parent;
0098 
0099     d->captionPage   = new EXIFCaption(this);
0100     d->page_caption  = addPage(d->captionPage, i18nc("@item: image caption", "Caption"));
0101     d->page_caption->setIcon(QIcon::fromTheme(QLatin1String("document-edit")));
0102 
0103     d->datetimePage  = new EXIFDateTime(this);
0104     d->page_datetime = addPage(d->datetimePage, i18nc("@item: date properties", "Date & Time"));
0105     d->page_datetime->setIcon(QIcon::fromTheme(QLatin1String("view-calendar")));
0106 
0107     d->lensPage      = new EXIFLens(this);
0108     d->page_lens     = addPage(d->lensPage, i18nc("@item: lens properties", "Lens"));
0109     d->page_lens->setIcon(QIcon::fromTheme(QLatin1String("camera-photo")));
0110 
0111     d->devicePage    = new EXIFDevice(this);
0112     d->page_device   = addPage(d->devicePage, i18nc("@item: device properties", "Device"));
0113     d->page_device->setIcon(QIcon::fromTheme(QLatin1String("scanner")));
0114 
0115     d->lightPage     = new EXIFLight(this);
0116     d->page_light    = addPage(d->lightPage, i18nc("@item; light properties", "Light"));
0117     d->page_light->setIcon(QIcon::fromTheme(QLatin1String("view-preview")));
0118 
0119     d->adjustPage    = new EXIFAdjust(this);
0120     d->page_adjust   = addPage(d->adjustPage, i18nc("@item: picture adjustments", "Adjustments"));
0121     d->page_adjust->setIcon(QIcon::fromTheme(QLatin1String("fill-color")));
0122 
0123     // ------------------------------------------------------------
0124 
0125     connect(d->captionPage, SIGNAL(signalModified()),
0126             this, SLOT(slotModified()));
0127 
0128     connect(d->datetimePage, SIGNAL(signalModified()),
0129             this, SLOT(slotModified()));
0130 
0131     connect(d->lensPage, SIGNAL(signalModified()),
0132             this, SLOT(slotModified()));
0133 
0134     connect(d->devicePage, SIGNAL(signalModified()),
0135             this, SLOT(slotModified()));
0136 
0137     connect(d->lightPage, SIGNAL(signalModified()),
0138             this, SLOT(slotModified()));
0139 
0140     connect(d->adjustPage, SIGNAL(signalModified()),
0141             this, SLOT(slotModified()));
0142 
0143     // ------------------------------------------------------------
0144 
0145     readSettings();
0146     slotItemChanged();
0147 }
0148 
0149 EXIFEditWidget::~EXIFEditWidget()
0150 {
0151     delete d;
0152 }
0153 
0154 void EXIFEditWidget::readSettings()
0155 {
0156     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0157     KConfigGroup group        = config->group(QLatin1String("All Metadata Edit Settings"));
0158     showPage(group.readEntry(QLatin1String("All EXIF Edit Page"), 0));
0159     d->captionPage->setCheckedSyncJFIFComment(group.readEntry(QLatin1String("All Sync JFIF Comment"), true));
0160     d->captionPage->setCheckedSyncXMPCaption(group.readEntry(QLatin1String("All Sync XMP Caption"), true));
0161     d->captionPage->setCheckedSyncIPTCCaption(group.readEntry(QLatin1String("All Sync IPTC Caption"), true));
0162     d->datetimePage->setCheckedSyncXMPDate(group.readEntry(QLatin1String("All Sync XMP Date"), true));
0163     d->datetimePage->setCheckedSyncIPTCDate(group.readEntry(QLatin1String("All Sync IPTC Date"), true));
0164 }
0165 
0166 void EXIFEditWidget::saveSettings()
0167 {
0168     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0169     KConfigGroup group        = config->group(QLatin1String("All Metadata Edit Settings"));
0170     group.writeEntry(QLatin1String("All EXIF Edit Page"),    activePageIndex());
0171     group.writeEntry(QLatin1String("All Sync JFIF Comment"), d->captionPage->syncJFIFCommentIsChecked());
0172     group.writeEntry(QLatin1String("All Sync XMP Caption"),  d->captionPage->syncXMPCaptionIsChecked());
0173     group.writeEntry(QLatin1String("All Sync IPTC Caption"), d->captionPage->syncIPTCCaptionIsChecked());
0174     group.writeEntry(QLatin1String("All Sync XMP Date"),     d->datetimePage->syncXMPDateIsChecked());
0175     group.writeEntry(QLatin1String("All Sync IPTC Date"),    d->datetimePage->syncIPTCDateIsChecked());
0176     config->sync();
0177 }
0178 
0179 void EXIFEditWidget::slotItemChanged()
0180 {
0181     d->page_caption->setHeader(d->dlg->currentItemTitleHeader(
0182                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0183                                        .arg(i18nc("@title", "Caption Information"))
0184                                        .arg(i18nc("@title", "Record technical descriptions"))));
0185 
0186     d->page_datetime->setHeader(d->dlg->currentItemTitleHeader(
0187                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0188                                        .arg(i18nc("@title", "Date and Time Information"))
0189                                        .arg(i18nc("@title", "Record camera time-stamp properties"))));
0190 
0191     d->page_lens->setHeader(d->dlg->currentItemTitleHeader(
0192                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0193                                        .arg(i18nc("@title", "Lens Settings"))
0194                                        .arg(i18nc("@title", "Record lens details used with camera"))));
0195 
0196     d->page_device->setHeader(d->dlg->currentItemTitleHeader(
0197                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0198                                        .arg(i18nc("@title", "Capture Device Settings"))
0199                                        .arg(i18nc("@title", "Record shot conditions used by camera"))));
0200 
0201     d->page_light->setHeader(d->dlg->currentItemTitleHeader(
0202                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0203                                        .arg(i18nc("@title", "Light Source Information"))
0204                                        .arg(i18nc("@title", "Record ambient condition captured by camera"))));
0205 
0206     d->page_adjust->setHeader(d->dlg->currentItemTitleHeader(
0207                                    QString::fromUtf8("<qt>%1<br/><i>%2</i></qt>")
0208                                        .arg(i18nc("@title", "Pictures Adjustments"))
0209                                        .arg(i18nc("@title", "Record technical details used by camera"))));
0210 
0211     QScopedPointer<DMetadata> meta(new DMetadata);
0212     meta->load((*d->dlg->currentItem()).toLocalFile());
0213 
0214     d->captionPage->readMetadata(*meta);
0215     d->datetimePage->readMetadata(*meta);
0216     d->lensPage->readMetadata(*meta);
0217     d->devicePage->readMetadata(*meta);
0218     d->lightPage->readMetadata(*meta);
0219     d->adjustPage->readMetadata(*meta);
0220 
0221     d->isReadOnly = (
0222                      (MetaEngineSettings::instance()->settings().metadataWritingMode == DMetadata::WRITE_TO_FILE_ONLY) &&
0223                      !QFileInfo((*d->dlg->currentItem()).toLocalFile()).isWritable()
0224                     );
0225 
0226     Q_EMIT signalSetReadOnly(d->isReadOnly);
0227 
0228     d->page_caption->setEnabled(!d->isReadOnly);
0229     d->page_datetime->setEnabled(!d->isReadOnly);
0230     d->page_lens->setEnabled(!d->isReadOnly);
0231     d->page_device->setEnabled(!d->isReadOnly);
0232     d->page_light->setEnabled(!d->isReadOnly);
0233     d->page_adjust->setEnabled(!d->isReadOnly);
0234 }
0235 
0236 void EXIFEditWidget::apply()
0237 {
0238     if (d->modified && !d->isReadOnly)
0239     {
0240         QScopedPointer<DMetadata> meta(new DMetadata);
0241         meta->load((*d->dlg->currentItem()).toLocalFile());
0242 
0243         d->captionPage->applyMetadata(*meta);
0244         d->datetimePage->applyMetadata(*meta);
0245         d->lensPage->applyMetadata(*meta);
0246         d->devicePage->applyMetadata(*meta);
0247         d->lightPage->applyMetadata(*meta);
0248         d->adjustPage->applyMetadata(*meta);
0249 
0250         meta->applyChanges();
0251 
0252         d->modified = false;
0253     }
0254 }
0255 
0256 void EXIFEditWidget::slotModified()
0257 {
0258     if (!d->isReadOnly)
0259     {
0260         d->modified = true;
0261         Q_EMIT signalModified();
0262     }
0263 }
0264 
0265 void EXIFEditWidget::showPage(int page)
0266 {
0267     switch (page)
0268     {
0269         case 0:
0270             setCurrentPage(d->page_caption);
0271             break;
0272         case 1:
0273             setCurrentPage(d->page_datetime);
0274             break;
0275         case 2:
0276             setCurrentPage(d->page_lens);
0277             break;
0278         case 3:
0279             setCurrentPage(d->page_device);
0280             break;
0281         case 4:
0282             setCurrentPage(d->page_light);
0283             break;
0284         case 5:
0285             setCurrentPage(d->page_adjust);
0286             break;
0287         default:
0288             setCurrentPage(d->page_caption);
0289             break;
0290     }
0291 }
0292 
0293 int EXIFEditWidget::activePageIndex() const
0294 {
0295     DConfigDlgWdgItem* const cur = currentPage();
0296 
0297     if (cur == d->page_caption)  return 0;
0298     if (cur == d->page_datetime) return 1;
0299     if (cur == d->page_lens)     return 2;
0300     if (cur == d->page_device)   return 3;
0301     if (cur == d->page_light)    return 4;
0302     if (cur == d->page_adjust)   return 5;
0303 
0304     return 0;
0305 }
0306 
0307 bool EXIFEditWidget::isModified() const
0308 {
0309     return d->modified;
0310 }
0311 
0312 } // namespace DigikamGenericMetadataEditPlugin
0313 
0314 #include "moc_exifeditwidget.cpp"