diff --git a/HopsanGUI/GUIConnector.cpp b/HopsanGUI/GUIConnector.cpp index 183c5eadf..7d1530b60 100644 --- a/HopsanGUI/GUIConnector.cpp +++ b/HopsanGUI/GUIConnector.cpp @@ -297,39 +297,41 @@ void Connector::setEndPort(Port *pPort) //! @brief Executes the final tasks before creation of the connector is complete. Then flags that the connection if finished. -void Connector::finishCreation() +void Connector::finishCreation(bool doCorrectGeometries) { if (mpStartPort && mpEndPort) { // Figure out whether or not the last line had the right direction, and make necessary corrections - if( ( ((mpEndPort->getPortDirection() == LeftRightDirectionType) && (mGeometries.back() == Horizontal)) || - ((mpEndPort->getPortDirection() == TopBottomDirectionType) && (mGeometries.back() == Vertical)) ) || - (mGeometries[mGeometries.size()-2] == Diagonal) || - mpEndPort->getPortType() == "ReadMultiportType" || mpEndPort->getPortType() == "PowerMultiportType") - { - // Wrong direction of last line, so remove last point. This is because an extra line was added with the last click, that shall not be there. It is also possible that we end up here because the end port is a multi port, which mean that we shall not add any offset to it. - this->removePoint(); - this->scene()->removeItem(mpLines.back()); - delete(mpLines.back()); - this->mpLines.pop_back(); - } - else - { - // Correct direction of last line, which was added due to the final mouse click. This means that the last "real" line has the wrong direction. - // We therefore keep the extra line, and move second last line a bit outwards from the component. - QPointF offsetPoint = getOffsetPointfromPort(mpStartPort, mpEndPort); - mPoints[mPoints.size()-2] = mpEndPort->mapToScene(mpEndPort->boundingRect().center()) + offsetPoint; - if(offsetPoint.x() != 0.0) + if(doCorrectGeometries) { + if( ( ((mpEndPort->getPortDirection() == LeftRightDirectionType) && (mGeometries.back() == Horizontal)) || + ((mpEndPort->getPortDirection() == TopBottomDirectionType) && (mGeometries.back() == Vertical)) ) || + (mGeometries[mGeometries.size()-2] == Diagonal) || + mpEndPort->getPortType() == "ReadMultiportType" || mpEndPort->getPortType() == "PowerMultiportType") { - mPoints[mPoints.size()-3].setX(mPoints[mPoints.size()-2].x()); + // Wrong direction of last line, so remove last point. This is because an extra line was added with the last click, that shall not be there. It is also possible that we end up here because the end port is a multi port, which mean that we shall not add any offset to it. + this->removePoint(); + this->scene()->removeItem(mpLines.back()); + delete(mpLines.back()); + this->mpLines.pop_back(); } else { - mPoints[mPoints.size()-3].setY(mPoints[mPoints.size()-2].y()); + // Correct direction of last line, which was added due to the final mouse click. This means that the last "real" line has the wrong direction. + // We therefore keep the extra line, and move second last line a bit outwards from the component. + QPointF offsetPoint = getOffsetPointfromPort(mpStartPort, mpEndPort); + mPoints[mPoints.size()-2] = mpEndPort->mapToScene(mpEndPort->boundingRect().center()) + offsetPoint; + if(offsetPoint.x() != 0.0) + { + mPoints[mPoints.size()-3].setX(mPoints[mPoints.size()-2].x()); + } + else + { + mPoints[mPoints.size()-3].setY(mPoints[mPoints.size()-2].y()); + } + this->determineAppearance(); //Figure out which connector appearance to use + this->drawConnector(); + mpParentSystemObject->mpModelWidget->getGraphicsView()->updateViewPort(); } - this->determineAppearance(); //Figure out which connector appearance to use - this->drawConnector(); - mpParentSystemObject->mpModelWidget->getGraphicsView()->updateViewPort(); } // Make sure the end point of the connector is the center position of the end port diff --git a/HopsanGUI/GUIConnector.h b/HopsanGUI/GUIConnector.h index 7d544d5cf..918179d14 100644 --- a/HopsanGUI/GUIConnector.h +++ b/HopsanGUI/GUIConnector.h @@ -74,7 +74,7 @@ class Connector : public QGraphicsWidget void setStartPort(Port *pPort); void setEndPort(Port *pPort); - void finishCreation(); + void finishCreation(bool doCorrectGeometries=true); void addPoint(QPointF point); void removePoint(bool deleteIfEmpty = false); diff --git a/HopsanGUI/GUIObjects/GUIComponent.cpp b/HopsanGUI/GUIObjects/GUIComponent.cpp index 46fed79eb..06aa4ef21 100644 --- a/HopsanGUI/GUIObjects/GUIComponent.cpp +++ b/HopsanGUI/GUIObjects/GUIComponent.cpp @@ -44,11 +44,11 @@ #include "GUIObjects/GUIComponent.h" #include "GUIObjects/GUIContainerObject.h" #include "GUIPort.h" +#include "GUIConnector.h" #include "PlotHandler.h" #include "PlotTab.h" #include "PlotWindow.h" #include "Widgets/ModelWidget.h" -#include "MessageHandler.h" #include "LibraryHandler.h" @@ -139,10 +139,12 @@ QString Component::getTypeCQS() const //! @brief Set a parameter value to be mapped to a System parameter bool Component::setParameterValue(QString name, QString value, bool force) { + QMap > connectionsBeforeReconfigure; if((this->getTypeName() == "FMIWrapper" || this->getTypeName() == "FMIWrapperQ") && (name == "path" || name == "portspecs")) { //Remove old ports QList ports = this->getPortListPtrs(); for(const auto port : ports) { + connectionsBeforeReconfigure.insert(port->getName(), port->getAttachedConnectorPtrs()); this->removeExternalPort(port->getName(), true); } this->getAppearanceData()->getPortAppearanceMap().clear(); @@ -201,6 +203,23 @@ bool Component::setParameterValue(QString name, QString value, bool force) } } + //Reconnect dangling connectors after reconfiguration + QMapIterator > it(connectionsBeforeReconfigure); + while(it.hasNext()) { + it.next(); + for(const auto &con : it.value()) { + if(con->getStartPort() == nullptr && con->getEndPort() != nullptr) { + con->setStartPort(this->getPort(it.key())); //The start port was disconnected + } + if(con->getEndPort() == nullptr && con->getStartPort() != nullptr) { + con->setEndPort(this->getPort(it.key())); //The end port was disconneted + } + + con->finishCreation(false); //Re-establish connection + } + } + + //Adjust icon scale this->getAppearanceData()->setIconScale(qMax(qMax(inputs.size(),outputs.size())/3.0,1.0), UserGraphics); diff --git a/HopsanGUI/GUIObjects/GUIModelObject.cpp b/HopsanGUI/GUIObjects/GUIModelObject.cpp index 57eae2d54..7bc2be91d 100644 --- a/HopsanGUI/GUIObjects/GUIModelObject.cpp +++ b/HopsanGUI/GUIObjects/GUIModelObject.cpp @@ -1331,6 +1331,11 @@ QAction *ModelObject::buildBaseContextMenu(QMenu &rMenu, QGraphicsSceneContextMe bool allowLimitedEditing = (!isLocallyLocked() && (getModelLockLevel() <= LimitedLock)); rMenu.addSeparator(); + QAction *pReloadAction=0; + if(getTypeName() == "FMIWrapper" || getTypeName() == "FMIWrapperQ") { + pReloadAction = rMenu.addAction(tr("Reload FMU")); + pReloadAction->setEnabled(!getParameterValue("path").isEmpty()); + } QAction *pRotateRightAction=0, *pRotateLeftAction=0, *pFlipVerticalAction=0, *pFlipHorizontalAction=0; QAction *pLockedAction=0; QAction *pDisabledAction=0; @@ -1446,6 +1451,23 @@ QAction *ModelObject::buildBaseContextMenu(QMenu &rMenu, QGraphicsSceneContextMe pObj->setDisabled(pDisabledAction->isChecked()); } } + else if(selectedAction == pReloadAction) { + QMap parametersBeforeReconfigure; + QStringList parameterNames = getParameterNames(); + for(const auto &par : qAsConst(parameterNames)) { + if(par == "path") { + continue; + } + parametersBeforeReconfigure.insert(par, getParameterValue(par)); + } + setParameterValue("path", getParameterValue("path")); //Reload FMU by "changing" the path variable to the existing value + QMapIterator it(parametersBeforeReconfigure); + while(it.hasNext()) + { + it.next(); + setParameterValue(it.key(), it.value()); + } + } else { for(int i=0; i