From 40529b9148765461475a105e17ac088ca4ffbe8e Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Tue, 17 Jul 2018 23:25:47 +0200 Subject: [PATCH] WIP translator --- bin/qsettingstranslator.py | 49 -------- examples/mvvmcore/SampleCore/SampleCore.pro | 5 +- mkspecs/features/qsettingstranslator.prf | 6 +- .../settingsgenerator/import_config.xml | 3 +- .../settingsgenerator/import_normal.xml | 2 +- .../settingsgenerator/settingsgenerator.pro | 11 +- .../mvvmcore/settingsgenerator/test_de.ts | 11 ++ .../settingsgenerator/translatortest.xml | 31 ++++++ tools/settingsgenerator/main.cpp | 2 +- tools/settingsgenerator/qpmx.json | 2 +- tools/settingsgenerator/settingsgenerator.cpp | 24 +++- tools/settingsgenerator/settingsgenerator.h | 2 + .../settingsgenerator/settingstranslator.cpp | 105 +++++++++++++++++- tools/settingsgenerator/settingstranslator.h | 10 +- 14 files changed, 194 insertions(+), 69 deletions(-) delete mode 100755 bin/qsettingstranslator.py create mode 100644 tests/auto/mvvmcore/settingsgenerator/test_de.ts create mode 100644 tests/auto/mvvmcore/settingsgenerator/translatortest.xml diff --git a/bin/qsettingstranslator.py b/bin/qsettingstranslator.py deleted file mode 100755 index 88166f8..0000000 --- a/bin/qsettingstranslator.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# Usage: qsettingstranslator.py - -import sys -try: - from defusedxml.ElementTree import parse -except ImportError: - from xml.etree.ElementTree import parse - - -def create_settings_ts(infile, outfile): - strings = [] - tree = parse(infile) - for elem in tree.iter(): - if elem.tag == "SearchKey": - strings.append(elem.text) - else: - if "title" in elem.attrib: - strings.append(elem.attrib["title"]) - if "tooltip" in elem.attrib: - strings.append(elem.attrib["tooltip"]) - if "tr" in elem.attrib and elem.attrib["tr"].lower() == "true": - strings.append(elem.text) - if "ztr" in elem.attrib and elem.attrib["ztr"].lower() == "true": # lazy translations - strings.append(elem.text) - if "trdefault" in elem.attrib and elem.attrib["trdefault"].lower() == "true": - strings.append(elem.attrib["default"]) - # legaxy keys, because of a typo... - if "ts" in elem.attrib and elem.attrib["ts"].lower() == "true": - strings.append(elem.text) - if "tsdefault" in elem.attrib and elem.attrib["tsdefault"].lower() == "true": - strings.append(elem.attrib["default"]) - - with open(outfile, "w") as file: - file.write("#include \n\n") - file.write("void dummyfn() {\n") - for string in strings: - string = string.replace("\\", "\\\\") - string = string.replace("\"", "\\\"") - file.write("\tQCoreApplication::translate(\"qtmvvm_settings_xml\", \"{}\");\n".format(string)) - file.write("}\n") - - -if __name__ == '__main__': - if len(sys.argv) != 3: - print("Usage: qsettingstranslator.py ", file=sys.stderr) - exit(1) - else: - create_settings_ts(*sys.argv[1:3]) diff --git a/examples/mvvmcore/SampleCore/SampleCore.pro b/examples/mvvmcore/SampleCore/SampleCore.pro index 6613db7..a8bad7f 100644 --- a/examples/mvvmcore/SampleCore/SampleCore.pro +++ b/examples/mvvmcore/SampleCore/SampleCore.pro @@ -13,7 +13,7 @@ HEADERS += \ resultviewmodel.h \ drawerviewmodel.h \ tabviewmodel.h \ - containerviewmodel.h + containerviewmodel.h SOURCES += \ samplecoreapp.cpp \ @@ -22,14 +22,13 @@ SOURCES += \ resultviewmodel.cpp \ drawerviewmodel.cpp \ tabviewmodel.cpp \ - containerviewmodel.cpp + containerviewmodel.cpp RESOURCES += \ sample_core.qrc QTMVVM_TS_SETTINGS += settings.xml _never_true_condition: SOURCES += $$files($$PWD/.ts-dummy/*) -PRE_TARGETDEPS += qtmvvm-tsgen TRANSLATIONS += samplecore_de.ts DISTFILES += $$TRANSLATIONS diff --git a/mkspecs/features/qsettingstranslator.prf b/mkspecs/features/qsettingstranslator.prf index bf470c9..91b1f57 100644 --- a/mkspecs/features/qsettingstranslator.prf +++ b/mkspecs/features/qsettingstranslator.prf @@ -12,11 +12,7 @@ isEmpty(QSETTINGSTRANSLATOR_DIR): QSETTINGSTRANSLATOR_DIR = $$_PRO_FILE_PWD_/.ts qsettingstranslator_c.depends += $$QMAKE_QSETTINGSGENERATOR_EXE QMAKE_EXTRA_COMPILERS += qsettingstranslator_c - - qtmvvm_tsgen_target.target = qtmvvm-tsgen - qtmvvm_tsgen_target.depends += compiler_qsettingstranslator_c_make_all - qtmvvm_tsgen_target.commands += @echo $$shell_quote(>>> Remember to add the line \"_never_true_condition: SOURCES += $${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}files($${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}PWD/.ts-dummy/*)\" to your pro file) - QMAKE_EXTRA_TARGETS += qtmvvm_tsgen_target + PRE_TARGETDEPS += compiler_qsettingstranslator_c_make_all } else { qtmvvm_tsgen_target.target = qtmvvm-tsgen QMAKE_EXTRA_TARGETS += qtmvvm_tsgen_target diff --git a/tests/auto/mvvmcore/settingsgenerator/import_config.xml b/tests/auto/mvvmcore/settingsgenerator/import_config.xml index af2c49f..1023ea7 100644 --- a/tests/auto/mvvmcore/settingsgenerator/import_config.xml +++ b/tests/auto/mvvmcore/settingsgenerator/import_config.xml @@ -12,7 +12,8 @@ + default="42" + trdefault="true">
diff --git a/tests/auto/mvvmcore/settingsgenerator/import_normal.xml b/tests/auto/mvvmcore/settingsgenerator/import_normal.xml index 27d8303..f3a8f4e 100644 --- a/tests/auto/mvvmcore/settingsgenerator/import_normal.xml +++ b/tests/auto/mvvmcore/settingsgenerator/import_normal.xml @@ -1,7 +1,7 @@ - + diff --git a/tests/auto/mvvmcore/settingsgenerator/settingsgenerator.pro b/tests/auto/mvvmcore/settingsgenerator/settingsgenerator.pro index a55a7b2..798ad16 100644 --- a/tests/auto/mvvmcore/settingsgenerator/settingsgenerator.pro +++ b/tests/auto/mvvmcore/settingsgenerator/settingsgenerator.pro @@ -7,6 +7,9 @@ CONFIG -= app_bundle TARGET = tst_settingsgenerator +HEADERS += \ + testbackend.h + SOURCES += \ tst_settingsgenerator.cpp \ testbackend.cpp @@ -15,9 +18,13 @@ SETTINGS_DEFINITIONS += \ generatortest.xml \ importtest.xml -HEADERS += \ - testbackend.h +SETTINGS_TRANSLATIONS += \ + translatortest.xml + +_never_true: SOURCES += $$files(.ts-dummy/*) DISTFILES += \ import_normal.xml \ import_config.xml + +TRANSLATIONS += test_de.ts diff --git a/tests/auto/mvvmcore/settingsgenerator/test_de.ts b/tests/auto/mvvmcore/settingsgenerator/test_de.ts new file mode 100644 index 0000000..a9a7cd4 --- /dev/null +++ b/tests/auto/mvvmcore/settingsgenerator/test_de.ts @@ -0,0 +1,11 @@ + + + + + qtmvvm_settings_xml + + dummy + + + + diff --git a/tests/auto/mvvmcore/settingsgenerator/translatortest.xml b/tests/auto/mvvmcore/settingsgenerator/translatortest.xml new file mode 100644 index 0000000..af2c49f --- /dev/null +++ b/tests/auto/mvvmcore/settingsgenerator/translatortest.xml @@ -0,0 +1,31 @@ + + + + + + + +
+ + +
+
+ + + + + + +
+
+
diff --git a/tools/settingsgenerator/main.cpp b/tools/settingsgenerator/main.cpp index c588eab..26a1b2d 100644 --- a/tools/settingsgenerator/main.cpp +++ b/tools/settingsgenerator/main.cpp @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) parser.addHelpOption(); parser.addOption({ - {QStringLiteral("t"), QStringLiteral("translate")}, + {QStringLiteral("t"), QStringLiteral("tr"), QStringLiteral("translate")}, QStringLiteral("Translate the given settings file. The output will be" "a dummy cpp file, writte to --impl.") }); diff --git a/tools/settingsgenerator/qpmx.json b/tools/settingsgenerator/qpmx.json index a47c6de..3de11e6 100644 --- a/tools/settingsgenerator/qpmx.json +++ b/tools/settingsgenerator/qpmx.json @@ -3,7 +3,7 @@ { "package": "de.skycoder42.qxmlcodegen", "provider": "qpm", - "version": "1.1.6" + "version": "1.1.7" } ], "license": { diff --git a/tools/settingsgenerator/settingsgenerator.cpp b/tools/settingsgenerator/settingsgenerator.cpp index 05e0dbd..e077ca6 100644 --- a/tools/settingsgenerator/settingsgenerator.cpp +++ b/tools/settingsgenerator/settingsgenerator.cpp @@ -17,7 +17,8 @@ void SettingsGenerator::process(const QString &inPath) // read settings and adjust defaults auto settings = readDocument(inPath); if(!settings.name) - settings.name = QFileInfo{_hdrFile.fileName()}.baseName(); + settings.name = QFileInfo{inPath}.baseName(); + fixTrContext(settings, QFileInfo{inPath}.fileName()); if(!_hdrFile.open(QIODevice::WriteOnly | QIODevice::Text)) throw FileException{_hdrFile}; @@ -79,7 +80,9 @@ void SettingsGenerator::read_included_file(QXmlStreamReader &reader, NodeContent return; } } + data = std::move(*cGrp); + fixTrContext(data, QFileInfo{import.importPath}.fileName()); } catch(FileException &e) { if(import.required) throw; @@ -223,6 +226,21 @@ SettingsGeneratorBase::NodeContentGroup *SettingsGenerator::replaceNodeByEntry(S return nullptr; } +void SettingsGenerator::fixTrContext(NodeContentGroup &group, const QString &context) +{ + for(auto &node : group.contentNodes) { + if(nonstd::holds_alternative(node)) + fixTrContext(nonstd::get(node), context); + else if(nonstd::holds_alternative(node)) { + auto &entry = nonstd::get(node); + if(!entry.trContext) + entry.trContext = context; + fixTrContext(entry, context); + } else if(nonstd::holds_alternative(node)) + fixTrContext(nonstd::get(node), context); + } +} + void SettingsGenerator::writeHeader(const SettingsType &settings) { QString incGuard = QFileInfo{_hdrFile.fileName()} @@ -306,7 +324,7 @@ void SettingsGenerator::writeSource(const SettingsType &settings) _src << "#include \n"; _src << "\n"; - auto backend = settings.backend.value_or(BackendType{QStringLiteral("QtMvvm::QSettingsAccessor"), {}}); + auto backend = settings.backend.value_or(BackendType{QStringLiteral("QtMvvm::QSettingsAccessor"), {}, {}}); _src << "namespace {\n\n" << "void __generated_settings_setup()\n" @@ -384,7 +402,7 @@ void SettingsGenerator::writeEntryDefinition(const SettingsGeneratorBase::EntryT else if(entry.defaultValue) { _src << ", QVariant{"; if(entry.tr) - _src << "QCoreApplication::translate(\"" << entry.trContext.value_or(QStringLiteral("qtmvvm_settings_xml")) << "\", \"" << entry.defaultValue.value() << "\")"; + _src << "QCoreApplication::translate(\"" << entry.trContext.value() << "\", \"" << entry.defaultValue.value() << "\")"; else _src << "QStringLiteral(\"" << entry.defaultValue.value() << "\")"; _src << "}.value<" << typeMappings.value(entry.type, entry.type) << ">()"; diff --git a/tools/settingsgenerator/settingsgenerator.h b/tools/settingsgenerator/settingsgenerator.h index 3dab964..ca3b4c6 100644 --- a/tools/settingsgenerator/settingsgenerator.h +++ b/tools/settingsgenerator/settingsgenerator.h @@ -35,6 +35,8 @@ private: 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 &typeMappings, int intendent = 1); void writeNodeDeclaration(const NodeType &node, const QHash &typeMappings, int intendent = 1); diff --git a/tools/settingsgenerator/settingstranslator.cpp b/tools/settingsgenerator/settingstranslator.cpp index 84e72b1..2126a3c 100644 --- a/tools/settingsgenerator/settingstranslator.cpp +++ b/tools/settingsgenerator/settingstranslator.cpp @@ -1,4 +1,5 @@ #include "settingstranslator.h" +#include SettingsTranslator::SettingsTranslator(const QString &srcPath) : _srcFile{srcPath}, @@ -10,10 +11,110 @@ void SettingsTranslator::process(const QString &inPath) auto settings = readDocument(inPath); if(!nonstd::holds_alternative(settings)) throw XmlException{inPath, 0, 0, QStringLiteral("Expected the root element to be a SettingsConfig element")}; - writeTranslations(nonstd::get(settings)); + writeTranslations(nonstd::get(settings), inPath); } -void SettingsTranslator::writeTranslations(const SettingsConfigBase::SettingsConfigType &settings) +void SettingsTranslator::writeTranslations(const SettingsConfigType &settings, const QString &inPath) { + QStringList strings; + for(auto &element : settings.content) { + if(nonstd::holds_alternative(element)) + readCategoryStrings(nonstd::get(element), strings); + else if(nonstd::holds_alternative(element)) + readSectionStrings(nonstd::get(element), strings); + else if(nonstd::holds_alternative(element)) + readGroupStrings(nonstd::get(element), strings); + else if(nonstd::holds_alternative(element)) + readEntryStrings(nonstd::get(element), strings); + else + Q_UNREACHABLE(); + } + strings.removeDuplicates(); + + if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text)) + throw FileException{_srcFile}; + auto context = QFileInfo{inPath}.fileName(); + + _src << "#include \n\n" + << "namespace {\n\n" + << "void Q_DECL_UNUSED dummyfn()\n" + << "{\n"; + for(auto &string : strings) { + _src << "\tQCoreApplication::translate(\"" << context << "\", \"" + << string.replace(QLatin1Char('\\'), QStringLiteral("\\\\")) + .replace(QLatin1Char('\"'), QStringLiteral("\\\"")) + << "\");\n"; + } + _src << "}\n\n" + << "}\n"; + + _srcFile.close(); +} + +void SettingsTranslator::readCategoryStrings(const CategoryType &category, QStringList &strings) +{ + readInfoStrings(category, strings); + for(auto &element : category.content) { + if(nonstd::holds_alternative(element)) + readSectionStrings(nonstd::get(element), strings); + else if(nonstd::holds_alternative(element)) + readGroupStrings(nonstd::get(element), strings); + else if(nonstd::holds_alternative(element)) + readEntryStrings(nonstd::get(element), strings); + else + Q_UNREACHABLE(); + } +} + +void SettingsTranslator::readSectionStrings(const SectionType §ion, QStringList &strings) +{ + readInfoStrings(section, strings); + for(auto &element : section.content) { + if(nonstd::holds_alternative(element)) + readGroupStrings(nonstd::get(element), strings); + else if(nonstd::holds_alternative(element)) + readEntryStrings(nonstd::get(element), strings); + else + Q_UNREACHABLE(); + } +} + +void SettingsTranslator::readGroupStrings(const GroupType &group, QStringList &strings) +{ + readInfoStrings(group, strings); + for(auto &element : group.content) { + if(nonstd::holds_alternative(element)) + readEntryStrings(nonstd::get(element), strings); + else + Q_UNREACHABLE(); + } +} + +void SettingsTranslator::readEntryStrings(const EntryType &entry, QStringList &strings) +{ + readInfoStrings(entry, strings); + if(entry.trdefault && entry.defaultValue) + strings.append(entry.defaultValue.value()); + strings.append(entry.searchKeys); + for(const auto &prop : entry.properties) + readElementStrings(prop, strings); +} + +void SettingsTranslator::readInfoStrings(const BasicContainerInfo &info, QStringList &strings) +{ + if(info.title) + strings.append(info.title.value()); + if(info.tooltip) + strings.append(info.tooltip.value()); +} + +void SettingsTranslator::readElementStrings(const ElementType &element, QStringList &strings) +{ + if(element.content && (element.tr || element.ztr)) + strings.append(element.content.value()); + for(const auto &prop : element.elements) + readElementStrings(prop, strings); + for(const auto &prop : element.properties) + readElementStrings(prop, strings); } diff --git a/tools/settingsgenerator/settingstranslator.h b/tools/settingsgenerator/settingstranslator.h index 5967ebf..ef8bdb6 100644 --- a/tools/settingsgenerator/settingstranslator.h +++ b/tools/settingsgenerator/settingstranslator.h @@ -17,7 +17,15 @@ private: QFile _srcFile; QTextStream _src; - void writeTranslations(const SettingsConfigType &settings); + void writeTranslations(const SettingsConfigType &settings, const QString &inPath); + + void readCategoryStrings(const CategoryType &category, QStringList &strings); + void readSectionStrings(const SectionType §ion, QStringList &strings); + void readGroupStrings(const GroupType &group, QStringList &strings); + void readEntryStrings(const EntryType &entry, QStringList &strings); + + void readInfoStrings(const BasicContainerInfo &info, QStringList &strings); + void readElementStrings(const ElementType &element, QStringList &strings); }; #endif // SETTINGSTRANSLATOR_H