Skip to content

Commit

Permalink
Allow creating a connector when making a connection (#7497)
Browse files Browse the repository at this point in the history
Fixes #7460
  • Loading branch information
adeas31 committed May 26, 2021
1 parent 2948fc2 commit 412eb41
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 53 deletions.
9 changes: 6 additions & 3 deletions OMEdit/OMEditLIB/Annotations/LineAnnotation.cpp
Expand Up @@ -1012,11 +1012,14 @@ void LineAnnotation::updateTransitionTextPosition()
}

/*!
Sets the shape flags.
*/
* \brief LineAnnotation::setShapeFlags
* Sets the shape flags.
* \param enable
*/
void LineAnnotation::setShapeFlags(bool enable)
{
if ((mLineType == LineAnnotation::ConnectionType || mLineType == LineAnnotation::TransitionType || mLineType == LineAnnotation::ShapeType)
if ((mLineType == LineAnnotation::ConnectionType || mLineType == LineAnnotation::TransitionType
|| mLineType == LineAnnotation::InitialStateType || mLineType == LineAnnotation::ShapeType)
&& mpGraphicsView) {
/*
Only set the ItemIsMovable & ItemSendsGeometryChanges flags on Line if the class is not a system library class
Expand Down
3 changes: 1 addition & 2 deletions OMEdit/OMEditLIB/Annotations/ShapeAnnotation.cpp
Expand Up @@ -1831,8 +1831,7 @@ void ShapeAnnotation::editTransition()
return;
}
LineAnnotation *pTransitionLineAnnotation = dynamic_cast<LineAnnotation*>(this);
CreateOrEditTransitionDialog *pCreateOrEditTransitionDialog = new CreateOrEditTransitionDialog(mpGraphicsView, pTransitionLineAnnotation,
true, MainWindow::instance());
CreateOrEditTransitionDialog *pCreateOrEditTransitionDialog = new CreateOrEditTransitionDialog(mpGraphicsView, pTransitionLineAnnotation, true, MainWindow::instance());
pCreateOrEditTransitionDialog->exec();
}

Expand Down
14 changes: 2 additions & 12 deletions OMEdit/OMEditLIB/Element/Element.cpp
Expand Up @@ -2926,20 +2926,10 @@ void Element::deleteMe()
*/
void Element::duplicate()
{
MainWindow *pMainWindow = MainWindow::instance();
QString name;
if (mpLibraryTreeItem) {
// get the model defaultElementName
QString defaultName = pMainWindow->getOMCProxy()->getDefaultComponentName(mpLibraryTreeItem->getNameStructure());
if (defaultName.isEmpty()) {
name = mpGraphicsView->getUniqueElementName(StringHandler::toCamelCase(mpLibraryTreeItem->getName()));
} else {
if (mpGraphicsView->checkElementName(defaultName)) {
name = defaultName;
} else {
name = mpGraphicsView->getUniqueElementName(defaultName);
}
}
QString defaultName;
name = mpGraphicsView->getUniqueElementName(mpLibraryTreeItem->getNameStructure(), mpLibraryTreeItem->getName(), &defaultName);
} else {
name = mpGraphicsView->getUniqueElementName(StringHandler::toCamelCase(getName()));
}
Expand Down
174 changes: 138 additions & 36 deletions OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp
Expand Up @@ -303,14 +303,20 @@ void GraphicsView::setDragModeInternal(bool enable, bool updateCursor)
void GraphicsView::setItemsFlags(bool enable)
{
// set components, shapes and connection flags accordingly
foreach(Element *pElement, mElementsList) {
foreach (Element *pElement, mElementsList) {
pElement->setElementFlags(enable);
}
foreach(ShapeAnnotation *pShapeAnnotation, mShapesList){
foreach (ShapeAnnotation *pShapeAnnotation, mShapesList){
pShapeAnnotation->setShapeFlags(enable);
}
foreach(LineAnnotation *pLineAnnotation, mConnectionsList) {
pLineAnnotation->setShapeFlags(enable);
foreach (LineAnnotation *pConnectionLineAnnotation, mConnectionsList) {
pConnectionLineAnnotation->setShapeFlags(enable);
}
foreach (LineAnnotation *pTransitionLineAnnotation, mTransitionsList) {
pTransitionLineAnnotation->setShapeFlags(enable);
}
foreach (LineAnnotation *pInitialStateLineAnnotation, mInitialStatesList) {
pInitialStateLineAnnotation->setShapeFlags(enable);
}
}

Expand Down Expand Up @@ -384,9 +390,7 @@ bool GraphicsView::addComponent(QString className, QPointF position)
} else { // check if the model is partial
if (pLibraryTreeItem->isPartial()) {
if (pOptionsDialog->getNotificationsPage()->getReplaceableIfPartialCheckBox()->isChecked()) {
NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::ReplaceableIfPartial,
NotificationsDialog::InformationIcon,
MainWindow::instance());
NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::ReplaceableIfPartial, NotificationsDialog::InformationIcon, MainWindow::instance());
pNotificationsDialog->setNotificationLabelString(GUIMessages::getMessage(GUIMessages::MAKE_REPLACEABLE_IF_PARTIAL)
.arg(StringHandler::getModelicaClassType(type).toLower()).arg(pLibraryTreeItem->getName()));
if (!pNotificationsDialog->exec()) {
Expand All @@ -396,14 +400,8 @@ bool GraphicsView::addComponent(QString className, QPointF position)
}
// get the model defaultComponentPrefixes
QString defaultPrefix = pMainWindow->getOMCProxy()->getDefaultComponentPrefixes(pLibraryTreeItem->getNameStructure());
// get the model defaultComponentName
QString defaultName = pMainWindow->getOMCProxy()->getDefaultComponentName(pLibraryTreeItem->getNameStructure());
QString name;
if (!defaultName.isEmpty()) {
name = getUniqueElementName(StringHandler::toCamelCase(defaultName));
} else {
name = getUniqueElementName(StringHandler::toCamelCase(pLibraryTreeItem->getName()));
}
QString defaultName;
QString name = getUniqueElementName(pLibraryTreeItem->getNameStructure(), pLibraryTreeItem->getName(), &defaultName);
// Allow user to change the component name if always ask for component name settings is true.
if (pOptionsDialog->getNotificationsPage()->getAlwaysAskForDraggedComponentName()->isChecked()) {
ComponentNameDialog *pComponentNameDialog = new ComponentNameDialog(name, this, pMainWindow);
Expand All @@ -420,11 +418,8 @@ bool GraphicsView::addComponent(QString className, QPointF position)
// show the information to the user if we have changed the name of some inner component.
if (defaultPrefix.contains("inner")) {
if (pOptionsDialog->getNotificationsPage()->getInnerModelNameChangedCheckBox()->isChecked()) {
NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::InnerModelNameChanged,
NotificationsDialog::InformationIcon,
MainWindow::instance());
pNotificationsDialog->setNotificationLabelString(GUIMessages::getMessage(GUIMessages::INNER_MODEL_NAME_CHANGED)
.arg(defaultName).arg(name));
NotificationsDialog *pNotificationsDialog = new NotificationsDialog(NotificationsDialog::InnerModelNameChanged, NotificationsDialog::InformationIcon, MainWindow::instance());
pNotificationsDialog->setNotificationLabelString(GUIMessages::getMessage(GUIMessages::INNER_MODEL_NAME_CHANGED).arg(defaultName).arg(name));
if (!pNotificationsDialog->exec()) {
return false;
}
Expand Down Expand Up @@ -541,26 +536,52 @@ void GraphicsView::addElementToClass(Element *pElement)
}
}

QString getComponentName(const QString &qualifiedComponentName)
{
QString componentName = StringHandler::getFirstWordBeforeDot(qualifiedComponentName);
if (componentName.contains("[")) {
componentName = componentName.mid(0, componentName.indexOf("["));
}
return componentName;
}

/*!
* \brief GraphicsView::deleteComponent
* Delete the component and its corresponding connections from the components list and OMC.
* \param component is the object to be deleted.
*/
void GraphicsView::deleteElement(Element *pElement)
{
// First Remove the connections associated to this element
// First remove the connections associated to this element
int i = 0;
while(i != mConnectionsList.size()) {
QString startComponentName = StringHandler::getFirstWordBeforeDot(mConnectionsList[i]->getStartComponentName());
if (startComponentName.contains("[")) {
startComponentName = startComponentName.mid(0, startComponentName.indexOf("["));
QString startComponentName = getComponentName(mConnectionsList[i]->getStartComponentName());
QString endComponentName = getComponentName(mConnectionsList[i]->getEndComponentName());
if ((startComponentName.compare(pElement->getName()) == 0) || (endComponentName.compare(pElement->getName()) == 0)) {
deleteConnection(mConnectionsList[i]);
i = 0; //Restart iteration if map has changed
} else {
++i;
}
QString endComponentName = StringHandler::getFirstWordBeforeDot(mConnectionsList[i]->getEndComponentName());
if (endComponentName.contains("[")) {
endComponentName = endComponentName.mid(0, endComponentName.indexOf("["));
}
// First remove the transitions associated to this element
i = 0;
while(i != mTransitionsList.size()) {
QString startComponentName = getComponentName(mTransitionsList[i]->getStartComponentName());
QString endComponentName = getComponentName(mTransitionsList[i]->getEndComponentName());
if ((startComponentName.compare(pElement->getName()) == 0) || (endComponentName.compare(pElement->getName()) == 0)) {
deleteTransition(mTransitionsList[i]);
i = 0; //Restart iteration if map has changed
} else {
++i;
}
if (startComponentName == pElement->getName() || endComponentName == pElement->getName()) {
deleteConnection(mConnectionsList[i]);
}
// First remove the initial state associated to this element
i = 0;
while(i != mInitialStatesList.size()) {
QString startComponentName = getComponentName(mInitialStatesList[i]->getStartComponentName());
if ((startComponentName.compare(pElement->getName()) == 0)) {
deleteInitialState(mInitialStatesList[i]);
i = 0; //Restart iteration if map has changed
} else {
++i;
Expand Down Expand Up @@ -615,6 +636,27 @@ Element* GraphicsView::getElementObject(QString elementName)
return 0;
}

/*!
* \brief GraphicsView::getUniqueElementName
* Checks the Element default name and returns a unique name for the element.
* \param nameStructure
* \param name
* \param defaultName
* \return
*/
QString GraphicsView::getUniqueElementName(const QString &nameStructure, const QString &name, QString *defaultName)
{
// get the model defaultComponentName
*defaultName = MainWindow::instance()->getOMCProxy()->getDefaultComponentName(nameStructure);
QString newName;
if (!defaultName->isEmpty()) {
newName = getUniqueElementName(StringHandler::toCamelCase(*defaultName));
} else {
newName = getUniqueElementName(StringHandler::toCamelCase(name));
}
return newName;
}

/*!
* \brief GraphicsView::getUniqueElementName
* Creates a unique element name.
Expand Down Expand Up @@ -1827,6 +1869,14 @@ void GraphicsView::createActions()
mpFlipVerticalAction->setShortcut(QKeySequence("v"));
mpFlipVerticalAction->setDisabled(isSystemLibrary);
connect(mpFlipVerticalAction, SIGNAL(triggered()), SLOT(flipVertical()));
// create connector Action
mpCreateConnectorAction = new QAction(tr("Create Connector"), this);
mpCreateConnectorAction->setStatusTip(tr("Creates a connector"));
connect(mpCreateConnectorAction, SIGNAL(triggered()), SLOT(createConnector()));
// cancel connection Action
mpCancelConnectionAction = new QAction(tr("Cancel Connection"), this);
mpCancelConnectionAction->setStatusTip(tr("Cancels the current connection"));
connect(mpCancelConnectionAction, SIGNAL(triggered()), SLOT(cancelConnection()));
// set initial state Action
mpSetInitialStateAction = new QAction(tr("Set Initial State"), this);
mpSetInitialStateAction->setStatusTip(tr("Sets the state as initial state"));
Expand Down Expand Up @@ -2269,6 +2319,7 @@ void GraphicsView::addTransition(Element *pComponent)
mpTransitionLineAnnotation->addPoint(startPos);
mpTransitionLineAnnotation->addPoint(startPos);
} else if (isCreatingTransition()) { // When clicking the end state
setIsCreatingTransition(false);
mpTransitionLineAnnotation->setEndComponent(pComponent);
// Remove reduntant points so that Liang Barsky algorithm can work well.
mpTransitionLineAnnotation->removeRedundantPointsGeometriesAndCornerItems();
Expand Down Expand Up @@ -2313,7 +2364,8 @@ void GraphicsView::addTransition(Element *pComponent)
removeCurrentTransition();
}
}
setIsCreatingTransition(false);
// Once we are done creating the transition then we should set mpTransitionLineAnnotation to 0.
mpTransitionLineAnnotation = 0;
}
}

Expand All @@ -2323,9 +2375,11 @@ void GraphicsView::addTransition(Element *pComponent)
*/
void GraphicsView::removeCurrentTransition()
{
if (isCreatingTransition()) {
setIsCreatingTransition(false);
delete mpTransitionLineAnnotation;
setIsCreatingTransition(false);
deleteTransitionFromList(mpTransitionLineAnnotation);
removeItem(mpTransitionLineAnnotation);
if (mpTransitionLineAnnotation) {
mpTransitionLineAnnotation->deleteLater();
mpTransitionLineAnnotation = 0;
}
}
Expand Down Expand Up @@ -3093,6 +3147,38 @@ void GraphicsView::flipVertical()
mpModelWidget->endMacro();
}

/*!
* \brief GraphicsView::createConnector
* Creates a connector while making a connection.\n
* Ends the connection on the newly created connector.
*/
void GraphicsView::createConnector()
{
if (mpConnectionLineAnnotation && mpConnectionLineAnnotation->getStartComponent()) {
Element *pConnectorElement = mpConnectionLineAnnotation->getStartComponent();
if (pConnectorElement->getLibraryTreeItem()) {
mpModelWidget->beginMacro("Add connector");
QString defaultName;
QString name = getUniqueElementName(pConnectorElement->getLibraryTreeItem()->getNameStructure(), pConnectorElement->getLibraryTreeItem()->getName(), &defaultName);
ElementInfo *pElementInfo = new ElementInfo;
addComponentToView(name, pConnectorElement->getLibraryTreeItem(), "", mapToScene(mapFromGlobal(QCursor::pos())), pElementInfo, true, true, true);
addConnection(mElementsList.last());
mpModelWidget->endMacro();
}
}
}

/*!
* \brief GraphicsView::cancelConnection
* Cancels the current connecton.
*/
void GraphicsView::cancelConnection()
{
if (mpConnectionLineAnnotation) {
removeCurrentConnection();
}
}

/*!
* \brief GraphicsView::setInitialState
* Sets the state as initial.
Expand All @@ -3102,8 +3188,8 @@ void GraphicsView::setInitialState()
if (mpTransitionLineAnnotation) {
QString startComponentName;
if (mpTransitionLineAnnotation->getStartComponent()->getParentComponent()) {
startComponentName = QString(mpTransitionLineAnnotation->getStartComponent()->getRootParentComponent()->getName()).append(".")
.append(mpTransitionLineAnnotation->getStartComponent()->getName());
startComponentName = QString("%1.%2").arg(mpTransitionLineAnnotation->getStartComponent()->getRootParentComponent()->getName())
.arg(mpTransitionLineAnnotation->getStartComponent()->getName());
} else {
startComponentName = mpTransitionLineAnnotation->getStartComponent()->getName();
}
Expand Down Expand Up @@ -3771,10 +3857,26 @@ void GraphicsView::keyReleaseEvent(QKeyEvent *event)
}
}

/*!
* \brief GraphicsView::contextMenuEvent
* Shows the context menu.
* \param event
*/
void GraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
/* If we are creating the connection OR creating any shape then don't show context menu */
if (isCreatingShape() || isCreatingConnection() || isCreatingTransition()) {
if (isCreatingShape()) {
return;
}
// if creating a connection
if (isCreatingConnection()) {
if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::Modelica) {
QMenu menu(MainWindow::instance());
menu.addAction(mpCreateConnectorAction);
menu.addSeparator();
menu.addAction(mpCancelConnectionAction);
menu.exec(event->globalPos());
}
return;
}
// if creating a transition
Expand Down
5 changes: 5 additions & 0 deletions OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h
Expand Up @@ -148,6 +148,8 @@ class GraphicsView : public QGraphicsView
QAction *mpRotateAntiClockwiseAction;
QAction *mpFlipHorizontalAction;
QAction *mpFlipVerticalAction;
QAction *mpCreateConnectorAction;
QAction *mpCancelConnectionAction;
QAction *mpSetInitialStateAction;
QAction *mpCancelTransitionAction;
// scene->items().contains(...) involves sorting on each items() call, avoid it
Expand Down Expand Up @@ -218,6 +220,7 @@ class GraphicsView : public QGraphicsView
void deleteElementFromOutOfSceneList(Element *pElement) {mOutOfSceneElementsList.removeOne(pElement);}
void deleteInheritedElementFromList(Element *pElement) {mInheritedElementsList.removeOne(pElement);}
Element* getElementObject(QString elementName);
QString getUniqueElementName(const QString &nameStructure, const QString &name, QString *defaultName);
QString getUniqueElementName(QString elementName, int number = 0);
bool checkElementName(QString elementName);
QList<Element*> getElementsList() {return mElementsList;}
Expand Down Expand Up @@ -381,6 +384,8 @@ public slots:
void rotateAntiClockwise();
void flipHorizontal();
void flipVertical();
void createConnector();
void cancelConnection();
void setInitialState();
void cancelTransition();
protected:
Expand Down

0 comments on commit 412eb41

Please sign in to comment.