QtProtobuf: add QML support

Enable QML flag for qtgrpcgen/qtprotobufgen plugins.
Generated output is updated: QProtobufMessage classes are Q_GADGETs,
such classes can be registered in QML code via QML_VALUE_TYPE macros only.
Also QProtobufMessages are not inherited from QObject class, it means
there is no full qmetaobject system support (no signals!).

Task-number: QTBUG-104513
Change-Id: I18c8f93782884efb8d923843df716ff8284ed8fb
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Tatiana Borisova 2023-03-30 18:38:28 +02:00
parent b3cf2e9d63
commit 21e208ec96
7 changed files with 22 additions and 6 deletions

View File

@ -8,6 +8,7 @@ macro(_qt_internal_get_protoc_common_options option_args single_args multi_args)
set(${option_args}
COPY_COMMENTS
GENERATE_PACKAGE_SUBFOLDERS
QML
)
set(${single_args}
EXTRA_NAMESPACE

View File

@ -141,6 +141,10 @@ void MessageDeclarationPrinter::printClassDeclarationBegin()
} else {
m_printer->Print(m_typeMap, CommonTemplates::ClassMessageBeginDeclarationTemplate());
}
if (Options::instance().hasQml()) {
m_printer->Print(m_typeMap, CommonTemplates::ClassMessageQmlBeginDeclarationTemplate());
}
}
void MessageDeclarationPrinter::printMetaTypesDeclaration()

View File

@ -77,7 +77,7 @@ void QProtobufGenerator::GenerateSources(const FileDescriptor *file,
sourcePrinter->Print({{"include", "QtProtobuf/qprotobufserializer.h"}},
CommonTemplates::ExternalIncludeTemplate());
if (Options::instance().hasQml()) {
sourcePrinter->Print({{"include", "QQmlEngine"}},
sourcePrinter->Print({{"include", "QtQml/QQmlEngine"}},
CommonTemplates::ExternalIncludeTemplate());
}

View File

@ -61,8 +61,8 @@ const char *CommonTemplates::DefaultSystemIncludesTemplate()
const char *CommonTemplates::QmlProtobufIncludesTemplate()
{
return "#include <QtQml/QQmlListProperty>\n"
"#include <QtProtobufQuick/qtprotobufqmllistpropertyconstructor.h>\n\n";
return "#include <QtQml/qqmlregistration.h>\n"
"#include <QtQml/qqmllist.h>\n\n";
}
const char *CommonTemplates::DisclaimerTemplate()
@ -159,6 +159,12 @@ const char *CommonTemplates::ClassMessageForwardDeclarationTemplate()
{
return "class $classname$;\n";
}
const char *CommonTemplates::ClassMessageQmlBeginDeclarationTemplate()
{
return " QML_VALUE_TYPE($classname_low_case$)\n";
}
const char *CommonTemplates::ClassMessageBeginDeclarationTemplate()
{
return "\nclass $export_macro$ $classname$ : public QProtobufMessage\n"

View File

@ -42,6 +42,7 @@ public:
static const char *ClassMessageForwardDeclarationTemplate();
static const char *ClassMessageBeginDeclarationTemplate();
static const char *ClassMessageBeginDeclarationTemplateEmptyMacros();
static const char *ClassMessageQmlBeginDeclarationTemplate();
static const char *EmptyConstructorTemplate();
static const char *UseNamespace();

View File

@ -214,6 +214,7 @@ TypeMap common::produceMessageTypeMap(const Descriptor *type, const Descriptor *
const std::string initializer = "nullptr";
return { { "classname", name },
{ "classname_low_case", utils::deCapitalizeAsciiName(type->name()) },
{ "type", name },
{ "full_type", fullName },
{ "scope_type", scopeName },
@ -266,6 +267,7 @@ TypeMap common::produceEnumTypeMap(const EnumDescriptor *type, const Descriptor
std::string initializer = scopeName + "::" + type->value(0)->name();
return { { "classname", enumGadget },
{ "classname_low_case", utils::deCapitalizeAsciiName(enumGadget) },
{ "type", name },
{ "full_type", fullName },
{ "scope_type", scopeName },
@ -350,6 +352,7 @@ MethodMap common::produceMethodMap(const MethodDescriptor *method, const std::st
inputTypeName = utils::replace(inputTypeName, ".", "::");
outputTypeName = utils::replace(outputTypeName, ".", "::");
return { { "classname", scope }, { "return_type", outputTypeName },
{ "classname_low_case", utils::deCapitalizeAsciiName(scope) },
{ "method_name", methodName }, { "method_name_upper", methodNameUpper },
{ "param_type", inputTypeName }, { "param_name", "arg" },
{ "return_name", "ret" } };
@ -367,6 +370,7 @@ TypeMap common::produceServiceTypeMap(const ServiceDescriptor *service, const De
getFullNamespace(scope, "::"));
return { { "classname", name },
{ "classname_low_case", utils::deCapitalizeAsciiName(name) },
{ "full_type", fullName },
{ "scope_type", scopeName },
{ "scope_namespaces", scopeNamespaces },
@ -386,6 +390,7 @@ TypeMap common::produceClientTypeMap(const ServiceDescriptor *service, const Des
getFullNamespace(scope, "::"));
return { { "classname", name },
{ "classname_low_case", utils::deCapitalizeAsciiName(name) },
{ "full_type", fullName },
{ "scope_type", scopeName },
{ "scope_namespaces", scopeNamespaces },

View File

@ -51,9 +51,8 @@ void Options::setFromString(const std::string &options)
for (const auto &option : utils::split(options, ";")) {
QT_PROTOBUF_DEBUG("option: " << option);
if (option == QmlPluginOption) {
// TODO: Disable QML until the porting is complete.
// QT_PROTOBUF_DEBUG("set m_hasQml: true");
// instance.m_hasQml = true;
QT_PROTOBUF_DEBUG("set m_hasQml: true");
instance.m_hasQml = true;
} else if (option == CommentsGenerationOption) {
QT_PROTOBUF_DEBUG("set m_generateComments: true");
instance.m_generateComments = true;