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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2006-10-18
0007  * Description : EXIF adjustments 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 "exifadjust.h"
0016 
0017 // C++ includes
0018 
0019 #include <cmath>
0020 
0021 // Qt includes
0022 
0023 #include <QGridLayout>
0024 #include <QApplication>
0025 #include <QStyle>
0026 #include <QComboBox>
0027 #include <QDoubleSpinBox>
0028 
0029 // KDE includes
0030 
0031 #include <klocalizedstring.h>
0032 
0033 // Local includes
0034 
0035 #include "metadatacheckbox.h"
0036 
0037 namespace DigikamGenericMetadataEditPlugin
0038 {
0039 
0040 class Q_DECL_HIDDEN EXIFAdjust::Private
0041 {
0042 public:
0043 
0044     explicit Private()
0045     {
0046         brightnessCheck     = nullptr;
0047         gainControlCheck    = nullptr;
0048         contrastCheck       = nullptr;
0049         saturationCheck     = nullptr;
0050         sharpnessCheck      = nullptr;
0051         customRenderedCheck = nullptr;
0052         brightnessEdit      = nullptr;
0053         gainControlCB       = nullptr;
0054         contrastCB          = nullptr;
0055         saturationCB        = nullptr;
0056         sharpnessCB         = nullptr;
0057         customRenderedCB    = nullptr;
0058     }
0059 
0060     QCheckBox*        brightnessCheck;
0061 
0062     QComboBox*        gainControlCB;
0063     QComboBox*        contrastCB;
0064     QComboBox*        saturationCB;
0065     QComboBox*        sharpnessCB;
0066     QComboBox*        customRenderedCB;
0067 
0068     QDoubleSpinBox*   brightnessEdit;
0069 
0070     MetadataCheckBox* gainControlCheck;
0071     MetadataCheckBox* contrastCheck;
0072     MetadataCheckBox* saturationCheck;
0073     MetadataCheckBox* sharpnessCheck;
0074     MetadataCheckBox* customRenderedCheck;
0075 };
0076 
0077 EXIFAdjust::EXIFAdjust(QWidget* const parent)
0078     : MetadataEditPage(parent),
0079       d               (new Private)
0080 {
0081     QGridLayout* const grid = new QGridLayout(widget());
0082 
0083     // --------------------------------------------------------
0084 
0085     d->brightnessCheck = new QCheckBox(i18n("Brightness (APEX):"), this);
0086     d->brightnessEdit  = new QDoubleSpinBox(this);
0087     d->brightnessEdit->setRange(-99.99, 99.99);
0088     d->brightnessEdit->setSingleStep(0.1);
0089     d->brightnessEdit->setValue(0.0);
0090     d->brightnessEdit->setWhatsThis(i18n("Set here the brightness adjustment value in APEX unit "
0091                                          "used by camera to take the picture."));
0092 
0093     // --------------------------------------------------------
0094 
0095     d->gainControlCheck = new MetadataCheckBox(i18n("Gain Control:"), this);
0096     d->gainControlCB    = new QComboBox(this);
0097     d->gainControlCB->insertItem(0, i18nc("gain control", "None"));
0098     d->gainControlCB->insertItem(1, i18nc("gain control", "Low gain up"));
0099     d->gainControlCB->insertItem(2, i18nc("gain control", "High gain up"));
0100     d->gainControlCB->insertItem(3, i18nc("gain control", "Low gain down"));
0101     d->gainControlCB->insertItem(4, i18nc("gain control", "High gain down"));
0102     d->gainControlCB->setWhatsThis(i18n("Set here the degree of overall image gain adjustment "
0103                                         "used by camera to take the picture."));
0104 
0105     // --------------------------------------------------------
0106 
0107     d->contrastCheck = new MetadataCheckBox(i18n("Contrast:"), this);
0108     d->contrastCB    = new QComboBox(this);
0109     d->contrastCB->insertItem(0, i18nc("contrast mode", "Normal"));
0110     d->contrastCB->insertItem(1, i18nc("contrast mode", "Soft"));
0111     d->contrastCB->insertItem(2, i18nc("contrast mode", "Hard"));
0112     d->contrastCB->setWhatsThis(i18n("Set here the direction of contrast processing "
0113                                      "applied by the camera to take the picture."));
0114 
0115     // --------------------------------------------------------
0116 
0117     d->saturationCheck = new MetadataCheckBox(i18n("Saturation:"), this);
0118     d->saturationCB    = new QComboBox(this);
0119     d->saturationCB->insertItem(0, i18nc("saturation mode", "Normal"));
0120     d->saturationCB->insertItem(1, i18nc("saturation mode", "Low"));
0121     d->saturationCB->insertItem(2, i18nc("saturation mode", "High"));
0122     d->saturationCB->setWhatsThis(i18n("Set here the direction of saturation processing "
0123                                        "applied by the camera to take the picture."));
0124 
0125     // --------------------------------------------------------
0126 
0127     d->sharpnessCheck = new MetadataCheckBox(i18n("Sharpness:"), this);
0128     d->sharpnessCB    = new QComboBox(this);
0129     d->sharpnessCB->insertItem(0, i18nc("sharpness mode", "Normal"));
0130     d->sharpnessCB->insertItem(1, i18nc("sharpness mode", "Soft"));
0131     d->sharpnessCB->insertItem(2, i18nc("sharpness mode", "Hard"));
0132     d->sharpnessCB->setWhatsThis(i18n("Set here the direction of sharpness processing "
0133                                       "applied by the camera to take the picture."));
0134 
0135     // --------------------------------------------------------
0136 
0137     d->customRenderedCheck = new MetadataCheckBox(i18n("Custom rendered:"), this);
0138     d->customRenderedCB    = new QComboBox(this);
0139     d->customRenderedCB->insertItem(0, i18n("Normal process"));
0140     d->customRenderedCB->insertItem(1, i18n("Custom process"));
0141     d->customRenderedCB->setWhatsThis(i18n("Set here the use of special processing on "
0142                                            "image data, such as rendering geared to output."));
0143 
0144     grid->addWidget(d->brightnessCheck,     0, 0, 1, 1);
0145     grid->addWidget(d->brightnessEdit,      0, 2, 1, 1);
0146     grid->addWidget(d->gainControlCheck,    1, 0, 1, 1);
0147     grid->addWidget(d->gainControlCB,       1, 2, 1, 1);
0148     grid->addWidget(d->contrastCheck,       2, 0, 1, 1);
0149     grid->addWidget(d->contrastCB,          2, 2, 1, 1);
0150     grid->addWidget(d->saturationCheck,     3, 0, 1, 1);
0151     grid->addWidget(d->saturationCB,        3, 2, 1, 1);
0152     grid->addWidget(d->sharpnessCheck,      4, 0, 1, 1);
0153     grid->addWidget(d->sharpnessCB,         4, 2, 1, 1);
0154     grid->addWidget(d->customRenderedCheck, 5, 0, 1, 1);
0155     grid->addWidget(d->customRenderedCB,    5, 2, 1, 1);
0156     grid->setColumnStretch(1, 10);
0157     grid->setRowStretch(6, 10);
0158 
0159     int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0160                        QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0161 
0162     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0163     grid->setSpacing(spacing);
0164 
0165     // --------------------------------------------------------
0166 
0167     connect(d->brightnessCheck, SIGNAL(toggled(bool)),
0168             d->brightnessEdit, SLOT(setEnabled(bool)));
0169 
0170     connect(d->gainControlCheck, SIGNAL(toggled(bool)),
0171             d->gainControlCB, SLOT(setEnabled(bool)));
0172 
0173     connect(d->contrastCheck, SIGNAL(toggled(bool)),
0174             d->contrastCB, SLOT(setEnabled(bool)));
0175 
0176     connect(d->saturationCheck, SIGNAL(toggled(bool)),
0177             d->saturationCB, SLOT(setEnabled(bool)));
0178 
0179     connect(d->sharpnessCheck, SIGNAL(toggled(bool)),
0180             d->sharpnessCB, SLOT(setEnabled(bool)));
0181 
0182     connect(d->customRenderedCheck, SIGNAL(toggled(bool)),
0183             d->customRenderedCB, SLOT(setEnabled(bool)));
0184 
0185     // --------------------------------------------------------
0186 
0187     connect(d->brightnessCheck, SIGNAL(toggled(bool)),
0188             this, SIGNAL(signalModified()));
0189 
0190     connect(d->gainControlCheck, SIGNAL(toggled(bool)),
0191             this, SIGNAL(signalModified()));
0192 
0193     connect(d->contrastCheck, SIGNAL(toggled(bool)),
0194             this, SIGNAL(signalModified()));
0195 
0196     connect(d->saturationCheck, SIGNAL(toggled(bool)),
0197             this, SIGNAL(signalModified()));
0198 
0199     connect(d->sharpnessCheck, SIGNAL(toggled(bool)),
0200             this, SIGNAL(signalModified()));
0201 
0202     connect(d->customRenderedCheck, SIGNAL(toggled(bool)),
0203             this, SIGNAL(signalModified()));
0204 
0205     // --------------------------------------------------------
0206 
0207     connect(d->gainControlCB, SIGNAL(activated(int)),
0208             this, SIGNAL(signalModified()));
0209 
0210     connect(d->contrastCB, SIGNAL(activated(int)),
0211             this, SIGNAL(signalModified()));
0212 
0213     connect(d->saturationCB, SIGNAL(activated(int)),
0214             this, SIGNAL(signalModified()));
0215 
0216     connect(d->sharpnessCB, SIGNAL(activated(int)),
0217             this, SIGNAL(signalModified()));
0218 
0219     connect(d->customRenderedCB, SIGNAL(activated(int)),
0220             this, SIGNAL(signalModified()));
0221 
0222     connect(d->brightnessEdit, SIGNAL(valueChanged(double)),
0223             this, SIGNAL(signalModified()));
0224 }
0225 
0226 EXIFAdjust::~EXIFAdjust()
0227 {
0228     delete d;
0229 }
0230 
0231 void EXIFAdjust::readMetadata(const DMetadata& meta)
0232 {
0233     blockSignals(true);
0234 
0235     long int num=1, den=1;
0236     long     val=0;
0237 
0238     d->brightnessEdit->setValue(0.0);
0239     d->brightnessCheck->setChecked(false);
0240 
0241     if (meta.getExifTagRational("Exif.Photo.BrightnessValue", num, den))
0242     {
0243         d->brightnessEdit->setValue((double)(num) / (double)(den));
0244         d->brightnessCheck->setChecked(true);
0245     }
0246 
0247     d->brightnessEdit->setEnabled(d->brightnessCheck->isChecked());
0248 
0249     d->gainControlCB->setCurrentIndex(0);
0250     d->gainControlCheck->setChecked(false);
0251 
0252     if (meta.getExifTagLong("Exif.Photo.GainControl", val))
0253     {
0254         if (val >= 0 && val <= 4)
0255         {
0256             d->gainControlCB->setCurrentIndex(val);
0257             d->gainControlCheck->setChecked(true);
0258         }
0259         else
0260             d->gainControlCheck->setValid(false);
0261     }
0262 
0263     d->gainControlCB->setEnabled(d->gainControlCheck->isChecked());
0264 
0265     d->contrastCB->setCurrentIndex(0);
0266     d->contrastCheck->setChecked(false);
0267 
0268     if (meta.getExifTagLong("Exif.Photo.Contrast", val))
0269     {
0270         if (val >= 0 && val <= 2)
0271         {
0272             d->contrastCB->setCurrentIndex(val);
0273             d->contrastCheck->setChecked(true);
0274         }
0275         else
0276             d->contrastCheck->setValid(false);
0277     }
0278 
0279     d->contrastCB->setEnabled(d->contrastCheck->isChecked());
0280 
0281     d->saturationCB->setCurrentIndex(0);
0282     d->saturationCheck->setChecked(false);
0283 
0284     if (meta.getExifTagLong("Exif.Photo.Saturation", val))
0285     {
0286         if (val >= 0 && val <= 2)
0287         {
0288             d->saturationCB->setCurrentIndex(val);
0289             d->saturationCheck->setChecked(true);
0290         }
0291         else
0292             d->saturationCheck->setValid(false);
0293     }
0294 
0295     d->saturationCB->setEnabled(d->saturationCheck->isChecked());
0296 
0297     d->sharpnessCB->setCurrentIndex(0);
0298     d->sharpnessCheck->setChecked(false);
0299 
0300     if (meta.getExifTagLong("Exif.Photo.Sharpness", val))
0301     {
0302         if (val >= 0 && val <= 2)
0303         {
0304             d->sharpnessCB->setCurrentIndex(val);
0305             d->sharpnessCheck->setChecked(true);
0306         }
0307         else
0308             d->sharpnessCheck->setValid(false);
0309     }
0310 
0311     d->sharpnessCB->setEnabled(d->sharpnessCheck->isChecked());
0312 
0313     d->customRenderedCB->setCurrentIndex(0);
0314     d->customRenderedCheck->setChecked(false);
0315 
0316     if (meta.getExifTagLong("Exif.Photo.CustomRendered", val))
0317     {
0318         if (val >= 0 && val <= 1)
0319         {
0320             d->customRenderedCB->setCurrentIndex(val);
0321             d->customRenderedCheck->setChecked(true);
0322         }
0323         else
0324             d->customRenderedCheck->setValid(false);
0325     }
0326 
0327     d->customRenderedCB->setEnabled(d->customRenderedCheck->isChecked());
0328 
0329     blockSignals(false);
0330 }
0331 
0332 void EXIFAdjust::applyMetadata(const DMetadata& meta)
0333 {
0334     long int num=1, den=1;
0335 
0336     if (d->brightnessCheck->isChecked())
0337     {
0338         meta.convertToRational(d->brightnessEdit->value(), &num, &den, 1);
0339         meta.setExifTagRational("Exif.Photo.BrightnessValue", num, den);
0340     }
0341     else
0342         meta.removeExifTag("Exif.Photo.BrightnessValue");
0343 
0344     if (d->gainControlCheck->isChecked())
0345         meta.setExifTagLong("Exif.Photo.GainControl", d->gainControlCB->currentIndex());
0346     else if (d->gainControlCheck->isValid())
0347         meta.removeExifTag("Exif.Photo.GainControl");
0348 
0349     if (d->contrastCheck->isChecked())
0350         meta.setExifTagLong("Exif.Photo.Contrast", d->contrastCB->currentIndex());
0351     else if (d->contrastCheck->isValid())
0352         meta.removeExifTag("Exif.Photo.Contrast");
0353 
0354     if (d->saturationCheck->isChecked())
0355         meta.setExifTagLong("Exif.Photo.Saturation", d->saturationCB->currentIndex());
0356     else if (d->saturationCheck->isValid())
0357         meta.removeExifTag("Exif.Photo.Saturation");
0358 
0359     if (d->sharpnessCheck->isChecked())
0360         meta.setExifTagLong("Exif.Photo.Sharpness", d->sharpnessCB->currentIndex());
0361     else if (d->sharpnessCheck->isValid())
0362         meta.removeExifTag("Exif.Photo.Sharpness");
0363 
0364     if (d->customRenderedCheck->isChecked())
0365         meta.setExifTagLong("Exif.Photo.CustomRendered", d->customRenderedCB->currentIndex());
0366     else if (d->customRenderedCheck->isValid())
0367         meta.removeExifTag("Exif.Photo.CustomRendered");
0368 }
0369 
0370 } // namespace DigikamGenericMetadataEditPlugin
0371 
0372 #include "moc_exifadjust.cpp"