File indexing completed on 2024-05-12 15:59:16
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "kis_meta_data_store.h" 0008 0009 #include <QStringList> 0010 0011 #include <kis_debug.h> 0012 0013 #include "kis_meta_data_entry.h" 0014 #include "kis_meta_data_filter.h" 0015 #include "kis_meta_data_schema.h" 0016 #include "kis_meta_data_schema_registry.h" 0017 #include "kis_meta_data_value.h" 0018 0019 using namespace KisMetaData; 0020 0021 uint qHash(const Entry& e) 0022 { 0023 return qHash(e.qualifiedName()); 0024 } 0025 0026 struct Q_DECL_HIDDEN Store::Private { 0027 QHash<QString, Entry> entries; 0028 }; 0029 0030 Store::Store() : d(new Private) 0031 { 0032 0033 } 0034 0035 Store::Store(const Store& s) : d(new Private(*s.d)) 0036 { 0037 // TODO: reaffect all schemas 0038 } 0039 0040 Store::~Store() 0041 { 0042 delete d; 0043 } 0044 0045 void Store::copyFrom(const Store* store) 0046 { 0047 for (QHash<QString, Entry>::const_iterator entryIt = store->begin(); 0048 entryIt != store->end(); ++entryIt) { 0049 const Entry& entry = entryIt.value(); 0050 if (entry.value().type() != KisMetaData::Value::Invalid) { 0051 if (containsEntry(entry.qualifiedName())) { 0052 getEntry(entry.qualifiedName()).value() = entry.value(); 0053 } else { 0054 addEntry(entry); 0055 } 0056 } 0057 } 0058 } 0059 0060 bool Store::addEntry(const Entry& entry) 0061 { 0062 Q_ASSERT(!entry.name().isEmpty()); 0063 if (d->entries.contains(entry.qualifiedName()) && d->entries[entry.qualifiedName()].isValid()) { 0064 dbgMetaData << "Entry" << entry.qualifiedName() << " already exists in the store, cannot be included twice"; 0065 return false; 0066 } 0067 d->entries.insert(entry.qualifiedName(), entry); 0068 return true; 0069 } 0070 0071 bool Store::empty() const 0072 { 0073 return d->entries.isEmpty(); 0074 } 0075 0076 bool Store::isEmpty() const 0077 { 0078 return d->entries.isEmpty(); 0079 } 0080 0081 bool Store::containsEntry(const QString & entryKey) const 0082 { 0083 return d->entries.contains(entryKey); 0084 } 0085 0086 bool Store::containsEntry(const QString & uri, const QString & entryName) const 0087 { 0088 const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); 0089 return containsEntry(schema->generateQualifiedName(entryName)); 0090 } 0091 0092 bool Store::containsEntry(const KisMetaData::Schema* schema, const QString & entryName) const 0093 { 0094 if (schema) { 0095 return containsEntry(schema->generateQualifiedName(entryName)); 0096 } 0097 return false; 0098 } 0099 0100 Entry& Store::getEntry(const QString & entryKey) 0101 { 0102 if (!d->entries.contains(entryKey)) { 0103 QStringList splitKey = entryKey.split(':'); 0104 QString prefix = splitKey[0]; 0105 splitKey.pop_front(); 0106 d->entries[entryKey] = Entry(SchemaRegistry::instance()->schemaFromPrefix(prefix), 0107 splitKey.join(":"), 0108 Value()); 0109 } 0110 return d->entries [entryKey]; 0111 } 0112 0113 Entry& Store::getEntry(const QString & uri, const QString & entryName) 0114 { 0115 const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); 0116 Q_ASSERT(schema); 0117 return getEntry(schema, entryName); 0118 } 0119 0120 Entry& Store::getEntry(const KisMetaData::Schema* schema, const QString & entryName) 0121 { 0122 return getEntry(schema->generateQualifiedName(entryName)); 0123 } 0124 0125 0126 const Entry& Store::getEntry(const QString & entryKey) const 0127 { 0128 return d->entries[entryKey]; 0129 } 0130 0131 const Entry& Store::getEntry(const QString & uri, const QString & entryName) const 0132 { 0133 const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); 0134 Q_ASSERT(schema); 0135 return getEntry(schema, entryName); 0136 } 0137 0138 const Entry& Store::getEntry(const KisMetaData::Schema* schema, const QString & entryName) const 0139 { 0140 return getEntry(schema->generateQualifiedName(entryName)); 0141 } 0142 0143 void Store::removeEntry(const QString & entryKey) 0144 { 0145 d->entries.remove(entryKey); 0146 } 0147 0148 void Store::removeEntry(const QString & uri, const QString & entryName) 0149 { 0150 const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); 0151 Q_ASSERT(schema); 0152 removeEntry(schema, entryName); 0153 } 0154 0155 void Store::removeEntry(const KisMetaData::Schema* schema, const QString & entryName) 0156 { 0157 removeEntry(schema->generateQualifiedName(entryName)); 0158 } 0159 0160 const Value& Store::getValue(const QString & uri, const QString & entryName) const 0161 { 0162 return getEntry(uri, entryName).value(); 0163 } 0164 0165 QHash<QString, Entry>::const_iterator Store::begin() const 0166 { 0167 return d->entries.constBegin(); 0168 } 0169 0170 QHash<QString, Entry>::const_iterator Store::end() const 0171 { 0172 return d->entries.constEnd(); 0173 } 0174 0175 void Store::debugDump() const 0176 { 0177 dbgMetaData << "=== Dumping MetaData Store ==="; 0178 dbgMetaData << " - Metadata (there are" << d->entries.size() << " entries)"; 0179 Q_FOREACH (const Entry& e, d->entries) { 0180 if (e.isValid()) { 0181 dbgMetaData << e; 0182 } else { 0183 dbgMetaData << "Invalid entry"; 0184 } 0185 } 0186 } 0187 0188 void Store::applyFilters(const QList<const Filter*> & filters) 0189 { 0190 dbgMetaData << "Apply " << filters.size() << " filters"; 0191 Q_FOREACH (const Filter* filter, filters) { 0192 filter->filter(this); 0193 } 0194 } 0195 0196 QList<QString> Store::keys() const 0197 { 0198 return d->entries.keys(); 0199 } 0200 0201 QList<Entry> Store::entries() const 0202 { 0203 return d->entries.values(); 0204 }