Salome HOME
c33671658d7ee0419d38d0ac5c85d2243ea95aca
[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 using namespace std;
12
13 #include "SUPERVGUI.h"
14 #include "SUPERVGUI_CanvasView.h"
15 #include "SUPERVGUI_Main.h"
16 #include "SUPERVGUI_CanvasNode.h"
17 #include "SUPERVGUI_CanvasPort.h"
18 #include "SUPERVGUI_CanvasLink.h"
19 #include "SUPERVGUI_CanvasNodePrs.h"
20 #include "SUPERVGUI_Clipboard.h"
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  
165
166 SUPERVGUI_CanvasView::~SUPERVGUI_CanvasView()
167 {
168   SUPERVGUI_Clipboard::setNullClipboard();
169 }
170
171 void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent) 
172 {
173   myPoint = inverseWorldMatrix().map(theEvent->pos());
174   myGlobalPoint = theEvent->globalPos();
175   myCurrentItem = 0;
176
177   // compute collision rectangle
178   QRect aSel(myPoint.x()-MARGIN, myPoint.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
179
180   if (((theEvent->button() == Qt::MidButton) &&
181        (theEvent->state() == Qt::ControlButton)) || 
182       myIsPanBtnClicked) {
183     myIsPanActivated = true;
184     myCursor = cursor();
185     setCursor(pan2Cursor);
186     return;
187   }
188
189   if (((theEvent->button() == Qt::LeftButton) &&
190        (theEvent->state() == Qt::ControlButton)) || 
191       myIsZoomActivated) {
192     myIsZoomActivated = true;
193     myCursor = cursor();
194     setCursor(zoom2Cursor);
195     return;
196   }
197
198   if ( theEvent->button() == Qt::RightButton) {
199     if (myIsLinkCreating) {
200       myMain->showPopup(mySketchPopup, theEvent);
201       return;
202     }
203
204     QCanvasItemList l = canvas()->collisions(aSel);
205     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
206       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
207         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
208         QObject* anObj = aNodePrs->getObject(myPoint);
209         if (anObj->inherits("SUPERVGUI_CanvasNode")) {
210           myMain->showPopup(((SUPERVGUI_CanvasNode*)anObj)->getPopupMenu(viewport()), 
211                             theEvent);
212           return;
213         }
214         else if (anObj->inherits("SUPERVGUI_CanvasPort")) {
215           myMain->showPopup(((SUPERVGUI_CanvasPort*)anObj)->getPopupMenu(viewport()), 
216                             theEvent);
217           return;
218         }
219       }
220       if (myMain->isEditable() && !myMain->getCanvas()->isControlView()) {
221         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
222           SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
223           aPrs->getLink()->setSelectedObject(aPrs, myPoint);
224           myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
225           return;
226         }
227         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
228           SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
229           aPrs->getLink()->setSelectedObject(aPrs, myPoint);
230           myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
231           return;
232         }
233       }
234     }
235         
236     myPopup->setItemEnabled(myAddStudyItem, !myMain->isDataflowInStudy());
237     // Paste Node functionality
238     SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard(); 
239     myPopup->setItemEnabled(myPasteNodeItem, aCB->isCopyNode() );
240        
241     myPopup->setItemEnabled( myDSParamsItem, isHavingStreamPort()/*myMain->getDataflow()->IsStreamGraph()*/ );
242
243     myPopup->setItemEnabled( myShowToolBarItem, !((SUPERVGraph_ViewFrame*)myMain->parent())->getToolBar()->isVisible() );
244
245     myMain->showPopup(myPopup, theEvent);
246     return;
247   }
248
249   if (theEvent->button() == Qt::LeftButton) {
250     if (!myIsFitWRActivated) {//not moving items if fit within rectangle 
251                               //functionality is enable
252       QCanvasItemList l = canvas()->collisions(myPoint);
253       if (myIsLinkCreating) {
254         for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
255           if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
256             SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
257             QObject* anObj = aNodePrs->getObject(myPoint);
258             if (anObj->inherits("SUPERVGUI_CanvasPort")) {
259               endSketch((SUPERVGUI_CanvasPort*)anObj);
260               return;
261             }
262             else {
263               myCurrentItem = *it;
264               ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
265               ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
266               return;
267             }
268           }
269           if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Hook) {
270             SUPERVGUI_CanvasHookPrs* aHookPrs = (SUPERVGUI_CanvasHookPrs*) (*it);
271             QObject* anObj = aHookPrs->getObject();
272             if (anObj->inherits("SUPERVGUI_CanvasPort")) {
273               endSketch((SUPERVGUI_CanvasPort*)anObj);
274               return;
275             }
276           }
277         }
278         if (myLinkBuilder) {
279           myLinkBuilder->addNextPoint(myPoint, mySketchPopup->isItemChecked(myOrtoItem));
280           canvas()->update();
281           mySketchPopup->setItemEnabled(myDelPntItem, true);
282           return;
283         }
284       }
285       
286 //  if (myMain->isEditable()) { // allow to move nodes and link point on imported graph
287       for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
288         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
289           myCurrentItem = *it;
290           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
291           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
292           return;
293         }
294         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
295           SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
296           if (aPrs->getIndex() > 0) {
297             myCurrentItem = *it;
298             aPrs->setMoving(true);
299             return;
300           }
301         }
302         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
303           //mkr: for moving segment of link
304           SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
305           if (aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->startPoint()
306               ||
307             aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->endPoint()
308               ||
309               aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->startPoint()
310               ||
311               aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->endPoint()) {
312             return;
313           }
314           myCurrentItem = *it;
315           aPrs->setMoving(true);
316           return;
317         }
318       }
319 //  }
320     } 
321   }
322 }
323
324 bool busy = false;
325
326 void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent) 
327 {
328   if (busy) return;
329       
330   busy = true;
331   QPoint p = inverseWorldMatrix().map(theEvent->pos());
332   QPoint g = theEvent->globalPos();
333       
334   if (myTimer->isActive()) myTimer->stop();
335
336   if (myIsLinkCreating && myLinkBuilder) {
337     myLinkBuilder->setFloatPoint(p);
338     canvas()->update();
339   }
340    
341   if (myCurrentItem) {
342     //    setHilighted(0);
343     if (myCurrentItem->x() && myCurrentItem->y()) {
344       double cx = myCurrentItem->x() - myPoint.x();
345       double cy = myCurrentItem->y() - myPoint.y();
346       
347       if (p.x()+cx < 0) p.setX(-(int)cx);
348       if (p.y()+cy < 0) p.setY(-(int)cy);
349     }
350     myCurrentItem->moveBy(p.x() - myPoint.x(), 
351                           p.y() - myPoint.y());
352     myPoint = p;
353     canvas()->update();
354         
355     // scroll contents if mouse is outside
356     QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
357     if (!r.contains(theEvent->pos())) {
358       int dx = 0, dy = 0;
359       if (theEvent->pos().x() < r.left()) dx = theEvent->pos().x() - r.left();
360       if (theEvent->pos().x() > r.right()) dx = theEvent->pos().x() - r.right();
361       if (theEvent->pos().y() < r.top()) dy = theEvent->pos().y() - r.top();
362       if (theEvent->pos().y() > r.bottom()) dy = theEvent->pos().y() - r.bottom();
363       scrollBy(dx, dy);
364       // start timer to scroll in silent mode
365       myDX = dx; myDY = dy;
366       myTimer->start(100);
367     }
368     busy = false;
369     return;
370   }
371
372   if (myIsPanActivated) {
373     setHilighted(0);
374     scrollBy(myGlobalPoint.x() - g.x(),
375              myGlobalPoint.y() - g.y());
376     myGlobalPoint = g;
377     busy = false;
378     return;
379   }
380       
381   if (myIsZoomActivated) {
382     setHilighted(0);
383     double dx = g.x() - myGlobalPoint.x();
384     double s = 1. + fabs(dx)/10.;
385     if (dx < 0) s = 1./s;
386     
387     QWMatrix m = worldMatrix();
388     m.scale(s, s);
389     setWorldMatrix(m);
390         
391     myGlobalPoint = g;
392     busy = false;
393     return;
394   }
395
396   //mkr: "Fit within rectangle" functionality
397   if (myIsFitWRActivated) {
398     int aLX, aTY; //left x and top y
399     if (myPoint.x() < p.x()) aLX = myPoint.x();
400     else aLX = p.x();
401     if (myPoint.y() < p.y()) aTY = myPoint.y();
402     else aTY = p.y();
403     QRect aRect(aLX, aTY, abs(myPoint.x()-p.x()), abs(myPoint.y()-p.y()));
404     QCanvasRectangle* aRect1 = new QCanvasRectangle(aRect, canvas());
405
406     //hide old selected rectangle
407     if (mySelectedRect)
408       mySelectedRect->hide();
409     //draw new selected rectangle
410     QPen pen(Qt::SolidLine);
411     pen.setWidth(1);
412     aRect1->setPen(pen);
413     aRect1->setZ(3);
414     aRect1->show();
415
416     mySelectedRect = aRect1;
417     canvas()->update();
418   }
419   
420   if (!myIsLinkCreating && myMain->isEditable() &&
421       !myMain->getCanvas()->isControlView()) {
422     // compute collision rectangle
423     QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
424     QCanvasItemList l = canvas()->collisions(aSel);
425     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
426       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
427         SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
428         setHilighted(aPrs->getLink());
429         busy = false;
430         return;
431       }
432       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
433         SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
434         setHilighted(aPrs->getLink());
435         busy = false;
436         return;
437       }
438     }
439     setHilighted(0);
440   }
441
442   busy = false;
443 }
444
445 void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent) 
446 {
447   if (myTimer->isActive()) myTimer->stop();
448
449   if (myCurrentItem) {
450     if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
451       ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(0);
452       ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(false);
453       canvas()->update();
454     }
455     if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
456       ((SUPERVGUI_CanvasPointPrs*)myCurrentItem)->setMoving(false);
457     }
458   }
459   myCurrentItem = 0;
460
461   if (myIsPanActivated) {
462     myIsPanActivated = false;
463     myIsPanBtnClicked = false;
464     setCursor(myCursor);
465   }
466
467   if (myIsZoomActivated) {
468     myIsZoomActivated = false;
469     setCursor(myCursor);
470   }
471
472   //mkr: "Fit within rectangle" functionality
473   if (myIsFitWRActivated) {
474     if (mySelectedRect) {
475       mySelectedRect->hide();
476       mySelectedRect = 0;
477       canvas()->update();
478     }
479
480     //myPoint is the start point for selecting rectangle now
481     QPoint anEndPoint = inverseWorldMatrix().map(theEvent->pos());
482     int aLX, aTY; //left x and top y
483     if (myPoint.x() < anEndPoint.x()) aLX = myPoint.x();
484     else aLX = anEndPoint.x();
485     if (myPoint.y() < anEndPoint.y()) aTY = myPoint.y();
486     else aTY = anEndPoint.y();
487
488     //calculate width and height for new view and new zoom factor
489     double aXzoom = ((double)visibleWidth())/((double)(abs(myPoint.x()-anEndPoint.x())));
490     double aYzoom = ((double)visibleHeight())/((double)(abs(myPoint.y()-anEndPoint.y())));
491     if (aXzoom > aYzoom) aXzoom = aYzoom;
492     
493     QWMatrix m;
494     m.scale(aXzoom, aXzoom);
495     setWorldMatrix(m);
496     setContentsPos((int)(aLX*aXzoom), (int)(aTY*aYzoom));
497
498     canvas()->update();
499     
500     myIsFitWRActivated = false;
501     viewport()->setMouseTracking(true);
502     setCursor(myCursor);
503   }
504 }
505
506 void SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* theEvent)
507 {
508   QPoint p = inverseWorldMatrix().map(theEvent->pos());
509
510   // compute collision rectangle
511   //QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
512
513   if (theEvent->button() == Qt::LeftButton) {
514     QCanvasItemList l = canvas()->collisions(p);
515     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
516       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
517         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
518         SUPERVGUI_CanvasNode* aNode = aNodePrs->getNode();
519         if (aNode->getEngine()->IsMacro() && !myIsLinkCreating) {
520           myMain->openSubGraph(aNode->getEngine(), true);
521           return;
522         }
523       }
524     }
525   }
526 }
527
528 void SUPERVGUI_CanvasView::onDestroyed(QObject* theObject)
529 {
530   if (theObject == myHilighted)
531     myHilighted = 0;
532 }
533
534 void SUPERVGUI_CanvasView::setHilighted(SUPERVGUI_CanvasLink* theLink)
535 {
536   if (theLink == myHilighted) return;
537   if (myHilighted) {
538     disconnect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
539     myHilighted->setHilighted(false);
540     myHilighted = 0;
541   }
542   if (theLink) {
543     myHilighted = theLink;
544     myHilighted->setHilighted(true);
545     connect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
546   }
547 }
548
549 void SUPERVGUI_CanvasView::onTimeout() 
550 {
551   if (myCurrentItem) {
552     scrollBy(myDX, myDY);
553
554     double cx, cy;
555     inverseWorldMatrix().map((double)myDX, (double)myDY, &cx, &cy);
556     if (myCurrentItem->x()+cx < 0) cx = -myCurrentItem->x();
557     if (myCurrentItem->y()+cy < 0) cy = -myCurrentItem->y();
558     myCurrentItem->moveBy(cx, cy);
559     myPoint.setX(myPoint.x()+(int)cx);
560     myPoint.setY(myPoint.y()+(int)cy);
561     canvas()->update();
562   }
563 }
564
565 void SUPERVGUI_CanvasView::changeBackground()
566 {
567   QColor aColor = QColorDialog::getColor(canvas()->backgroundColor(), this );
568   if ( aColor.isValid() ) {
569     // change background color for canvas view
570     canvas()->setBackgroundColor(aColor);
571     setPaletteBackgroundColor(aColor.light(120));
572     // change background color for array view
573     getMain()->getArrayView()->canvas()->setBackgroundColor(aColor);
574     getMain()->getArrayView()->setPaletteBackgroundColor(aColor.light(120));
575
576     // mkr : IPAL10825 -->
577     SUPERVGUI* aSupMod = SUPERVGUI::Supervision();
578     if ( !aSupMod ) {
579       MESSAGE("NULL Supervision module!");
580       return;
581     }
582     aSupMod->setIVFBackgroundColor(aColor); 
583     // <--
584   }
585 }
586
587 void SUPERVGUI_CanvasView::ActivatePanning()
588 {
589   myIsPanBtnClicked = true;
590 }
591
592 void SUPERVGUI_CanvasView::ResetView()
593 {
594   setContentsPos(0,0);
595   QWMatrix m;
596   setWorldMatrix(m);
597 }
598
599 void SUPERVGUI_CanvasView::startSketch(SUPERVGUI_CanvasPort* thePort)
600 {
601   if (myIsLinkCreating) return;
602
603   myIsLinkCreating = true;
604   myLinkBuilder = new SUPERVGUI_CanvasLinkBuilder(canvas(), myMain, thePort);
605   mySketchPopup->setItemEnabled(myDelPntItem, false);
606 }
607
608 void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
609 {
610   if (!myIsLinkCreating) return;
611
612   if (myLinkBuilder && myLinkBuilder->canCreateEngine(thePort)) {
613     bool input = thePort->getEngine()->IsInput();
614     SUPERV_Link aLinkEngine;
615     if (thePort->getEngine()->Kind() == SUPERV::DataStreamParameter) {
616       SUPERVGUI_CanvasStreamPortIn* aInPort = (SUPERVGUI_CanvasStreamPortIn*) 
617         (input ? thePort : myLinkBuilder->getStartPort());
618       SUPERVGUI_CanvasStreamPortOut* aOutPort = (SUPERVGUI_CanvasStreamPortOut*) 
619         (input ? myLinkBuilder->getStartPort() : thePort);
620 //       aLinkEngine = myMain->getDataflow()->StreamLink(aOutPort->getStreamEngine(), 
621 //                                                    aInPort->getStreamEngine());
622       if (myMain->getDataflow()->IsStreamGraph()) {
623         SUPERV_StreamGraph aSGraph = myMain->getDataflow()->ToStreamGraph();
624         if (!SUPERV_isNull(aSGraph))
625           aLinkEngine = aSGraph->StreamLink(aOutPort->getStreamEngine(), 
626                                             aInPort->getStreamEngine());
627       }
628     }
629     else {
630       SUPERVGUI_CanvasPort* aInPort = (input ? thePort : myLinkBuilder->getStartPort());
631       SUPERVGUI_CanvasPort* aOutPort = (input ? myLinkBuilder->getStartPort() : thePort);
632       aLinkEngine = myMain->getDataflow()->Link(aOutPort->getEngine(), aInPort->getEngine());
633     }
634     if (SUPERV_isNull(aLinkEngine)) 
635       return;    
636
637     // here, in fact, aLinkEngine may NOT be a newly created link.  If a link already existed between the
638     // the 2 given ports - it will be return (NOT created again).
639     // this should be checked and new presentation should NOT be created for existing link.
640     // Solution 1: NOT to allow creation of a link if it already exists between the ports in 
641     //             myLinkBuilder->canCreateEngine()
642     // Solution 2: check here if aLinkEngine is "new" or "old"
643     // Implement 2nd solution, because canCreateEngine() checks for types of ports, etc.. - it's another thing
644     // THE CHECK:
645     QObjectList* canvasLinks = canvas()->queryList("SUPERVGUI_CanvasLink");
646     SUPERVGUI_CanvasLink* canvasLink = 0;
647     QObjectListIt it(*canvasLinks);
648     bool prsAlreadyExists = false;
649     while ( (canvasLink=(SUPERVGUI_CanvasLink*)it.current()) ) {
650       ++it;
651       SUPERV_Link existingLinkWithPrs = canvasLink->getEngine();
652       if ( !SUPERV_isNull( existingLinkWithPrs ) ) {
653         if ( existingLinkWithPrs->IsEqual( aLinkEngine ) ) {
654           prsAlreadyExists = true;
655           break;
656         }       
657       }
658     }
659     delete canvasLinks;
660     if ( prsAlreadyExists ) { // aLinkEngine is already bound with a SUPERVGUI_CanvasLink object
661       //return;  // -> if return here, than the old CanvasLink is kept
662
663       // we want to delete old and create a new CanvasLink for this Link
664       delete canvasLink;
665       canvasLink = 0;
666       // clear old corrdinates in Engine link
667       for ( int i = 1; i <= aLinkEngine->CoordsSize(); i++ )
668         aLinkEngine->RemoveCoord( i );
669       // now we are ready to set coords for a link and create a new CanvasLink presentation that will use them.
670     }
671
672     myLinkBuilder->setCoords(aLinkEngine.in());
673
674     delete myLinkBuilder;
675     myLinkBuilder = 0;
676
677     SUPERVGUI_CanvasLink* aLink = new SUPERVGUI_CanvasLink(canvas(), myMain, aLinkEngine);
678     aLink->show();
679
680     canvas()->update();
681     myIsLinkCreating = false;
682
683     // asv : 13.12.04 : introducing a check for ports' types compatibility (Bugs and Improvements p.1.16, PAL7380)
684     if ( !aLinkEngine->IsValid() ) { 
685       const int id = SUIT_MessageBox::warn2( this, tr( "TLT_INVALID_LINK" ), 
686                                              tr( "MSG_INVALID_LINK" ) + QString(" : ") + QString(myMain->getDataflow()->Messages()), 
687                                              tr( "Keep" ), tr( "Remove" ), 0, 1, 0 );
688       if ( id == 1 ) { // "Remove" was selected in Message Box
689         aLink->remove(); // the new link did not live long...
690       }
691     }
692   }
693 }
694
695 void SUPERVGUI_CanvasView::cancelSketch()
696 {
697   if (myLinkBuilder) {
698     delete myLinkBuilder;
699     myLinkBuilder = 0;
700     canvas()->update();
701   }
702   myIsLinkCreating = false;
703 }
704
705 void SUPERVGUI_CanvasView::deletePoint()
706 {
707   if (myIsLinkCreating && myLinkBuilder) {
708     myLinkBuilder->removeLastPoint();
709     canvas()->update();
710     mySketchPopup->setItemEnabled(myDelPntItem, myLinkBuilder->getPointCount());
711   }
712 }
713
714 void SUPERVGUI_CanvasView::setOrthoMode()
715 {
716   bool aIsOrtho = !mySketchPopup->isItemChecked(myOrtoItem);
717   mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
718 }
719
720 void SUPERVGUI_CanvasView::zoomIn() 
721 {
722   QWMatrix m;
723   m.scale(2.0, 2.0);
724   setWorldMatrix(m);
725   canvas()->update();
726 }
727
728 void SUPERVGUI_CanvasView::zoomReset() 
729 {
730   QWMatrix m;
731   m.scale(1.0, 1.0);
732   setWorldMatrix(m);
733   canvas()->update();
734 }
735
736 void SUPERVGUI_CanvasView::zoomOut() 
737 {
738   QWMatrix m;
739   m.scale(0.5, 0.5);
740   setWorldMatrix(m);
741   canvas()->update();
742 }
743
744 void SUPERVGUI_CanvasView::fitAll() 
745 {
746   int w = 0, h = 0;
747   QCanvasItemList l = canvas()->allItems();
748   for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
749     QRect r = (*it)->boundingRect();
750     if (w < r.right()) w = r.right();
751     if (h < r.bottom()) h = r.bottom();
752   }
753   w += GRAPH_MARGIN; h += GRAPH_MARGIN;
754   double s = ((double)visibleWidth())/((double)w);
755   double s1 = ((double)visibleHeight())/((double)h);
756   if (s > s1) s = s1;
757
758   setContentsPos(0,0);
759   QWMatrix m;
760   m.scale(s, s);
761   setWorldMatrix(m);
762   canvas()->update();
763 }
764
765 void SUPERVGUI_CanvasView::fitWithinRect() 
766 {
767   //mkr: "Fit within rectangle" functionality
768   myIsFitWRActivated = true;
769   viewport()->setMouseTracking(false);
770   myCursor = cursor();
771   setCursor(handCursor);
772 }
773
774 bool SUPERVGUI_CanvasView::isHavingStreamPort() const
775 {
776   SUPERV::ListOfNodes* aNodesList = myMain->getDataflow()->Nodes();
777
778   //Computing Nodes
779   for ( int i = 0 ; i < (int) aNodesList->CNodes.length() ; i++ ) {
780     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->CNodes)[i]->StreamPorts() );
781     if ((int) aStrPortsList.length() > 0) {
782       return true;
783     }
784   }
785    
786   //FactoryNodes
787   for ( int i = 0 ; i < (int) aNodesList->FNodes.length() ; i++ ) {
788     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->FNodes)[i]->StreamPorts() );
789     if ((int) aStrPortsList.length() > 0) {
790       return true;
791     }
792   }
793         
794   //InLineNodes
795   for ( int i = 0 ; i < (int) aNodesList->INodes.length() ; i++ ) {
796     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->INodes)[i]->StreamPorts() );
797     if ((int) aStrPortsList.length() > 0) {
798       return true;
799     }
800   }
801         
802   //GOTONodes
803   for ( int i = 0 ; i < (int) aNodesList->GNodes.length() ; i++ ) {
804     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->GNodes)[i]->StreamPorts() );
805     if ((int) aStrPortsList.length() > 0) {
806       return true;
807     }
808   }
809         
810   //LoopNodes
811   for ( int i = 0 ; i < (int) aNodesList->LNodes.length() ; i++ ) {
812     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->LNodes)[i]->StreamPorts() );
813     if ((int) aStrPortsList.length() > 0) {
814      return true;
815     }
816   }
817         
818   //SwitchNodes
819   for ( int i = 0 ; i < (int) aNodesList->SNodes.length() ; i++ ) {
820     SUPERV::ListOfStreamPorts aStrPortsList = *( (aNodesList->SNodes)[i]->StreamPorts() );
821     if ((int) aStrPortsList.length() > 0) {
822       return true;
823     }
824   }
825         
826   return false;
827 }