24#include <QDomDocument>
37 tabString.fill(
'\t', tabs );
39 if ( QMetaType::Type::QStringList == mValue.userType() )
41 const QStringList sl = mValue.toStringList();
43 for (
const auto &
string : sl )
50 QgsDebugMsgLevel( QStringLiteral(
"%1%2" ).arg( tabString, mValue.toString() ), 4 );
58 QDomElement subkeyElement = keyNode.toElement();
61 QString typeString = subkeyElement.attribute( QStringLiteral(
"type" ) );
63 if ( typeString.isNull() )
65 QgsDebugError( QStringLiteral(
"null ``type'' attribute for %1" ).arg( keyNode.nodeName() ) );
75#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
76 QMetaType::Type type =
static_cast<QMetaType::Type
>( QMetaType::type( typeString.toLocal8Bit().constData() ) );
78 QMetaType::Type type =
static_cast<QMetaType::Type
>( QMetaType::fromName( typeString.toLocal8Bit().constData() ).id() );
90 case QMetaType::Type::UnknownType:
91 QgsDebugError( QStringLiteral(
"invalid value type %1 .. " ).arg( typeString ) );
94 case QMetaType::Type::QVariantMap:
95 QgsDebugError( QStringLiteral(
"no support for QVariant::Map" ) );
98 case QMetaType::Type::QVariantList:
99 QgsDebugError( QStringLiteral(
"no support for QVariant::List" ) );
102 case QMetaType::Type::QString:
103 mValue = subkeyElement.text();
106 case QMetaType::Type::QStringList:
109 QDomNodeList values = keyNode.childNodes();
112 QStringList valueStringList;
114 while ( i < values.count() )
116 if (
"value" == values.item( i ).nodeName() )
119 valueStringList.append( values.item( i ).firstChild().nodeValue() );
123 QgsDebugError( QStringLiteral(
"non <value> element ``%1'' in string list" ).arg( values.item( i ).nodeName() ) );
129 mValue = valueStringList;
133 case QMetaType::Type::QFont:
134 QgsDebugError( QStringLiteral(
"no support for QVariant::Font" ) );
137 case QMetaType::Type::QPixmap:
138 QgsDebugError( QStringLiteral(
"no support for QVariant::Pixmap" ) );
141 case QMetaType::Type::QBrush:
142 QgsDebugError( QStringLiteral(
"no support for QVariant::Brush" ) );
145 case QMetaType::Type::QRect:
146 QgsDebugError( QStringLiteral(
"no support for QVariant::Rect" ) );
149 case QMetaType::Type::QSize:
150 QgsDebugError( QStringLiteral(
"no support for QVariant::Size" ) );
153 case QMetaType::Type::QColor:
154 QgsDebugError( QStringLiteral(
"no support for QVariant::Color" ) );
157 case QMetaType::Type::QPalette:
158 QgsDebugError( QStringLiteral(
"no support for QVariant::Palette" ) );
161 case QMetaType::Type::QPoint:
162 QgsDebugError( QStringLiteral(
"no support for QVariant::Point" ) );
165 case QMetaType::Type::QImage:
166 QgsDebugError( QStringLiteral(
"no support for QVariant::Image" ) );
169 case QMetaType::Type::Int:
170 mValue = QVariant( subkeyElement.text() ).toInt();
173 case QMetaType::Type::UInt:
174 mValue = QVariant( subkeyElement.text() ).toUInt();
177 case QMetaType::Type::Bool:
178 mValue = QVariant( subkeyElement.text() ).toBool();
181 case QMetaType::Type::Double:
182 mValue = QVariant( subkeyElement.text() ).toDouble();
185 case QMetaType::Type::QByteArray:
186 mValue = QVariant( subkeyElement.text() ).toByteArray();
189 case QMetaType::Type::QPolygon:
190 QgsDebugError( QStringLiteral(
"no support for QVariant::Polygon" ) );
193 case QMetaType::Type::QRegion:
194 QgsDebugError( QStringLiteral(
"no support for QVariant::Region" ) );
197 case QMetaType::Type::QBitmap:
198 QgsDebugError( QStringLiteral(
"no support for QVariant::Bitmap" ) );
201 case QMetaType::Type::QCursor:
202 QgsDebugError( QStringLiteral(
"no support for QVariant::Cursor" ) );
205 case QMetaType::Type::QBitArray :
206 QgsDebugError( QStringLiteral(
"no support for QVariant::BitArray" ) );
209 case QMetaType::Type::QKeySequence :
210 QgsDebugError( QStringLiteral(
"no support for QVariant::KeySequence" ) );
213 case QMetaType::Type::QPen :
214 QgsDebugError( QStringLiteral(
"no support for QVariant::Pen" ) );
218 case QVariant::LongLong :
219 value_ = QVariant( subkeyElement.text() ).toLongLong();
222 case QVariant::ULongLong :
223 value_ = QVariant( subkeyElement.text() ).toULongLong();
227 QgsDebugError( QStringLiteral(
"unsupported value type %1 .. not properly translated to QVariant" ).arg( typeString ) );
237 QDomElement &keyElement,
238 QDomDocument &document )
240 QDomElement valueElement = document.createElement( QStringLiteral(
"properties" ) );
243 valueElement.setAttribute( QStringLiteral(
"name" ), nodeName );
244 valueElement.setAttribute( QStringLiteral(
"type" ), mValue.typeName() );
250 if ( QMetaType::Type::QStringList == mValue.userType() )
252 QStringList sl = mValue.toStringList();
254 for ( QStringList::iterator i = sl.begin();
258 QDomElement stringListElement = document.createElement( QStringLiteral(
"value" ) );
259 QDomText valueText = document.createTextNode( *i );
260 stringListElement.appendChild( valueText );
262 valueElement.appendChild( stringListElement );
267 QDomText valueText = document.createTextNode( mValue.toString() );
268 valueElement.appendChild( valueText );
271 keyElement.appendChild( valueElement );
290 if ( !foundQgsProperty )
296 return foundQgsProperty->
value();
304 tabString.fill(
'\t', tabs );
309 tabString.fill(
'\t', tabs );
311 if ( ! mProperties.isEmpty() )
313 QHashIterator < QString, QgsProjectProperty * > i( mProperties );
314 while ( i.hasNext() )
316 if ( i.next().value()->isValue() )
320 if ( QMetaType::Type::QStringList == propertyValue->
value().userType() )
322 QgsDebugMsgLevel( QStringLiteral(
"%1key: <%2> value:" ).arg( tabString, i.key() ), 4 );
323 propertyValue->
dump( tabs + 1 );
327 QgsDebugMsgLevel( QStringLiteral(
"%1key: <%2> value: %3" ).arg( tabString, i.key(), propertyValue->
value().toString() ), 4 );
336 i.value()->dump( tabs + 1 );
340 qDebug(
"<%s>",
name().toUtf8().constData() );
341 if ( i.value()->isValue() )
343 qDebug(
" <%s>", i.key().toUtf8().constData() );
346 if ( i.value()->isValue() )
348 qDebug(
" </%s>", i.key().toUtf8().constData() );
350 qDebug(
"</%s>",
name().toUtf8().constData() );
362 QDomNodeList subkeys = keyNode.childNodes();
364 while ( i < subkeys.count() )
366 const QDomNode subkey = subkeys.item( i );
369 if ( subkey.nodeName() == QLatin1String(
"properties" ) &&
370 subkey.hasAttributes() &&
371 subkey.isElement() &&
372 subkey.toElement().hasAttribute( QStringLiteral(
"name" ) ) )
373 name = subkey.toElement().attribute( QStringLiteral(
"name" ) );
375 name = subkey.nodeName();
380 if ( subkey.hasAttributes() &&
381 subkey.isElement() &&
382 subkey.toElement().hasAttribute( QStringLiteral(
"type" ) ) )
386 delete mProperties.take(
name );
420 QDomElement keyElement = document.createElement(
"properties" );
421 keyElement.toElement().setAttribute( QStringLiteral(
"name" ), nodeName );
423 if ( ! mProperties.isEmpty() )
425 auto keys = mProperties.keys();
426 std::sort( keys.begin(), keys.end() );
428 for (
const auto &key : std::as_const( keys ) )
430 if ( !mProperties.value( key )->writeXml( key, keyElement, document ) )
435 element.appendChild( keyElement );
443 QHashIterator < QString, QgsProjectProperty * > i( mProperties );
444 while ( i.hasNext() )
447 if ( i.next().value()->isLeaf() )
449 entries.append( i.key() );
457 QHashIterator < QString, QgsProjectProperty * > i( mProperties );
458 while ( i.hasNext() )
461 if ( !i.next().value()->isLeaf() )
463 entries.append( i.key() );
475 else if ( 1 ==
count() )
477 QHashIterator < QString, QgsProjectProperty * > i( mProperties );
479 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())
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)