diff --git a/OMEdit/OMEditLIB/Annotations/ShapeAnnotation.h b/OMEdit/OMEditLIB/Annotations/ShapeAnnotation.h index 3b66fa2695f..2ec96e332ec 100644 --- a/OMEdit/OMEditLIB/Annotations/ShapeAnnotation.h +++ b/OMEdit/OMEditLIB/Annotations/ShapeAnnotation.h @@ -164,6 +164,7 @@ class ShapeAnnotation : public QObject, public QGraphicsItem, public GraphicItem void updateExtent(const int index, const QPointF point); void setOriginItemPos(const QPointF point); GraphicsView* getGraphicsView() {return mpGraphicsView;} + Element* getParentComponent() const {return mpParentComponent;} OriginItem* getOriginItem() {return mpOriginItem;} void setPoints(QVector points) {mPoints = points;} const PointArrayAnnotation &getPoints() {return mPoints;} diff --git a/OMEdit/OMEditLIB/Element/Element.cpp b/OMEdit/OMEditLIB/Element/Element.cpp index 332e0b4cfee..c8e082f8233 100644 --- a/OMEdit/OMEditLIB/Element/Element.cpp +++ b/OMEdit/OMEditLIB/Element/Element.cpp @@ -4043,3 +4043,19 @@ QVariant Element::itemChange(GraphicsItemChange change, const QVariant &value) } return value; } + +/*! + * \brief Element::mousePressEvent + * The GraphicsView sets the Element under mouse object and then we use that to accept the mouse press event. + * Only accept the mouse press event for the Element set by GraphicsView and ignore all others. + * This allows us to select Element's by clicking on their drawn items instead of the bounding rectangle. + * \param event + */ +void Element::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (mpGraphicsView->getElementUnderMouse() == this) { + QGraphicsItem::mousePressEvent(event); + } else { + event->ignore(); + } +} diff --git a/OMEdit/OMEditLIB/Element/Element.h b/OMEdit/OMEditLIB/Element/Element.h index 387476b78a5..38e02349fb2 100644 --- a/OMEdit/OMEditLIB/Element/Element.h +++ b/OMEdit/OMEditLIB/Element/Element.h @@ -440,8 +440,10 @@ public slots: void showReplaceSubModelDialog(); void updateDynamicSelect(double time); void resetDynamicSelect(); + // QGraphicsItem interface protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; }; #endif // ELEMENT_H diff --git a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp index d8489bd3e2b..15b734aa26d 100644 --- a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp +++ b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp @@ -208,6 +208,7 @@ GraphicsView::GraphicsView(StringHandler::ViewType viewType, ModelWidget *pModel mIsCreatingTextShape = false; mIsCreatingBitmapShape = false; mIsPanning = false; + mpElementUnderMouse = 0; mLastMouseEventPos = QPoint(0, 0); mpClickedComponent = 0; mpClickedState = 0; @@ -2939,7 +2940,7 @@ void GraphicsView::duplicateItems(const QString &action) * A QGraphicsItem can be a Element or a ShapeAnnotation inside a Element. * \return */ -Element *GraphicsView::getElementFromQGraphicsItem(QGraphicsItem *pGraphicsItem) +Element* GraphicsView::getElementFromQGraphicsItem(QGraphicsItem *pGraphicsItem) { if (pGraphicsItem) { Element *pElement = dynamic_cast(pGraphicsItem); @@ -2957,18 +2958,36 @@ Element *GraphicsView::getElementFromQGraphicsItem(QGraphicsItem *pGraphicsItem) return 0; } +/*! + * \brief GraphicsView::getShapeFromQGraphicsItem + * \param pGraphicsItem + * A QGraphicsItem can be a ShapeAnnotation. + * \return + */ +ShapeAnnotation* GraphicsView::getShapeFromQGraphicsItem(QGraphicsItem *pGraphicsItem) +{ + if (pGraphicsItem) { + ShapeAnnotation *pShapeAnnotation = dynamic_cast(pGraphicsItem); + if (pShapeAnnotation && pShapeAnnotation->getParentComponent()) { + return pShapeAnnotation; + } + } + return 0; +} + /*! * \brief GraphicsView::elementAtPosition * Returns the first Element at the position. * \param position * \return */ -Element *GraphicsView::elementAtPosition(QPoint position) +Element* GraphicsView::elementAtPosition(QPoint position) { QList graphicsItems = items(position); foreach (QGraphicsItem *pGraphicsItem, graphicsItems) { - Element *pElement = getElementFromQGraphicsItem(pGraphicsItem); - if (pElement) { + ShapeAnnotation *pShapeAnnotation = getShapeFromQGraphicsItem(pGraphicsItem); + if (pShapeAnnotation && pShapeAnnotation->getParentComponent()) { + Element *pElement = pShapeAnnotation->getParentComponent(); Element *pRootElement = pElement->getRootParentElement(); if (pRootElement && ((pRootElement->getLibraryTreeItem() && !pRootElement->getLibraryTreeItem()->isNonExisting()) || (mpModelWidget->isNewApi()))) { return pRootElement; @@ -4522,6 +4541,7 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) if (event->button() == Qt::RightButton) { return; } + mpElementUnderMouse = elementAtPosition(event->pos()); // if user is starting panning. if (QApplication::keyboardModifiers() == Qt::ControlModifier) { setIsPanning(true); @@ -4530,12 +4550,13 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) return; } MainWindow *pMainWindow = MainWindow::instance(); - QPointF snappedPoint = snapPointToGrid(mapToScene(event->pos())); + QPointF scenePos = mapToScene(event->pos()); + QPointF snappedPoint = snapPointToGrid(scenePos); bool eventConsumed = false; // if left button presses and we are creating a connector if (isCreatingConnection()) { if (mpModelWidget->getLibraryTreeItem()->getLibraryType() == LibraryTreeItem::OMS) { - mpConnectionLineAnnotation->addPoint(roundPoint(mapToScene(event->pos()))); + mpConnectionLineAnnotation->addPoint(roundPoint(scenePos)); } else { mpConnectionLineAnnotation->addPoint(snappedPoint); } @@ -4596,7 +4617,7 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) pInitialStateLineAnnotation->setOldAnnotation(pInitialStateLineAnnotation->getOMCShapeAnnotation()); } } - // if some item is clicked + // if connector is clicked if (Element *pComponent = connectorElementAtPosition(event->pos())) { if (!isCreatingConnection()) { mpClickedComponent = pComponent; @@ -4604,7 +4625,7 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) addConnection(pComponent); // end the connection eventConsumed = true; // consume the event so that connection line or end component will not become selected } - } else if (Element *pComponent = stateElementAtPosition(event->pos())) { + } else if (Element *pComponent = stateElementAtPosition(event->pos())) { // if state is clicked if (!isCreatingTransition()) { mpClickedState = pComponent; } else if (isCreatingTransition()) { @@ -4704,6 +4725,7 @@ void GraphicsView::mouseReleaseEvent(QMouseEvent *event) return; } setIsPanning(false); + mpElementUnderMouse = 0; mpClickedComponent = 0; mpClickedState = 0; @@ -4761,9 +4783,8 @@ void GraphicsView::mouseReleaseEvent(QMouseEvent *event) bool GraphicsView::handleDoubleClickOnComponent(QMouseEvent *event) { - QGraphicsItem *pGraphicsItem = itemAt(event->pos()); bool shouldEnactQTDoubleClick = true; - Element *pComponent = getElementFromQGraphicsItem(pGraphicsItem); + Element *pComponent = elementAtPosition(event->pos()); if (pComponent) { shouldEnactQTDoubleClick = false; Element *pRootComponent = pComponent->getRootParentElement(); diff --git a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h index af710a19cf3..35951b1034e 100644 --- a/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h +++ b/OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h @@ -124,6 +124,7 @@ class GraphicsView : public QGraphicsView bool mIsCreatingTextShape; bool mIsCreatingBitmapShape; bool mIsPanning; + Element *mpElementUnderMouse; QPoint mLastMouseEventPos; Element *mpClickedComponent; Element *mpClickedState; @@ -221,6 +222,7 @@ class GraphicsView : public QGraphicsView void setIsCreatingPrologue(const bool enable); void setIsPanning(bool enable); bool isPanning() {return mIsPanning;} + Element* getElementUnderMouse() const {return mpElementUnderMouse;} void setDragModeInternal(bool enable, bool updateCursor = false); void setItemsFlags(bool enable); void updateUndoRedoActions(bool enable); @@ -365,6 +367,7 @@ class GraphicsView : public QGraphicsView void duplicateItems(const QString &action); bool isCreatingShape(); Element* getElementFromQGraphicsItem(QGraphicsItem *pGraphicsItem); + ShapeAnnotation* getShapeFromQGraphicsItem(QGraphicsItem *pGraphicsItem); Element* elementAtPosition(QPoint position); Element* connectorElementAtPosition(QPoint position); Element* stateElementAtPosition(QPoint position);