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 a tag with multiple fixed values.
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 "multivaluesedit.h"
0016 
0017 // Qt includes
0018 
0019 #include <QCheckBox>
0020 #include <QPushButton>
0021 #include <QGridLayout>
0022 #include <QApplication>
0023 #include <QComboBox>
0024 #include <QListWidget>
0025 
0026 // KDE includes
0027 
0028 #include <klocalizedstring.h>
0029 
0030 // Local includes
0031 
0032 #include "squeezedcombobox.h"
0033 #include "metadatacheckbox.h"
0034 
0035 using namespace Digikam;
0036 
0037 namespace DigikamGenericMetadataEditPlugin
0038 {
0039 
0040 class Q_DECL_HIDDEN MultiValuesEdit::Private
0041 {
0042 public:
0043 
0044     explicit Private()
0045       : addValueButton(nullptr),
0046         delValueButton(nullptr),
0047         repValueButton(nullptr),
0048         valueBox      (nullptr),
0049         valueCheck    (nullptr),
0050         dataList      (nullptr)
0051     {
0052     }
0053 
0054     QStringList       oldValues;
0055 
0056     QPushButton*      addValueButton;
0057     QPushButton*      delValueButton;
0058     QPushButton*      repValueButton;
0059 
0060     QListWidget*      valueBox;
0061 
0062     MetadataCheckBox* valueCheck;
0063 
0064     SqueezedComboBox* dataList;
0065 };
0066 
0067 MultiValuesEdit::MultiValuesEdit(QWidget* const parent, const QString& title, const QString& desc)
0068     : QWidget(parent),
0069       d      (new Private)
0070 {
0071     QGridLayout* const grid = new QGridLayout(this);
0072 
0073     // --------------------------------------------------------
0074 
0075     d->valueCheck     = new MetadataCheckBox(title, this);
0076 
0077     d->addValueButton = new QPushButton(this);
0078     d->delValueButton = new QPushButton(this);
0079     d->repValueButton = new QPushButton(this);
0080     d->addValueButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
0081     d->delValueButton->setIcon(QIcon::fromTheme(QLatin1String("edit-delete")));
0082     d->repValueButton->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
0083     d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
0084     d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
0085     d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
0086     d->delValueButton->setEnabled(false);
0087     d->repValueButton->setEnabled(false);
0088 
0089     d->valueBox = new QListWidget(this);
0090     d->valueBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored);
0091     d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0092 
0093     d->dataList = new SqueezedComboBox(this);
0094     d->dataList->model()->sort(0);
0095     d->dataList->setWhatsThis(desc);
0096 
0097     // --------------------------------------------------------
0098 
0099     grid->setAlignment( Qt::AlignTop );
0100     grid->addWidget(d->valueCheck,      0, 0, 1, 1);
0101     grid->addWidget(d->addValueButton,  0, 1, 1, 1);
0102     grid->addWidget(d->delValueButton,  0, 2, 1, 1);
0103     grid->addWidget(d->repValueButton,  0, 3, 1, 1);
0104     grid->addWidget(d->valueBox,        0, 4, 3, 1);
0105     grid->addWidget(d->dataList,        2, 0, 1, 4);
0106     grid->setRowStretch(1, 10);
0107     grid->setColumnStretch(0, 10);
0108     grid->setColumnStretch(4, 100);
0109     grid->setContentsMargins(QMargins());
0110     grid->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0111                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)));
0112 
0113     // --------------------------------------------------------
0114 
0115     connect(d->valueBox, SIGNAL(itemSelectionChanged()),
0116             this, SLOT(slotSelectionChanged()));
0117 
0118     connect(d->addValueButton, SIGNAL(clicked()),
0119             this, SLOT(slotAddValue()));
0120 
0121     connect(d->delValueButton, SIGNAL(clicked()),
0122             this, SLOT(slotDeleteValue()));
0123 
0124     connect(d->repValueButton, SIGNAL(clicked()),
0125             this, SLOT(slotReplaceValue()));
0126 
0127     // --------------------------------------------------------
0128 
0129     connect(d->valueCheck, SIGNAL(toggled(bool)),
0130             d->dataList, SLOT(setEnabled(bool)));
0131 
0132     connect(d->valueCheck, SIGNAL(toggled(bool)),
0133             d->addValueButton, SLOT(setEnabled(bool)));
0134 
0135     connect(d->valueCheck, SIGNAL(toggled(bool)),
0136             d->delValueButton, SLOT(setEnabled(bool)));
0137 
0138     connect(d->valueCheck, SIGNAL(toggled(bool)),
0139             d->repValueButton, SLOT(setEnabled(bool)));
0140 
0141     connect(d->valueCheck, SIGNAL(toggled(bool)),
0142             d->valueBox, SLOT(setEnabled(bool)));
0143 
0144     // --------------------------------------------------------
0145 
0146     connect(d->valueCheck, SIGNAL(toggled(bool)),
0147             this, SIGNAL(signalModified()));
0148 
0149     connect(d->addValueButton, SIGNAL(clicked()),
0150             this, SIGNAL(signalModified()));
0151 
0152     connect(d->delValueButton, SIGNAL(clicked()),
0153             this, SIGNAL(signalModified()));
0154 
0155     connect(d->repValueButton, SIGNAL(clicked()),
0156             this, SIGNAL(signalModified()));
0157 }
0158 
0159 MultiValuesEdit::~MultiValuesEdit()
0160 {
0161     delete d;
0162 }
0163 
0164 void MultiValuesEdit::slotDeleteValue()
0165 {
0166     QListWidgetItem* const item = d->valueBox->currentItem();
0167 
0168     if (!item)
0169     {
0170         return;
0171     }
0172 
0173     d->valueBox->takeItem(d->valueBox->row(item));
0174     delete item;
0175 }
0176 
0177 void MultiValuesEdit::slotReplaceValue()
0178 {
0179     QString newValue = d->dataList->itemHighlighted();
0180 
0181     if (newValue.isEmpty())
0182     {
0183         return;
0184     }
0185 
0186     if (!d->valueBox->selectedItems().isEmpty())
0187     {
0188         d->valueBox->selectedItems()[0]->setText(newValue);
0189     }
0190 }
0191 
0192 void MultiValuesEdit::slotSelectionChanged()
0193 {
0194     if (!d->valueBox->selectedItems().isEmpty())
0195     {
0196         d->dataList->findText(d->valueBox->selectedItems()[0]->text());
0197         d->delValueButton->setEnabled(true);
0198         d->repValueButton->setEnabled(true);
0199     }
0200     else
0201     {
0202         d->delValueButton->setEnabled(false);
0203         d->repValueButton->setEnabled(false);
0204     }
0205 }
0206 
0207 void MultiValuesEdit::slotAddValue()
0208 {
0209     QString newValue = d->dataList->itemHighlighted();
0210 
0211     if (newValue.isEmpty())
0212     {
0213         return;
0214     }
0215 
0216     bool found = false;
0217 
0218     for (int i = 0 ; i < d->valueBox->count() ; ++i)
0219     {
0220         QListWidgetItem* const item = d->valueBox->item(i);
0221 
0222         if (newValue == item->text())
0223         {
0224             found = true;
0225             break;
0226         }
0227     }
0228 
0229     if (!found)
0230     {
0231         d->valueBox->insertItem(d->valueBox->count(), newValue);
0232     }
0233 }
0234 
0235 void MultiValuesEdit::setData(const QStringList& data)
0236 {
0237     d->dataList->clear();
0238 
0239     for (QStringList::const_iterator it = data.constBegin() ; it != data.constEnd() ; ++it )
0240     {
0241         d->dataList->addSqueezedItem(*it);
0242     }
0243 }
0244 
0245 QStringList MultiValuesEdit::getData() const
0246 {
0247     QStringList data;
0248 
0249     for (int i = 0 ; i < d->dataList->count() ; ++i)
0250     {
0251         data.append(d->dataList->item(i));
0252     }
0253 
0254     return data;
0255 }
0256 
0257 void MultiValuesEdit::setValues(const QStringList& values)
0258 {
0259     blockSignals(true);
0260     d->oldValues = values;
0261 
0262     d->valueBox->clear();
0263     d->valueCheck->setChecked(false);
0264 
0265     if (!d->oldValues.isEmpty())
0266     {
0267         d->valueBox->insertItems(0, d->oldValues);
0268         d->valueCheck->setChecked(true);
0269     }
0270 
0271     d->dataList->setEnabled(d->valueCheck->isChecked());
0272     d->valueBox->setEnabled(d->valueCheck->isChecked());
0273     d->addValueButton->setEnabled(d->valueCheck->isChecked());
0274     d->delValueButton->setEnabled(d->valueCheck->isChecked());
0275 
0276     blockSignals(false);
0277 }
0278 
0279 bool MultiValuesEdit::getValues(QStringList& oldValues, QStringList& newValues)
0280 {
0281     oldValues = d->oldValues;
0282     newValues.clear();
0283 
0284     for (int i = 0 ; i < d->valueBox->count() ; ++i)
0285     {
0286         QListWidgetItem* const item = d->valueBox->item(i);
0287         newValues.append(item->text());
0288     }
0289 
0290     return d->valueCheck->isChecked();
0291 }
0292 
0293 void MultiValuesEdit::setValid(bool v)
0294 {
0295     d->valueCheck->setValid(v);
0296 }
0297 
0298 bool MultiValuesEdit::isValid() const
0299 {
0300     return d->valueCheck->isValid();
0301 }
0302 
0303 } // namespace DigikamGenericMetadataEditPlugin
0304 
0305 #include "moc_multivaluesedit.cpp"