Salome HOME
6ab2ca46fdde2352f45c441065d3f6dbdffce0ea
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_Link.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : SUPERVGUI_Link.cxx
8 //  Author : Vitaly SMETANNIKOV
9 //  Module : SUPERV
10
11 using namespace std;
12 #include "SUPERVGUI_Graph.h"
13 #include "SUPERVGUI_Main.h"
14 #include "SUPERVGUI_Link.h"
15
16
17
18 #define SKETCH_CLR Qt::green
19 #define DRAW_CLR Qt::black
20 #define HLT_CLR Qt::magenta
21 #define CTRL_CLR Qt::red
22
23 #define LINE_WIDTH 2
24 #define PNT_SIZE 6
25
26
27 // Prevents moving of several links at once
28 bool SUPERVGUI_Link::LinkIsMoving=false;
29
30 bool SUPERVGUI_Link::OrthoMode = false;
31
32 SUPERVGUI_Link* SUPERVGUI_Link::SelectedLink=0;
33
34 /**
35  * Consructor:
36  * If link is NULL - this must be defined later
37  */
38 SUPERVGUI_Link::SUPERVGUI_Link(SUPERVGUI_Graph* theGraph, SUPERV_Link theLink) {
39   myGraph = theGraph;
40   myEngine = theLink;
41   myPortIn = 0;
42   myPortInES = 0;
43   myPortOut = 0;
44   myStartPort = 0;
45   myHltPnt = -1;
46   myPntMovingState = false;
47   myPainter = 0;
48   myIsVisible = true;
49   myTmpPen.setColor(SKETCH_CLR);
50   myTmpPen.setWidth(LINE_WIDTH);
51   myIsSelected = false;
52   myTmpPoints.clear();
53
54   if (!SUPERV_isNull(myEngine))
55     connectToEvents();
56 }
57
58
59 //**********************************************************************
60 SUPERVGUI_Link::~SUPERVGUI_Link() {
61   if (!SUPERV_isNull(myEngine)) {
62     disconnect(myGraph, 0, this, 0);
63   }
64   if (SelectedLink == this) SelectedLink=0;
65   emit linkDeleted(this);
66 }
67
68
69 //**********************************************************************
70 void SUPERVGUI_Link::setInputPort(SUPERVGUI_PortIn* thePortIn) {
71   myPortIn = thePortIn;
72   myPortIn->setLinkPrs(this);
73 }
74
75
76 //**********************************************************************
77 void SUPERVGUI_Link::setInputPortES(SUPERVGUI_PortInESNode* thePortInES) {
78   myPortInES = thePortInES;
79   myPortInES->setLinkPrs(this);
80 }
81
82 //**********************************************************************
83 bool SUPERVGUI_Link::isESInputPort() {
84   if (myPortInES)
85     return true;
86   else
87     return false;
88 }
89
90 //**********************************************************************
91 void SUPERVGUI_Link::destroyEngine() {
92   if (!SUPERV_isNull(myEngine)) {
93     myEngine->destroy();
94   }
95 }
96
97 //**********************************************************************
98 void SUPERVGUI_Link::setOutputPort(SUPERVGUI_PortOut* thePortOut){
99   myPortOut = thePortOut;
100   myPortOut->addLinkPrs(this);
101 }
102
103
104 //**********************************************************************
105 void SUPERVGUI_Link::addPoint(long theX, long theY) {
106   if (SUPERV_isNull(myEngine)) return;
107
108   if (myEngine->CoordsSize() <= 0) {
109     myEngine->AddCoord(1, theX, theY);
110     return;
111   } else {
112     QPoint aPnt(theX, theY);
113     long aX, aY;
114     myEngine->Coords(1, aX, aY);
115     if (!isESInputPort()) {
116       if (distance(aPnt, myGraph->viewportToContents(myPortIn->getConnectPnt()), 
117                    QPoint(aX, aY)) <= 0) {
118         myEngine->AddCoord(1, theX, theY);
119         return;
120       }
121     }
122     else {
123       if (distance(aPnt, myGraph->viewportToContents(myPortInES->getConnectPnt()), 
124                    QPoint(aX, aY)) <= 0) {
125         myEngine->AddCoord(1, theX, theY);
126         return;
127       }
128     }
129
130     int i = 2;
131     long aNextX, aNextY;
132     for (i = 2; i <= myEngine->CoordsSize(); i++) {
133       myEngine->Coords(i, aNextX, aNextY);    
134       if (distance(aPnt,  QPoint(aX, aY), 
135                    QPoint(aNextX, aNextY)) <= 0) {
136         myEngine->AddCoord(i, theX, theY);
137         return;
138       }
139       aX = aNextX;
140       aY = aNextY;
141     }
142     if (distance(aPnt, QPoint(aX, aY), 
143                 myGraph->viewportToContents(myPortOut->getConnectPnt())) <= 0) {
144       myEngine->AddCoord(myEngine->CoordsSize()+1, theX, theY);
145       return;
146     }
147   }
148   repaint();
149 }
150
151
152 //**********************************************************************
153 /**
154  * Can be used only in Sketching mode
155  */
156 void SUPERVGUI_Link::addTmpPoint(QPoint thePnt) { 
157   if (OrthoMode) {
158     int aSize = myTmpPoints.size();
159     QPoint aPrevPnt;
160     // Previous point
161     if (aSize > 0)
162       aPrevPnt = myTmpPoints[aSize-1];
163     else
164       aPrevPnt = myStartPort->getConnectPnt();
165
166     // Next point
167     QPoint aNewPoint;
168     if (Abs(thePnt.x() - aPrevPnt.x()) >
169         Abs(thePnt.y() - aPrevPnt.y())) {
170       aNewPoint = QPoint(thePnt.x(), aPrevPnt.y());
171     } else {
172       aNewPoint = QPoint(aPrevPnt.x(), thePnt.y());
173     }
174     // repaint last line
175    
176     myPainter->drawLine(aPrevPnt, thePnt);
177     myPainter->moveTo(aPrevPnt);
178     myPainter->lineTo(aNewPoint);
179     myPainter->lineTo(thePnt);
180     
181     myTmpPoints.push_back(aNewPoint);
182   } else 
183     myTmpPoints.push_back(thePnt); 
184 }
185
186
187 //**********************************************************************
188 /**
189  * Can be used only in Sketching mode
190  */
191 void SUPERVGUI_Link::delLastTmpPoint() { 
192   int aSize = myTmpPoints.size();
193   if (aSize > 0) {
194     QPoint aRemPnt = myTmpPoints[aSize-1];
195     
196     QPoint aLastPnt;
197     if (aSize > 1)
198       aLastPnt = myTmpPoints[aSize-2];
199     else
200       aLastPnt = myStartPort->getConnectPnt();
201
202     myPainter->moveTo(aLastPnt);
203     myPainter->lineTo(aRemPnt);
204     myPainter->lineTo(myPrevPoint);
205
206     myPainter->drawLine(aLastPnt, myPrevPoint);
207
208     myTmpPoints.pop_back();
209   }
210 }
211
212
213 //**********************************************************************
214 void SUPERVGUI_Link::removeLastPoint() {
215   if (myEngine && (!SUPERV_isNull(myEngine)))
216     myEngine->RemoveCoord(myEngine->CoordsSize());
217 }
218
219
220 //**********************************************************************
221 void SUPERVGUI_Link::removePoint(int thePnt) {
222   if ((thePnt > -1) && (!SUPERV_isNull(myEngine))) {
223     paint(true);
224     myEngine->RemoveCoord(thePnt);
225     paint(false);
226   }
227 }
228
229 //**********************************************************************
230 /**
231  * Repaints the link
232  */
233 void SUPERVGUI_Link::repaint() {
234   paint(true);
235   paint(false);
236 }
237
238
239 //**********************************************************************
240 /**
241  * Paints or erases the link
242  * if toErase = true then it draws link by background color
243  */
244 void SUPERVGUI_Link::paint(bool toErase) {
245   if ((!myGraph) || (!myIsVisible)) return;
246   if (!myEngine && SUPERV_isNull(myEngine)) return;
247   //  if (!isCreationComplete()) return;
248
249   QPainter aPainter(myGraph->viewport());
250   QPen aDataPen;
251   aDataPen.setWidth(LINE_WIDTH);
252
253   if (toErase) {
254     aDataPen.setColor(myGraph->viewport()->paletteBackgroundColor());
255   } else {
256     if ((strcmp(myEngine->InPort()->Name(), "InVoid")==0) || 
257         (myEngine->InPort()->Kind() == SUPERV::DataStreamParameter ))
258       aDataPen.setColor(CTRL_CLR);
259     else
260       aDataPen.setColor(DRAW_CLR);
261   }
262   aPainter.setPen(aDataPen);
263   drawLink(&aPainter);
264 }
265
266
267 //**********************************************************************
268 /**
269  * Defines a pen and draws link using given painter
270  */
271 void SUPERVGUI_Link::paint(QPainter* thePainter, bool toErase) {
272   if ((!myGraph) || (!myIsVisible)) return;
273   if (!myEngine && SUPERV_isNull(myEngine)) return;
274   //  if (!isCreationComplete()) return;
275   thePainter->save();
276
277   QPen aDataPen;
278   aDataPen.setWidth(LINE_WIDTH);
279
280   if (toErase) {
281     aDataPen.setColor(myGraph->viewport()->paletteBackgroundColor());
282   } else {
283     if ((strcmp(myEngine->InPort()->Name(), "InVoid")==0)|| 
284         (myEngine->InPort()->Kind() == SUPERV::DataStreamParameter ))
285       aDataPen.setColor(CTRL_CLR);
286     else
287       aDataPen.setColor(DRAW_CLR);
288   }
289   thePainter->setPen(aDataPen);
290   drawLink(thePainter);
291   thePainter->restore();
292 }
293
294
295 //**********************************************************************
296 /**
297  * Draws link using given painter
298  */
299 void SUPERVGUI_Link::drawLink(QPainter* thePainter) {
300   if (!myIsVisible) return;
301   if (!isESInputPort())
302     thePainter->moveTo(myPortIn->getConnectPnt());
303   else
304     thePainter->moveTo(myPortInES->getConnectPnt());    
305   long aX, aY;
306   QPoint aPnt;
307   for (int i=0; i < myEngine->CoordsSize(); i++) {
308     myEngine->Coords(i+1, aX, aY);
309     aPnt = myGraph->contentsToViewport(QPoint(aX, aY));
310     thePainter->lineTo(aPnt);
311     thePainter->drawEllipse(aPnt.x()-PNT_SIZE/2, aPnt.y()-PNT_SIZE/2, 
312                             PNT_SIZE, PNT_SIZE);
313   }
314   thePainter->lineTo(myPortOut->getConnectPnt());
315 }
316
317
318 //**********************************************************************
319 /**
320  * Repaints whole link when it is sketching
321  */
322 void SUPERVGUI_Link::repaintSketch() {
323   if (!myStartPort) return;
324   if (!myPainter) return;
325
326   //  myPainter->save();
327   //myPainter->setRasterOp(Qt::CopyROP);
328   myPainter->moveTo(myStartPort->getConnectPnt());
329   for (int i = 0; i< myTmpPoints.size(); i++) {
330     myPainter->lineTo(myGraph->contentsToViewport(myTmpPoints[i]));
331   }
332   myPainter->lineTo(myPrevPoint);
333   //myPainter->restore();
334 }
335
336
337 //**********************************************************************
338 /**
339  * Drawing of non created link following to mouse pointer
340  */
341 void SUPERVGUI_Link::drawTo(QPoint thePnt) {
342   if (!myStartPort) {
343     if (myPortIn)
344       myStartPort = myPortIn;
345     else if (myPortInES)
346       myStartPort = myPortInES;
347     else if (myPortOut)
348       myStartPort = myPortOut;
349     else
350       return;
351   }
352   if (!myPainter) {
353     myPainter = new QPainter(myGraph->viewport());
354     myPainter->setPen(myTmpPen);
355     myPainter->setRasterOp(Qt::XorROP);
356     myPrevPoint = myStartPort->getConnectPnt();
357     LinkIsMoving = true;
358   }
359
360   long aX, aY;
361
362   QPoint aStartPnt;
363   if (myTmpPoints.size() > 0) 
364     aStartPnt = myGraph->contentsToViewport(myTmpPoints[myTmpPoints.size()-1]);
365   else
366     aStartPnt = myStartPort->getConnectPnt();
367
368   // erase old line
369   myPainter->drawLine(aStartPnt, myPrevPoint);
370
371   // draw new line
372   QPoint aNewPoint = myGraph->contentsToViewport(thePnt);
373   myPainter->drawLine(aStartPnt, aNewPoint);
374   myPrevPoint = aNewPoint;
375
376 }
377
378
379 //**********************************************************************
380 /**
381  * Set link non visible
382  */
383 void SUPERVGUI_Link::setVisible(bool theVisible) {
384   myIsVisible = theVisible;
385   if (myIsVisible) {
386     connectToEvents();
387   } else {
388     disconnect(myGraph, 0, this, 0);
389   }
390 }
391
392
393 //**********************************************************************
394 /**
395  * Checks full definition of the link
396  */
397 bool SUPERVGUI_Link::isCreationComplete() {
398   bool aIsBoth = myPortIn && myPortOut;
399   if (myPortIn && myPortOut) {
400     SUPERV_Port aInPort = myPortIn->getPort();
401     QString aInNodeName(aInPort->Node()->Name());
402     SUPERV_Port aOutPort = myPortOut->getPort();
403     QString aOutNodeName(aOutPort->Node()->Name());
404     
405     return (aInNodeName != aOutNodeName);
406   }
407   else if (myPortInES && myPortOut) {
408     SUPERV_Port aInPortES = myPortInES->getPort();
409     QString aInNodeName(aInPortES->Node()->Name());
410     SUPERV_Port aOutPort = myPortOut->getPort();
411     QString aOutNodeName(aOutPort->Node()->Name());
412     
413     return (aInNodeName != aOutNodeName);
414   }
415   else 
416     return false;
417 }
418
419 //**********************************************************************
420 /** 
421  * Abort creation of link
422  */
423 void SUPERVGUI_Link::abortCreation() {
424   LinkIsMoving = false;
425 }
426
427 //**********************************************************************
428 /** 
429  * Final procedure of link creation
430  */
431 bool SUPERVGUI_Link::createEngine() {
432   // clear temporary drawing
433   QPen aOldPen(myGraph->viewport()->paletteBackgroundColor(), LINE_WIDTH);
434   //check if myPainter not null
435   if (myPainter) {
436     myPainter->setPen(aOldPen);
437     myPainter->setRasterOp(Qt::CopyROP);
438     
439     QPoint aStartPnt;
440     if (myTmpPoints.size() > 0) 
441       aStartPnt = myGraph->contentsToViewport(myTmpPoints[myTmpPoints.size()-1]);
442     else
443       aStartPnt = myStartPort->getConnectPnt();
444     
445     myPainter->drawLine(aStartPnt, myPrevPoint);
446
447     delete myPainter;
448     myPainter = 0;
449   }
450     
451   // Create engine
452   if (!isESInputPort())
453     myEngine = myGraph->getMain()->getDataflow()->
454       Link(myPortOut->getPort(), myPortIn->getPort());
455   else
456     myEngine = myGraph->getMain()->getDataflow()->
457       Link(myPortOut->getPort(), myPortInES->getPort());
458
459   if (SUPERV_isNull(myEngine)) return false;
460
461   // remember all points
462   QPoint aPnt;
463   if (myStartPort == myPortOut) {
464     int aSize = myTmpPoints.size();
465     for (int i = aSize; i > 0; i--) {
466       aPnt = myTmpPoints[i-1];
467       myEngine->AddCoord(aSize+1-i, aPnt.x(), aPnt.y());
468     }
469   } else {
470     for (int i = 0; i < myTmpPoints.size(); i++) {
471       aPnt = myTmpPoints[i];
472       myEngine->AddCoord(i+1, aPnt.x(), aPnt.y());
473     }
474   }
475   LinkIsMoving = false;
476
477   // empty temporary resources
478   myTmpPoints.clear();
479   myStartPort = 0;
480   connectToEvents();
481   paint(false);
482   return true;
483 }
484
485
486
487 //**********************************************************************
488 void SUPERVGUI_Link::onMouseMove(QMouseEvent * theEvent) {
489   if (myPntMovingState) {
490     drawSegments();
491
492     QPoint aPos = myGraph->contentsToViewport(theEvent->pos());
493     int aX = (aPos.x() > 0)? aPos.x(): 1;
494     int aY = (aPos.y() > 0)? aPos.y(): 1;
495     aX = (aX < myGraph->contentsWidth())? aX: myGraph->contentsWidth()-1;
496     aY = (aY < myGraph->contentsHeight())? aY: myGraph->contentsHeight()-1;
497
498     myMovedPnt = QPoint(aX, aY);
499     drawSegments();
500     return;
501   }
502
503   if (LinkIsMoving) return;
504
505   // Points highlighting
506   QPoint aPos = theEvent->pos();
507   if (myEngine->CoordsSize() > 0 ) {
508     long aX, aY;
509     bool aIsFound = false;
510     for (int i=0; i < myEngine->CoordsSize(); i++) {
511       myEngine->Coords(i+1, aX, aY);
512       if (distance(aX, aY, 
513                    aPos.x(), 
514                    aPos.y()) < (PNT_SIZE+2)) {
515         myHltPnt = i+1;
516         aIsFound = true;
517         break;
518       }
519     }
520     if (!aIsFound) myHltPnt = -1;
521   }
522
523   // Highlight line
524   if (isSelected(aPos)) {
525     if (SelectedLink==0) {
526       QPen aNewPen(HLT_CLR, LINE_WIDTH);
527       QPainter aPainter(myGraph->viewport());
528       aPainter.setPen(aNewPen);
529       drawLink(&aPainter);
530       myIsSelected = true;
531       SelectedLink = this;
532     }
533   } else if (myIsSelected) {
534     myIsSelected = false;
535     if (SelectedLink == this) SelectedLink = 0;
536     paint(false);
537   }
538 }
539
540
541 //**********************************************************************
542 /**
543  * For internal using only
544  * Draws segments by current Pen when point is moving
545  */
546 void SUPERVGUI_Link::drawSegments() {
547   myPainter->drawLine(myBeforePnt, myMovedPnt);
548   myPainter->drawLine(myMovedPnt, myAfterPnt);
549   myPainter->drawEllipse(myMovedPnt.x()-PNT_SIZE/2, 
550                          myMovedPnt.y()-PNT_SIZE/2, 
551                          PNT_SIZE, PNT_SIZE);
552 }
553
554
555 //**********************************************************************
556 void SUPERVGUI_Link::onMousePress(QMouseEvent * theEvent) {
557   if (LinkIsMoving) {
558     return;
559   }
560   if (theEvent->button() != Qt::LeftButton) {
561     myHltPnt = -1;
562     return;
563   }
564   if (myHltPnt > -1) { // start point moving
565     if (myHltPnt == 1) {
566       if (!isESInputPort()) {
567         myBeforePnt = myPortIn->getConnectPnt();
568       }
569       else {
570         myBeforePnt = myPortInES->getConnectPnt();      
571       }
572     }
573     else {
574       long aX, aY;
575       myEngine->Coords(myHltPnt-1, aX, aY);
576       myBeforePnt = myGraph->contentsToViewport(QPoint(aX, aY));
577     }
578     if (myHltPnt == myEngine->CoordsSize()) 
579       myAfterPnt = myPortOut->getConnectPnt();
580     else {
581       long aX, aY;
582       myEngine->Coords(myHltPnt+1, aX, aY);
583       myAfterPnt = myGraph->contentsToViewport(QPoint(aX, aY));
584     }
585     long aX, aY;
586     myEngine->Coords(myHltPnt, aX, aY);
587     myMovedPnt = myGraph->contentsToViewport(QPoint(aX, aY));
588
589     myPainter = new QPainter(myGraph->viewport());
590     QPen aOldPen(myGraph->viewport()->paletteBackgroundColor(), LINE_WIDTH);
591
592     myPainter->setPen(aOldPen); 
593     drawSegments();
594
595     myPainter->setPen(myTmpPen);
596     myPainter->setRasterOp(Qt::XorROP);
597     drawSegments();
598
599     myPntMovingState = true;
600     LinkIsMoving = true;
601   } else if (myHltPnt > -1)
602     paint(false);
603 }
604
605 //**********************************************************************
606 void SUPERVGUI_Link::onMouseRelease(QMouseEvent * theEvent){
607   if (theEvent->button() != Qt::LeftButton) return;
608
609   if (myPntMovingState) {
610     myPntMovingState = false;
611     LinkIsMoving = false;
612     drawSegments();
613     delete myPainter;
614     myPainter = 0;
615
616     int aX = (theEvent->pos().x() > 0)? theEvent->pos().x(): 1;
617     int aY = (theEvent->pos().y() > 0)? theEvent->pos().y(): 1;
618     aX = (aX < myGraph->contentsWidth())? aX: myGraph->contentsWidth()-1;
619     aY = (aY < myGraph->contentsHeight())? aY: myGraph->contentsHeight()-1;
620     myEngine->ChangeCoord(myHltPnt, aX, aY);
621
622     paint(false);
623   }  
624 }
625
626 //**********************************************************************
627 /**
628  * Connects to the Graph mouse events
629  */
630 void SUPERVGUI_Link::connectToEvents() {
631   connect(myGraph, SIGNAL(mouseMoved(QMouseEvent*)),
632           this, SLOT(onMouseMove(QMouseEvent*)));
633
634   connect(myGraph, SIGNAL(mousePressed(QMouseEvent*)),
635           this, SLOT(onMousePress(QMouseEvent*)));
636
637   connect(myGraph, SIGNAL(mouseReleased(QMouseEvent*)),
638           this, SLOT(onMouseRelease(QMouseEvent*)));
639 }
640
641
642 //**********************************************************************
643 bool SUPERVGUI_Link::isSelected(QPoint thePnt) {
644   if (myEngine->CoordsSize() == 0) {
645     if (!isESInputPort()) {
646       return (distance(thePnt,  myGraph->viewportToContents(myPortOut->getConnectPnt()), 
647                        myGraph->viewportToContents(myPortIn->getConnectPnt())) <= 0); 
648     }
649     else {
650       return (distance(thePnt,  myGraph->viewportToContents(myPortOut->getConnectPnt()), 
651                        myGraph->viewportToContents(myPortInES->getConnectPnt())) <= 0); 
652     }
653   }
654   else {
655     long aX, aY;
656     myEngine->Coords(1, aX, aY);    
657     if (!isESInputPort()) { 
658       if (distance(thePnt, myGraph->viewportToContents(myPortIn->getConnectPnt()), 
659                    QPoint(aX, aY)) <= 0) {
660         return true;
661       }
662     }
663     else {
664       if (distance(thePnt, myGraph->viewportToContents(myPortInES->getConnectPnt()), 
665                    QPoint(aX, aY)) <= 0) {
666         return true;
667       }
668     }
669         
670     int i = 2;
671     long aNextX, aNextY;
672     for (i = 2; i <= myEngine->CoordsSize(); i++) {
673       myEngine->Coords(i, aNextX, aNextY);    
674       if (distance(thePnt,  QPoint(aX, aY), 
675                    QPoint(aNextX, aNextY)) <= 0) {
676         return true;
677       }
678       aX = aNextX;
679       aY = aNextY;
680     }
681     if (distance(thePnt, QPoint(aX, aY), 
682                  myGraph->viewportToContents(myPortOut->getConnectPnt())) <= 0) {
683       return true;
684     }
685   }
686   return false;
687 }
688
689
690 //**********************************************************************
691 /**
692  * Returns true if at least one point is within the rect.
693  * Rect must be in contents coordinate space
694  */
695 bool SUPERVGUI_Link::isInRect(int theX, int theY, int theW, int theH) {
696   QRect aRect(theX, theY, theW, theH);
697   if (aRect.contains(myGraph->viewportToContents(myPortOut->getConnectPnt()), true))
698     return true;
699
700   if (!isESInputPort()) {
701     if (aRect.contains(myGraph->viewportToContents(myPortIn->getConnectPnt()), true)) {
702       return true;
703     }
704   }
705   else {
706     if (aRect.contains(myGraph->viewportToContents(myPortInES->getConnectPnt()), true)) {
707       return true;
708     }
709   }
710   
711   long aX, aY;
712   QPoint aPrevPnt;
713   if (!isESInputPort())
714     aPrevPnt = myGraph->viewportToContents(myPortIn->getConnectPnt());
715   else
716     aPrevPnt = myGraph->viewportToContents(myPortInES->getConnectPnt());    
717   for (int i = 1; i <= myEngine->CoordsSize(); i++) {
718     myEngine->Coords(i, aX, aY);   
719     if (aRect.contains(aX, aY, true))
720       return true;
721     else {
722       QRect aTmpRect(QPoint(QMIN(aPrevPnt.x(), aX), 
723                             QMIN(aPrevPnt.y(), aY)),
724                      QPoint(QMAX(aPrevPnt.x(), aX),
725                             QMAX(aPrevPnt.y(), aY)));
726       if (aRect.intersects(aTmpRect))
727         return true;
728       aPrevPnt = QPoint(aX, aY);
729     }
730   }
731   QPoint aLastPnt = myGraph->viewportToContents(myPortOut->getConnectPnt());
732   QRect aLastRect(QPoint(QMIN(aPrevPnt.x(), aLastPnt.x()), 
733                          QMIN(aPrevPnt.y(), aLastPnt.y())),
734                   QPoint(QMAX(aPrevPnt.x(), aLastPnt.x()),
735                          QMAX(aPrevPnt.y(), aLastPnt.y())));
736   if (aRect.intersects(aLastRect))
737     return true;
738
739   return false;
740 }
741
742
743 //**********************************************************************
744 /**
745  * Calculates distance between points
746  */
747 int distance(int x1, int y1, int x2, int y2) {
748   int x = x2 - x1;
749   x = x * x;
750   int y = y2 - y1;
751   y = y * y;
752   return (int) sqrt((double)(x + y));
753 }
754
755
756 //**********************************************************************
757 /**
758  * Finds distance between thePnt and line(thePntLn1, thePntLn2)
759  * Returned value is not an mathematical value - this is only estimation of
760  * of closing point to the line. 0 - means that point belongs to the line
761  */
762 int distance(QPoint thePnt, QPoint thePntLn1, QPoint thePntLn2) {
763   int r, s;
764   int a, b, c;
765   
766   int px = thePnt.x();
767   int py = thePnt.y();
768   int lx = thePntLn1.x();
769   int ly = thePntLn1.y();
770   int nx = thePntLn2.x();
771   int ny = thePntLn2.y();
772   
773   r = px - lx;
774   r = r * r;
775   s = py - ly;
776   s = s * s;
777   a = (int) sqrt((double)(r + s));
778
779   r = px - nx;
780   r = r * r;
781   s = py - ny;
782   s = s * s;
783   b = (int) sqrt((double)(r + s));
784   
785   r = nx - lx;
786   r = r * r;
787   s = ny - ly;
788   s = s * s;
789   c = (int) sqrt((double)(r + s));
790
791   return (a+b-c);
792 }
793
794 void SUPERVGUI_Link::setBeginPort(SUPERVGUI_Port* theBeginPort) {
795   myBeginPort = theBeginPort;
796 }
797
798 SUPERVGUI_Port* SUPERVGUI_Link::getBeginPort() {
799   return myBeginPort;
800 }
801
802