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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-10-16
0007  * Description : XMP keywords settings page.
0008  *
0009  * SPDX-FileCopyrightText: 2007-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 "xmpkeywords.h"
0016 
0017 // Qt includes
0018 
0019 #include <QCheckBox>
0020 #include <QPushButton>
0021 #include <QGridLayout>
0022 #include <QApplication>
0023 #include <QStyle>
0024 #include <QLineEdit>
0025 #include <QListWidget>
0026 
0027 // KDE includes
0028 
0029 #include <klocalizedstring.h>
0030 
0031 // Local includes
0032 
0033 #include "dtextedit.h"
0034 
0035 namespace DigikamGenericMetadataEditPlugin
0036 {
0037 
0038 class Q_DECL_HIDDEN XMPKeywords::Private
0039 {
0040 public:
0041 
0042     explicit Private()
0043       : addKeywordButton(nullptr),
0044         delKeywordButton(nullptr),
0045         repKeywordButton(nullptr),
0046         keywordsCheck   (nullptr),
0047         keywordEdit     (nullptr),
0048         keywordsBox     (nullptr)
0049     {
0050     }
0051 
0052     QStringList  oldKeywords;
0053 
0054     QPushButton* addKeywordButton;
0055     QPushButton* delKeywordButton;
0056     QPushButton* repKeywordButton;
0057 
0058     QCheckBox*   keywordsCheck;
0059 
0060     DTextEdit*   keywordEdit;
0061 
0062     QListWidget* keywordsBox;
0063 };
0064 
0065 XMPKeywords::XMPKeywords(QWidget* const parent)
0066     : MetadataEditPage(parent),
0067       d               (new Private)
0068 {
0069     QGridLayout* const grid = new QGridLayout(widget());
0070 
0071     // --------------------------------------------------------
0072 
0073     d->keywordsCheck = new QCheckBox(i18n("Use information retrieval words:"), this);
0074 
0075     d->keywordEdit   = new DTextEdit(this);
0076     d->keywordEdit->setLinesVisible(1);
0077     d->keywordEdit->setPlaceholderText(i18n("Set here a new keyword"));
0078 
0079     d->keywordsBox   = new QListWidget(this);
0080     d->keywordsBox->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
0081 
0082     d->addKeywordButton = new QPushButton( i18n("&Add"), this);
0083     d->delKeywordButton = new QPushButton( i18n("&Delete"), this);
0084     d->repKeywordButton = new QPushButton( i18n("&Replace"), this);
0085     d->addKeywordButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
0086     d->delKeywordButton->setIcon(QIcon::fromTheme(QLatin1String("edit-delete")));
0087     d->repKeywordButton->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
0088     d->delKeywordButton->setEnabled(false);
0089     d->repKeywordButton->setEnabled(false);
0090 
0091     // --------------------------------------------------------
0092 
0093     grid->setAlignment(Qt::AlignTop);
0094     grid->addWidget(d->keywordsCheck,       0, 0, 1, 2);
0095     grid->addWidget(d->keywordEdit,         1, 0, 1, 1);
0096     grid->addWidget(d->keywordsBox,         2, 0, 5, 1);
0097     grid->addWidget(d->addKeywordButton,    2, 1, 1, 1);
0098     grid->addWidget(d->delKeywordButton,    3, 1, 1, 1);
0099     grid->addWidget(d->repKeywordButton,    4, 1, 1, 1);
0100     grid->setColumnStretch(0, 10);
0101     grid->setRowStretch(5, 10);
0102 
0103     int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0104                        QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0105 
0106     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0107     grid->setSpacing(spacing);
0108 
0109     // --------------------------------------------------------
0110 
0111     connect(d->keywordsBox, SIGNAL(itemSelectionChanged()),
0112             this, SLOT(slotKeywordSelectionChanged()));
0113 
0114     connect(d->addKeywordButton, SIGNAL(clicked()),
0115             this, SLOT(slotAddKeyword()));
0116 
0117     connect(d->delKeywordButton, SIGNAL(clicked()),
0118             this, SLOT(slotDelKeyword()));
0119 
0120     connect(d->repKeywordButton, SIGNAL(clicked()),
0121             this, SLOT(slotRepKeyword()));
0122 
0123     // --------------------------------------------------------
0124 
0125     connect(d->keywordsCheck, SIGNAL(toggled(bool)),
0126             d->keywordEdit, SLOT(setEnabled(bool)));
0127 
0128     connect(d->keywordsCheck, SIGNAL(toggled(bool)),
0129             d->addKeywordButton, SLOT(setEnabled(bool)));
0130 
0131     connect(d->keywordsCheck, SIGNAL(toggled(bool)),
0132             d->delKeywordButton, SLOT(setEnabled(bool)));
0133 
0134     connect(d->keywordsCheck, SIGNAL(toggled(bool)),
0135             d->repKeywordButton, SLOT(setEnabled(bool)));
0136 
0137     connect(d->keywordsCheck, SIGNAL(toggled(bool)),
0138             d->keywordsBox, SLOT(setEnabled(bool)));
0139 
0140     // --------------------------------------------------------
0141 
0142     connect(d->keywordsCheck, SIGNAL(toggled(bool)),
0143             this, SIGNAL(signalModified()));
0144 
0145     connect(d->addKeywordButton, SIGNAL(clicked()),
0146             this, SIGNAL(signalModified()));
0147 
0148     connect(d->delKeywordButton, SIGNAL(clicked()),
0149             this, SIGNAL(signalModified()));
0150 
0151     connect(d->repKeywordButton, SIGNAL(clicked()),
0152             this, SIGNAL(signalModified()));
0153 }
0154 
0155 XMPKeywords::~XMPKeywords()
0156 {
0157     delete d;
0158 }
0159 
0160 void XMPKeywords::slotDelKeyword()
0161 {
0162     QListWidgetItem* const item = d->keywordsBox->currentItem();
0163 
0164     if (!item)
0165     {
0166         return;
0167     }
0168 
0169     d->keywordsBox->takeItem(d->keywordsBox->row(item));
0170     delete item;
0171 }
0172 
0173 void XMPKeywords::slotRepKeyword()
0174 {
0175     QString newKeyword = d->keywordEdit->text();
0176 
0177     if (newKeyword.isEmpty())
0178     {
0179         return;
0180     }
0181 
0182     if (!d->keywordsBox->selectedItems().isEmpty())
0183     {
0184         d->keywordsBox->selectedItems()[0]->setText(newKeyword);
0185         d->keywordEdit->clear();
0186     }
0187 }
0188 
0189 void XMPKeywords::slotKeywordSelectionChanged()
0190 {
0191     if (!d->keywordsBox->selectedItems().isEmpty())
0192     {
0193         d->keywordEdit->setText(d->keywordsBox->selectedItems()[0]->text());
0194         d->delKeywordButton->setEnabled(true);
0195         d->repKeywordButton->setEnabled(true);
0196     }
0197     else
0198     {
0199         d->delKeywordButton->setEnabled(false);
0200         d->repKeywordButton->setEnabled(false);
0201     }
0202 }
0203 
0204 void XMPKeywords::slotAddKeyword()
0205 {
0206     QString newKeyword = d->keywordEdit->text();
0207 
0208     if (newKeyword.isEmpty())
0209     {
0210         return;
0211     }
0212 
0213     bool found = false;
0214 
0215     for (int i = 0 ; i < d->keywordsBox->count() ; ++i)
0216     {
0217         QListWidgetItem* const item = d->keywordsBox->item(i);
0218 
0219         if (newKeyword == item->text())
0220         {
0221             found = true;
0222             break;
0223         }
0224     }
0225 
0226     if (!found)
0227     {
0228         d->keywordsBox->insertItem(d->keywordsBox->count(), newKeyword);
0229         d->keywordEdit->clear();
0230     }
0231 }
0232 
0233 void XMPKeywords::readMetadata(const DMetadata& meta)
0234 {
0235     blockSignals(true);
0236 
0237     d->oldKeywords = meta.getXmpKeywords();
0238 
0239     d->keywordsBox->clear();
0240     d->keywordsCheck->setChecked(false);
0241 
0242     if (!d->oldKeywords.isEmpty())
0243     {
0244         d->keywordsBox->insertItems(0, d->oldKeywords);
0245         d->keywordsCheck->setChecked(true);
0246     }
0247 
0248     d->keywordEdit->setEnabled(d->keywordsCheck->isChecked());
0249     d->keywordsBox->setEnabled(d->keywordsCheck->isChecked());
0250     d->addKeywordButton->setEnabled(d->keywordsCheck->isChecked());
0251     d->delKeywordButton->setEnabled(d->keywordsCheck->isChecked());
0252 
0253     blockSignals(false);
0254 }
0255 
0256 void XMPKeywords::applyMetadata(const DMetadata& meta)
0257 {
0258     QStringList newKeywords;
0259 
0260     for (int i = 0 ; i < d->keywordsBox->count() ; ++i)
0261     {
0262         QListWidgetItem* const item = d->keywordsBox->item(i);
0263         newKeywords.append(item->text());
0264     }
0265 
0266     // We remove in first all existing keywords.
0267 
0268     meta.removeXmpTag("Xmp.dc.subject");
0269 
0270     // And add new list if necessary.
0271 
0272     if (d->keywordsCheck->isChecked())
0273     {
0274         meta.setXmpKeywords(newKeywords);
0275     }
0276 }
0277 
0278 } // namespace DigikamGenericMetadataEditPlugin
0279 
0280 #include "moc_xmpkeywords.cpp"