Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_meta_data_type_info.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
8
9#include <QVariant>
10
13#include "kis_meta_data_value.h"
15
16using namespace KisMetaData;
17
18QHash< const TypeInfo*, const TypeInfo*> TypeInfo::Private::orderedArrays;
19QHash< const TypeInfo*, const TypeInfo*> TypeInfo::Private::unorderedArrays;
20QHash< const TypeInfo*, const TypeInfo*> TypeInfo::Private::alternativeArrays;
21
22const TypeInfo* TypeInfo::Private::Boolean = new TypeInfo(TypeInfo::BooleanType);
23const TypeInfo* TypeInfo::Private::Integer = new TypeInfo(TypeInfo::IntegerType);
24const TypeInfo* TypeInfo::Private::Date = new TypeInfo(TypeInfo::DateType);
25const TypeInfo* TypeInfo::Private::Text = new TypeInfo(TypeInfo::TextType);
26const TypeInfo* TypeInfo::Private::Rational = new TypeInfo(TypeInfo::RationalType);
27const TypeInfo* TypeInfo::Private::GPSCoordinate = new TypeInfo(TypeInfo::GPSCoordinateType);
28
29const TypeInfo* TypeInfo::Private::orderedArray(const TypeInfo* _typeInfo)
30{
31 if (Private::orderedArrays.contains(_typeInfo)) {
32 return Private::orderedArrays[ _typeInfo ];
33 }
34 const TypeInfo* info = new TypeInfo(TypeInfo::OrderedArrayType, _typeInfo);
35 Private::orderedArrays[ _typeInfo ] = info;
36 return info;
37}
38
39const TypeInfo* TypeInfo::Private::unorderedArray(const TypeInfo* _typeInfo)
40{
41 if (Private::unorderedArrays.contains(_typeInfo)) {
42 return Private::unorderedArrays[ _typeInfo ];
43 }
44 const TypeInfo* info = new TypeInfo(TypeInfo::UnorderedArrayType, _typeInfo);
45 Private::unorderedArrays[ _typeInfo ] = info;
46 return info;
47}
48
49const TypeInfo* TypeInfo::Private::alternativeArray(const TypeInfo* _typeInfo)
50{
51 if (Private::alternativeArrays.contains(_typeInfo)) {
52 return Private::alternativeArrays[ _typeInfo ];
53 }
54 const TypeInfo* info = new TypeInfo(TypeInfo::AlternativeArrayType, _typeInfo);
55 Private::alternativeArrays[ _typeInfo ] = info;
56 return info;
57}
58
59const TypeInfo* TypeInfo::Private::createChoice(PropertyType _propertiesType, const TypeInfo* _embedded, const QList< Choice >& _choices)
60{
61 return new TypeInfo(_propertiesType, _embedded, _choices);
62}
63
64const TypeInfo* TypeInfo::Private::createStructure(Schema* _structureSchema, const QString& name)
65{
66 return new TypeInfo(_structureSchema, name);
67}
68
69const TypeInfo* TypeInfo::Private::LangArray = new TypeInfo(TypeInfo::LangArrayType);
70
71TypeInfo::TypeInfo(TypeInfo::PropertyType _propertyType) : d(new Private)
72{
73 d->propertyType = _propertyType;
74 if (d->propertyType == TypeInfo::LangArrayType) {
75 d->embeddedTypeInfo = TypeInfo::Private::Text;
76 }
77 switch (d->propertyType) {
78 case IntegerType:
79 d->parser = new IntegerParser;
80 break;
81 case TextType:
82 d->parser = new TextParser;
83 break;
84 case DateType:
85 d->parser = new DateParser;
86 break;
87 case RationalType:
88 d->parser = new RationalParser;
89 break;
90 default:
91 ;
92 }
93}
94
95struct Q_DECL_HIDDEN TypeInfo::Choice::Private {
97 QString hint;
98};
99
100TypeInfo::Choice::Choice(const Value& value, const QString& hint) : d(new Private)
101{
102 d->value = value;
103 d->hint = hint;
104}
105
106TypeInfo::Choice::Choice(const Choice& _rhs) : d(new Private(*_rhs.d))
107{
108}
109
111{
112 *d = *_rhs.d;
113 return *this;
114}
115
117{
118 delete d;
119}
121{
122 return d->value;
123}
124
125const QString& TypeInfo::Choice::hint() const
126{
127 return d->hint;
128}
129
130TypeInfo::TypeInfo(PropertyType _propertyType, const TypeInfo* _embedded) : d(new Private)
131{
132 Q_ASSERT(_propertyType == OrderedArrayType || _propertyType == UnorderedArrayType || _propertyType == AlternativeArrayType);
133 d->propertyType = _propertyType;
134 d->embeddedTypeInfo = _embedded;
135}
136
137TypeInfo::TypeInfo(PropertyType _propertyType, const TypeInfo* _embedded, const QList< Choice >& _choices) : d(new Private)
138{
139 Q_ASSERT(_propertyType == ClosedChoice || _propertyType == OpenedChoice);
140 d->propertyType = _propertyType;
141 d->embeddedTypeInfo = _embedded;
142 d->parser = _embedded->parser();
143 d->choices = _choices;
144}
145
146TypeInfo::TypeInfo(Schema* _structureSchema, const QString& name) : d(new Private)
147{
148 d->propertyType = TypeInfo::StructureType;
149 d->structureSchema = _structureSchema;
150 d->structureName = name;
151}
152
154{
155 delete d->parser;
156 delete d;
157}
158
160{
161 return d->propertyType;
162}
163
165{
166 return d->embeddedTypeInfo;
167}
168
170{
171 return d->choices;
172}
173
175{
176 return d->structureSchema;
177}
178
179const QString& TypeInfo::structureName() const
180{
181 return d->structureName;
182}
183
185{
186 return d->parser;
187}
188
189bool checkArray(const Value& value, const TypeInfo* typeInfo)
190{
191 QList< Value > values = value.asArray();
192 Q_FOREACH (const Value& val, values) {
193 if (!typeInfo->hasCorrectType(val)) {
194 return false;
195 }
196 }
197 return true;
198}
199
201{
202 switch (d->propertyType) {
203 case BooleanType:
204 return value.type() == Value::Variant && value.asVariant().type() == QVariant::Bool;
205 case IntegerType:
206 return value.type() == Value::Variant && value.asVariant().type() == QVariant::Int;
207 case DateType:
208 return value.type() == Value::Variant && value.asVariant().type() == QVariant::DateTime;
210 case TextType:
211 return value.type() == Value::Variant && value.asVariant().type() == QVariant::String;
212 case OrderedArrayType:
213 if (value.type() == Value::OrderedArray) {
214 return checkArray(value, d->embeddedTypeInfo);
215 } else {
216 return false;
217 }
219 if (value.type() == Value::UnorderedArray) {
220 return checkArray(value, d->embeddedTypeInfo);
221 } else {
222 return false;
223 }
225 if (value.type() == Value::AlternativeArray) {
226 return checkArray(value, d->embeddedTypeInfo);
227 } else {
228 return false;
229 }
230 case LangArrayType:
231 if (value.type() == Value::LangArray) {
232 QList< Value > values = value.asArray();
233 Q_FOREACH (const Value& vallang, values) {
234 if (!Private::Text->hasCorrectType(vallang) ||
235 !Private::Text->hasCorrectType(vallang.propertyQualifiers()["xml:lang"])) {
236 return false;
237 }
238 }
239 return true;
240 } else {
241 return false;
242 }
243 case StructureType:
244 if (value.type() == Value::Structure) {
245 QMap<QString, KisMetaData::Value> structure = value.asStructure();
246 for (QMap<QString, KisMetaData::Value>::iterator it = structure.begin();
247 it != structure.end(); ++it) {
248 const TypeInfo* typeInfo = d->structureSchema->propertyType(it.key());
249 if (!typeInfo || !typeInfo->hasCorrectType(it.value())) {
250 return false;
251 }
252 }
253 return true;
254 } else {
255 return false;
256 }
257 case RationalType:
258 return value.type() == Value::Rational;
259 case OpenedChoice:
260 case ClosedChoice:
261 return d->embeddedTypeInfo->hasCorrectType(value);
262 }
263 return false;
264}
265
267{
268 if (d->propertyType == ClosedChoice) {
269 Q_FOREACH (const Choice& choice, d->choices) {
270 if (choice.value() == value) {
271 return true;
272 }
273 }
274 return false;
275 } else {
276 return true;
277 }
278}
float value(const T *src, size_t ch)
Choice(const Value &, const QString &hint)
TypeInfo(PropertyType _propertiesType)
bool hasCorrectType(const Value &value) const
bool hasCorrectValue(const Value &value) const
const QString & structureName() const
PropertyType propertyType() const
const Parser * parser() const
const TypeInfo * embeddedPropertyType() const
const QList< Choice > & choices() const
const QMap< QString, Value > & propertyQualifiers() const
bool checkArray(const Value &value, const TypeInfo *typeInfo)