File indexing completed on 2025-01-19 03:50:57

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2022-09-24
0007  * Description : assign captions metadata batch tool.
0008  *
0009  * SPDX-FileCopyrightText: 2021-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 "assigncaptions.h"
0016 
0017 // Qt includes
0018 
0019 #include <QApplication>
0020 #include <QWidget>
0021 #include <QLabel>
0022 #include <QStyle>
0023 #include <QLayout>
0024 #include <QCheckBox>
0025 
0026 // KDE includes
0027 
0028 #include <klocalizedstring.h>
0029 
0030 // Local includes
0031 
0032 #include "digikam_debug.h"
0033 #include "digikam_globals.h"
0034 #include "dimg.h"
0035 #include "dfileoperations.h"
0036 #include "dinfointerface.h"
0037 #include "dmetadata.h"
0038 #include "dpluginbqm.h"
0039 #include "altlangstredit.h"
0040 #include "dlayoutbox.h"
0041 #include "captionvalues.h"
0042 #include "captionedit.h"
0043 
0044 namespace DigikamBqmAssignCaptionsPlugin
0045 {
0046 
0047 class Q_DECL_HIDDEN AssignCaptions::Private
0048 {
0049 public:
0050 
0051     explicit Private()
0052       : setTitles     (nullptr),
0053         titlesWidget  (nullptr),
0054         setCaptions   (nullptr),
0055         captionsWidget(nullptr),
0056         cleanupCB     (nullptr),
0057         changeSettings(true)
0058     {
0059     }
0060 
0061     QCheckBox*          setTitles;
0062     AltLangStrEdit*     titlesWidget;
0063 
0064     QCheckBox*          setCaptions;
0065     CaptionEdit*        captionsWidget;
0066 
0067     QCheckBox*          cleanupCB;
0068 
0069     bool                changeSettings;
0070 };
0071 
0072 AssignCaptions::AssignCaptions(QObject* const parent)
0073     : BatchTool(QLatin1String("AssignCaptions"), MetadataTool, parent),
0074       d        (new Private)
0075 {
0076 }
0077 
0078 AssignCaptions::~AssignCaptions()
0079 {
0080     delete d;
0081 }
0082 
0083 BatchTool* AssignCaptions::clone(QObject* const parent) const
0084 {
0085     return new AssignCaptions(parent);
0086 }
0087 
0088 void AssignCaptions::registerSettingsWidget()
0089 {
0090     const int spacing     = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0091                                  QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0092 
0093     DVBox* const vbox     = new DVBox;
0094     vbox->setContentsMargins(spacing, spacing, spacing, spacing);
0095 
0096     d->titlesWidget       = new AltLangStrEdit(vbox, 0);
0097     d->setTitles          = new QCheckBox(i18n("Titles:"), d->titlesWidget);
0098     d->setTitles->setChecked(false);
0099     d->titlesWidget->setPlaceholderText(i18nc("@info", "Enter title text here."));
0100     d->titlesWidget->setTitleWidget(d->setTitles);
0101     d->titlesWidget->slotEnabledInternalWidgets(false);
0102 
0103     d->captionsWidget     = new CaptionEdit(vbox);
0104 
0105     d->setCaptions        = new QCheckBox(i18n("Captions:"), d->captionsWidget);
0106     d->setCaptions->setChecked(false);
0107     d->captionsWidget->setPlaceholderText(i18nc("@info", "Enter caption text here."));
0108     d->captionsWidget->altLangStrEdit()->setTitleWidget(d->setCaptions);
0109     d->captionsWidget->altLangStrEdit()->slotEnabledInternalWidgets(false);
0110     d->captionsWidget->authorEdit()->setEnabled(false);
0111 
0112     d->cleanupCB          = new QCheckBox(i18n("Clean up and overwrite metadata"), vbox);
0113     d->cleanupCB->setToolTip(i18nc("@info", "If you turn on this options, titles and captions "
0114                                    "will be cleaned and replaced by the new values,\nelse "
0115                                    "old values will be merged with new values."));
0116 
0117     m_settingsWidget      = vbox;
0118 
0119     connect(d->setTitles, SIGNAL(toggled(bool)),
0120             this, SLOT(slotSettingsChanged()));
0121 
0122     connect(d->setTitles, SIGNAL(toggled(bool)),
0123             d->titlesWidget, SLOT(slotEnabledInternalWidgets(bool)));
0124 
0125     connect(d->titlesWidget, SIGNAL(signalModified(QString,QString)),
0126             this, SLOT(slotSettingsChanged()));
0127 
0128     connect(d->titlesWidget, SIGNAL(signalValueAdded(QString,QString)),
0129             this, SLOT(slotSettingsChanged()));
0130 
0131     connect(d->titlesWidget, SIGNAL(signalValueDeleted(QString)),
0132             this, SLOT(slotSettingsChanged()));
0133 
0134     connect(d->setCaptions, SIGNAL(toggled(bool)),
0135             this, SLOT(slotSettingsChanged()));
0136 
0137     connect(d->setCaptions, SIGNAL(toggled(bool)),
0138             d->captionsWidget->altLangStrEdit(), SLOT(slotEnabledInternalWidgets(bool)));
0139 
0140     connect(d->setCaptions, SIGNAL(toggled(bool)),
0141             d->captionsWidget->authorEdit(), SLOT(setEnabled(bool)));
0142 
0143     connect(d->captionsWidget, SIGNAL(signalModified()),
0144             this, SLOT(slotSettingsChanged()));
0145 
0146     connect(d->cleanupCB, SIGNAL(toggled(bool)),
0147             this, SLOT(slotSettingsChanged()));
0148 
0149     BatchTool::registerSettingsWidget();
0150 }
0151 
0152 BatchToolSettings AssignCaptions::defaultSettings()
0153 {
0154     BatchToolSettings settings;
0155 
0156     settings.insert(QLatin1String("SetTitles"),     false);
0157     settings.insert(QLatin1String("TitleValues"),   QVariant::fromValue(MetaEngine::AltLangMap()));
0158     settings.insert(QLatin1String("SetCaptions"),   false);
0159     settings.insert(QLatin1String("CaptionValues"), QVariant::fromValue(CaptionsMap()));
0160     settings.insert(QLatin1String("CleanUp"),       false);
0161 
0162     return settings;
0163 }
0164 
0165 void AssignCaptions::slotAssignSettings2Widget()
0166 {
0167     d->changeSettings             = false;
0168 
0169     bool setTitles                = settings()[QLatin1String("SetTitles")].toBool();
0170     MetaEngine::AltLangMap titles = qvariant_cast<MetaEngine::AltLangMap>(settings()[QLatin1String("TitleValues")]);
0171     bool setCaptions              = settings()[QLatin1String("SetCaptions")].toBool();
0172     CaptionsMap captions          = qvariant_cast<CaptionsMap>(settings()[QLatin1String("CaptionValues")]);
0173     bool cleanup                  = settings()[QLatin1String("CleanUp")].toBool();
0174 
0175     d->setTitles->setChecked(setTitles);
0176     d->setCaptions->setChecked(setCaptions);
0177 
0178     if (d->titlesWidget->values() != titles)
0179     {
0180         d->titlesWidget->setValues(titles);
0181     }
0182 
0183     if (d->captionsWidget->values() != captions)
0184     {
0185         d->captionsWidget->setValues(captions);
0186     }
0187 
0188     d->cleanupCB->setChecked(cleanup);
0189 
0190     d->changeSettings             = true;
0191 }
0192 
0193 void AssignCaptions::slotSettingsChanged()
0194 {
0195     if (d->changeSettings)
0196     {
0197         BatchToolSettings settings;
0198 
0199         settings.insert(QLatin1String("SetTitles"),     d->setTitles->isChecked());
0200         settings.insert(QLatin1String("TitleValues"),   QVariant::fromValue(d->titlesWidget->values()));
0201         settings.insert(QLatin1String("SetCaptions"),   d->setCaptions->isChecked());
0202         settings.insert(QLatin1String("CaptionValues"), QVariant::fromValue(d->captionsWidget->values()));
0203         settings.insert(QLatin1String("CleanUp"),       d->cleanupCB->isChecked());
0204 
0205         BatchTool::slotSettingsChanged(settings);
0206     }
0207 }
0208 
0209 bool AssignCaptions::toolOperations()
0210 {
0211     bool ret = true;
0212     QScopedPointer<DMetadata> meta(new DMetadata);
0213 
0214     if (image().isNull())
0215     {
0216         if (!meta->load(inputUrl().toLocalFile()))
0217         {
0218             return false;
0219         }
0220     }
0221     else
0222     {
0223         meta->setData(image().getMetadata());
0224     }
0225 
0226     bool setTitles                = settings()[QLatin1String("SetTitles")].toBool();
0227     MetaEngine::AltLangMap titles = qvariant_cast<MetaEngine::AltLangMap>(settings()[QLatin1String("TitleValues")]);
0228     bool setCaptions              = settings()[QLatin1String("SetCaptions")].toBool();
0229     CaptionsMap captions          = qvariant_cast<CaptionsMap>(settings()[QLatin1String("CaptionValues")]);
0230     bool cleanup                  = settings()[QLatin1String("CleanUp")].toBool();
0231 
0232     if (setTitles)
0233     {
0234         CaptionsMap orgTitlesMap;
0235 
0236         if (!cleanup)
0237         {
0238             orgTitlesMap = meta->getItemTitles();
0239         }
0240 
0241         MetaEngine::AltLangMap orgTitles = orgTitlesMap.toAltLangMap();
0242         MetaEngine::AltLangMap::const_iterator it;
0243 
0244         for (it = titles.constBegin() ; it != titles.constEnd() ; ++it)
0245         {
0246             orgTitles.insert( it.key(), it.value());
0247         }
0248 
0249         CaptionsMap newTitlesMap;
0250         newTitlesMap.fromAltLangMap(orgTitles);
0251         meta->setItemTitles(newTitlesMap);
0252         qCDebug(DIGIKAM_DPLUGIN_BQM_LOG) << "Assign Titles:" << orgTitles;
0253     }
0254 
0255     if (setCaptions)
0256     {
0257         CaptionsMap orgCaptionsMap;
0258 
0259         if (!cleanup)
0260         {
0261             orgCaptionsMap = meta->getItemComments();
0262         }
0263 
0264         CaptionsMap::const_iterator it;
0265 
0266         for (it = captions.constBegin() ; it != captions.constEnd() ; ++it)
0267         {
0268             orgCaptionsMap.insert(it.key(), it.value());
0269         }
0270 
0271         meta->setItemComments(orgCaptionsMap);
0272         qCDebug(DIGIKAM_DPLUGIN_BQM_LOG) << "Assign Captions:" << orgCaptionsMap;
0273     }
0274 
0275     if (image().isNull())
0276     {
0277         QFile::remove(outputUrl().toLocalFile());
0278         ret &= DFileOperations::copyFile(inputUrl().toLocalFile(), outputUrl().toLocalFile());
0279 
0280         if (ret)
0281         {
0282             ret &= meta->save(outputUrl().toLocalFile());
0283             qCDebug(DIGIKAM_DPLUGIN_BQM_LOG) << "Save metadata to file:" << ret;
0284         }
0285     }
0286     else
0287     {
0288         qCDebug(DIGIKAM_DPLUGIN_BQM_LOG) << "Save metadata to image";
0289         image().setMetadata(meta->data());
0290         ret &= savefromDImg();
0291     }
0292 
0293     return ret;
0294 }
0295 
0296 } // namespace DigikamBqmAssignCaptionsPlugin
0297 
0298 #include "moc_assigncaptions.cpp"