11 changed files with 642 additions and 522 deletions
			
			
		@ -0,0 +1,231 @@ | 
				
			|||
#include "cppsettingsgenerator.h" | 
				
			|||
#include <QFileInfo> | 
				
			|||
 | 
				
			|||
#define TABS QString{QLatin1Char('\t')}.repeated(intendent) | 
				
			|||
 | 
				
			|||
CppSettingsGenerator::CppSettingsGenerator(const QString &hdrPath, const QString &srcPath) : | 
				
			|||
	_hdrFile{hdrPath}, | 
				
			|||
	_srcFile{srcPath}, | 
				
			|||
	_hdr{&_hdrFile}, | 
				
			|||
	_src{&_srcFile} | 
				
			|||
{} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::process(const QString &inPath) | 
				
			|||
{ | 
				
			|||
	// read settings and adjust defaults
 | 
				
			|||
	auto settings = readDocument(inPath); | 
				
			|||
	if(!settings.name) | 
				
			|||
		settings.name = QFileInfo{inPath}.baseName(); | 
				
			|||
	fixTrContext(settings, QFileInfo{inPath}.fileName()); | 
				
			|||
 | 
				
			|||
	if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) | 
				
			|||
		throw FileException{_hdrFile}; | 
				
			|||
	writeHeader(settings); | 
				
			|||
	_hdrFile.close(); | 
				
			|||
 | 
				
			|||
	if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) | 
				
			|||
		throw FileException{_srcFile}; | 
				
			|||
	writeSource(settings); | 
				
			|||
	_srcFile.close(); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeHeader(const SettingsType &settings) | 
				
			|||
{ | 
				
			|||
	QString incGuard = QFileInfo{_hdrFile.fileName()} | 
				
			|||
					   .completeBaseName() | 
				
			|||
					   .replace(QLatin1Char('.'), QLatin1Char('_')) | 
				
			|||
					   .toUpper() + QStringLiteral("_H"); | 
				
			|||
	_hdr << "#ifndef " << incGuard << '\n' | 
				
			|||
		 << "#define " << incGuard << "\n\n"; | 
				
			|||
 | 
				
			|||
	// write the includes
 | 
				
			|||
	auto includes = QList<IncludeType> { | 
				
			|||
		{false, QStringLiteral("QtCore/QObject")}, | 
				
			|||
		{false, QStringLiteral("QtMvvmCore/ISettingsAccessor")}, | 
				
			|||
		{false, QStringLiteral("QtMvvmCore/SettingsEntry")} | 
				
			|||
	} + settings.includes; | 
				
			|||
	for(const auto &inc : includes) { | 
				
			|||
		if(inc.local) | 
				
			|||
			_hdr << "#include \"" << inc.includePath << "\"\n"; | 
				
			|||
		else | 
				
			|||
			_hdr << "#include <" << inc.includePath << ">\n"; | 
				
			|||
	} | 
				
			|||
	_hdr << "\n"; | 
				
			|||
 | 
				
			|||
	// create the class
 | 
				
			|||
	_hdr << "class " << QString{settings.prefix ? settings.prefix.value() + QLatin1Char(' ') + settings.name.value() : settings.name.value()} << " : public QObject\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\tQ_OBJECT\n\n" | 
				
			|||
		 << "\tQ_PROPERTY(QtMvvm::ISettingsAccessor *accessor READ accessor CONSTANT FINAL)\n\n" | 
				
			|||
		 << "public:\n" | 
				
			|||
		 << "\tQ_INVOKABLE explicit " << settings.name.value() << "(QObject *parent = nullptr);\n" | 
				
			|||
		 << "\texplicit " << settings.name.value() << "(QtMvvm::ISettingsAccessor *accessor, QObject *parent);\n\n" | 
				
			|||
		 << "\tstatic " << settings.name.value() << " *instance();\n\n" | 
				
			|||
		 << "\tQtMvvm::ISettingsAccessor *accessor() const;\n\n"; | 
				
			|||
 | 
				
			|||
	writeNodeElementDeclarations(settings, settings.typeMappings); | 
				
			|||
 | 
				
			|||
	_hdr << "\nprivate:\n" | 
				
			|||
		 << "\tQtMvvm::ISettingsAccessor *_accessor;\n" | 
				
			|||
		 << "};\n\n" | 
				
			|||
		 << "#endif //" << incGuard << '\n'; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeNodeElementDeclarations(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	for(const auto &cNode : node.contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) | 
				
			|||
			writeNodeDeclaration(nonstd::get<NodeType>(cNode), typeMappings, intendent); | 
				
			|||
		else if(nonstd::holds_alternative<EntryType>(cNode)) | 
				
			|||
			writeEntryDeclaration(nonstd::get<EntryType>(cNode), typeMappings, intendent); | 
				
			|||
		else if(nonstd::holds_alternative<ListEntryType>(cNode)) | 
				
			|||
			writeListEntryDeclaration(nonstd::get<ListEntryType>(cNode), typeMappings, intendent); | 
				
			|||
		else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) | 
				
			|||
			writeNodeElementDeclarations(nonstd::get<NodeContentGroup>(cNode), typeMappings, intendent); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	_hdr << TABS << "struct { //" << node.key << "\n"; | 
				
			|||
	writeNodeElementDeclarations(node, typeMappings, intendent + 1); | 
				
			|||
	_hdr << TABS << "} " << node.key << ";\n"; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeEntryDeclaration(const EntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	if(entry.contentNodes.isEmpty()) | 
				
			|||
		_hdr << TABS << "QtMvvm::SettingsEntry<" << typeMappings.value(entry.type, entry.type) << "> " << entry.key << ";\n"; | 
				
			|||
	else { | 
				
			|||
		const auto &mType = typeMappings.value(entry.type, entry.type); | 
				
			|||
		_hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n"; | 
				
			|||
		writeNodeElementDeclarations(entry, typeMappings, intendent + 1); | 
				
			|||
		_hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "} " << entry.key << ";\n"; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeListEntryDeclaration(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	if(entry.contentNodes.isEmpty()) | 
				
			|||
		_hdr << TABS << "QtMvvm::SettingsEntry<QList<" << typeMappings.value(entry.type, entry.type) << ">> " << entry.key << ";\n"; | 
				
			|||
	else { | 
				
			|||
		const QString mType = QStringLiteral("QList<") + typeMappings.value(entry.type, entry.type) + QLatin1Char('>'); | 
				
			|||
		_hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n"; | 
				
			|||
		writeNodeElementDeclarations(entry, typeMappings, intendent + 1); | 
				
			|||
		_hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "\tinline auto &operator+=(const " << typeMappings.value(entry.type, entry.type) << " &__value) { SettingsEntry<" << mType << ">::operator+=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "\tinline auto &operator+=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator+=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "} " << entry.key << ";\n"; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeSource(const SettingsType &settings) | 
				
			|||
{ | 
				
			|||
	_src << "#include \"" << _hdrFile.fileName() << "\"\n"; | 
				
			|||
	_src << "#include <QtCore/QCoreApplication>\n"; | 
				
			|||
	_src << "#include <QtMvvmCore/ServiceRegistry>\n"; | 
				
			|||
	if(!settings.backend) | 
				
			|||
		_src << "#include <QtMvvmCore/QSettingsAccessor>\n"; | 
				
			|||
	_src << "\n"; | 
				
			|||
 | 
				
			|||
	auto backend = settings.backend.value_or(BackendType{QStringLiteral("QtMvvm::QSettingsAccessor"), {}, {}}); | 
				
			|||
 | 
				
			|||
	_src << "namespace {\n\n" | 
				
			|||
		 << "void __generated_settings_setup()\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\tQtMvvm::ServiceRegistry::instance()->registerObject<" << settings.name.value() << ">("; | 
				
			|||
	if(backend.scope) | 
				
			|||
		_src << "QtMvvm::ServiceRegistry::" << backend.scope.value(); | 
				
			|||
	_src << ");\n" | 
				
			|||
		 << "}\n\n" | 
				
			|||
		 << "}\n" | 
				
			|||
		 << "Q_COREAPP_STARTUP_FUNCTION(__generated_settings_setup)\n\n"; | 
				
			|||
 | 
				
			|||
	_src << settings.name.value() << "::" << settings.name.value() << "(QObject *parent) : \n" | 
				
			|||
		 << "\t" << settings.name.value() << "{new " << backend.className << "{"; | 
				
			|||
	if(!backend.param.isEmpty()) { | 
				
			|||
		_src << "\n"; | 
				
			|||
		auto first = true; | 
				
			|||
		for(const auto ¶m : qAsConst(backend.param)) { | 
				
			|||
			if(first) | 
				
			|||
				first = false; | 
				
			|||
			else | 
				
			|||
				_src << ",\n"; | 
				
			|||
			_src << "\t\tQVariant{"; | 
				
			|||
			if(param.asStr) | 
				
			|||
				_src << "QStringLiteral(\"" << param.value << "\")"; | 
				
			|||
			else | 
				
			|||
				_src << param.value; | 
				
			|||
			_src << "}.value<" << param.type << ">()"; | 
				
			|||
		} | 
				
			|||
		_src << "\n\t"; | 
				
			|||
	} | 
				
			|||
	_src << "}, parent}\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\t_accessor->setParent(this);\n" | 
				
			|||
		 << "}\n\n"; | 
				
			|||
 | 
				
			|||
	_src << settings.name.value() << "::" << settings.name.value() << "(QtMvvm::ISettingsAccessor *accessor, QObject *parent) : \n" | 
				
			|||
		 << "\tQObject{parent},\n" | 
				
			|||
		 << "\t_accessor{accessor}\n" | 
				
			|||
		 << "{\n"; | 
				
			|||
	writeNodeElementDefinitions(settings, settings.typeMappings, settings.baseKey); | 
				
			|||
	_src << "}\n\n"; | 
				
			|||
 | 
				
			|||
	_src << settings.name.value() << " *" << settings.name.value() << "::instance()\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\treturn QtMvvm::ServiceRegistry::instance()->service<" << settings.name.value() << ">();\n" | 
				
			|||
		 << "}\n\n"; | 
				
			|||
 | 
				
			|||
	_src << "QtMvvm::ISettingsAccessor *" << settings.name.value() << "::accessor() const\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\treturn _accessor;\n" | 
				
			|||
		 << "}\n\n"; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeNodeElementDefinitions(const SettingsGeneratorBase::NodeContentGroup &node, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, const QStringList &keyChain) | 
				
			|||
{ | 
				
			|||
	for(const auto &cNode : node.contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) { | 
				
			|||
			const auto &xNode = nonstd::get<NodeType>(cNode); | 
				
			|||
			writeNodeElementDefinitions(xNode, typeMappings, baseKey, QStringList{keyChain} << xNode.key); | 
				
			|||
		} else if(nonstd::holds_alternative<EntryType>(cNode)) | 
				
			|||
			writeEntryDefinition(nonstd::get<EntryType>(cNode), typeMappings, baseKey, keyChain); | 
				
			|||
		else if(nonstd::holds_alternative<ListEntryType>(cNode)) | 
				
			|||
			writeListEntryDefinition(nonstd::get<ListEntryType>(cNode), typeMappings, baseKey, keyChain); | 
				
			|||
		else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) | 
				
			|||
			writeNodeElementDefinitions(nonstd::get<NodeContentGroup>(cNode), typeMappings, baseKey, keyChain); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeEntryDefinition(const SettingsGeneratorBase::EntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain, bool skipChildren) | 
				
			|||
{ | 
				
			|||
	keyChain.append(entry.key); | 
				
			|||
	_src << "\t" << keyChain.join(QLatin1Char('.')) | 
				
			|||
		 << ".setup(QStringLiteral(\"" << (baseKey ? QStringList{baseKey.value()} + keyChain : keyChain).join(QLatin1Char('/')) << "\"), _accessor"; | 
				
			|||
	if(entry.code) | 
				
			|||
		_src << ", QVariant::fromValue<" << typeMappings.value(entry.type, entry.type) << ">(" << entry.code.value().trimmed() << ")"; | 
				
			|||
	else if(entry.defaultValue) { | 
				
			|||
		_src << ", QVariant{"; | 
				
			|||
		if(entry.tr) | 
				
			|||
			_src << "QCoreApplication::translate(\"" << entry.trContext.value() << "\", \"" << entry.defaultValue.value() << "\")"; | 
				
			|||
		else | 
				
			|||
			_src << "QStringLiteral(\"" << entry.defaultValue.value() << "\")"; | 
				
			|||
		_src << "}.value<" << typeMappings.value(entry.type, entry.type) << ">()"; | 
				
			|||
	} | 
				
			|||
	_src << ");\n"; | 
				
			|||
	if(!skipChildren) | 
				
			|||
		writeNodeElementDefinitions(entry, typeMappings, baseKey, keyChain); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void CppSettingsGenerator::writeListEntryDefinition(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain) | 
				
			|||
{ | 
				
			|||
	writeEntryDefinition(entry, typeMappings, baseKey, keyChain, entry.init.has_value()); | 
				
			|||
	if(entry.init) { | 
				
			|||
		keyChain.append(entry.key); | 
				
			|||
		_src << "\t" << keyChain.join(QLatin1Char('.')) << ".setupInit(" << entry.init.value().trimmed() << ");\n"; | 
				
			|||
		writeNodeElementDefinitions(entry, typeMappings, baseKey, keyChain); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@ -0,0 +1,33 @@ | 
				
			|||
#ifndef CPPSETTINGSGENERATOR_H | 
				
			|||
#define CPPSETTINGSGENERATOR_H | 
				
			|||
 | 
				
			|||
#include "settingsgeneratorimpl.h" | 
				
			|||
 | 
				
			|||
class CppSettingsGenerator : public SettingsGeneratorImpl | 
				
			|||
{ | 
				
			|||
public: | 
				
			|||
	CppSettingsGenerator(const QString &hdrPath, | 
				
			|||
						 const QString &srcPath); | 
				
			|||
 | 
				
			|||
	void process(const QString &inPath); | 
				
			|||
 | 
				
			|||
private: | 
				
			|||
	QFile _hdrFile; | 
				
			|||
	QFile _srcFile; | 
				
			|||
 | 
				
			|||
	QTextStream _hdr; | 
				
			|||
	QTextStream _src; | 
				
			|||
 | 
				
			|||
	void writeHeader(const SettingsType &settings); | 
				
			|||
	void writeNodeElementDeclarations(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
	void writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
	void writeEntryDeclaration(const EntryType &entry, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
	void writeListEntryDeclaration(const ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
 | 
				
			|||
	void writeSource(const SettingsType &settings); | 
				
			|||
	void writeNodeElementDefinitions(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, const QStringList &keyChain = {}); | 
				
			|||
	void writeEntryDefinition(const EntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain, bool skipChildren = false); | 
				
			|||
	void writeListEntryDefinition(const ListEntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
#endif // CPPSETTINGSGENERATOR_H
 | 
				
			|||
@ -0,0 +1,74 @@ | 
				
			|||
#include "qmlsettingsgenerator.h" | 
				
			|||
#include <QFileInfo> | 
				
			|||
 | 
				
			|||
QmlSettingsGenerator::QmlSettingsGenerator(const QString &hdrPath, const QString &srcPath) : | 
				
			|||
	_hdrFile{hdrPath}, | 
				
			|||
	_srcFile{srcPath}, | 
				
			|||
	_hdr{&_hdrFile}, | 
				
			|||
	_src{&_srcFile} | 
				
			|||
{} | 
				
			|||
 | 
				
			|||
void QmlSettingsGenerator::process(const QString &inPath) | 
				
			|||
{ | 
				
			|||
	// read settings and adjust defaults
 | 
				
			|||
	auto settings = readDocument(inPath); | 
				
			|||
	if(!settings.name) | 
				
			|||
		settings.name = QFileInfo{inPath}.baseName(); | 
				
			|||
	settings.name.value().prepend(QStringLiteral("QMLTYPE_")); | 
				
			|||
	fixTrContext(settings, QFileInfo{inPath}.fileName()); | 
				
			|||
 | 
				
			|||
	if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) | 
				
			|||
		throw FileException{_hdrFile}; | 
				
			|||
	writeHeader(settings); | 
				
			|||
	_hdrFile.close(); | 
				
			|||
 | 
				
			|||
	if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) | 
				
			|||
		throw FileException{_srcFile}; | 
				
			|||
	writeSource(settings); | 
				
			|||
	_srcFile.close(); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void QmlSettingsGenerator::writeHeader(const SettingsGeneratorBase::SettingsType &settings) | 
				
			|||
{ | 
				
			|||
	QString incGuard = QFileInfo{_hdrFile.fileName()} | 
				
			|||
					   .completeBaseName() | 
				
			|||
					   .replace(QLatin1Char('.'), QLatin1Char('_')) | 
				
			|||
					   .toUpper() + QStringLiteral("_H"); | 
				
			|||
	_hdr << "#ifndef " << incGuard << '\n' | 
				
			|||
		 << "#define " << incGuard << "\n\n"; | 
				
			|||
 | 
				
			|||
	// write the includes
 | 
				
			|||
	auto includes = QList<IncludeType> { | 
				
			|||
		{false, QStringLiteral("QtCore/QObject")}, | 
				
			|||
		{false, QStringLiteral("QtQml/QQmlListProperty")}, | 
				
			|||
		{false, QStringLiteral("QtMvvmCore/ISettingsAccessor")} | 
				
			|||
	} + settings.includes; | 
				
			|||
	for(const auto &inc : includes) { | 
				
			|||
		if(inc.local) | 
				
			|||
			_hdr << "#include \"" << inc.includePath << "\"\n"; | 
				
			|||
		else | 
				
			|||
			_hdr << "#include <" << inc.includePath << ">\n"; | 
				
			|||
	} | 
				
			|||
	_hdr << "\n"; | 
				
			|||
 | 
				
			|||
	// create the class
 | 
				
			|||
	_hdr << "class " << QString{settings.prefix ? settings.prefix.value() + QLatin1Char(' ') + settings.name.value() : settings.name.value()} << " : public QObject\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\tQ_OBJECT\n\n" | 
				
			|||
		 << "\tQ_PROPERTY(QtMvvm::ISettingsAccessor *accessor READ accessor CONSTANT FINAL)\n\n" | 
				
			|||
		 << "public:\n" | 
				
			|||
		 << "\texplicit " << settings.name.value() << "(QObject *parent = nullptr);\n" | 
				
			|||
		 << "\tQtMvvm::ISettingsAccessor *accessor() const;\n\n"; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
 | 
				
			|||
	_hdr << "\nprivate:\n" | 
				
			|||
		 << "\tQtMvvm::ISettingsAccessor *_accessor;\n" | 
				
			|||
		 << "};\n\n" | 
				
			|||
		 << "#endif //" << incGuard << '\n'; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void QmlSettingsGenerator::writeSource(const SettingsGeneratorBase::SettingsType &settings) | 
				
			|||
{ | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -0,0 +1,25 @@ | 
				
			|||
#ifndef QMLSETTINGSGENERATOR_H | 
				
			|||
#define QMLSETTINGSGENERATOR_H | 
				
			|||
 | 
				
			|||
#include "settingsgeneratorimpl.h" | 
				
			|||
 | 
				
			|||
class QmlSettingsGenerator : public SettingsGeneratorImpl | 
				
			|||
{ | 
				
			|||
public: | 
				
			|||
	QmlSettingsGenerator(const QString &hdrPath, | 
				
			|||
						 const QString &srcPath); | 
				
			|||
 | 
				
			|||
	void process(const QString &inPath); | 
				
			|||
 | 
				
			|||
	void writeHeader(const SettingsType &settings); | 
				
			|||
	void writeSource(const SettingsType &settings); | 
				
			|||
 | 
				
			|||
private: | 
				
			|||
	QFile _hdrFile; | 
				
			|||
	QFile _srcFile; | 
				
			|||
 | 
				
			|||
	QTextStream _hdr; | 
				
			|||
	QTextStream _src; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
#endif // QMLSETTINGSGENERATOR_H
 | 
				
			|||
@ -1,458 +0,0 @@ | 
				
			|||
#include "settingsgenerator.h" | 
				
			|||
#include <QDebug> | 
				
			|||
#include <QFileInfo> | 
				
			|||
#include <QDir> | 
				
			|||
 | 
				
			|||
#define TABS QString{QLatin1Char('\t')}.repeated(intendent) | 
				
			|||
 | 
				
			|||
SettingsGenerator::SettingsGenerator(const QString &hdrPath, const QString &srcPath) : | 
				
			|||
	_hdrFile{hdrPath}, | 
				
			|||
	_srcFile{srcPath}, | 
				
			|||
	_hdr{&_hdrFile}, | 
				
			|||
	_src{&_srcFile} | 
				
			|||
{} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::process(const QString &inPath) | 
				
			|||
{ | 
				
			|||
	// read settings and adjust defaults
 | 
				
			|||
	auto settings = readDocument(inPath); | 
				
			|||
	if(!settings.name) | 
				
			|||
		settings.name = QFileInfo{inPath}.baseName(); | 
				
			|||
	fixTrContext(settings, QFileInfo{inPath}.fileName()); | 
				
			|||
 | 
				
			|||
	if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) | 
				
			|||
		throw FileException{_hdrFile}; | 
				
			|||
	writeHeader(settings); | 
				
			|||
	_hdrFile.close(); | 
				
			|||
 | 
				
			|||
	if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) | 
				
			|||
		throw FileException{_srcFile}; | 
				
			|||
	writeSource(settings); | 
				
			|||
	_srcFile.close(); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::processQml(const QString &inPath) | 
				
			|||
{ | 
				
			|||
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
bool SettingsGenerator::read_type_mapping(QXmlStreamReader &reader, QHash<QString, QString> &data, bool hasNext) | 
				
			|||
{ | 
				
			|||
	TypeMappingGroup grp; | 
				
			|||
	hasNext = read_TypeMappingGroup(reader, grp, hasNext); | 
				
			|||
	for(const auto &mapping : qAsConst(grp.typeMapping)) | 
				
			|||
		data.insert(mapping.key, mapping.type); | 
				
			|||
	return hasNext; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::read_included_file(QXmlStreamReader &reader, NodeContentGroup &data) | 
				
			|||
{ | 
				
			|||
	ImportType import; | 
				
			|||
	read_ImportType(reader, import); | 
				
			|||
 | 
				
			|||
	//make the path relative if possbile
 | 
				
			|||
	if(dynamic_cast<QFileDevice*>(reader.device())) { | 
				
			|||
		QFileInfo docInfo{static_cast<QFileDevice*>(reader.device())->fileName()}; | 
				
			|||
		import.importPath = docInfo.dir().absoluteFilePath(import.importPath); | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	// read the document
 | 
				
			|||
	try { | 
				
			|||
		QFile xmlFile{import.importPath}; | 
				
			|||
		if(!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) | 
				
			|||
			throw FileException{xmlFile}; | 
				
			|||
 | 
				
			|||
		QXmlStreamReader subReader{&xmlFile}; | 
				
			|||
		if(!subReader.readNextStartElement()) | 
				
			|||
			throw XmlException{subReader}; | 
				
			|||
 | 
				
			|||
		SettingsType settings; | 
				
			|||
		if(subReader.name() == QStringLiteral("Settings")) { | 
				
			|||
			read_SettingsType(subReader, settings); | 
				
			|||
		} else if(subReader.name() == QStringLiteral("SettingsConfig")) { | 
				
			|||
			SettingsConfigImpl confReader; | 
				
			|||
			SettingsConfigBase::SettingsConfigType settingsConf; | 
				
			|||
			confReader.read_SettingsConfigType(subReader, settingsConf); | 
				
			|||
			convertFromConf(reader, settingsConf, settings); | 
				
			|||
		} else | 
				
			|||
			throwChild(subReader); | 
				
			|||
 | 
				
			|||
		NodeContentGroup *cGrp = &settings; | 
				
			|||
		if(import.rootNode) { | 
				
			|||
			for(const auto &key : import.rootNode.value().split(QLatin1Char('/'), QString::SkipEmptyParts)) { | 
				
			|||
				cGrp = findContentGroup(cGrp, key); | 
				
			|||
				if(!cGrp) | 
				
			|||
					return; | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
 | 
				
			|||
		data = std::move(*cGrp); | 
				
			|||
		fixTrContext(data, QFileInfo{import.importPath}.fileName()); | 
				
			|||
	} catch(FileException &e) { | 
				
			|||
		if(import.required) | 
				
			|||
			throw; | 
				
			|||
		else { | 
				
			|||
			qWarning() << e.what(); | 
				
			|||
			return; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::convertFromConf(QXmlStreamReader &reader, SettingsConfigBase::SettingsConfigType &conf, SettingsType &data) | 
				
			|||
{ | 
				
			|||
	for(auto &element : conf.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::CategoryType>(element)) | 
				
			|||
			readCategory(reader, nonstd::get<SettingsConfigBase::CategoryType>(element), data); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::SectionType>(element)) | 
				
			|||
			readSection(reader, nonstd::get<SettingsConfigBase::SectionType>(element), data); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::GroupType>(element)) | 
				
			|||
			readGroup(reader, nonstd::get<SettingsConfigBase::GroupType>(element), data); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), data); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::readCategory(QXmlStreamReader &reader, SettingsConfigBase::CategoryContentGroup &content, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	for(auto &element : content.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::SectionType>(element)) | 
				
			|||
			readSection(reader, nonstd::get<SettingsConfigBase::SectionType>(element), targetRootNode); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::GroupType>(element)) | 
				
			|||
			readGroup(reader, nonstd::get<SettingsConfigBase::GroupType>(element), targetRootNode); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), targetRootNode); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf Categoy")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::readSection(QXmlStreamReader &reader, SettingsConfigBase::SectionContentGroup &content, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	for(auto &element : content.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::GroupType>(element)) | 
				
			|||
			readGroup(reader, nonstd::get<SettingsConfigBase::GroupType>(element), targetRootNode); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), targetRootNode); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf Section")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::readGroup(QXmlStreamReader &reader, SettingsConfigBase::GroupContentGroup &content, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	for(auto &element : content.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), targetRootNode); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf Group")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::readEntry(QXmlStreamReader &reader, SettingsConfigBase::EntryType &entry, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	auto keyChain = entry.key.split(QLatin1Char('/'), QString::SkipEmptyParts); | 
				
			|||
	auto entryKey = keyChain.takeLast(); | 
				
			|||
 | 
				
			|||
	auto cGrp = &targetRootNode; | 
				
			|||
	for(const auto &key : keyChain) { | 
				
			|||
		auto nGrp = findContentGroup(cGrp, key); | 
				
			|||
		if(!nGrp) { | 
				
			|||
			NodeType nNode; | 
				
			|||
			nNode.key = key; | 
				
			|||
			cGrp->contentNodes.append(std::move(nNode)); | 
				
			|||
			nGrp = &(nonstd::get<NodeType>(cGrp->contentNodes.last())); | 
				
			|||
		} | 
				
			|||
		cGrp = nGrp; | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	auto isEntry = false; | 
				
			|||
	auto eGrp = findContentGroup(cGrp, entryKey, &isEntry); | 
				
			|||
	if(!eGrp) { | 
				
			|||
		EntryType nEntry; | 
				
			|||
		nEntry.key = entryKey; | 
				
			|||
		cGrp->contentNodes.append(std::move(nEntry)); | 
				
			|||
		eGrp = &(nonstd::get<EntryType>(cGrp->contentNodes.last())); | 
				
			|||
	} else if(!isEntry) { | 
				
			|||
		EntryType nEntry; | 
				
			|||
		nEntry.key = entryKey; | 
				
			|||
		nEntry.contentNodes = std::move(eGrp->contentNodes); | 
				
			|||
		eGrp = replaceNodeByEntry(cGrp, eGrp, nEntry); | 
				
			|||
		Q_ASSERT(eGrp); | 
				
			|||
	} else | 
				
			|||
		throw XmlException{reader, QStringLiteral("Found duplicated entry with key: %1").arg(entry.key)}; | 
				
			|||
 | 
				
			|||
	auto nEntry = static_cast<EntryType*>(eGrp); | 
				
			|||
	nEntry->type = std::move(entry.type); | 
				
			|||
	nEntry->defaultValue = std::move(entry.defaultValue); | 
				
			|||
	nEntry->tr = entry.trdefault; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
SettingsGeneratorBase::NodeContentGroup *SettingsGenerator::findContentGroup(SettingsGeneratorBase::NodeContentGroup *cGrp, const QString &key, bool *isEntry) | 
				
			|||
{ | 
				
			|||
	if(isEntry) | 
				
			|||
		*isEntry = false; | 
				
			|||
	for(auto &cNode : cGrp->contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) { | 
				
			|||
			if(nonstd::get<NodeType>(cNode).key == key) | 
				
			|||
				return &(nonstd::get<NodeType>(cNode)); | 
				
			|||
		} else if(nonstd::holds_alternative<EntryType>(cNode)) { | 
				
			|||
			if(nonstd::get<EntryType>(cNode).key == key) { | 
				
			|||
				if(isEntry) | 
				
			|||
					*isEntry = true; | 
				
			|||
				return &(nonstd::get<EntryType>(cNode)); | 
				
			|||
			} | 
				
			|||
		} else if(nonstd::holds_alternative<ListEntryType>(cNode)) { | 
				
			|||
			if(nonstd::get<ListEntryType>(cNode).key == key) { | 
				
			|||
				if(isEntry) | 
				
			|||
					*isEntry = true; | 
				
			|||
				return &(nonstd::get<ListEntryType>(cNode)); | 
				
			|||
			} | 
				
			|||
		} else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) { | 
				
			|||
			auto res = findContentGroup(&(nonstd::get<NodeContentGroup>(cNode)), key); | 
				
			|||
			if(res) | 
				
			|||
				return res; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return nullptr; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
SettingsGeneratorBase::NodeContentGroup *SettingsGenerator::replaceNodeByEntry(SettingsGeneratorBase::NodeContentGroup *cGrp, NodeContentGroup *node, SettingsGeneratorBase::EntryType &entry) | 
				
			|||
{ | 
				
			|||
	for(auto &cNode : cGrp->contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) { | 
				
			|||
			if(&nonstd::get<NodeType>(cNode) == node) { | 
				
			|||
				cNode = std::move(entry); | 
				
			|||
				return &(nonstd::get<EntryType>(cNode)); | 
				
			|||
			} | 
				
			|||
		} else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) { | 
				
			|||
			auto res = replaceNodeByEntry(&(nonstd::get<NodeContentGroup>(cNode)), node, entry); | 
				
			|||
			if(res) | 
				
			|||
				return res; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return nullptr; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::fixTrContext(NodeContentGroup &group, const QString &context) | 
				
			|||
{ | 
				
			|||
	for(auto &node : group.contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(node)) | 
				
			|||
			fixTrContext(nonstd::get<NodeType>(node), context); | 
				
			|||
		else if(nonstd::holds_alternative<EntryType>(node)) { | 
				
			|||
			auto &entry = nonstd::get<EntryType>(node); | 
				
			|||
			if(!entry.trContext) | 
				
			|||
				entry.trContext = context; | 
				
			|||
			fixTrContext(entry, context); | 
				
			|||
		} else if(nonstd::holds_alternative<ListEntryType>(node)) { | 
				
			|||
			auto &entry = nonstd::get<ListEntryType>(node); | 
				
			|||
			if(!entry.trContext) | 
				
			|||
				entry.trContext = context; | 
				
			|||
			fixTrContext(entry, context); | 
				
			|||
		} else if(nonstd::holds_alternative<NodeContentGroup>(node)) | 
				
			|||
			fixTrContext(nonstd::get<NodeContentGroup>(node), context); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeHeader(const SettingsType &settings) | 
				
			|||
{ | 
				
			|||
	QString incGuard = QFileInfo{_hdrFile.fileName()} | 
				
			|||
					   .completeBaseName() | 
				
			|||
					   .replace(QLatin1Char('.'), QLatin1Char('_')) | 
				
			|||
					   .toUpper() + QStringLiteral("_H"); | 
				
			|||
	_hdr << "#ifndef " << incGuard << '\n' | 
				
			|||
		 << "#define " << incGuard << "\n\n"; | 
				
			|||
 | 
				
			|||
	// write the includes
 | 
				
			|||
	auto includes = QList<IncludeType> { | 
				
			|||
		{false, QStringLiteral("QtCore/QObject")}, | 
				
			|||
		{false, QStringLiteral("QtMvvmCore/ISettingsAccessor")}, | 
				
			|||
		{false, QStringLiteral("QtMvvmCore/SettingsEntry")} | 
				
			|||
	} + settings.includes; | 
				
			|||
	for(const auto &inc : includes) { | 
				
			|||
		if(inc.local) | 
				
			|||
			_hdr << "#include \"" << inc.includePath << "\"\n"; | 
				
			|||
		else | 
				
			|||
			_hdr << "#include <" << inc.includePath << ">\n"; | 
				
			|||
	} | 
				
			|||
	_hdr << "\n"; | 
				
			|||
 | 
				
			|||
	// create the class
 | 
				
			|||
	_hdr << "class " << QString{settings.prefix ? settings.prefix.value() + QLatin1Char(' ') + settings.name.value() : settings.name.value()} << " : public QObject\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\tQ_OBJECT\n\n" | 
				
			|||
		 << "\tQ_PROPERTY(QtMvvm::ISettingsAccessor *accessor READ accessor CONSTANT FINAL)\n\n" | 
				
			|||
		 << "public:\n" | 
				
			|||
		 << "\tQ_INVOKABLE explicit " << settings.name.value() << "(QObject *parent = nullptr);\n" | 
				
			|||
		 << "\texplicit " << settings.name.value() << "(QtMvvm::ISettingsAccessor *accessor, QObject *parent);\n\n" | 
				
			|||
		 << "\tstatic " << settings.name.value() << " *instance();\n\n" | 
				
			|||
		 << "\tQtMvvm::ISettingsAccessor *accessor() const;\n\n"; | 
				
			|||
 | 
				
			|||
	writeNodeElementDeclarations(settings, settings.typeMappings); | 
				
			|||
 | 
				
			|||
	_hdr << "\nprivate:\n" | 
				
			|||
		 << "\tQtMvvm::ISettingsAccessor *_accessor;\n" | 
				
			|||
		 << "};\n\n" | 
				
			|||
		 << "#endif //" << incGuard << '\n'; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeNodeElementDeclarations(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	for(const auto &cNode : node.contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) | 
				
			|||
			writeNodeDeclaration(nonstd::get<NodeType>(cNode), typeMappings, intendent); | 
				
			|||
		else if(nonstd::holds_alternative<EntryType>(cNode)) | 
				
			|||
			writeEntryDeclaration(nonstd::get<EntryType>(cNode), typeMappings, intendent); | 
				
			|||
		else if(nonstd::holds_alternative<ListEntryType>(cNode)) | 
				
			|||
			writeListEntryDeclaration(nonstd::get<ListEntryType>(cNode), typeMappings, intendent); | 
				
			|||
		else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) | 
				
			|||
			writeNodeElementDeclarations(nonstd::get<NodeContentGroup>(cNode), typeMappings, intendent); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	_hdr << TABS << "struct { //" << node.key << "\n"; | 
				
			|||
	writeNodeElementDeclarations(node, typeMappings, intendent + 1); | 
				
			|||
	_hdr << TABS << "} " << node.key << ";\n"; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeEntryDeclaration(const EntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	if(entry.contentNodes.isEmpty()) | 
				
			|||
		_hdr << TABS << "QtMvvm::SettingsEntry<" << typeMappings.value(entry.type, entry.type) << "> " << entry.key << ";\n"; | 
				
			|||
	else { | 
				
			|||
		const auto &mType = typeMappings.value(entry.type, entry.type); | 
				
			|||
		_hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n"; | 
				
			|||
		writeNodeElementDeclarations(entry, typeMappings, intendent + 1); | 
				
			|||
		_hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "} " << entry.key << ";\n"; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeListEntryDeclaration(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent) | 
				
			|||
{ | 
				
			|||
	if(entry.contentNodes.isEmpty()) | 
				
			|||
		_hdr << TABS << "QtMvvm::SettingsEntry<QList<" << typeMappings.value(entry.type, entry.type) << ">> " << entry.key << ";\n"; | 
				
			|||
	else { | 
				
			|||
		const QString mType = QStringLiteral("QList<") + typeMappings.value(entry.type, entry.type) + QLatin1Char('>'); | 
				
			|||
		_hdr << TABS << "struct : QtMvvm::SettingsEntry<" << mType << "> { //" << entry.key << "\n"; | 
				
			|||
		writeNodeElementDeclarations(entry, typeMappings, intendent + 1); | 
				
			|||
		_hdr << TABS << "\tinline auto &operator=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "\tinline auto &operator+=(const " << typeMappings.value(entry.type, entry.type) << " &__value) { SettingsEntry<" << mType << ">::operator+=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "\tinline auto &operator+=(const " << mType << " &__value) { SettingsEntry<" << mType << ">::operator+=(__value); return *this; }\n"; | 
				
			|||
		_hdr << TABS << "} " << entry.key << ";\n"; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeSource(const SettingsType &settings) | 
				
			|||
{ | 
				
			|||
	_src << "#include \"" << _hdrFile.fileName() << "\"\n"; | 
				
			|||
	_src << "#include <QtCore/QCoreApplication>\n"; | 
				
			|||
	_src << "#include <QtMvvmCore/ServiceRegistry>\n"; | 
				
			|||
	if(!settings.backend) | 
				
			|||
		_src << "#include <QtMvvmCore/QSettingsAccessor>\n"; | 
				
			|||
	_src << "\n"; | 
				
			|||
 | 
				
			|||
	auto backend = settings.backend.value_or(BackendType{QStringLiteral("QtMvvm::QSettingsAccessor"), {}, {}}); | 
				
			|||
 | 
				
			|||
	_src << "namespace {\n\n" | 
				
			|||
		 << "void __generated_settings_setup()\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\tQtMvvm::ServiceRegistry::instance()->registerObject<" << settings.name.value() << ">("; | 
				
			|||
	if(backend.scope) | 
				
			|||
		_src << "QtMvvm::ServiceRegistry::" << backend.scope.value(); | 
				
			|||
	_src << ");\n" | 
				
			|||
		 << "}\n\n" | 
				
			|||
		 << "}\n" | 
				
			|||
		 << "Q_COREAPP_STARTUP_FUNCTION(__generated_settings_setup)\n\n"; | 
				
			|||
 | 
				
			|||
	_src << settings.name.value() << "::" << settings.name.value() << "(QObject *parent) : \n" | 
				
			|||
		 << "\t" << settings.name.value() << "{new " << backend.className << "{"; | 
				
			|||
	if(!backend.param.isEmpty()) { | 
				
			|||
		_src << "\n"; | 
				
			|||
		auto first = true; | 
				
			|||
		for(const auto ¶m : qAsConst(backend.param)) { | 
				
			|||
			if(first) | 
				
			|||
				first = false; | 
				
			|||
			else | 
				
			|||
				_src << ",\n"; | 
				
			|||
			_src << "\t\tQVariant{"; | 
				
			|||
			if(param.asStr) | 
				
			|||
				_src << "QStringLiteral(\"" << param.value << "\")"; | 
				
			|||
			else | 
				
			|||
				_src << param.value; | 
				
			|||
			_src << "}.value<" << param.type << ">()"; | 
				
			|||
		} | 
				
			|||
		_src << "\n\t"; | 
				
			|||
	} | 
				
			|||
	_src << "}, parent}\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\t_accessor->setParent(this);\n" | 
				
			|||
		 << "}\n\n"; | 
				
			|||
 | 
				
			|||
	_src << settings.name.value() << "::" << settings.name.value() << "(QtMvvm::ISettingsAccessor *accessor, QObject *parent) : \n" | 
				
			|||
		 << "\tQObject{parent},\n" | 
				
			|||
		 << "\t_accessor{accessor}\n" | 
				
			|||
		 << "{\n"; | 
				
			|||
	writeNodeElementDefinitions(settings, settings.typeMappings, settings.baseKey); | 
				
			|||
	_src << "}\n\n"; | 
				
			|||
 | 
				
			|||
	_src << settings.name.value() << " *" << settings.name.value() << "::instance()\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\treturn QtMvvm::ServiceRegistry::instance()->service<" << settings.name.value() << ">();\n" | 
				
			|||
		 << "}\n\n"; | 
				
			|||
 | 
				
			|||
	_src << "QtMvvm::ISettingsAccessor *" << settings.name.value() << "::accessor() const\n" | 
				
			|||
		 << "{\n" | 
				
			|||
		 << "\treturn _accessor;\n" | 
				
			|||
		 << "}\n\n"; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeNodeElementDefinitions(const SettingsGeneratorBase::NodeContentGroup &node, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, const QStringList &keyChain) | 
				
			|||
{ | 
				
			|||
	for(const auto &cNode : node.contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) { | 
				
			|||
			const auto &xNode = nonstd::get<NodeType>(cNode); | 
				
			|||
			writeNodeElementDefinitions(xNode, typeMappings, baseKey, QStringList{keyChain} << xNode.key); | 
				
			|||
		} else if(nonstd::holds_alternative<EntryType>(cNode)) | 
				
			|||
			writeEntryDefinition(nonstd::get<EntryType>(cNode), typeMappings, baseKey, keyChain); | 
				
			|||
		else if(nonstd::holds_alternative<ListEntryType>(cNode)) | 
				
			|||
			writeListEntryDefinition(nonstd::get<ListEntryType>(cNode), typeMappings, baseKey, keyChain); | 
				
			|||
		else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) | 
				
			|||
			writeNodeElementDefinitions(nonstd::get<NodeContentGroup>(cNode), typeMappings, baseKey, keyChain); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeEntryDefinition(const SettingsGeneratorBase::EntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain, bool skipChildren) | 
				
			|||
{ | 
				
			|||
	keyChain.append(entry.key); | 
				
			|||
	_src << "\t" << keyChain.join(QLatin1Char('.')) | 
				
			|||
		 << ".setup(QStringLiteral(\"" << (baseKey ? QStringList{baseKey.value()} + keyChain : keyChain).join(QLatin1Char('/')) << "\"), _accessor"; | 
				
			|||
	if(entry.code) | 
				
			|||
		_src << ", QVariant::fromValue<" << typeMappings.value(entry.type, entry.type) << ">(" << entry.code.value().trimmed() << ")"; | 
				
			|||
	else if(entry.defaultValue) { | 
				
			|||
		_src << ", QVariant{"; | 
				
			|||
		if(entry.tr) | 
				
			|||
			_src << "QCoreApplication::translate(\"" << entry.trContext.value() << "\", \"" << entry.defaultValue.value() << "\")"; | 
				
			|||
		else | 
				
			|||
			_src << "QStringLiteral(\"" << entry.defaultValue.value() << "\")"; | 
				
			|||
		_src << "}.value<" << typeMappings.value(entry.type, entry.type) << ">()"; | 
				
			|||
	} | 
				
			|||
	_src << ");\n"; | 
				
			|||
	if(!skipChildren) | 
				
			|||
		writeNodeElementDefinitions(entry, typeMappings, baseKey, keyChain); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGenerator::writeListEntryDefinition(const SettingsGeneratorBase::ListEntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain) | 
				
			|||
{ | 
				
			|||
	writeEntryDefinition(entry, typeMappings, baseKey, keyChain, entry.init.has_value()); | 
				
			|||
	if(entry.init) { | 
				
			|||
		keyChain.append(entry.key); | 
				
			|||
		_src << "\t" << keyChain.join(QLatin1Char('.')) << ".setupInit(" << entry.init.value().trimmed() << ");\n"; | 
				
			|||
		writeNodeElementDefinitions(entry, typeMappings, baseKey, keyChain); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
@ -1,53 +0,0 @@ | 
				
			|||
#ifndef SETTINGSGENERATOR_H | 
				
			|||
#define SETTINGSGENERATOR_H | 
				
			|||
 | 
				
			|||
#include <QFile> | 
				
			|||
#include <QTextStream> | 
				
			|||
 | 
				
			|||
#include "qsettingsgenerator.h" | 
				
			|||
#include "settingsconfigimpl.h" | 
				
			|||
 | 
				
			|||
class SettingsGenerator : public SettingsGeneratorBase | 
				
			|||
{ | 
				
			|||
public: | 
				
			|||
	SettingsGenerator(const QString &hdrPath, | 
				
			|||
					  const QString &srcPath); | 
				
			|||
 | 
				
			|||
	void process(const QString &inPath); | 
				
			|||
	void processQml(const QString &inPath); | 
				
			|||
 | 
				
			|||
protected: | 
				
			|||
	bool read_type_mapping(QXmlStreamReader &reader, QHash<QString, QString> &data, bool hasNext) override; | 
				
			|||
	void read_included_file(QXmlStreamReader &reader, NodeContentGroup &data) override; | 
				
			|||
 | 
				
			|||
private: | 
				
			|||
	QFile _hdrFile; | 
				
			|||
	QFile _srcFile; | 
				
			|||
 | 
				
			|||
	QTextStream _hdr; | 
				
			|||
	QTextStream _src; | 
				
			|||
 | 
				
			|||
	void convertFromConf(QXmlStreamReader &reader, SettingsConfigBase::SettingsConfigType &conf, SettingsType &data); | 
				
			|||
	void readCategory(QXmlStreamReader &reader, SettingsConfigBase::CategoryContentGroup &content, NodeContentGroup &targetRootNode); | 
				
			|||
	void readSection(QXmlStreamReader &reader, SettingsConfigBase::SectionContentGroup &content, NodeContentGroup &targetRootNode); | 
				
			|||
	void readGroup(QXmlStreamReader &reader, SettingsConfigBase::GroupContentGroup &content, NodeContentGroup &targetRootNode); | 
				
			|||
	void readEntry(QXmlStreamReader &reader, SettingsConfigBase::EntryType &entry, NodeContentGroup &targetRootNode); | 
				
			|||
 | 
				
			|||
	NodeContentGroup *findContentGroup(NodeContentGroup *cGrp, const QString &key, bool *isEntry = nullptr); | 
				
			|||
	NodeContentGroup *replaceNodeByEntry(NodeContentGroup *cGrp, NodeContentGroup *node, EntryType &entry); | 
				
			|||
 | 
				
			|||
	void fixTrContext(NodeContentGroup &group, const QString &context); | 
				
			|||
 | 
				
			|||
	void writeHeader(const SettingsType &settings); | 
				
			|||
	void writeNodeElementDeclarations(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
	void writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
	void writeEntryDeclaration(const EntryType &entry, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
	void writeListEntryDeclaration(const ListEntryType &entry, const QHash<QString, QString> &typeMappings, int intendent = 1); | 
				
			|||
 | 
				
			|||
	void writeSource(const SettingsType &settings); | 
				
			|||
	void writeNodeElementDefinitions(const NodeContentGroup &node, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, const QStringList &keyChain = {}); | 
				
			|||
	void writeEntryDefinition(const EntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain, bool skipChildren = false); | 
				
			|||
	void writeListEntryDefinition(const ListEntryType &entry, const QHash<QString, QString> &typeMappings, const optional<QString> &baseKey, QStringList keyChain); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
#endif // SETTINGSGENERATOR_H
 | 
				
			|||
@ -0,0 +1,225 @@ | 
				
			|||
#include "settingsgeneratorimpl.h" | 
				
			|||
#include <QFileInfo> | 
				
			|||
#include <QDir> | 
				
			|||
#include <QDebug> | 
				
			|||
 | 
				
			|||
bool SettingsGeneratorImpl::read_type_mapping(QXmlStreamReader &reader, QHash<QString, QString> &data, bool hasNext) | 
				
			|||
{ | 
				
			|||
	TypeMappingGroup grp; | 
				
			|||
	hasNext = read_TypeMappingGroup(reader, grp, hasNext); | 
				
			|||
	for(const auto &mapping : qAsConst(grp.typeMapping)) | 
				
			|||
		data.insert(mapping.key, mapping.type); | 
				
			|||
	return hasNext; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::read_included_file(QXmlStreamReader &reader, NodeContentGroup &data) | 
				
			|||
{ | 
				
			|||
	ImportType import; | 
				
			|||
	read_ImportType(reader, import); | 
				
			|||
 | 
				
			|||
	//make the path relative if possbile
 | 
				
			|||
	if(dynamic_cast<QFileDevice*>(reader.device())) { | 
				
			|||
		QFileInfo docInfo{static_cast<QFileDevice*>(reader.device())->fileName()}; | 
				
			|||
		import.importPath = docInfo.dir().absoluteFilePath(import.importPath); | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	// read the document
 | 
				
			|||
	try { | 
				
			|||
		QFile xmlFile{import.importPath}; | 
				
			|||
		if(!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) | 
				
			|||
			throw FileException{xmlFile}; | 
				
			|||
 | 
				
			|||
		QXmlStreamReader subReader{&xmlFile}; | 
				
			|||
		if(!subReader.readNextStartElement()) | 
				
			|||
			throw XmlException{subReader}; | 
				
			|||
 | 
				
			|||
		SettingsType settings; | 
				
			|||
		if(subReader.name() == QStringLiteral("Settings")) { | 
				
			|||
			read_SettingsType(subReader, settings); | 
				
			|||
		} else if(subReader.name() == QStringLiteral("SettingsConfig")) { | 
				
			|||
			SettingsConfigImpl confReader; | 
				
			|||
			SettingsConfigBase::SettingsConfigType settingsConf; | 
				
			|||
			confReader.read_SettingsConfigType(subReader, settingsConf); | 
				
			|||
			convertFromConf(reader, settingsConf, settings); | 
				
			|||
		} else | 
				
			|||
			throwChild(subReader); | 
				
			|||
 | 
				
			|||
		NodeContentGroup *cGrp = &settings; | 
				
			|||
		if(import.rootNode) { | 
				
			|||
			for(const auto &key : import.rootNode.value().split(QLatin1Char('/'), QString::SkipEmptyParts)) { | 
				
			|||
				cGrp = findContentGroup(cGrp, key); | 
				
			|||
				if(!cGrp) | 
				
			|||
					return; | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
 | 
				
			|||
		data = std::move(*cGrp); | 
				
			|||
		fixTrContext(data, QFileInfo{import.importPath}.fileName()); | 
				
			|||
	} catch(FileException &e) { | 
				
			|||
		if(import.required) | 
				
			|||
			throw; | 
				
			|||
		else { | 
				
			|||
			qWarning() << e.what(); | 
				
			|||
			return; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::convertFromConf(QXmlStreamReader &reader, SettingsConfigBase::SettingsConfigType &conf, SettingsType &data) | 
				
			|||
{ | 
				
			|||
	for(auto &element : conf.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::CategoryType>(element)) | 
				
			|||
			readCategory(reader, nonstd::get<SettingsConfigBase::CategoryType>(element), data); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::SectionType>(element)) | 
				
			|||
			readSection(reader, nonstd::get<SettingsConfigBase::SectionType>(element), data); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::GroupType>(element)) | 
				
			|||
			readGroup(reader, nonstd::get<SettingsConfigBase::GroupType>(element), data); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), data); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::readCategory(QXmlStreamReader &reader, SettingsConfigBase::CategoryContentGroup &content, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	for(auto &element : content.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::SectionType>(element)) | 
				
			|||
			readSection(reader, nonstd::get<SettingsConfigBase::SectionType>(element), targetRootNode); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::GroupType>(element)) | 
				
			|||
			readGroup(reader, nonstd::get<SettingsConfigBase::GroupType>(element), targetRootNode); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), targetRootNode); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf Categoy")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::readSection(QXmlStreamReader &reader, SettingsConfigBase::SectionContentGroup &content, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	for(auto &element : content.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::GroupType>(element)) | 
				
			|||
			readGroup(reader, nonstd::get<SettingsConfigBase::GroupType>(element), targetRootNode); | 
				
			|||
		else if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), targetRootNode); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf Section")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::readGroup(QXmlStreamReader &reader, SettingsConfigBase::GroupContentGroup &content, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	for(auto &element : content.content) { | 
				
			|||
		if(nonstd::holds_alternative<SettingsConfigBase::EntryType>(element)) | 
				
			|||
			readEntry(reader, nonstd::get<SettingsConfigBase::EntryType>(element), targetRootNode); | 
				
			|||
		else | 
				
			|||
			throw XmlException{reader, QStringLiteral("Unexpected child element in included SettingsConf Group")}; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::readEntry(QXmlStreamReader &reader, SettingsConfigBase::EntryType &entry, NodeContentGroup &targetRootNode) | 
				
			|||
{ | 
				
			|||
	auto keyChain = entry.key.split(QLatin1Char('/'), QString::SkipEmptyParts); | 
				
			|||
	auto entryKey = keyChain.takeLast(); | 
				
			|||
 | 
				
			|||
	auto cGrp = &targetRootNode; | 
				
			|||
	for(const auto &key : keyChain) { | 
				
			|||
		auto nGrp = findContentGroup(cGrp, key); | 
				
			|||
		if(!nGrp) { | 
				
			|||
			NodeType nNode; | 
				
			|||
			nNode.key = key; | 
				
			|||
			cGrp->contentNodes.append(std::move(nNode)); | 
				
			|||
			nGrp = &(nonstd::get<NodeType>(cGrp->contentNodes.last())); | 
				
			|||
		} | 
				
			|||
		cGrp = nGrp; | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	auto isEntry = false; | 
				
			|||
	auto eGrp = findContentGroup(cGrp, entryKey, &isEntry); | 
				
			|||
	if(!eGrp) { | 
				
			|||
		EntryType nEntry; | 
				
			|||
		nEntry.key = entryKey; | 
				
			|||
		cGrp->contentNodes.append(std::move(nEntry)); | 
				
			|||
		eGrp = &(nonstd::get<EntryType>(cGrp->contentNodes.last())); | 
				
			|||
	} else if(!isEntry) { | 
				
			|||
		EntryType nEntry; | 
				
			|||
		nEntry.key = entryKey; | 
				
			|||
		nEntry.contentNodes = std::move(eGrp->contentNodes); | 
				
			|||
		eGrp = replaceNodeByEntry(cGrp, eGrp, nEntry); | 
				
			|||
		Q_ASSERT(eGrp); | 
				
			|||
	} else | 
				
			|||
		throw XmlException{reader, QStringLiteral("Found duplicated entry with key: %1").arg(entry.key)}; | 
				
			|||
 | 
				
			|||
	auto nEntry = static_cast<EntryType*>(eGrp); | 
				
			|||
	nEntry->type = std::move(entry.type); | 
				
			|||
	nEntry->defaultValue = std::move(entry.defaultValue); | 
				
			|||
	nEntry->tr = entry.trdefault; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
SettingsGeneratorBase::NodeContentGroup *SettingsGeneratorImpl::findContentGroup(SettingsGeneratorBase::NodeContentGroup *cGrp, const QString &key, bool *isEntry) | 
				
			|||
{ | 
				
			|||
	if(isEntry) | 
				
			|||
		*isEntry = false; | 
				
			|||
	for(auto &cNode : cGrp->contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) { | 
				
			|||
			if(nonstd::get<NodeType>(cNode).key == key) | 
				
			|||
				return &(nonstd::get<NodeType>(cNode)); | 
				
			|||
		} else if(nonstd::holds_alternative<EntryType>(cNode)) { | 
				
			|||
			if(nonstd::get<EntryType>(cNode).key == key) { | 
				
			|||
				if(isEntry) | 
				
			|||
					*isEntry = true; | 
				
			|||
				return &(nonstd::get<EntryType>(cNode)); | 
				
			|||
			} | 
				
			|||
		} else if(nonstd::holds_alternative<ListEntryType>(cNode)) { | 
				
			|||
			if(nonstd::get<ListEntryType>(cNode).key == key) { | 
				
			|||
				if(isEntry) | 
				
			|||
					*isEntry = true; | 
				
			|||
				return &(nonstd::get<ListEntryType>(cNode)); | 
				
			|||
			} | 
				
			|||
		} else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) { | 
				
			|||
			auto res = findContentGroup(&(nonstd::get<NodeContentGroup>(cNode)), key); | 
				
			|||
			if(res) | 
				
			|||
				return res; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return nullptr; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
SettingsGeneratorBase::NodeContentGroup *SettingsGeneratorImpl::replaceNodeByEntry(SettingsGeneratorBase::NodeContentGroup *cGrp, NodeContentGroup *node, SettingsGeneratorBase::EntryType &entry) | 
				
			|||
{ | 
				
			|||
	for(auto &cNode : cGrp->contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(cNode)) { | 
				
			|||
			if(&nonstd::get<NodeType>(cNode) == node) { | 
				
			|||
				cNode = std::move(entry); | 
				
			|||
				return &(nonstd::get<EntryType>(cNode)); | 
				
			|||
			} | 
				
			|||
		} else if(nonstd::holds_alternative<NodeContentGroup>(cNode)) { | 
				
			|||
			auto res = replaceNodeByEntry(&(nonstd::get<NodeContentGroup>(cNode)), node, entry); | 
				
			|||
			if(res) | 
				
			|||
				return res; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return nullptr; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void SettingsGeneratorImpl::fixTrContext(NodeContentGroup &group, const QString &context) | 
				
			|||
{ | 
				
			|||
	for(auto &node : group.contentNodes) { | 
				
			|||
		if(nonstd::holds_alternative<NodeType>(node)) | 
				
			|||
			fixTrContext(nonstd::get<NodeType>(node), context); | 
				
			|||
		else if(nonstd::holds_alternative<EntryType>(node)) { | 
				
			|||
			auto &entry = nonstd::get<EntryType>(node); | 
				
			|||
			if(!entry.trContext) | 
				
			|||
				entry.trContext = context; | 
				
			|||
			fixTrContext(entry, context); | 
				
			|||
		} else if(nonstd::holds_alternative<ListEntryType>(node)) { | 
				
			|||
			auto &entry = nonstd::get<ListEntryType>(node); | 
				
			|||
			if(!entry.trContext) | 
				
			|||
				entry.trContext = context; | 
				
			|||
			fixTrContext(entry, context); | 
				
			|||
		} else if(nonstd::holds_alternative<NodeContentGroup>(node)) | 
				
			|||
			fixTrContext(nonstd::get<NodeContentGroup>(node), context); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
@ -0,0 +1,28 @@ | 
				
			|||
#ifndef SETTINGSGENERATOR_H | 
				
			|||
#define SETTINGSGENERATOR_H | 
				
			|||
 | 
				
			|||
#include <QFile> | 
				
			|||
#include <QTextStream> | 
				
			|||
 | 
				
			|||
#include "qsettingsgenerator.h" | 
				
			|||
#include "settingsconfigimpl.h" | 
				
			|||
 | 
				
			|||
class SettingsGeneratorImpl : public SettingsGeneratorBase | 
				
			|||
{ | 
				
			|||
protected: | 
				
			|||
	bool read_type_mapping(QXmlStreamReader &reader, QHash<QString, QString> &data, bool hasNext) override; | 
				
			|||
	void read_included_file(QXmlStreamReader &reader, NodeContentGroup &data) override; | 
				
			|||
 | 
				
			|||
	void convertFromConf(QXmlStreamReader &reader, SettingsConfigBase::SettingsConfigType &conf, SettingsType &data); | 
				
			|||
	void readCategory(QXmlStreamReader &reader, SettingsConfigBase::CategoryContentGroup &content, NodeContentGroup &targetRootNode); | 
				
			|||
	void readSection(QXmlStreamReader &reader, SettingsConfigBase::SectionContentGroup &content, NodeContentGroup &targetRootNode); | 
				
			|||
	void readGroup(QXmlStreamReader &reader, SettingsConfigBase::GroupContentGroup &content, NodeContentGroup &targetRootNode); | 
				
			|||
	void readEntry(QXmlStreamReader &reader, SettingsConfigBase::EntryType &entry, NodeContentGroup &targetRootNode); | 
				
			|||
 | 
				
			|||
	NodeContentGroup *findContentGroup(NodeContentGroup *cGrp, const QString &key, bool *isEntry = nullptr); | 
				
			|||
	NodeContentGroup *replaceNodeByEntry(NodeContentGroup *cGrp, NodeContentGroup *node, EntryType &entry); | 
				
			|||
 | 
				
			|||
	void fixTrContext(NodeContentGroup &group, const QString &context); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
#endif // SETTINGSGENERATOR_H
 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue