ConnectionItem::ConnectionItem(InterfaceItem* _iface1,
InterfaceItem* _iface2,
Dispatcher* _dispatcher,
- Parameters* _params,
- QGraphicsItem *_parent) : QGraphicsItem(_parent) {
+ Parameters* _params) : QGraphicsItem() {
dispatcher = _dispatcher;
case 1 : ref1 is group interface, and ref2 block interface of a block within the group
case 2 : the opposite of case 1
case 3 : ref1 and ref2 are block interface of blocks that are both within the same parent group.
+ case 4 : ref1 is source interface and ref2 interface of top group
+ case 5 : the opposite of case 4
*/
if (ref1->getOwner() == ref2->getOwner()->getParent()) {
fromInterfaceItem = _iface1;
}
}
+ else if ((ref1->getOwner()->isSourceBlock()) && (ref2->getOwner()->isTopGroupBlock())) {
+ fromInterfaceItem = _iface1;
+ toInterfaceItem = _iface2;
+ }
+ else if ((ref2->getOwner()->isSourceBlock()) && (ref1->getOwner()->isTopGroupBlock())) {
+ fromInterfaceItem = _iface2;
+ toInterfaceItem = _iface1;
+ }
// adding this to interface items
fromInterfaceItem->addConnectionItem(this);
toInterfaceItem->addConnectionItem(this);
setAcceptHoverEvents(true);
setFlag(ItemSendsGeometryChanges);
setCursor(Qt::PointingHandCursor);
- setZValue(0);
+ setZValue(200);
+
+ if (fromInterfaceItem->refInter->getPurpose() == AbstractInterface::Data) {
+ visible = true;
+ }
+ else {
+ visible = false;
+ }
setPath();
}
const QStyleOptionGraphicsItem *option,
QWidget *widget) {
+ if (!visible) return;
+
painter->setPen(Qt::blue);
if(selected){
painter->setPen(Qt::red);
// signals to the scene that this connection is going to change of shape.
prepareGeometryChange();
- pointFrom = fromInterfaceItem->getEndPointInGroup();
- pointTo = toInterfaceItem->getEndPointInGroup();
+ bool withinGroup = false;
+ /* NB: four cases
+ 1: from group input iface to box input iface
+ 2: from output box iface to group output iface
+ 3: from output box iface to input box iface
+ 4: from source output iface to input group iface
+
+ For cases 1 & 2, the position of group iface is given by getStartPosition
+ For all other cases, the iface from and to position is given by getEndPosition
+ */
+ if ((fromInterfaceItem->getOwner()->isGroupItem()) && (toInterfaceItem->getOwner()->isBoxItem())) {
+ pointFrom = fromInterfaceItem->getStartPosition();
+ pointTo = toInterfaceItem->getEndPosition();
+ withinGroup = true;
+ }
+ else if ((toInterfaceItem->getOwner()->isGroupItem()) && (fromInterfaceItem->getOwner()->isBoxItem())) {
+ pointFrom = fromInterfaceItem->getEndPosition();
+ pointTo = toInterfaceItem->getStartPosition();
+ withinGroup = true;
+ }
+ else {
+ pointFrom = fromInterfaceItem->getEndPosition();
+ pointTo = toInterfaceItem->getEndPosition();
+ }
int oriFrom, oriTo;
oriFrom = fromInterfaceItem->getOrientation();
/* NB: if src or dest is onwed by a GroupItem the orientation
must be changed as it is a block.
*/
- if(fromInterfaceItem->owner->isGroupItem()){
- switch(fromInterfaceItem->getOrientation()){
- case Parameters::North :
- oriFrom = Parameters::South;
- break;
- case Parameters::South :
- oriFrom = Parameters::North;
- break;
- case Parameters::East :
- oriFrom = Parameters::West;
- break;
- case Parameters::West :
- oriFrom = Parameters::East;
- break;
- }
- }
- if(toInterfaceItem->owner->isGroupItem()){
- switch(toInterfaceItem->getOrientation()){
- case Parameters::North :
- oriTo = Parameters::South;
- break;
- case Parameters::South :
- oriTo = Parameters::North;
- break;
- case Parameters::East :
- oriTo = Parameters::West;
- break;
- case Parameters::West :
- oriTo = Parameters::East;
- break;
+ if (withinGroup) {
+ if(fromInterfaceItem->owner->isGroupItem()){
+ switch(fromInterfaceItem->getOrientation()){
+ case Parameters::North :
+ oriFrom = Parameters::South;
+ break;
+ case Parameters::South :
+ oriFrom = Parameters::North;
+ break;
+ case Parameters::East :
+ oriFrom = Parameters::West;
+ break;
+ case Parameters::West :
+ oriFrom = Parameters::East;
+ break;
+ }
+ }
+ else if(toInterfaceItem->owner->isGroupItem()){
+ switch(toInterfaceItem->getOrientation()){
+ case Parameters::North :
+ oriTo = Parameters::South;
+ break;
+ case Parameters::South :
+ oriTo = Parameters::North;
+ break;
+ case Parameters::East :
+ oriTo = Parameters::West;
+ break;
+ case Parameters::West :
+ oriTo = Parameters::East;
+ break;
+ }
}
}
double gap1 = 0.0;
}
}
- pps.setWidth(5);
- pathShape = pps.createStroke(pathPaint);
+ //pps.setWidth(5);
+ //pathShape = pps.createStroke(pathPaint);
}
//cout << "drawing an esse" << endl;
pathPaint = QPainterPath(pointFrom);
+ QPainterPath s;
interPoints.clear();
- double gap = marginConn;
+ double gap = marginConn;
+
if ((orientationFrom == Parameters::North)||(orientationFrom == Parameters::West)) gap = -gap;
QPointF p(0.0,0.0);
if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+
// must draw a complete esse
- p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ s.moveTo(p);
pathPaint.lineTo(p);
interPoints.append(p);
p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x()-gap,(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x()-gap,pointTo.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
// must draw a complete esse
- p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap);
pathPaint.lineTo(p);
+ s.moveTo(p);
interPoints.append(p);
p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()-gap);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x(), pointTo.y()-gap);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
void ConnectionItem::computeStaircase(int orientationFrom) {
pathPaint = QPainterPath(pointFrom);
- interPoints.clear();
+ QPainterPath s;
+ double gap = marginConn;
+ interPoints.clear();
QPointF p(0.0,0.0);
if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+
+ if (orientationFrom == Parameters::West) gap = -gap;
+ p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ s.moveTo(p);
+
if (pointFrom.y() == pointTo.y()) {
//cout << "drawing straight line" << endl;
pathPaint.lineTo(pointTo);
+
}
else {
//cout << "drawing a staircase" << endl;
// sufficient place to draw a simple staircase
p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
+ p = QPointF(pointTo.x()-gap,pointTo.y());
+ s.lineTo(p);
}
else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+
+ if (orientationFrom == Parameters::North) gap = -gap;
+
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ s.moveTo(p);
+
if (pointFrom.x() == pointTo.x()) {
//cout << "drawing straight line" << endl;
- pathPaint.lineTo(pointTo);
+ pathPaint.lineTo(pointTo);
}
else {
//cout << "drawing a staircase" << endl;
// sufficient place to draw a simple staircase
p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
+ p = QPointF(pointTo.x(),pointTo.y()-gap);
+ s.lineTo(p);
}
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
/* drawCorner():
pathPaint = QPainterPath(pointFrom);
interPoints.clear();
QPointF p(0.0,0.0);
+ QPainterPath s;
+ double gap = marginConn;
+
//cout << "drawing a corner" << endl;
if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
+ if (orientationFrom == Parameters::West) gap = -gap;
+ p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ s.moveTo(p);
p = QPointF(pointTo.x(),pointFrom.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
+ p = QPointF(pointTo.x(),pointTo.y()-gap);
+ s.lineTo(p);
}
else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
+ if (orientationFrom == Parameters::North) gap = -gap;
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ s.moveTo(p);
p = QPointF(pointFrom.x(),pointTo.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
+ p = QPointF(pointTo.x()-gap,pointTo.y());
+ s.lineTo(p);
}
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
/* drawOpenRect():
__
|
|_|
+
+ Its beginning and end have always a size of marginConn
*/
void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) {
pathPaint = QPainterPath(pointFrom);
QPointF p(0.0,0.0);
double gap1 = marginConn;
double gap2 = marginConn;
+ QPainterPath s;
//cout << "drawing an OpenRect" << endl;
if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
}
p = QPointF(pointFrom.x()+gap1,pointFrom.y());
pathPaint.lineTo(p);
+ s.moveTo(p);
interPoints.append(p);
p = QPointF(pointFrom.x()+gap1,pointTo.y()+gap2);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x(),pointTo.y()+gap2);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
p = QPointF(pointFrom.x(),pointFrom.y()+gap1);
pathPaint.lineTo(p);
+ s.moveTo(p);
interPoints.append(p);
p = QPointF(pointTo.x()+gap2,pointFrom.y()+gap1);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x()+gap2,pointTo.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
+
/* drawHookSmallEnd():
A Hook has the following shape :
void ConnectionItem::computeHookSmallEnd(int orientationFrom, int orientationTo) {
pathPaint = QPainterPath(pointFrom);
interPoints.clear();
- QPointF p(0.0,0.0);
- double gap = marginConn;
+ QPointF p(0.0,0.0);
+ QPainterPath s;
+ double gap2 = marginConn;
+ double gap1 = marginConn;
//cout << "drawing a Hook with small end" << endl;
if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
- if (orientationTo == Parameters::North) gap = -gap;
+ if (orientationFrom == Parameters::West) gap1 = -gap1;
+ if (orientationTo == Parameters::North) gap2 = -gap2;
+ p = QPointF(pointFrom.x()+gap1,pointFrom.y());
+ s.moveTo(p);
p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
- p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()+gap);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()+gap2);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
- p = QPointF(pointTo.x(),pointTo.y()+gap);
+ p = QPointF(pointTo.x(),pointTo.y()+gap2);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
- if (orientationTo == Parameters::West) gap = -gap;
-
+ if (orientationFrom == Parameters::North) gap1 = -gap1;
+ if (orientationTo == Parameters::West) gap2 = -gap2;
+
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap1);
+ s.moveTo(p);
p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
- p = QPointF(pointTo.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
+ p = QPointF(pointTo.x()+gap2,(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
- p = QPointF(pointTo.x()+gap,pointTo.y());
+ p = QPointF(pointTo.x()+gap2,pointTo.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
}
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
/* drawHookSmallStart():
pathPaint = QPainterPath(pointFrom);
interPoints.clear();
QPointF p(0.0,0.0);
- double gap = marginConn;
+ QPainterPath s;
+ double gap1 = marginConn;
+ double gap2 = marginConn;
//cout << "drawing a Hook with small start" << endl;
if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
- if (orientationFrom == Parameters::West) gap = -gap;
+ if (orientationFrom == Parameters::West) gap1 = -gap1;
+ if (orientationTo == Parameters::North) gap2 = -gap2;
- p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ p = QPointF(pointFrom.x()+gap1,pointFrom.y());
+ s.moveTo(p);
pathPaint.lineTo(p);
interPoints.append(p);
- p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
+ p = QPointF(pointFrom.x()+gap1,(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
+ p = QPointF(pointTo.x(),pointFrom.y()+gap2);
+ s.lineTo(p);
}
else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
- if (orientationFrom == Parameters::North) gap = -gap;
+ if (orientationFrom == Parameters::North) gap1 = -gap1;
+ if (orientationTo == Parameters::West) gap2 = -gap2;
- p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap1);
+ s.moveTo(p);
pathPaint.lineTo(p);
interPoints.append(p);
- p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap);
+ p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap1);
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y());
pathPaint.lineTo(p);
+ s.lineTo(p);
interPoints.append(p);
pathPaint.lineTo(pointTo);
+ p = QPointF(pointTo.x()+gap2,pointFrom.y());
+ s.lineTo(p);
}
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
/* drawElle():
pathPaint = QPainterPath(pointFrom);
interPoints.clear();
QPointF p(0.0,0.0);
+ QPainterPath s;
+ double gap = marginConn;
+
double x;
double y;
- switch(orientationFrom){
- case Parameters::North :
- if(pointFrom.y() < pointTo.y()) {
- y = pointFrom.y()-marginConn;
- }
- else {
- y = pointTo.y()-marginConn;
- }
- p = QPointF(pointFrom.x(),y);
- pathPaint.lineTo(p);
- interPoints.append(p);
- p = QPointF(pointTo.x(),y);
- pathPaint.lineTo(p);
- interPoints.append(p);
- pathPaint.lineTo(pointTo);
- break;
- case Parameters::South :
- if(pointFrom.y() > pointTo.y()) {
- y = pointFrom.y()+marginConn;
- }
- else {
- y = pointTo.y()+marginConn;
+ if ((orientationFrom == Parameters::North) || (orientationFrom == Parameters::South)) {
+ double diffPos = pointFrom.y() - pointTo.y();
+ if (orientationFrom == Parameters::North) {
+ gap = -gap;
+ diffPos = -diffPos;
}
- p = QPointF(pointFrom.x(),y);
- pathPaint.lineTo(p);
- interPoints.append(p);
- p = QPointF(pointTo.x(),y);
- pathPaint.lineTo(p);
- interPoints.append(p);
- pathPaint.lineTo(pointTo);
- break;
- case Parameters::West :
- if(pointFrom.x() < pointTo.x()) {
- x = pointFrom.x()-marginConn;
+ p = QPointF(pointFrom.x(),pointFrom.y()+gap);
+ s.moveTo(p);
+ if (diffPos >= 0.0) {
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),pointFrom.y()+gap);
+ pathPaint.lineTo(p);
+ s.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ p = QPointF(pointTo.x(),pointTo.y()+gap);
+ s.lineTo(p);
}
else {
- x = pointTo.x()-marginConn;
+ p = QPointF(pointFrom.x(),pointTo.y()+gap);
+ pathPaint.lineTo(p);
+ s.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x(),pointTo.y()+gap);
+ pathPaint.lineTo(p);
+ s.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ }
+ }
+ else if ((orientationFrom == Parameters::West) || (orientationFrom == Parameters::East)) {
+ double diffPos = pointFrom.x() - pointTo.x();
+ if (orientationFrom == Parameters::West) {
+ gap = -gap;
+ diffPos = -diffPos;
}
- p = QPointF(x, pointFrom.y());
- pathPaint.lineTo(p);
- interPoints.append(p);
- p = QPointF(x, pointTo.y());
- pathPaint.lineTo(p);
- interPoints.append(p);
- pathPaint.lineTo(pointTo);
- break;
- case Parameters::East :
- if(pointFrom.x() > pointTo.x()) {
- x = pointFrom.x()+marginConn;
+ p = QPointF(pointFrom.x()+gap,pointFrom.y());
+ s.moveTo(p);
+ if (diffPos >= 0.0) {
+ pathPaint.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()+gap,pointFrom.y());
+ pathPaint.lineTo(p);
+ s.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
+ p = QPointF(pointTo.x()+gap,pointTo.y());
+ s.lineTo(p);
}
else {
- x = pointTo.x()+marginConn;
+ p = QPointF(pointFrom.x()+gap,pointTo.y());
+ pathPaint.lineTo(p);
+ s.lineTo(p);
+ interPoints.append(p);
+ p = QPointF(pointTo.x()+gap,pointTo.y());
+ pathPaint.lineTo(p);
+ s.lineTo(p);
+ interPoints.append(p);
+ pathPaint.lineTo(pointTo);
}
- p = QPointF(x, pointFrom.y());
- pathPaint.lineTo(p);
- interPoints.append(p);
- p = QPointF(x, pointTo.y());
- pathPaint.lineTo(p);
- interPoints.append(p);
- pathPaint.lineTo(pointTo);
- break;
}
+
+ pps.setWidth(5);
+ pathShape = pps.createStroke(s);
}
void ConnectionItem::setSelected(bool selected) {
this->selected = selected;
if(selected){
- setZValue(50);
+ setZValue(201);
} else {
- setZValue(0);
+ setZValue(200);
}
}
/* have to check if the connection can be removed.
If the from or to InterfaceItem is owned by a group item, and this item
is both connected to and from, thus it is impossible to remove this connection
+ because there would be a group interface alone and not connected and this situation is not allowed.
+
+ Nevertheless, there are 2 exceptions :
+ - a from group interface is connected to more than one input interface
+ - the connection is between a source block outside the top group and the top group
*/
bool canRemove = true;
- InterfaceItem* groupIfaceItem = NULL;
+
if (fromInterfaceItem->getOwner()->isGroupItem()) {
- groupIfaceItem = fromInterfaceItem;
- }
- else if (toInterfaceItem->getOwner()->isGroupItem()) {
- groupIfaceItem = toInterfaceItem;
+ ConnectedInterface* ref = fromInterfaceItem->refInter;
+ if ((ref->isConnectedFrom()) && (ref->getConnectedTo().length() == 1)) {
+ canRemove = false;
+ }
}
-
- if (groupIfaceItem != NULL) {
- ConnectedInterface* ref = groupIfaceItem->refInter;
+ else if ((toInterfaceItem->getOwner()->isGroupItem()) && (! toInterfaceItem->getOwner()->getRefBlock()->isTopGroupBlock())) {
+ ConnectedInterface* ref = toInterfaceItem->refInter;
if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
canRemove = false;
}
QAction * selectedAction= menu.exec(event->screenPos());
if(selectedAction == removeAction){
- dispatcher->removeConnection(this);
+ dispatcher->removeConnection(Dispatcher::Design, this);
}
}
}