From 21e208ec96495463875ec460e878947c47343d47 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova Date: Thu, 30 Mar 2023 18:38:28 +0200 Subject: [PATCH] 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 --- src/tools/qtprotobufgen/Qt6ProtobufToolsMacros.cmake | 1 + src/tools/qtprotobufgen/messagedeclarationprinter.cpp | 4 ++++ src/tools/qtprotobufgen/qprotobufgenerator.cpp | 2 +- src/tools/qtprotoccommon/commontemplates.cpp | 10 ++++++++-- src/tools/qtprotoccommon/commontemplates.h | 1 + src/tools/qtprotoccommon/generatorcommon.cpp | 5 +++++ src/tools/qtprotoccommon/options.cpp | 5 ++--- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/tools/qtprotobufgen/Qt6ProtobufToolsMacros.cmake b/src/tools/qtprotobufgen/Qt6ProtobufToolsMacros.cmake index 65da5672..731e0f33 100644 --- a/src/tools/qtprotobufgen/Qt6ProtobufToolsMacros.cmake +++ b/src/tools/qtprotobufgen/Qt6ProtobufToolsMacros.cmake @@ -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 diff --git a/src/tools/qtprotobufgen/messagedeclarationprinter.cpp b/src/tools/qtprotobufgen/messagedeclarationprinter.cpp index e17540bf..731e1a75 100644 --- a/src/tools/qtprotobufgen/messagedeclarationprinter.cpp +++ b/src/tools/qtprotobufgen/messagedeclarationprinter.cpp @@ -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() diff --git a/src/tools/qtprotobufgen/qprotobufgenerator.cpp b/src/tools/qtprotobufgen/qprotobufgenerator.cpp index 9775a4a9..d66b11a7 100644 --- a/src/tools/qtprotobufgen/qprotobufgenerator.cpp +++ b/src/tools/qtprotobufgen/qprotobufgenerator.cpp @@ -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()); } diff --git a/src/tools/qtprotoccommon/commontemplates.cpp b/src/tools/qtprotoccommon/commontemplates.cpp index 8fa6473e..a437abbd 100644 --- a/src/tools/qtprotoccommon/commontemplates.cpp +++ b/src/tools/qtprotoccommon/commontemplates.cpp @@ -61,8 +61,8 @@ const char *CommonTemplates::DefaultSystemIncludesTemplate() const char *CommonTemplates::QmlProtobufIncludesTemplate() { - return "#include \n" - "#include \n\n"; + return "#include \n" + "#include \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" diff --git a/src/tools/qtprotoccommon/commontemplates.h b/src/tools/qtprotoccommon/commontemplates.h index e4cdb0be..f1252a1b 100644 --- a/src/tools/qtprotoccommon/commontemplates.h +++ b/src/tools/qtprotoccommon/commontemplates.h @@ -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(); diff --git a/src/tools/qtprotoccommon/generatorcommon.cpp b/src/tools/qtprotoccommon/generatorcommon.cpp index 4502b38a..b07ecdf1 100644 --- a/src/tools/qtprotoccommon/generatorcommon.cpp +++ b/src/tools/qtprotoccommon/generatorcommon.cpp @@ -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 }, diff --git a/src/tools/qtprotoccommon/options.cpp b/src/tools/qtprotoccommon/options.cpp index 6b59d036..108be613 100644 --- a/src/tools/qtprotoccommon/options.cpp +++ b/src/tools/qtprotoccommon/options.cpp @@ -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;