Browse Source

WIP translator

pull/2/head
Skycoder42 7 years ago
parent
commit
40529b9148
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 49
      bin/qsettingstranslator.py
  2. 5
      examples/mvvmcore/SampleCore/SampleCore.pro
  3. 6
      mkspecs/features/qsettingstranslator.prf
  4. 3
      tests/auto/mvvmcore/settingsgenerator/import_config.xml
  5. 2
      tests/auto/mvvmcore/settingsgenerator/import_normal.xml
  6. 11
      tests/auto/mvvmcore/settingsgenerator/settingsgenerator.pro
  7. 11
      tests/auto/mvvmcore/settingsgenerator/test_de.ts
  8. 31
      tests/auto/mvvmcore/settingsgenerator/translatortest.xml
  9. 2
      tools/settingsgenerator/main.cpp
  10. 2
      tools/settingsgenerator/qpmx.json
  11. 24
      tools/settingsgenerator/settingsgenerator.cpp
  12. 2
      tools/settingsgenerator/settingsgenerator.h
  13. 105
      tools/settingsgenerator/settingstranslator.cpp
  14. 10
      tools/settingsgenerator/settingstranslator.h

49
bin/qsettingstranslator.py

@ -1,49 +0,0 @@
#!/usr/bin/env python3
# Usage: qsettingstranslator.py <in> <out>
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 <QCoreApplication>\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 <in> <out>", file=sys.stderr)
exit(1)
else:
create_settings_ts(*sys.argv[1:3])

5
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

6
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

3
tests/auto/mvvmcore/settingsgenerator/import_config.xml

@ -12,7 +12,8 @@
<Entry key="node1/entry2"
type="int"
title="dummy"
default="42">
default="42"
trdefault="true">
</Entry>
</Section>
<Section>

2
tests/auto/mvvmcore/settingsgenerator/import_normal.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Settings>
<Node key="baum42">
<Entry key="importedEntry" type="bool"/>
<Entry key="importedEntry" type="bool" default="false" tr="true"/>
</Node>
<Entry key="unimportedEntry" type="bool"/>
</Settings>

11
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

11
tests/auto/mvvmcore/settingsgenerator/test_de.ts

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<context>
<name>qtmvvm_settings_xml</name>
<message>
<source>dummy</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

31
tests/auto/mvvmcore/settingsgenerator/translatortest.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<SettingsConfig allowSearch="true" allowRestore="true">
<Category>
<Entry key="node1/entry1"
type="bool"
title="dummy"
default="true">
</Entry>
</Category>
<Category>
<Section>
<Entry key="node1/entry2"
type="int"
title="dummy"
default="42">
</Entry>
</Section>
<Section>
<Group>
<Entry key="node2/entry1"
type="string"
title="dummy">
</Entry>
<Entry key="node1"
type="url"
title="dummy">
</Entry>
</Group>
</Section>
</Category>
</SettingsConfig>

2
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.")
});

2
tools/settingsgenerator/qpmx.json

@ -3,7 +3,7 @@
{
"package": "de.skycoder42.qxmlcodegen",
"provider": "qpm",
"version": "1.1.6"
"version": "1.1.7"
}
],
"license": {

24
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<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<NodeContentGroup>(node))
fixTrContext(nonstd::get<NodeContentGroup>(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 <QtMvvmCore/QSettingsAccessor>\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) << ">()";

2
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<QString, QString> &typeMappings, int intendent = 1);
void writeNodeDeclaration(const NodeType &node, const QHash<QString, QString> &typeMappings, int intendent = 1);

105
tools/settingsgenerator/settingstranslator.cpp

@ -1,4 +1,5 @@
#include "settingstranslator.h"
#include <QFileInfo>
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<SettingsConfigType>(settings))
throw XmlException{inPath, 0, 0, QStringLiteral("Expected the root element to be a SettingsConfig element")};
writeTranslations(nonstd::get<SettingsConfigType>(settings));
writeTranslations(nonstd::get<SettingsConfigType>(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<CategoryType>(element))
readCategoryStrings(nonstd::get<CategoryType>(element), strings);
else if(nonstd::holds_alternative<SectionType>(element))
readSectionStrings(nonstd::get<SectionType>(element), strings);
else if(nonstd::holds_alternative<GroupType>(element))
readGroupStrings(nonstd::get<GroupType>(element), strings);
else if(nonstd::holds_alternative<EntryType>(element))
readEntryStrings(nonstd::get<EntryType>(element), strings);
else
Q_UNREACHABLE();
}
strings.removeDuplicates();
if(!_srcFile.open(QIODevice::WriteOnly | QIODevice::Text))
throw FileException{_srcFile};
auto context = QFileInfo{inPath}.fileName();
_src << "#include <QtCore/QCoreApplication>\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<SectionType>(element))
readSectionStrings(nonstd::get<SectionType>(element), strings);
else if(nonstd::holds_alternative<GroupType>(element))
readGroupStrings(nonstd::get<GroupType>(element), strings);
else if(nonstd::holds_alternative<EntryType>(element))
readEntryStrings(nonstd::get<EntryType>(element), strings);
else
Q_UNREACHABLE();
}
}
void SettingsTranslator::readSectionStrings(const SectionType &section, QStringList &strings)
{
readInfoStrings(section, strings);
for(auto &element : section.content) {
if(nonstd::holds_alternative<GroupType>(element))
readGroupStrings(nonstd::get<GroupType>(element), strings);
else if(nonstd::holds_alternative<EntryType>(element))
readEntryStrings(nonstd::get<EntryType>(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<EntryType>(element))
readEntryStrings(nonstd::get<EntryType>(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);
}

10
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 &section, 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

Loading…
Cancel
Save