/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT!

#include "ui4.h"


QT_BEGIN_NAMESPACE
#ifdef QFORMINTERNAL_NAMESPACE
using namespace QFormInternal;
#endif

/*******************************************************************************
** Implementations
*/

DomUI::~DomUI()
{
    delete m_widget;
    delete m_layoutDefault;
    delete m_layoutFunction;
    delete m_customWidgets;
    delete m_tabStops;
    delete m_includes;
    delete m_resources;
    delete m_connections;
    delete m_designerdata;
    delete m_slots;
    delete m_buttonGroups;
}

void DomUI::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("version")) {
            setAttributeVersion(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("language")) {
            setAttributeLanguage(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("displayname")) {
            setAttributeDisplayname(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("idbasedtr")) {
            setAttributeIdbasedtr(attribute.value() == QLatin1String("true"));
            continue;
        }
        if (name == QLatin1String("connectslotsbyname")) {
            setAttributeConnectslotsbyname(attribute.value() == QLatin1String("true"));
            continue;
        }
        if (name == QLatin1String("stdsetdef")) {
            setAttributeStdsetdef(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("stdSetDef")) {
            setAttributeStdSetDef(attribute.value().toInt());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("author"), Qt::CaseInsensitive)) {
                setElementAuthor(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("comment"), Qt::CaseInsensitive)) {
                setElementComment(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("exportmacro"), Qt::CaseInsensitive)) {
                setElementExportMacro(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("class"), Qt::CaseInsensitive)) {
                setElementClass(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
                auto *v = new DomWidget();
                v->read(reader);
                setElementWidget(v);
                continue;
            }
            if (!tag.compare(QLatin1String("layoutdefault"), Qt::CaseInsensitive)) {
                auto *v = new DomLayoutDefault();
                v->read(reader);
                setElementLayoutDefault(v);
                continue;
            }
            if (!tag.compare(QLatin1String("layoutfunction"), Qt::CaseInsensitive)) {
                auto *v = new DomLayoutFunction();
                v->read(reader);
                setElementLayoutFunction(v);
                continue;
            }
            if (!tag.compare(QLatin1String("pixmapfunction"), Qt::CaseInsensitive)) {
                setElementPixmapFunction(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("customwidgets"), Qt::CaseInsensitive)) {
                auto *v = new DomCustomWidgets();
                v->read(reader);
                setElementCustomWidgets(v);
                continue;
            }
            if (!tag.compare(QLatin1String("tabstops"), Qt::CaseInsensitive)) {
                auto *v = new DomTabStops();
                v->read(reader);
                setElementTabStops(v);
                continue;
            }
            if (!tag.compare(QLatin1String("images"), Qt::CaseInsensitive)) {
                qWarning("Omitting deprecated element <images>.");
                reader.skipCurrentElement();
                continue;
            }
            if (!tag.compare(QLatin1String("includes"), Qt::CaseInsensitive)) {
                auto *v = new DomIncludes();
                v->read(reader);
                setElementIncludes(v);
                continue;
            }
            if (!tag.compare(QLatin1String("resources"), Qt::CaseInsensitive)) {
                auto *v = new DomResources();
                v->read(reader);
                setElementResources(v);
                continue;
            }
            if (!tag.compare(QLatin1String("connections"), Qt::CaseInsensitive)) {
                auto *v = new DomConnections();
                v->read(reader);
                setElementConnections(v);
                continue;
            }
            if (!tag.compare(QLatin1String("designerdata"), Qt::CaseInsensitive)) {
                auto *v = new DomDesignerData();
                v->read(reader);
                setElementDesignerdata(v);
                continue;
            }
            if (!tag.compare(QLatin1String("slots"), Qt::CaseInsensitive)) {
                auto *v = new DomSlots();
                v->read(reader);
                setElementSlots(v);
                continue;
            }
            if (!tag.compare(QLatin1String("buttongroups"), Qt::CaseInsensitive)) {
                auto *v = new DomButtonGroups();
                v->read(reader);
                setElementButtonGroups(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomUI::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("ui") : tagName.toLower());

    if (hasAttributeVersion())
        writer.writeAttribute(QStringLiteral("version"), attributeVersion());

    if (hasAttributeLanguage())
        writer.writeAttribute(QStringLiteral("language"), attributeLanguage());

    if (hasAttributeDisplayname())
        writer.writeAttribute(QStringLiteral("displayname"), attributeDisplayname());

    if (hasAttributeIdbasedtr())
        writer.writeAttribute(QStringLiteral("idbasedtr"), (attributeIdbasedtr() ? QLatin1String("true") : QLatin1String("false")));

    if (hasAttributeConnectslotsbyname())
        writer.writeAttribute(QStringLiteral("connectslotsbyname"), (attributeConnectslotsbyname() ? QLatin1String("true") : QLatin1String("false")));

    if (hasAttributeStdsetdef())
        writer.writeAttribute(QStringLiteral("stdsetdef"), QString::number(attributeStdsetdef()));

    if (hasAttributeStdSetDef())
        writer.writeAttribute(QStringLiteral("stdsetdef"), QString::number(attributeStdSetDef()));

    if (m_children & Author)
        writer.writeTextElement(QStringLiteral("author"), m_author);

    if (m_children & Comment)
        writer.writeTextElement(QStringLiteral("comment"), m_comment);

    if (m_children & ExportMacro)
        writer.writeTextElement(QStringLiteral("exportmacro"), m_exportMacro);

    if (m_children & Class)
        writer.writeTextElement(QStringLiteral("class"), m_class);

    if (m_children & Widget)
        m_widget->write(writer, QStringLiteral("widget"));

    if (m_children & LayoutDefault)
        m_layoutDefault->write(writer, QStringLiteral("layoutdefault"));

    if (m_children & LayoutFunction)
        m_layoutFunction->write(writer, QStringLiteral("layoutfunction"));

    if (m_children & PixmapFunction)
        writer.writeTextElement(QStringLiteral("pixmapfunction"), m_pixmapFunction);

    if (m_children & CustomWidgets)
        m_customWidgets->write(writer, QStringLiteral("customwidgets"));

    if (m_children & TabStops)
        m_tabStops->write(writer, QStringLiteral("tabstops"));

    if (m_children & Includes)
        m_includes->write(writer, QStringLiteral("includes"));

    if (m_children & Resources)
        m_resources->write(writer, QStringLiteral("resources"));

    if (m_children & Connections)
        m_connections->write(writer, QStringLiteral("connections"));

    if (m_children & Designerdata)
        m_designerdata->write(writer, QStringLiteral("designerdata"));

    if (m_children & Slots)
        m_slots->write(writer, QStringLiteral("slots"));

    if (m_children & ButtonGroups)
        m_buttonGroups->write(writer, QStringLiteral("buttongroups"));

    writer.writeEndElement();
}

void DomUI::setElementAuthor(const QString &a)
{
    m_children |= Author;
    m_author = a;
}

void DomUI::setElementComment(const QString &a)
{
    m_children |= Comment;
    m_comment = a;
}

void DomUI::setElementExportMacro(const QString &a)
{
    m_children |= ExportMacro;
    m_exportMacro = a;
}

void DomUI::setElementClass(const QString &a)
{
    m_children |= Class;
    m_class = a;
}

DomWidget *DomUI::takeElementWidget()
{
    DomWidget *a = m_widget;
    m_widget = nullptr;
    m_children ^= Widget;
    return a;
}

void DomUI::setElementWidget(DomWidget *a)
{
    delete m_widget;
    m_children |= Widget;
    m_widget = a;
}

DomLayoutDefault *DomUI::takeElementLayoutDefault()
{
    DomLayoutDefault *a = m_layoutDefault;
    m_layoutDefault = nullptr;
    m_children ^= LayoutDefault;
    return a;
}

void DomUI::setElementLayoutDefault(DomLayoutDefault *a)
{
    delete m_layoutDefault;
    m_children |= LayoutDefault;
    m_layoutDefault = a;
}

DomLayoutFunction *DomUI::takeElementLayoutFunction()
{
    DomLayoutFunction *a = m_layoutFunction;
    m_layoutFunction = nullptr;
    m_children ^= LayoutFunction;
    return a;
}

void DomUI::setElementLayoutFunction(DomLayoutFunction *a)
{
    delete m_layoutFunction;
    m_children |= LayoutFunction;
    m_layoutFunction = a;
}

void DomUI::setElementPixmapFunction(const QString &a)
{
    m_children |= PixmapFunction;
    m_pixmapFunction = a;
}

DomCustomWidgets *DomUI::takeElementCustomWidgets()
{
    DomCustomWidgets *a = m_customWidgets;
    m_customWidgets = nullptr;
    m_children ^= CustomWidgets;
    return a;
}

void DomUI::setElementCustomWidgets(DomCustomWidgets *a)
{
    delete m_customWidgets;
    m_children |= CustomWidgets;
    m_customWidgets = a;
}

DomTabStops *DomUI::takeElementTabStops()
{
    DomTabStops *a = m_tabStops;
    m_tabStops = nullptr;
    m_children ^= TabStops;
    return a;
}

void DomUI::setElementTabStops(DomTabStops *a)
{
    delete m_tabStops;
    m_children |= TabStops;
    m_tabStops = a;
}

DomIncludes *DomUI::takeElementIncludes()
{
    DomIncludes *a = m_includes;
    m_includes = nullptr;
    m_children ^= Includes;
    return a;
}

void DomUI::setElementIncludes(DomIncludes *a)
{
    delete m_includes;
    m_children |= Includes;
    m_includes = a;
}

DomResources *DomUI::takeElementResources()
{
    DomResources *a = m_resources;
    m_resources = nullptr;
    m_children ^= Resources;
    return a;
}

void DomUI::setElementResources(DomResources *a)
{
    delete m_resources;
    m_children |= Resources;
    m_resources = a;
}

DomConnections *DomUI::takeElementConnections()
{
    DomConnections *a = m_connections;
    m_connections = nullptr;
    m_children ^= Connections;
    return a;
}

void DomUI::setElementConnections(DomConnections *a)
{
    delete m_connections;
    m_children |= Connections;
    m_connections = a;
}

DomDesignerData *DomUI::takeElementDesignerdata()
{
    DomDesignerData *a = m_designerdata;
    m_designerdata = nullptr;
    m_children ^= Designerdata;
    return a;
}

void DomUI::setElementDesignerdata(DomDesignerData *a)
{
    delete m_designerdata;
    m_children |= Designerdata;
    m_designerdata = a;
}

DomSlots *DomUI::takeElementSlots()
{
    DomSlots *a = m_slots;
    m_slots = nullptr;
    m_children ^= Slots;
    return a;
}

void DomUI::setElementSlots(DomSlots *a)
{
    delete m_slots;
    m_children |= Slots;
    m_slots = a;
}

DomButtonGroups *DomUI::takeElementButtonGroups()
{
    DomButtonGroups *a = m_buttonGroups;
    m_buttonGroups = nullptr;
    m_children ^= ButtonGroups;
    return a;
}

void DomUI::setElementButtonGroups(DomButtonGroups *a)
{
    delete m_buttonGroups;
    m_children |= ButtonGroups;
    m_buttonGroups = a;
}

void DomUI::clearElementAuthor()
{
    m_children &= ~Author;
}

void DomUI::clearElementComment()
{
    m_children &= ~Comment;
}

void DomUI::clearElementExportMacro()
{
    m_children &= ~ExportMacro;
}

void DomUI::clearElementClass()
{
    m_children &= ~Class;
}

void DomUI::clearElementWidget()
{
    delete m_widget;
    m_widget = nullptr;
    m_children &= ~Widget;
}

void DomUI::clearElementLayoutDefault()
{
    delete m_layoutDefault;
    m_layoutDefault = nullptr;
    m_children &= ~LayoutDefault;
}

void DomUI::clearElementLayoutFunction()
{
    delete m_layoutFunction;
    m_layoutFunction = nullptr;
    m_children &= ~LayoutFunction;
}

void DomUI::clearElementPixmapFunction()
{
    m_children &= ~PixmapFunction;
}

void DomUI::clearElementCustomWidgets()
{
    delete m_customWidgets;
    m_customWidgets = nullptr;
    m_children &= ~CustomWidgets;
}

void DomUI::clearElementTabStops()
{
    delete m_tabStops;
    m_tabStops = nullptr;
    m_children &= ~TabStops;
}

void DomUI::clearElementIncludes()
{
    delete m_includes;
    m_includes = nullptr;
    m_children &= ~Includes;
}

void DomUI::clearElementResources()
{
    delete m_resources;
    m_resources = nullptr;
    m_children &= ~Resources;
}

void DomUI::clearElementConnections()
{
    delete m_connections;
    m_connections = nullptr;
    m_children &= ~Connections;
}

void DomUI::clearElementDesignerdata()
{
    delete m_designerdata;
    m_designerdata = nullptr;
    m_children &= ~Designerdata;
}

void DomUI::clearElementSlots()
{
    delete m_slots;
    m_slots = nullptr;
    m_children &= ~Slots;
}

void DomUI::clearElementButtonGroups()
{
    delete m_buttonGroups;
    m_buttonGroups = nullptr;
    m_children &= ~ButtonGroups;
}

DomIncludes::~DomIncludes()
{
    qDeleteAll(m_include);
    m_include.clear();
}

void DomIncludes::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("include"), Qt::CaseInsensitive)) {
                auto *v = new DomInclude();
                v->read(reader);
                m_include.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomIncludes::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("includes") : tagName.toLower());

    for (DomInclude *v : m_include)
        v->write(writer, QStringLiteral("include"));

    writer.writeEndElement();
}

void DomIncludes::setElementInclude(const QVector<DomInclude *> &a)
{
    m_children |= Include;
    m_include = a;
}

DomInclude::~DomInclude() = default;

void DomInclude::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("location")) {
            setAttributeLocation(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("impldecl")) {
            setAttributeImpldecl(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        case QXmlStreamReader::Characters :
            if (!reader.isWhitespace())
                m_text.append(reader.text().toString());
            break;
        default :
            break;
        }
    }
}

void DomInclude::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("include") : tagName.toLower());

    if (hasAttributeLocation())
        writer.writeAttribute(QStringLiteral("location"), attributeLocation());

    if (hasAttributeImpldecl())
        writer.writeAttribute(QStringLiteral("impldecl"), attributeImpldecl());

    if (!m_text.isEmpty())
        writer.writeCharacters(m_text);

    writer.writeEndElement();
}

DomResources::~DomResources()
{
    qDeleteAll(m_include);
    m_include.clear();
}

void DomResources::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("include"), Qt::CaseInsensitive)) {
                auto *v = new DomResource();
                v->read(reader);
                m_include.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomResources::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("resources") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    for (DomResource *v : m_include)
        v->write(writer, QStringLiteral("include"));

    writer.writeEndElement();
}

void DomResources::setElementInclude(const QVector<DomResource *> &a)
{
    m_children |= Include;
    m_include = a;
}

DomResource::~DomResource() = default;

void DomResource::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("location")) {
            setAttributeLocation(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomResource::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("resource") : tagName.toLower());

    if (hasAttributeLocation())
        writer.writeAttribute(QStringLiteral("location"), attributeLocation());

    writer.writeEndElement();
}

DomActionGroup::~DomActionGroup()
{
    qDeleteAll(m_action);
    m_action.clear();
    qDeleteAll(m_actionGroup);
    m_actionGroup.clear();
    qDeleteAll(m_property);
    m_property.clear();
    qDeleteAll(m_attribute);
    m_attribute.clear();
}

void DomActionGroup::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("action"), Qt::CaseInsensitive)) {
                auto *v = new DomAction();
                v->read(reader);
                m_action.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("actiongroup"), Qt::CaseInsensitive)) {
                auto *v = new DomActionGroup();
                v->read(reader);
                m_actionGroup.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_attribute.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomActionGroup::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("actiongroup") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    for (DomAction *v : m_action)
        v->write(writer, QStringLiteral("action"));

    for (DomActionGroup *v : m_actionGroup)
        v->write(writer, QStringLiteral("actiongroup"));

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    for (DomProperty *v : m_attribute)
        v->write(writer, QStringLiteral("attribute"));

    writer.writeEndElement();
}

void DomActionGroup::setElementAction(const QVector<DomAction *> &a)
{
    m_children |= Action;
    m_action = a;
}

void DomActionGroup::setElementActionGroup(const QVector<DomActionGroup *> &a)
{
    m_children |= ActionGroup;
    m_actionGroup = a;
}

void DomActionGroup::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

void DomActionGroup::setElementAttribute(const QList<DomProperty *> &a)
{
    m_children |= Attribute;
    m_attribute = a;
}

DomAction::~DomAction()
{
    qDeleteAll(m_property);
    m_property.clear();
    qDeleteAll(m_attribute);
    m_attribute.clear();
}

void DomAction::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("menu")) {
            setAttributeMenu(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_attribute.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomAction::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("action") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    if (hasAttributeMenu())
        writer.writeAttribute(QStringLiteral("menu"), attributeMenu());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    for (DomProperty *v : m_attribute)
        v->write(writer, QStringLiteral("attribute"));

    writer.writeEndElement();
}

void DomAction::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

void DomAction::setElementAttribute(const QList<DomProperty *> &a)
{
    m_children |= Attribute;
    m_attribute = a;
}

DomActionRef::~DomActionRef() = default;

void DomActionRef::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomActionRef::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("actionref") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    writer.writeEndElement();
}

DomButtonGroup::~DomButtonGroup()
{
    qDeleteAll(m_property);
    m_property.clear();
    qDeleteAll(m_attribute);
    m_attribute.clear();
}

void DomButtonGroup::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_attribute.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomButtonGroup::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("buttongroup") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    for (DomProperty *v : m_attribute)
        v->write(writer, QStringLiteral("attribute"));

    writer.writeEndElement();
}

void DomButtonGroup::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

void DomButtonGroup::setElementAttribute(const QList<DomProperty *> &a)
{
    m_children |= Attribute;
    m_attribute = a;
}

DomButtonGroups::~DomButtonGroups()
{
    qDeleteAll(m_buttonGroup);
    m_buttonGroup.clear();
}

void DomButtonGroups::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("buttongroup"), Qt::CaseInsensitive)) {
                auto *v = new DomButtonGroup();
                v->read(reader);
                m_buttonGroup.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomButtonGroups::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("buttongroups") : tagName.toLower());

    for (DomButtonGroup *v : m_buttonGroup)
        v->write(writer, QStringLiteral("buttongroup"));

    writer.writeEndElement();
}

void DomButtonGroups::setElementButtonGroup(const QVector<DomButtonGroup *> &a)
{
    m_children |= ButtonGroup;
    m_buttonGroup = a;
}

DomCustomWidgets::~DomCustomWidgets()
{
    qDeleteAll(m_customWidget);
    m_customWidget.clear();
}

void DomCustomWidgets::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("customwidget"), Qt::CaseInsensitive)) {
                auto *v = new DomCustomWidget();
                v->read(reader);
                m_customWidget.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomCustomWidgets::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("customwidgets") : tagName.toLower());

    for (DomCustomWidget *v : m_customWidget)
        v->write(writer, QStringLiteral("customwidget"));

    writer.writeEndElement();
}

void DomCustomWidgets::setElementCustomWidget(const QVector<DomCustomWidget *> &a)
{
    m_children |= CustomWidget;
    m_customWidget = a;
}

DomHeader::~DomHeader() = default;

void DomHeader::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("location")) {
            setAttributeLocation(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        case QXmlStreamReader::Characters :
            if (!reader.isWhitespace())
                m_text.append(reader.text().toString());
            break;
        default :
            break;
        }
    }
}

void DomHeader::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("header") : tagName.toLower());

    if (hasAttributeLocation())
        writer.writeAttribute(QStringLiteral("location"), attributeLocation());

    if (!m_text.isEmpty())
        writer.writeCharacters(m_text);

    writer.writeEndElement();
}

DomCustomWidget::~DomCustomWidget()
{
    delete m_header;
    delete m_sizeHint;
    delete m_slots;
    delete m_propertyspecifications;
}

void DomCustomWidget::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("class"), Qt::CaseInsensitive)) {
                setElementClass(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("extends"), Qt::CaseInsensitive)) {
                setElementExtends(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("header"), Qt::CaseInsensitive)) {
                auto *v = new DomHeader();
                v->read(reader);
                setElementHeader(v);
                continue;
            }
            if (!tag.compare(QLatin1String("sizehint"), Qt::CaseInsensitive)) {
                auto *v = new DomSize();
                v->read(reader);
                setElementSizeHint(v);
                continue;
            }
            if (!tag.compare(QLatin1String("addpagemethod"), Qt::CaseInsensitive)) {
                setElementAddPageMethod(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("container"), Qt::CaseInsensitive)) {
                setElementContainer(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("sizepolicy"), Qt::CaseInsensitive)) {
                qWarning("Omitting deprecated element <sizepolicy>.");
                reader.skipCurrentElement();
                continue;
            }
            if (!tag.compare(QLatin1String("pixmap"), Qt::CaseInsensitive)) {
                setElementPixmap(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("script"), Qt::CaseInsensitive)) {
                qWarning("Omitting deprecated element <script>.");
                reader.skipCurrentElement();
                continue;
            }
            if (!tag.compare(QLatin1String("properties"), Qt::CaseInsensitive)) {
                qWarning("Omitting deprecated element <properties>.");
                reader.skipCurrentElement();
                continue;
            }
            if (!tag.compare(QLatin1String("slots"), Qt::CaseInsensitive)) {
                auto *v = new DomSlots();
                v->read(reader);
                setElementSlots(v);
                continue;
            }
            if (!tag.compare(QLatin1String("propertyspecifications"), Qt::CaseInsensitive)) {
                auto *v = new DomPropertySpecifications();
                v->read(reader);
                setElementPropertyspecifications(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomCustomWidget::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("customwidget") : tagName.toLower());

    if (m_children & Class)
        writer.writeTextElement(QStringLiteral("class"), m_class);

    if (m_children & Extends)
        writer.writeTextElement(QStringLiteral("extends"), m_extends);

    if (m_children & Header)
        m_header->write(writer, QStringLiteral("header"));

    if (m_children & SizeHint)
        m_sizeHint->write(writer, QStringLiteral("sizehint"));

    if (m_children & AddPageMethod)
        writer.writeTextElement(QStringLiteral("addpagemethod"), m_addPageMethod);

    if (m_children & Container)
        writer.writeTextElement(QStringLiteral("container"), QString::number(m_container));

    if (m_children & Pixmap)
        writer.writeTextElement(QStringLiteral("pixmap"), m_pixmap);

    if (m_children & Slots)
        m_slots->write(writer, QStringLiteral("slots"));

    if (m_children & Propertyspecifications)
        m_propertyspecifications->write(writer, QStringLiteral("propertyspecifications"));

    writer.writeEndElement();
}

void DomCustomWidget::setElementClass(const QString &a)
{
    m_children |= Class;
    m_class = a;
}

void DomCustomWidget::setElementExtends(const QString &a)
{
    m_children |= Extends;
    m_extends = a;
}

DomHeader *DomCustomWidget::takeElementHeader()
{
    DomHeader *a = m_header;
    m_header = nullptr;
    m_children ^= Header;
    return a;
}

void DomCustomWidget::setElementHeader(DomHeader *a)
{
    delete m_header;
    m_children |= Header;
    m_header = a;
}

DomSize *DomCustomWidget::takeElementSizeHint()
{
    DomSize *a = m_sizeHint;
    m_sizeHint = nullptr;
    m_children ^= SizeHint;
    return a;
}

void DomCustomWidget::setElementSizeHint(DomSize *a)
{
    delete m_sizeHint;
    m_children |= SizeHint;
    m_sizeHint = a;
}

void DomCustomWidget::setElementAddPageMethod(const QString &a)
{
    m_children |= AddPageMethod;
    m_addPageMethod = a;
}

void DomCustomWidget::setElementContainer(int a)
{
    m_children |= Container;
    m_container = a;
}

void DomCustomWidget::setElementPixmap(const QString &a)
{
    m_children |= Pixmap;
    m_pixmap = a;
}

DomSlots *DomCustomWidget::takeElementSlots()
{
    DomSlots *a = m_slots;
    m_slots = nullptr;
    m_children ^= Slots;
    return a;
}

void DomCustomWidget::setElementSlots(DomSlots *a)
{
    delete m_slots;
    m_children |= Slots;
    m_slots = a;
}

DomPropertySpecifications *DomCustomWidget::takeElementPropertyspecifications()
{
    DomPropertySpecifications *a = m_propertyspecifications;
    m_propertyspecifications = nullptr;
    m_children ^= Propertyspecifications;
    return a;
}

void DomCustomWidget::setElementPropertyspecifications(DomPropertySpecifications *a)
{
    delete m_propertyspecifications;
    m_children |= Propertyspecifications;
    m_propertyspecifications = a;
}

void DomCustomWidget::clearElementClass()
{
    m_children &= ~Class;
}

void DomCustomWidget::clearElementExtends()
{
    m_children &= ~Extends;
}

void DomCustomWidget::clearElementHeader()
{
    delete m_header;
    m_header = nullptr;
    m_children &= ~Header;
}

void DomCustomWidget::clearElementSizeHint()
{
    delete m_sizeHint;
    m_sizeHint = nullptr;
    m_children &= ~SizeHint;
}

void DomCustomWidget::clearElementAddPageMethod()
{
    m_children &= ~AddPageMethod;
}

void DomCustomWidget::clearElementContainer()
{
    m_children &= ~Container;
}

void DomCustomWidget::clearElementPixmap()
{
    m_children &= ~Pixmap;
}

void DomCustomWidget::clearElementSlots()
{
    delete m_slots;
    m_slots = nullptr;
    m_children &= ~Slots;
}

void DomCustomWidget::clearElementPropertyspecifications()
{
    delete m_propertyspecifications;
    m_propertyspecifications = nullptr;
    m_children &= ~Propertyspecifications;
}

DomLayoutDefault::~DomLayoutDefault() = default;

void DomLayoutDefault::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("spacing")) {
            setAttributeSpacing(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("margin")) {
            setAttributeMargin(attribute.value().toInt());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomLayoutDefault::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("layoutdefault") : tagName.toLower());

    if (hasAttributeSpacing())
        writer.writeAttribute(QStringLiteral("spacing"), QString::number(attributeSpacing()));

    if (hasAttributeMargin())
        writer.writeAttribute(QStringLiteral("margin"), QString::number(attributeMargin()));

    writer.writeEndElement();
}

DomLayoutFunction::~DomLayoutFunction() = default;

void DomLayoutFunction::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("spacing")) {
            setAttributeSpacing(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("margin")) {
            setAttributeMargin(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomLayoutFunction::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("layoutfunction") : tagName.toLower());

    if (hasAttributeSpacing())
        writer.writeAttribute(QStringLiteral("spacing"), attributeSpacing());

    if (hasAttributeMargin())
        writer.writeAttribute(QStringLiteral("margin"), attributeMargin());

    writer.writeEndElement();
}

DomTabStops::~DomTabStops()
{
    m_tabStop.clear();
}

void DomTabStops::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("tabstop"), Qt::CaseInsensitive)) {
                m_tabStop.append(reader.readElementText());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomTabStops::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("tabstops") : tagName.toLower());

    for (const QString &v : m_tabStop)
        writer.writeTextElement(QStringLiteral("tabstop"), v);

    writer.writeEndElement();
}

void DomTabStops::setElementTabStop(const QStringList &a)
{
    m_children |= TabStop;
    m_tabStop = a;
}

DomLayout::~DomLayout()
{
    qDeleteAll(m_property);
    m_property.clear();
    qDeleteAll(m_attribute);
    m_attribute.clear();
    qDeleteAll(m_item);
    m_item.clear();
}

void DomLayout::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("class")) {
            setAttributeClass(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("stretch")) {
            setAttributeStretch(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("rowstretch")) {
            setAttributeRowStretch(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("columnstretch")) {
            setAttributeColumnStretch(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("rowminimumheight")) {
            setAttributeRowMinimumHeight(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("columnminimumwidth")) {
            setAttributeColumnMinimumWidth(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_attribute.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("item"), Qt::CaseInsensitive)) {
                auto *v = new DomLayoutItem();
                v->read(reader);
                m_item.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomLayout::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("layout") : tagName.toLower());

    if (hasAttributeClass())
        writer.writeAttribute(QStringLiteral("class"), attributeClass());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    if (hasAttributeStretch())
        writer.writeAttribute(QStringLiteral("stretch"), attributeStretch());

    if (hasAttributeRowStretch())
        writer.writeAttribute(QStringLiteral("rowstretch"), attributeRowStretch());

    if (hasAttributeColumnStretch())
        writer.writeAttribute(QStringLiteral("columnstretch"), attributeColumnStretch());

    if (hasAttributeRowMinimumHeight())
        writer.writeAttribute(QStringLiteral("rowminimumheight"), attributeRowMinimumHeight());

    if (hasAttributeColumnMinimumWidth())
        writer.writeAttribute(QStringLiteral("columnminimumwidth"), attributeColumnMinimumWidth());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    for (DomProperty *v : m_attribute)
        v->write(writer, QStringLiteral("attribute"));

    for (DomLayoutItem *v : m_item)
        v->write(writer, QStringLiteral("item"));

    writer.writeEndElement();
}

void DomLayout::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

void DomLayout::setElementAttribute(const QList<DomProperty *> &a)
{
    m_children |= Attribute;
    m_attribute = a;
}

void DomLayout::setElementItem(const QVector<DomLayoutItem *> &a)
{
    m_children |= Item;
    m_item = a;
}

DomLayoutItem::~DomLayoutItem()
{
    delete m_widget;
    delete m_layout;
    delete m_spacer;
}

void DomLayoutItem::clear()
{
    delete m_widget;
    delete m_layout;
    delete m_spacer;

    m_kind = Unknown;

    m_widget = nullptr;
    m_layout = nullptr;
    m_spacer = nullptr;
}

void DomLayoutItem::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("row")) {
            setAttributeRow(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("column")) {
            setAttributeColumn(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("rowspan")) {
            setAttributeRowSpan(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("colspan")) {
            setAttributeColSpan(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("alignment")) {
            setAttributeAlignment(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
                auto *v = new DomWidget();
                v->read(reader);
                setElementWidget(v);
                continue;
            }
            if (!tag.compare(QLatin1String("layout"), Qt::CaseInsensitive)) {
                auto *v = new DomLayout();
                v->read(reader);
                setElementLayout(v);
                continue;
            }
            if (!tag.compare(QLatin1String("spacer"), Qt::CaseInsensitive)) {
                auto *v = new DomSpacer();
                v->read(reader);
                setElementSpacer(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomLayoutItem::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("layoutitem") : tagName.toLower());

    if (hasAttributeRow())
        writer.writeAttribute(QStringLiteral("row"), QString::number(attributeRow()));

    if (hasAttributeColumn())
        writer.writeAttribute(QStringLiteral("column"), QString::number(attributeColumn()));

    if (hasAttributeRowSpan())
        writer.writeAttribute(QStringLiteral("rowspan"), QString::number(attributeRowSpan()));

    if (hasAttributeColSpan())
        writer.writeAttribute(QStringLiteral("colspan"), QString::number(attributeColSpan()));

    if (hasAttributeAlignment())
        writer.writeAttribute(QStringLiteral("alignment"), attributeAlignment());

    switch (kind()) {
    case Widget:
        if (m_widget != nullptr)
            m_widget->write(writer, QStringLiteral("widget"));
        break;

    case Layout:
        if (m_layout != nullptr)
            m_layout->write(writer, QStringLiteral("layout"));
        break;

    case Spacer:
        if (m_spacer != nullptr)
            m_spacer->write(writer, QStringLiteral("spacer"));
        break;

    default:
        break;
    }
    writer.writeEndElement();
}

DomWidget *DomLayoutItem::takeElementWidget()
{
    DomWidget *a = m_widget;
    m_widget = nullptr;
    return a;
}

void DomLayoutItem::setElementWidget(DomWidget *a)
{
    clear();
    m_kind = Widget;
    m_widget = a;
}

DomLayout *DomLayoutItem::takeElementLayout()
{
    DomLayout *a = m_layout;
    m_layout = nullptr;
    return a;
}

void DomLayoutItem::setElementLayout(DomLayout *a)
{
    clear();
    m_kind = Layout;
    m_layout = a;
}

DomSpacer *DomLayoutItem::takeElementSpacer()
{
    DomSpacer *a = m_spacer;
    m_spacer = nullptr;
    return a;
}

void DomLayoutItem::setElementSpacer(DomSpacer *a)
{
    clear();
    m_kind = Spacer;
    m_spacer = a;
}

DomRow::~DomRow()
{
    qDeleteAll(m_property);
    m_property.clear();
}

void DomRow::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomRow::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("row") : tagName.toLower());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    writer.writeEndElement();
}

void DomRow::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

DomColumn::~DomColumn()
{
    qDeleteAll(m_property);
    m_property.clear();
}

void DomColumn::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomColumn::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("column") : tagName.toLower());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    writer.writeEndElement();
}

void DomColumn::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

DomItem::~DomItem()
{
    qDeleteAll(m_property);
    m_property.clear();
    qDeleteAll(m_item);
    m_item.clear();
}

void DomItem::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("row")) {
            setAttributeRow(attribute.value().toInt());
            continue;
        }
        if (name == QLatin1String("column")) {
            setAttributeColumn(attribute.value().toInt());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("item"), Qt::CaseInsensitive)) {
                auto *v = new DomItem();
                v->read(reader);
                m_item.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomItem::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("item") : tagName.toLower());

    if (hasAttributeRow())
        writer.writeAttribute(QStringLiteral("row"), QString::number(attributeRow()));

    if (hasAttributeColumn())
        writer.writeAttribute(QStringLiteral("column"), QString::number(attributeColumn()));

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    for (DomItem *v : m_item)
        v->write(writer, QStringLiteral("item"));

    writer.writeEndElement();
}

void DomItem::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

void DomItem::setElementItem(const QVector<DomItem *> &a)
{
    m_children |= Item;
    m_item = a;
}

DomWidget::~DomWidget()
{
    m_class.clear();
    qDeleteAll(m_property);
    m_property.clear();
    qDeleteAll(m_attribute);
    m_attribute.clear();
    qDeleteAll(m_row);
    m_row.clear();
    qDeleteAll(m_column);
    m_column.clear();
    qDeleteAll(m_item);
    m_item.clear();
    qDeleteAll(m_layout);
    m_layout.clear();
    qDeleteAll(m_widget);
    m_widget.clear();
    qDeleteAll(m_action);
    m_action.clear();
    qDeleteAll(m_actionGroup);
    m_actionGroup.clear();
    qDeleteAll(m_addAction);
    m_addAction.clear();
    m_zOrder.clear();
}

void DomWidget::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("class")) {
            setAttributeClass(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("native")) {
            setAttributeNative(attribute.value() == QLatin1String("true"));
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("class"), Qt::CaseInsensitive)) {
                m_class.append(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("script"), Qt::CaseInsensitive)) {
                qWarning("Omitting deprecated element <script>.");
                reader.skipCurrentElement();
                continue;
            }
            if (!tag.compare(QLatin1String("widgetdata"), Qt::CaseInsensitive)) {
                qWarning("Omitting deprecated element <widgetdata>.");
                reader.skipCurrentElement();
                continue;
            }
            if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_attribute.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("row"), Qt::CaseInsensitive)) {
                auto *v = new DomRow();
                v->read(reader);
                m_row.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("column"), Qt::CaseInsensitive)) {
                auto *v = new DomColumn();
                v->read(reader);
                m_column.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("item"), Qt::CaseInsensitive)) {
                auto *v = new DomItem();
                v->read(reader);
                m_item.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("layout"), Qt::CaseInsensitive)) {
                auto *v = new DomLayout();
                v->read(reader);
                m_layout.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
                auto *v = new DomWidget();
                v->read(reader);
                m_widget.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("action"), Qt::CaseInsensitive)) {
                auto *v = new DomAction();
                v->read(reader);
                m_action.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("actiongroup"), Qt::CaseInsensitive)) {
                auto *v = new DomActionGroup();
                v->read(reader);
                m_actionGroup.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("addaction"), Qt::CaseInsensitive)) {
                auto *v = new DomActionRef();
                v->read(reader);
                m_addAction.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("zorder"), Qt::CaseInsensitive)) {
                m_zOrder.append(reader.readElementText());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomWidget::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("widget") : tagName.toLower());

    if (hasAttributeClass())
        writer.writeAttribute(QStringLiteral("class"), attributeClass());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    if (hasAttributeNative())
        writer.writeAttribute(QStringLiteral("native"), (attributeNative() ? QLatin1String("true") : QLatin1String("false")));

    for (const QString &v : m_class)
        writer.writeTextElement(QStringLiteral("class"), v);

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    for (DomProperty *v : m_attribute)
        v->write(writer, QStringLiteral("attribute"));

    for (DomRow *v : m_row)
        v->write(writer, QStringLiteral("row"));

    for (DomColumn *v : m_column)
        v->write(writer, QStringLiteral("column"));

    for (DomItem *v : m_item)
        v->write(writer, QStringLiteral("item"));

    for (DomLayout *v : m_layout)
        v->write(writer, QStringLiteral("layout"));

    for (DomWidget *v : m_widget)
        v->write(writer, QStringLiteral("widget"));

    for (DomAction *v : m_action)
        v->write(writer, QStringLiteral("action"));

    for (DomActionGroup *v : m_actionGroup)
        v->write(writer, QStringLiteral("actiongroup"));

    for (DomActionRef *v : m_addAction)
        v->write(writer, QStringLiteral("addaction"));

    for (const QString &v : m_zOrder)
        writer.writeTextElement(QStringLiteral("zorder"), v);

    writer.writeEndElement();
}

void DomWidget::setElementClass(const QStringList &a)
{
    m_children |= Class;
    m_class = a;
}

void DomWidget::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

void DomWidget::setElementAttribute(const QList<DomProperty *> &a)
{
    m_children |= Attribute;
    m_attribute = a;
}

void DomWidget::setElementRow(const QVector<DomRow *> &a)
{
    m_children |= Row;
    m_row = a;
}

void DomWidget::setElementColumn(const QVector<DomColumn *> &a)
{
    m_children |= Column;
    m_column = a;
}

void DomWidget::setElementItem(const QVector<DomItem *> &a)
{
    m_children |= Item;
    m_item = a;
}

void DomWidget::setElementLayout(const QVector<DomLayout *> &a)
{
    m_children |= Layout;
    m_layout = a;
}

void DomWidget::setElementWidget(const QVector<DomWidget *> &a)
{
    m_children |= Widget;
    m_widget = a;
}

void DomWidget::setElementAction(const QVector<DomAction *> &a)
{
    m_children |= Action;
    m_action = a;
}

void DomWidget::setElementActionGroup(const QVector<DomActionGroup *> &a)
{
    m_children |= ActionGroup;
    m_actionGroup = a;
}

void DomWidget::setElementAddAction(const QVector<DomActionRef *> &a)
{
    m_children |= AddAction;
    m_addAction = a;
}

void DomWidget::setElementZOrder(const QStringList &a)
{
    m_children |= ZOrder;
    m_zOrder = a;
}

DomSpacer::~DomSpacer()
{
    qDeleteAll(m_property);
    m_property.clear();
}

void DomSpacer::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomSpacer::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("spacer") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    writer.writeEndElement();
}

void DomSpacer::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

DomColor::~DomColor() = default;

void DomColor::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("alpha")) {
            setAttributeAlpha(attribute.value().toInt());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("red"), Qt::CaseInsensitive)) {
                setElementRed(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("green"), Qt::CaseInsensitive)) {
                setElementGreen(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("blue"), Qt::CaseInsensitive)) {
                setElementBlue(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomColor::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("color") : tagName.toLower());

    if (hasAttributeAlpha())
        writer.writeAttribute(QStringLiteral("alpha"), QString::number(attributeAlpha()));

    if (m_children & Red)
        writer.writeTextElement(QStringLiteral("red"), QString::number(m_red));

    if (m_children & Green)
        writer.writeTextElement(QStringLiteral("green"), QString::number(m_green));

    if (m_children & Blue)
        writer.writeTextElement(QStringLiteral("blue"), QString::number(m_blue));

    writer.writeEndElement();
}

void DomColor::setElementRed(int a)
{
    m_children |= Red;
    m_red = a;
}

void DomColor::setElementGreen(int a)
{
    m_children |= Green;
    m_green = a;
}

void DomColor::setElementBlue(int a)
{
    m_children |= Blue;
    m_blue = a;
}

void DomColor::clearElementRed()
{
    m_children &= ~Red;
}

void DomColor::clearElementGreen()
{
    m_children &= ~Green;
}

void DomColor::clearElementBlue()
{
    m_children &= ~Blue;
}

DomGradientStop::~DomGradientStop()
{
    delete m_color;
}

void DomGradientStop::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("position")) {
            setAttributePosition(attribute.value().toDouble());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
                auto *v = new DomColor();
                v->read(reader);
                setElementColor(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomGradientStop::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("gradientstop") : tagName.toLower());

    if (hasAttributePosition())
        writer.writeAttribute(QStringLiteral("position"), QString::number(attributePosition(), 'f', 15));

    if (m_children & Color)
        m_color->write(writer, QStringLiteral("color"));

    writer.writeEndElement();
}

DomColor *DomGradientStop::takeElementColor()
{
    DomColor *a = m_color;
    m_color = nullptr;
    m_children ^= Color;
    return a;
}

void DomGradientStop::setElementColor(DomColor *a)
{
    delete m_color;
    m_children |= Color;
    m_color = a;
}

void DomGradientStop::clearElementColor()
{
    delete m_color;
    m_color = nullptr;
    m_children &= ~Color;
}

DomGradient::~DomGradient()
{
    qDeleteAll(m_gradientStop);
    m_gradientStop.clear();
}

void DomGradient::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("startx")) {
            setAttributeStartX(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("starty")) {
            setAttributeStartY(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("endx")) {
            setAttributeEndX(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("endy")) {
            setAttributeEndY(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("centralx")) {
            setAttributeCentralX(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("centraly")) {
            setAttributeCentralY(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("focalx")) {
            setAttributeFocalX(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("focaly")) {
            setAttributeFocalY(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("radius")) {
            setAttributeRadius(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("angle")) {
            setAttributeAngle(attribute.value().toDouble());
            continue;
        }
        if (name == QLatin1String("type")) {
            setAttributeType(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("spread")) {
            setAttributeSpread(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("coordinatemode")) {
            setAttributeCoordinateMode(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("gradientstop"), Qt::CaseInsensitive)) {
                auto *v = new DomGradientStop();
                v->read(reader);
                m_gradientStop.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomGradient::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("gradient") : tagName.toLower());

    if (hasAttributeStartX())
        writer.writeAttribute(QStringLiteral("startx"), QString::number(attributeStartX(), 'f', 15));

    if (hasAttributeStartY())
        writer.writeAttribute(QStringLiteral("starty"), QString::number(attributeStartY(), 'f', 15));

    if (hasAttributeEndX())
        writer.writeAttribute(QStringLiteral("endx"), QString::number(attributeEndX(), 'f', 15));

    if (hasAttributeEndY())
        writer.writeAttribute(QStringLiteral("endy"), QString::number(attributeEndY(), 'f', 15));

    if (hasAttributeCentralX())
        writer.writeAttribute(QStringLiteral("centralx"), QString::number(attributeCentralX(), 'f', 15));

    if (hasAttributeCentralY())
        writer.writeAttribute(QStringLiteral("centraly"), QString::number(attributeCentralY(), 'f', 15));

    if (hasAttributeFocalX())
        writer.writeAttribute(QStringLiteral("focalx"), QString::number(attributeFocalX(), 'f', 15));

    if (hasAttributeFocalY())
        writer.writeAttribute(QStringLiteral("focaly"), QString::number(attributeFocalY(), 'f', 15));

    if (hasAttributeRadius())
        writer.writeAttribute(QStringLiteral("radius"), QString::number(attributeRadius(), 'f', 15));

    if (hasAttributeAngle())
        writer.writeAttribute(QStringLiteral("angle"), QString::number(attributeAngle(), 'f', 15));

    if (hasAttributeType())
        writer.writeAttribute(QStringLiteral("type"), attributeType());

    if (hasAttributeSpread())
        writer.writeAttribute(QStringLiteral("spread"), attributeSpread());

    if (hasAttributeCoordinateMode())
        writer.writeAttribute(QStringLiteral("coordinatemode"), attributeCoordinateMode());

    for (DomGradientStop *v : m_gradientStop)
        v->write(writer, QStringLiteral("gradientstop"));

    writer.writeEndElement();
}

void DomGradient::setElementGradientStop(const QVector<DomGradientStop *> &a)
{
    m_children |= GradientStop;
    m_gradientStop = a;
}

DomBrush::~DomBrush()
{
    delete m_color;
    delete m_texture;
    delete m_gradient;
}

void DomBrush::clear()
{
    delete m_color;
    delete m_texture;
    delete m_gradient;

    m_kind = Unknown;

    m_color = nullptr;
    m_texture = nullptr;
    m_gradient = nullptr;
}

void DomBrush::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("brushstyle")) {
            setAttributeBrushStyle(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
                auto *v = new DomColor();
                v->read(reader);
                setElementColor(v);
                continue;
            }
            if (!tag.compare(QLatin1String("texture"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                setElementTexture(v);
                continue;
            }
            if (!tag.compare(QLatin1String("gradient"), Qt::CaseInsensitive)) {
                auto *v = new DomGradient();
                v->read(reader);
                setElementGradient(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomBrush::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("brush") : tagName.toLower());

    if (hasAttributeBrushStyle())
        writer.writeAttribute(QStringLiteral("brushstyle"), attributeBrushStyle());

    switch (kind()) {
    case Color:
        if (m_color != nullptr)
            m_color->write(writer, QStringLiteral("color"));
        break;

    case Texture:
        if (m_texture != nullptr)
            m_texture->write(writer, QStringLiteral("texture"));
        break;

    case Gradient:
        if (m_gradient != nullptr)
            m_gradient->write(writer, QStringLiteral("gradient"));
        break;

    default:
        break;
    }
    writer.writeEndElement();
}

DomColor *DomBrush::takeElementColor()
{
    DomColor *a = m_color;
    m_color = nullptr;
    return a;
}

void DomBrush::setElementColor(DomColor *a)
{
    clear();
    m_kind = Color;
    m_color = a;
}

DomProperty *DomBrush::takeElementTexture()
{
    DomProperty *a = m_texture;
    m_texture = nullptr;
    return a;
}

void DomBrush::setElementTexture(DomProperty *a)
{
    clear();
    m_kind = Texture;
    m_texture = a;
}

DomGradient *DomBrush::takeElementGradient()
{
    DomGradient *a = m_gradient;
    m_gradient = nullptr;
    return a;
}

void DomBrush::setElementGradient(DomGradient *a)
{
    clear();
    m_kind = Gradient;
    m_gradient = a;
}

DomColorRole::~DomColorRole()
{
    delete m_brush;
}

void DomColorRole::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("role")) {
            setAttributeRole(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("brush"), Qt::CaseInsensitive)) {
                auto *v = new DomBrush();
                v->read(reader);
                setElementBrush(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomColorRole::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("colorrole") : tagName.toLower());

    if (hasAttributeRole())
        writer.writeAttribute(QStringLiteral("role"), attributeRole());

    if (m_children & Brush)
        m_brush->write(writer, QStringLiteral("brush"));

    writer.writeEndElement();
}

DomBrush *DomColorRole::takeElementBrush()
{
    DomBrush *a = m_brush;
    m_brush = nullptr;
    m_children ^= Brush;
    return a;
}

void DomColorRole::setElementBrush(DomBrush *a)
{
    delete m_brush;
    m_children |= Brush;
    m_brush = a;
}

void DomColorRole::clearElementBrush()
{
    delete m_brush;
    m_brush = nullptr;
    m_children &= ~Brush;
}

DomColorGroup::~DomColorGroup()
{
    qDeleteAll(m_colorRole);
    m_colorRole.clear();
    qDeleteAll(m_color);
    m_color.clear();
}

void DomColorGroup::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("colorrole"), Qt::CaseInsensitive)) {
                auto *v = new DomColorRole();
                v->read(reader);
                m_colorRole.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
                auto *v = new DomColor();
                v->read(reader);
                m_color.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomColorGroup::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("colorgroup") : tagName.toLower());

    for (DomColorRole *v : m_colorRole)
        v->write(writer, QStringLiteral("colorrole"));

    for (DomColor *v : m_color)
        v->write(writer, QStringLiteral("color"));

    writer.writeEndElement();
}

void DomColorGroup::setElementColorRole(const QVector<DomColorRole *> &a)
{
    m_children |= ColorRole;
    m_colorRole = a;
}

void DomColorGroup::setElementColor(const QVector<DomColor *> &a)
{
    m_children |= Color;
    m_color = a;
}

DomPalette::~DomPalette()
{
    delete m_active;
    delete m_inactive;
    delete m_disabled;
}

void DomPalette::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("active"), Qt::CaseInsensitive)) {
                auto *v = new DomColorGroup();
                v->read(reader);
                setElementActive(v);
                continue;
            }
            if (!tag.compare(QLatin1String("inactive"), Qt::CaseInsensitive)) {
                auto *v = new DomColorGroup();
                v->read(reader);
                setElementInactive(v);
                continue;
            }
            if (!tag.compare(QLatin1String("disabled"), Qt::CaseInsensitive)) {
                auto *v = new DomColorGroup();
                v->read(reader);
                setElementDisabled(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomPalette::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("palette") : tagName.toLower());

    if (m_children & Active)
        m_active->write(writer, QStringLiteral("active"));

    if (m_children & Inactive)
        m_inactive->write(writer, QStringLiteral("inactive"));

    if (m_children & Disabled)
        m_disabled->write(writer, QStringLiteral("disabled"));

    writer.writeEndElement();
}

DomColorGroup *DomPalette::takeElementActive()
{
    DomColorGroup *a = m_active;
    m_active = nullptr;
    m_children ^= Active;
    return a;
}

void DomPalette::setElementActive(DomColorGroup *a)
{
    delete m_active;
    m_children |= Active;
    m_active = a;
}

DomColorGroup *DomPalette::takeElementInactive()
{
    DomColorGroup *a = m_inactive;
    m_inactive = nullptr;
    m_children ^= Inactive;
    return a;
}

void DomPalette::setElementInactive(DomColorGroup *a)
{
    delete m_inactive;
    m_children |= Inactive;
    m_inactive = a;
}

DomColorGroup *DomPalette::takeElementDisabled()
{
    DomColorGroup *a = m_disabled;
    m_disabled = nullptr;
    m_children ^= Disabled;
    return a;
}

void DomPalette::setElementDisabled(DomColorGroup *a)
{
    delete m_disabled;
    m_children |= Disabled;
    m_disabled = a;
}

void DomPalette::clearElementActive()
{
    delete m_active;
    m_active = nullptr;
    m_children &= ~Active;
}

void DomPalette::clearElementInactive()
{
    delete m_inactive;
    m_inactive = nullptr;
    m_children &= ~Inactive;
}

void DomPalette::clearElementDisabled()
{
    delete m_disabled;
    m_disabled = nullptr;
    m_children &= ~Disabled;
}

DomFont::~DomFont() = default;

void DomFont::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("family"), Qt::CaseInsensitive)) {
                setElementFamily(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("pointsize"), Qt::CaseInsensitive)) {
                setElementPointSize(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("weight"), Qt::CaseInsensitive)) {
                setElementWeight(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("italic"), Qt::CaseInsensitive)) {
                setElementItalic(reader.readElementText() == QLatin1String("true"));
                continue;
            }
            if (!tag.compare(QLatin1String("bold"), Qt::CaseInsensitive)) {
                setElementBold(reader.readElementText() == QLatin1String("true"));
                continue;
            }
            if (!tag.compare(QLatin1String("underline"), Qt::CaseInsensitive)) {
                setElementUnderline(reader.readElementText() == QLatin1String("true"));
                continue;
            }
            if (!tag.compare(QLatin1String("strikeout"), Qt::CaseInsensitive)) {
                setElementStrikeOut(reader.readElementText() == QLatin1String("true"));
                continue;
            }
            if (!tag.compare(QLatin1String("antialiasing"), Qt::CaseInsensitive)) {
                setElementAntialiasing(reader.readElementText() == QLatin1String("true"));
                continue;
            }
            if (!tag.compare(QLatin1String("stylestrategy"), Qt::CaseInsensitive)) {
                setElementStyleStrategy(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("kerning"), Qt::CaseInsensitive)) {
                setElementKerning(reader.readElementText() == QLatin1String("true"));
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomFont::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("font") : tagName.toLower());

    if (m_children & Family)
        writer.writeTextElement(QStringLiteral("family"), m_family);

    if (m_children & PointSize)
        writer.writeTextElement(QStringLiteral("pointsize"), QString::number(m_pointSize));

    if (m_children & Weight)
        writer.writeTextElement(QStringLiteral("weight"), QString::number(m_weight));

    if (m_children & Italic)
        writer.writeTextElement(QStringLiteral("italic"), (m_italic ? QLatin1String("true") : QLatin1String("false")));

    if (m_children & Bold)
        writer.writeTextElement(QStringLiteral("bold"), (m_bold ? QLatin1String("true") : QLatin1String("false")));

    if (m_children & Underline)
        writer.writeTextElement(QStringLiteral("underline"), (m_underline ? QLatin1String("true") : QLatin1String("false")));

    if (m_children & StrikeOut)
        writer.writeTextElement(QStringLiteral("strikeout"), (m_strikeOut ? QLatin1String("true") : QLatin1String("false")));

    if (m_children & Antialiasing)
        writer.writeTextElement(QStringLiteral("antialiasing"), (m_antialiasing ? QLatin1String("true") : QLatin1String("false")));

    if (m_children & StyleStrategy)
        writer.writeTextElement(QStringLiteral("stylestrategy"), m_styleStrategy);

    if (m_children & Kerning)
        writer.writeTextElement(QStringLiteral("kerning"), (m_kerning ? QLatin1String("true") : QLatin1String("false")));

    writer.writeEndElement();
}

void DomFont::setElementFamily(const QString &a)
{
    m_children |= Family;
    m_family = a;
}

void DomFont::setElementPointSize(int a)
{
    m_children |= PointSize;
    m_pointSize = a;
}

void DomFont::setElementWeight(int a)
{
    m_children |= Weight;
    m_weight = a;
}

void DomFont::setElementItalic(bool a)
{
    m_children |= Italic;
    m_italic = a;
}

void DomFont::setElementBold(bool a)
{
    m_children |= Bold;
    m_bold = a;
}

void DomFont::setElementUnderline(bool a)
{
    m_children |= Underline;
    m_underline = a;
}

void DomFont::setElementStrikeOut(bool a)
{
    m_children |= StrikeOut;
    m_strikeOut = a;
}

void DomFont::setElementAntialiasing(bool a)
{
    m_children |= Antialiasing;
    m_antialiasing = a;
}

void DomFont::setElementStyleStrategy(const QString &a)
{
    m_children |= StyleStrategy;
    m_styleStrategy = a;
}

void DomFont::setElementKerning(bool a)
{
    m_children |= Kerning;
    m_kerning = a;
}

void DomFont::clearElementFamily()
{
    m_children &= ~Family;
}

void DomFont::clearElementPointSize()
{
    m_children &= ~PointSize;
}

void DomFont::clearElementWeight()
{
    m_children &= ~Weight;
}

void DomFont::clearElementItalic()
{
    m_children &= ~Italic;
}

void DomFont::clearElementBold()
{
    m_children &= ~Bold;
}

void DomFont::clearElementUnderline()
{
    m_children &= ~Underline;
}

void DomFont::clearElementStrikeOut()
{
    m_children &= ~StrikeOut;
}

void DomFont::clearElementAntialiasing()
{
    m_children &= ~Antialiasing;
}

void DomFont::clearElementStyleStrategy()
{
    m_children &= ~StyleStrategy;
}

void DomFont::clearElementKerning()
{
    m_children &= ~Kerning;
}

DomPoint::~DomPoint() = default;

void DomPoint::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
                setElementX(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("y"), Qt::CaseInsensitive)) {
                setElementY(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomPoint::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("point") : tagName.toLower());

    if (m_children & X)
        writer.writeTextElement(QString(QLatin1Char('x')), QString::number(m_x));

    if (m_children & Y)
        writer.writeTextElement(QString(QLatin1Char('y')), QString::number(m_y));

    writer.writeEndElement();
}

void DomPoint::setElementX(int a)
{
    m_children |= X;
    m_x = a;
}

void DomPoint::setElementY(int a)
{
    m_children |= Y;
    m_y = a;
}

void DomPoint::clearElementX()
{
    m_children &= ~X;
}

void DomPoint::clearElementY()
{
    m_children &= ~Y;
}

DomRect::~DomRect() = default;

void DomRect::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
                setElementX(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("y"), Qt::CaseInsensitive)) {
                setElementY(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("width"), Qt::CaseInsensitive)) {
                setElementWidth(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("height"), Qt::CaseInsensitive)) {
                setElementHeight(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomRect::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("rect") : tagName.toLower());

    if (m_children & X)
        writer.writeTextElement(QString(QLatin1Char('x')), QString::number(m_x));

    if (m_children & Y)
        writer.writeTextElement(QString(QLatin1Char('y')), QString::number(m_y));

    if (m_children & Width)
        writer.writeTextElement(QStringLiteral("width"), QString::number(m_width));

    if (m_children & Height)
        writer.writeTextElement(QStringLiteral("height"), QString::number(m_height));

    writer.writeEndElement();
}

void DomRect::setElementX(int a)
{
    m_children |= X;
    m_x = a;
}

void DomRect::setElementY(int a)
{
    m_children |= Y;
    m_y = a;
}

void DomRect::setElementWidth(int a)
{
    m_children |= Width;
    m_width = a;
}

void DomRect::setElementHeight(int a)
{
    m_children |= Height;
    m_height = a;
}

void DomRect::clearElementX()
{
    m_children &= ~X;
}

void DomRect::clearElementY()
{
    m_children &= ~Y;
}

void DomRect::clearElementWidth()
{
    m_children &= ~Width;
}

void DomRect::clearElementHeight()
{
    m_children &= ~Height;
}

DomLocale::~DomLocale() = default;

void DomLocale::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("language")) {
            setAttributeLanguage(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("country")) {
            setAttributeCountry(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomLocale::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("locale") : tagName.toLower());

    if (hasAttributeLanguage())
        writer.writeAttribute(QStringLiteral("language"), attributeLanguage());

    if (hasAttributeCountry())
        writer.writeAttribute(QStringLiteral("country"), attributeCountry());

    writer.writeEndElement();
}

DomSizePolicy::~DomSizePolicy() = default;

void DomSizePolicy::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("hsizetype")) {
            setAttributeHSizeType(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("vsizetype")) {
            setAttributeVSizeType(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("hsizetype"), Qt::CaseInsensitive)) {
                setElementHSizeType(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("vsizetype"), Qt::CaseInsensitive)) {
                setElementVSizeType(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("horstretch"), Qt::CaseInsensitive)) {
                setElementHorStretch(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("verstretch"), Qt::CaseInsensitive)) {
                setElementVerStretch(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomSizePolicy::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("sizepolicy") : tagName.toLower());

    if (hasAttributeHSizeType())
        writer.writeAttribute(QStringLiteral("hsizetype"), attributeHSizeType());

    if (hasAttributeVSizeType())
        writer.writeAttribute(QStringLiteral("vsizetype"), attributeVSizeType());

    if (m_children & HSizeType)
        writer.writeTextElement(QStringLiteral("hsizetype"), QString::number(m_hSizeType));

    if (m_children & VSizeType)
        writer.writeTextElement(QStringLiteral("vsizetype"), QString::number(m_vSizeType));

    if (m_children & HorStretch)
        writer.writeTextElement(QStringLiteral("horstretch"), QString::number(m_horStretch));

    if (m_children & VerStretch)
        writer.writeTextElement(QStringLiteral("verstretch"), QString::number(m_verStretch));

    writer.writeEndElement();
}

void DomSizePolicy::setElementHSizeType(int a)
{
    m_children |= HSizeType;
    m_hSizeType = a;
}

void DomSizePolicy::setElementVSizeType(int a)
{
    m_children |= VSizeType;
    m_vSizeType = a;
}

void DomSizePolicy::setElementHorStretch(int a)
{
    m_children |= HorStretch;
    m_horStretch = a;
}

void DomSizePolicy::setElementVerStretch(int a)
{
    m_children |= VerStretch;
    m_verStretch = a;
}

void DomSizePolicy::clearElementHSizeType()
{
    m_children &= ~HSizeType;
}

void DomSizePolicy::clearElementVSizeType()
{
    m_children &= ~VSizeType;
}

void DomSizePolicy::clearElementHorStretch()
{
    m_children &= ~HorStretch;
}

void DomSizePolicy::clearElementVerStretch()
{
    m_children &= ~VerStretch;
}

DomSize::~DomSize() = default;

void DomSize::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("width"), Qt::CaseInsensitive)) {
                setElementWidth(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("height"), Qt::CaseInsensitive)) {
                setElementHeight(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomSize::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("size") : tagName.toLower());

    if (m_children & Width)
        writer.writeTextElement(QStringLiteral("width"), QString::number(m_width));

    if (m_children & Height)
        writer.writeTextElement(QStringLiteral("height"), QString::number(m_height));

    writer.writeEndElement();
}

void DomSize::setElementWidth(int a)
{
    m_children |= Width;
    m_width = a;
}

void DomSize::setElementHeight(int a)
{
    m_children |= Height;
    m_height = a;
}

void DomSize::clearElementWidth()
{
    m_children &= ~Width;
}

void DomSize::clearElementHeight()
{
    m_children &= ~Height;
}

DomDate::~DomDate() = default;

void DomDate::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("year"), Qt::CaseInsensitive)) {
                setElementYear(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("month"), Qt::CaseInsensitive)) {
                setElementMonth(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("day"), Qt::CaseInsensitive)) {
                setElementDay(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomDate::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("date") : tagName.toLower());

    if (m_children & Year)
        writer.writeTextElement(QStringLiteral("year"), QString::number(m_year));

    if (m_children & Month)
        writer.writeTextElement(QStringLiteral("month"), QString::number(m_month));

    if (m_children & Day)
        writer.writeTextElement(QStringLiteral("day"), QString::number(m_day));

    writer.writeEndElement();
}

void DomDate::setElementYear(int a)
{
    m_children |= Year;
    m_year = a;
}

void DomDate::setElementMonth(int a)
{
    m_children |= Month;
    m_month = a;
}

void DomDate::setElementDay(int a)
{
    m_children |= Day;
    m_day = a;
}

void DomDate::clearElementYear()
{
    m_children &= ~Year;
}

void DomDate::clearElementMonth()
{
    m_children &= ~Month;
}

void DomDate::clearElementDay()
{
    m_children &= ~Day;
}

DomTime::~DomTime() = default;

void DomTime::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("hour"), Qt::CaseInsensitive)) {
                setElementHour(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("minute"), Qt::CaseInsensitive)) {
                setElementMinute(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("second"), Qt::CaseInsensitive)) {
                setElementSecond(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomTime::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("time") : tagName.toLower());

    if (m_children & Hour)
        writer.writeTextElement(QStringLiteral("hour"), QString::number(m_hour));

    if (m_children & Minute)
        writer.writeTextElement(QStringLiteral("minute"), QString::number(m_minute));

    if (m_children & Second)
        writer.writeTextElement(QStringLiteral("second"), QString::number(m_second));

    writer.writeEndElement();
}

void DomTime::setElementHour(int a)
{
    m_children |= Hour;
    m_hour = a;
}

void DomTime::setElementMinute(int a)
{
    m_children |= Minute;
    m_minute = a;
}

void DomTime::setElementSecond(int a)
{
    m_children |= Second;
    m_second = a;
}

void DomTime::clearElementHour()
{
    m_children &= ~Hour;
}

void DomTime::clearElementMinute()
{
    m_children &= ~Minute;
}

void DomTime::clearElementSecond()
{
    m_children &= ~Second;
}

DomDateTime::~DomDateTime() = default;

void DomDateTime::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("hour"), Qt::CaseInsensitive)) {
                setElementHour(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("minute"), Qt::CaseInsensitive)) {
                setElementMinute(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("second"), Qt::CaseInsensitive)) {
                setElementSecond(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("year"), Qt::CaseInsensitive)) {
                setElementYear(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("month"), Qt::CaseInsensitive)) {
                setElementMonth(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("day"), Qt::CaseInsensitive)) {
                setElementDay(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomDateTime::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("datetime") : tagName.toLower());

    if (m_children & Hour)
        writer.writeTextElement(QStringLiteral("hour"), QString::number(m_hour));

    if (m_children & Minute)
        writer.writeTextElement(QStringLiteral("minute"), QString::number(m_minute));

    if (m_children & Second)
        writer.writeTextElement(QStringLiteral("second"), QString::number(m_second));

    if (m_children & Year)
        writer.writeTextElement(QStringLiteral("year"), QString::number(m_year));

    if (m_children & Month)
        writer.writeTextElement(QStringLiteral("month"), QString::number(m_month));

    if (m_children & Day)
        writer.writeTextElement(QStringLiteral("day"), QString::number(m_day));

    writer.writeEndElement();
}

void DomDateTime::setElementHour(int a)
{
    m_children |= Hour;
    m_hour = a;
}

void DomDateTime::setElementMinute(int a)
{
    m_children |= Minute;
    m_minute = a;
}

void DomDateTime::setElementSecond(int a)
{
    m_children |= Second;
    m_second = a;
}

void DomDateTime::setElementYear(int a)
{
    m_children |= Year;
    m_year = a;
}

void DomDateTime::setElementMonth(int a)
{
    m_children |= Month;
    m_month = a;
}

void DomDateTime::setElementDay(int a)
{
    m_children |= Day;
    m_day = a;
}

void DomDateTime::clearElementHour()
{
    m_children &= ~Hour;
}

void DomDateTime::clearElementMinute()
{
    m_children &= ~Minute;
}

void DomDateTime::clearElementSecond()
{
    m_children &= ~Second;
}

void DomDateTime::clearElementYear()
{
    m_children &= ~Year;
}

void DomDateTime::clearElementMonth()
{
    m_children &= ~Month;
}

void DomDateTime::clearElementDay()
{
    m_children &= ~Day;
}

DomStringList::~DomStringList()
{
    m_string.clear();
}

void DomStringList::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("notr")) {
            setAttributeNotr(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("comment")) {
            setAttributeComment(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("extracomment")) {
            setAttributeExtraComment(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("id")) {
            setAttributeId(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
                m_string.append(reader.readElementText());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomStringList::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("stringlist") : tagName.toLower());

    if (hasAttributeNotr())
        writer.writeAttribute(QStringLiteral("notr"), attributeNotr());

    if (hasAttributeComment())
        writer.writeAttribute(QStringLiteral("comment"), attributeComment());

    if (hasAttributeExtraComment())
        writer.writeAttribute(QStringLiteral("extracomment"), attributeExtraComment());

    if (hasAttributeId())
        writer.writeAttribute(QStringLiteral("id"), attributeId());

    for (const QString &v : m_string)
        writer.writeTextElement(QStringLiteral("string"), v);

    writer.writeEndElement();
}

void DomStringList::setElementString(const QStringList &a)
{
    m_children |= String;
    m_string = a;
}

DomResourcePixmap::~DomResourcePixmap() = default;

void DomResourcePixmap::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("resource")) {
            setAttributeResource(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("alias")) {
            setAttributeAlias(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        case QXmlStreamReader::Characters :
            if (!reader.isWhitespace())
                m_text.append(reader.text().toString());
            break;
        default :
            break;
        }
    }
}

void DomResourcePixmap::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("resourcepixmap") : tagName.toLower());

    if (hasAttributeResource())
        writer.writeAttribute(QStringLiteral("resource"), attributeResource());

    if (hasAttributeAlias())
        writer.writeAttribute(QStringLiteral("alias"), attributeAlias());

    if (!m_text.isEmpty())
        writer.writeCharacters(m_text);

    writer.writeEndElement();
}

DomResourceIcon::~DomResourceIcon()
{
    delete m_normalOff;
    delete m_normalOn;
    delete m_disabledOff;
    delete m_disabledOn;
    delete m_activeOff;
    delete m_activeOn;
    delete m_selectedOff;
    delete m_selectedOn;
}

void DomResourceIcon::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("theme")) {
            setAttributeTheme(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("resource")) {
            setAttributeResource(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("normaloff"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementNormalOff(v);
                continue;
            }
            if (!tag.compare(QLatin1String("normalon"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementNormalOn(v);
                continue;
            }
            if (!tag.compare(QLatin1String("disabledoff"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementDisabledOff(v);
                continue;
            }
            if (!tag.compare(QLatin1String("disabledon"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementDisabledOn(v);
                continue;
            }
            if (!tag.compare(QLatin1String("activeoff"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementActiveOff(v);
                continue;
            }
            if (!tag.compare(QLatin1String("activeon"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementActiveOn(v);
                continue;
            }
            if (!tag.compare(QLatin1String("selectedoff"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementSelectedOff(v);
                continue;
            }
            if (!tag.compare(QLatin1String("selectedon"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementSelectedOn(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        case QXmlStreamReader::Characters :
            if (!reader.isWhitespace())
                m_text.append(reader.text().toString());
            break;
        default :
            break;
        }
    }
}

void DomResourceIcon::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("resourceicon") : tagName.toLower());

    if (hasAttributeTheme())
        writer.writeAttribute(QStringLiteral("theme"), attributeTheme());

    if (hasAttributeResource())
        writer.writeAttribute(QStringLiteral("resource"), attributeResource());

    if (m_children & NormalOff)
        m_normalOff->write(writer, QStringLiteral("normaloff"));

    if (m_children & NormalOn)
        m_normalOn->write(writer, QStringLiteral("normalon"));

    if (m_children & DisabledOff)
        m_disabledOff->write(writer, QStringLiteral("disabledoff"));

    if (m_children & DisabledOn)
        m_disabledOn->write(writer, QStringLiteral("disabledon"));

    if (m_children & ActiveOff)
        m_activeOff->write(writer, QStringLiteral("activeoff"));

    if (m_children & ActiveOn)
        m_activeOn->write(writer, QStringLiteral("activeon"));

    if (m_children & SelectedOff)
        m_selectedOff->write(writer, QStringLiteral("selectedoff"));

    if (m_children & SelectedOn)
        m_selectedOn->write(writer, QStringLiteral("selectedon"));

    if (!m_text.isEmpty())
        writer.writeCharacters(m_text);

    writer.writeEndElement();
}

DomResourcePixmap *DomResourceIcon::takeElementNormalOff()
{
    DomResourcePixmap *a = m_normalOff;
    m_normalOff = nullptr;
    m_children ^= NormalOff;
    return a;
}

void DomResourceIcon::setElementNormalOff(DomResourcePixmap *a)
{
    delete m_normalOff;
    m_children |= NormalOff;
    m_normalOff = a;
}

DomResourcePixmap *DomResourceIcon::takeElementNormalOn()
{
    DomResourcePixmap *a = m_normalOn;
    m_normalOn = nullptr;
    m_children ^= NormalOn;
    return a;
}

void DomResourceIcon::setElementNormalOn(DomResourcePixmap *a)
{
    delete m_normalOn;
    m_children |= NormalOn;
    m_normalOn = a;
}

DomResourcePixmap *DomResourceIcon::takeElementDisabledOff()
{
    DomResourcePixmap *a = m_disabledOff;
    m_disabledOff = nullptr;
    m_children ^= DisabledOff;
    return a;
}

void DomResourceIcon::setElementDisabledOff(DomResourcePixmap *a)
{
    delete m_disabledOff;
    m_children |= DisabledOff;
    m_disabledOff = a;
}

DomResourcePixmap *DomResourceIcon::takeElementDisabledOn()
{
    DomResourcePixmap *a = m_disabledOn;
    m_disabledOn = nullptr;
    m_children ^= DisabledOn;
    return a;
}

void DomResourceIcon::setElementDisabledOn(DomResourcePixmap *a)
{
    delete m_disabledOn;
    m_children |= DisabledOn;
    m_disabledOn = a;
}

DomResourcePixmap *DomResourceIcon::takeElementActiveOff()
{
    DomResourcePixmap *a = m_activeOff;
    m_activeOff = nullptr;
    m_children ^= ActiveOff;
    return a;
}

void DomResourceIcon::setElementActiveOff(DomResourcePixmap *a)
{
    delete m_activeOff;
    m_children |= ActiveOff;
    m_activeOff = a;
}

DomResourcePixmap *DomResourceIcon::takeElementActiveOn()
{
    DomResourcePixmap *a = m_activeOn;
    m_activeOn = nullptr;
    m_children ^= ActiveOn;
    return a;
}

void DomResourceIcon::setElementActiveOn(DomResourcePixmap *a)
{
    delete m_activeOn;
    m_children |= ActiveOn;
    m_activeOn = a;
}

DomResourcePixmap *DomResourceIcon::takeElementSelectedOff()
{
    DomResourcePixmap *a = m_selectedOff;
    m_selectedOff = nullptr;
    m_children ^= SelectedOff;
    return a;
}

void DomResourceIcon::setElementSelectedOff(DomResourcePixmap *a)
{
    delete m_selectedOff;
    m_children |= SelectedOff;
    m_selectedOff = a;
}

DomResourcePixmap *DomResourceIcon::takeElementSelectedOn()
{
    DomResourcePixmap *a = m_selectedOn;
    m_selectedOn = nullptr;
    m_children ^= SelectedOn;
    return a;
}

void DomResourceIcon::setElementSelectedOn(DomResourcePixmap *a)
{
    delete m_selectedOn;
    m_children |= SelectedOn;
    m_selectedOn = a;
}

void DomResourceIcon::clearElementNormalOff()
{
    delete m_normalOff;
    m_normalOff = nullptr;
    m_children &= ~NormalOff;
}

void DomResourceIcon::clearElementNormalOn()
{
    delete m_normalOn;
    m_normalOn = nullptr;
    m_children &= ~NormalOn;
}

void DomResourceIcon::clearElementDisabledOff()
{
    delete m_disabledOff;
    m_disabledOff = nullptr;
    m_children &= ~DisabledOff;
}

void DomResourceIcon::clearElementDisabledOn()
{
    delete m_disabledOn;
    m_disabledOn = nullptr;
    m_children &= ~DisabledOn;
}

void DomResourceIcon::clearElementActiveOff()
{
    delete m_activeOff;
    m_activeOff = nullptr;
    m_children &= ~ActiveOff;
}

void DomResourceIcon::clearElementActiveOn()
{
    delete m_activeOn;
    m_activeOn = nullptr;
    m_children &= ~ActiveOn;
}

void DomResourceIcon::clearElementSelectedOff()
{
    delete m_selectedOff;
    m_selectedOff = nullptr;
    m_children &= ~SelectedOff;
}

void DomResourceIcon::clearElementSelectedOn()
{
    delete m_selectedOn;
    m_selectedOn = nullptr;
    m_children &= ~SelectedOn;
}

DomString::~DomString() = default;

void DomString::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("notr")) {
            setAttributeNotr(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("comment")) {
            setAttributeComment(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("extracomment")) {
            setAttributeExtraComment(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("id")) {
            setAttributeId(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        case QXmlStreamReader::Characters :
            if (!reader.isWhitespace())
                m_text.append(reader.text().toString());
            break;
        default :
            break;
        }
    }
}

void DomString::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("string") : tagName.toLower());

    if (hasAttributeNotr())
        writer.writeAttribute(QStringLiteral("notr"), attributeNotr());

    if (hasAttributeComment())
        writer.writeAttribute(QStringLiteral("comment"), attributeComment());

    if (hasAttributeExtraComment())
        writer.writeAttribute(QStringLiteral("extracomment"), attributeExtraComment());

    if (hasAttributeId())
        writer.writeAttribute(QStringLiteral("id"), attributeId());

    if (!m_text.isEmpty())
        writer.writeCharacters(m_text);

    writer.writeEndElement();
}

DomPointF::~DomPointF() = default;

void DomPointF::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
                setElementX(reader.readElementText().toDouble());
                continue;
            }
            if (!tag.compare(QLatin1String("y"), Qt::CaseInsensitive)) {
                setElementY(reader.readElementText().toDouble());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomPointF::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("pointf") : tagName.toLower());

    if (m_children & X)
        writer.writeTextElement(QString(QLatin1Char('x')), QString::number(m_x, 'f', 15));

    if (m_children & Y)
        writer.writeTextElement(QString(QLatin1Char('y')), QString::number(m_y, 'f', 15));

    writer.writeEndElement();
}

void DomPointF::setElementX(double a)
{
    m_children |= X;
    m_x = a;
}

void DomPointF::setElementY(double a)
{
    m_children |= Y;
    m_y = a;
}

void DomPointF::clearElementX()
{
    m_children &= ~X;
}

void DomPointF::clearElementY()
{
    m_children &= ~Y;
}

DomRectF::~DomRectF() = default;

void DomRectF::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
                setElementX(reader.readElementText().toDouble());
                continue;
            }
            if (!tag.compare(QLatin1String("y"), Qt::CaseInsensitive)) {
                setElementY(reader.readElementText().toDouble());
                continue;
            }
            if (!tag.compare(QLatin1String("width"), Qt::CaseInsensitive)) {
                setElementWidth(reader.readElementText().toDouble());
                continue;
            }
            if (!tag.compare(QLatin1String("height"), Qt::CaseInsensitive)) {
                setElementHeight(reader.readElementText().toDouble());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomRectF::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("rectf") : tagName.toLower());

    if (m_children & X)
        writer.writeTextElement(QString(QLatin1Char('x')), QString::number(m_x, 'f', 15));

    if (m_children & Y)
        writer.writeTextElement(QString(QLatin1Char('y')), QString::number(m_y, 'f', 15));

    if (m_children & Width)
        writer.writeTextElement(QStringLiteral("width"), QString::number(m_width, 'f', 15));

    if (m_children & Height)
        writer.writeTextElement(QStringLiteral("height"), QString::number(m_height, 'f', 15));

    writer.writeEndElement();
}

void DomRectF::setElementX(double a)
{
    m_children |= X;
    m_x = a;
}

void DomRectF::setElementY(double a)
{
    m_children |= Y;
    m_y = a;
}

void DomRectF::setElementWidth(double a)
{
    m_children |= Width;
    m_width = a;
}

void DomRectF::setElementHeight(double a)
{
    m_children |= Height;
    m_height = a;
}

void DomRectF::clearElementX()
{
    m_children &= ~X;
}

void DomRectF::clearElementY()
{
    m_children &= ~Y;
}

void DomRectF::clearElementWidth()
{
    m_children &= ~Width;
}

void DomRectF::clearElementHeight()
{
    m_children &= ~Height;
}

DomSizeF::~DomSizeF() = default;

void DomSizeF::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("width"), Qt::CaseInsensitive)) {
                setElementWidth(reader.readElementText().toDouble());
                continue;
            }
            if (!tag.compare(QLatin1String("height"), Qt::CaseInsensitive)) {
                setElementHeight(reader.readElementText().toDouble());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomSizeF::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("sizef") : tagName.toLower());

    if (m_children & Width)
        writer.writeTextElement(QStringLiteral("width"), QString::number(m_width, 'f', 15));

    if (m_children & Height)
        writer.writeTextElement(QStringLiteral("height"), QString::number(m_height, 'f', 15));

    writer.writeEndElement();
}

void DomSizeF::setElementWidth(double a)
{
    m_children |= Width;
    m_width = a;
}

void DomSizeF::setElementHeight(double a)
{
    m_children |= Height;
    m_height = a;
}

void DomSizeF::clearElementWidth()
{
    m_children &= ~Width;
}

void DomSizeF::clearElementHeight()
{
    m_children &= ~Height;
}

DomChar::~DomChar() = default;

void DomChar::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("unicode"), Qt::CaseInsensitive)) {
                setElementUnicode(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomChar::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("char") : tagName.toLower());

    if (m_children & Unicode)
        writer.writeTextElement(QStringLiteral("unicode"), QString::number(m_unicode));

    writer.writeEndElement();
}

void DomChar::setElementUnicode(int a)
{
    m_children |= Unicode;
    m_unicode = a;
}

void DomChar::clearElementUnicode()
{
    m_children &= ~Unicode;
}

DomUrl::~DomUrl()
{
    delete m_string;
}

void DomUrl::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
                auto *v = new DomString();
                v->read(reader);
                setElementString(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomUrl::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("url") : tagName.toLower());

    if (m_children & String)
        m_string->write(writer, QStringLiteral("string"));

    writer.writeEndElement();
}

DomString *DomUrl::takeElementString()
{
    DomString *a = m_string;
    m_string = nullptr;
    m_children ^= String;
    return a;
}

void DomUrl::setElementString(DomString *a)
{
    delete m_string;
    m_children |= String;
    m_string = a;
}

void DomUrl::clearElementString()
{
    delete m_string;
    m_string = nullptr;
    m_children &= ~String;
}

DomProperty::~DomProperty()
{
    delete m_color;
    delete m_font;
    delete m_iconSet;
    delete m_pixmap;
    delete m_palette;
    delete m_point;
    delete m_rect;
    delete m_locale;
    delete m_sizePolicy;
    delete m_size;
    delete m_string;
    delete m_stringList;
    delete m_date;
    delete m_time;
    delete m_dateTime;
    delete m_pointF;
    delete m_rectF;
    delete m_sizeF;
    delete m_char;
    delete m_url;
    delete m_brush;
}

void DomProperty::clear()
{
    delete m_color;
    delete m_font;
    delete m_iconSet;
    delete m_pixmap;
    delete m_palette;
    delete m_point;
    delete m_rect;
    delete m_locale;
    delete m_sizePolicy;
    delete m_size;
    delete m_string;
    delete m_stringList;
    delete m_date;
    delete m_time;
    delete m_dateTime;
    delete m_pointF;
    delete m_rectF;
    delete m_sizeF;
    delete m_char;
    delete m_url;
    delete m_brush;

    m_kind = Unknown;

    m_color = nullptr;
    m_cursor = 0;
    m_font = nullptr;
    m_iconSet = nullptr;
    m_pixmap = nullptr;
    m_palette = nullptr;
    m_point = nullptr;
    m_rect = nullptr;
    m_locale = nullptr;
    m_sizePolicy = nullptr;
    m_size = nullptr;
    m_string = nullptr;
    m_stringList = nullptr;
    m_number = 0;
    m_float = 0.0;
    m_double = 0.0;
    m_date = nullptr;
    m_time = nullptr;
    m_dateTime = nullptr;
    m_pointF = nullptr;
    m_rectF = nullptr;
    m_sizeF = nullptr;
    m_longLong = 0;
    m_char = nullptr;
    m_url = nullptr;
    m_UInt = 0;
    m_uLongLong = 0;
    m_brush = nullptr;
}

void DomProperty::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("stdset")) {
            setAttributeStdset(attribute.value().toInt());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("bool"), Qt::CaseInsensitive)) {
                setElementBool(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
                auto *v = new DomColor();
                v->read(reader);
                setElementColor(v);
                continue;
            }
            if (!tag.compare(QLatin1String("cstring"), Qt::CaseInsensitive)) {
                setElementCstring(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("cursor"), Qt::CaseInsensitive)) {
                setElementCursor(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("cursorshape"), Qt::CaseInsensitive)) {
                setElementCursorShape(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("enum"), Qt::CaseInsensitive)) {
                setElementEnum(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("font"), Qt::CaseInsensitive)) {
                auto *v = new DomFont();
                v->read(reader);
                setElementFont(v);
                continue;
            }
            if (!tag.compare(QLatin1String("iconset"), Qt::CaseInsensitive)) {
                auto *v = new DomResourceIcon();
                v->read(reader);
                setElementIconSet(v);
                continue;
            }
            if (!tag.compare(QLatin1String("pixmap"), Qt::CaseInsensitive)) {
                auto *v = new DomResourcePixmap();
                v->read(reader);
                setElementPixmap(v);
                continue;
            }
            if (!tag.compare(QLatin1String("palette"), Qt::CaseInsensitive)) {
                auto *v = new DomPalette();
                v->read(reader);
                setElementPalette(v);
                continue;
            }
            if (!tag.compare(QLatin1String("point"), Qt::CaseInsensitive)) {
                auto *v = new DomPoint();
                v->read(reader);
                setElementPoint(v);
                continue;
            }
            if (!tag.compare(QLatin1String("rect"), Qt::CaseInsensitive)) {
                auto *v = new DomRect();
                v->read(reader);
                setElementRect(v);
                continue;
            }
            if (!tag.compare(QLatin1String("set"), Qt::CaseInsensitive)) {
                setElementSet(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("locale"), Qt::CaseInsensitive)) {
                auto *v = new DomLocale();
                v->read(reader);
                setElementLocale(v);
                continue;
            }
            if (!tag.compare(QLatin1String("sizepolicy"), Qt::CaseInsensitive)) {
                auto *v = new DomSizePolicy();
                v->read(reader);
                setElementSizePolicy(v);
                continue;
            }
            if (!tag.compare(QLatin1String("size"), Qt::CaseInsensitive)) {
                auto *v = new DomSize();
                v->read(reader);
                setElementSize(v);
                continue;
            }
            if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
                auto *v = new DomString();
                v->read(reader);
                setElementString(v);
                continue;
            }
            if (!tag.compare(QLatin1String("stringlist"), Qt::CaseInsensitive)) {
                auto *v = new DomStringList();
                v->read(reader);
                setElementStringList(v);
                continue;
            }
            if (!tag.compare(QLatin1String("number"), Qt::CaseInsensitive)) {
                setElementNumber(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("float"), Qt::CaseInsensitive)) {
                setElementFloat(reader.readElementText().toFloat());
                continue;
            }
            if (!tag.compare(QLatin1String("double"), Qt::CaseInsensitive)) {
                setElementDouble(reader.readElementText().toDouble());
                continue;
            }
            if (!tag.compare(QLatin1String("date"), Qt::CaseInsensitive)) {
                auto *v = new DomDate();
                v->read(reader);
                setElementDate(v);
                continue;
            }
            if (!tag.compare(QLatin1String("time"), Qt::CaseInsensitive)) {
                auto *v = new DomTime();
                v->read(reader);
                setElementTime(v);
                continue;
            }
            if (!tag.compare(QLatin1String("datetime"), Qt::CaseInsensitive)) {
                auto *v = new DomDateTime();
                v->read(reader);
                setElementDateTime(v);
                continue;
            }
            if (!tag.compare(QLatin1String("pointf"), Qt::CaseInsensitive)) {
                auto *v = new DomPointF();
                v->read(reader);
                setElementPointF(v);
                continue;
            }
            if (!tag.compare(QLatin1String("rectf"), Qt::CaseInsensitive)) {
                auto *v = new DomRectF();
                v->read(reader);
                setElementRectF(v);
                continue;
            }
            if (!tag.compare(QLatin1String("sizef"), Qt::CaseInsensitive)) {
                auto *v = new DomSizeF();
                v->read(reader);
                setElementSizeF(v);
                continue;
            }
            if (!tag.compare(QLatin1String("longlong"), Qt::CaseInsensitive)) {
                setElementLongLong(reader.readElementText().toLongLong());
                continue;
            }
            if (!tag.compare(QLatin1String("char"), Qt::CaseInsensitive)) {
                auto *v = new DomChar();
                v->read(reader);
                setElementChar(v);
                continue;
            }
            if (!tag.compare(QLatin1String("url"), Qt::CaseInsensitive)) {
                auto *v = new DomUrl();
                v->read(reader);
                setElementUrl(v);
                continue;
            }
            if (!tag.compare(QLatin1String("uint"), Qt::CaseInsensitive)) {
                setElementUInt(reader.readElementText().toUInt());
                continue;
            }
            if (!tag.compare(QLatin1String("ulonglong"), Qt::CaseInsensitive)) {
                setElementULongLong(reader.readElementText().toULongLong());
                continue;
            }
            if (!tag.compare(QLatin1String("brush"), Qt::CaseInsensitive)) {
                auto *v = new DomBrush();
                v->read(reader);
                setElementBrush(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomProperty::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("property") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    if (hasAttributeStdset())
        writer.writeAttribute(QStringLiteral("stdset"), QString::number(attributeStdset()));

    switch (kind()) {
    case Bool:
        writer.writeTextElement(QStringLiteral("bool"), elementBool());
        break;

    case Color:
        if (m_color != nullptr)
            m_color->write(writer, QStringLiteral("color"));
        break;

    case Cstring:
        writer.writeTextElement(QStringLiteral("cstring"), elementCstring());
        break;

    case Cursor:
        writer.writeTextElement(QStringLiteral("cursor"), QString::number(elementCursor()));
        break;

    case CursorShape:
        writer.writeTextElement(QStringLiteral("cursorShape"), elementCursorShape());
        break;

    case Enum:
        writer.writeTextElement(QStringLiteral("enum"), elementEnum());
        break;

    case Font:
        if (m_font != nullptr)
            m_font->write(writer, QStringLiteral("font"));
        break;

    case IconSet:
        if (m_iconSet != nullptr)
            m_iconSet->write(writer, QStringLiteral("iconset"));
        break;

    case Pixmap:
        if (m_pixmap != nullptr)
            m_pixmap->write(writer, QStringLiteral("pixmap"));
        break;

    case Palette:
        if (m_palette != nullptr)
            m_palette->write(writer, QStringLiteral("palette"));
        break;

    case Point:
        if (m_point != nullptr)
            m_point->write(writer, QStringLiteral("point"));
        break;

    case Rect:
        if (m_rect != nullptr)
            m_rect->write(writer, QStringLiteral("rect"));
        break;

    case Set:
        writer.writeTextElement(QStringLiteral("set"), elementSet());
        break;

    case Locale:
        if (m_locale != nullptr)
            m_locale->write(writer, QStringLiteral("locale"));
        break;

    case SizePolicy:
        if (m_sizePolicy != nullptr)
            m_sizePolicy->write(writer, QStringLiteral("sizepolicy"));
        break;

    case Size:
        if (m_size != nullptr)
            m_size->write(writer, QStringLiteral("size"));
        break;

    case String:
        if (m_string != nullptr)
            m_string->write(writer, QStringLiteral("string"));
        break;

    case StringList:
        if (m_stringList != nullptr)
            m_stringList->write(writer, QStringLiteral("stringlist"));
        break;

    case Number:
        writer.writeTextElement(QStringLiteral("number"), QString::number(elementNumber()));
        break;

    case Float:
        writer.writeTextElement(QStringLiteral("float"), QString::number(elementFloat(), 'f', 8));
        break;

    case Double:
        writer.writeTextElement(QStringLiteral("double"), QString::number(elementDouble(), 'f', 15));
        break;

    case Date:
        if (m_date != nullptr)
            m_date->write(writer, QStringLiteral("date"));
        break;

    case Time:
        if (m_time != nullptr)
            m_time->write(writer, QStringLiteral("time"));
        break;

    case DateTime:
        if (m_dateTime != nullptr)
            m_dateTime->write(writer, QStringLiteral("datetime"));
        break;

    case PointF:
        if (m_pointF != nullptr)
            m_pointF->write(writer, QStringLiteral("pointf"));
        break;

    case RectF:
        if (m_rectF != nullptr)
            m_rectF->write(writer, QStringLiteral("rectf"));
        break;

    case SizeF:
        if (m_sizeF != nullptr)
            m_sizeF->write(writer, QStringLiteral("sizef"));
        break;

    case LongLong:
        writer.writeTextElement(QStringLiteral("longLong"), QString::number(elementLongLong()));
        break;

    case Char:
        if (m_char != nullptr)
            m_char->write(writer, QStringLiteral("char"));
        break;

    case Url:
        if (m_url != nullptr)
            m_url->write(writer, QStringLiteral("url"));
        break;

    case UInt:
        writer.writeTextElement(QStringLiteral("UInt"), QString::number(elementUInt()));
        break;

    case ULongLong:
        writer.writeTextElement(QStringLiteral("uLongLong"), QString::number(elementULongLong()));
        break;

    case Brush:
        if (m_brush != nullptr)
            m_brush->write(writer, QStringLiteral("brush"));
        break;

    default:
        break;
    }
    writer.writeEndElement();
}

void DomProperty::setElementBool(const QString &a)
{
    clear();
    m_kind = Bool;
    m_bool = a;
}

DomColor *DomProperty::takeElementColor()
{
    DomColor *a = m_color;
    m_color = nullptr;
    return a;
}

void DomProperty::setElementColor(DomColor *a)
{
    clear();
    m_kind = Color;
    m_color = a;
}

void DomProperty::setElementCstring(const QString &a)
{
    clear();
    m_kind = Cstring;
    m_cstring = a;
}

void DomProperty::setElementCursor(int a)
{
    clear();
    m_kind = Cursor;
    m_cursor = a;
}

void DomProperty::setElementCursorShape(const QString &a)
{
    clear();
    m_kind = CursorShape;
    m_cursorShape = a;
}

void DomProperty::setElementEnum(const QString &a)
{
    clear();
    m_kind = Enum;
    m_enum = a;
}

DomFont *DomProperty::takeElementFont()
{
    DomFont *a = m_font;
    m_font = nullptr;
    return a;
}

void DomProperty::setElementFont(DomFont *a)
{
    clear();
    m_kind = Font;
    m_font = a;
}

DomResourceIcon *DomProperty::takeElementIconSet()
{
    DomResourceIcon *a = m_iconSet;
    m_iconSet = nullptr;
    return a;
}

void DomProperty::setElementIconSet(DomResourceIcon *a)
{
    clear();
    m_kind = IconSet;
    m_iconSet = a;
}

DomResourcePixmap *DomProperty::takeElementPixmap()
{
    DomResourcePixmap *a = m_pixmap;
    m_pixmap = nullptr;
    return a;
}

void DomProperty::setElementPixmap(DomResourcePixmap *a)
{
    clear();
    m_kind = Pixmap;
    m_pixmap = a;
}

DomPalette *DomProperty::takeElementPalette()
{
    DomPalette *a = m_palette;
    m_palette = nullptr;
    return a;
}

void DomProperty::setElementPalette(DomPalette *a)
{
    clear();
    m_kind = Palette;
    m_palette = a;
}

DomPoint *DomProperty::takeElementPoint()
{
    DomPoint *a = m_point;
    m_point = nullptr;
    return a;
}

void DomProperty::setElementPoint(DomPoint *a)
{
    clear();
    m_kind = Point;
    m_point = a;
}

DomRect *DomProperty::takeElementRect()
{
    DomRect *a = m_rect;
    m_rect = nullptr;
    return a;
}

void DomProperty::setElementRect(DomRect *a)
{
    clear();
    m_kind = Rect;
    m_rect = a;
}

void DomProperty::setElementSet(const QString &a)
{
    clear();
    m_kind = Set;
    m_set = a;
}

DomLocale *DomProperty::takeElementLocale()
{
    DomLocale *a = m_locale;
    m_locale = nullptr;
    return a;
}

void DomProperty::setElementLocale(DomLocale *a)
{
    clear();
    m_kind = Locale;
    m_locale = a;
}

DomSizePolicy *DomProperty::takeElementSizePolicy()
{
    DomSizePolicy *a = m_sizePolicy;
    m_sizePolicy = nullptr;
    return a;
}

void DomProperty::setElementSizePolicy(DomSizePolicy *a)
{
    clear();
    m_kind = SizePolicy;
    m_sizePolicy = a;
}

DomSize *DomProperty::takeElementSize()
{
    DomSize *a = m_size;
    m_size = nullptr;
    return a;
}

void DomProperty::setElementSize(DomSize *a)
{
    clear();
    m_kind = Size;
    m_size = a;
}

DomString *DomProperty::takeElementString()
{
    DomString *a = m_string;
    m_string = nullptr;
    return a;
}

void DomProperty::setElementString(DomString *a)
{
    clear();
    m_kind = String;
    m_string = a;
}

DomStringList *DomProperty::takeElementStringList()
{
    DomStringList *a = m_stringList;
    m_stringList = nullptr;
    return a;
}

void DomProperty::setElementStringList(DomStringList *a)
{
    clear();
    m_kind = StringList;
    m_stringList = a;
}

void DomProperty::setElementNumber(int a)
{
    clear();
    m_kind = Number;
    m_number = a;
}

void DomProperty::setElementFloat(float a)
{
    clear();
    m_kind = Float;
    m_float = a;
}

void DomProperty::setElementDouble(double a)
{
    clear();
    m_kind = Double;
    m_double = a;
}

DomDate *DomProperty::takeElementDate()
{
    DomDate *a = m_date;
    m_date = nullptr;
    return a;
}

void DomProperty::setElementDate(DomDate *a)
{
    clear();
    m_kind = Date;
    m_date = a;
}

DomTime *DomProperty::takeElementTime()
{
    DomTime *a = m_time;
    m_time = nullptr;
    return a;
}

void DomProperty::setElementTime(DomTime *a)
{
    clear();
    m_kind = Time;
    m_time = a;
}

DomDateTime *DomProperty::takeElementDateTime()
{
    DomDateTime *a = m_dateTime;
    m_dateTime = nullptr;
    return a;
}

void DomProperty::setElementDateTime(DomDateTime *a)
{
    clear();
    m_kind = DateTime;
    m_dateTime = a;
}

DomPointF *DomProperty::takeElementPointF()
{
    DomPointF *a = m_pointF;
    m_pointF = nullptr;
    return a;
}

void DomProperty::setElementPointF(DomPointF *a)
{
    clear();
    m_kind = PointF;
    m_pointF = a;
}

DomRectF *DomProperty::takeElementRectF()
{
    DomRectF *a = m_rectF;
    m_rectF = nullptr;
    return a;
}

void DomProperty::setElementRectF(DomRectF *a)
{
    clear();
    m_kind = RectF;
    m_rectF = a;
}

DomSizeF *DomProperty::takeElementSizeF()
{
    DomSizeF *a = m_sizeF;
    m_sizeF = nullptr;
    return a;
}

void DomProperty::setElementSizeF(DomSizeF *a)
{
    clear();
    m_kind = SizeF;
    m_sizeF = a;
}

void DomProperty::setElementLongLong(qlonglong a)
{
    clear();
    m_kind = LongLong;
    m_longLong = a;
}

DomChar *DomProperty::takeElementChar()
{
    DomChar *a = m_char;
    m_char = nullptr;
    return a;
}

void DomProperty::setElementChar(DomChar *a)
{
    clear();
    m_kind = Char;
    m_char = a;
}

DomUrl *DomProperty::takeElementUrl()
{
    DomUrl *a = m_url;
    m_url = nullptr;
    return a;
}

void DomProperty::setElementUrl(DomUrl *a)
{
    clear();
    m_kind = Url;
    m_url = a;
}

void DomProperty::setElementUInt(uint a)
{
    clear();
    m_kind = UInt;
    m_UInt = a;
}

void DomProperty::setElementULongLong(qulonglong a)
{
    clear();
    m_kind = ULongLong;
    m_uLongLong = a;
}

DomBrush *DomProperty::takeElementBrush()
{
    DomBrush *a = m_brush;
    m_brush = nullptr;
    return a;
}

void DomProperty::setElementBrush(DomBrush *a)
{
    clear();
    m_kind = Brush;
    m_brush = a;
}

DomConnections::~DomConnections()
{
    qDeleteAll(m_connection);
    m_connection.clear();
}

void DomConnections::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("connection"), Qt::CaseInsensitive)) {
                auto *v = new DomConnection();
                v->read(reader);
                m_connection.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomConnections::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("connections") : tagName.toLower());

    for (DomConnection *v : m_connection)
        v->write(writer, QStringLiteral("connection"));

    writer.writeEndElement();
}

void DomConnections::setElementConnection(const QVector<DomConnection *> &a)
{
    m_children |= Connection;
    m_connection = a;
}

DomConnection::~DomConnection()
{
    delete m_hints;
}

void DomConnection::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("sender"), Qt::CaseInsensitive)) {
                setElementSender(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("signal"), Qt::CaseInsensitive)) {
                setElementSignal(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("receiver"), Qt::CaseInsensitive)) {
                setElementReceiver(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("slot"), Qt::CaseInsensitive)) {
                setElementSlot(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("hints"), Qt::CaseInsensitive)) {
                auto *v = new DomConnectionHints();
                v->read(reader);
                setElementHints(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomConnection::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("connection") : tagName.toLower());

    if (m_children & Sender)
        writer.writeTextElement(QStringLiteral("sender"), m_sender);

    if (m_children & Signal)
        writer.writeTextElement(QStringLiteral("signal"), m_signal);

    if (m_children & Receiver)
        writer.writeTextElement(QStringLiteral("receiver"), m_receiver);

    if (m_children & Slot)
        writer.writeTextElement(QStringLiteral("slot"), m_slot);

    if (m_children & Hints)
        m_hints->write(writer, QStringLiteral("hints"));

    writer.writeEndElement();
}

void DomConnection::setElementSender(const QString &a)
{
    m_children |= Sender;
    m_sender = a;
}

void DomConnection::setElementSignal(const QString &a)
{
    m_children |= Signal;
    m_signal = a;
}

void DomConnection::setElementReceiver(const QString &a)
{
    m_children |= Receiver;
    m_receiver = a;
}

void DomConnection::setElementSlot(const QString &a)
{
    m_children |= Slot;
    m_slot = a;
}

DomConnectionHints *DomConnection::takeElementHints()
{
    DomConnectionHints *a = m_hints;
    m_hints = nullptr;
    m_children ^= Hints;
    return a;
}

void DomConnection::setElementHints(DomConnectionHints *a)
{
    delete m_hints;
    m_children |= Hints;
    m_hints = a;
}

void DomConnection::clearElementSender()
{
    m_children &= ~Sender;
}

void DomConnection::clearElementSignal()
{
    m_children &= ~Signal;
}

void DomConnection::clearElementReceiver()
{
    m_children &= ~Receiver;
}

void DomConnection::clearElementSlot()
{
    m_children &= ~Slot;
}

void DomConnection::clearElementHints()
{
    delete m_hints;
    m_hints = nullptr;
    m_children &= ~Hints;
}

DomConnectionHints::~DomConnectionHints()
{
    qDeleteAll(m_hint);
    m_hint.clear();
}

void DomConnectionHints::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("hint"), Qt::CaseInsensitive)) {
                auto *v = new DomConnectionHint();
                v->read(reader);
                m_hint.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomConnectionHints::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("connectionhints") : tagName.toLower());

    for (DomConnectionHint *v : m_hint)
        v->write(writer, QStringLiteral("hint"));

    writer.writeEndElement();
}

void DomConnectionHints::setElementHint(const QVector<DomConnectionHint *> &a)
{
    m_children |= Hint;
    m_hint = a;
}

DomConnectionHint::~DomConnectionHint() = default;

void DomConnectionHint::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("type")) {
            setAttributeType(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("x"), Qt::CaseInsensitive)) {
                setElementX(reader.readElementText().toInt());
                continue;
            }
            if (!tag.compare(QLatin1String("y"), Qt::CaseInsensitive)) {
                setElementY(reader.readElementText().toInt());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomConnectionHint::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("connectionhint") : tagName.toLower());

    if (hasAttributeType())
        writer.writeAttribute(QStringLiteral("type"), attributeType());

    if (m_children & X)
        writer.writeTextElement(QString(QLatin1Char('x')), QString::number(m_x));

    if (m_children & Y)
        writer.writeTextElement(QString(QLatin1Char('y')), QString::number(m_y));

    writer.writeEndElement();
}

void DomConnectionHint::setElementX(int a)
{
    m_children |= X;
    m_x = a;
}

void DomConnectionHint::setElementY(int a)
{
    m_children |= Y;
    m_y = a;
}

void DomConnectionHint::clearElementX()
{
    m_children &= ~X;
}

void DomConnectionHint::clearElementY()
{
    m_children &= ~Y;
}

DomDesignerData::~DomDesignerData()
{
    qDeleteAll(m_property);
    m_property.clear();
}

void DomDesignerData::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
                auto *v = new DomProperty();
                v->read(reader);
                m_property.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomDesignerData::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("designerdata") : tagName.toLower());

    for (DomProperty *v : m_property)
        v->write(writer, QStringLiteral("property"));

    writer.writeEndElement();
}

void DomDesignerData::setElementProperty(const QList<DomProperty *> &a)
{
    m_children |= Property;
    m_property = a;
}

DomSlots::~DomSlots()
{
    m_signal.clear();
    m_slot.clear();
}

void DomSlots::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("signal"), Qt::CaseInsensitive)) {
                m_signal.append(reader.readElementText());
                continue;
            }
            if (!tag.compare(QLatin1String("slot"), Qt::CaseInsensitive)) {
                m_slot.append(reader.readElementText());
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomSlots::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("slots") : tagName.toLower());

    for (const QString &v : m_signal)
        writer.writeTextElement(QStringLiteral("signal"), v);

    for (const QString &v : m_slot)
        writer.writeTextElement(QStringLiteral("slot"), v);

    writer.writeEndElement();
}

void DomSlots::setElementSignal(const QStringList &a)
{
    m_children |= Signal;
    m_signal = a;
}

void DomSlots::setElementSlot(const QStringList &a)
{
    m_children |= Slot;
    m_slot = a;
}

DomPropertySpecifications::~DomPropertySpecifications()
{
    qDeleteAll(m_tooltip);
    m_tooltip.clear();
    qDeleteAll(m_stringpropertyspecification);
    m_stringpropertyspecification.clear();
}

void DomPropertySpecifications::read(QXmlStreamReader &reader)
{
    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            if (!tag.compare(QLatin1String("tooltip"), Qt::CaseInsensitive)) {
                auto *v = new DomPropertyToolTip();
                v->read(reader);
                m_tooltip.append(v);
                continue;
            }
            if (!tag.compare(QLatin1String("stringpropertyspecification"), Qt::CaseInsensitive)) {
                auto *v = new DomStringPropertySpecification();
                v->read(reader);
                m_stringpropertyspecification.append(v);
                continue;
            }
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomPropertySpecifications::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("propertyspecifications") : tagName.toLower());

    for (DomPropertyToolTip *v : m_tooltip)
        v->write(writer, QStringLiteral("tooltip"));

    for (DomStringPropertySpecification *v : m_stringpropertyspecification)
        v->write(writer, QStringLiteral("stringpropertyspecification"));

    writer.writeEndElement();
}

void DomPropertySpecifications::setElementTooltip(const QVector<DomPropertyToolTip *> &a)
{
    m_children |= Tooltip;
    m_tooltip = a;
}

void DomPropertySpecifications::setElementStringpropertyspecification(const QVector<DomStringPropertySpecification *> &a)
{
    m_children |= Stringpropertyspecification;
    m_stringpropertyspecification = a;
}

DomPropertyToolTip::~DomPropertyToolTip() = default;

void DomPropertyToolTip::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomPropertyToolTip::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("propertytooltip") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    writer.writeEndElement();
}

DomStringPropertySpecification::~DomStringPropertySpecification() = default;

void DomStringPropertySpecification::read(QXmlStreamReader &reader)
{
    const QXmlStreamAttributes &attributes = reader.attributes();
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef name = attribute.name();
        if (name == QLatin1String("name")) {
            setAttributeName(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("type")) {
            setAttributeType(attribute.value().toString());
            continue;
        }
        if (name == QLatin1String("notr")) {
            setAttributeNotr(attribute.value().toString());
            continue;
        }
        reader.raiseError(QLatin1String("Unexpected attribute ") + name);
    }

    while (!reader.hasError()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef tag = reader.name();
            reader.raiseError(QLatin1String("Unexpected element ") + tag);
        }
            break;
        case QXmlStreamReader::EndElement :
            return;
        default :
            break;
        }
    }
}

void DomStringPropertySpecification::write(QXmlStreamWriter &writer, const QString &tagName) const
{
    writer.writeStartElement(tagName.isEmpty() ? QStringLiteral("stringpropertyspecification") : tagName.toLower());

    if (hasAttributeName())
        writer.writeAttribute(QStringLiteral("name"), attributeName());

    if (hasAttributeType())
        writer.writeAttribute(QStringLiteral("type"), attributeType());

    if (hasAttributeNotr())
        writer.writeAttribute(QStringLiteral("notr"), attributeNotr());

    writer.writeEndElement();
}

QT_END_NAMESPACE

