]> AND Private Git Repository - blast.git/blob - ConnectionItem.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
adding save to gitignore
[blast.git] / ConnectionItem.cpp
1 #include "ConnectionItem.h"
2
3 #include "Dispatcher.h"
4 #include "Parameters.h"
5 #include "AbstractBoxItem.h"
6 #include "ConnectedInterface.h"
7 #include "InterfaceItem.h"
8 #include "AbstractBlock.h"
9
10 //int ConnectionItem::counter = 0;
11
12 ConnectionItem::ConnectionItem(InterfaceItem* _iface1,
13                                InterfaceItem* _iface2,
14                                Dispatcher* _dispatcher,
15                                Parameters* _params,
16                                QGraphicsItem *_parent) : QGraphicsItem(_parent) {
17
18
19   dispatcher = _dispatcher;
20   params = _params;
21
22   ConnectedInterface* ref1 = _iface1->refInter;
23   ConnectedInterface* ref2 = _iface2->refInter;
24   /* ref. note in .h
25      case 1 : ref1 is group interface, and ref2 block interface of a block within the group
26      case 2 : the opposite of case 1
27      case 3 : ref1 and ref2 are block interface of blocks that are both within the same parent group.
28    */
29   if (ref1->getOwner() == ref2->getOwner()->getParent()) {
30
31     if (ref1->getDirection() == AbstractInterface::Input) {
32       fromInterfaceItem = _iface1;
33       toInterfaceItem = _iface2;
34     }
35     else if (ref1->getDirection() == AbstractInterface::InOut) {
36       fromInterfaceItem = _iface1;
37       toInterfaceItem = _iface2;
38     }
39     else if (ref1->getDirection() == AbstractInterface::Output) {
40       toInterfaceItem = _iface1;
41       fromInterfaceItem = _iface2;
42     }
43   }
44   else if (ref1->getOwner()->getParent() == ref2->getOwner()) {
45
46     if (ref1->getDirection() == AbstractInterface::Input) {
47       fromInterfaceItem = _iface2;
48       toInterfaceItem = _iface1;
49     }
50     else if (ref1->getDirection() == AbstractInterface::InOut) {
51       fromInterfaceItem = _iface2;
52       toInterfaceItem = _iface1;
53     }
54     else if (ref1->getDirection() == AbstractInterface::Output) {
55       toInterfaceItem = _iface2;
56       fromInterfaceItem = _iface1;
57     }
58   }
59   // NB : this case is in fact similar to the previous. Kept here for clarity
60   else if (ref1->getOwner()->getParent() == ref2->getOwner()->getParent()) {
61
62     if (ref1->getDirection() == AbstractInterface::Input) {
63       fromInterfaceItem = _iface2;
64       toInterfaceItem = _iface1;
65     }
66     else if (ref1->getDirection() == AbstractInterface::InOut) {
67       fromInterfaceItem = _iface2;
68       toInterfaceItem = _iface1;
69     }
70     else if (ref1->getDirection() == AbstractInterface::Output) {
71       toInterfaceItem = _iface2;
72       fromInterfaceItem = _iface1;
73     }
74   }
75   // adding this to interface items
76   fromInterfaceItem->addConnectionItem(this);
77   toInterfaceItem->addConnectionItem(this);
78
79   selected = false;
80   marginConn = params->arrowLineLength+params->arrowWidth;
81
82   setFlag(ItemIsSelectable);
83   setAcceptHoverEvents(true);
84   setFlag(ItemSendsGeometryChanges);
85   setCursor(Qt::PointingHandCursor);
86   setZValue(0);
87
88   setPath();
89 }
90
91
92 ConnectionItem::ConnectionItem(const ConnectionItem &copy) {
93   pointFrom = copy.pointFrom;
94   pointTo = copy.pointTo;
95   interPoint1 = copy.interPoint1;
96   interPoint2 = copy.interPoint2;
97   interPoint3 = copy.interPoint3;
98   interPoint4 = copy.interPoint4;
99 }
100
101 ConnectionItem::~ConnectionItem() {
102 }
103
104 ConnectionItem::ConnectionItem() {
105 }
106
107 QPainterPath ConnectionItem::shape() const {
108   return pathShape;
109 }
110
111 QRectF ConnectionItem::boundingRect() const {
112
113   QPointF start, end;
114
115   if(pointFrom.x() < pointTo.x()){
116     start.setX(pointFrom.x()-20);
117     end.setX(pointTo.x()+20);
118   } else {
119     start.setX(pointTo.x()-20);
120     end.setX(pointFrom.x()+20);
121   }
122   if(pointFrom.y() < pointTo.y()){
123     start.setY(pointFrom.y()-20);
124     end.setY(pointTo.y()+20);
125   } else {
126     start.setY(pointTo.y()-20);
127     end.setY(pointFrom.y()+20);
128   }
129   return QRectF(start, end);
130 }
131
132 void ConnectionItem::paint(QPainter *painter,
133                            const QStyleOptionGraphicsItem *option,
134                            QWidget *widget) {
135
136   painter->setPen(Qt::blue);
137   if(selected){
138     painter->setPen(Qt::red);
139   }
140
141   painter->drawPath(pathPaint);
142 }
143
144 void ConnectionItem::addInterPoint(QPointF point) {
145
146 }
147
148 void ConnectionItem::setPath() {
149
150   // signals to the scene that this connection is going to change of shape.
151   prepareGeometryChange();
152
153   pointFrom = fromInterfaceItem->getEndPointInGroup();
154   pointTo = toInterfaceItem->getEndPointInGroup();
155
156   int oriFrom, oriTo;
157   oriFrom = fromInterfaceItem->getOrientation();
158   oriTo = toInterfaceItem->getOrientation();
159
160 /* NB: if src or dest is onwed by a GroupItem the orientation
161    must be changed as it is a block.
162  */
163   if(fromInterfaceItem->owner->isGroupItem()){
164     switch(fromInterfaceItem->getOrientation()){
165     case Parameters::North :
166       oriFrom = Parameters::South;
167       break;
168     case Parameters::South :
169       oriFrom = Parameters::North;
170       break;
171     case Parameters::East :
172       oriFrom = Parameters::West;
173       break;
174     case Parameters::West :
175       oriFrom = Parameters::East;
176       break;
177     }
178   }
179   if(toInterfaceItem->owner->isGroupItem()){
180     switch(toInterfaceItem->getOrientation()){
181     case Parameters::North :
182       oriTo = Parameters::South;
183       break;
184     case Parameters::South :
185       oriTo = Parameters::North;
186       break;
187     case Parameters::East :
188       oriTo = Parameters::West;
189       break;
190     case Parameters::West :
191       oriTo = Parameters::East;
192       break;
193     }
194   }
195   double gap1 = 0.0;
196   double gap2 = 0.0;
197
198   if(oriFrom == Parameters::South) {
199
200     // FROM SOUTH TO SOUTH
201     if(oriTo == Parameters::South) {
202       computeElle(oriFrom);
203     }
204     // FROM SOUTH TO NORTH
205     else if(oriTo == Parameters::North) {
206       gap1 = pointTo.y() - pointFrom.y();
207       if (gap1 > 2*marginConn) {
208         computeStaircase(oriFrom);
209       }
210       else {
211         computeEsse(oriFrom);
212       }
213     }
214     // FROM SOUTH TO EAST OR WEST
215     else if ((oriTo == Parameters::East) || (oriTo == Parameters::West)){
216
217       gap1 = pointTo.x() - pointFrom.x();
218       if (oriTo == Parameters::West) gap1 = -gap1;
219       gap2 = pointTo.y() - pointFrom.y();
220
221       if (gap1 > 0.0) {
222         if (gap2 > 0.0) {
223           computeHookSmallEnd(oriFrom,oriTo);
224         }
225         else {
226           computeOpenRect(oriFrom,oriTo);
227         }
228       }
229       else {
230         if (gap2 >= 0.0) {
231           computeCorner(oriFrom);
232         }
233         else {
234           computeHookSmallStart(oriFrom,oriTo);
235         }
236       }
237     }
238   }
239   else if(oriFrom == Parameters::North) {
240
241     // FROM NORTH TO SOUTH
242     if(oriTo == Parameters::South) {
243       gap1 = pointFrom.y() - pointTo.y();
244       if (gap1 > 2*marginConn) {
245         computeStaircase(oriFrom);
246       }
247       else {
248         computeEsse(oriFrom);
249       }
250     }
251     // FROM NORTH TO NORTH
252     else if(oriTo == Parameters::North) {
253       computeElle(oriFrom);
254     }
255     // FROM NORTH TO EAST OR WEST
256     else if ((oriTo == Parameters::East) || (oriTo == Parameters::West)){
257
258       gap1 = pointTo.x() - pointFrom.x();
259       if (oriTo == Parameters::West) gap1 = -gap1;
260       gap2 = pointFrom.y() - pointTo.y();
261
262       if (gap1 > 0.0) {
263         if (gap2 > 0.0) {
264           computeHookSmallEnd(oriFrom,oriTo);
265         }
266         else {
267           computeOpenRect(oriFrom,oriTo);
268         }
269       }
270       else {
271         if (gap2 >= 0.0) {
272           computeCorner(oriFrom);
273         }
274         else {
275           computeHookSmallStart(oriFrom,oriTo);
276         }
277       }
278     }
279   }
280   else if(oriFrom == Parameters::East) {
281     // FROM EAST TO NORTH OR SOUTH
282     if ((oriTo == Parameters::South) || (oriTo == Parameters::North)){
283
284       gap1 = pointFrom.x() - pointTo.x();
285       gap2 = pointFrom.y() - pointTo.y();
286       if (oriTo == Parameters::North) gap2 = -gap2;
287
288       if (gap1 > 0.0) {
289         if (gap2 > 0.0) {
290           computeHookSmallStart(oriFrom,oriTo);
291         }
292         else {
293           computeOpenRect(oriFrom,oriTo);
294         }
295       }
296       else {
297         if (gap2 >= 0.0) {
298           computeCorner(oriFrom);
299         }
300         else {
301           computeHookSmallEnd(oriFrom,oriTo);
302         }
303       }
304     }
305     else if(oriTo == Parameters::East) {
306       computeElle(oriFrom);
307     }
308     else if (oriTo == Parameters::West) {
309       gap1 = pointTo.x() - pointFrom.x();
310       if (gap1 > 2*marginConn) {
311         computeStaircase(oriFrom);
312       }
313       else {
314         computeEsse(oriFrom);
315       }
316     }
317   }
318   else if (oriFrom == Parameters::West) {
319
320     // FROM WEST TO NORTH OR SOUTH
321     if ((oriTo == Parameters::South) || (oriTo == Parameters::North)){
322
323       gap1 = pointTo.x() - pointFrom.x();
324       gap2 = pointFrom.y() - pointTo.y();
325       if (oriTo == Parameters::North) gap2 = -gap2;
326
327       if (gap1 > 0.0) {
328         if (gap2 > 0.0) {
329           computeHookSmallStart(oriFrom,oriTo);
330         }
331         else {
332           computeOpenRect(oriFrom,oriTo);
333         }
334       }
335       else {
336         if (gap2 >= 0.0) {
337           computeCorner(oriFrom);
338         }
339         else {
340           computeHookSmallEnd(oriFrom,oriTo);
341         }
342       }
343     }
344     else if(oriTo == Parameters::East) {
345       gap1 = pointFrom.x() - pointTo.x();
346       if (gap1 > 2*marginConn) {
347         computeStaircase(oriFrom);
348       }
349       else {
350         computeEsse(oriFrom);
351       }
352     }
353     else if (oriTo == Parameters::West) {
354       computeElle(oriFrom);
355     }
356   }
357
358   pps.setWidth(5);
359   pathShape = pps.createStroke(pathPaint);
360 }
361
362
363 void ConnectionItem::computeEsse(int orientationFrom) {
364
365   //cout << "drawing an esse" << endl;
366   pathPaint = QPainterPath(pointFrom);
367   interPoints.clear();
368   double gap = marginConn;
369   if ((orientationFrom == Parameters::North)||(orientationFrom == Parameters::West)) gap = -gap;
370   QPointF p(0.0,0.0);
371
372   if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
373     // must draw a complete esse
374     p = QPointF(pointFrom.x()+gap,pointFrom.y());
375     pathPaint.lineTo(p);
376     interPoints.append(p);
377     p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
378     pathPaint.lineTo(p);
379     interPoints.append(p);
380     p = QPointF(pointTo.x()-gap,(pointFrom.y()+pointTo.y())/2.0);
381     pathPaint.lineTo(p);
382     interPoints.append(p);
383     p = QPointF(pointTo.x()-gap,pointTo.y());
384     pathPaint.lineTo(p);
385     interPoints.append(p);
386     pathPaint.lineTo(pointTo);
387   }
388   else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
389
390     // must draw a complete esse
391     p = QPointF(pointFrom.x(),pointFrom.y()+gap);
392     pathPaint.lineTo(p);
393     interPoints.append(p);
394     p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap);
395     pathPaint.lineTo(p);
396     interPoints.append(p);
397     p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()-gap);
398     pathPaint.lineTo(p);
399     interPoints.append(p);
400     p = QPointF(pointTo.x(), pointTo.y()-gap);
401     pathPaint.lineTo(p);
402     interPoints.append(p);
403     pathPaint.lineTo(pointTo);
404   }
405 }
406
407 void ConnectionItem::computeStaircase(int orientationFrom) {
408
409   pathPaint = QPainterPath(pointFrom);
410   interPoints.clear();
411   QPointF p(0.0,0.0);
412
413   if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
414     if (pointFrom.y() == pointTo.y()) {
415       //cout << "drawing straight line" << endl;
416       pathPaint.lineTo(pointTo);
417     }
418     else  {
419       //cout << "drawing a staircase" << endl;
420       // sufficient place to draw a simple staircase
421       p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y());
422       pathPaint.lineTo(p);
423       interPoints.append(p);
424       p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y());
425       pathPaint.lineTo(p);
426       interPoints.append(p);
427       pathPaint.lineTo(pointTo);
428     }
429   }
430   else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
431     if (pointFrom.x() == pointTo.x()) {
432       //cout << "drawing straight line" << endl;
433       pathPaint.lineTo(pointTo);
434     }
435     else {
436       //cout << "drawing a staircase" << endl;
437       // sufficient place to draw a simple staircase
438       p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0);
439       pathPaint.lineTo(p);
440       interPoints.append(p);
441       p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0);
442       pathPaint.lineTo(p);
443       interPoints.append(p);
444       pathPaint.lineTo(pointTo);
445     }
446   }
447 }
448
449 /* drawCorner():
450
451   A Corner has the following shape :
452   |
453   |__
454
455 */
456 void ConnectionItem::computeCorner(int orientationFrom) {
457
458   pathPaint = QPainterPath(pointFrom);
459   interPoints.clear();
460   QPointF p(0.0,0.0);
461   //cout << "drawing a corner" << endl;
462
463   if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
464     p = QPointF(pointTo.x(),pointFrom.y());
465     pathPaint.lineTo(p);
466     interPoints.append(p);
467     pathPaint.lineTo(pointTo);
468   }
469   else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
470     p = QPointF(pointFrom.x(),pointTo.y());
471     pathPaint.lineTo(p);
472     interPoints.append(p);
473     pathPaint.lineTo(pointTo);
474   }
475 }
476
477 /* drawOpenRect():
478
479   A OpenRect has the following shape :
480   __
481   |
482   |_|
483 */
484 void ConnectionItem::computeOpenRect(int orientationFrom, int orientationTo) {
485   pathPaint = QPainterPath(pointFrom);
486   interPoints.clear();
487   QPointF p(0.0,0.0);
488   double gap1 = marginConn;
489   double gap2 = marginConn;
490   //cout << "drawing an OpenRect" << endl;
491
492   if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
493     if (orientationFrom == Parameters::West) {
494       gap1 = -gap1;
495     }
496     if (orientationTo == Parameters::North) {
497       gap2 = -gap2;
498     }
499     p = QPointF(pointFrom.x()+gap1,pointFrom.y());
500     pathPaint.lineTo(p);
501     interPoints.append(p);
502     p = QPointF(pointFrom.x()+gap1,pointTo.y()+gap2);
503     pathPaint.lineTo(p);
504     interPoints.append(p);
505     p = QPointF(pointTo.x(),pointTo.y()+gap2);
506     pathPaint.lineTo(p);
507     interPoints.append(p);
508     pathPaint.lineTo(pointTo);
509
510   }
511   else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
512     if (orientationFrom == Parameters::North) {
513       gap1 = -gap1;
514     }
515     if (orientationTo == Parameters::West) {
516       gap2 = -gap2;
517     }
518     p = QPointF(pointFrom.x(),pointFrom.y()+gap1);
519     pathPaint.lineTo(p);
520     interPoints.append(p);
521     p = QPointF(pointTo.x()+gap2,pointFrom.y()+gap1);
522     pathPaint.lineTo(p);
523     interPoints.append(p);
524     p = QPointF(pointTo.x()+gap2,pointTo.y());
525     pathPaint.lineTo(p);
526     interPoints.append(p);
527     pathPaint.lineTo(pointTo);
528   }
529 }
530
531 /* drawHookSmallEnd():
532
533   A Hook has the following shape :
534   _
535    |
536    |_|
537    Its end has always a size of marginConn
538 */
539 void ConnectionItem::computeHookSmallEnd(int orientationFrom, int orientationTo) {
540   pathPaint = QPainterPath(pointFrom);
541   interPoints.clear();
542   QPointF p(0.0,0.0);
543   double gap = marginConn;
544   //cout << "drawing a Hook with small end" << endl;
545
546   if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
547
548     if (orientationTo == Parameters::North) gap = -gap;
549
550     p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y());
551     pathPaint.lineTo(p);
552     interPoints.append(p);
553     p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y()+gap);
554     pathPaint.lineTo(p);
555     interPoints.append(p);
556     p = QPointF(pointTo.x(),pointTo.y()+gap);
557     pathPaint.lineTo(p);
558     interPoints.append(p);
559     pathPaint.lineTo(pointTo);
560
561   }
562   else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
563
564     if (orientationTo == Parameters::West) gap = -gap;
565
566     p = QPointF(pointFrom.x(),(pointFrom.y()+pointTo.y())/2.0);
567     pathPaint.lineTo(p);
568     interPoints.append(p);
569     p = QPointF(pointTo.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
570     pathPaint.lineTo(p);
571     interPoints.append(p);
572     p = QPointF(pointTo.x()+gap,pointTo.y());
573     pathPaint.lineTo(p);
574     interPoints.append(p);
575     pathPaint.lineTo(pointTo);
576   }
577 }
578
579 /* drawHookSmallStart():
580
581   A Hook has the following shape :
582   _
583    |
584    |_|
585    Its start has always a size of marginConn
586 */
587 void ConnectionItem::computeHookSmallStart(int orientationFrom, int orientationTo) {
588   pathPaint = QPainterPath(pointFrom);
589   interPoints.clear();
590   QPointF p(0.0,0.0);
591   double gap = marginConn;
592   //cout << "drawing a Hook with small start" << endl;
593
594   if ((orientationFrom == Parameters::East)||(orientationFrom == Parameters::West)) {
595
596     if (orientationFrom == Parameters::West) gap = -gap;
597
598     p = QPointF(pointFrom.x()+gap,pointFrom.y());
599     pathPaint.lineTo(p);
600     interPoints.append(p);
601     p = QPointF(pointFrom.x()+gap,(pointFrom.y()+pointTo.y())/2.0);
602     pathPaint.lineTo(p);
603     interPoints.append(p);
604     p = QPointF(pointTo.x(),(pointFrom.y()+pointTo.y())/2.0);
605     pathPaint.lineTo(p);
606     interPoints.append(p);
607     pathPaint.lineTo(pointTo);
608   }
609   else if ((orientationFrom == Parameters::South)||(orientationFrom == Parameters::North)) {
610
611     if (orientationFrom == Parameters::North) gap = -gap;
612
613     p = QPointF(pointFrom.x(),pointFrom.y()+gap);
614     pathPaint.lineTo(p);
615     interPoints.append(p);
616     p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointFrom.y()+gap);
617     pathPaint.lineTo(p);
618     interPoints.append(p);
619     p = QPointF((pointFrom.x()+pointTo.x())/2.0,pointTo.y());
620     pathPaint.lineTo(p);
621     interPoints.append(p);
622     pathPaint.lineTo(pointTo);
623   }
624 }
625
626 /* drawElle():
627
628   An Elle has the following shape :
629   |
630   |_|
631
632 */
633 void ConnectionItem::computeElle(int orientationFrom) {
634
635   pathPaint = QPainterPath(pointFrom);
636   interPoints.clear();
637   QPointF p(0.0,0.0);
638   double x;
639   double y;
640   switch(orientationFrom){
641   case Parameters::North :
642     if(pointFrom.y() < pointTo.y()) {
643       y = pointFrom.y()-marginConn;
644     }
645     else {
646       y = pointTo.y()-marginConn;
647     }
648     p = QPointF(pointFrom.x(),y);
649     pathPaint.lineTo(p);
650     interPoints.append(p);
651     p = QPointF(pointTo.x(),y);
652     pathPaint.lineTo(p);
653     interPoints.append(p);
654     pathPaint.lineTo(pointTo);
655     break;
656   case Parameters::South :
657     if(pointFrom.y() > pointTo.y()) {
658       y = pointFrom.y()+marginConn;
659     }
660     else {
661       y = pointTo.y()+marginConn;
662     }
663     p = QPointF(pointFrom.x(),y);
664     pathPaint.lineTo(p);
665     interPoints.append(p);
666     p = QPointF(pointTo.x(),y);
667     pathPaint.lineTo(p);
668     interPoints.append(p);
669     pathPaint.lineTo(pointTo);
670     break;
671   case Parameters::West :
672     if(pointFrom.x() < pointTo.x()) {
673       x = pointFrom.x()-marginConn;
674     }
675     else {
676       x = pointTo.x()-marginConn;
677     }
678     p = QPointF(x, pointFrom.y());
679     pathPaint.lineTo(p);
680     interPoints.append(p);
681     p = QPointF(x, pointTo.y());
682     pathPaint.lineTo(p);
683     interPoints.append(p);
684     pathPaint.lineTo(pointTo);
685     break;
686   case Parameters::East :
687     if(pointFrom.x() > pointTo.x()) {
688       x = pointFrom.x()+marginConn;
689     }
690     else {
691       x = pointTo.x()+marginConn;
692     }
693     p = QPointF(x, pointFrom.y());
694     pathPaint.lineTo(p);
695     interPoints.append(p);
696     p = QPointF(x, pointTo.y());
697     pathPaint.lineTo(p);
698     interPoints.append(p);
699     pathPaint.lineTo(pointTo);
700     break;
701   }
702 }
703
704 void ConnectionItem::setSelected(bool selected) {
705   this->selected = selected;
706   if(selected){
707     setZValue(50);
708   } else {
709     setZValue(0);
710   }
711 }
712
713 void ConnectionItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
714   QGraphicsItem::mousePressEvent(event);
715   setZValue(zValue()+100);  
716   setSelected(!selected);
717   update(boundingRect());
718 }
719
720 void ConnectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
721   QGraphicsItem::mouseReleaseEvent(event);
722   setZValue(zValue()-100);
723 }
724
725 void ConnectionItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
726   QGraphicsItem::mouseMoveEvent(event);
727 }
728
729 void ConnectionItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
730   /* have to check if the connection can be removed.
731      If the from or to InterfaceItem is owned by a group item, and this item
732      is both connected to and from, thus it is impossible to remove this connection
733    */
734   bool canRemove = true;
735   InterfaceItem* groupIfaceItem = NULL;
736   if (fromInterfaceItem->getOwner()->isGroupItem()) {
737     groupIfaceItem = fromInterfaceItem;
738   }
739   else if (toInterfaceItem->getOwner()->isGroupItem()) {
740     groupIfaceItem = toInterfaceItem;
741   }
742
743   if (groupIfaceItem != NULL) {
744     ConnectedInterface* ref = groupIfaceItem->refInter;
745     if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
746       canRemove = false;
747     }
748   }
749
750   if (canRemove) {
751     QMenu menu;
752     QAction* titleAction = menu.addAction("Connection operations");
753     titleAction->setEnabled(false);
754     menu.addSeparator();
755     QAction* removeAction = menu.addAction("Remove");
756     QAction * selectedAction= menu.exec(event->screenPos());
757
758     if(selectedAction == removeAction){
759       dispatcher->removeConnection(this);
760     }
761   }
762 }
763
764 void ConnectionItem::prepareChange() {
765   prepareGeometryChange();
766 }
767
768 QDataStream &operator <<(QDataStream &out, ConnectionItem &c) {
769   out.setVersion(QDataStream::Qt_4_8);
770
771   QByteArray connData;
772   QDataStream toWrite(&connData, QIODevice::WriteOnly);
773
774   toWrite << c.id;
775   toWrite << c.getFromInterfaceItem()->getId();
776   toWrite << c.getToInterfaceItem()->getId();
777
778   out << connData;
779
780   return out;
781 }
782
783 QDataStream &operator >>(QDataStream &in, ConnectionItem &c) {
784   in.setVersion(QDataStream::Qt_4_8);
785
786   return in;
787 }