File indexing completed on 2024-12-22 04:15:06
0001 /* 0002 * SPDX-FileCopyrightText: 2007, 2010 Cyrille Berger <cberger@cberger.net> 0003 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "kis_meta_data_editor.h" 0009 0010 #include <QDomDocument> 0011 #include <QFile> 0012 #include <QHeaderView> 0013 #include <QTableView> 0014 0015 #include <KoResourcePaths.h> 0016 #include <kis_debug.h> 0017 #include <kis_icon.h> 0018 #include <kis_meta_data_entry.h> 0019 #include <kis_meta_data_schema.h> 0020 #include <kis_meta_data_schema_registry.h> 0021 #include <kis_meta_data_store.h> 0022 #include <kis_meta_data_value.h> 0023 #include <klocalizedstring.h> 0024 0025 #include "kis_entry_editor.h" 0026 #include "kis_meta_data_model.h" 0027 0028 0029 struct KisMetaDataEditor::Private { 0030 KisMetaData::Store *store; 0031 KisMetaData::Store *temporaryStorage; 0032 QList<KisEntryEditor *> entryHandlers; 0033 }; 0034 0035 #define GET_VALUE(entryName, wdg, wdgPropertyName, editorSignal) \ 0036 QString key = schema->generateQualifiedName(#entryName); \ 0037 KisEntryEditor *ee = new KisEntryEditor(wdg, d->temporaryStorage, key, #wdgPropertyName, QString(), 0); \ 0038 connect(wdg, editorSignal, ee, &KisEntryEditor::valueEdited); \ 0039 d->entryHandlers.push_back(ee); 0040 0041 #define GET_ARRAY_VALUE(entryName, arrayIndex, wdg, wdgPropertyName, editorSignal) \ 0042 QString key = schema->generateQualifiedName(#entryName); \ 0043 KisEntryEditor *ee = new KisEntryEditor(wdg, d->temporaryStorage, key, #wdgPropertyName, QString(), arrayIndex); \ 0044 connect(wdg, editorSignal, ee, &KisEntryEditor::valueEdited); \ 0045 d->entryHandlers.push_back(ee); 0046 0047 #define GET_STRUCTURE_VALUE(entryName, structureField, wdg, wdgPropertyName, editorSignal) \ 0048 QString key = schema->generateQualifiedName(#entryName); \ 0049 KisEntryEditor *ee = new KisEntryEditor(wdg, d->temporaryStorage, key, #wdgPropertyName, #structureField, 0); \ 0050 connect(wdg, editorSignal, ee, &KisEntryEditor::valueEdited); \ 0051 d->entryHandlers.push_back(ee); 0052 0053 #define GET_DC_VALUE(entryName, wdgPropertyName, editorSignal) { \ 0054 GET_VALUE(entryName, wdg->entryName, wdgPropertyName, editorSignal) \ 0055 } 0056 0057 #define GET_EXIF_VALUE(entryName, wdgPropertyName, editorSignal) { \ 0058 GET_VALUE(entryName, wdg->edit##entryName, wdgPropertyName, editorSignal) \ 0059 } 0060 0061 #define GET_EXIF_ARRAY_VALUE(entryName, arrayIndex, wdgPropertyName, editorSignal) { \ 0062 GET_ARRAY_VALUE(entryName, arrayIndex, wdg->edit##entryName, wdgPropertyName, editorSignal) \ 0063 } 0064 0065 #define GET_EXIF_STRUCTURE_VALUE(entryName, structureField, wdgPropertyName, editorSignal) { \ 0066 GET_STRUCTURE_VALUE(entryName, structureField, wdg->edit##entryName##structureField, wdgPropertyName, editorSignal) \ 0067 } 0068 0069 KisMetaDataEditor::KisMetaDataEditor(QWidget *parent, KisMetaData::Store *store) 0070 : KPageDialog(parent) 0071 , d(new Private) 0072 { 0073 d->temporaryStorage = new KisMetaData::Store(*store); 0074 d->store = store; 0075 0076 // Add the Dublin Core widget 0077 { 0078 WdgDublinCore *wdg = new WdgDublinCore(this); 0079 0080 { 0081 // copy from dublin core 0082 const KisMetaData::Schema *schema = 0083 KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri); 0084 0085 Q_ASSERT(schema); 0086 0087 GET_DC_VALUE(creator, text, &QLineEdit::textEdited); 0088 GET_DC_VALUE(publisher, text, &QLineEdit::textEdited); 0089 GET_DC_VALUE(rights, text, &QLineEdit::textEdited); 0090 GET_DC_VALUE(date, date, &QDateTimeEdit::editingFinished); 0091 GET_DC_VALUE(title, text, &QLineEdit::textEdited); 0092 GET_DC_VALUE(description, plainText, &QTextEdit::textChanged); 0093 } 0094 0095 wdg->date->setDisplayFormat(QLocale().dateFormat()); 0096 0097 KPageWidgetItem *page = new KPageWidgetItem(wdg, i18n("Dublin Core")); 0098 page->setIcon(KisIconUtils::loadIcon("user-identity")); 0099 addPage(page); 0100 } 0101 0102 // Add the Exif widget 0103 { 0104 WdgExif *wdg = new WdgExif(this); 0105 0106 { 0107 // copy from exif 0108 const KisMetaData::Schema *schema = 0109 KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::EXIFSchemaUri); 0110 0111 Q_ASSERT(schema); 0112 0113 /* exposure tab */ 0114 GET_EXIF_VALUE(BrightnessValue, text, &QLineEdit::textEdited); 0115 GET_EXIF_VALUE(ExposureTime, text, &QLineEdit::textEdited); 0116 GET_EXIF_ARRAY_VALUE(ISOSpeedRatings, 0, value, QOverload<int>::of(&KisIntParseSpinBox::valueChanged)); 0117 GET_EXIF_VALUE(ExposureMode, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0118 GET_EXIF_VALUE(ExposureProgram, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0119 GET_EXIF_VALUE(ExposureIndex, text, &QLineEdit::textEdited); 0120 GET_EXIF_VALUE(ExposureBiasValue, text, &QLineEdit::textEdited); 0121 GET_EXIF_VALUE(ApertureValue, text, &QLineEdit::textEdited); 0122 GET_EXIF_VALUE(ShutterSpeedValue, text, &QLineEdit::textEdited); 0123 GET_EXIF_VALUE(FNumber, text, &QLineEdit::textEdited); 0124 /* lens tab */ 0125 GET_EXIF_VALUE(FocalLengthIn35mmFilm, value, QOverload<int>::of(&QSpinBox::valueChanged)); 0126 GET_EXIF_VALUE(FocalLength, value, QOverload<int>::of(&QSpinBox::valueChanged)); 0127 GET_EXIF_VALUE(MaxApertureValue, text, &QLineEdit::textEdited); 0128 /* autofocus tab */ 0129 GET_EXIF_VALUE(MeteringMode, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0130 GET_EXIF_VALUE(SubjectDistance, text, &QLineEdit::textEdited); 0131 GET_EXIF_VALUE(SubjectDistanceRange, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0132 /* flash */ 0133 GET_EXIF_STRUCTURE_VALUE(Flash, Fired, isChecked, QOverload<bool>::of(&QCheckBox::toggled)); 0134 GET_EXIF_STRUCTURE_VALUE(Flash, StrobeReturn, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0135 GET_EXIF_STRUCTURE_VALUE(Flash, Mode, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0136 GET_EXIF_STRUCTURE_VALUE(Flash, Function, isChecked, QOverload<bool>::of(&QCheckBox::toggled)); 0137 GET_EXIF_STRUCTURE_VALUE(Flash, RedEyeMode, isChecked, QOverload<bool>::of(&QCheckBox::toggled)); 0138 GET_EXIF_VALUE(FlashEnergy, text, &QLineEdit::textEdited); 0139 /* postprocessing tab */ 0140 GET_EXIF_VALUE(GainControl, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0141 GET_EXIF_VALUE(LightSource, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0142 GET_EXIF_VALUE(Sharpness, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0143 GET_EXIF_VALUE(Contrast, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0144 GET_EXIF_VALUE(WhiteBalance, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0145 /* misc tab */ 0146 GET_EXIF_VALUE(SceneCaptureType, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0147 GET_EXIF_VALUE(SensingMethod, currentIndex, QOverload<int>::of(&QComboBox::activated)); 0148 } 0149 0150 { 0151 // copy from exif (tiff schema) 0152 const KisMetaData::Schema *schema = 0153 KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri); 0154 0155 Q_ASSERT(schema); 0156 0157 /* misc */ 0158 GET_EXIF_VALUE(Make, text, &QLineEdit::textEdited); 0159 GET_EXIF_VALUE(Model, text, &QLineEdit::textEdited); 0160 } 0161 0162 KPageWidgetItem *page = new KPageWidgetItem(wdg, i18n("Exif")); 0163 page->setIcon(KisIconUtils::loadIcon("camera-photo")); 0164 addPage(page); 0165 } 0166 0167 { 0168 // Add the list page 0169 QTableView *tableView = new QTableView; 0170 KisMetaDataModel *model = new KisMetaDataModel(d->store); 0171 tableView->setModel(model); 0172 tableView->verticalHeader()->setVisible(false); 0173 tableView->resizeColumnsToContents(); 0174 KPageWidgetItem *page = new KPageWidgetItem(tableView, i18n("List")); 0175 page->setIcon(KisIconUtils::loadIcon("format-list-unordered")); 0176 addPage(page); 0177 } 0178 } 0179 0180 KisMetaDataEditor::~KisMetaDataEditor() 0181 { 0182 Q_FOREACH (KisEntryEditor *e, d->entryHandlers) { 0183 delete e; 0184 } 0185 delete d->temporaryStorage; 0186 delete d; 0187 } 0188 0189 void KisMetaDataEditor::accept() 0190 { 0191 KPageDialog::accept(); 0192 0193 d->store->copyFrom(d->temporaryStorage); 0194 }