QtMvvm  1.1.0
A mvvm oriented library for Qt, to create Projects for Widgets and Quick in parallel
The XML settings format

Table of Contents

Documentation of the XML format used to create settings uis

This format is used to create settings.xml files to be read by the default XML QtMvvm::ISettingsSetupLoader. The files are read via that service and mapped to QtMvvm::SettingsElements::Setup.

Translations

All the settings files you have can be easily translated via a standard ts/qm file. The following explains how exactly.

The mvvm core module comes with a special make taget, called lupdate that will automatically run lupdate when your sources change to update the TRANSLATIONS files. To not run this automatically, call qmake with qmake CONFIG+=no_auto_lupdate .... In both cases, you can always run make lupdate to explicitly update the dependencies.

With this step enabled, the only thing left to do is to add the settings xml file to the translation targets so it gets included as a source when running the lupdate target. To do so, simply add it to the SETTINGS_TRANSLATIONS qmake variable:

SETTINGS_TRANSLATIONS += settings.xml

This will internally generate a cpp file that is parsed and included in lupdate when running it via the builtin lupdate target.

Elements

The possible elements of such a file

SettingsConfig

The whole settings setup.

The <SettingsConfig> element must be the root Element of the XML document and is mapped to the QtMvvm::SettingsElements::Setup.

Attributes

Name Type Default Translated Description
allowSearch bool true no Specifies if the user is allowed to search in the settings.
allowRestore bool true no Specifies if the user is allowed to restore the factory defaults.

Content

Can be an arbitrary number of Elements from the following list. However, only one type of element is allowed. If you for example use <Entry> as first child, all other children must be of the same type as well:

Category

A top level category to organize sections in.

The <Category> element is mapped to the QtMvvm::SettingsElements::Category.

Attributes

Name Type Default Translated Description
title string "General Settings" yes The categories title.
icon url "qrc:/de/skycoder42/qtmvvm/icons/settings.svg" no An icon for the category.
tooltip string Empty yes A tooltip to describe what the category is about.
frontends descriptor Empty no [Internal] A logical string describing the allowed frontends
selectors descriptor Empty no [Internal] A logical string describing the allowed selectors

Content

Can be an arbitrary number of Elements from the following list. However, only one type of element is allowed. If you for example use <Entry> as first child, all other children must be of the same type as well:

Section

A bigger section for different entries and groups.

The <Section> element is mapped to the QtMvvm::SettingsElements::Section.

Attributes

Name Type Default Translated Description
title string "General" yes The sections title.
icon url Empty no An icon for the section.
tooltip string Empty yes A tooltip to describe what the section is about.
frontends descriptor Empty no [Internal] A logical string describing the allowed frontends
selectors descriptor Empty no [Internal] A logical string describing the allowed selectors

Content

Can be an arbitrary number of Elements from the following list. However, only one type of element is allowed. If you for example use <Entry> as first child, all other children must be of the same type as well:

Group

A logical group of settings entries.

The <Group> element is mapped to the QtMvvm::SettingsElements::Group. A special property of the group is, that when the title is not set, the group becomes hidden and instead all entries that are part of the group are simply shown as normal elements in the section, instead of organizing them into subgroups. If the title is empty, the tooltip is ignored, even if set. The descriptors however still apply.

Attributes

Name Type Default Translated Description
title string Empty yes The groups title.
tooltip string Empty yes A tooltip to describe what the group is about.
frontends descriptor Empty no [Internal] A logical string describing the allowed frontends
selectors descriptor Empty no [Internal] A logical string describing the allowed selectors

Content

Can be an arbitrary number of Elements from the following list. However, only one type of element is allowed. If you for example use <Entry> as first child, all other children must be of the same type as well:

Entry

An entry in the settings to display and edit a value.

The <Entry> element is mapped to the QtMvvm::SettingsElements::Entry.

Attributes

Name Type Default Translated Description
key string Empty no The QSettings key this entry should handle.
type type "QString" no The input view type (typically the actual data type) to show.
title string Empty yes A short title/label of the entry to give it a name.
tooltip string Empty yes A tooltip with more detailed information about the entry.
default variant Invalid trdefault A default value to display in case no value is in the settings yet.
trdefault bool false no If set to true, default will be translated. If not set or set to false, it will not be
frontends descriptor Empty no [Internal] A logical string describing the allowed frontends
selectors descriptor Empty no [Internal] A logical string describing the allowed selectors

Content

Can be an arbitrary number of Elements from the following list. They can be mixed and in any order

SearchKey

The <SearchKey> Element is converted to a string added to the QtMvvm::SettingsElements::Entry::searchKeys property. A searchkey can only be a child of an Entry, and all the keys are merged to a list. It's a leaf element and must contain the string that becomes the search key. The contens of the search key will be translated.

Property

The <Property> Element is an XML description of a generic QVariant property. Each property gets converted to a QString key and a QVariant value that then becomes a property of the parent element. Properties can be children of entries, as well as properties and elements, as long as for the last two their type is object

Attributes

Name Type Default Translated Description
key string Required no The key of the property
type type Required no The type of the properties value
tr bool false no Specify whether the properties value (content) should be translated. Does not apply to list or object types
ztr bool false no Like tr, but does not translate the text, only generate the translation in the ts file

Content

The content depend on the type attribute. The following tables shows which type leads to which kind of child element:

Type Child Element
list An arbitrary number of Element elements
object An arbitrary number of Property elements
Others Has text content. The text content is interpreted as a value of the given type

Element

The <Element> Element is an XML description of a generic QVariant list value. A property of type list will have a number of elements as children that are converted to a list of QVariant values. Each element can be of a different type, but typically they all are of the same.

Attributes

Name Type Default Translated Description
type type Required no The type of the list element
tr bool false no Specify whether the element value (content) should be translated. Does not apply to list or object types
ztr bool false no Like tr, but does not translate the text, only generate the translation in the ts file

Content

The content depend on the type attribute. The following tables shows which type leads to which kind of child element:

Type Child Element
list An arbitrary number of Element elements
object An arbitrary number of Property elements
Others Has text content. The text content is interpreted as a value of the given type

Include

An <Include> element is a reference to a different file to be included at that point. When the parser reaches an include, it continues to read the included file as if it was a part of the original XML document. Because of that the root element of an included settings file must not be <SettingsConfig>, but instead the expected primary child of the current parent element. For example, if the include element is a child of a <Section>, then the root element must be a <Group> element (Each element that support includes as one child type marked as primary). It is possible to specify an include element in another included document.

Attributes

Name Type Default Translated Description
optional bool false no An optional include. If the file cannot be found it is skipped instead of aborting with an error
frontends descriptor Empty no [Internal] A logical string describing the allowed frontends
selectors descriptor Empty no [Internal] A logical string describing the allowed selectors

Content

The content of the include element must be a path to an XML file to be read as include. If the path is relative, it is resolved relative to the directory of the current file (the one that contains the include directive). It is possible to use a path with file selectors. If the file could not be found, the parser will fail, unless the include is marked as optional.

Attribute and Value types

In the above element descriptions a number of types are specified. Most are very basic types, but some need some more explanation to them.

Basic Types

The following table lists all basic types that don't need much explanation:

Type Description
string A simple string
bool A boolean value. Allowed values are true and false
url A standard XML encoded URL
variant A string that is read by C++ as string and then stored as QVariant. It thus must be a string convertible to the desired type via QVariant

type

The type type must be a simple string that corresponds to a C++ type name (or special ui type, for entry elements). It defines the actual type of for example the default of the <Entry> element or the contents of a <Property> element. Typical values would be:

The type you need depends on what kind of data you want to represent via the XML elements. But remember that all types you use must be convertible from a simple string.

descriptor

A descripter is a simplified string of a boolean logic statement. It us used for the frontend and selectors attributes of various elements. The general idea is that these descriptors serve as "filters". This allows you to create one xml file for all platforms and frontends, by excluding specific elements for specific configurations. See QtMvvm::ISettingsSetupLoader::loadSetup.

The allowed symbols and syntax depend on the attribute the descriptor is used for:

frontend descriptor

The frontend is the name of the GUI implementation beeing used (For example widgest for the QWidgets based gui, and quick for the Qt Quick Controls 2 gui). Must be a string of the following format:

<frontend>[|<frontend>...]

With <frontend> beeing the name of the frontend the element should be visible for. It's basically a list of allowed frontend as simple string. If the attribute is not specified, the element is visible on all frontends.

selectors descriptor

The selectors are active file selectors (of the QFileSelector class). By specifiying this attribute you can set selectors that must be active for the element to be visible. This can for example be used to show a specific element on one platform only. Must be a string of the following format:

<selector>[&<selector>...][|<frontend>[&<selector>...]...]

With <selector> beeing the names of the selectors that must be set. It's basically a bunch of or condiditions around and conditions. This is a very reduced boolean logic, but it should be enough to create the desired filters. For example, you may want to show an element only on windows or on android when the material design is used. The resulting string would be: windows|android&material.

action

The action type is meant as a placeholder for a pressable button. An action edit will simply display a button or similar, and instead of representing a value in the settings, pressing it will trigger QtMvvm::SettingsViewModel::callAction. The Entries key attribute is passed as the first parameter to the method. The parameters can be specified by adding a <Property> to the entry with the key args and the type object. The property of this object are the elements of the map passed as the second parameter.

Sample settings XML file

The following code block is a sample settings XML file. It is the same that is beeing used in the example application.

<?xml version="1.0" encoding="UTF-8"?>
<SettingsConfig allowSearch="true" allowRestore="true">
<!--Include optional="true">/absolute/include/path.xml</Include-->
<Category>
<Section>
<Group>
<Entry key="prop1"
type="bool"
title="&amp;Check me"
tooltip="I am a checkbox!"
default="true">
<SearchKey>property</SearchKey>
<SearchKey>bool</SearchKey>
<Property key="qtmvvm_preview" type="bool">true</Property>
</Entry>
<Entry key="prop2"
type="string"
title="Enter a &amp;name">
<SearchKey>property</SearchKey>
<Property key="placeholderText" type="string" tr="true">Enter a nice name</Property>
<Property key="qtmvvm_preview" type="string" tr="true">Your current name: %1</Property>
</Entry>
</Group>
<Group title="Sub-Group" tooltip="This is a tooltip">
<Entry key="prop3"
type="action"
title="Open &amp;system settings"
tooltip="Pressing this action will open the system settings">
<Property key="text" type="string">Trigger Action</Property>
<Property key="args" type="object">
<Property key="hint" type="string" tr="true">You can use this to trigger whatever kind of action you need</Property>
</Property>
</Entry>
<Entry key="prop4"
type="selection"
title="Select a &amp;mode"
default="Variant B"
trdefault="true">
<Property key="listElements" type="list">
<Element type="string" tr="true">Variant A</Element>
<Element type="string" tr="true">Variant B</Element>
<Element type="string" tr="true">Variant C</Element>
</Property>
<Property key="qtmvvm_preview" type="string" tr="true">Current value: %1</Property>
</Entry>
</Group>
</Section>
<Section title="Another Section" icon="" tooltip="This is another section">
<Entry key="prop5"
type="double"
title="Enter a &amp;value"
tooltip="The value must be between 0 and 1"
default="0.0">
<Property key="minimum" type="double">0.0</Property>
<Property key="maximum" type="double">1.0</Property>
<Property key="qtmvvm_preview" type="string" tr="true">Current value: %L1</Property>
</Entry>
<Entry key="prop6"
type="selection"
title="Select a &amp;mode"
default="3">
<Property key="listElements" type="list">
<Element type="object">
<Property key="name" type="string" tr="true">Value A</Property>
<Property key="value" type="int">1</Property>
</Element>
<Element type="object">
<Property key="name" type="string" tr="true">Value B</Property>
<Property key="value" type="int">2</Property>
</Element>
<Element type="object">
<Property key="name" type="string" tr="true">Value C</Property>
<Property key="value" type="int">4</Property>
</Element>
<Element type="object">
<Property key="name" type="string" tr="true">Value A+B</Property>
<Property key="value" type="int">3</Property>
</Element>
<Element type="object">
<Property key="name" type="string" tr="true">Value A+C</Property>
<Property key="value" type="int">5</Property>
</Element>
<Element type="object">
<Property key="name" type="string" tr="true">Value B+C</Property>
<Property key="value" type="int">6</Property>
</Element>
<Element type="object">
<Property key="name" type="string" tr="true">Value A+B+C</Property>
<Property key="value" type="int">7</Property>
</Element>
</Property>
<Property key="qtmvvm_preview" type="string" tr="true">Current value: %1</Property>
</Entry>
</Section>
</Category>
<Category title="Another main category">
<Entry key="prop7"
type="int"
title="Enter a &amp;number"
default="42">
<Property key="qtmvvm_preview" type="string" ztr="true">Is set to %n unit(s)</Property>
</Entry>
<Entry key="prop8"
type="selection"
title="Select a &amp;mode"
default="Text 2"
trdefault="true">
<Property key="editable" type="bool">true</Property>
<Property key="listElements" type="list">
<Element type="string" tr="true">Text 1</Element>
<Element type="string" tr="true">Text 2</Element>
</Property>
</Entry>
<Entry key="prop9"
type="url"
title="Enter a &amp;website">
<Property key="placeholderText" type="string" tr="true">https://example.org/test</Property>
</Entry>
<Entry key="prop10"
type="QFont"
title="Choose a &amp;font" />
<Entry key="prop12"
type="range"
title="&amp;Volume"
default="50">
<Property key="minimum" type="int">0</Property>
<Property key="maximum" type="int">100</Property>
<Property key="valueFormat" type="string">%1 %</Property>
</Entry>
<Entry key="prop13"
type="QTime"
title="Choose a time"
default="14:30">
<Property key="qtmvvm_preview" type="string">Selected time: %1</Property>
<Property key="qtmvvm_dateformat" type="int">1</Property>
</Entry>
<Entry key="prop14"
type="QDate"
title="Choose a date"
default="2018-10-10">
<Property key="qtmvvm_preview" type="string">Selected date: %1</Property>
<Property key="qtmvvm_dateformat" type="string">dd. MMMM yyyy</Property>
</Entry>
<Entry key="prop15"
type="QDateTime"
title="Choose a date and time"
default="2018-10-10T14:30">
<Property key="qtmvvm_preview" type="string">Selected date and time: %1</Property>
</Entry>
<Entry key="prop16"
type="QColor"
title="Choose a color"
default="#AA00FF" />
<Entry key="propErr"
type="non-existant-type"
title="Non existing type" />
</Category>
</SettingsConfig>

The XSD for the settings files

The following file is the XSD the parser operates on. You can use it to verify your settings xml files.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:qxg="https://skycoder42.de/xml/schemas/QXmlCodeGen">
<!-- QXG Definitions -->
<qxg:config class="SettingsConfigBase"
prefix="Q_MVVMCORE_EXPORT"
stdcompat="true"
schemaUrl="qrc:/schemas/settingsconfig.xsd"
visibility="public">
<qxg:include>QtCore/QHash</qxg:include>
<qxg:include local="true">prefix_p.h</qxg:include>
</qxg:config>
<qxg:method name="finish_group_content" type="GroupContentGroup" asGroup="true"/>
<qxg:method name="finish_section_content" type="SectionContentGroup" asGroup="true"/>
<qxg:method name="finish_category_content" type="CategoryContentGroup" asGroup="true"/>
<qxg:method name="finish_settings_config_content" type="SettingsConfigContentGroup" asGroup="true"/>
<!-- Basic property-like elements definitions -->
<xs:complexType name="ElementType" mixed="true" qxg:declare="true" qxg:member="content">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" type="PropertyType" name="Property" qxg:member="properties"/>
<xs:element maxOccurs="unbounded" minOccurs="0" type="ElementType" name="Element" qxg:member="elements"/>
</xs:sequence>
<xs:attribute type="xs:string" name="type" use="required"/>
<xs:attribute type="xs:boolean" name="tr" use="optional" default="false"/>
<xs:attribute type="xs:boolean" name="ztr" use="optional" default="false"/>
</xs:complexType>
<xs:complexType name="PropertyType" qxg:declare="true">
<xs:complexContent>
<xs:extension base="ElementType">
<xs:attribute type="xs:string" name="key" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- Group Definitions to build the elements from -->
<xs:attributeGroup name="SelectableContrainerInfo">
<xs:attribute type="xs:string" name="frontends" use="optional"/>
<xs:attribute type="xs:string" name="selectors" use="optional"/>
</xs:attributeGroup>
<xs:attributeGroup name="BasicContainerInfo">
<xs:attributeGroup ref="SelectableContrainerInfo" qxg:inherit="true"/>
<xs:attribute type="xs:string" name="title" use="optional"/>
<xs:attribute type="xs:string" name="tooltip" use="optional"/>
</xs:attributeGroup>
<xs:attributeGroup name="ExtendedContainerInfo">
<xs:attributeGroup ref="BasicContainerInfo" qxg:inherit="true"/>
<xs:attribute type="xs:string" name="icon" use="optional"/>
</xs:attributeGroup>
<xs:group name="GroupContentGroup">
<xs:sequence>
<xs:choice maxOccurs="unbounded" minOccurs="0" qxg:member="content">
<xs:element type="IncludeType" name="Include"/>
<xs:element type="EntryType" name="Entry"/>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="SectionContentGroup">
<xs:sequence>
<xs:choice maxOccurs="unbounded" minOccurs="0" qxg:member="content">
<xs:element type="IncludeType" name="Include"/>
<xs:element type="GroupType" name="Group"/>
<xs:element type="EntryType" name="Entry"/>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="CategoryContentGroup">
<xs:sequence>
<xs:choice maxOccurs="unbounded" minOccurs="0" qxg:member="content">
<xs:element type="IncludeType" name="Include"/>
<xs:element type="SectionType" name="Section"/>
<xs:element type="GroupType" name="Group"/>
<xs:element type="EntryType" name="Entry"/>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="SettingsConfigContentGroup">
<xs:sequence>
<xs:choice maxOccurs="unbounded" minOccurs="0" qxg:member="content">
<xs:element type="IncludeType" name="Include"/>
<xs:element type="CategoryType" name="Category"/>
<xs:element type="SectionType" name="Section"/>
<xs:element type="GroupType" name="Group"/>
<xs:element type="EntryType" name="Entry"/>
</xs:choice>
</xs:sequence>
</xs:group>
<!-- Element definitions -->
<xs:complexType name="IncludeType" qxg:declare="true">
<xs:simpleContent>
<xs:extension base="xs:string" qxg:member="includePath">
<xs:attributeGroup ref="SelectableContrainerInfo" qxg:inherit="true"/>
<xs:attribute type="xs:boolean" name="optional" default="false" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="EntryType" qxg:declare="true">
<xs:sequence>
<xs:choice maxOccurs="unbounded" minOccurs="0" qxg:unordered="true">
<xs:element type="xs:string" name="SearchKey" qxg:member="searchKeys"/>
<xs:element type="PropertyType" name="Property" qxg:member="properties"/>
</xs:choice>
</xs:sequence>
<xs:attributeGroup ref="BasicContainerInfo" qxg:inherit="true"/>
<xs:attribute type="xs:string" name="key" use="required"/>
<xs:attribute type="xs:string" name="type" use="required"/>
<xs:attribute type="xs:string" name="default" use="optional" qxg:member="defaultValue"/>
<xs:attribute type="xs:boolean" name="trdefault" use="optional" default="false"/>
</xs:complexType>
<xs:complexType name="GroupType" qxg:declare="true">
<xs:group ref="GroupContentGroup" qxg:inherit="true" qxg:method="finish_group_content"/>
<xs:attributeGroup ref="BasicContainerInfo" qxg:inherit="true"/>
</xs:complexType>
<xs:complexType name="SectionType" qxg:declare="true">
<xs:group ref="SectionContentGroup" qxg:inherit="true" qxg:method="finish_section_content"/>
<xs:attributeGroup ref="ExtendedContainerInfo" qxg:inherit="true"/>
</xs:complexType>
<xs:complexType name="CategoryType" qxg:declare="true">
<xs:group ref="CategoryContentGroup" qxg:inherit="true" qxg:method="finish_category_content"/>
<xs:attributeGroup ref="ExtendedContainerInfo" qxg:inherit="true"/>
</xs:complexType>
<xs:complexType name="SettingsConfigType" qxg:declare="true">
<xs:group ref="SettingsConfigContentGroup" qxg:inherit="true" qxg:method="finish_settings_config_content"/>
<xs:attribute type="xs:boolean" name="allowSearch" use="optional" default="true"/>
<xs:attribute type="xs:boolean" name="allowRestore" use="optional" default="true"/>
</xs:complexType>
<!-- root elements-->
<xs:element name="SettingsConfig" type="SettingsConfigType"/>
<xs:element name="Category" type="CategoryType"/>
<xs:element name="Section" type="SectionType"/>
<xs:element name="Group" type="GroupType"/>
<xs:element name="Entry" type="EntryType"/>
</xs:schema>