diff --git a/OMEdit/OMEditLIB/Modeling/MessagesWidget.cpp b/OMEdit/OMEditLIB/Modeling/MessagesWidget.cpp index 5e0ec871907..8559093b087 100644 --- a/OMEdit/OMEditLIB/Modeling/MessagesWidget.cpp +++ b/OMEdit/OMEditLIB/Modeling/MessagesWidget.cpp @@ -563,15 +563,17 @@ SimulationOutputWidget* MessagesWidget::getSimulationOutputWidget(const QString */ bool MessagesWidget::closeTab(int index) { + // Close SimulationOutputWidget SimulationOutputWidget *pSimulationOutputWidget = qobject_cast(mpMessagesTabWidget->widget(index)); - if (pSimulationOutputWidget && !pSimulationOutputWidget->isCompilationProcessRunning() && !pSimulationOutputWidget->isSimulationProcessRunning()) { + if (pSimulationOutputWidget + && !pSimulationOutputWidget->isCompilationProcessRunning() + && !pSimulationOutputWidget->isPostCompilationProcessRunning() + && !pSimulationOutputWidget->isSimulationProcessRunning()) { mpMessagesTabWidget->removeTab(index); - if (pSimulationOutputWidget->getSimulationOptions().isInteractiveSimulation()) { - MainWindow::instance()->getSimulationDialog()->removeSimulationOutputWidget(pSimulationOutputWidget); - } emit messageTabClosed(index); return true; } + // Close OMSSimulationOutputWidget OMSSimulationOutputWidget *pOMSSimulationOutputWidget = qobject_cast(mpMessagesTabWidget->widget(index)); if (pOMSSimulationOutputWidget && !pOMSSimulationOutputWidget->isSimulationProcessRunning()) { mpMessagesTabWidget->removeTab(index); diff --git a/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.cpp b/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.cpp index cb0e5b4a604..c647b6484c8 100644 --- a/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.cpp +++ b/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.cpp @@ -275,6 +275,22 @@ bool PlotWindowContainer::eventFilter(QObject *pObject, QEvent *pEvent) return QMdiArea::eventFilter(pObject, pEvent); } +/*! + * \brief PlotWindowContainer::removePlotCurves + * Removes all the plot curves from PlotWindow + * \param pPlotWindow + */ +void PlotWindowContainer::removePlotCurves(PlotWindow *pPlotWindow) +{ + int i = 0; + while(i != pPlotWindow->getPlot()->getPlotCurvesList().size()) { + PlotCurve *pPlotCurve = pPlotWindow->getPlot()->getPlotCurvesList()[i]; + pPlotWindow->getPlot()->removeCurve(pPlotCurve); + pPlotCurve->detach(); + i = 0; //Restart iteration + } +} + /*! * \brief PlotWindowContainer::addPlotWindow * Adds a new Plot Window. @@ -521,7 +537,7 @@ void PlotWindowContainer::removeInteractivePlotWindow() { PlotWindow *pPlotWindow = qobject_cast(sender()); QString owner = pPlotWindow->getInteractiveOwner(); - MainWindow::instance()->getVariablesWidget()->getVariablesTreeModel()->removeVariableTreeItem(owner); + MainWindow::instance()->getVariablesWidget()->getVariablesTreeModel()->removeVariableTreeItem(owner, false); } /*! @@ -561,13 +577,7 @@ void PlotWindowContainer::clearPlotWindow() tr("No plot window is active for clearing curves."), Helper::ok); return; } - int i = 0; - while(i != pPlotWindow->getPlot()->getPlotCurvesList().size()) { - PlotCurve *pPlotCurve = pPlotWindow->getPlot()->getPlotCurvesList()[i]; - pPlotWindow->getPlot()->removeCurve(pPlotCurve); - pPlotCurve->detach(); - i = 0; //Restart iteration - } + removePlotCurves(pPlotWindow); pPlotWindow->fitInView(); MainWindow::instance()->getVariablesWidget()->updateVariablesTreeHelper(subWindowList(QMdiArea::ActivationHistoryOrder).last()); } diff --git a/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.h b/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.h index 6b37ac55d5a..950523ab9e6 100644 --- a/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.h +++ b/OMEdit/OMEditLIB/Plotting/PlotWindowContainer.h @@ -67,6 +67,7 @@ class PlotWindowContainer : public QMdiArea bool isDiagramWindow(QObject *pObject); bool isUniqueName(QString name); bool eventFilter(QObject *pObject, QEvent *pEvent); + void removePlotCurves(OMPlot::PlotWindow *pPlotWindow); private: void addRenameTabToSubWindowSystemMenu(QMdiSubWindow *pMdiSubWindow); DiagramWindow *mpDiagramWindow; diff --git a/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp b/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp index 7821090038f..60e8c2908ce 100644 --- a/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp +++ b/OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp @@ -630,9 +630,10 @@ void VariablesTreeModel::parseInitXml(QXmlStreamReader &xmlReader, SimulationOpt * \brief VariablesTreeModel::removeVariableTreeItem * Removes the VariablesTreeItem. * \param variable + * \param closeInteractivePlotWindow * \return */ -bool VariablesTreeModel::removeVariableTreeItem(QString variable) +bool VariablesTreeModel::removeVariableTreeItem(QString variable, bool closeInteractivePlotWindow) { VariablesTreeItem *pVariablesTreeItem = findVariablesTreeItem(variable, mpRootVariablesTreeItem); if (pVariablesTreeItem) { @@ -647,14 +648,8 @@ bool VariablesTreeModel::removeVariableTreeItem(QString variable) pVariablesTreeItem->removeChildren(); VariablesTreeItem *pParentVariablesTreeItem = pVariablesTreeItem->parent(); pParentVariablesTreeItem->removeChild(pVariablesTreeItem); - - if (pVariablesTreeItem->getSimulationOptions().isInteractiveSimulation()) { - // remove the right interactive simulation output widget - SimulationOutputWidget *pSimulationOutputWidget = MessagesWidget::instance()->getSimulationOutputWidget(pVariablesTreeItem->getFileName()); - if (pSimulationOutputWidget) { - MainWindow::instance()->getSimulationDialog()->removeSimulationOutputWidget(pSimulationOutputWidget); - } - } + MainWindow::instance()->getSimulationDialog()->removeInteractiveSimulation(pVariablesTreeItem->getSimulationOptions().isInteractiveSimulation(), + pVariablesTreeItem->getFileName(), closeInteractivePlotWindow); if (pVariablesTreeItem) { delete pVariablesTreeItem; } @@ -795,7 +790,7 @@ bool VariablesTreeModel::insertVariablesItems(QString fileName, QString filePath * But don't make them checkable so user can't plot them. */ QStringList variableListFromResultFile; - if (readingVariablesFromInitFile) { + if (readingVariablesFromInitFile && !simulationOptions.isInteractiveSimulation()) { variableListFromResultFile = MainWindow::instance()->getOMCProxy()->readSimulationResultVars(QString("%1%2%3").arg(filePath, QDir::separator(), fileName)); } QStringList variables; @@ -1231,7 +1226,7 @@ void VariablesTreeModel::removeVariableTreeItem() { QAction *pAction = qobject_cast(sender()); if (pAction) { - removeVariableTreeItem(pAction->data().toString()); + removeVariableTreeItem(pAction->data().toString(), true); emit variableTreeItemRemoved(pAction->data().toString()); } } @@ -1409,7 +1404,7 @@ void VariablesTreeView::keyPressEvent(QKeyEvent *event) index = mpVariablesWidget->getVariableTreeProxyModel()->mapToSource(index); VariablesTreeItem *pVariablesTreeItem = static_cast(index.internalPointer()); if (event->key() == Qt::Key_Delete && pVariablesTreeItem->isRootItem()) { - mpVariablesWidget->getVariablesTreeModel()->removeVariableTreeItem(pVariablesTreeItem->getVariableName()); + mpVariablesWidget->getVariablesTreeModel()->removeVariableTreeItem(pVariablesTreeItem->getVariableName(), true); return; } } @@ -1565,10 +1560,6 @@ void VariablesWidget::insertVariablesItemsToTree(QString fileName, QString fileP mpVariableTreeProxyModel->setFilterRegExp(QRegExp("")); // insert the plot variables bool updateVariables = mpVariablesTreeModel->insertVariablesItems(fileName, filePath, variablesList, simulationOptions); - // handle interactive re-simulation - if (simulationOptions.isInteractiveSimulation() && simulationOptions.isReSimulate()) { - interactiveReSimulation(simulationOptions.getClassName()); - } // update the plot variables tree if (updateVariables) { variablesUpdated(); @@ -1704,24 +1695,6 @@ void VariablesWidget::updateVariablesTreeHelper(QMdiSubWindow *pSubWindow) mpVariableTreeProxyModel->invalidate(); } -void VariablesWidget::interactiveReSimulation(QString modelName) -{ - QList selectedVariables = mSelectedInteractiveVariables.value(modelName); - - foreach (QString variable, selectedVariables) { - QString curveNameStructure = modelName + "." + variable; - VariablesTreeItem *pVariableTreeItem; - pVariableTreeItem = mpVariablesTreeModel->findVariablesTreeItem(curveNameStructure, mpVariablesTreeModel->getRootVariablesTreeItem()); - if (pVariableTreeItem) { - bool state = mpVariablesTreeModel->blockSignals(true); - QModelIndex index = mpVariablesTreeModel->variablesTreeItemIndex(pVariableTreeItem); - mpVariablesTreeModel->setData(index, Qt::Checked, Qt::CheckStateRole); - plotVariables(index, 1, 1, false); - mpVariablesTreeModel->blockSignals(state); - } - } -} - /*! * \brief VariablesWidget::readVariablesAndUpdateXML * Reads the updated values @@ -1800,16 +1773,13 @@ void VariablesWidget::reSimulate(bool showSetup) pVariablesTreeItem = pVariablesTreeItem->rootParent(); SimulationOptions simulationOptions = pVariablesTreeItem->getSimulationOptions(); if (simulationOptions.isValid()) { - if (simulationOptions.isInteractiveSimulation()) { - QMessageBox::information(this, QString("%1 - %2").arg(Helper::applicationName, Helper::information), tr("You cannot re-simulate an interactive simulation."), Helper::ok); + MainWindow::instance()->getSimulationDialog()->removeInteractiveSimulation(simulationOptions.isInteractiveSimulation(), pVariablesTreeItem->getFileName(), false); + simulationOptions.setReSimulate(true); + updateInitXmlFile(pVariablesTreeItem, simulationOptions); + if (showSetup) { + MainWindow::instance()->getSimulationDialog()->show(0, true, simulationOptions); } else { - simulationOptions.setReSimulate(true); - updateInitXmlFile(simulationOptions); - if (showSetup) { - MainWindow::instance()->getSimulationDialog()->show(0, true, simulationOptions); - } else { - MainWindow::instance()->getSimulationDialog()->reSimulate(simulationOptions); - } + MainWindow::instance()->getSimulationDialog()->reSimulate(simulationOptions); } } else { QMessageBox::information(this, QString("%1 - %2").arg(Helper::applicationName, Helper::information), @@ -1817,7 +1787,13 @@ void VariablesWidget::reSimulate(bool showSetup) } } -void VariablesWidget::updateInitXmlFile(SimulationOptions simulationOptions) +/*! + * \brief VariablesWidget::updateInitXmlFile + * Updates the model_init.xml file + * \param pVariablesTreeItem + * \param simulationOptions + */ +void VariablesWidget::updateInitXmlFile(VariablesTreeItem *pVariablesTreeItem, SimulationOptions simulationOptions) { /* Update the _init.xml file with new values. */ /* open the model_init.xml file for writing */ @@ -1826,11 +1802,9 @@ void VariablesWidget::updateInitXmlFile(SimulationOptions simulationOptions) QDomDocument initXmlDocument; if (initFile.open(QIODevice::ReadOnly)) { if (initXmlDocument.setContent(&initFile)) { - VariablesTreeItem *pTopVariableTreeItem; - pTopVariableTreeItem = mpVariablesTreeModel->findVariablesTreeItem(simulationOptions.getFullResultFileName(), mpVariablesTreeModel->getRootVariablesTreeItem()); - if (pTopVariableTreeItem) { + if (pVariablesTreeItem) { QHash > variables; - readVariablesAndUpdateXML(pTopVariableTreeItem, simulationOptions.getFullResultFileName(), &variables); + readVariablesAndUpdateXML(pVariablesTreeItem, simulationOptions.getFullResultFileName(), &variables); findVariableAndUpdateValue(initXmlDocument, variables); } } else { @@ -2303,11 +2277,6 @@ void VariablesWidget::plotVariables(const QModelIndex &index, qreal curveThickne } } -void VariablesWidget::addSelectedInteractiveVariables(const QString &modelName, const QList &selectedVariables) -{ - mSelectedInteractiveVariables.insert(modelName, selectedVariables); -} - /*! * \brief VariablesWidget::unitChanged * Handles the case when display unit is changed in VariablesTreeView.\n diff --git a/OMEdit/OMEditLIB/Plotting/VariablesWidget.h b/OMEdit/OMEditLIB/Plotting/VariablesWidget.h index 75aa74f1de2..3a35bd6e0ff 100644 --- a/OMEdit/OMEditLIB/Plotting/VariablesWidget.h +++ b/OMEdit/OMEditLIB/Plotting/VariablesWidget.h @@ -161,7 +161,7 @@ class VariablesTreeModel : public QAbstractItemModel QModelIndex variablesTreeItemIndex(const VariablesTreeItem *pVariablesTreeItem) const; bool insertVariablesItems(QString fileName, QString filePath, QStringList variablesList, SimulationOptions simulationOptions); void parseInitXml(QXmlStreamReader &xmlReader, SimulationOptions simulationOptions, QStringList *variablesList); - bool removeVariableTreeItem(QString variable); + bool removeVariableTreeItem(QString variable, bool closeInteractivePlotWindow); void unCheckVariables(VariablesTreeItem *pVariablesTreeItem); void plotAllVariables(VariablesTreeItem *pVariablesTreeItem, OMPlot::PlotWindow *pPlotWindow); private: @@ -226,15 +226,13 @@ class VariablesWidget : public QWidget VariablesTreeView* getVariablesTreeView() {return mpVariablesTreeView;} void enableVisualizationControls(bool enable); void insertVariablesItemsToTree(QString fileName, QString filePath, QStringList variablesList, SimulationOptions simulationOptions); - void addSelectedInteractiveVariables(const QString &modelName, const QList &selectedVariables); void variablesUpdated(); void updateVariablesTreeHelper(QMdiSubWindow *pSubWindow); void readVariablesAndUpdateXML(VariablesTreeItem *pVariablesTreeItem, QString outputFileName, QHash > *variables); void findVariableAndUpdateValue(QDomDocument xmlDocument, QHash > variables); void reSimulate(bool showSetup); - void interactiveReSimulation(QString modelName); - void updateInitXmlFile(SimulationOptions simulationOptions); + void updateInitXmlFile(VariablesTreeItem *pVariablesTreeItem, SimulationOptions simulationOptions); void initializeVisualization(); void updateVisualization(); void updatePlotWindows(); @@ -260,7 +258,6 @@ class VariablesWidget : public QWidget VariablesTreeModel *mpVariablesTreeModel; VariablesTreeView *mpVariablesTreeView; QVector mPlotParametricCurves; - QHash> mSelectedInteractiveVariables; QMdiSubWindow *mpLastActiveSubWindow; ModelicaMatReader mModelicaMatReader; csv_data *mpCSVData; diff --git a/OMEdit/OMEditLIB/Simulation/OpcUaClient.cpp b/OMEdit/OMEditLIB/Simulation/OpcUaClient.cpp index fbf7e02f019..8271c0b8c58 100644 --- a/OMEdit/OMEditLIB/Simulation/OpcUaClient.cpp +++ b/OMEdit/OMEditLIB/Simulation/OpcUaClient.cpp @@ -83,18 +83,28 @@ OpcUaClient::~OpcUaClient() /*! Connect to an OPC UA server. */ -bool OpcUaClient::connectToServer() +bool OpcUaClient::connectToServer(QString *pErrorString) { std::string endPoint = "opc.tcp://localhost:" + std::to_string(mSimulationOptions.getInteractiveSimulationPortNumber()); mpClient = UA_Client_new(UA_ClientConfig_standard); UA_StatusCode returnValue; + int tries = 0; do { Sleep::msleep(100); - // QCoreApplication::processEvents(QEventLoop::AllEvents, 100); returnValue = UA_Client_connect(mpClient, endPoint.c_str()); + ++tries; + if (tries > 50) { // Do not go in infinte loop. Try 50 times i.e., 5 secs max and then give up. + break; + } } while (returnValue != UA_STATUSCODE_GOOD); // qDebug() << "Connected to OPC-UA server " << endPoint; - return true; + if (returnValue != UA_STATUSCODE_GOOD) { + *pErrorString = tr("Could not connect to the embedded server. Status code %1.").arg(QString(UA_StatusCode_name(returnValue))); + return false; + } else { + *pErrorString = QString(UA_StatusCode_name(returnValue)); + return true; + } } /*! @@ -454,10 +464,10 @@ void OpcUaWorker::checkMinMaxValues(const double& value) { if (value < mMinMaxValues.first) { mMinMaxValues.first = value; - emit sendUpdateYAxis(mMinMaxValues.first, mMinMaxValues.second); + emit sendUpdateYAxis(qMakePair(mMinMaxValues.first, mMinMaxValues.second)); } else if ( value > mMinMaxValues.second ) { mMinMaxValues.second = value; - emit sendUpdateYAxis(mMinMaxValues.first, mMinMaxValues.second); + emit sendUpdateYAxis(qMakePair(mMinMaxValues.first, mMinMaxValues.second)); } } diff --git a/OMEdit/OMEditLIB/Simulation/OpcUaClient.h b/OMEdit/OMEditLIB/Simulation/OpcUaClient.h index 868c76a6f01..95d0b19263f 100644 --- a/OMEdit/OMEditLIB/Simulation/OpcUaClient.h +++ b/OMEdit/OMEditLIB/Simulation/OpcUaClient.h @@ -16,7 +16,7 @@ class OpcUaClient : public QObject OpcUaClient(SimulationOptions simulationOptions); ~OpcUaClient(); - bool connectToServer(); + bool connectToServer(QString *pErrorString); QStringList fetchVariableNamesFromServer(); QMap *getVariables() {return &mVariables;} UA_Client* getClient() {return mpClient;} @@ -96,7 +96,7 @@ private slots: UA_UInt32 mSubscriptionId; signals: void sendUpdateCurves(); - void sendUpdateYAxis(double, double); + void sendUpdateYAxis(QPair minMaxValues); void sendAddMonitoredItem(int, QString); void sendRemoveMonitoredItem(QString); }; diff --git a/OMEdit/OMEditLIB/Simulation/SimulationDialog.cpp b/OMEdit/OMEditLIB/Simulation/SimulationDialog.cpp index 11182aad20e..b9557ddf2d6 100644 --- a/OMEdit/OMEditLIB/Simulation/SimulationDialog.cpp +++ b/OMEdit/OMEditLIB/Simulation/SimulationDialog.cpp @@ -132,33 +132,6 @@ void SimulationDialog::directSimulate(LibraryTreeItem *pLibraryTreeItem, bool la mpSaveSimulationFlagsAnnotationCheckBox->setChecked(simuationFlagsCheckState); } -/*! - * \brief SimulationDialog::removeSimulationOutputWidget - * Remove the simulation output widget. - * \param pSimulationOutputWidget - */ -void SimulationDialog::removeSimulationOutputWidget(SimulationOutputWidget* pSimulationOutputWidget) -{ - // close the window - // remove the old opc ua instance - int port = pSimulationOutputWidget->getSimulationOptions().getInteractiveSimulationPortNumber(); - if (mOpcUaClientsMap.contains(port)) { - OMPlot::PlotWindow *pPlotWindow = mOpcUaClientsMap.value(pSimulationOutputWidget->getSimulationOptions().getInteractiveSimulationPortNumber())->getTargetPlotWindow(); - if (pPlotWindow) { - pPlotWindow->parentWidget()->close(); - } - delete mOpcUaClientsMap.value(port); - mOpcUaClientsMap.remove(port); - } - // Kill the compilation and simulation processes if they are running. - if (pSimulationOutputWidget->isCompilationProcessRunning() && pSimulationOutputWidget->getCompilationProcess()) { - pSimulationOutputWidget->getCompilationProcess()->kill(); - } - if (pSimulationOutputWidget->isSimulationProcessRunning() && pSimulationOutputWidget->getSimulationProcess()) { - pSimulationOutputWidget->getSimulationProcess()->kill(); - } -} - /*! Creates all the controls and set their layout. */ @@ -622,7 +595,10 @@ bool SimulationDialog::validate() * Check if there is already active simulation running of this model. */ SimulationOutputWidget *pSimulationOutputWidget = MessagesWidget::instance()->getSimulationOutputWidget(mClassName); - if (pSimulationOutputWidget && (pSimulationOutputWidget->isCompilationProcessRunning() || pSimulationOutputWidget->isSimulationProcessRunning())) { + if (pSimulationOutputWidget + && (pSimulationOutputWidget->isCompilationProcessRunning() + || pSimulationOutputWidget->isPostCompilationProcessRunning() + || pSimulationOutputWidget->isSimulationProcessRunning())) { QMessageBox::critical(MainWindow::instance(), QString("%1 - %2").arg(Helper::applicationName, Helper::error), tr("Simulation of model %1 is already running. Please wait for it to finish or cancel it before running another simulation of the same model.") .arg(mClassName), Helper::ok); @@ -1218,6 +1194,8 @@ SimulationOptions SimulationDialog::createSimulationOptions() if (!mpInteractiveSimulationGroupBox->isChecked()) { if (!mpResultFileNameTextBox->text().isEmpty()) { simulationOptions.setResultFileName(mpResultFileNameTextBox->text()); + } else { + simulationOptions.setResultFileName(""); } } else { // set an invalid result file name to avoid interactive simulations to destroy previous results @@ -1389,7 +1367,15 @@ SimulationOptions SimulationDialog::createSimulationOptions() simulationFlags.append(QString("-embeddedServerPort=").append(QString::number(portNumber))); // if the user enters a used port if (mOpcUaClientsMap.contains(portNumber)) { - killSimulationProcess(portNumber); + OpcUaClient *pOpcUaClient = getOpcUaClient(portNumber); + if (pOpcUaClient && pOpcUaClient->getSimulationOptions().getClassName().compare(simulationOptions.getClassName()) != 0) { + MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, + tr("Port %1 is already in use for interactive simulation of %2. Cannot run the interactive simulation.") + .arg(QString::number(portNumber), pOpcUaClient->getSimulationOptions().getClassName()), + Helper::scriptingKind, Helper::notificationLevel)); + simulationOptions.setIsValid(false); + return simulationOptions; // return from here without setting valid for SimulationOptions + } } } } @@ -1418,9 +1404,6 @@ void SimulationDialog::createAndShowSimulationOutputWidget(const SimulationOptio if (simulationOptions.isReSimulate() && simulationOptions.getLaunchAlgorithmicDebugger()) { showAlgorithmicDebugger(simulationOptions); } else { - if (simulationOptions.isReSimulate() && simulationOptions.isInteractiveSimulation()) { - removeVariablesFromTree(simulationOptions.getClassName()); - } SimulationOutputWidget *pSimulationOutputWidget = new SimulationOutputWidget(simulationOptions); MessagesWidget::instance()->addSimulationOutputTab(pSimulationOutputWidget, simulationOptions.getOutputFileName()); pSimulationOutputWidget->start(); @@ -1811,150 +1794,112 @@ void SimulationDialog::showVariableFilterHelp() QDesktopServices::openUrl(variabeFilterHelpPath); } -/*! - * \brief SimulationDialog::simulationStarted - * This slot makes a call for diabling parameter changes during a simulation \n - * and update the control buttons. \n - */ -void SimulationDialog::simulationStarted() -{ - setInteractiveControls(false); -} - -/*! - * \brief SimulationDialog::simulationStarted - * This slot makes a call for diabling parameter changes during a simulation \n - * and update the control buttons. \n - */ -void SimulationDialog::simulationPaused() -{ - setInteractiveControls(true); -} - -void SimulationDialog::updateInteractiveSimulationCurves() -{ - OMPlot::PlotWindow* window = MainWindow::instance()->getPlotWindowContainer()->getCurrentWindow(); - if (window) { - window->updateCurves(); - } -} - -void SimulationDialog::updateYAxis(double min, double max) +void SimulationDialog::stopInteractiveSimulationSampling(SimulationOptions simulationOptions) { - OMPlot::PlotWindow* window = MainWindow::instance()->getPlotWindowContainer()->getCurrentWindow(); - if (window) { - window->updateYAxis(qMakePair(min, max)); - } -} - -void SimulationDialog::removeVariablesFromTree(QString className) -{ - MainWindow::instance()->getVariablesWidget()->getVariablesTreeModel()->removeVariableTreeItem(className); -} - -/*! - * \brief SimulationDialog::setInteractiveControls - * \param enabled - * Sets the graphical response depending on the parameter enabled. \n - * true = started, false = paused \n - */ -void SimulationDialog::setInteractiveControls(bool enabled) -{ - int port = MainWindow::instance()->getPlotWindowContainer()->getCurrentWindow()->getInteractivePort(); - OpcUaClient *pOpcUaClient = getOpcUaClient(port); - if (pOpcUaClient) { - // control buttons - pOpcUaClient->getTargetPlotWindow()->getStartSimulationButton()->setEnabled(enabled); - pOpcUaClient->getTargetPlotWindow()->getPauseSimulationButton()->setEnabled(!enabled); - //plotpicker - pOpcUaClient->getTargetPlotWindow()->getPlot()->getPlotPicker()->setEnabled(enabled); + if (simulationOptions.isInteractiveSimulation()) { + OpcUaClient *pOpcUaClient = getOpcUaClient(simulationOptions.getInteractiveSimulationPortNumber()); + if (pOpcUaClient && pOpcUaClient->getSampleThread()) { + pOpcUaClient->getSampleThread()->exit(); + } + if (pOpcUaClient && pOpcUaClient->getOpcUaWorker()) { + pOpcUaClient->getOpcUaWorker()->pauseInteractiveSimulation(); + } } } /*! - * \brief SimulationDialog::killSimulationProcess - * \param port - * If another executable is running over the port, kill it. \n + * \brief VariablesWidget::removeInteractiveSimulation + * Stops the interatice simulation and removes the OpcUaClient associated to it. + * \param isInteractiveSimulation + * \param className + * \param closeInteractivePlotWindow */ -void SimulationDialog::killSimulationProcess(int port) +void SimulationDialog::removeInteractiveSimulation(bool isInteractiveSimulation, QString className, bool closeInteractivePlotWindow) { - std::string endPoint = "opc.tcp://localhost:" + std::to_string(port); - UA_Client *pClient = UA_Client_new(UA_ClientConfig_standard); - UA_StatusCode returnValue = UA_Client_connect(pClient, endPoint.c_str()); - - if (returnValue == UA_STATUSCODE_GOOD) { - removeVariablesFromTree(mOpcUaClientsMap.value(port)->getSimulationOptions().getClassName()); - - foreach (SimulationOutputWidget *pSimulationOutputWidget, mSimulationOutputWidgetsList) { - if (pSimulationOutputWidget->getSimulationOptions().getInteractiveSimulationPortNumber() == port) { - removeSimulationOutputWidget(pSimulationOutputWidget); - break; + if (isInteractiveSimulation) { + className.remove(QRegExp("_res.int")); + SimulationOutputWidget *pSimulationOutputWidget = MessagesWidget::instance()->getSimulationOutputWidget(className); + if (pSimulationOutputWidget) { + pSimulationOutputWidget->cancelCompilationOrSimulation(); + } + // remove the opc ua instance + if (closeInteractivePlotWindow) { + int port = pSimulationOutputWidget->getSimulationOptions().getInteractiveSimulationPortNumber(); + if (mOpcUaClientsMap.contains(port)) { + OpcUaClient *pOpcUaClient = getOpcUaClient(port); + if (pOpcUaClient) { + OMPlot::PlotWindow *pPlotWindow = pOpcUaClient->getTargetPlotWindow(); + if (pPlotWindow) { + pPlotWindow->parentWidget()->close(); + } + mOpcUaClientsMap.remove(port); + delete pOpcUaClient; + } } } } - UA_Client_disconnect(pClient); - UA_Client_delete(pClient); } /*! * \brief SimulationDialog::createOpcUaClient - * \param simulationOptions * Creates a OpcUaClient object when embedded server is up and running. \n + * \param simulationOptions + * \param pErrorString + * \return */ -void SimulationDialog::createOpcUaClient(SimulationOptions simulationOptions) +bool SimulationDialog::createOpcUaClient(SimulationOptions simulationOptions, QString *pErrorString) { OpcUaClient *pOpcUaClient = new OpcUaClient(simulationOptions); - if (pOpcUaClient->connectToServer()) { - // create the sample thread - OpcUaWorker *pOpcUaWorker = new OpcUaWorker(pOpcUaClient, simulationOptions.isInteractiveSimulationWithSteps()); - pOpcUaClient->setOpcUaWorker(pOpcUaWorker); - pOpcUaWorker->moveToThread(pOpcUaClient->getSampleThread()); - pOpcUaClient->getSampleThread()->start(); - - connect(pOpcUaWorker, SIGNAL(sendUpdateCurves()), SLOT(updateInteractiveSimulationCurves())); - connect(pOpcUaWorker, SIGNAL(sendUpdateYAxis(double, double)), SLOT(updateYAxis(double, double))); - connect(pOpcUaWorker, SIGNAL(sendAddMonitoredItem(int,QString)), pOpcUaWorker, SLOT(addMonitoredItem(int,QString))); - connect(pOpcUaWorker, SIGNAL(sendRemoveMonitoredItem(QString)), pOpcUaWorker, SLOT(removeMonitoredItem(QString))); - - // insert the newly created OpcUaClient to the data structure - mOpcUaClientsMap.insert(simulationOptions.getInteractiveSimulationPortNumber(), pOpcUaClient); - - // determine the model owner of the interactive plot window - QString owner = simulationOptions.getClassName(); - PlotWindowContainer* pPlotWindowContainer = MainWindow::instance()->getPlotWindowContainer(); - OMPlot::PlotWindow* pInteractivePlotWindow = pPlotWindowContainer->addInteractivePlotWindow(true, owner, simulationOptions.getInteractiveSimulationPortNumber()); - connect(pInteractivePlotWindow->getStartSimulationButton(), SIGNAL(clicked()), pOpcUaWorker, SLOT(startInteractiveSimulation())); - connect(pInteractivePlotWindow->getPauseSimulationButton(), SIGNAL(clicked()), pOpcUaWorker, SLOT(pauseInteractiveSimulation())); - connect(pInteractivePlotWindow->getSimulationSpeedBox(), SIGNAL(editTextChanged(QString)), pOpcUaWorker, SLOT(setSpeed(QString))); - - // make graphical responses from the main thread - connect(pInteractivePlotWindow->getStartSimulationButton(), SIGNAL(clicked(bool)), SLOT(simulationStarted())); - connect(pInteractivePlotWindow->getPauseSimulationButton(), SIGNAL(clicked(bool)), SLOT(simulationPaused())); - - pOpcUaClient->setTargetPlotWindow(pInteractivePlotWindow); - - // fetch variables - QStringList list = pOpcUaClient->fetchVariableNamesFromServer(); - VariablesWidget *pVariablesWidget = MainWindow::instance()->getVariablesWidget(); - // insert them into the tree structure - pVariablesWidget->insertVariablesItemsToTree(simulationOptions.getClassName(), simulationOptions.getWorkingDirectory(), list, simulationOptions); - // remember the variablestreeitem root pointer - foreach (VariablesTreeItem *pVariablesTreeItem, pVariablesWidget->getVariablesTreeModel()->getRootVariablesTreeItem()->mChildren) { - if (pVariablesTreeItem->getFileName() == simulationOptions.getClassName()) { - pOpcUaWorker->setVariablesTreeItemRoot(pVariablesTreeItem); - } - } - - MainWindow::instance()->switchToPlottingPerspectiveSlot(); + if (!pOpcUaClient->connectToServer(pErrorString)) { + return false; + } + // create the sample thread + OpcUaWorker *pOpcUaWorker = new OpcUaWorker(pOpcUaClient, simulationOptions.isInteractiveSimulationWithSteps()); + pOpcUaClient->setOpcUaWorker(pOpcUaWorker); + pOpcUaWorker->moveToThread(pOpcUaClient->getSampleThread()); + pOpcUaClient->getSampleThread()->start(); + + connect(pOpcUaWorker, SIGNAL(sendAddMonitoredItem(int,QString)), pOpcUaWorker, SLOT(addMonitoredItem(int,QString))); + connect(pOpcUaWorker, SIGNAL(sendRemoveMonitoredItem(QString)), pOpcUaWorker, SLOT(removeMonitoredItem(QString))); + // insert the newly created OpcUaClient to the data structure + mOpcUaClientsMap.insert(simulationOptions.getInteractiveSimulationPortNumber(), pOpcUaClient); + // determine the model owner of the interactive plot window + QString owner = simulationOptions.getResultFileName(); + PlotWindowContainer* pPlotWindowContainer = MainWindow::instance()->getPlotWindowContainer(); + OMPlot::PlotWindow* pInteractivePlotWindow = MainWindow::instance()->getPlotWindowContainer()->getInteractiveWindow(owner); + // if we have a pInteractivePlotWindow then clear it + if (pInteractivePlotWindow) { + MainWindow::instance()->getPlotWindowContainer()->removePlotCurves(pInteractivePlotWindow); + MainWindow::instance()->getPlotWindowContainer()->setActiveSubWindow(pInteractivePlotWindow->getSubWindow()); + pInteractivePlotWindow->interactiveSimulationPaused(); } else { - MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, "Could not connect to the embedded server.", - Helper::scriptingKind, Helper::errorLevel)); + pInteractivePlotWindow = pPlotWindowContainer->addInteractivePlotWindow(true, owner, simulationOptions.getInteractiveSimulationPortNumber()); + } + connect(pOpcUaWorker, SIGNAL(sendUpdateCurves()), pInteractivePlotWindow, SLOT(updateCurves())); + qRegisterMetaType>(); + connect(pOpcUaWorker, SIGNAL(sendUpdateYAxis(QPair)), pInteractivePlotWindow, SLOT(updateYAxis(QPair))); + connect(pInteractivePlotWindow->getStartSimulationButton(), SIGNAL(clicked()), pOpcUaWorker, SLOT(startInteractiveSimulation())); + connect(pInteractivePlotWindow->getPauseSimulationButton(), SIGNAL(clicked()), pOpcUaWorker, SLOT(pauseInteractiveSimulation())); + connect(pInteractivePlotWindow->getSimulationSpeedBox(), SIGNAL(editTextChanged(QString)), pOpcUaWorker, SLOT(setSpeed(QString))); + pOpcUaClient->setTargetPlotWindow(pInteractivePlotWindow); + // fetch variables + QStringList list = pOpcUaClient->fetchVariableNamesFromServer(); + VariablesWidget *pVariablesWidget = MainWindow::instance()->getVariablesWidget(); + // insert them into the tree structure + pVariablesWidget->insertVariablesItemsToTree(simulationOptions.getResultFileName(), simulationOptions.getWorkingDirectory(), list, simulationOptions); + // remember the variablestreeitem root pointer + foreach (VariablesTreeItem *pVariablesTreeItem, pVariablesWidget->getVariablesTreeModel()->getRootVariablesTreeItem()->mChildren) { + if (pVariablesTreeItem->getFileName() == simulationOptions.getClassName()) { + pOpcUaWorker->setVariablesTreeItemRoot(pVariablesTreeItem); + } } + MainWindow::instance()->switchToPlottingPerspectiveSlot(); + return true; } OpcUaClient* SimulationDialog::getOpcUaClient(int port) { - return mOpcUaClientsMap.value(port); + return mOpcUaClientsMap.value(port, nullptr); } /*! @@ -1966,17 +1911,6 @@ OpcUaClient* SimulationDialog::getOpcUaClient(int port) */ void SimulationDialog::simulationProcessFinished(SimulationOptions simulationOptions, QDateTime resultFileLastModifiedDateTime) { - // Simulation is over, the sampling thread should stop sampling... - if (simulationOptions.isInteractiveSimulation()) { - OpcUaClient *pOpcUaClient = getOpcUaClient(simulationOptions.getInteractiveSimulationPortNumber()); - if (pOpcUaClient && pOpcUaClient->getSampleThread()) { - pOpcUaClient->getSampleThread()->exit(); - } - if (pOpcUaClient && pOpcUaClient->getOpcUaWorker()) { - pOpcUaClient->getOpcUaWorker()->pauseInteractiveSimulation(); - } - return; - } QString workingDirectory = simulationOptions.getWorkingDirectory(); QRegExp regExp(Helper::omResultFileTypesRegExp); bool resultFileKnown = regExp.indexIn(simulationOptions.getFullResultFileName()) != -1; @@ -2195,42 +2129,44 @@ void SimulationDialog::simulate() { if (validate()) { SimulationOptions simulationOptions = createSimulationOptions(); - // If we are not doing a re-simulation then save the new SimulationOptions in the class. - if (!mIsReSimulate) { - mpLibraryTreeItem->mSimulationOptions = simulationOptions; - } - // interactive simulation - if (mpInteractiveSimulationGroupBox->isChecked() || mIsReSimulate) { - performSimulation(simulationOptions); - } else { - // if no option is selected then show error message to user - if (!(mpSaveExperimentAnnotationCheckBox->isChecked() || - mpSaveTranslationFlagsAnnotationCheckBox->isChecked() || - mpSaveSimulationFlagsAnnotationCheckBox->isChecked() || - mpSimulateCheckBox->isChecked())) { - QMessageBox::information(this, QString("%1 - %2").arg(Helper::applicationName).arg(Helper::information), - GUIMessages::getMessage(GUIMessages::SELECT_SIMULATION_OPTION), Helper::ok); - return; - } - if ((mpLibraryTreeItem->getModelWidget() && mpSaveExperimentAnnotationCheckBox->isChecked()) || - mpSaveTranslationFlagsAnnotationCheckBox->isChecked() || mpSaveSimulationFlagsAnnotationCheckBox->isChecked()) { - mpLibraryTreeItem->getModelWidget()->beginMacro("Simulation settings"); - } - if (mpSaveExperimentAnnotationCheckBox->isChecked()) { - saveExperimentAnnotation(); - } - if (mpSaveTranslationFlagsAnnotationCheckBox->isChecked()) { - saveTranslationFlagsAnnotation(); + if (simulationOptions.isValid()) { + // If we are not doing a re-simulation then save the new SimulationOptions in the class. + if (!mIsReSimulate) { + mpLibraryTreeItem->mSimulationOptions = simulationOptions; } - if (mpSaveSimulationFlagsAnnotationCheckBox->isChecked()) { - saveSimulationFlagsAnnotation(); - } - if ((mpLibraryTreeItem->getModelWidget() && mpSaveExperimentAnnotationCheckBox->isChecked()) || - mpSaveTranslationFlagsAnnotationCheckBox->isChecked() || mpSaveSimulationFlagsAnnotationCheckBox->isChecked()) { - mpLibraryTreeItem->getModelWidget()->endMacro(); - } - if (mpSimulateCheckBox->isChecked()) { + // interactive simulation + if (mpInteractiveSimulationGroupBox->isChecked() || mIsReSimulate) { performSimulation(simulationOptions); + } else { + // if no option is selected then show error message to user + if (!(mpSaveExperimentAnnotationCheckBox->isChecked() || + mpSaveTranslationFlagsAnnotationCheckBox->isChecked() || + mpSaveSimulationFlagsAnnotationCheckBox->isChecked() || + mpSimulateCheckBox->isChecked())) { + QMessageBox::information(this, QString("%1 - %2").arg(Helper::applicationName).arg(Helper::information), + GUIMessages::getMessage(GUIMessages::SELECT_SIMULATION_OPTION), Helper::ok); + return; + } + if ((mpLibraryTreeItem->getModelWidget() && mpSaveExperimentAnnotationCheckBox->isChecked()) || + mpSaveTranslationFlagsAnnotationCheckBox->isChecked() || mpSaveSimulationFlagsAnnotationCheckBox->isChecked()) { + mpLibraryTreeItem->getModelWidget()->beginMacro("Simulation settings"); + } + if (mpSaveExperimentAnnotationCheckBox->isChecked()) { + saveExperimentAnnotation(); + } + if (mpSaveTranslationFlagsAnnotationCheckBox->isChecked()) { + saveTranslationFlagsAnnotation(); + } + if (mpSaveSimulationFlagsAnnotationCheckBox->isChecked()) { + saveSimulationFlagsAnnotation(); + } + if ((mpLibraryTreeItem->getModelWidget() && mpSaveExperimentAnnotationCheckBox->isChecked()) || + mpSaveTranslationFlagsAnnotationCheckBox->isChecked() || mpSaveSimulationFlagsAnnotationCheckBox->isChecked()) { + mpLibraryTreeItem->getModelWidget()->endMacro(); + } + if (mpSimulateCheckBox->isChecked()) { + performSimulation(simulationOptions); + } } } if (isVisible()) { diff --git a/OMEdit/OMEditLIB/Simulation/SimulationDialog.h b/OMEdit/OMEditLIB/Simulation/SimulationDialog.h index ab68b88bd39..aca26749c8d 100644 --- a/OMEdit/OMEditLIB/Simulation/SimulationDialog.h +++ b/OMEdit/OMEditLIB/Simulation/SimulationDialog.h @@ -67,7 +67,6 @@ class SimulationDialog : public QDialog void show(LibraryTreeItem *pLibraryTreeItem, bool isReSimulate, SimulationOptions simulationOptions); void directSimulate(LibraryTreeItem *pLibraryTreeItem, bool launchTransformationalDebugger, bool launchAlgorithmicDebugger, bool launchAnimation, bool enableDataReconciliation); OpcUaClient* getOpcUaClient(int port); - void removeSimulationOutputWidget(SimulationOutputWidget* pSimulationOutputWidget); private: Label *mpSimulationHeading; QFrame *mpHorizontalLine; @@ -202,14 +201,13 @@ class SimulationDialog : public QDialog void saveTranslationFlagsAnnotation(); void performSimulation(const SimulationOptions &simulationOptions); void saveDialogGeometry(); - void killSimulationProcess(int port); - void removeVariablesFromTree(QString className); - void setInteractiveControls(bool enabled); public: + void stopInteractiveSimulationSampling(SimulationOptions simulationOptions); + void removeInteractiveSimulation(bool isInteractiveSimulation, QString className, bool closeInteractivePlotWindow); void reSimulate(SimulationOptions simulationOptions); void showAlgorithmicDebugger(SimulationOptions simulationOptions); void simulationProcessFinished(SimulationOptions simulationOptions, QDateTime resultFileLastModifiedDateTime); - void createOpcUaClient(SimulationOptions simulationOptions); + bool createOpcUaClient(SimulationOptions simulationOptions, QString *pErrorString); public slots: void numberOfIntervalsRadioToggled(bool toggle); void intervalRadioToggled(bool toggle); @@ -222,13 +220,9 @@ public slots: void showSimulationFlagsHelp(); void simulate(); void reject(); - void updateInteractiveSimulationCurves(); - void updateYAxis(double min, double max); private slots: void resultFileNameChanged(QString text); void showVariableFilterHelp(); - void simulationStarted(); - void simulationPaused(); }; class DataReconciliationDialog : public QDialog diff --git a/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.cpp b/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.cpp index f5970b882bf..1dd57e8aad5 100644 --- a/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.cpp +++ b/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.cpp @@ -538,7 +538,10 @@ void SimulationOutputWidget::writeSimulationMessage(SimulationMessage *pSimulati */ void SimulationOutputWidget::embeddedServerInitialized() { - MainWindow::instance()->getSimulationDialog()->createOpcUaClient(mSimulationOptions); + QString errorString; + if (!MainWindow::instance()->getSimulationDialog()->createOpcUaClient(mSimulationOptions, &errorString)) { + writeSimulationOutput(errorString, StringHandler::Error, true); + } } /*! @@ -987,6 +990,7 @@ void SimulationOutputWidget::cancelCompilationOrSimulation() if (isCompilationProcessRunning()) { setCompilationProcessKilled(true); mpCompilationProcess->kill(); + mIsCompilationProcessRunning = false; progressStr = tr("Compilation of %1 is cancelled.").arg(mSimulationOptions.getClassName()); mpProgressBar->setRange(0, 1); mpProgressBar->setValue(0); @@ -995,6 +999,7 @@ void SimulationOutputWidget::cancelCompilationOrSimulation() } else if (isPostCompilationProcessRunning()) { setPostCompilationProcessKilled(true); mpPostCompilationProcess->kill(); + mIsPostCompilationProcessRunning = false; progressStr = tr("Post compilation of %1 is cancelled.").arg(mSimulationOptions.getClassName()); mpProgressBar->setRange(0, 1); mpProgressBar->setValue(0); @@ -1003,6 +1008,7 @@ void SimulationOutputWidget::cancelCompilationOrSimulation() } else if (isSimulationProcessRunning()) { setSimulationProcessKilled(true); mpSimulationProcess->kill(); + mIsSimulationProcessRunning = false; progressStr = tr("Simulation of %1 is cancelled.").arg(mSimulationOptions.getClassName()); mpCancelButton->setEnabled(false); mpArchivedSimulationItem->setStatus(Helper::finished); @@ -1260,6 +1266,7 @@ void SimulationOutputWidget::simulationProcessFinished(int exitCode, QProcess::E if (mSocketState != SocketState::Connected) { simulationProcessFinishedHelper(); } + MainWindow::instance()->getSimulationDialog()->stopInteractiveSimulationSampling(mSimulationOptions); } /*! diff --git a/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.h b/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.h index b23396fd9e0..99fc48fa833 100644 --- a/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.h +++ b/OMEdit/OMEditLIB/Simulation/SimulationOutputWidget.h @@ -153,7 +153,6 @@ class SimulationOutputWidget : public QWidget void simulationProcessFinishedHelper(); QString getPathsFromBatFile(QString fileName); private slots: - void cancelCompilationOrSimulation(); void openTransformationalDebugger(); void openSimulationLogFile(); void createSimulationProgressSocket(); @@ -175,6 +174,7 @@ private slots: void simulationProcessError(QProcess::ProcessError error); void simulationProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); public slots: + void cancelCompilationOrSimulation(); void openTransformationBrowser(QUrl url); signals: void simulationFinished(); diff --git a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp index 226d3fdc520..09c5c6717d1 100644 --- a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp +++ b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp @@ -296,6 +296,7 @@ void PlotWindow::setupToolbar() mpStartSimulationToolButton->setIcon(QIcon(":/Resources/icons/play_animation.svg")); mpStartSimulationToolButton->setToolTip(tr("Start")); mpStartSimulationToolButton->setAutoRaise(true); + connect(mpStartSimulationToolButton, SIGNAL(clicked(bool)), SLOT(interactiveSimulationStarted())); // pause tool button mpPauseSimulationToolButton = new QToolButton; mpPauseSimulationToolButton->setEnabled(false); @@ -303,6 +304,7 @@ void PlotWindow::setupToolbar() mpPauseSimulationToolButton->setIcon(QIcon(":/Resources/icons/pause.svg")); mpPauseSimulationToolButton->setToolTip(tr("Pause")); mpPauseSimulationToolButton->setAutoRaise(true); + connect(mpPauseSimulationToolButton, SIGNAL(clicked(bool)), SLOT(interactiveSimulationPaused())); // speed label and combo box mpSimulationSpeedLabel = new QLabel(tr("Speed:")); QDoubleValidator *pDoubleValidator = new QDoubleValidator(this); @@ -1398,22 +1400,6 @@ void PlotWindow::setTitle(QString title) mpPlot->setTitle(title); } -void PlotWindow::updateCurves() -{ - for (auto & p : mpPlot->getPlotCurvesList()) { - // append the last point to the plotting curve - p->getPlotDirectPainter()->drawSeries(p, p->getSize() - 2, -1); - } -} - -void PlotWindow::updateYAxis(QPair minMaxValues) -{ - // replot if a value is out of bounds - if (minMaxValues.first < mpPlot->axisScaleDiv(QwtPlot::yLeft).lowerBound() || minMaxValues.second > mpPlot->axisScaleDiv(QwtPlot::yLeft).upperBound()) { - mpPlot->replot(); - } -} - /*! * \brief PlotWindow::updatePlot * This function is called by OMEdit when auto scale is false. @@ -1428,6 +1414,15 @@ void PlotWindow::updatePlot() } } +void PlotWindow::setInteractiveControls(bool enabled) +{ + // control buttons + mpStartSimulationToolButton->setEnabled(enabled); + mpPauseSimulationToolButton->setEnabled(!enabled); + //plotpicker + mpPlot->getPlotPicker()->setEnabled(enabled); +} + void PlotWindow::setGrid(QString grid) { if (grid.toLower().compare("detailed") == 0) { @@ -1667,6 +1662,22 @@ void PlotWindow::closeEvent(QCloseEvent *event) event->accept(); } +void PlotWindow::updateCurves() +{ + for (auto & p : mpPlot->getPlotCurvesList()) { + // append the last point to the plotting curve + p->getPlotDirectPainter()->drawSeries(p, p->getSize() - 2, -1); + } +} + +void PlotWindow::updateYAxis(QPair minMaxValues) +{ + // replot if a value is out of bounds + if (minMaxValues.first < mpPlot->axisScaleDiv(QwtPlot::yLeft).lowerBound() || minMaxValues.second > mpPlot->axisScaleDiv(QwtPlot::yLeft).upperBound()) { + mpPlot->replot(); + } +} + void PlotWindow::enableZoomMode(bool on) { mpPlot->getPlotZoomer()->setEnabled(on); @@ -1874,6 +1885,16 @@ void PlotWindow::showSetupDialog(QString variable) pSetupDialog->exec(); } +void PlotWindow::interactiveSimulationStarted() +{ + setInteractiveControls(false); +} + +void PlotWindow::interactiveSimulationPaused() +{ + setInteractiveControls(true); +} + /*! \class VariablePageWidget \brief Represent the attribute of a plot variable. diff --git a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h index 700e983f43d..86cc9fe842f 100644 --- a/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h +++ b/OMPlot/OMPlot/OMPlotGUI/PlotWindow.h @@ -208,12 +208,14 @@ class PlotWindow : public QMainWindow void setTime(double time){mTime = time;} double getTime() {return mTime;} void updateTimeText(); - void updateCurves(); - void updateYAxis(QPair minMaxValues); void updatePlot(); +private: + void setInteractiveControls(bool enabled); signals: void closingDown(); public slots: + void updateCurves(); + void updateYAxis(QPair minMaxValues); void enableZoomMode(bool on); void enablePanMode(bool on); void exportDocument(); @@ -226,6 +228,8 @@ public slots: bool toggleSign(PlotCurve *pPlotCurve, bool checked); void showSetupDialog(); void showSetupDialog(QString variable); + void interactiveSimulationStarted(); + void interactiveSimulationPaused(); }; //Exception classes