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

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