24#include <QDomDocument>
28using namespace Qt::StringLiterals;
39 tabString.fill(
'\t', tabs );
41 if ( QMetaType::Type::QStringList == mValue.userType() )
43 const QStringList sl = mValue.toStringList();
45 for (
const auto &
string : sl )
60 QDomElement subkeyElement = keyNode.toElement();
63 QString typeString = subkeyElement.attribute( u
"type"_s );
65 if ( typeString.isNull() )
67 QgsDebugError( u
"null ``type'' attribute for %1"_s.arg( keyNode.nodeName() ) );
77 QMetaType::Type type =
static_cast<QMetaType::Type
>( QMetaType::fromName( typeString.toLocal8Bit().constData() ).id() );
88 case QMetaType::Type::UnknownType:
89 QgsDebugError( u
"invalid value type %1 .. "_s.arg( typeString ) );
92 case QMetaType::Type::QVariantMap:
96 case QMetaType::Type::QVariantList:
100 case QMetaType::Type::QString:
101 mValue = subkeyElement.text();
104 case QMetaType::Type::QStringList:
107 QDomNodeList values = keyNode.childNodes();
110 QStringList valueStringList;
112 while ( i < values.count() )
114 if (
"value" == values.item( i ).nodeName() )
117 valueStringList.append( values.item( i ).firstChild().nodeValue() );
121 QgsDebugError( u
"non <value> element ``%1'' in string list"_s.arg( values.item( i ).nodeName() ) );
127 mValue = valueStringList;
131 case QMetaType::Type::QFont:
135 case QMetaType::Type::QPixmap:
139 case QMetaType::Type::QBrush:
143 case QMetaType::Type::QRect:
147 case QMetaType::Type::QSize:
151 case QMetaType::Type::QColor:
155 case QMetaType::Type::QPalette:
159 case QMetaType::Type::QPoint:
163 case QMetaType::Type::QImage:
167 case QMetaType::Type::Int:
168 mValue = QVariant( subkeyElement.text() ).toInt();
171 case QMetaType::Type::UInt:
172 mValue = QVariant( subkeyElement.text() ).toUInt();
175 case QMetaType::Type::Bool:
176 mValue = QVariant( subkeyElement.text() ).toBool();
179 case QMetaType::Type::Double:
180 mValue = QVariant( subkeyElement.text() ).toDouble();
183 case QMetaType::Type::QByteArray:
184 mValue = QVariant( subkeyElement.text() ).toByteArray();
187 case QMetaType::Type::QPolygon:
191 case QMetaType::Type::QRegion:
195 case QMetaType::Type::QBitmap:
199 case QMetaType::Type::QCursor:
203 case QMetaType::Type::QBitArray:
207 case QMetaType::Type::QKeySequence:
211 case QMetaType::Type::QPen:
216 case QVariant::LongLong :
217 value_ = QVariant( subkeyElement.text() ).toLongLong();
220 case QVariant::ULongLong :
221 value_ = QVariant( subkeyElement.text() ).toULongLong();
225 QgsDebugError( u
"unsupported value type %1 .. not properly translated to QVariant"_s.arg( typeString ) );
235 QDomElement valueElement = document.createElement( u
"properties"_s );
238 valueElement.setAttribute( u
"name"_s, nodeName );
239 valueElement.setAttribute( u
"type"_s, mValue.typeName() );
245 if ( QMetaType::Type::QStringList == mValue.userType() )
247 QStringList sl = mValue.toStringList();
249 for ( QStringList::iterator i = sl.begin(); i != sl.end(); ++i )
251 QDomElement stringListElement = document.createElement( u
"value"_s );
252 QDomText valueText = document.createTextNode( *i );
253 stringListElement.appendChild( valueText );
255 valueElement.appendChild( stringListElement );
260 QDomText valueText = document.createTextNode( mValue.toString() );
261 valueElement.appendChild( valueText );
264 keyElement.appendChild( valueElement );
283 if ( !foundQgsProperty )
289 return foundQgsProperty->
value();
297 tabString.fill(
'\t', tabs );
302 tabString.fill(
'\t', tabs );
304 if ( !mProperties.isEmpty() )
306 QHashIterator< QString, QgsProjectProperty * > i( mProperties );
307 while ( i.hasNext() )
309 if ( i.next().value()->isValue() )
313 if ( QMetaType::Type::QStringList == propertyValue->
value().userType() )
316 propertyValue->
dump( tabs + 1 );
320 QgsDebugMsgLevel( u
"%1key: <%2> value: %3"_s.arg( tabString, i.key(), propertyValue->
value().toString() ), 4 );
326 i.value()->dump( tabs + 1 );
330 qDebug(
"<%s>",
name().toUtf8().constData() );
331 if ( i.value()->isValue() )
333 qDebug(
" <%s>", i.key().toUtf8().constData() );
336 if ( i.value()->isValue() )
338 qDebug(
" </%s>", i.key().toUtf8().constData() );
340 qDebug(
"</%s>",
name().toUtf8().constData() );
350 QDomNodeList subkeys = keyNode.childNodes();
352 while ( i < subkeys.count() )
354 const QDomNode subkey = subkeys.item( i );
357 if ( subkey.nodeName() ==
"properties"_L1
358 && subkey.hasAttributes()
362 subkey.toElement().hasAttribute( u
"name"_s ) )
363 name = subkey.toElement().attribute( u
"name"_s );
365 name = subkey.nodeName();
370 if ( subkey.hasAttributes()
374 subkey.toElement().hasAttribute( u
"type"_s ) )
378 delete mProperties.take(
name );
412 QDomElement keyElement = document.createElement(
"properties" );
413 keyElement.toElement().setAttribute( u
"name"_s, nodeName );
415 if ( !mProperties.isEmpty() )
417 auto keys = mProperties.keys();
418 std::sort( keys.begin(), keys.end() );
420 for (
const auto &key : std::as_const( keys ) )
422 if ( !mProperties.value( key )->writeXml( key, keyElement, document ) )
427 element.appendChild( keyElement );
435 QHashIterator< QString, QgsProjectProperty * > i( mProperties );
436 while ( i.hasNext() )
439 if ( i.next().value()->isLeaf() )
441 entries.append( i.key() );
449 QHashIterator< QString, QgsProjectProperty * > i( mProperties );
450 while ( i.hasNext() )
453 if ( !i.next().value()->isLeaf() )
455 entries.append( i.key() );
467 else if ( 1 ==
count() )
469 QHashIterator< QString, QgsProjectProperty * > i( mProperties );
471 if ( i.hasNext() && i.next().value()->isValue() )
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
bool isLeaf() const override
Returns true if property is a leaf node.
QString name() const
The name of the property is used as identifier.
QgsProjectPropertyKey(const QString &name=QString())
Create a new QgsProjectPropertyKey with the specified identifier.
void dump(int tabs=0) const override
Dumps out the keys and values.
virtual void clearKeys()
Deletes any sub-nodes from the property.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
void setName(const QString &name)
The name of the property is used as identifier.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
~QgsProjectPropertyKey() override
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
void entryList(QStringList &entries) const
Returns any sub-keys contained by this property that do not contain other keys.
int count() const
Returns the number of sub-keys contained by this property.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
Project property value node, contains a QgsProjectPropertyKey's value.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
QVariant value() const override
Returns the node's value.
void dump(int tabs=0) const override
Dumps out the keys and values.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
virtual QVariant value() const =0
Returns the node's value.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)