From 12071b12048a3aca19e8fdda12552b97b8a6d455 Mon Sep 17 00:00:00 2001 From: arun3688 Date: Mon, 17 Oct 2022 19:37:50 +0200 Subject: [PATCH] add replaceSubModel() to GUI (#9469) * add replaceSubModel() to GUI * remove signals * move all actions and slot to Element class * minor fixes * remove header --- OMEdit/OMEditLIB/Element/Element.cpp | 13 ++ OMEdit/OMEditLIB/Element/Element.h | 3 + .../Modeling/ModelWidgetContainer.cpp | 12 ++ .../OMEditLIB/Modeling/ModelWidgetContainer.h | 1 + OMEdit/OMEditLIB/OMS/ModelDialog.cpp | 127 ++++++++++++++++++ OMEdit/OMEditLIB/OMS/ModelDialog.h | 23 ++++ OMEdit/OMEditLIB/OMS/OMSProxy.cpp | 20 +++ OMEdit/OMEditLIB/OMS/OMSProxy.h | 1 + 8 files changed, 200 insertions(+) diff --git a/OMEdit/OMEditLIB/Element/Element.cpp b/OMEdit/OMEditLIB/Element/Element.cpp index 1e41770e08b..71772d26328 100644 --- a/OMEdit/OMEditLIB/Element/Element.cpp +++ b/OMEdit/OMEditLIB/Element/Element.cpp @@ -2746,6 +2746,19 @@ void Element::createActions() mpElementPropertiesAction = new QAction(Helper::properties, mpGraphicsView); mpElementPropertiesAction->setStatusTip(tr("Shows the Properties dialog")); connect(mpElementPropertiesAction, SIGNAL(triggered()), SLOT(showElementPropertiesDialog())); + // ReplaceSubModel Action + mpReplaceSubModelAction = new QAction(ResourceCache::getIcon(":/Resources/icons/import-fmu.svg"), tr("Replace SubModel"), this); + mpReplaceSubModelAction->setStatusTip(tr("Replaces the SubModel, but retains the connections and parameters if valid")); + connect(mpReplaceSubModelAction, SIGNAL(triggered()), SLOT(showReplaceSubModelDialog())); +} + +/*! + * \brief Element::showReplaceSubModelDialog + * Slot that opens up the ReplaceSubModelDialog Dialog from GraphicsView. + */ +void Element::showReplaceSubModelDialog() +{ + mpGraphicsView->showReplaceSubModelDialog(this->getName()); } void Element::createResizerItems() diff --git a/OMEdit/OMEditLIB/Element/Element.h b/OMEdit/OMEditLIB/Element/Element.h index c2dda7dc088..4193c81e681 100644 --- a/OMEdit/OMEditLIB/Element/Element.h +++ b/OMEdit/OMEditLIB/Element/Element.h @@ -243,6 +243,7 @@ class Element : public QObject, public QGraphicsItem QAction* getOpenClassAction() {return mpOpenClassAction;} QAction* getSubModelAttributesAction() {return mpSubModelAttributesAction;} QAction* getElementPropertiesAction() {return mpElementPropertiesAction;} + QAction* getReplaceSubModelAction() {return mpReplaceSubModelAction;} ElementInfo* getElementInfo() {return mpElementInfo;} QList getShapesList() {return mShapesList;} QList getInheritedElementsList() {return mInheritedElementsList;} @@ -335,6 +336,7 @@ class Element : public QObject, public QGraphicsItem QAction *mpOpenClassAction; QAction *mpSubModelAttributesAction; QAction *mpElementPropertiesAction; + QAction *mpReplaceSubModelAction; ResizerItem *mpBottomLeftResizerItem; ResizerItem *mpTopLeftResizerItem; ResizerItem *mpTopRightResizerItem; @@ -432,6 +434,7 @@ public slots: void openClass(); void showSubModelAttributes(); void showElementPropertiesDialog(); + void showReplaceSubModelDialog(); void updateDynamicSelect(double time); void resetDynamicSelect(); protected: diff --git a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp index 151b69c3dfd..b2a581e0d26 100644 --- a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp +++ b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp @@ -3734,6 +3734,8 @@ void GraphicsView::omsOneComponentContextMenu(Element *pComponent, QMenu *pMenu) pMenu->addAction(mpRotateAntiClockwiseAction); pMenu->addAction(mpFlipHorizontalAction); pMenu->addAction(mpFlipVerticalAction); + pMenu->addSeparator(); + pMenu->addAction(pComponent->getReplaceSubModelAction()); } /*! @@ -4070,6 +4072,16 @@ void GraphicsView::flipVertical() mpModelWidget->endMacro(); } +/*! + * \brief GraphicsView::showReplaceSubModelDialog + * function that opens up the ReplaceSubModelDialog Dialog. + */ +void GraphicsView::showReplaceSubModelDialog(QString name) +{ + ReplaceSubModelDialog *pReplaceFMUDialog = new ReplaceSubModelDialog(this, name); + pReplaceFMUDialog->exec(); +} + /*! * \brief GraphicsView::createConnector * Creates a connector while making a connection.\n diff --git a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h index f24c1e7738f..617495c1511 100644 --- a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h +++ b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h @@ -350,6 +350,7 @@ class GraphicsView : public QGraphicsView void removeItem(QGraphicsItem *pGraphicsItem); void fitInViewInternal(); void emitResetDynamicSelect(); + void showReplaceSubModelDialog(QString name); private: void createActions(); bool isClassDroppedOnItself(LibraryTreeItem *pLibraryTreeItem); diff --git a/OMEdit/OMEditLIB/OMS/ModelDialog.cpp b/OMEdit/OMEditLIB/OMS/ModelDialog.cpp index 2fa016fe62b..f1572d1e8e4 100644 --- a/OMEdit/OMEditLIB/OMS/ModelDialog.cpp +++ b/OMEdit/OMEditLIB/OMS/ModelDialog.cpp @@ -440,6 +440,133 @@ void AddSubModelDialog::addSubModel() } } +/*! + * \class ReplaceSubModelDialog + * \Creates a dialog to allow users to replace a submodel to OMSimulator model. + * \brief ReplaceSubModelDialog::ReplaceSubModelDialog + * \param pGraphicsView + * \param path + * \param name + */ +ReplaceSubModelDialog::ReplaceSubModelDialog(GraphicsView *pGraphicsView, QString pName) + : QDialog(pGraphicsView) +{ + setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(QString("%1 - %2").arg(Helper::applicationName).arg("replaceSubModel")); + setMinimumWidth(400); + mpGraphicsView = pGraphicsView; + mpElementName = pName; + // set heading + mpHeading = Utilities::getHeadingLabel("replaceSubModel"); + // set separator line + mpHorizontalLine = Utilities::getHeadingLine(); + + // path + mpPathLabel = new Label(Helper::path); + mpPathTextBox = new QLineEdit(); + mpBrowsePathButton = new QPushButton(Helper::browse); + mpBrowsePathButton->setAutoDefault(false); + connect(mpBrowsePathButton, SIGNAL(clicked()), SLOT(browseSubModelPath())); + + // dryRun + mpDryRunLabel = new Label("dryRun:"); + mpDryRunLabel->setToolTip( tr("dryRun = true will not replace the subModel, you can see the list of warnings and dryRun = false will replace the SubModel")); + mpDryRunComboBox = new QComboBox; + mpDryRunComboBox->addItem("true"); + mpDryRunComboBox->addItem("false"); + + + // buttons + mpOkButton = new QPushButton(Helper::ok); + mpOkButton->setAutoDefault(true); + connect(mpOkButton, SIGNAL(clicked()), SLOT(replaceSubModel())); + mpCancelButton = new QPushButton(Helper::cancel); + mpCancelButton->setAutoDefault(false); + connect(mpCancelButton, SIGNAL(clicked()), SLOT(reject())); + + // add buttons to the button box + mpButtonBox = new QDialogButtonBox(Qt::Horizontal); + mpButtonBox->addButton(mpOkButton, QDialogButtonBox::ActionRole); + mpButtonBox->addButton(mpCancelButton, QDialogButtonBox::ActionRole); + + // set the layout + QGridLayout *pMainLayout = new QGridLayout; + pMainLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); + pMainLayout->addWidget(mpHeading, 0, 0, 1, 3); + pMainLayout->addWidget(mpHorizontalLine, 1, 0, 1, 3); + pMainLayout->addWidget(mpPathLabel, 2, 0); + pMainLayout->addWidget(mpPathTextBox, 2, 1); + pMainLayout->addWidget(mpBrowsePathButton, 2, 2); + pMainLayout->addWidget(mpDryRunLabel, 3, 0); + pMainLayout->addWidget(mpDryRunComboBox, 3, 1, 1, 2); + pMainLayout->addWidget(mpButtonBox, 4, 0, 1, 3, Qt::AlignRight); + setLayout(pMainLayout); +} + +/*! + * \brief ReplaceSubModelDialog::browseSubModelPath + * Allows the user to select the submodel path and returns it. + */ + +void ReplaceSubModelDialog::browseSubModelPath() +{ + QString path = StringHandler::getOpenFileName(this, QString("%1 - %2").arg(Helper::applicationName, Helper::chooseFile), NULL, Helper::subModelFileTypes, NULL); + if (!path.isEmpty()){ + mpPathTextBox->setText(path); + } +} + +/*! + * \brief ReplaceSubModelDialog::replaceSubModel + * replaces a submodel to the OMSimulator model, but still retains + * the connection and other variables and parameters if they are valid + */ +void ReplaceSubModelDialog::replaceSubModel() +{ + if (mpPathTextBox->text().isEmpty()) { + QMessageBox::critical(this, QString("%1 - %2").arg(Helper::applicationName, Helper::error), GUIMessages::getMessage(GUIMessages::ENTER_VALUE).arg(tr("ReplaceSubModel")), Helper::ok); + return; + } + + QFileInfo fileInfo(mpPathTextBox->text()); + if (!fileInfo.exists()) { + QMessageBox::critical(this, QString("%1 - %2").arg(Helper::applicationName, Helper::error), tr("Unable to find the SubModel file."), Helper::ok); + return; + } + + LibraryTreeItem *pParentLibraryTreeItem; + pParentLibraryTreeItem = mpGraphicsView->getModelWidget()->getLibraryTreeItem(); + + // add the submodel + QString nameStructure = QString("%1.%2").arg(pParentLibraryTreeItem->getNameStructure()).arg(mpElementName); + //qDebug() << "\nnamestructure : " << nameStructure << "==>" << mpDryRunComboBox->currentIndex(); + + bool dryRun; + if (mpDryRunComboBox->currentIndex() == 0){ + dryRun = true; + } else { + dryRun = false; + } + + bool failed = false; + int warningCount; + + if (OMSProxy::instance()->replaceSubModel(nameStructure, fileInfo.absoluteFilePath(), dryRun, &warningCount)) { + mpGraphicsView->getModelWidget()->createOMSimulatorUndoCommand(QString("replace submodel %1").arg(nameStructure)); + mpGraphicsView->getModelWidget()->updateModelText(); + accept(); + } else { + failed = true; + } + + // TODO remove the dryRun combo box check and always make the first run dryRun = true and warn users in case warnings exist + + if (failed) { + QMessageBox::critical(this, QString("%1 - %2").arg(Helper::applicationName, Helper::error), + tr("Failed to replace submodel. %1").arg(GUIMessages::getMessage(GUIMessages::CHECK_MESSAGES_BROWSER)), Helper::ok); + } +} + /*! * \class AddOrEditIconDialog * \brief Creates a dialog to allow users to add or edit icon for system or component. diff --git a/OMEdit/OMEditLIB/OMS/ModelDialog.h b/OMEdit/OMEditLIB/OMS/ModelDialog.h index 2aa416c2d06..866cecf3390 100644 --- a/OMEdit/OMEditLIB/OMS/ModelDialog.h +++ b/OMEdit/OMEditLIB/OMS/ModelDialog.h @@ -122,6 +122,29 @@ private slots: void addSubModel(); }; +class ReplaceSubModelDialog: public QDialog +{ + Q_OBJECT +public: + ReplaceSubModelDialog(GraphicsView *pGraphicsView, QString pName); +private: + GraphicsView *mpGraphicsView; + QString mpElementName; + Label *mpHeading; + QFrame *mpHorizontalLine; + Label *mpPathLabel; + QLineEdit *mpPathTextBox; + Label *mpDryRunLabel; + QComboBox *mpDryRunComboBox; + QPushButton *mpBrowsePathButton; + QPushButton *mpOkButton; + QPushButton *mpCancelButton; + QDialogButtonBox *mpButtonBox; +private slots: + void browseSubModelPath(); + void replaceSubModel(); +}; + class ShapeAnnotation; class AddOrEditIconDialog : public QDialog { diff --git a/OMEdit/OMEditLIB/OMS/OMSProxy.cpp b/OMEdit/OMEditLIB/OMS/OMSProxy.cpp index 0b29663f1d9..9c9dd4d865b 100644 --- a/OMEdit/OMEditLIB/OMS/OMSProxy.cpp +++ b/OMEdit/OMEditLIB/OMS/OMSProxy.cpp @@ -437,6 +437,26 @@ bool OMSProxy::addSubModel(QString cref, QString fmuPath) return statusToBool(status); } +/*! + * \brief OMSProxy::replaceSubModel + * \Adds the submodel to the system + * \param cref + * \param fmupath + * \param dryCount + * \param count + * \return + */ +bool OMSProxy::replaceSubModel(QString cref, QString fmuPath, bool dryCount, int *count) +{ + QString command = "oms_replaceSubModel"; + QStringList args; + args << "\"" + cref + "\"" << fmuPath << QString::number(dryCount); + LOG_COMMAND(command, args); + oms_status_enu_t status = oms_replaceSubModel(cref.toUtf8().constData(), fmuPath.toUtf8().constData(), dryCount, count); + logResponse(command, status, &commandTime); + return statusToBool(status); +} + /*! * \brief OMSProxy::createElementGeometryUsingPosition * Creates the element geometry using position. diff --git a/OMEdit/OMEditLIB/OMS/OMSProxy.h b/OMEdit/OMEditLIB/OMS/OMSProxy.h index e4c3e83d0d2..592e3a5cbb2 100644 --- a/OMEdit/OMEditLIB/OMS/OMSProxy.h +++ b/OMEdit/OMEditLIB/OMS/OMSProxy.h @@ -78,6 +78,7 @@ class OMSProxy : public QObject bool addConnectorToBus(QString busCref, QString connectorCref); bool addConnectorToTLMBus(QString busCref, QString connectorCref, QString type); bool addSubModel(QString cref, QString fmuPath); + bool replaceSubModel(QString cref, QString fmuPath, bool dryCount, int* count); void createElementGeometryUsingPosition(const QString &cref, QPointF position); bool addExternalTLMModel(QString cref, QString startScript, QString modelPath); bool addSystem(QString cref, oms_system_enu_t type);