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