forked from qt-creator/qt-creator
ModelEditor: Allow relocation of ends of relations in diagrams
Change-Id: I8dbf536731cb24819f70dc6acacc4658fd257259 Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
@@ -156,6 +156,39 @@ void DUpdateVisitor::visitMRelation(const MRelation *relation)
|
||||
drelation->setStereotypes(relation->stereotypes());
|
||||
if (isUpdating(relation->name() != drelation->name()))
|
||||
drelation->setName(relation->name());
|
||||
// TODO improve performance of MDiagram::findDiagramElement
|
||||
DObject *endAObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endAUid()));
|
||||
if (!endAObject || relation->endAUid() != endAObject->modelUid()) {
|
||||
isUpdating(true);
|
||||
endAObject = 0;
|
||||
// TODO use DiagramController::findDelegate (and improve performance of that method)
|
||||
foreach (DElement *diagramElement, m_diagram->diagramElements()) {
|
||||
if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == relation->endAUid()) {
|
||||
endAObject = dynamic_cast<DObject *>(diagramElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (endAObject)
|
||||
drelation->setEndAUid(endAObject->uid());
|
||||
else
|
||||
drelation->setEndAUid(Uid::invalidUid());
|
||||
}
|
||||
DObject *endBObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endBUid()));
|
||||
if (!endBObject || relation->endBUid() != endBObject->modelUid()) {
|
||||
isUpdating(true);
|
||||
endBObject = 0;
|
||||
// TODO use DiagramController::findDelegate
|
||||
foreach (DElement *diagramElement, m_diagram->diagramElements()) {
|
||||
if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == relation->endBUid()) {
|
||||
endBObject = dynamic_cast<DObject *>(diagramElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (endBObject)
|
||||
drelation->setEndBUid(endBObject->uid());
|
||||
else
|
||||
drelation->setEndBUid(Uid::invalidUid());
|
||||
}
|
||||
visitMElement(relation);
|
||||
}
|
||||
|
||||
|
@@ -44,11 +44,11 @@ class IWindable
|
||||
public:
|
||||
virtual ~IWindable() { }
|
||||
|
||||
virtual QPointF handlePos(int index) = 0;
|
||||
virtual void insertHandle(int beforeIndex, const QPointF &pos) = 0;
|
||||
virtual QPointF grabHandle(int index) = 0;
|
||||
virtual void insertHandle(int beforeIndex, const QPointF &pos, double rasterWidth, double rasterHeight) = 0;
|
||||
virtual void deleteHandle(int index) = 0;
|
||||
virtual void setHandlePos(int index, const QPointF &pos) = 0;
|
||||
virtual void alignHandleToRaster(int index, double rasterWidth, double rasterHeight) = 0;
|
||||
virtual void dropHandle(int index, double rasterWidth, double rasterHeight) = 0;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
@@ -232,6 +232,20 @@ DElement *DiagramSceneModel::findTopmostElement(const QPointF &scenePos) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
DObject *DiagramSceneModel::findTopmostObject(const QPointF &scenePos) const
|
||||
{
|
||||
// fetch affected items from scene in correct drawing order to find topmost element
|
||||
QList<QGraphicsItem *> items = m_graphicsScene->items(scenePos);
|
||||
foreach (QGraphicsItem *item, items) {
|
||||
if (m_graphicsItems.contains(item)) {
|
||||
DObject *object = dynamic_cast<DObject *>(m_itemToElementMap.value(item));
|
||||
if (object)
|
||||
return object;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QGraphicsItem *DiagramSceneModel::graphicsItem(DElement *element) const
|
||||
{
|
||||
return m_elementToItemMap.value(element);
|
||||
|
@@ -102,6 +102,7 @@ public:
|
||||
bool hasMultiObjectsSelection() const;
|
||||
DSelection selectedElements() const;
|
||||
DElement *findTopmostElement(const QPointF &scenePos) const;
|
||||
DObject *findTopmostObject(const QPointF &scenePos) const;
|
||||
|
||||
QList<QGraphicsItem *> graphicsItems() const { return m_graphicsItems; }
|
||||
QGraphicsItem *graphicsItem(DElement *element) const;
|
||||
|
@@ -174,6 +174,10 @@ private:
|
||||
QList<QPointF> m_points;
|
||||
};
|
||||
|
||||
bool RelationItem::m_grabbedEndA = false;
|
||||
bool RelationItem::m_grabbedEndB = false;
|
||||
QPointF RelationItem::m_grabbedEndPos;
|
||||
|
||||
RelationItem::RelationItem(DRelation *relation, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent),
|
||||
m_relation(relation),
|
||||
@@ -271,14 +275,19 @@ void RelationItem::setFocusSelected(bool focusSelected)
|
||||
}
|
||||
}
|
||||
|
||||
QPointF RelationItem::handlePos(int index)
|
||||
QPointF RelationItem::grabHandle(int index)
|
||||
{
|
||||
if (index == 0) {
|
||||
// TODO implement
|
||||
return QPointF(0,0);
|
||||
m_grabbedEndA = true;
|
||||
QPointF endBPos = calcEndPoint(m_relation->endBUid(), m_relation->endAUid(), m_relation->intermediatePoints().size() - 1);
|
||||
QPointF endAPos = calcEndPoint(m_relation->endAUid(), endBPos, 0);
|
||||
m_grabbedEndPos = endAPos;
|
||||
return endAPos;
|
||||
} else if (index == m_relation->intermediatePoints().size() + 1) {
|
||||
// TODO implement
|
||||
return QPointF(0,0);
|
||||
m_grabbedEndB = true;
|
||||
QPointF endBPos = calcEndPoint(m_relation->endBUid(), m_relation->endAUid(), m_relation->intermediatePoints().size() - 1);
|
||||
m_grabbedEndPos = endBPos;
|
||||
return endBPos;
|
||||
} else {
|
||||
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
|
||||
--index;
|
||||
@@ -287,11 +296,15 @@ QPointF RelationItem::handlePos(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void RelationItem::insertHandle(int beforeIndex, const QPointF &pos)
|
||||
void RelationItem::insertHandle(int beforeIndex, const QPointF &pos, double rasterWidth, double rasterHeight)
|
||||
{
|
||||
if (beforeIndex == 0)
|
||||
++beforeIndex;
|
||||
if (beforeIndex >= 1 && beforeIndex <= m_relation->intermediatePoints().size() + 1) {
|
||||
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
|
||||
intermediatePoints.insert(beforeIndex - 1, DRelation::IntermediatePoint(pos));
|
||||
double x = qRound(pos.x() / rasterWidth) * rasterWidth;
|
||||
double y = qRound(pos.y() / rasterHeight) * rasterHeight;
|
||||
intermediatePoints.insert(beforeIndex - 1, DRelation::IntermediatePoint(QPointF(x, y)));
|
||||
|
||||
m_diagramSceneModel->diagramController()->startUpdateElement(m_relation, m_diagramSceneModel->diagram(), DiagramController::UpdateMajor);
|
||||
m_relation->setIntermediatePoints(intermediatePoints);
|
||||
@@ -301,6 +314,10 @@ void RelationItem::insertHandle(int beforeIndex, const QPointF &pos)
|
||||
|
||||
void RelationItem::deleteHandle(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
++index;
|
||||
else if (index == m_relation->intermediatePoints().size() + 1)
|
||||
--index;
|
||||
if (index >= 1 && index <= m_relation->intermediatePoints().size()) {
|
||||
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
|
||||
intermediatePoints.removeAt(index - 1);
|
||||
@@ -314,9 +331,11 @@ void RelationItem::deleteHandle(int index)
|
||||
void RelationItem::setHandlePos(int index, const QPointF &pos)
|
||||
{
|
||||
if (index == 0) {
|
||||
// TODO implement
|
||||
m_grabbedEndPos = pos;
|
||||
update();
|
||||
} else if (index == m_relation->intermediatePoints().size() + 1) {
|
||||
// TODO implement
|
||||
m_grabbedEndPos = pos;
|
||||
update();
|
||||
} else {
|
||||
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
|
||||
--index;
|
||||
@@ -329,12 +348,18 @@ void RelationItem::setHandlePos(int index, const QPointF &pos)
|
||||
}
|
||||
}
|
||||
|
||||
void RelationItem::alignHandleToRaster(int index, double rasterWidth, double rasterHeight)
|
||||
void RelationItem::dropHandle(int index, double rasterWidth, double rasterHeight)
|
||||
{
|
||||
if (index == 0) {
|
||||
// TODO implement
|
||||
} else if (index ==m_relation->intermediatePoints().size() + 1) {
|
||||
// TODO implement
|
||||
m_grabbedEndA = false;
|
||||
DObject *targetObject = m_diagramSceneModel->findTopmostObject(m_grabbedEndPos);
|
||||
if (!m_diagramSceneModel->diagramSceneController()->relocateRelationEndA(m_relation, targetObject))
|
||||
update();
|
||||
} else if (index == m_relation->intermediatePoints().size() + 1) {
|
||||
m_grabbedEndB = false;
|
||||
DObject *targetObject = m_diagramSceneModel->findTopmostObject(m_grabbedEndPos);
|
||||
if (!m_diagramSceneModel->diagramSceneController()->relocateRelationEndB(m_relation, targetObject))
|
||||
update();
|
||||
} else {
|
||||
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
|
||||
--index;
|
||||
@@ -365,8 +390,19 @@ void RelationItem::update()
|
||||
|
||||
void RelationItem::update(const Style *style)
|
||||
{
|
||||
QPointF endBPos = calcEndPoint(m_relation->endBUid(), m_relation->endAUid(), m_relation->intermediatePoints().size() - 1);
|
||||
QPointF endAPos = calcEndPoint(m_relation->endAUid(), endBPos, 0);
|
||||
QPointF endAPos;
|
||||
QPointF endBPos;
|
||||
|
||||
if (m_grabbedEndA) {
|
||||
endAPos = m_grabbedEndPos;
|
||||
endBPos = calcEndPoint(m_relation->endBUid(), endAPos, m_relation->intermediatePoints().size() - 1);
|
||||
} else if (m_grabbedEndB) {
|
||||
endBPos = m_grabbedEndPos;
|
||||
endAPos = calcEndPoint(m_relation->endAUid(), endBPos, 0);
|
||||
} else {
|
||||
endBPos = calcEndPoint(m_relation->endBUid(), m_relation->endAUid(), m_relation->intermediatePoints().size() - 1);
|
||||
endAPos = calcEndPoint(m_relation->endAUid(), endBPos, 0);
|
||||
}
|
||||
|
||||
setPos(endAPos);
|
||||
|
||||
|
@@ -77,11 +77,11 @@ public:
|
||||
bool isFocusSelected() const override;
|
||||
void setFocusSelected(bool focusSelected) override;
|
||||
|
||||
QPointF handlePos(int index) override;
|
||||
void insertHandle(int beforeIndex, const QPointF &pos) override;
|
||||
QPointF grabHandle(int index) override;
|
||||
void insertHandle(int beforeIndex, const QPointF &pos, double rasterWidth, double rasterHeight) override;
|
||||
void deleteHandle(int index) override;
|
||||
void setHandlePos(int index, const QPointF &pos) override;
|
||||
void alignHandleToRaster(int index, double rasterWidth, double rasterHeight) override;
|
||||
void dropHandle(int index, double rasterWidth, double rasterHeight) override;
|
||||
|
||||
virtual void update();
|
||||
|
||||
@@ -108,6 +108,9 @@ protected:
|
||||
QGraphicsSimpleTextItem *m_name = 0;
|
||||
StereotypesItem *m_stereotypes = 0;
|
||||
PathSelectionItem *m_selectionHandles = 0;
|
||||
static bool m_grabbedEndA;
|
||||
static bool m_grabbedEndB;
|
||||
static QPointF m_grabbedEndPos;
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
@@ -33,12 +33,14 @@
|
||||
#include "qmt/diagram_scene/capabilities/windable.h"
|
||||
#include "qmt/diagram_scene/diagramsceneconstants.h"
|
||||
#include "qmt/infrastructure/geometryutilities.h"
|
||||
#include "qmt/infrastructure/qmtassert.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QBrush>
|
||||
#include <QLineF>
|
||||
#include <QPainter>
|
||||
#include <QKeyEvent>
|
||||
|
||||
namespace qmt {
|
||||
|
||||
@@ -58,6 +60,12 @@ public:
|
||||
m_owner(parent),
|
||||
m_pointIndex(pointIndex)
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsFocusable);
|
||||
}
|
||||
|
||||
void setPointIndex(int pointIndex)
|
||||
{
|
||||
m_pointIndex = pointIndex;
|
||||
}
|
||||
|
||||
void setPointSize(const QSizeF &pointSize)
|
||||
@@ -79,21 +87,31 @@ public:
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
m_startPos = mapToScene(event->pos());
|
||||
m_startPos = event->scenePos();
|
||||
m_lastPos = m_startPos;
|
||||
m_qualifier = event->modifiers() & Qt::ControlModifier ? DeleteHandle : None;
|
||||
m_owner->moveHandle(m_pointIndex, QPointF(0.0, 0.0), Press, m_qualifier);
|
||||
setFocus();
|
||||
}
|
||||
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QPointF delta = mapToScene(event->pos()) - m_startPos;
|
||||
m_lastPos = event->scenePos();
|
||||
QPointF delta = m_lastPos - m_startPos;
|
||||
m_owner->moveHandle(m_pointIndex, delta, Move, m_qualifier);
|
||||
}
|
||||
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QPointF delta = mapToScene(event->pos()) - m_startPos;
|
||||
m_lastPos = event->scenePos();
|
||||
QPointF delta = m_lastPos - m_startPos;
|
||||
m_owner->moveHandle(m_pointIndex, delta, Release, m_qualifier);
|
||||
clearFocus();
|
||||
}
|
||||
|
||||
void keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
m_owner->keyPressed(m_pointIndex, event, m_lastPos);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -122,6 +140,7 @@ private:
|
||||
QSizeF m_pointSize;
|
||||
Selection m_selection = NotSelected;
|
||||
QPointF m_startPos;
|
||||
QPointF m_lastPos;
|
||||
PathSelectionItem::HandleQualifier m_qualifier = PathSelectionItem::None;
|
||||
};
|
||||
|
||||
@@ -193,11 +212,23 @@ QList<QPointF> PathSelectionItem::points() const
|
||||
|
||||
void PathSelectionItem::setPoints(const QList<QPointF> &points)
|
||||
{
|
||||
QMT_CHECK(points.size() >= 2);
|
||||
prepareGeometryChange();
|
||||
|
||||
GraphicsHandleItem *focusEndBItem = 0;
|
||||
if (!m_handles.isEmpty() && m_focusHandleItem == m_handles.last()) {
|
||||
focusEndBItem = m_focusHandleItem;
|
||||
m_handles.removeLast();
|
||||
}
|
||||
int pointIndex = 0;
|
||||
foreach (const QPointF &point, points) {
|
||||
GraphicsHandleItem *handle;
|
||||
if (pointIndex >= m_handles.size()) {
|
||||
if (focusEndBItem && pointIndex == points.size() - 1) {
|
||||
handle = focusEndBItem;
|
||||
handle->setPointIndex(pointIndex);
|
||||
m_handles.insert(pointIndex, handle);
|
||||
focusEndBItem = 0;
|
||||
} else if (pointIndex >= m_handles.size()) {
|
||||
handle = new GraphicsHandleItem(pointIndex, this);
|
||||
handle->setPointSize(m_pointSize);
|
||||
m_handles.append(handle);
|
||||
@@ -207,6 +238,7 @@ void PathSelectionItem::setPoints(const QList<QPointF> &points)
|
||||
handle->setPos(point);
|
||||
++pointIndex;
|
||||
}
|
||||
QMT_CHECK(!focusEndBItem);
|
||||
while (m_handles.size() > pointIndex) {
|
||||
m_handles.last()->scene()->removeItem(m_handles.last());
|
||||
delete m_handles.last();
|
||||
@@ -229,7 +261,7 @@ void PathSelectionItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
for (int i = 0; i < m_handles.size() - 1; ++i) {
|
||||
qreal distance = GeometryUtilities::calcDistancePointToLine(event->pos(), QLineF(m_handles.at(i)->pos(), m_handles.at(i+1)->pos()));
|
||||
if (distance < MAX_SELECTION_DISTANCE_FROM_PATH) {
|
||||
m_windable->insertHandle(i + 1, event->scenePos());
|
||||
m_windable->insertHandle(i + 1, event->scenePos(), RASTER_WIDTH, RASTER_HEIGHT);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
@@ -239,15 +271,19 @@ void PathSelectionItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
bool PathSelectionItem::isEndHandle(int pointIndex) const
|
||||
{
|
||||
return pointIndex == 0 || pointIndex == m_handles.size() - 1;
|
||||
}
|
||||
|
||||
void PathSelectionItem::update()
|
||||
{
|
||||
prepareGeometryChange();
|
||||
int i = 0;
|
||||
foreach (GraphicsHandleItem *handle, m_handles) {
|
||||
handle->setPointSize(m_pointSize);
|
||||
bool isEndPoint = (i == 0 || i == m_handles.size() - 1);
|
||||
handle->setSelection(m_isSecondarySelected
|
||||
? (isEndPoint ? GraphicsHandleItem::NotSelected : GraphicsHandleItem::SecondarySelected)
|
||||
? (isEndHandle(i) ? GraphicsHandleItem::NotSelected : GraphicsHandleItem::SecondarySelected)
|
||||
: GraphicsHandleItem::Selected);
|
||||
++i;
|
||||
}
|
||||
@@ -258,12 +294,16 @@ void PathSelectionItem::moveHandle(int pointIndex, const QPointF &deltaMove, Han
|
||||
switch (handleQualifier) {
|
||||
case None:
|
||||
{
|
||||
if (handleStatus == Press)
|
||||
m_originalHandlePos = m_windable->handlePos(pointIndex);
|
||||
if (handleStatus == Press) {
|
||||
m_focusHandleItem = m_handles.at(pointIndex);
|
||||
m_originalHandlePos = m_windable->grabHandle(pointIndex);
|
||||
}
|
||||
QPointF newPos = m_originalHandlePos + deltaMove;
|
||||
m_windable->setHandlePos(pointIndex, newPos);
|
||||
if (handleStatus == Release)
|
||||
m_windable->alignHandleToRaster(pointIndex, RASTER_WIDTH, RASTER_HEIGHT);
|
||||
if (handleStatus == Release) {
|
||||
m_windable->dropHandle(pointIndex, RASTER_WIDTH, RASTER_HEIGHT);
|
||||
m_focusHandleItem = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DeleteHandle:
|
||||
@@ -273,4 +313,14 @@ void PathSelectionItem::moveHandle(int pointIndex, const QPointF &deltaMove, Han
|
||||
}
|
||||
}
|
||||
|
||||
void PathSelectionItem::keyPressed(int pointIndex, QKeyEvent *event, const QPointF &pos)
|
||||
{
|
||||
if (isEndHandle(pointIndex)) {
|
||||
if (event->key() == Qt::Key_Shift)
|
||||
m_windable->insertHandle(pointIndex, pos, RASTER_WIDTH, RASTER_HEIGHT);
|
||||
else if (event->key() == Qt::Key_Control)
|
||||
m_windable->deleteHandle(pointIndex);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
|
@@ -72,14 +72,17 @@ protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool isEndHandle(int pointIndex) const;
|
||||
void update();
|
||||
void moveHandle(int pointIndex, const QPointF &deltaMove, HandleStatus handleStatus,
|
||||
HandleQualifier handleQualifier);
|
||||
void keyPressed(int pointIndex, QKeyEvent *event, const QPointF &pos);
|
||||
|
||||
IWindable *m_windable = 0;
|
||||
QSizeF m_pointSize;
|
||||
bool m_isSecondarySelected = false;
|
||||
QList<GraphicsHandleItem *> m_handles;
|
||||
GraphicsHandleItem *m_focusHandleItem = 0;
|
||||
QPointF m_originalHandlePos;
|
||||
};
|
||||
|
||||
|
@@ -109,6 +109,8 @@ void MFlatAssignmentVisitor::visitMRelation(const MRelation *relation)
|
||||
auto targetRelation = dynamic_cast<MRelation *>(m_target);
|
||||
QMT_CHECK(targetRelation);
|
||||
targetRelation->setName(relation->name());
|
||||
targetRelation->setEndAUid(relation->endAUid());
|
||||
targetRelation->setEndBUid(relation->endBUid());
|
||||
}
|
||||
|
||||
void MFlatAssignmentVisitor::visitMDependency(const MDependency *dependency)
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include "qmt/diagram_ui/diagram_mime_types.h"
|
||||
#include "qmt/model_controller/modelcontroller.h"
|
||||
#include "qmt/model_controller/mselection.h"
|
||||
#include "qmt/model_controller/mvoidvisitor.h"
|
||||
#include "qmt/model/massociation.h"
|
||||
#include "qmt/model/mcanvasdiagram.h"
|
||||
#include "qmt/model/mclass.h"
|
||||
@@ -71,6 +72,35 @@ namespace {
|
||||
static VoidElementTasks dummyElementTasks;
|
||||
}
|
||||
|
||||
class DiagramSceneController::AcceptRelationVisitor : public MVoidConstVisitor
|
||||
{
|
||||
public:
|
||||
AcceptRelationVisitor(const MRelation *relation)
|
||||
: m_relation(relation)
|
||||
{
|
||||
}
|
||||
|
||||
bool isAccepted() const { return m_accepted; }
|
||||
|
||||
void visitMObject(const MObject *object) override
|
||||
{
|
||||
Q_UNUSED(object);
|
||||
m_accepted = dynamic_cast<const MDependency *>(m_relation) != 0;
|
||||
}
|
||||
|
||||
void visitMClass(const MClass *klass) override
|
||||
{
|
||||
Q_UNUSED(klass);
|
||||
m_accepted = dynamic_cast<const MDependency *>(m_relation) != 0
|
||||
|| dynamic_cast<const MInheritance *>(m_relation) != 0
|
||||
|| dynamic_cast<const MAssociation *>(m_relation) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const MRelation *m_relation = 0;
|
||||
bool m_accepted = false;
|
||||
};
|
||||
|
||||
DiagramSceneController::DiagramSceneController(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_modelController(0),
|
||||
@@ -225,6 +255,16 @@ void DiagramSceneController::createAssociation(DClass *endAClass, DClass *endBCl
|
||||
emit newElementCreated(relation, diagram);
|
||||
}
|
||||
|
||||
bool DiagramSceneController::relocateRelationEndA(DRelation *relation, DObject *targetObject)
|
||||
{
|
||||
return relocateRelationEnd(relation, targetObject, &MRelation::endAUid, &MRelation::setEndAUid);
|
||||
}
|
||||
|
||||
bool DiagramSceneController::relocateRelationEndB(DRelation *relation, DObject *targetObject)
|
||||
{
|
||||
return relocateRelationEnd(relation, targetObject, &MRelation::endBUid, &MRelation::setEndBUid);
|
||||
}
|
||||
|
||||
bool DiagramSceneController::isAddingAllowed(const Uid &modelElementKey, MDiagram *diagram)
|
||||
{
|
||||
MElement *modelElement = m_modelController->findElement(modelElementKey);
|
||||
@@ -673,4 +713,32 @@ DRelation *DiagramSceneController::addRelation(MRelation *modelRelation, const Q
|
||||
return diagramRelation;
|
||||
}
|
||||
|
||||
bool DiagramSceneController::relocateRelationEnd(DRelation *relation, DObject *targetObject,
|
||||
Uid (MRelation::*endUid)() const,
|
||||
void (MRelation::*setEndUid)(const Uid &))
|
||||
{
|
||||
QMT_CHECK(relation);
|
||||
if (targetObject && targetObject->uid() != relation->endAUid()) {
|
||||
MRelation *modelRelation = m_modelController->findRelation(relation->modelUid());
|
||||
QMT_CHECK(modelRelation);
|
||||
MObject *targetMObject = m_modelController->findObject(targetObject->modelUid());
|
||||
QMT_CHECK(targetMObject);
|
||||
AcceptRelationVisitor visitor(modelRelation);
|
||||
targetMObject->accept(&visitor);
|
||||
if (visitor.isAccepted()) {
|
||||
MObject *currentTargetMObject = m_modelController->findObject((modelRelation->*endUid)());
|
||||
QMT_CHECK(currentTargetMObject);
|
||||
m_modelController->undoController()->beginMergeSequence(tr("Relocate Relation"));
|
||||
if (currentTargetMObject == modelRelation->owner())
|
||||
m_modelController->moveRelation(targetMObject, modelRelation);
|
||||
m_modelController->startUpdateRelation(modelRelation);
|
||||
(modelRelation->*setEndUid)(targetMObject->uid());
|
||||
m_modelController->finishUpdateRelation(modelRelation, false);
|
||||
m_modelController->undoController()->endMergeSequence();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace qmt
|
||||
|
@@ -59,6 +59,8 @@ class QMT_EXPORT DiagramSceneController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class AcceptRelationVisitor;
|
||||
|
||||
public:
|
||||
explicit DiagramSceneController(QObject *parent = 0);
|
||||
~DiagramSceneController() override;
|
||||
@@ -85,6 +87,8 @@ public:
|
||||
const QList<QPointF> &intermediatePoints, MDiagram *diagram);
|
||||
void createAssociation(DClass *endAClass, DClass *endBClass,
|
||||
const QList<QPointF> &intermediatePoints, MDiagram *diagram);
|
||||
bool relocateRelationEndA(DRelation *relation, DObject *targetObject);
|
||||
bool relocateRelationEndB(DRelation *relation, DObject *targetObject);
|
||||
|
||||
bool isAddingAllowed(const Uid &modelElementKey, MDiagram *diagram);
|
||||
void addExistingModelElement(const Uid &modelElementKey, const QPointF &pos, MDiagram *diagram);
|
||||
@@ -124,6 +128,8 @@ private:
|
||||
DObject *addObject(MObject *modelObject, const QPointF &pos, MDiagram *diagram);
|
||||
DRelation *addRelation(MRelation *modelRelation, const QList<QPointF> &intermediatePoints,
|
||||
MDiagram *diagram);
|
||||
bool relocateRelationEnd(DRelation *relation, DObject *targetObject, Uid (MRelation::*endUid)() const,
|
||||
void (MRelation::*setEndUid)(const Uid &));
|
||||
|
||||
ModelController *m_modelController;
|
||||
DiagramController *m_diagramController;
|
||||
|
Reference in New Issue
Block a user