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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-10-08
0007  * Description : a widget to edit Application2 ObjectAttribute
0008  *               Iptc tag.
0009  *
0010  * SPDX-FileCopyrightText: 2007-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "objectattributesedit.h"
0017 
0018 // Qt includes
0019 
0020 #include <QCheckBox>
0021 #include <QToolTip>
0022 #include <QPushButton>
0023 #include <QGridLayout>
0024 #include <QComboBox>
0025 #include <QApplication>
0026 #include <QListWidget>
0027 
0028 // KDE includes
0029 
0030 #include <klocalizedstring.h>
0031 
0032 // Local includes
0033 
0034 #include "metadatacheckbox.h"
0035 #include "squeezedcombobox.h"
0036 #include "dtextedit.h"
0037 
0038 using namespace Digikam;
0039 
0040 namespace DigikamGenericMetadataEditPlugin
0041 {
0042 
0043 class Q_DECL_HIDDEN ObjectAttributesEdit::Private
0044 {
0045 public:
0046 
0047     explicit Private()
0048       : addValueButton(nullptr),
0049         delValueButton(nullptr),
0050         repValueButton(nullptr),
0051         valueEdit     (nullptr),
0052         valueBox      (nullptr),
0053         valueCheck    (nullptr),
0054         dataList      (nullptr)
0055     {
0056     }
0057 
0058     QStringList       oldValues;
0059 
0060     QPushButton*      addValueButton;
0061     QPushButton*      delValueButton;
0062     QPushButton*      repValueButton;
0063 
0064     DPlainTextEdit*   valueEdit;
0065 
0066     QListWidget*      valueBox;
0067 
0068     MetadataCheckBox* valueCheck;
0069 
0070     SqueezedComboBox* dataList;
0071 };
0072 
0073 ObjectAttributesEdit::ObjectAttributesEdit(QWidget* const parent, int size)
0074     : QWidget(parent),
0075       d      (new Private)
0076 {
0077     QGridLayout* const grid = new QGridLayout(this);
0078 
0079     // --------------------------------------------------------
0080 
0081     d->valueCheck     = new MetadataCheckBox(i18n("Attribute:"), this);
0082 
0083     d->addValueButton = new QPushButton(this);
0084     d->delValueButton = new QPushButton(this);
0085     d->repValueButton = new QPushButton(this);
0086     d->addValueButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
0087     d->delValueButton->setIcon(QIcon::fromTheme(QLatin1String("edit-delete")));
0088     d->repValueButton->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
0089     d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
0090     d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
0091     d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
0092     d->delValueButton->setEnabled(false);
0093     d->repValueButton->setEnabled(false);
0094 
0095     d->valueBox       = new QListWidget(this);
0096     d->valueBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
0097     d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0098 
0099     // --------------------------------------------------------
0100 
0101     d->dataList       = new SqueezedComboBox(this);
0102     d->dataList->model()->sort(0);
0103     d->dataList->setWhatsThis(i18n("Select here the editorial attribute of content."));
0104     d->dataList->addSqueezedItem(QLatin1String("001 - ") + i18nc("Content type", "Current"));
0105     d->dataList->addSqueezedItem(QLatin1String("002 - ") + i18nc("Content type", "Analysis"));
0106     d->dataList->addSqueezedItem(QLatin1String("003 - ") + i18nc("Content type", "Archive material"));
0107     d->dataList->addSqueezedItem(QLatin1String("004 - ") + i18nc("Content type", "Background"));
0108     d->dataList->addSqueezedItem(QLatin1String("005 - ") + i18nc("Content type", "Feature"));
0109     d->dataList->addSqueezedItem(QLatin1String("006 - ") + i18nc("Content type", "Forecast"));
0110     d->dataList->addSqueezedItem(QLatin1String("007 - ") + i18nc("Content type", "History"));
0111     d->dataList->addSqueezedItem(QLatin1String("008 - ") + i18nc("Content type", "Obituary"));
0112     d->dataList->addSqueezedItem(QLatin1String("009 - ") + i18nc("Content type", "Opinion"));
0113     d->dataList->addSqueezedItem(QLatin1String("010 - ") + i18nc("Content type", "Polls & Surveys"));
0114     d->dataList->addSqueezedItem(QLatin1String("011 - ") + i18nc("Content type", "Profile"));
0115     d->dataList->addSqueezedItem(QLatin1String("012 - ") + i18nc("Content type", "Results Listings & Table"));
0116     d->dataList->addSqueezedItem(QLatin1String("013 - ") + i18nc("Content type", "Side bar & Supporting information"));
0117     d->dataList->addSqueezedItem(QLatin1String("014 - ") + i18nc("Content type", "Summary"));
0118     d->dataList->addSqueezedItem(QLatin1String("015 - ") + i18nc("Content type", "Transcript & Verbatim"));
0119     d->dataList->addSqueezedItem(QLatin1String("016 - ") + i18nc("Content type", "Interview"));
0120     d->dataList->addSqueezedItem(QLatin1String("017 - ") + i18nc("Content type", "From the Scene"));
0121     d->dataList->addSqueezedItem(QLatin1String("018 - ") + i18nc("Content type", "Retrospective"));
0122     d->dataList->addSqueezedItem(QLatin1String("019 - ") + i18nc("Content type", "Statistics"));
0123     d->dataList->addSqueezedItem(QLatin1String("020 - ") + i18nc("Content type", "Update"));
0124     d->dataList->addSqueezedItem(QLatin1String("021 - ") + i18nc("Content type", "Wrap-up"));
0125     d->dataList->addSqueezedItem(QLatin1String("022 - ") + i18nc("Content type", "Press Release"));
0126 
0127     // --------------------------------------------------------
0128 
0129     d->valueEdit = new DPlainTextEdit(this);
0130     d->valueEdit->setLinesVisible(1);
0131     QString whatsThis = i18n("Set here the editorial attribute description of "
0132                              "content.");
0133 
0134     if (size != -1)
0135     {
0136         whatsThis.append(i18n(" This field is limited to "));
0137         d->valueEdit->setMaxLength(size);
0138         whatsThis.append(i18np("%1 character.","%1 characters.", size));
0139 
0140         connect(d->valueEdit, SIGNAL(textChanged()),
0141                 this, SLOT(slotLineEditModified()));
0142     }
0143 
0144     d->valueEdit->setWhatsThis(whatsThis);
0145     d->valueEdit->setPlaceholderText(i18n("Set here the editorial description"));
0146 
0147     // --------------------------------------------------------
0148 
0149     grid->setAlignment(Qt::AlignTop);
0150     grid->addWidget(d->valueCheck,     0, 0, 1, 1);
0151     grid->addWidget(d->addValueButton, 0, 1, 1, 1);
0152     grid->addWidget(d->delValueButton, 0, 2, 1, 1);
0153     grid->addWidget(d->repValueButton, 0, 3, 1, 1);
0154     grid->addWidget(d->valueBox,       0, 4, 4, 1);
0155     grid->addWidget(d->dataList,       1, 0, 1, 4);
0156     grid->addWidget(d->valueEdit,      2, 0, 1, 4);
0157     grid->setRowStretch(3, 10);
0158     grid->setColumnStretch(0, 10);
0159     grid->setColumnStretch(4, 10);
0160     grid->setContentsMargins(QMargins());
0161     grid->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0162                           QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)));
0163 
0164     // --------------------------------------------------------
0165 
0166     connect(d->valueBox, SIGNAL(itemSelectionChanged()),
0167             this, SLOT(slotSelectionChanged()));
0168 
0169     connect(d->addValueButton, SIGNAL(clicked()),
0170             this, SLOT(slotAddValue()));
0171 
0172     connect(d->delValueButton, SIGNAL(clicked()),
0173             this, SLOT(slotDeleteValue()));
0174 
0175     connect(d->repValueButton, SIGNAL(clicked()),
0176             this, SLOT(slotReplaceValue()));
0177 
0178     // --------------------------------------------------------
0179 
0180     connect(d->valueCheck, SIGNAL(toggled(bool)),
0181             d->valueEdit, SLOT(setEnabled(bool)));
0182 
0183     connect(d->valueCheck, SIGNAL(toggled(bool)),
0184             d->dataList, SLOT(setEnabled(bool)));
0185 
0186     connect(d->valueCheck, SIGNAL(toggled(bool)),
0187             d->addValueButton, SLOT(setEnabled(bool)));
0188 
0189     connect(d->valueCheck, SIGNAL(toggled(bool)),
0190             d->delValueButton, SLOT(setEnabled(bool)));
0191 
0192     connect(d->valueCheck, SIGNAL(toggled(bool)),
0193             d->repValueButton, SLOT(setEnabled(bool)));
0194 
0195     connect(d->valueCheck, SIGNAL(toggled(bool)),
0196             d->valueBox, SLOT(setEnabled(bool)));
0197 
0198     // --------------------------------------------------------
0199 
0200     connect(d->valueCheck, SIGNAL(toggled(bool)),
0201             this, SIGNAL(signalModified()));
0202 
0203     connect(d->addValueButton, SIGNAL(clicked()),
0204             this, SIGNAL(signalModified()));
0205 
0206     connect(d->delValueButton, SIGNAL(clicked()),
0207             this, SIGNAL(signalModified()));
0208 
0209     connect(d->repValueButton, SIGNAL(clicked()),
0210             this, SIGNAL(signalModified()));
0211 }
0212 
0213 ObjectAttributesEdit::~ObjectAttributesEdit()
0214 {
0215     delete d;
0216 }
0217 
0218 void ObjectAttributesEdit::slotDeleteValue()
0219 {
0220     QListWidgetItem* const item = d->valueBox->currentItem();
0221 
0222     if (!item)
0223     {
0224         return;
0225     }
0226 
0227     d->valueBox->takeItem(d->valueBox->row(item));
0228     delete item;
0229 }
0230 
0231 void ObjectAttributesEdit::slotReplaceValue()
0232 {
0233     QString newValue = d->dataList->itemHighlighted().left(3);
0234     newValue.append(QString::fromUtf8(":%1").arg(d->valueEdit->text()));
0235 
0236     if (!d->valueBox->selectedItems().isEmpty())
0237     {
0238         d->valueBox->selectedItems()[0]->setText(newValue);
0239     }
0240 }
0241 
0242 void ObjectAttributesEdit::slotSelectionChanged()
0243 {
0244     if (!d->valueBox->selectedItems().isEmpty())
0245     {
0246         bool ok   = false;
0247         int index = d->valueBox->selectedItems()[0]->text().section(QLatin1Char(':'), 0, 0).toInt(&ok);
0248 
0249         if (ok)
0250         {
0251             d->dataList->setCurrentIndex(index-1);
0252             d->valueEdit->setText(d->valueBox->selectedItems()[0]->text().section(QLatin1Char(':'), -1));
0253             d->delValueButton->setEnabled(true);
0254             d->repValueButton->setEnabled(true);
0255             return;
0256         }
0257     }
0258 
0259     d->delValueButton->setEnabled(false);
0260     d->repValueButton->setEnabled(false);
0261 }
0262 
0263 void ObjectAttributesEdit::slotAddValue()
0264 {
0265     QString newValue = d->dataList->itemHighlighted().left(3);
0266     newValue.append(QLatin1Char(':'));
0267 
0268     if (!d->valueEdit->text().isEmpty())
0269     {
0270         newValue.append(d->valueEdit->text());
0271     }
0272     else
0273     {
0274         newValue.append(d->dataList->itemHighlighted()
0275                         .section(QLatin1String(" - "), -1));
0276     }
0277 
0278     bool found = false;
0279 
0280     for (int i = 0 ; i < d->valueBox->count() ; ++i)
0281     {
0282         QListWidgetItem* const item = d->valueBox->item(i);
0283 
0284         if (newValue == item->text())
0285         {
0286             found = true;
0287             break;
0288         }
0289     }
0290 
0291     if (!found)
0292     {
0293         d->valueBox->insertItem(d->valueBox->count(), newValue);
0294     }
0295 }
0296 
0297 void ObjectAttributesEdit::setValues(const QStringList& values)
0298 {
0299     blockSignals(true);
0300     d->oldValues = values;
0301 
0302     d->valueBox->clear();
0303     d->valueCheck->setChecked(false);
0304 
0305     if (!d->oldValues.isEmpty())
0306     {
0307         d->valueBox->insertItems(0, d->oldValues);
0308         d->valueCheck->setChecked(true);
0309     }
0310 
0311     d->dataList->setEnabled(d->valueCheck->isChecked());
0312     d->valueBox->setEnabled(d->valueCheck->isChecked());
0313     d->addValueButton->setEnabled(d->valueCheck->isChecked());
0314     d->delValueButton->setEnabled(d->valueCheck->isChecked());
0315 
0316     blockSignals(false);
0317 }
0318 
0319 bool ObjectAttributesEdit::getValues(QStringList& oldValues, QStringList& newValues)
0320 {
0321     oldValues = d->oldValues;
0322     newValues.clear();
0323 
0324     for (int i = 0 ; i < d->valueBox->count() ; ++i)
0325     {
0326         QListWidgetItem* const item = d->valueBox->item(i);
0327         newValues.append(item->text());
0328     }
0329 
0330     return d->valueCheck->isChecked();
0331 }
0332 
0333 void ObjectAttributesEdit::setValid(bool v)
0334 {
0335     d->valueCheck->setValid(v);
0336 }
0337 
0338 bool ObjectAttributesEdit::isValid() const
0339 {
0340     return d->valueCheck->isValid();
0341 }
0342 
0343 void ObjectAttributesEdit::slotLineEditModified()
0344 {
0345     QToolTip::showText(d->valueEdit->mapToGlobal(QPoint(0, (-1)*(d->valueEdit->height() + 16))),
0346                        i18np("%1 character left", "%1 characters left",
0347                        d->valueEdit->maxLength() - d->valueEdit->text().size()),
0348                        d->valueEdit);
0349 }
0350 
0351 } // namespace DigikamGenericMetadataEditPlugin
0352 
0353 #include "moc_objectattributesedit.cpp"