void QrsMetamodelLoader::parseObjectsOnDiagram(const qrRepo::RepoApi &repo, Metamodel &metamodel, const Id &diagram) { if (diagram.isNull() || diagram == Id::rootId()) { return; } for (const Id &id : repo.children(diagram)) { if (!repo.isLogicalElement(id)) { continue; } const Id type = id.type(); if (type == metamodelEnumType) { parseEnum(repo, metamodel, id); } else if (type == metamodelPortType) { parsePort(repo, metamodel, id); } else if (type == metamodelGroupType) { parseGroup(repo, metamodel, diagram, id); } else if (type == metamodelImportType) { parseImport(repo, metamodel, id); } else if (type == metamodelNodeType) { parseNode(repo, metamodel, diagram, id); } else if (type == metamodelEdgeType) { parseEdge(repo, metamodel, diagram, id); } } }
PioneerGetLPSPosition::PioneerGetLPSPosition(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent) : BindingGenerator(repo, customizer, id, "quadcopterCommands/getLPSPosition.t" , { Binding::createConverting( "@@X@@" , "X" , customizer.factory()->stringPropertyConverter(id, "X")) , Binding::createConverting( "@@Y@@" , "Y" , customizer.factory()->stringPropertyConverter(id, "Y")) , Binding::createConverting( "@@Z@@" , "Z" , customizer.factory()->stringPropertyConverter(id, "Z")) } , parent) { customizer.factory()->functionBlockConverter(id, "")->convert( QString("%1 = 0;%2 = 0;%3 = 0;") .arg(repo.stringProperty(id, "X")) .arg(repo.stringProperty(id, "Y")) .arg(repo.stringProperty(id, "Z"))); }
QString QrsMetamodelLoader::stringProperty(const qrRepo::RepoApi &repo, const Id &id , const QString &propertyName, const QString &defaultValue) { if (!repo.hasProperty(id, propertyName)) { return defaultValue; } return repo.stringProperty(id, propertyName); }
bool QrsMetamodelLoader::boolProperty(const qrRepo::RepoApi &repo, const Id &id , const QString &propertyName, bool defaultValue) { if (!repo.hasProperty(id, propertyName)) { return defaultValue; } return repo.stringProperty(id, propertyName) == "true"; }
int QrsMetamodelLoader::intProperty(const qrRepo::RepoApi &repo, const Id &id , const QString &propertyName, int defaultValue) { if (!repo.hasProperty(id, propertyName)) { return defaultValue; } return parseInt(repo.stringProperty(id, propertyName), id); }
Id QrsMetamodelSaver::saveEdge(qrRepo::RepoApi &repo, const EdgeElementType &edge, const Id &diagram) { const Id edgeId = metamodelEdgeType.sameTypeId(); repo.addChild(diagram, edgeId); repo.setName(edgeId, edge.name()); repo.setProperty(edgeId, "displayedName", edge.friendlyName()); repo.setProperty(edgeId, "description", edge.description()); repo.setProperty(edgeId, "isDividable", edge.isDividable()); repo.setProperty(edgeId, "lineType", penStyleToString(edge.penStyle())); repo.setProperty(edgeId, "shape", linkShapeToString(edge.shapeType())); const QList<LabelProperties> &labels = edge.labels(); if (!labels.isEmpty()) { const LabelProperties &label = labels.first(); repo.setProperty(edgeId, "labelText", label.isStatic() ? label.text() : label.binding()); repo.setProperty(edgeId, "labelType", label.isStatic() ? "staticText" : "dynamicText"); repo.setProperty(edgeId, "hardLabel", label.isHard()); } saveAssociations(repo, edge, edgeId); saveProperties(repo, edge, edgeId); savePorts(repo, edge, edgeId, "from"); savePorts(repo, edge, edgeId, "to"); return edgeId; }
QList<QPair<QString, QString>> QrsMetamodelLoader::parseEnumValues(const qrRepo::RepoApi &repo, const Id &id) { QList<QPair<QString, QString>> result; for (const Id &child : repo.children(id)) { if (child.type() == metamodelEnumValueType && repo.isLogicalElement(child)) { result << qMakePair(validateName(repo, child), stringProperty(repo, child, "displayedName")); } } return result; }
VariableInitGenerator::VariableInitGenerator(qrRepo::RepoApi const &repo , GeneratorCustomizer &customizer , Id const &id , QObject *parent) : BindingGenerator(repo, customizer, id, "function.t" , { Binding::createStaticConverting("@@BODY@@" , repo.property(id, "variable").toString() + "=" + repo.property(id, "value").toString() , customizer.factory()->functionBlockConverter(id, "value")) } , parent) { }
SayGenerator::SayGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent) : BindingGenerator(repo, customizer, id , "say.t" , { repo.property(id, "Evaluate").toBool() ? Binding::createConverting("@@TEXT@@", "Text" , customizer.factory()->stringPropertyConverter(id, "Text")) : Binding::createStatic("@@TEXT@@", utils::StringUtils::wrap(repo.property(id, "Text").toString())) } , parent) { }
QVector<int> QrsMetamodelLoader::intVectorProperty(const qrRepo::RepoApi &repo, const Id &id , const QString &propertyName, const QVector<int> &defaultValue) { if (!repo.hasProperty(id, propertyName)) { return defaultValue; } const QStringList values = repo.stringProperty(id, propertyName).split(",", QString::SkipEmptyParts); QVector<int> result(values.size()); for (int i = 0; i < values.size(); ++i) { result[i] = parseInt(values[i], id); } return result; }
void Binding::apply(const qrRepo::RepoApi &repo , const Id &id, QString &data) { const QString property = mProperty.isEmpty() ? mValue : mProperty == "name" ? repo.name(id) : repo.property(id, mProperty).toString(); if (mConverter) { data.replace(mLabel, mConverter->convert(property)); } else { applyMulti(property, data); } }
QString QrsMetamodelLoader::validatePortName(const qrRepo::RepoApi &repo, const Id &id, const QString &name) { if (name == "NonTyped") { return name; } for (const Id &port : repo.elementsByType(metamodelPortType.element())) { if (repo.name(port) == name) { return name; } } emit errorOccured(tr("Port type %1 not declared in metamodel"), id); return "NonTyped"; }
void QrsMetamodelLoader::parseProperties(const qrRepo::RepoApi &repo, ElementType &element, const Id &id) { const IdList children = repo.children(id); for (const Id &child : children) { if (child.type() == metamodelAttributeType && repo.isLogicalElement(id)) { const QString type = repo.stringProperty(child, "attributeType"); element.addProperty(repo.name(child), type , stringProperty(repo, child, "defaultValue", "string") , stringProperty(repo, child, "displayedName") , stringProperty(repo, child, "description") , type == "reference"); } } }
void QrsMetamodelSaver::saveDiagram(qrRepo::RepoApi &repo, const Metamodel &metamodel , const QString &diagramName, const Id &metamodelId, Id &resultingId) { const Id diagramId = metamodelDiagramType.sameTypeId(); resultingId = diagramId; repo.addChild(metamodelId, diagramId); repo.setName(diagramId, diagramName); repo.setProperty(diagramId, "displayedName", metamodel.diagramFriendlyName(diagramName)); if (const ElementType *node = metamodel.diagramNode(diagramName)) { repo.setProperty(diagramId, "nodeName", node->name()); } QMap<const ElementType *, Id> elements; saveObjectsOnDiagram(repo, metamodel, diagramName, diagramId, elements); saveLinksInMetamodel(repo, metamodel, diagramName, diagramId, elements); }
void QrsMetamodelLoader::parseContainer(const qrRepo::RepoApi &repo, Metamodel &metamodel , const Id &id, const QString &diagram) { const Id from = repo.from(id); const Id to = repo.to(id); if (from.isNull() || to.isNull()) { qWarning() << "Containment link" << id << "is not connected!"; return; } const QString fromName = validateName(repo, from); const QString toName = validateName(repo, to); ElementType &fromElement = metamodel.elementType(diagram, fromName); ElementType &toElement = metamodel.elementType(diagram, toName); metamodel.produceEdge(fromElement, toElement, ElementType::containmentLinkType); }
void QrsMetamodelLoader::parseExplosion(const qrRepo::RepoApi &repo, Metamodel &metamodel , const Id &id, const QString &diagram) { const Id from = repo.from(id); const Id to = repo.to(id); if (from.isNull() || to.isNull()) { qWarning() << "Explosion" << id << "is not connected!"; return; } const QString fromName = validateName(repo, from); const QString toName = validateName(repo, to); ElementType &fromElement = metamodel.elementType(diagram, fromName); ElementType &toElement = metamodel.elementType(diagram, toName); metamodel.addExplosion(fromElement, toElement, boolProperty(repo, id, "makeReusable") , boolProperty(repo, id, "requireImmediateLinkage")); }
void QrsMetamodelLoader::parseContainerProperties(const qrRepo::RepoApi &repo, NodeElementType &node, const Id &id) { const IdList elements = repo.children(id); for (const Id &child : elements) { if (child.type() == metamodelPropertiesAsContainerType && repo.isLogicalElement(child)) { node.setContainer(true); node.setSizeOfForestalling(intVectorProperty(repo, child, "forestallingSize", {0,0,0,0})); node.setSizeOfChildrenForestalling(intProperty(repo, child, "childrenForestallingSize")); node.setSortingContainer(boolProperty(repo, child, "sortContainer")); node.setChildrenMovable(!boolProperty(repo, child, "banChildrenMove")); node.setMinimizesToChildren(boolProperty(repo, child, "minimizeToChildren")); node.setMaximizesChildren(boolProperty(repo, child, "maximizeChildren")); } } }
QString QrsMetamodelLoader::validateRootNode(const qrRepo::RepoApi &repo, const Id &diagram) { if (!repo.hasProperty(diagram, "nodeName")) { return QString(); } const QString rootNode = repo.property(diagram, "nodeName").toString(); for (const Id &child : repo.children(diagram)) { if (repo.name(child) == rootNode && (child.type() == metamodelNodeType || child.type() == metamodelGroupType)) { return rootNode; } } emit errorOccured(QObject::tr("Root node for diagram %1 (which is %2) does not exist!") .arg(repo.name(diagram)).arg(rootNode), diagram); return rootNode; }
PrintTextBlockGenerator::PrintTextBlockGenerator(const qrRepo::RepoApi &repo , GeneratorCustomizer &customizer , const Id &id , QObject *parent) : BindingGenerator(repo, customizer, id, "drawing/printText.t", QList<Binding *>() << Binding::createConverting("@@X@@", "XCoordinateText" , customizer.factory()->intPropertyConverter(id, "XCoordinateText")) << Binding::createConverting("@@Y@@", "YCoordinateText" , customizer.factory()->intPropertyConverter(id, "YCoordinateText")) << (repo.property(id, "Evaluate").toBool() ? Binding::createConverting("@@TEXT@@", "PrintText" , customizer.factory()->stringPropertyConverter(id, "PrintText")) : Binding::createStatic("@@TEXT@@" , utils::StringUtils::wrap(repo.stringProperty(id, "PrintText")))) , parent) { }
SystemGenerator::SystemGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent) : BindingGenerator(repo, customizer, id , repo.property(id, "Code").toBool() ? "nativeCode.t" : "system.t" , { repo.property(id, "Code").toBool() ? Binding::createStatic("@@COMMAND@@" , utils::StringUtils::dequote(repo.property(id, "Command").toString())) : repo.property(id, "Evaluate").toBool() ? Binding::createConverting("@@COMMAND@@", "Command" , customizer.factory()->stringPropertyConverter(id, "Command")) : Binding::createStatic("@@COMMAND@@" , utils::StringUtils::wrap(repo.property(id, "Command").toString())) } , parent) { }
void QrsMetamodelLoader::parseGroupNodes(const qrRepo::RepoApi &repo, QDomElement &parent, const Id &id) { /// @todo: We should not use XML here, PatternType must not parse XML at all. for (const Id &child : repo.children(id)) { if (repo.isLogicalElement(child)) { QDomElement groupNodeTag = parent.ownerDocument().createElement("groupNode"); groupNodeTag.setAttribute("name", validateName(repo, child)); groupNodeTag.setAttribute("parent", stringProperty(repo, child, "parent")); groupNodeTag.setAttribute("xPosition", stringProperty(repo, child, "xPosition")); groupNodeTag.setAttribute("yPosition", stringProperty(repo, child, "yPosition")); const Id typeElement = Id::loadFromString(stringProperty(repo, child, "type")); groupNodeTag.setAttribute("type", validateName(repo, typeElement)); parent.appendChild(groupNodeTag); } } }
void QrsMetamodelLoader::parseGeneralization(const qrRepo::RepoApi &repo, Metamodel &metamodel, const Id &id , const QString &diagram, ElementType *&fromElement, ElementType *&toElement, QString &overridingProperties) { const Id from = repo.from(id); const Id to = repo.to(id); if (from.isNull() || to.isNull()) { qWarning() << "Generalization" << id << "is not connected!"; return; } const QString fromName = validateName(repo, from); const QString toName = validateName(repo, to); fromElement = &metamodel.elementType(diagram, fromName); toElement = &metamodel.elementType(diagram, toName); metamodel.produceEdge(*toElement, *fromElement, ElementType::generalizationLinkType); overridingProperties = stringProperty(repo, id, "overrides"); }
InitCameraGenerator::InitCameraGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent) : BindingGenerator(repo, customizer, id , "videosensors/init" + repo.property(id, "Mode").toString() + "Sensor.t" , {} , parent) { }
PrintTextBlockGenerator::PrintTextBlockGenerator(const qrRepo::RepoApi &repo , GeneratorCustomizer &customizer , const Id &id , QObject *parent) : BindingGenerator(repo, customizer, id, "drawing/printText.t", { Binding::createConverting("@@X@@", "XCoordinateText" , customizer.factory()->intPropertyConverter(id, "XCoordinateText")) , Binding::createConverting("@@Y@@", "YCoordinateText" , customizer.factory()->intPropertyConverter(id, "YCoordinateText")) , (repo.property(id, "Evaluate").toBool() ? Binding::createConverting("@@TEXT@@", "PrintText" , customizer.factory()->stringPropertyConverter(id, "PrintText")) : Binding::createStatic("@@TEXT@@" , utils::StringUtils::wrap(repo.stringProperty(id, "PrintText")))) }, parent) { // Calling virtual readTemplate() before base class constructor will cause segfault. addBinding(Binding::createStatic("@@REDRAW@@", repo.property(id, "Redraw").toBool() ? readTemplate("drawing/redraw.t") : QString())); }
void QrsMetamodelLoader::parseNode(const qrRepo::RepoApi &repo , Metamodel &metamodel, const Id &diagram, const Id &id) { NodeElementType *node = new NodeElementType(metamodel); node->setName(validateName(repo, id)); node->setFriendlyName(repo.stringProperty(id, "displayedName")); node->setDiagram(repo.name(diagram)); node->setMouseGesture(stringProperty(repo, id, "path")); node->setDescription(stringProperty(repo, id, "description")); node->setHidden(boolProperty(repo, id, "abstract")); node->setResizable(boolProperty(repo, id, "isResizeable", true)); node->setCreateChildrenFromMenu(boolProperty(repo, id, "createChildrenFromMenu")); parseSdfGraphics(repo, *node, id); parseContainerProperties(repo, *node, id); parseProperties(repo, *node, id); metamodel.addElement(*node); }
ClearScreenBlockGenerator::ClearScreenBlockGenerator(const qrRepo::RepoApi &repo , GeneratorCustomizer &customizer , const Id &id , QObject *parent) : BindingGenerator(repo, customizer, id, "drawing/clearScreen.t" , {} , parent) { // Calling virtual readTemplate() before base class constructor will cause segfault. addBinding(Binding::createStatic("@@REDRAW@@", repo.property(id, "Redraw").toBool() ? readTemplate("drawing/redraw.t") : QString())); }
InitCameraGenerator::InitCameraGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent) : BindingGenerator(repo, customizer, id , "videosensors/init" + repo.property(id, "Mode").toString() + "Sensor.t" , { Binding::createConverting("@@DRAW@@" , "DrawStream", customizer.factory()->boolPropertyConverter(id, "DrawStream", false)) } , parent) { }
void QrsMetamodelLoader::parseEdge(const qrRepo::RepoApi &repo , Metamodel &metamodel, const Id &diagram, const Id &id) { EdgeElementType *edge = new EdgeElementType(metamodel); edge->setName(validateName(repo, id)); edge->setFriendlyName(repo.stringProperty(id, "displayedName")); edge->setDiagram(repo.name(diagram)); edge->setDescription(stringProperty(repo, id, "description")); edge->setDividable(boolProperty(repo, id, "isDividable")); edge->setPenWidth(1); edge->setPenColor(Qt::black); edge->setPenStyle(parsePenStyle(stringProperty(repo, id, "lineType"), id)); edge->setShapeType(parseLinkShape(stringProperty(repo, id, "shape"), id)); const QString labelText = stringProperty(repo, id, "labelText"); if (!labelText.isEmpty()) { LabelProperties label; const QString labelType = stringProperty(repo, id, "labelType"); if (labelType.contains("static", Qt::CaseInsensitive)) { label = LabelProperties(0, 0, 0, labelText, 0); } else if (labelType.contains("dynamic", Qt::CaseInsensitive)) { label = LabelProperties(0, 0, 0, labelText, false, 0); } else { emit errorOccured(tr("Incorrect label type"), id); } label.setHard(boolProperty(repo, id, "hardLabel")); edge->addLabel(label); } parseAssociations(repo, *edge, id); parseProperties(repo, *edge, id); parsePorts(repo, *edge, id, "from"); parsePorts(repo, *edge, id, "to"); metamodel.addElement(*edge); }
DrawRectGenerator::DrawRectGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent) : BindingGenerator(repo, customizer, id, (repo.stringProperty(id, "Filled") == "true") ? "drawing/drawFilledRect.t" : "drawing/drawRect.t" , { Binding::createConverting("@@XCoordinateRect@@", "XCoordinateRect" , customizer.factory()->intPropertyConverter(id, "XCoordinateRect")) , Binding::createConverting("@@YCoordinateRect@@", "YCoordinateRect" , customizer.factory()->intPropertyConverter(id, "YCoordinateRect")) , Binding::createConverting("@@WidthRect@@", "WidthRect" , customizer.factory()->intPropertyConverter(id, "WidthRect")) , Binding::createConverting("@@HeightRect@@", "HeightRect" , customizer.factory()->intPropertyConverter(id, "HeightRect")) } , parent) { addBinding(Binding::createStatic("@@REDRAW@@", repo.property(id, "Redraw").toBool() ? readTemplate("drawing/redraw.t") : QString())); }
void QrsMetamodelSaver::saveMetamodel(qrRepo::RepoApi &repo, const Metamodel &metamodel) { const Id metamodelId = metamodelRootDiagramType.sameTypeId(); repo.addChild(Id::rootId(), metamodelId); repo.setName(metamodelId, metamodel.id()); repo.setProperty(metamodelId, "displayedName", metamodel.friendlyName()); repo.setProperty(metamodelId, "version", metamodel.version()); Id lastDiagramId; for (const QString &diagram : metamodel.diagrams()) { saveDiagram(repo, metamodel, diagram, metamodelId, lastDiagramId); } if (lastDiagramId.isNull()) { // Metamodel contained no diagrams, nowhere to save enums and ports, giving up. return; } for (const QString &enumName : metamodel.enumNames()) { saveEnum(repo, metamodel, enumName, lastDiagramId); } }