1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2007-10-08
7 * Description : a widget to edit Application2 ObjectAttribute
8 * Iptc tag.
9 *
10 * Copyright (C) 2007-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 *
12 * This program is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation;
15 * either version 2, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * ============================================================ */
23
24 #include "objectattributesedit.h"
25
26 // Qt includes
27
28 #include <QCheckBox>
29 #include <QPushButton>
30 #include <QValidator>
31 #include <QGridLayout>
32 #include <QComboBox>
33 #include <QApplication>
34 #include <QLineEdit>
35 #include <QListWidget>
36
37 // KDE includes
38
39 #include <klocalizedstring.h>
40
41 // Local includes
42
43 #include "metadatacheckbox.h"
44 #include "squeezedcombobox.h"
45
46 using namespace Digikam;
47
48 namespace DigikamGenericMetadataEditPlugin
49 {
50
51 class Q_DECL_HIDDEN ObjectAttributesEdit::Private
52 {
53 public:
54
Private()55 explicit Private()
56 : addValueButton(nullptr),
57 delValueButton(nullptr),
58 repValueButton(nullptr),
59 valueEdit (nullptr),
60 valueBox (nullptr),
61 valueCheck (nullptr),
62 dataList (nullptr)
63 {
64 }
65
66 QStringList oldValues;
67
68 QPushButton* addValueButton;
69 QPushButton* delValueButton;
70 QPushButton* repValueButton;
71
72 QLineEdit* valueEdit;
73
74 QListWidget* valueBox;
75
76 MetadataCheckBox* valueCheck;
77
78 SqueezedComboBox* dataList;
79 };
80
ObjectAttributesEdit(QWidget * const parent,int size)81 ObjectAttributesEdit::ObjectAttributesEdit(QWidget* const parent, int size)
82 : QWidget(parent),
83 d (new Private)
84 {
85 QGridLayout* const grid = new QGridLayout(this);
86
87 // --------------------------------------------------------
88
89 d->valueCheck = new MetadataCheckBox(i18n("Attribute:"), this);
90
91 d->addValueButton = new QPushButton(this);
92 d->delValueButton = new QPushButton(this);
93 d->repValueButton = new QPushButton(this);
94 d->addValueButton->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
95 d->delValueButton->setIcon(QIcon::fromTheme(QLatin1String("edit-delete")));
96 d->repValueButton->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
97 d->addValueButton->setWhatsThis(i18n("Add a new value to the list"));
98 d->delValueButton->setWhatsThis(i18n("Remove the current selected value from the list"));
99 d->repValueButton->setWhatsThis(i18n("Replace the current selected value from the list"));
100 d->delValueButton->setEnabled(false);
101 d->repValueButton->setEnabled(false);
102
103 d->valueBox = new QListWidget(this);
104 d->valueBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
105 d->valueBox->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
106
107 // --------------------------------------------------------
108
109 d->dataList = new SqueezedComboBox(this);
110 d->dataList->model()->sort(0);
111 d->dataList->setWhatsThis(i18n("Select here the editorial attribute of content."));
112 d->dataList->addSqueezedItem(QLatin1String("001 - ") + i18nc("Content type", "Current"));
113 d->dataList->addSqueezedItem(QLatin1String("002 - ") + i18nc("Content type", "Analysis"));
114 d->dataList->addSqueezedItem(QLatin1String("003 - ") + i18nc("Content type", "Archive material"));
115 d->dataList->addSqueezedItem(QLatin1String("004 - ") + i18nc("Content type", "Background"));
116 d->dataList->addSqueezedItem(QLatin1String("005 - ") + i18nc("Content type", "Feature"));
117 d->dataList->addSqueezedItem(QLatin1String("006 - ") + i18nc("Content type", "Forecast"));
118 d->dataList->addSqueezedItem(QLatin1String("007 - ") + i18nc("Content type", "History"));
119 d->dataList->addSqueezedItem(QLatin1String("008 - ") + i18nc("Content type", "Obituary"));
120 d->dataList->addSqueezedItem(QLatin1String("009 - ") + i18nc("Content type", "Opinion"));
121 d->dataList->addSqueezedItem(QLatin1String("010 - ") + i18nc("Content type", "Polls & Surveys"));
122 d->dataList->addSqueezedItem(QLatin1String("011 - ") + i18nc("Content type", "Profile"));
123 d->dataList->addSqueezedItem(QLatin1String("012 - ") + i18nc("Content type", "Results Listings & Table"));
124 d->dataList->addSqueezedItem(QLatin1String("013 - ") + i18nc("Content type", "Side bar & Supporting information"));
125 d->dataList->addSqueezedItem(QLatin1String("014 - ") + i18nc("Content type", "Summary"));
126 d->dataList->addSqueezedItem(QLatin1String("015 - ") + i18nc("Content type", "Transcript & Verbatim"));
127 d->dataList->addSqueezedItem(QLatin1String("016 - ") + i18nc("Content type", "Interview"));
128 d->dataList->addSqueezedItem(QLatin1String("017 - ") + i18nc("Content type", "From the Scene"));
129 d->dataList->addSqueezedItem(QLatin1String("018 - ") + i18nc("Content type", "Retrospective"));
130 d->dataList->addSqueezedItem(QLatin1String("019 - ") + i18nc("Content type", "Statistics"));
131 d->dataList->addSqueezedItem(QLatin1String("020 - ") + i18nc("Content type", "Update"));
132 d->dataList->addSqueezedItem(QLatin1String("021 - ") + i18nc("Content type", "Wrap-up"));
133 d->dataList->addSqueezedItem(QLatin1String("022 - ") + i18nc("Content type", "Press Release"));
134
135 // --------------------------------------------------------
136
137 d->valueEdit = new QLineEdit(this);
138 d->valueEdit->setClearButtonEnabled(true);
139 QString whatsThis = i18n("Set here the editorial attribute description of "
140 "content.");
141
142 if (size != -1)
143 {
144 whatsThis.append(i18n(" This field is limited to "));
145 d->valueEdit->setMaxLength(size);
146 whatsThis.append(i18np("%1 character.","%1 characters.", size));
147 }
148
149 d->valueEdit->setWhatsThis(whatsThis);
150
151 // --------------------------------------------------------
152
153 grid->setAlignment(Qt::AlignTop);
154 grid->addWidget(d->valueCheck, 0, 0, 1, 1);
155 grid->addWidget(d->addValueButton, 0, 1, 1, 1);
156 grid->addWidget(d->delValueButton, 0, 2, 1, 1);
157 grid->addWidget(d->repValueButton, 0, 3, 1, 1);
158 grid->addWidget(d->valueBox, 0, 4, 4, 1);
159 grid->addWidget(d->dataList, 1, 0, 1, 4);
160 grid->addWidget(d->valueEdit, 2, 0, 1, 4);
161 grid->setRowStretch(3, 10);
162 grid->setColumnStretch(0, 10);
163 grid->setColumnStretch(4, 10);
164 grid->setContentsMargins(QMargins());
165 grid->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing));
166
167 // --------------------------------------------------------
168
169 connect(d->valueBox, SIGNAL(itemSelectionChanged()),
170 this, SLOT(slotSelectionChanged()));
171
172 connect(d->addValueButton, SIGNAL(clicked()),
173 this, SLOT(slotAddValue()));
174
175 connect(d->delValueButton, SIGNAL(clicked()),
176 this, SLOT(slotDeleteValue()));
177
178 connect(d->repValueButton, SIGNAL(clicked()),
179 this, SLOT(slotReplaceValue()));
180
181 // --------------------------------------------------------
182
183 connect(d->valueCheck, SIGNAL(toggled(bool)),
184 d->valueEdit, SLOT(setEnabled(bool)));
185
186 connect(d->valueCheck, SIGNAL(toggled(bool)),
187 d->dataList, SLOT(setEnabled(bool)));
188
189 connect(d->valueCheck, SIGNAL(toggled(bool)),
190 d->addValueButton, SLOT(setEnabled(bool)));
191
192 connect(d->valueCheck, SIGNAL(toggled(bool)),
193 d->delValueButton, SLOT(setEnabled(bool)));
194
195 connect(d->valueCheck, SIGNAL(toggled(bool)),
196 d->repValueButton, SLOT(setEnabled(bool)));
197
198 connect(d->valueCheck, SIGNAL(toggled(bool)),
199 d->valueBox, SLOT(setEnabled(bool)));
200
201 // --------------------------------------------------------
202
203 connect(d->valueCheck, SIGNAL(toggled(bool)),
204 this, SIGNAL(signalModified()));
205
206 connect(d->addValueButton, SIGNAL(clicked()),
207 this, SIGNAL(signalModified()));
208
209 connect(d->delValueButton, SIGNAL(clicked()),
210 this, SIGNAL(signalModified()));
211
212 connect(d->repValueButton, SIGNAL(clicked()),
213 this, SIGNAL(signalModified()));
214 }
215
~ObjectAttributesEdit()216 ObjectAttributesEdit::~ObjectAttributesEdit()
217 {
218 delete d;
219 }
220
valueEdit() const221 QLineEdit* ObjectAttributesEdit::valueEdit() const
222 {
223 return d->valueEdit;
224 }
225
slotDeleteValue()226 void ObjectAttributesEdit::slotDeleteValue()
227 {
228 QListWidgetItem* const item = d->valueBox->currentItem();
229
230 if (!item)
231 {
232 return;
233 }
234
235 d->valueBox->takeItem(d->valueBox->row(item));
236 delete item;
237 }
238
slotReplaceValue()239 void ObjectAttributesEdit::slotReplaceValue()
240 {
241 QString newValue = d->dataList->itemHighlighted().left(3);
242 newValue.append(QString::fromUtf8(":%1").arg(d->valueEdit->text()));
243
244 if (!d->valueBox->selectedItems().isEmpty())
245 {
246 d->valueBox->selectedItems()[0]->setText(newValue);
247 }
248 }
249
slotSelectionChanged()250 void ObjectAttributesEdit::slotSelectionChanged()
251 {
252 if (!d->valueBox->selectedItems().isEmpty())
253 {
254 bool ok = false;
255 int index = d->valueBox->selectedItems()[0]->text().section(QLatin1Char(':'), 0, 0).toInt(&ok);
256
257 if (ok)
258 {
259 d->dataList->setCurrentIndex(index-1);
260 d->valueEdit->setText(d->valueBox->selectedItems()[0]->text().section(QLatin1Char(':'), -1));
261 d->delValueButton->setEnabled(true);
262 d->repValueButton->setEnabled(true);
263 return;
264 }
265 }
266
267 d->delValueButton->setEnabled(false);
268 d->repValueButton->setEnabled(false);
269 }
270
slotAddValue()271 void ObjectAttributesEdit::slotAddValue()
272 {
273 QString newValue = d->dataList->itemHighlighted().left(3);
274 newValue.append(QLatin1Char(':'));
275
276 if (!d->valueEdit->text().isEmpty())
277 {
278 newValue.append(d->valueEdit->text());
279 }
280 else
281 {
282 newValue.append(d->dataList->itemHighlighted()
283 .section(QLatin1String(" - "), -1));
284 }
285
286 bool found = false;
287
288 for (int i = 0 ; i < d->valueBox->count() ; ++i)
289 {
290 QListWidgetItem* const item = d->valueBox->item(i);
291
292 if (newValue == item->text())
293 {
294 found = true;
295 break;
296 }
297 }
298
299 if (!found)
300 {
301 d->valueBox->insertItem(d->valueBox->count(), newValue);
302 }
303 }
304
setValues(const QStringList & values)305 void ObjectAttributesEdit::setValues(const QStringList& values)
306 {
307 blockSignals(true);
308 d->oldValues = values;
309
310 d->valueBox->clear();
311 d->valueCheck->setChecked(false);
312
313 if (!d->oldValues.isEmpty())
314 {
315 d->valueBox->insertItems(0, d->oldValues);
316 d->valueCheck->setChecked(true);
317 }
318
319 d->dataList->setEnabled(d->valueCheck->isChecked());
320 d->valueBox->setEnabled(d->valueCheck->isChecked());
321 d->addValueButton->setEnabled(d->valueCheck->isChecked());
322 d->delValueButton->setEnabled(d->valueCheck->isChecked());
323
324 blockSignals(false);
325 }
326
getValues(QStringList & oldValues,QStringList & newValues)327 bool ObjectAttributesEdit::getValues(QStringList& oldValues, QStringList& newValues)
328 {
329 oldValues = d->oldValues;
330 newValues.clear();
331
332 for (int i = 0 ; i < d->valueBox->count() ; ++i)
333 {
334 QListWidgetItem* const item = d->valueBox->item(i);
335 newValues.append(item->text());
336 }
337
338 return d->valueCheck->isChecked();
339 }
340
setValid(bool v)341 void ObjectAttributesEdit::setValid(bool v)
342 {
343 d->valueCheck->setValid(v);
344 }
345
isValid() const346 bool ObjectAttributesEdit::isValid() const
347 {
348 return d->valueCheck->isValid();
349 }
350
351 } // namespace DigikamGenericMetadataEditPlugin
352