diff options
author | Brett Stottlemyer <bstottle@ford.com> | 2017-05-19 15:21:40 -0400 |
---|---|---|
committer | Brett Stottlemyer <bstottle@ford.com> | 2017-05-19 19:26:32 +0000 |
commit | 97236fa44cb8067ed0193239a43154ae4a0b526d (patch) | |
tree | acff1e3784f0bc9bc3d090c2b927ffaa0f637b8e /tools | |
parent | eb1854b58d802a46405f68cef61a5b4450d01f4b (diff) |
Add MODEL keyword to repc
This change enables QAbstractItemModel types to be included in .rep files
as Source/Replica members. QtRO already handles QAIM types, but with an
overload of enableRemoting() and acquireModel() methods. If the goal of
the .rep file is to decribe the interface, the model should be part of the
interface as well.
For example, the following will include a QAbstractItemModel in the
forwarded data, passing the display role (Qt::DisplayRole). Note, it uses
QML roleNames (http://doc.qt.io/qt-5/qabstractitemmodel.html#roleNames)
class Media
{
ENUM state{Stopped, Paused, Playing}
PROP(QString currentTrack)
PROP(state playState)
MODEL tracks(display)
}
Future TODO - update docs for this feature and include ability to use with
a QItemSelectionModel. Potentially add something for default values in
the Replica until data is fetched.
Change-Id: I53a365fbc2bdb7fc5d3be19c1fb0d12e743050ee
Reviewed-by: Michael Brasser <michael.brasser@live.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/repc/repcodegenerator.cpp | 110 |
1 files changed, 104 insertions, 6 deletions
diff --git a/tools/repc/repcodegenerator.cpp b/tools/repc/repcodegenerator.cpp index 73bc532..c34c284 100644 --- a/tools/repc/repcodegenerator.cpp +++ b/tools/repc/repcodegenerator.cpp @@ -226,17 +226,32 @@ void RepCodeGenerator::generateHeader(Mode mode, QTextStream &out, const AST &as "#include <QtCore/qobject.h>\n" "#include <QtCore/qdatastream.h>\n" "#include <QtCore/qvariant.h>\n" - "#include <QtCore/qmetatype.h>\n" - "\n" - "#include <QtRemoteObjects/qremoteobjectnode.h>\n" - ; + "#include <QtCore/qmetatype.h>\n"; + bool hasModel = false; + for (auto c : ast.classes) + { + if (c.models.count() > 0) + { + hasModel = true; + break; + } + } + if (hasModel) + out << "#include <QtCore/qabstractitemmodel.h>\n"; + out << "\n" + "#include <QtRemoteObjects/qremoteobjectnode.h>\n"; + if (mode == MERGED) { out << "#include <QtRemoteObjects/qremoteobjectpendingcall.h>\n"; out << "#include <QtRemoteObjects/qremoteobjectreplica.h>\n"; out << "#include <QtRemoteObjects/qremoteobjectsource.h>\n"; + if (hasModel) + out << "#include <QtRemoteObjects/qremoteobjectabstractitemmodelreplica.h>\n"; } else if (mode == REPLICA) { out << "#include <QtRemoteObjects/qremoteobjectpendingcall.h>\n"; out << "#include <QtRemoteObjects/qremoteobjectreplica.h>\n"; + if (hasModel) + out << "#include <QtRemoteObjects/qremoteobjectabstractitemmodelreplica.h>\n"; } else out << "#include <QtRemoteObjects/qremoteobjectsource.h>\n"; out << "\n"; @@ -562,6 +577,12 @@ void RepCodeGenerator::generateClass(Mode mode, QTextStream &out, const ASTClass } out << ")" << endl; } + for (auto model : astClass.models) { + if (mode == REPLICA) + out << QString::fromLatin1(" Q_PROPERTY(QAbstractItemModelReplica *%1 READ %1 CONSTANT)").arg(model.name) << endl; + else + out << QString::fromLatin1(" Q_PROPERTY(QAbstractItemModel *%1 READ %1 CONSTANT)").arg(model.name) << endl; + } if (!astClass.enums.isEmpty()) { out << "" << endl; @@ -590,6 +611,9 @@ void RepCodeGenerator::generateClass(Mode mode, QTextStream &out, const ASTClass out << "private:" << endl; out << " " << className << "(QRemoteObjectNode *node, const QString &name = QString())" << endl; out << " : QRemoteObjectReplica(ConstructWithNode)" << endl; + for (auto model : astClass.models) + out << QString::fromLatin1(" , m_%1(node->acquireModel(\"%2::%1\"))") + .arg(model.name, astClass.name) << endl; out << " { initializeNode(node, name); }" << endl; out << "" << endl; @@ -617,7 +641,22 @@ void RepCodeGenerator::generateClass(Mode mode, QTextStream &out, const ASTClass out << " setProperties(properties);" << endl; out << " }" << endl; } else { - out << " explicit " << className << "(QObject *parent = nullptr) : QObject(parent)" << endl; + if (astClass.models.isEmpty() || mode == SOURCE) + out << " explicit " << className << "(QObject *parent = nullptr) : QObject(parent)" << endl; + else { + const QString modelParameterString = QStringLiteral("model%1"); + QStringList parametersForModels; + for (int i = 0; i < astClass.models.count(); i++) + parametersForModels << modelParameterString.arg(i+1); + out << " explicit " << className << "(QAbstractItemModel *" + << parametersForModels.join(QString::fromLatin1(", QAbstractItemModel *")) + << ", QObject *parent = nullptr) : QObject(parent)" << endl; + for (int i = 0; i < astClass.models.count(); i++) + { + out << " , m_" << astClass.models[i].name + << "(" << parametersForModels.at(i) << ")" << endl; + } + } if (mode == SIMPLE_SOURCE) { Q_FOREACH (const ASTProperty &property, astClass.properties) { @@ -702,6 +741,22 @@ void RepCodeGenerator::generateClass(Mode mode, QTextStream &out, const ASTClass } } + if (!astClass.models.isEmpty()) { + Q_FOREACH (const ASTModel &model, astClass.models) { + if (mode != SOURCE) { + if (mode == REPLICA) + out << " QAbstractItemModelReplica *" << model.name << "()" << endl; + else + out << " QAbstractItemModel *" << model.name << "()" << endl; + out << " {" << endl; + out << " return m_" << model.name << ".data();" << endl; + out << " }" << endl; + } else { + out << " virtual QAbstractItemModel *" << model.name << "() = 0;" << endl; + } + } + } + //Next output property signals if (!astClass.properties.isEmpty() || !astClass.signalsList.isEmpty()) { out << "" << endl; @@ -779,10 +834,16 @@ void RepCodeGenerator::generateClass(Mode mode, QTextStream &out, const ASTClass out << " " << property.type << " " << "_" << property.name << ";" << endl; } } + Q_FOREACH (const ASTModel &model, astClass.models) + out << " QScopedPointer<QAbstractItemModel> m_" << model.name << ";" << endl; } out << "" << endl; out << "private:" << endl; + if (mode == REPLICA) { + Q_FOREACH (const ASTModel &model, astClass.models) + out << " QScopedPointer<QAbstractItemModelReplica> m_" << model.name << ";" << endl; + } out << " friend class QT_PREPEND_NAMESPACE(QRemoteObjectNode);" << endl; out << "};" << endl; @@ -809,9 +870,11 @@ void RepCodeGenerator::generateSourceAPI(QTextStream &out, const ASTClass &astCl // Include enum definition in SourceAPI generateDeclarationsForEnums(out, astClass.enums, false); } - out << QString::fromLatin1(" %1()").arg(className) << endl; + out << QString::fromLatin1(" %1(ObjectType *object)").arg(className) << endl; out << QStringLiteral(" : SourceApiMap()") << endl; out << QStringLiteral(" {") << endl; + if (astClass.models.isEmpty()) + out << QStringLiteral(" Q_UNUSED(object);") << endl; const int propCount = astClass.properties.count(); out << QString::fromLatin1(" _properties[0] = %1;").arg(propCount) << endl; QStringList changeSignals; @@ -867,6 +930,12 @@ void RepCodeGenerator::generateSourceAPI(QTextStream &out, const ASTClass &astCl "static_cast<void (QObject::*)(%3)>(0),\"%2(%3)\",methodArgCount+%4,&methodArgTypes[%4]);") .arg(QString::number(i+pushCount+1), slot.name, slot.paramsAsString(ASTFunction::Normalized), QString::number(i+pushCount)) << endl; } + const int modelCount = astClass.models.count(); + out << QString::fromLatin1(" _modelCount = %1;").arg(modelCount) << endl; + for (int i = 0; i < modelCount; ++i) { + const ASTModel &model = astClass.models.at(i); + out << QString::fromLatin1(" _models[%1] = object->%2();").arg(QString::number(i), model.name) << endl; + } out << QStringLiteral(" }") << endl; out << QStringLiteral("") << endl; @@ -875,6 +944,7 @@ void RepCodeGenerator::generateSourceAPI(QTextStream &out, const ASTClass &astCl out << QStringLiteral(" int propertyCount() const override { return _properties[0]; }") << endl; out << QStringLiteral(" int signalCount() const override { return _signals[0]; }") << endl; out << QStringLiteral(" int methodCount() const override { return _methods[0]; }") << endl; + out << QStringLiteral(" int modelCount() const override { return _modelCount; }") << endl; out << QStringLiteral(" int sourcePropertyIndex(int index) const override") << endl; out << QStringLiteral(" {") << endl; out << QStringLiteral(" if (index < 0 || index >= _properties[0])") << endl; @@ -1041,6 +1111,34 @@ void RepCodeGenerator::generateSourceAPI(QTextStream &out, const ASTClass &astCl out << QString::fromLatin1(" int methodArgCount[%1];").arg(methodCount) << endl; out << QString::fromLatin1(" const int* methodArgTypes[%1];").arg(methodCount) << endl; } + out << QString::fromLatin1(" int _modelCount;") << endl; + if (modelCount > 0) + { + out << QString::fromLatin1(" QAbstractItemModel *_models[%1];").arg(modelCount) << endl; + out << " void modelSetup(QRemoteObjectHostBase *node) const override" << endl; + out << " {" << endl; + out << " QVector<int> roles;" << endl; + out << " int roleIndex;" << endl; + out << " QHash<int, QByteArray> knownRoles;" << endl; + for (int i = 0; i < astClass.models.count(); i++) + { + out << endl; + const ASTModel model = astClass.models.at(i); + out << " // Handle model #" << i+1 << " " << model.name << endl; + out << " roles.clear();" << endl; + out << " knownRoles = _models[" << i << "]->roleNames();" << endl; + for (auto role : model.roles) + { + out << " roleIndex = knownRoles.key(\"" << role.name << "\", -1);" << endl; + out << " if (roleIndex == -1)" << endl; + out << " qWarning() << " << QString::fromLatin1("\"Invalid role %1 for model %2\";").arg(role.name, model.name) << endl; + out << " else" << endl; + out << " roles << roleIndex;" << endl; + } + out << " node->enableRemoting(" << QString::fromLatin1("_models[%1], \"%2::%3\", roles, nullptr);").arg(QString::number(i), astClass.name, model.name) << endl; + } + out << " }" << endl; + } out << QStringLiteral("};") << endl; } |