You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
16 KiB
337 lines
16 KiB
6 years ago
|
/*!
|
||
|
@page settings_generator The qsettingsgenerator Tool
|
||
|
@brief A tool to generate static, typesafe settings access without having to type key strings
|
||
|
|
||
|
@tableofcontents
|
||
|
|
||
|
The general idea is that instead of this:
|
||
|
@code{.cpp}
|
||
|
QSettins settings;
|
||
|
int value = settings.value("my/key", 42).toInt();
|
||
|
@endcode
|
||
|
|
||
|
You create a settings file like this:
|
||
|
@code{.xml}
|
||
|
<Settings name="Settings">
|
||
|
<Node key="my">
|
||
|
<Entry key="key" type="int" default="42"/>
|
||
|
</Node>
|
||
|
</Settings>
|
||
|
@endcode
|
||
|
|
||
|
And can now access the data like this:
|
||
|
@code{.cpp}
|
||
|
int value = Settings::instance()->my.key;
|
||
|
@endcode
|
||
|
|
||
|
So in summary: First, using QSettings requires you to type in
|
||
|
strings as keys - which cannot be checked by the compiler. With this tool you get a c++ member
|
||
|
hirachie instead - which is checked by the compiler and thus typo free. Also, the values in
|
||
|
the settings are made statically typed by using this generator. The second point was to support
|
||
|
multiple backends, not only QSettings, without having to change the frontend code.
|
||
|
|
||
|
@section settings_generator_features Features
|
||
|
- Access settings via code - no more typos and redundant strings!
|
||
|
- Static typing gives additionl saftey and is easier to use (no `.toType()` calls needed)
|
||
|
- Default values in one single, central place - less error prone and easier to maintain
|
||
|
- Can be specified as strings in the xml
|
||
|
- Can be specified as C++ code in the xml
|
||
|
- Use as a global single instance or create local instances
|
||
|
- Support for custom settings backends instead of QSettings alone
|
||
|
- QtMvvm::QSettingsAccessor for usage with QSettings (the default)
|
||
|
- QtMvvm::DataSyncSettingsAccessor to sync settings via [QtDataSync](https://github.com/Skycoder42/QtDataSync)
|
||
|
- QtMvvm::AndroidSettingsAccessor (android only) to access the SharedPreferences
|
||
|
- Can be used as an injectable service
|
||
|
|
||
|
@section settings_generator_usage Usage
|
||
|
Using QtMvvmCore adds a custom qmake compiler to you project. All you need to do is to create the settings xml
|
||
|
definition and then add it to the pro file as `SETTINGS_DEFINITIONS += mysettings.xml`. This will create a header
|
||
|
named "mysettings.h" you can include. That header contains the C++ generated settings class to access the settings.
|
||
|
|
||
|
@subsection settings_generator_usage_example Example
|
||
|
Create a pro file with and add the lines:
|
||
|
@code{.pro}
|
||
|
QT += mvvmcore
|
||
|
|
||
|
SETTINGS_DEFINITIONS += mysettings.xml
|
||
|
@endcode
|
||
|
|
||
|
Create a file named `mysettings.xml` and fill it:
|
||
|
@code{.xml}
|
||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||
|
<Settings name="MySettings">
|
||
|
<Node key="my">
|
||
|
<Entry key="key" type="int" default="42"/>
|
||
|
</Node>
|
||
|
</Settings>
|
||
|
@endcode
|
||
|
|
||
|
Finally, adjust you main to look like this:
|
||
|
@code{.cpp}
|
||
|
#include <QCoreApplication>
|
||
|
#include <QDebug>
|
||
|
#include "mysettings.h"
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
QCoreApplication a(argc, argv);
|
||
|
|
||
|
int myKey = MySettings::instance()->my.key;
|
||
|
qDebug() << myKey;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
@section settings_generator_qml QML-Bindings
|
||
|
The tool can also generate QML-Bindings, so you can access the settings in the same way from
|
||
|
QML. To do so, add to your pro file (in addition to `SETTINGS_DEFINITIONS`):
|
||
|
@code{.pro}
|
||
|
QML_SETTINGS_DEFINITIONS += mysettings.xml
|
||
|
@endcode
|
||
|
|
||
|
And also add some QML metadata using the Qml element in the settings
|
||
|
@code{.xml}
|
||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||
|
<Settings name="MySettings">
|
||
|
<Qml uri="com.example.settings"
|
||
|
major="1"
|
||
|
minor="0"/>
|
||
|
<!-- ... -->
|
||
|
</Settings>
|
||
|
@endcode
|
||
|
|
||
|
And with that, you can use the specified uri to access the settings from QML:
|
||
|
@code{.qml}
|
||
|
import com.example.settings 1.0
|
||
|
|
||
|
SomeItem {
|
||
|
someProperty: MySettings.my.key
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
@section settings_generator_format XML-Format Documentation
|
||
|
The following sections document the different elements and attributes in the XML format used
|
||
|
by the generator.
|
||
|
|
||
|
@subsection settings_generator_elements Elements
|
||
|
The possible elements of such a file.
|
||
|
|
||
|
@subsubsection settings_generator_elements_Settings Settings
|
||
|
The root Element of the XML document. It defines meta-stuff and the actual nodes and entries.
|
||
|
|
||
|
@paragraph settings_generator_elements_Settings_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
------------|-----------------------------------------------|-----------------------|-------------
|
||
|
name | string | _filename_ | The C++ class name of the generated class
|
||
|
prefix | string | _empty_ | Specify an export macro. The value is put before the class definition, if you want to export the generated class from a dynamic library
|
||
|
baseKey | string | _empty_ | A base settings key that is prepended to all keys
|
||
|
scope | @ref settings_generator_values_InstanceScope | DestroyOnAppDestroy | The destruction scope of the create service instance
|
||
|
|
||
|
@paragraph settings_generator_elements_Settings_children Child elements
|
||
|
Name | XML-Type | Limits | Description
|
||
|
----------------|-----------------------------------------------|-----------|-------------
|
||
|
Include | @ref settings_generator_elements_Include | 0 - ∞ | A header file to be included
|
||
|
Backend | @ref settings_generator_elements_Backend | 0 - 1 | The definition of the settings backend to use
|
||
|
Qml | @ref settings_generator_elements_Qml | 0 - 1 | Special configuration parameters for the QML bindings
|
||
|
TypeMapping | @ref settings_generator_elements_TypeMapping | 0 - ∞ | Type mappings to map abstract type names to C++ types
|
||
|
<node> | @ref settings_generator_elements_NodeContent | 0 - ∞ | General "node-like" elements, that can be inside any node-like element
|
||
|
|
||
|
@subsubsection settings_generator_elements_Include Include
|
||
|
Describes a file to be included via a c++ include directive. You can use them if you want to
|
||
|
make use of special classes in your generated classes. Both global includes (#include <header>)
|
||
|
and local includes (#include "header") are supported.<br/>
|
||
|
|
||
|
@paragraph settings_generator_elements_Include_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
--------|-------|-------------------|-------------
|
||
|
local | bool | false | Specifies whether the include is a global or a local include
|
||
|
|
||
|
@paragraph settings_generator_elements_Include_children Content
|
||
|
The content of this element must be a string. More specific the header to be included. It
|
||
|
becomes the content of the include directive. Specifiy it without the braces or quores, as thoes
|
||
|
are added automatically.
|
||
|
|
||
|
@subsubsection settings_generator_elements_Backend Backend
|
||
|
The backend element can be used to select a different QtMvvm::ISettingsAccessor instead of the
|
||
|
standard QtMvvm::QSettingsAccessor.
|
||
|
|
||
|
@paragraph settings_generator_elements_Backend_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
--------|-----------|-------------------|-------------
|
||
|
class | string | _required_ | The C++ class name of the backend to be used. Must be a class that implements QtMvvm::ISettingsAccessor
|
||
|
|
||
|
@paragraph settings_generator_elements_Backend_children Child elements
|
||
|
Name | XML-Type | Limits | Description
|
||
|
--------|-------------------------------------------|-----------|-------------
|
||
|
Param | @ref settings_generator_elements_Param | 0 - ∞ | A parameter to be passed to the backends constructor, before the QObject* parent
|
||
|
|
||
|
@subsubsection settings_generator_elements_Param Param
|
||
|
A generic parameter to be passed to C++ method.
|
||
|
|
||
|
@paragraph settings_generator_elements_Param_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
--------|-----------|-------------------|-------------
|
||
|
type | string | _required_ | The C++ class name of type of the parameter.
|
||
|
asStr | bool | false | Specify how the element content should be interpreted
|
||
|
|
||
|
@paragraph settings_generator_elements_Param_children Content
|
||
|
The content of a param represents the value of the parameter. How the content is interpreted
|
||
|
depends on the asStr attribute.
|
||
|
|
||
|
If it is set to false (the default), the content must be c++ code and is copied to the generated
|
||
|
class as is. The code must be an expression that evalutes to a single value that is implicitly
|
||
|
convertible to the given type. If type was for example int, valid expressions could be:
|
||
|
|
||
|
@code{.xml}
|
||
|
<Param type="int">-1</Param>
|
||
|
<Param type="int">10 + 20</Param>
|
||
|
<Param type="int">qRand()</Param>
|
||
|
@endcode
|
||
|
|
||
|
If set to true, the content is assumed to be a string. You don't need to specify quotation
|
||
|
marks around the string. That string is used to initialize a QVariant that is then converted to
|
||
|
type - in other words, the type you use must be variant convertible from a string. This can be
|
||
|
used to, for example, create a QDate from a string with the value of
|
||
|
`<Param type="QDate" asStr="true">2018-05-09</Param>`.<br/>
|
||
|
|
||
|
@subsubsection settings_generator_elements_Qml Qml
|
||
|
The Qml element contains special properties that are only used for QML binding generation.
|
||
|
|
||
|
@paragraph settings_generator_elements_Qml_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
------------|-------------------------------------------------------|-------------------|-------------
|
||
|
uri | string | _required_ | The QML-Import URI for the QML module
|
||
|
major | int | 1 | The major version of the generated module
|
||
|
minor | int | 0 | The minor version of the generated module
|
||
|
type | @ref settings_generator_values_QmlRegistrationMode | Singleton | The mode on how to register the instance in QML
|
||
|
register | bool | true | Specify, if the type should be registered automatically
|
||
|
header | string | _empty_ | A custom path to the generate C++-Code of the settings generator, if it can't be the default path
|
||
|
|
||
|
@subsubsection settings_generator_elements_TypeMapping TypeMapping
|
||
|
Type mappings allow you to specify the C++-type of an arbitrary type to be replaced by in the
|
||
|
generated code. This can be useful when importing a @ref settings_xml "Settings-XML" file.
|
||
|
|
||
|
@paragraph settings_generator_elements_TypeMapping_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
--------|-----------|-------------------|-------------
|
||
|
key | string | _required_ | The fake type name
|
||
|
type | string | _required_ | The C++-type to replace it with
|
||
|
|
||
|
@subsubsection settings_generator_elements_NodeContent NodeContent Elements
|
||
|
Elements that have the NodeContent as child type can have a combination of the following
|
||
|
actual child elements. Can can be unordered and mixed in any way:
|
||
|
|
||
|
- @ref settings_generator_elements_Node
|
||
|
- @ref settings_generator_elements_Entry
|
||
|
- @ref settings_generator_elements_ListNode
|
||
|
- @ref settings_generator_elements_Import
|
||
|
|
||
|
@subsubsection settings_generator_elements_Node Node
|
||
|
The node represents a sub-group within the settings. All elements within the node will have
|
||
|
the node's key prepended to their key (seperated by a `/`)
|
||
|
|
||
|
@paragraph settings_generator_elements_Node_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
--------|-----------|-------------------|-------------
|
||
|
key | string | _required_ | The name (and group key) of the node
|
||
|
|
||
|
@paragraph settings_generator_elements_Node_children Child elements
|
||
|
Name | XML-Type | Limits | Description
|
||
|
----------------|-----------------------------------------------|-----------|-------------
|
||
|
<node> | @ref settings_generator_elements_NodeContent | 0 - ∞ | General "node-like" elements, that can be inside any node-like element
|
||
|
|
||
|
@subsubsection settings_generator_elements_Entry Entry
|
||
|
The Entry element is an extension of the @ref settings_generator_elements_Node type. This
|
||
|
means it's the same as a Node, but with additional properties.
|
||
|
|
||
|
The entry represents a leaf entry in the settings, with a value that can be loaded and stored
|
||
|
from the settings via the entry's key (within the node subgroups). Entries themselves can also
|
||
|
be used as a node as well, and thus contain child elements, too.
|
||
|
|
||
|
The default value can be specified in 2 ways. Either as a string (via the attribute) that is
|
||
|
converted to the target type using QVariant, or via the `<Code>` child element, that contains
|
||
|
actual C++-Code that evaluates to a default value.
|
||
|
|
||
|
@sa QtMvvm::SettingsEntry
|
||
|
|
||
|
@paragraph settings_generator_elements_Entry_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
------------|-----------|-------------------|-------------
|
||
|
type | string | _required_ | The C++-type that this entry saves and loads. Can be a virtual type, that is resolved by a @ref settings_generator_elements_TypeMapping
|
||
|
qmlGroupKey | string | `<key>Group` | The name the property that holds the entries sub-nodes for the QML binding
|
||
|
default | string | _empty_ | A default value (as string) to be returned if the entry is not stored in the settings
|
||
|
tr | bool | false | Specify whether the default value should be translated
|
||
|
trContext | string | _filename_ | A custom translation context to use instead of the filename
|
||
|
|
||
|
@paragraph settings_generator_elements_Entry_children Additional Child elements
|
||
|
Name | XML-Type | Limits | Description
|
||
|
--------|---------------------------------------|-----------|-------------
|
||
|
Code | @ref settings_generator_elements_Code | 0 - 1 | C++-Code to create a default value
|
||
|
|
||
|
@subsubsection settings_generator_elements_ListNode ListNode
|
||
|
The ListNode element is an extension of the @ref settings_generator_elements_Node type. This
|
||
|
means it's the same as a Node, but with additional properties.
|
||
|
|
||
|
The ListNode is a special node that allows you to easily store lists of elements. All children
|
||
|
that are defined within a listnode are part of the "array elements", so you will access
|
||
|
elements in a list node via `listNode[2].group.entry` and can append and remove elements from
|
||
|
that list.
|
||
|
|
||
|
@sa QtMvvm::SettingsListNode
|
||
|
|
||
|
@subsubsection settings_generator_elements_ImportType ImportType
|
||
|
The Imports allow you to include other files within this one as sub elements. You can include
|
||
|
either a Settings-Generator-XML (this file) or a @ref settings_xml "Settings-XML". The
|
||
|
imported file is then treated like it's contents where simply defined instead of the import
|
||
|
element, allowing seemless combination of different files.
|
||
|
|
||
|
You can use the rootNode to instead of importing the root element in the importet file, go
|
||
|
down to the node that matches the key defined by rootNode and only import that part.
|
||
|
|
||
|
@paragraph settings_generator_elements_ImportType_attributes Attributes
|
||
|
Name | Type | Default/Required | Description
|
||
|
------------|-----------|-------------------|-------------
|
||
|
required | bool | true | Specify, if the import is required or optional
|
||
|
rootNode | string | _empty_ | A root node withing the imported file to use as a starting point
|
||
|
|
||
|
@paragraph settings_generator_elements_ImportType_children Content
|
||
|
The content of the element is a string - the path to the file to be imported. If the path is
|
||
|
a relative path, it is resolved relative to the file that is importing it, aka "this" file.
|
||
|
|
||
|
@subsection settings_generator_values XML-Types
|
||
|
The XML-Types are not elements, but values of attributes etc. that have been defined for the
|
||
|
file.
|
||
|
|
||
|
@subsubsection settings_generator_values_InstanceScope InstanceScope
|
||
|
InstanceScope is a simple enum with the following allowed values:
|
||
|
|
||
|
Name | Description
|
||
|
----------------------------|-------------
|
||
|
DestroyOnAppQuit | Sets the scope of the created mvvm service to QtMvvm::ServiceRegistry::DestroyOnAppQuit
|
||
|
DestroyOnAppDestroy | Sets the scope of the created mvvm service to QtMvvm::ServiceRegistry::DestroyOnAppDestroy
|
||
|
DestroyOnRegistryDestroy | Sets the scope of the created mvvm service to QtMvvm::ServiceRegistry::DestroyOnRegistryDestroy
|
||
|
DestroyNever | Sets the scope of the created mvvm service to QtMvvm::ServiceRegistry::DestroyNever
|
||
|
|
||
|
@subsubsection settings_generator_values_QmlRegistrationMode QmlRegistrationMode
|
||
|
InstanceScope is a simple enum with the following allowed values:
|
||
|
|
||
|
Name | Description
|
||
|
----------------|-------------
|
||
|
Singleton | Register the QML type as a singleton instance
|
||
|
Uncreatable | Register the QML type as a uncreatable type
|
||
|
Creatable | Register the QML type as a normal, constructable type
|
||
|
|
||
|
@section settings_generator_sample Sample settings generator XML file
|
||
|
The following code block is a sample of a settings generator XML file. It's a little bigger to
|
||
|
show of the capabilities
|
||
|
|
||
|
@include generatortest.xml
|
||
|
|
||
|
@section settings_xml_xsd 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.
|
||
|
|
||
|
@include qsettingsgenerator.xsd
|
||
|
*/
|