]> SALOME platform Git repositories - modules/superv.git/blob - src/SUPERVGUI/SUPERVGUI_CanvasView.cxx
Salome HOME
Merge from OCC_development_generic_2006
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasView.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : SUPERVGUI_CanvasView.cxx
8 //  Author : Natalia KOPNOVA
9 //  Module : SUPERV
10
11 #include "SUPERVGUI.h"
12 #include "SUPERVGUI_CanvasView.h"
13 #include "SUPERVGUI_Main.h"
14 #include "SUPERVGUI_CanvasNode.h"
15 #include "SUPERVGUI_CanvasPort.h"
16 #include "SUPERVGUI_CanvasLink.h"
17 #include "SUPERVGUI_CanvasNodePrs.h"
18 #include "SUPERVGUI_Clipboard.h"
19
20 #include "SUPERVGUI_ArrayView.h" //for tooltip testing
21
22 #include "SUIT_MessageBox.h"
23
24 #include <qpixmap.h>
25 #include <qcolordialog.h>
26
27 #define MARGIN 2
28
29
30 /* XPM */
31 const char* imageZoomCursor[] = { 
32 "32 32 3 1",
33 ". c None",
34 "a c #000000",
35 "# c #ffffff",
36 "................................",
37 "................................",
38 ".#######........................",
39 "..aaaaaaa.......................",
40 "................................",
41 ".............#####..............",
42 "...........##.aaaa##............",
43 "..........#.aa.....a#...........",
44 ".........#.a.........#..........",
45 ".........#a..........#a.........",
46 "........#.a...........#.........",
47 "........#a............#a........",
48 "........#a............#a........",
49 "........#a............#a........",
50 "........#a............#a........",
51 ".........#...........#.a........",
52 ".........#a..........#a.........",
53 ".........##.........#.a.........",
54 "........#####.....##.a..........",
55 ".......###aaa#####.aa...........",
56 "......###aa...aaaaa.......#.....",
57 ".....###aa................#a....",
58 "....###aa.................#a....",
59 "...###aa...............#######..",
60 "....#aa.................aa#aaaa.",
61 ".....a....................#a....",
62 "..........................#a....",
63 "...........................a....",
64 "................................",
65 "................................",
66 "................................",
67 "................................"};
68
69 QPixmap zoomPix(imageZoomCursor);
70 QCursor zoom2Cursor(zoomPix);
71 QCursor handCursor(Qt::PointingHandCursor);
72
73 #if QT_VERSION >= 0x030005
74 QCursor pan2Cursor(Qt::SizeAllCursor);
75 #else
76 QCursor pan2Cursor(SizeAllCursor);
77 #endif
78
79 SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGUI_Main* theMain):
80   QCanvasView(theCanvas, theMain),
81   myMain(theMain), myCurrentItem(0), myHilighted(0), myLinkBuilder(0)
82 {
83   setName("CanvasView");
84
85   myIsPanBtnClicked = false;
86   myIsPanActivated = false;
87   myIsFitWRActivated = false;
88   myIsZoomActivated = false;
89   myIsLinkCreating = false;
90
91   myAddStudyItem = 0;
92   mySelectedRect = 0;
93   myCursor = cursor();
94
95   myTimer = new QTimer(this);
96   connect(myTimer, SIGNAL(timeout()), this, SLOT(onTimeout()));
97
98   myPopup = new QPopupMenu(viewport());
99
100   const bool isEdit = myMain->isEditable();
101   if (isEdit) {
102     myPopup->insertItem(tr("MSG_ADD_NODE"), myMain, SLOT(addNode()));
103
104     // Paste Node functionality
105     SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
106     myPasteNodeItem = myPopup->insertItem(tr("ITM_PASTE_NODE"), aCB, SLOT(pasteNode()));
107
108     myPopup->insertItem(tr("MSG_INS_FILE"), myMain, SLOT(insertFile()));
109     myPopup->insertSeparator();
110   }
111
112   QPopupMenu* aViewPopup = new QPopupMenu(viewport());
113   aViewPopup->insertItem(tr("POP_FULLVIEW"), myMain, SLOT(showCanvas()));
114   aViewPopup->insertItem(tr("POP_CONTROLVIEW"), myMain, SLOT(showContolFlow()));
115   aViewPopup->insertItem(tr("POP_TABLEVIEW"), myMain, SLOT(showCanvasTable()));
116
117   myPopup->insertItem(tr("POP_VIEW"), aViewPopup);
118   myPopup->insertSeparator();
119
120   QPopupMenu* aZoomPopup = new QPopupMenu(viewport());
121   aZoomPopup->insertItem("200%", this, SLOT(zoomIn()));
122   aZoomPopup->insertItem("100%", this, SLOT(zoomReset()));
123   aZoomPopup->insertItem("50%", this, SLOT(zoomOut()));
124   aZoomPopup->insertSeparator();
125   //mkr: "Fit within rectangle" functionality
126   aZoomPopup->insertItem(tr("POP_FITWITHINRECT"), this, SLOT(fitWithinRect()));
127   aZoomPopup->insertSeparator();
128   aZoomPopup->insertItem(tr("POP_FITALL"), this, SLOT(fitAll()));
129   
130
131   myPopup->insertItem(tr("POP_ZOOM"), aZoomPopup);
132   myPopup->insertSeparator();
133
134   myAddStudyItem = myPopup->insertItem(tr("MSG_ADD_STUDY"), myMain, SLOT(addDataflowToStudy()));
135   myPopup->insertItem(tr(isEdit ? "MSG_CHANGE_INFO" : "MSG_INFO"), myMain, SLOT(changeInformation()));
136   myPopup->insertSeparator();
137
138   myPopup->insertItem(tr("MSG_COPY_DATAFLOW"), myMain, SLOT(copy()));
139   myPopup->insertItem(tr("MSG_FILTER_NOTIFY"), myMain, SLOT(filterNotification()));
140
141   myPopup->insertSeparator();
142   myPopup->insertItem(tr("MSG_CHANGE_BACKGROUND"), this, SLOT(changeBackground()));
143
144   viewport()->setMouseTracking(true);
145
146   //create sketching popup menu
147   mySketchPopup = new QPopupMenu(viewport());
148   mySketchPopup->setCheckable(true);
149   myDelPntItem = mySketchPopup->insertItem(tr("MSG_DEL_LAST_PNT"), this, SLOT(deletePoint()));
150   mySketchPopup->insertItem(tr("MSG_DEL_LINK"), this, SLOT(cancelSketch()));
151   myOrtoItem = mySketchPopup->insertItem(tr("MSG_ORTHO_LINE"), this, SLOT(setOrthoMode()));
152
153   
154   // add "change dataflow parameters" popup item
155   myPopup->insertSeparator();
156   myDSParamsItem = myPopup->insertItem( tr( "MSG_SET_GRAPHPARAMS" ), myMain, SLOT( changeDSGraphParameters() ) );
157
158   SUPERVGraph_ViewFrame* anActiveVF = (SUPERVGraph_ViewFrame*)myMain->parent();
159   if ( anActiveVF ) {
160     myPopup->insertSeparator();
161     myShowToolBarItem = myPopup->insertItem( tr( "MEN_SHOW_TOOLBAR" ), myMain, SLOT( onShowToolbar() ) );
162   }
163
164   // mkr : PAL8237
165   connect(this, SIGNAL(objectCreated()), myMain, SLOT(onObjectCreatedDeleted()));
166 }
167  
168
169 SUPERVGUI_CanvasView::~SUPERVGUI_CanvasView()
170 {
171   SUPERVGUI_Clipboard::setNullClipboard();
172 }
173
174 void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent) 
175 {
176   myPoint = inverseWorldMatrix().map(theEvent->pos());
177   myGlobalPoint = theEvent->globalPos();
178   myCurrentItem = 0;
179
180   // compute collision rectangle
181   QRect aSel(myPoint.x()-MARGIN, myPoint.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
182
183   if (((theEvent->button() == Qt::MidButton) &&
184        (theEvent->state() == Qt::ControlButton)) || 
185       myIsPanBtnClicked) {
186     myIsPanActivated = true;
187     myCursor = cursor();
188     setCursor(pan2Cursor);
189     return;
190   }
191
192   if (((theEvent->button() == Qt::LeftButton) &&
193        (theEvent->state() == Qt::ControlButton)) || 
194       myIsZoomActivated) {
195     myIsZoomActivated = true;
196     myCursor = cursor();
197     setCursor(zoom2Cursor);
198     return;
199   }
200
201   if ( theEvent->button() == Qt::RightButton) {
202     if (myIsLinkCreating) {
203       myMain->showPopup(mySketchPopup, theEvent);
204       return;
205     }
206
207     QCanvasItemList l = canvas()->collisions(aSel);
208     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
209       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
210         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
211         QObject* anObj = aNodePrs->getObject(myPoint);
212         if (anObj->inherits("SUPERVGUI_CanvasNode")) {
213           myMain->showPopup(((SUPERVGUI_CanvasNode*)anObj)->getPopupMenu(viewport()), 
214                             theEvent);
215           return;
216         }
217         else if (anObj->inherits("SUPERVGUI_CanvasPort")) {
218           myMain->showPopup(((SUPERVGUI_CanvasPort*)anObj)->getPopupMenu(viewport()), 
219                             theEvent);
220           return;
221         }
222       }
223       if (myMain->isEditable() && !myMain->getCanvas()->isControlView()) {
224         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
225           SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
226           aPrs->getLink()->setSelectedObject(aPrs, myPoint);
227           myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
228           return;
229         }
230         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
231           SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
232           aPrs->getLink()->setSelectedObject(aPrs, myPoint);
233           myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
234           return;
235         }
236       }
237     }
238         
239     myPopup->setItemEnabled(myAddStudyItem, !myMain->isDataflowInStudy());
240     // Paste Node functionality
241     SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard(); 
242     myPopup->setItemEnabled(myPasteNodeItem, aCB->isCopyNode() );
243        
244     myPopup->setItemEnabled( myDSParamsItem, isHavingStreamPort()/*myMain->getDataflow()->IsStreamGraph()*/ );
245
246     myPopup->setItemEnabled( myShowToolBarItem, !((SUPERVGraph_ViewFrame*)myMain->parent())->getToolBar()->isVisible() );
247
248     myMain->showPopup(myPopup, theEvent);
249     return;
250   }
251
252   if (theEvent->button() == Qt::LeftButton) {
253     if (!myIsFitWRActivated) {//not moving items if fit within rectangle 
254                               //functionality is enable
255       QCanvasItemList l = canvas()->collisions(myPoint);
256       if (myIsLinkCreating) {
257         for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
258           if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
259             SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
260             QObject* anObj = aNodePrs->getObject(myPoint);
261             if (anObj->inherits("SUPERVGUI_CanvasPort")) {
262               endSketch((SUPERVGUI_CanvasPort*)anObj);
263               return;
264             }
265             else {
266               myCurrentItem = *it;
267               ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
268               ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
269               return;
270             }
271           }
272           if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Hook) {
273             SUPERVGUI_CanvasHookPrs* aHookPrs = (SUPERVGUI_CanvasHookPrs*) (*it);
274             QObject* anObj = aHookPrs->getObject();
275             if (anObj->inherits("SUPERVGUI_CanvasPort")) {
276               endSketch((SUPERVGUI_CanvasPort*)anObj);
277               return;
278             }
279           }
280         }
281         if (myLinkBuilder) {
282           myLinkBuilder->addNextPoint(myPoint, mySketchPopup->isItemChecked(myOrtoItem));
283           canvas()->update();
284           mySketchPopup->setItemEnabled(myDelPntItem, true);
285           return;
286         }
287       }
288       
289 //  if (myMain->isEditable()) { // allow to move nodes and link point on imported graph
290       for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
291         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
292           myCurrentItem = *it;
293           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
294           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
295           return;
296         }
297         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
298           SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
299           if (aPrs->getIndex() > 0) {
300             myCurrentItem = *it;
301             aPrs->setMoving(true);
302             return;
303           }
304         }
305         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
306           //mkr: for moving segment of link
307           SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
308           if (aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->startPoint()
309               ||
310             aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->endPoint()
311               ||
312               aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->startPoint()
313               ||
314               aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->endPoint()) {
315             return;
316           }
317           myCurrentItem = *it;
318           aPrs->setMoving(true);
319           return;
320         }
321       }
322 //  }
323     } 
324   }
325 }
326
327 bool busy = false;
328
329 void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent) 
330 {
331   if (busy) return;
332       
333   busy = true;
334   QPoint p = inverseWorldMatrix().map(theEvent->pos());
335   QPoint g = theEvent->globalPos();
336       
337   if (myTimer->isActive()) myTimer->stop();
338
339   if (myIsLinkCreating && myLinkBuilder) {
340     myLinkBuilder->setFloatPoint(p);
341     canvas()->update();
342   }
343    
344   if (myCurrentItem) {
345     //    setHilighted(0);
346     if (myCurrentItem->x() && myCurrentItem->y()) {
347       double cx = myCurrentItem->x() - myPoint.x();
348       double cy = myCurrentItem->y() - myPoint.y();
349       
350       if (p.x()+cx < 0) p.setX(-(int)cx);
351       if (p.y()+cy < 0) p.setY(-(int)cy);
352     }
353     myCurrentItem->moveBy(p.x() - myPoint.x(), 
354                           p.y() - myPoint.y());
355     myPoint = p;
356     canvas()->update();
357         
358     // scroll contents if mouse is outside
359     QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
360     if (!r.contains(theEvent->pos())) {
361       int dx = 0, dy = 0;
362       if (theEvent->pos().x() < r.left()) dx = theEvent->pos().x() - r.left();
363       if (theEvent->pos().x() > r.right()) dx = theEvent->pos().x() - r.right();
364       if (theEvent->pos().y() < r.top()) dy = theEvent->pos().y() - r.top();
365       if (theEvent->pos().y() > r.bottom()) dy = theEvent->pos().y() - r.bottom();
366       scrollBy(dx, dy);
367       // start timer to scroll in silent mode
368       myDX = dx; myDY = dy;
369       myTimer->start(100);
370     }
371     busy = false;
372     return;
373   }
374
375   if (myIsPanActivated) {
376     setHilighted(0);
377     scrollBy(myGlobalPoint.x() - g.x(),
378              myGlobalPoint.y() - g.y());
379     myGlobalPoint = g;
380     busy = false;
381     return;
382   }
383       
384   if (myIsZoomActivated) {
385     setHilighted(0);
386     double dx = g.x() - myGlobalPoint.x();
387     double s = 1. + fabs(dx)/10.;
388     if (dx < 0) s = 1./s;
389     
390     QWMatrix m = worldMatrix();
391     m.scale(s, s);
392     setWorldMatrix(m);
393         
394     myGlobalPoint = g;
395     busy = false;
396     return;
397   }
398
399   //mkr: "Fit within rectangle" functionality
400   if (myIsFitWRActivated) {
401     int aLX, aTY; //left x and top y
402     if (myPoint.x() < p.x()) aLX = myPoint.x();
403     else aLX = p.x();
404     if (myPoint.y() < p.y()) aTY = myPoint.y();
405     else aTY = p.y();
406     QRect aRect(aLX, aTY, abs(myPoint.x()-p.x()), abs(myPoint.y()-p.y()));
407     QCanvasRectangle* aRect1 = new QCanvasRectangle(aRect, canvas());
408
409     //hide old selected rectangle
410     if (mySelectedRect)
411       mySelectedRect->hide();
412     //draw new selected rectangle
413     QPen pen(Qt::SolidLine);
414     pen.setWidth(1);
415     aRect1->setPen(pen);
416     aRect1->setZ(3);
417     aRect1->show();
418
419     mySelectedRect = aRect1;
420     canvas()->update();
421   }
422   
423   if (!myIsLinkCreating && myMain->isEditable() &&
424       !myMain->getCanvas()->isControlView()) {
425     // compute collision rectangle
426     QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
427     QCanvasItemList l = canvas()->collisions(aSel);
428     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
429       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
430         SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
431         setHilighted(aPrs->getLink());
432         busy = false;
433         return;
434       }
435       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
436         SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
437         setHilighted(aPrs->getLink());
438         busy = false;
439         return;
440       }
441     }
442     setHilighted(0);
443   }
444
445   // QToolTip for title and label for SUPERVGUI_CanvasNode
446   SUPERVGUI_ToolTip* aTT = new SUPERVGUI_ToolTip(this);
447   aTT->maybeTip(p);
448
449   busy = false;
450 }
451
452 void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent) 
453 {
454   if (myTimer->isActive()) myTimer->stop();
455
456   if (myCurrentItem) {
457     if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
458       ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(0);
459       ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(false);
460       canvas()->update();
461     }
462     if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
463       ((SUPERVGUI_CanvasPointPrs*)myCurrentItem)->setMoving(false);
464     }
465   }
466   myCurrentItem = 0;
467
468   if (myIsPanActivated) {
469     myIsPanActivated = false;
470     myIsPanBtnClicked = false;
471     setCursor(myCursor);
472   }
473
474   if (myIsZoomActivated) {
475     myIsZoomActivated = false;
476     setCursor(myCursor);
477   }
478
479   //mkr: "Fit within rectangle" functionality
480   if (myIsFitWRActivated) {
481     if (mySelectedRect) {
482       mySelectedRect->hide();
483       mySelectedRect = 0;
484       canvas()->update();
485     }
486
487     //myPoint is the start point for selecting rectangle now
488     QPoint anEndPoint = inverseWorldMatrix().map(theEvent->pos());
489     int aLX, aTY; //left x and top y
490     if (myPoint.x() < anEndPoint.x()) aLX = myPoint.x();
491     else aLX = anEndPoint.x();
492     if (myPoint.y() < anEndPoint.y()) aTY = myPoint.y();
493     else aTY = anEndPoint.y();
494
495     //calculate width and height for new view and new zoom factor
496     double aXzoom = ((double)visibleWidth())/((double)(abs(myPoint.x()-anEndPoint.x())));
497     double aYzoom = ((double)visibleHeight())/((double)(abs(myPoint.y()-anEndPoint.y())));
498     if (aXzoom > aYzoom) aXzoom = aYzoom;
499     
500     QWMatrix m;
501     m.scale(aXzoom, aXzoom);
502     setWorldMatrix(m);
503     setContentsPos((int)(aLX*aXzoom), (int)(aTY*aYzoom));
504
505     canvas()->update();
506     
507     myIsFitWRActivated = false;
508     viewport()->setMouseTracking(true);
509     setCursor(myCursor);
510   }
511 }
512
513 void SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* theEvent)
514 {
515   QPoint p = inverseWorldMatrix().map(theEvent->pos());
516
517   // compute collision rectangle
518   //QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
519
520   if (theEvent->button() == Qt::LeftButton) {
521     QCanvasItemList l = canvas()->collisions(p);
522     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
523       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
524         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
525         SUPERVGUI_CanvasNode* aNode = aNodePrs->getNode();
526         if (aNode->getEngine()->IsMacro() && !myIsLinkCreating) {
527           myMain->openSubGraph(aNode->getEngine(), true);
528           return;
529         }
530       }
531     }
532   }
533 }
534
535 void SUPERVGUI_CanvasView::onDestroyed(QObject* theObject)
536 {
537   if (theObject == myHilighted)
538     myHilighted = 0;
539 }
540
541 void SUPERVGUI_CanvasView::setHilighted(SUPERVGUI_CanvasLink* theLink)
542 {
543   if (theLink == myHilighted) return;
544   if (myHilighted) {
545     disconnect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
546     myHilighted->setHilighted(false);
547     myHilighted = 0;
548   }
549   if (theLink) {
550     myHilighted = theLink;
551     myHilighted->setHilighted(true);
552     connect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
553   }
554 }
555
556 void SUPERVGUI_CanvasView::onTimeout() 
557 {
558   if (myCurrentItem) {
559     scrollBy(myDX, myDY);
560
561     double cx, cy;
562     inverseWorldMatrix().map((double)myDX, (double)myDY, &cx, &cy);
563     if (myCurrentItem->x()+cx < 0) cx = -myCurrentItem->x();
564     if (myCurrentItem->y()+cy < 0) cy = -myCurrentItem->y();
565     myCurrentItem->moveBy(cx, cy);
566     myPoint.setX(myPoint.x()+(int)cx);
567     myPoint.setY(myPoint.y()+(int)cy);
568     canvas()->update();
569   }
570 }
571
572 void SUPERVGUI_CanvasView::changeBackground()
573 {
574   QColor aColor = QColorDialog::getColor(canvas()->backgroundColor(), this );
575   if ( aColor.isValid() ) {
576     // change background color for canvas view
577     canvas()->setBackgroundColor(aColor);
578     setPaletteBackgroundColor(aColor.light(120));
579     // change background color for array view
580     getMain()->getArrayView()->canvas()->setBackgroundColor(aColor);
581     getMain()->getArrayView()->setPaletteBackgroundColor(aColor.light(120));
582
583     // mkr : IPAL10825 -->
584     SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
585     if ( !aSupMod ) {
586       MESSAGE("NULL Supervision module!");
587       return;
588     }
589     aSupMod->setIVFBackgroundColor(aColor); 
590     // <--
591   }
592 }
593
594 void SUPERVGUI_CanvasView::ActivatePanning()
595 {
596   myIsPanBtnClicked = true;
597 }
598
599 void SUPERVGUI_CanvasView::ResetView()
600 {
601   setContentsPos(0,0);
602   QWMatrix m;
603   setWorldMatrix(m);
604 }
605
606 void SUPERVGUI_CanvasView::startSketch(SUPERVGUI_CanvasPort* thePort)
607 {
608   if (myIsLinkCreating) return;
609
610   myIsLinkCreating = true;
611   myLinkBuilder = new SUPERVGUI_CanvasLinkBuilder(canvas(), myMain, thePort);
612   mySketchPopup->setItemEnabled(myDelPntItem, false);
613 }
614
615 void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
616 {
617   if (!myIsLinkCreating) return;
618
619   if (myLinkBuilder && myLinkBuilder->canCreateEngine(thePort)) {
620     bool input = thePort->getEngine()->IsInput();
621     SUPERV_Link aLinkEngine;
622     if (thePort->getEngine()->Kind() == SUPERV::DataStreamParameter) {
623       SUPERVGUI_CanvasStreamPortIn* aInPort = (SUPERVGUI_CanvasStreamPortIn*) 
624         (input ? thePort : myLinkBuilder->getStartPort());
625       SUPERVGUI_CanvasStreamPortOut* aOutPort = (SUPERVGUI_CanvasStreamPortOut*) 
626         (input ? myLinkBuilder->getStartPort() : thePort);
627 //       aLinkEngine = myMain->getDataflow()->StreamLink(aOutPort->getStreamEngine(), 
628 //                                                    aInPort->getStreamEngine());
629       if (myMain->getDataflow()->IsStreamGraph()) {
630         SUPERV_StreamGraph aSGraph = myMain->getDataflow()->ToStreamGraph();
631         if (!SUPERV_isNull(aSGraph))
632           aLinkEngine = aSGraph->StreamLink(aOutPort->getStreamEngine(), 
633                                             aInPort->getStreamEngine());
634       }
635     }
636     else {
637       SUPERVGUI_CanvasPort* aInPort = (input ? thePort : myLinkBuilder->getStartPort());
638       SUPERVGUI_CanvasPort* aOutPort = (input ? myLinkBuilder->getStartPort() : thePort);
639       aLinkEngine = myMain->getDataflow()->Link(aOutPort->getEngine(), aInPort->getEngine());
640     }
641     if (SUPERV_isNull(aLinkEngine)) 
642       return;    
643
644     // here, in fact, aLinkEngine may NOT be a newly created link.  If a link already existed between the
645     // the 2 given ports - it will be return (NOT created again).
646     // this should be checked and new presentation should NOT be created for existing link.
647     // Solution 1: NOT to allow creation of a link if it already exists between the ports in 
648     //             myLinkBuilder->canCreateEngine()
649     // Solution 2: check here if aLinkEngine is "new" or "old"
650     // Implement 2nd solution, because canCreateEngine() checks for types of ports, etc.. - it's another thing
651     // THE CHECK:
652     QObjectList* canvasLinks = canvas()->queryList("SUPERVGUI_CanvasLink");
653     SUPERVGUI_CanvasLink* canvasLink = 0;
654     QObjectListIt it(*canvasLinks);
655     bool prsAlreadyExists = false;
656     while ( (canvasLink=(SUPERVGUI_CanvasLink*)it.current()) ) {
657       ++it;
658       SUPERV_Link existingLinkWithPrs = canvasLink->getEngine();
659       if ( !SUPERV_isNull( existingLinkWithPrs ) ) {
660         if ( existingLinkWithPrs->IsEqual( aLinkEngine ) ) {
661           prsAlreadyExists = true;
662           break;
663         }       
664       }
665     }
666     delete canvasLinks;
667     if ( prsAlreadyExists ) { // aLinkEngine is already bound with a SUPERVGUI_CanvasLink object
668       //return;  // -> if return here, than the old CanvasLink is kept
669
670       // we want to delete old and create a new CanvasLink for this Link
671       delete canvasLink;
672       canvasLink = 0;
673       // clear old corrdinates in Engine link
674       for ( int i = 1; i <= aLinkEngine->CoordsSize(); i++ )
675         aLinkEngine->RemoveCoord( i );
676       // now we are ready to set coords for a link and create a new CanvasLink presentation that will use them.
677     }
678
679     myLinkBuilder->setCoords(aLinkEngine.in());
680
681     delete myLinkBuilder;
682     myLinkBuilder = 0;
683
684     SUPERVGUI_CanvasLink* aLink = new SUPERVGUI_CanvasLink(canvas(), myMain, aLinkEngine);
685     aLink->show();
686
687     emit objectCreated(); // mkr : PAL8237
688
689     canvas()->update();
690     myIsLinkCreating = false;
691
692     // asv : 13.12.04 : introducing a check for ports' types compatibility (Bugs and Improvements p.1.16, PAL7380)
693     if ( !aLinkEngine->IsValid() ) { 
694       const int id = SUIT_MessageBox::warn2( this, tr( "TLT_INVALID_LINK" ), 
695                                              tr( "MSG_INVALID_LINK" ) + QString(" : ") + QString(myMain->getDataflow()->Messages()), 
696                                              tr( "Keep" ), tr( "Remove" ), 0, 1, 0 );
697       if ( id == 1 ) { // "Remove" was selected in Message Box
698         aLink->remove(); // the new link did not live long...
699       }
700     }
701   }
702 }
703
704 void SUPERVGUI_CanvasView::cancelSketch()
705 {
706   if (myLinkBuilder) {
707     delete myLinkBuilder;
708     myLinkBuilder = 0;
709     canvas()->update();
710   }
711   myIsLinkCreating = false;
712 }
713
714 void SUPERVGUI_CanvasView::deletePoint()
715 {
716   if (myIsLinkCreating && myLinkBuilder) {
717     myLinkBuilder->removeLastPoint();
718     canvas()->update();
719     mySketchPopup->setItemEnabled(myDelPntItem, myLinkBuilder->getPointCount());
720   }
721 }
722
723 void SUPERVGUI_CanvasView::setOrthoMode()
724 {
725   bool aIsOrtho = !mySketchPopup->isItemChecked(myOrtoItem);
726   mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
727 }
728
729 void SUPERVGUI_CanvasView::zoomIn() 
730 {
731   QWMatrix m;
732   m.scale(2.0, 2.0);
733   setWorldMatrix(m);
734   canvas()->update();
735 }
736
737 void SUPERVGUI_CanvasView::zoomReset() 
738 {
739   QWMatrix m;
740   m.scale(1.0, 1.0);
741   setWorldMatrix(m);
742   canvas()->update();
743 }
744
745 void SUPERVGUI_CanvasView::zoomOut() 
746 {
747   QWMatrix m;
748   m.scale(0.5, 0.5);
749   setWorldMatrix(m);
750   canvas()->update();
751 }
752
753 void SUPERVGUI_CanvasView::fitAll() 
754 {
755   int w = 0, h = 0;
756   QCanvasItemList l = canvas()->allItems();
757   for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
758     QRect r = (*it)->boundingRect();
759     if (w < r.right()) w = r.right();
760     if (h < r.bottom()) h = r.bottom();
761   }
762   w += GRAPH_MARGIN; h += GRAPH_MARGIN;
763   double s = ((double)visibleWidth())/((double)w);
764   double s1 = ((double)visibleHeight())/((double)h);
765   if (s > s1) s = s1;
766
767   setContentsPos(0,0);
768   QWMatrix m;
769   m.scale(s, s);
770   setWorldMatrix(m);
771   canvas()->update();
772 }
773
774 void SUPERVGUI_CanvasView::fitWithinRect() 
775 {
776   //mkr: "Fit within rectangle" functionality
777   myIsFitWRActivated = true;
778   viewport()->setMouseTracking(false);
779   myCursor = cursor();
780   setCursor(handCursor);
781 }
782
783 bool SUPERVGUI_CanvasView::isHavingStreamPort() const
784 {
785   SUPERV::ListOfNodes* aNodesList = myMain->getDataflow()->Nodes();
786
787   //Computing Nodes
788   for ( int i = 0 ; i < (int) aNodesList->CNodes.length() ; i++ ) {
789     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->CNodes)[i]->StreamPorts() );
790     if ((int) aStrPortsList.length() > 0) {
791       return true;
792     }
793   }
794    
795   //FactoryNodes
796   for ( int i = 0 ; i < (int) aNodesList->FNodes.length() ; i++ ) {
797     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->FNodes)[i]->StreamPorts() );
798     if ((int) aStrPortsList.length() > 0) {
799       return true;
800     }
801   }
802         
803   //InLineNodes
804   for ( int i = 0 ; i < (int) aNodesList->INodes.length() ; i++ ) {
805     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->INodes)[i]->StreamPorts() );
806     if ((int) aStrPortsList.length() > 0) {
807       return true;
808     }
809   }
810         
811   //GOTONodes
812   for ( int i = 0 ; i < (int) aNodesList->GNodes.length() ; i++ ) {
813     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->GNodes)[i]->StreamPorts() );
814     if ((int) aStrPortsList.length() > 0) {
815       return true;
816     }
817   }
818         
819   //LoopNodes
820   for ( int i = 0 ; i < (int) aNodesList->LNodes.length() ; i++ ) {
821     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->LNodes)[i]->StreamPorts() );
822     if ((int) aStrPortsList.length() > 0) {
823      return true;
824     }
825   }
826         
827   //SwitchNodes
828   for ( int i = 0 ; i < (int) aNodesList->SNodes.length() ; i++ ) {
829     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->SNodes)[i]->StreamPorts() );
830     if ((int) aStrPortsList.length() > 0) {
831       return true;
832     }
833   }
834         
835   return false;
836 }