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