ModelEditor: Implement dragging end of custom relations

Change-Id: I38dff44cecd21d32393dfac76d581138dbb6a589
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Jochen Becher
2017-07-29 17:34:08 +02:00
parent 4c469e0111
commit 90e40f932d
3 changed files with 67 additions and 27 deletions

View File

@@ -91,6 +91,7 @@ DocumentController::DocumentController(QObject *parent) :
// diagram scene controller // diagram scene controller
m_diagramSceneController->setModelController(m_modelController); m_diagramSceneController->setModelController(m_modelController);
m_diagramSceneController->setDiagramController(m_diagramController); m_diagramSceneController->setDiagramController(m_diagramController);
m_diagramSceneController->setStereotypeController(m_stereotypeController);
// config controller // config controller
m_configController->setStereotypeController(m_stereotypeController); m_configController->setStereotypeController(m_stereotypeController);

View File

@@ -31,13 +31,13 @@
#include "qmt/diagram_controller/diagramcontroller.h" #include "qmt/diagram_controller/diagramcontroller.h"
#include "qmt/diagram_controller/dselection.h" #include "qmt/diagram_controller/dselection.h"
#include "qmt/diagram/dannotation.h" #include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dassociation.h"
#include "qmt/diagram/dboundary.h" #include "qmt/diagram/dboundary.h"
#include "qmt/diagram/dclass.h" #include "qmt/diagram/dclass.h"
#include "qmt/diagram/dpackage.h"
#include "qmt/diagram/ditem.h"
#include "qmt/diagram/drelation.h"
#include "qmt/diagram/dassociation.h"
#include "qmt/diagram/dconnection.h" #include "qmt/diagram/dconnection.h"
#include "qmt/diagram/ditem.h"
#include "qmt/diagram/dpackage.h"
#include "qmt/diagram/drelation.h"
#include "qmt/diagram/dswimlane.h" #include "qmt/diagram/dswimlane.h"
#include "qmt/diagram_ui/diagram_mime_types.h" #include "qmt/diagram_ui/diagram_mime_types.h"
#include "qmt/model_controller/modelcontroller.h" #include "qmt/model_controller/modelcontroller.h"
@@ -55,6 +55,8 @@
#include "qmt/model/mobject.h" #include "qmt/model/mobject.h"
#include "qmt/model/mpackage.h" #include "qmt/model/mpackage.h"
#include "qmt/model/msourceexpansion.h" #include "qmt/model/msourceexpansion.h"
#include "qmt/stereotype/customrelation.h"
#include "qmt/stereotype/stereotypecontroller.h"
#include "qmt/tasks/alignonrastervisitor.h" #include "qmt/tasks/alignonrastervisitor.h"
#include "qmt/tasks/isceneinspector.h" #include "qmt/tasks/isceneinspector.h"
#include "qmt/tasks/voidelementtasks.h" #include "qmt/tasks/voidelementtasks.h"
@@ -74,8 +76,11 @@ static VoidElementTasks dummyElementTasks;
class DiagramSceneController::AcceptRelationVisitor : public MVoidConstVisitor class DiagramSceneController::AcceptRelationVisitor : public MVoidConstVisitor
{ {
public: public:
AcceptRelationVisitor(const MRelation *relation) AcceptRelationVisitor(StereotypeController *stereotypeController, const MRelation *relation,
: m_relation(relation) RelationEnd relationEnd)
: m_stereotypeController(stereotypeController),
m_relation(relation),
m_relationEnd(relationEnd)
{ {
} }
@@ -84,30 +89,49 @@ public:
void visitMObject(const MObject *object) override void visitMObject(const MObject *object) override
{ {
Q_UNUSED(object); Q_UNUSED(object);
// TODO enhance with handling MConnection if (auto connection = dynamic_cast<const MConnection *>(m_relation)) {
m_accepted = dynamic_cast<const MDependency *>(m_relation) != 0; CustomRelation customRelation = m_stereotypeController->findCustomRelation(connection->customRelationId());
if (!customRelation.isNull()) {
QMT_ASSERT(customRelation.element() == CustomRelation::Element::Relation, return);
CustomRelation::End customEnd = m_relationEnd == EndA ? customRelation.endA() : customRelation.endB();
QStringList endItems = customEnd.endItems();
if (endItems.isEmpty())
endItems = customRelation.endItems();
QString stereotypeIconId = m_stereotypeController->findStereotypeIconId(StereotypeIcon::ElementItem, object->stereotypes());
if (stereotypeIconId.isEmpty() && !m_variety.isEmpty())
stereotypeIconId = m_stereotypeController->findStereotypeIconId(StereotypeIcon::ElementItem, QStringList(m_variety));
m_accepted = endItems.contains(stereotypeIconId);
}
}
if (!m_accepted)
m_accepted = dynamic_cast<const MDependency *>(m_relation) != nullptr;
} }
void visitMClass(const MClass *klass) override void visitMClass(const MClass *klass) override
{ {
Q_UNUSED(klass); m_accepted = dynamic_cast<const MInheritance *>(m_relation) != nullptr
// TODO enhance with handling MConnection || dynamic_cast<const MAssociation *>(m_relation) != nullptr;
m_accepted = dynamic_cast<const MDependency *>(m_relation) != 0 if (!m_accepted)
|| dynamic_cast<const MInheritance *>(m_relation) != 0 visitMObject(klass);
|| dynamic_cast<const MAssociation *>(m_relation) != 0; }
void visitMItem(const MItem *item) override
{
m_variety = item->variety();
visitMObject(item);
} }
private: private:
const MRelation *m_relation = 0; StereotypeController *m_stereotypeController = nullptr;
const MRelation *m_relation = nullptr;
RelationEnd m_relationEnd = EndA;
QString m_variety;
bool m_accepted = false; bool m_accepted = false;
}; };
DiagramSceneController::DiagramSceneController(QObject *parent) DiagramSceneController::DiagramSceneController(QObject *parent)
: QObject(parent), : QObject(parent),
m_modelController(0), m_elementTasks(&dummyElementTasks)
m_diagramController(0),
m_elementTasks(&dummyElementTasks),
m_sceneInspector(0)
{ {
} }
@@ -139,6 +163,11 @@ void DiagramSceneController::setDiagramController(DiagramController *diagramCont
m_diagramController = diagramController; m_diagramController = diagramController;
} }
void DiagramSceneController::setStereotypeController(StereotypeController *stereotypeController)
{
m_stereotypeController = stereotypeController;
}
void DiagramSceneController::setElementTasks(IElementTasks *elementTasks) void DiagramSceneController::setElementTasks(IElementTasks *elementTasks)
{ {
m_elementTasks = elementTasks; m_elementTasks = elementTasks;
@@ -302,12 +331,12 @@ void DiagramSceneController::createConnection(const QString &customRelationId,
bool DiagramSceneController::relocateRelationEndA(DRelation *relation, DObject *targetObject) bool DiagramSceneController::relocateRelationEndA(DRelation *relation, DObject *targetObject)
{ {
return relocateRelationEnd(relation, targetObject, &MRelation::endAUid, &MRelation::setEndAUid); return relocateRelationEnd(relation, targetObject, EndA, &MRelation::endAUid, &MRelation::setEndAUid);
} }
bool DiagramSceneController::relocateRelationEndB(DRelation *relation, DObject *targetObject) bool DiagramSceneController::relocateRelationEndB(DRelation *relation, DObject *targetObject)
{ {
return relocateRelationEnd(relation, targetObject, &MRelation::endBUid, &MRelation::setEndBUid); return relocateRelationEnd(relation, targetObject, EndB, &MRelation::endBUid, &MRelation::setEndBUid);
} }
bool DiagramSceneController::isAddingAllowed(const Uid &modelElementKey, MDiagram *diagram) bool DiagramSceneController::isAddingAllowed(const Uid &modelElementKey, MDiagram *diagram)
@@ -770,6 +799,7 @@ DRelation *DiagramSceneController::addRelation(MRelation *modelRelation, const Q
} }
bool DiagramSceneController::relocateRelationEnd(DRelation *relation, DObject *targetObject, bool DiagramSceneController::relocateRelationEnd(DRelation *relation, DObject *targetObject,
RelationEnd relationEnd,
Uid (MRelation::*endUid)() const, Uid (MRelation::*endUid)() const,
void (MRelation::*setEndUid)(const Uid &)) void (MRelation::*setEndUid)(const Uid &))
{ {
@@ -779,7 +809,7 @@ bool DiagramSceneController::relocateRelationEnd(DRelation *relation, DObject *t
QMT_ASSERT(modelRelation, return false); QMT_ASSERT(modelRelation, return false);
MObject *targetMObject = m_modelController->findObject(targetObject->modelUid()); MObject *targetMObject = m_modelController->findObject(targetObject->modelUid());
QMT_ASSERT(targetMObject, return false); QMT_ASSERT(targetMObject, return false);
AcceptRelationVisitor visitor(modelRelation); AcceptRelationVisitor visitor(m_stereotypeController, modelRelation, relationEnd);
targetMObject->accept(&visitor); targetMObject->accept(&visitor);
if (visitor.isAccepted()) { if (visitor.isAccepted()) {
MObject *currentTargetMObject = m_modelController->findObject((modelRelation->*endUid)()); MObject *currentTargetMObject = m_modelController->findObject((modelRelation->*endUid)());

View File

@@ -39,6 +39,7 @@ namespace qmt {
class Uid; class Uid;
class ModelController; class ModelController;
class DiagramController; class DiagramController;
class StereotypeController;
class MObject; class MObject;
class MPackage; class MPackage;
class MDiagram; class MDiagram;
@@ -61,6 +62,11 @@ class QMT_EXPORT DiagramSceneController : public QObject
class AcceptRelationVisitor; class AcceptRelationVisitor;
enum RelationEnd {
EndA,
EndB
};
public: public:
explicit DiagramSceneController(QObject *parent = 0); explicit DiagramSceneController(QObject *parent = 0);
~DiagramSceneController() override; ~DiagramSceneController() override;
@@ -74,6 +80,8 @@ public:
void setModelController(ModelController *modelController); void setModelController(ModelController *modelController);
DiagramController *diagramController() const { return m_diagramController; } DiagramController *diagramController() const { return m_diagramController; }
void setDiagramController(DiagramController *diagramController); void setDiagramController(DiagramController *diagramController);
StereotypeController *stereotypeController() const { return m_stereotypeController; }
void setStereotypeController(StereotypeController *stereotypeController);
IElementTasks *elementTasks() const { return m_elementTasks; } IElementTasks *elementTasks() const { return m_elementTasks; }
void setElementTasks(IElementTasks *elementTasks); void setElementTasks(IElementTasks *elementTasks);
ISceneInspector *sceneInspector() const { return m_sceneInspector; } ISceneInspector *sceneInspector() const { return m_sceneInspector; }
@@ -132,13 +140,14 @@ private:
DObject *addObject(MObject *modelObject, const QPointF &pos, MDiagram *diagram); DObject *addObject(MObject *modelObject, const QPointF &pos, MDiagram *diagram);
DRelation *addRelation(MRelation *modelRelation, const QList<QPointF> &intermediatePoints, DRelation *addRelation(MRelation *modelRelation, const QList<QPointF> &intermediatePoints,
MDiagram *diagram); MDiagram *diagram);
bool relocateRelationEnd(DRelation *relation, DObject *targetObject, Uid (MRelation::*endUid)() const, bool relocateRelationEnd(DRelation *relation, DObject *targetObject, RelationEnd relationEnd,
void (MRelation::*setEndUid)(const Uid &)); Uid (MRelation::*endUid)() const, void (MRelation::*setEndUid)(const Uid &));
ModelController *m_modelController; ModelController *m_modelController = nullptr;
DiagramController *m_diagramController; DiagramController *m_diagramController = nullptr;
IElementTasks *m_elementTasks; StereotypeController *m_stereotypeController = nullptr;
ISceneInspector *m_sceneInspector; IElementTasks *m_elementTasks = nullptr;
ISceneInspector *m_sceneInspector = nullptr;
}; };
} // namespace qmt } // namespace qmt