23#include <QDomDocument> 
   36  tabString.fill( 
'\t', tabs );
 
   38  if ( QVariant::StringList == mValue.type() )
 
   40    const QStringList sl = mValue.toStringList();
 
   42    for ( 
const auto &
string : sl )
 
   49    QgsDebugMsgLevel( QStringLiteral( 
"%1%2" ).arg( tabString, mValue.toString() ), 4 );
 
   57  QDomElement subkeyElement = keyNode.toElement();
 
   60  QString typeString = subkeyElement.attribute( QStringLiteral( 
"type" ) );
 
   62  if ( typeString.isNull() )
 
   64    QgsDebugMsg( QStringLiteral( 
"null ``type'' attribute for %1" ).arg( keyNode.nodeName() ) );
 
   74  QVariant::Type type = QVariant::nameToType( typeString.toLocal8Bit().constData() );
 
   85    case QVariant::Invalid:
 
   86      QgsDebugMsg( QStringLiteral( 
"invalid value type %1 .. " ).arg( typeString ) );
 
   90      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Map" ) );
 
   94      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::List" ) );
 
   97    case QVariant::String:
 
   98      mValue = subkeyElement.text();  
 
  101    case QVariant::StringList:
 
  104      QDomNodeList values = keyNode.childNodes();
 
  107      QStringList valueStringList;
 
  109      while ( i < values.count() )
 
  111        if ( 
"value" == values.item( i ).nodeName() )
 
  114          valueStringList.append( values.item( i ).firstChild().nodeValue() );
 
  118          QgsDebugMsg( QStringLiteral( 
"non <value> element ``%1'' in string list" ).arg( values.item( i ).nodeName() ) );
 
  124      mValue = valueStringList;
 
  129      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Font" ) );
 
  132    case QVariant::Pixmap:
 
  133      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Pixmap" ) );
 
  136    case QVariant::Brush:
 
  137      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Brush" ) );
 
  141      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Rect" ) );
 
  145      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Size" ) );
 
  148    case QVariant::Color:
 
  149      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Color" ) );
 
  152    case QVariant::Palette:
 
  153      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Palette" ) );
 
  156    case QVariant::Point:
 
  157      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Point" ) );
 
  160    case QVariant::Image:
 
  161      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Image" ) );
 
  165      mValue = QVariant( subkeyElement.text() ).toInt();
 
  169      mValue = QVariant( subkeyElement.text() ).toUInt();
 
  173      mValue = QVariant( subkeyElement.text() ).toBool();
 
  176    case QVariant::Double:
 
  177      mValue = QVariant( subkeyElement.text() ).toDouble();
 
  180    case QVariant::ByteArray:
 
  181      mValue = QVariant( subkeyElement.text() ).toByteArray();
 
  184    case QVariant::Polygon:
 
  185      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Polygon" ) );
 
  188    case QVariant::Region:
 
  189      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Region" ) );
 
  192    case QVariant::Bitmap:
 
  193      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Bitmap" ) );
 
  196    case QVariant::Cursor:
 
  197      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Cursor" ) );
 
  200    case QVariant::BitArray :
 
  201      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::BitArray" ) );
 
  204    case QVariant::KeySequence :
 
  205      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::KeySequence" ) );
 
  209      QgsDebugMsg( QStringLiteral( 
"no support for QVariant::Pen" ) );
 
  213    case QVariant::LongLong :
 
  214      value_ = QVariant( subkeyElement.text() ).toLongLong();
 
  217    case QVariant::ULongLong :
 
  218      value_ = QVariant( subkeyElement.text() ).toULongLong();
 
  222      QgsDebugMsg( QStringLiteral( 
"unsupported value type %1 .. not properly translated to QVariant" ).arg( typeString ) );
 
  232                                        QDomElement    &keyElement,
 
  233                                        QDomDocument   &document )
 
  235  QDomElement valueElement = document.createElement( nodeName );
 
  238  valueElement.setAttribute( QStringLiteral( 
"type" ), mValue.typeName() );
 
  245  if ( QVariant::StringList == mValue.type() )
 
  247    QStringList sl = mValue.toStringList();
 
  249    for ( QStringList::iterator i = sl.begin();
 
  253      QDomElement stringListElement = document.createElement( QStringLiteral( 
"value" ) );
 
  254      QDomText valueText = document.createTextNode( *i );
 
  255      stringListElement.appendChild( valueText );
 
  257      valueElement.appendChild( stringListElement );
 
  262    QDomText valueText = document.createTextNode( mValue.toString() );
 
  263    valueElement.appendChild( valueText );
 
  266  keyElement.appendChild( valueElement );
 
  285  if ( !foundQgsProperty )
 
  287    QgsDebugMsg( QStringLiteral( 
"key has null child" ) );
 
  291  return foundQgsProperty->
value();
 
  299  tabString.fill( 
'\t', tabs );
 
  304  tabString.fill( 
'\t', tabs );
 
  306  if ( ! mProperties.isEmpty() )
 
  308    QHashIterator < QString, QgsProjectProperty * > i( mProperties );
 
  309    while ( i.hasNext() )
 
  311      if ( i.next().value()->isValue() )
 
  315        if ( QVariant::StringList == propertyValue->
value().type() )
 
  317          QgsDebugMsgLevel( QStringLiteral( 
"%1key: <%2>  value:" ).arg( tabString, i.key() ), 4 );
 
  318          propertyValue->
dump( tabs + 1 );
 
  322          QgsDebugMsgLevel( QStringLiteral( 
"%1key: <%2>  value: %3" ).arg( tabString, i.key(), propertyValue->
value().toString() ), 4 );
 
  331        i.value()->dump( tabs + 1 );
 
  335      qDebug( 
"<%s>", 
name().toUtf8().constData() );
 
  336      if ( i.value()->isValue() )
 
  338        qDebug( 
"   <%s>", i.key().toUtf8().constData() );
 
  341      if ( i.value()->isValue() )
 
  343        qDebug( 
"   </%s>", i.key().toUtf8().constData() );
 
  345      qDebug( 
"</%s>", 
name().toUtf8().constData() );
 
  357  QDomNodeList subkeys = keyNode.childNodes();
 
  359  while ( i < subkeys.count() )
 
  364    if ( subkeys.item( i ).hasAttributes() && 
 
  365         subkeys.item( i ).isElement() && 
 
  366         subkeys.item( i ).toElement().hasAttribute( QStringLiteral( 
"type" ) ) ) 
 
  369      delete mProperties.take( subkeys.item( i ).nodeName() );
 
  372      QDomNode subkey = subkeys.item( i );
 
  374      if ( !mProperties[subkeys.item( i ).nodeName()]->readXml( subkey ) )
 
  376        QgsDebugMsg( QStringLiteral( 
"unable to parse key value %1" ).arg( subkeys.item( i ).nodeName() ) );
 
  381      addKey( subkeys.item( i ).nodeName() );
 
  383      QDomNode subkey = subkeys.item( i );
 
  385      if ( !mProperties[subkeys.item( i ).nodeName()]->readXml( subkey ) )
 
  387        QgsDebugMsg( QStringLiteral( 
"unable to parse subkey %1" ).arg( subkeys.item( i ).nodeName() ) );
 
  407  QDomElement keyElement = document.createElement( nodeName ); 
 
  409  if ( ! mProperties.isEmpty() )
 
  411    auto keys = mProperties.keys();
 
  412    std::sort( keys.begin(), keys.end() );
 
  414    for ( 
const auto &key : std::as_const( keys ) )
 
  416      if ( !mProperties.value( key )->writeXml( key, keyElement, document ) )
 
  421  element.appendChild( keyElement );
 
  429  QHashIterator < QString, QgsProjectProperty * > i( mProperties );
 
  430  while ( i.hasNext() )
 
  433    if ( i.next().value()->isLeaf() )
 
  435      entries.append( i.key() );
 
  443  QHashIterator < QString, QgsProjectProperty * > i( mProperties );
 
  444  while ( i.hasNext() )
 
  447    if ( !i.next().value()->isLeaf() )
 
  449      entries.append( i.key() );
 
  461  else if ( 1 == 
count() )
 
  463    QHashIterator < QString, QgsProjectProperty * > i( mProperties );
 
  465    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)
Adds a message to the log instance (and creates it if necessary).
 
Project property key node.
 
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.
 
An Abstract Base Class for QGIS project property hierarchys.
 
virtual QVariant value() const =0
Returns the node's value.
 
#define QgsDebugMsgLevel(str, level)