Salome HOME
MPV: Merge V1_2d
[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       aDataPen.setColor(CTRL_CLR);
258     else
259       aDataPen.setColor(DRAW_CLR);
260   }
261   aPainter.setPen(aDataPen);
262   drawLink(&aPainter);
263 }
264
265
266 //**********************************************************************
267 /**
268  * Defines a pen and draws link using given painter
269  */
270 void SUPERVGUI_Link::paint(QPainter* thePainter, bool toErase) {
271   if ((!myGraph) || (!myIsVisible)) return;
272   if (!myEngine && SUPERV_isNull(myEngine)) return;
273   //  if (!isCreationComplete()) return;
274   thePainter->save();
275
276   QPen aDataPen;
277   aDataPen.setWidth(LINE_WIDTH);
278
279   if (toErase) {
280     aDataPen.setColor(myGraph->viewport()->paletteBackgroundColor());
281   } else {
282     if (strcmp(myEngine->InPort()->Name(), "InVoid")==0)
283       aDataPen.setColor(CTRL_CLR);
284     else
285       aDataPen.setColor(DRAW_CLR);
286   }
287   thePainter->setPen(aDataPen);
288   drawLink(thePainter);
289   thePainter->restore();
290 }
291
292
293 //**********************************************************************
294 /**
295  * Draws link using given painter
296  */
297 void SUPERVGUI_Link::drawLink(QPainter* thePainter) {
298   if (!myIsVisible) return;
299   if (!isESInputPort())
300     thePainter->moveTo(myPortIn->getConnectPnt());
301   else
302     thePainter->moveTo(myPortInES->getConnectPnt());    
303   long aX, aY;
304   QPoint aPnt;
305   for (int i=0; i < myEngine->CoordsSize(); i++) {
306     myEngine->Coords(i+1, aX, aY);
307     aPnt = myGraph->contentsToViewport(QPoint(aX, aY));
308     thePainter->lineTo(aPnt);
309     thePainter->drawEllipse(aPnt.x()-PNT_SIZE/2, aPnt.y()-PNT_SIZE/2, 
310                             PNT_SIZE, PNT_SIZE);
311   }
312   thePainter->lineTo(myPortOut->getConnectPnt());
313 }
314
315
316 //**********************************************************************
317 /**
318  * Repaints whole link when it is sketching
319  */
320 void SUPERVGUI_Link::repaintSketch() {
321   if (!myStartPort) return;
322   if (!myPainter) return;
323
324   //  myPainter->save();
325   //myPainter->setRasterOp(Qt::CopyROP);
326   myPainter->moveTo(myStartPort->getConnectPnt());
327   for (int i = 0; i< myTmpPoints.size(); i++) {
328     myPainter->lineTo(myGraph->contentsToViewport(myTmpPoints[i]));
329   }
330   myPainter->lineTo(myPrevPoint);
331   //myPainter->restore();
332 }
333
334
335 //**********************************************************************
336 /**
337  * Drawing of non created link following to mouse pointer
338  */
339 void SUPERVGUI_Link::drawTo(QPoint thePnt) {
340   if (!myStartPort) {
341     if (myPortIn)
342       myStartPort = myPortIn;
343     else if (myPortInES)
344       myStartPort = myPortInES;
345     else if (myPortOut)
346       myStartPort = myPortOut;
347     else
348       return;
349   }
350   if (!myPainter) {
351     myPainter = new QPainter(myGraph->viewport());
352     myPainter->setPen(myTmpPen);
353     myPainter->setRasterOp(Qt::XorROP);
354     myPrevPoint = myStartPort->getConnectPnt();
355     LinkIsMoving = true;
356   }
357
358   long aX, aY;
359
360   QPoint aStartPnt;
361   if (myTmpPoints.size() > 0) 
362     aStartPnt = myGraph->contentsToViewport(myTmpPoints[myTmpPoints.size()-1]);
363   else
364     aStartPnt = myStartPort->getConnectPnt();
365
366   // erase old line
367   myPainter->drawLine(aStartPnt, myPrevPoint);
368
369   // draw new line
370   QPoint aNewPoint = myGraph->contentsToViewport(thePnt);
371   myPainter->drawLine(aStartPnt, aNewPoint);
372   myPrevPoint = aNewPoint;
373
374 }
375
376
377 //**********************************************************************
378 /**
379  * Set link non visible
380  */
381 void SUPERVGUI_Link::setVisible(bool theVisible) {
382   myIsVisible = theVisible;
383   if (myIsVisible) {
384     connectToEvents();
385   } else {
386     disconnect(myGraph, 0, this, 0);
387   }
388 }
389
390
391 //**********************************************************************
392 /**
393  * Checks full definition of the link
394  */
395 bool SUPERVGUI_Link::isCreationComplete() {
396   bool aIsBoth = myPortIn && myPortOut;
397   if (myPortIn && myPortOut) {
398     SUPERV_Port aInPort = myPortIn->getPort();
399     QString aInNodeName(aInPort->Node()->Name());
400     SUPERV_Port aOutPort = myPortOut->getPort();
401     QString aOutNodeName(aOutPort->Node()->Name());
402     
403     return (aInNodeName != aOutNodeName);
404   }
405   else if (myPortInES && myPortOut) {
406     SUPERV_Port aInPortES = myPortInES->getPort();
407     QString aInNodeName(aInPortES->Node()->Name());
408     SUPERV_Port aOutPort = myPortOut->getPort();
409     QString aOutNodeName(aOutPort->Node()->Name());
410     
411     return (aInNodeName != aOutNodeName);
412   }
413   else 
414     return false;
415 }
416
417 //**********************************************************************
418 /** 
419  * Abort creation of link
420  */
421 void SUPERVGUI_Link::abortCreation() {
422   LinkIsMoving = false;
423 }
424
425 //**********************************************************************
426 /** 
427  * Final procedure of link creation
428  */
429 bool SUPERVGUI_Link::createEngine() {
430   // clear temporary drawing
431   QPen aOldPen(myGraph->viewport()->paletteBackgroundColor(), LINE_WIDTH);
432   //check if myPainter not null
433   if (myPainter) {
434     myPainter->setPen(aOldPen);
435     myPainter->setRasterOp(Qt::CopyROP);
436     
437     QPoint aStartPnt;
438     if (myTmpPoints.size() > 0) 
439       aStartPnt = myGraph->contentsToViewport(myTmpPoints[myTmpPoints.size()-1]);
440     else
441       aStartPnt = myStartPort->getConnectPnt();
442     
443     myPainter->drawLine(aStartPnt, myPrevPoint);
444
445     delete myPainter;
446     myPainter = 0;
447   }
448     
449   // Create engine
450   if (!isESInputPort())
451     myEngine = myGraph->getMain()->getDataflow()->
452       Link(myPortOut->getPort(), myPortIn->getPort());
453   else
454     myEngine = myGraph->getMain()->getDataflow()->
455       Link(myPortOut->getPort(), myPortInES->getPort());
456
457   if (SUPERV_isNull(myEngine)) return false;
458
459   // remember all points
460   QPoint aPnt;
461   if (myStartPort == myPortOut) {
462     int aSize = myTmpPoints.size();
463     for (int i = aSize; i > 0; i--) {
464       aPnt = myTmpPoints[i-1];
465       myEngine->AddCoord(aSize+1-i, aPnt.x(), aPnt.y());
466     }
467   } else {
468     for (int i = 0; i < myTmpPoints.size(); i++) {
469       aPnt = myTmpPoints[i];
470       myEngine->AddCoord(i+1, aPnt.x(), aPnt.y());
471     }
472   }
473   LinkIsMoving = false;
474
475   // empty temporary resources
476   myTmpPoints.clear();
477   myStartPort = 0;
478   connectToEvents();
479   paint(false);
480   return true;
481 }
482
483
484
485 //**********************************************************************
486 void SUPERVGUI_Link::onMouseMove(QMouseEvent * theEvent) {
487   if (myPntMovingState) {
488     drawSegments();
489
490     QPoint aPos = myGraph->contentsToViewport(theEvent->pos());
491     int aX = (aPos.x() > 0)? aPos.x(): 1;
492     int aY = (aPos.y() > 0)? aPos.y(): 1;
493     aX = (aX < myGraph->contentsWidth())? aX: myGraph->contentsWidth()-1;
494     aY = (aY < myGraph->contentsHeight())? aY: myGraph->contentsHeight()-1;
495
496     myMovedPnt = QPoint(aX, aY);
497     drawSegments();
498     return;
499   }
500
501   if (LinkIsMoving) return;
502
503   // Points highlighting
504   QPoint aPos = theEvent->pos();
505   if (myEngine->CoordsSize() > 0 ) {
506     long aX, aY;
507     bool aIsFound = false;
508     for (int i=0; i < myEngine->CoordsSize(); i++) {
509       myEngine->Coords(i+1, aX, aY);
510       if (distance(aX, aY, 
511                    aPos.x(), 
512                    aPos.y()) < (PNT_SIZE+2)) {
513         myHltPnt = i+1;
514         aIsFound = true;
515         break;
516       }
517     }
518     if (!aIsFound) myHltPnt = -1;
519   }
520
521   // Highlight line
522   if (isSelected(aPos)) {
523     if (SelectedLink==0) {
524       QPen aNewPen(HLT_CLR, LINE_WIDTH);
525       QPainter aPainter(myGraph->viewport());
526       aPainter.setPen(aNewPen);
527       drawLink(&aPainter);
528       myIsSelected = true;
529       SelectedLink = this;
530     }
531   } else if (myIsSelected) {
532     myIsSelected = false;
533     if (SelectedLink == this) SelectedLink = 0;
534     paint(false);
535   }
536 }
537
538
539 //**********************************************************************
540 /**
541  * For internal using only
542  * Draws segments by current Pen when point is moving
543  */
544 void SUPERVGUI_Link::drawSegments() {
545   myPainter->drawLine(myBeforePnt, myMovedPnt);
546   myPainter->drawLine(myMovedPnt, myAfterPnt);
547   myPainter->drawEllipse(myMovedPnt.x()-PNT_SIZE/2, 
548                          myMovedPnt.y()-PNT_SIZE/2, 
549                          PNT_SIZE, PNT_SIZE);
550 }
551
552
553 //**********************************************************************
554 void SUPERVGUI_Link::onMousePress(QMouseEvent * theEvent) {
555   if (LinkIsMoving) {
556     return;
557   }
558   if (theEvent->button() != Qt::LeftButton) {
559     myHltPnt = -1;
560     return;
561   }
562   if (myHltPnt > -1) { // start point moving
563     if (myHltPnt == 1) {
564       if (!isESInputPort()) {
565         myBeforePnt = myPortIn->getConnectPnt();
566       }
567       else {
568         myBeforePnt = myPortInES->getConnectPnt();      
569       }
570     }
571     else {
572       long aX, aY;
573       myEngine->Coords(myHltPnt-1, aX, aY);
574       myBeforePnt = myGraph->contentsToViewport(QPoint(aX, aY));
575     }
576     if (myHltPnt == myEngine->CoordsSize()) 
577       myAfterPnt = myPortOut->getConnectPnt();
578     else {
579       long aX, aY;
580       myEngine->Coords(myHltPnt+1, aX, aY);
581       myAfterPnt = myGraph->contentsToViewport(QPoint(aX, aY));
582     }
583     long aX, aY;
584     myEngine->Coords(myHltPnt, aX, aY);
585     myMovedPnt = myGraph->contentsToViewport(QPoint(aX, aY));
586
587     myPainter = new QPainter(myGraph->viewport());
588     QPen aOldPen(myGraph->viewport()->paletteBackgroundColor(), LINE_WIDTH);
589
590     myPainter->setPen(aOldPen); 
591     drawSegments();
592
593     myPainter->setPen(myTmpPen);
594     myPainter->setRasterOp(Qt::XorROP);
595     drawSegments();
596
597     myPntMovingState = true;
598     LinkIsMoving = true;
599   } else if (myHltPnt > -1)
600     paint(false);
601 }
602
603 //**********************************************************************
604 void SUPERVGUI_Link::onMouseRelease(QMouseEvent * theEvent){
605   if (theEvent->button() != Qt::LeftButton) return;
606
607   if (myPntMovingState) {
608     myPntMovingState = false;
609     LinkIsMoving = false;
610     drawSegments();
611     delete myPainter;
612     myPainter = 0;
613
614     int aX = (theEvent->pos().x() > 0)? theEvent->pos().x(): 1;
615     int aY = (theEvent->pos().y() > 0)? theEvent->pos().y(): 1;
616     aX = (aX < myGraph->contentsWidth())? aX: myGraph->contentsWidth()-1;
617     aY = (aY < myGraph->contentsHeight())? aY: myGraph->contentsHeight()-1;
618     myEngine->ChangeCoord(myHltPnt, aX, aY);
619
620     paint(false);
621   }  
622 }
623
624 //**********************************************************************
625 /**
626  * Connects to the Graph mouse events
627  */
628 void SUPERVGUI_Link::connectToEvents() {
629   connect(myGraph, SIGNAL(mouseMoved(QMouseEvent*)),
630           this, SLOT(onMouseMove(QMouseEvent*)));
631
632   connect(myGraph, SIGNAL(mousePressed(QMouseEvent*)),
633           this, SLOT(onMousePress(QMouseEvent*)));
634
635   connect(myGraph, SIGNAL(mouseReleased(QMouseEvent*)),
636           this, SLOT(onMouseRelease(QMouseEvent*)));
637 }
638
639
640 //**********************************************************************
641 bool SUPERVGUI_Link::isSelected(QPoint thePnt) {
642   if (myEngine->CoordsSize() == 0) {
643     if (!isESInputPort()) {
644       return (distance(thePnt,  myGraph->viewportToContents(myPortOut->getConnectPnt()), 
645                        myGraph->viewportToContents(myPortIn->getConnectPnt())) <= 0); 
646     }
647     else {
648       return (distance(thePnt,  myGraph->viewportToContents(myPortOut->getConnectPnt()), 
649                        myGraph->viewportToContents(myPortInES->getConnectPnt())) <= 0); 
650     }
651   }
652   else {
653     long aX, aY;
654     myEngine->Coords(1, aX, aY);    
655     if (!isESInputPort()) { 
656       if (distance(thePnt, myGraph->viewportToContents(myPortIn->getConnectPnt()), 
657                    QPoint(aX, aY)) <= 0) {
658         return true;
659       }
660     }
661     else {
662       if (distance(thePnt, myGraph->viewportToContents(myPortInES->getConnectPnt()), 
663                    QPoint(aX, aY)) <= 0) {
664         return true;
665       }
666     }
667         
668     int i = 2;
669     long aNextX, aNextY;
670     for (i = 2; i <= myEngine->CoordsSize(); i++) {
671       myEngine->Coords(i, aNextX, aNextY);    
672       if (distance(thePnt,  QPoint(aX, aY), 
673                    QPoint(aNextX, aNextY)) <= 0) {
674         return true;
675       }
676       aX = aNextX;
677       aY = aNextY;
678     }
679     if (distance(thePnt, QPoint(aX, aY), 
680                  myGraph->viewportToContents(myPortOut->getConnectPnt())) <= 0) {
681       return true;
682     }
683   }
684   return false;
685 }
686
687
688 //**********************************************************************
689 /**
690  * Returns true if at least one point is within the rect.
691  * Rect must be in contents coordinate space
692  */
693 bool SUPERVGUI_Link::isInRect(int theX, int theY, int theW, int theH) {
694   QRect aRect(theX, theY, theW, theH);
695   if (aRect.contains(myGraph->viewportToContents(myPortOut->getConnectPnt()), true))
696     return true;
697
698   if (!isESInputPort()) {
699     if (aRect.contains(myGraph->viewportToContents(myPortIn->getConnectPnt()), true)) {
700       return true;
701     }
702   }
703   else {
704     if (aRect.contains(myGraph->viewportToContents(myPortInES->getConnectPnt()), true)) {
705       return true;
706     }
707   }
708   
709   long aX, aY;
710   QPoint aPrevPnt;
711   if (!isESInputPort())
712     aPrevPnt = myGraph->viewportToContents(myPortIn->getConnectPnt());
713   else
714     aPrevPnt = myGraph->viewportToContents(myPortInES->getConnectPnt());    
715   for (int i = 1; i <= myEngine->CoordsSize(); i++) {
716     myEngine->Coords(i, aX, aY);   
717     if (aRect.contains(aX, aY, true))
718       return true;
719     else {
720       QRect aTmpRect(QPoint(QMIN(aPrevPnt.x(), aX), 
721                             QMIN(aPrevPnt.y(), aY)),
722                      QPoint(QMAX(aPrevPnt.x(), aX),
723                             QMAX(aPrevPnt.y(), aY)));
724       if (aRect.intersects(aTmpRect))
725         return true;
726       aPrevPnt = QPoint(aX, aY);
727     }
728   }
729   QPoint aLastPnt = myGraph->viewportToContents(myPortOut->getConnectPnt());
730   QRect aLastRect(QPoint(QMIN(aPrevPnt.x(), aLastPnt.x()), 
731                          QMIN(aPrevPnt.y(), aLastPnt.y())),
732                   QPoint(QMAX(aPrevPnt.x(), aLastPnt.x()),
733                          QMAX(aPrevPnt.y(), aLastPnt.y())));
734   if (aRect.intersects(aLastRect))
735     return true;
736
737   return false;
738 }
739
740
741 //**********************************************************************
742 /**
743  * Calculates distance between points
744  */
745 int distance(int x1, int y1, int x2, int y2) {
746   int x = x2 - x1;
747   x = x * x;
748   int y = y2 - y1;
749   y = y * y;
750   return (int) sqrt((double)(x + y));
751 }
752
753
754 //**********************************************************************
755 /**
756  * Finds distance between thePnt and line(thePntLn1, thePntLn2)
757  * Returned value is not an mathematical value - this is only estimation of
758  * of closing point to the line. 0 - means that point belongs to the line
759  */
760 int distance(QPoint thePnt, QPoint thePntLn1, QPoint thePntLn2) {
761   int r, s;
762   int a, b, c;
763   
764   int px = thePnt.x();
765   int py = thePnt.y();
766   int lx = thePntLn1.x();
767   int ly = thePntLn1.y();
768   int nx = thePntLn2.x();
769   int ny = thePntLn2.y();
770   
771   r = px - lx;
772   r = r * r;
773   s = py - ly;
774   s = s * s;
775   a = (int) sqrt((double)(r + s));
776
777   r = px - nx;
778   r = r * r;
779   s = py - ny;
780   s = s * s;
781   b = (int) sqrt((double)(r + s));
782   
783   r = nx - lx;
784   r = r * r;
785   s = ny - ly;
786   s = s * s;
787   c = (int) sqrt((double)(r + s));
788
789   return (a+b-c);
790 }
791
792 void SUPERVGUI_Link::setBeginPort(SUPERVGUI_Port* theBeginPort) {
793   myBeginPort = theBeginPort;
794 }
795
796 SUPERVGUI_Port* SUPERVGUI_Link::getBeginPort() {
797   return myBeginPort;
798 }
799
800