Salome HOME
Point 2.12 from "SUPERVISOR: Current status - bugs/improvements"
[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_CanvasView.h"
14 #include "SUPERVGUI_Main.h"
15 #include "SUPERVGUI_CanvasNode.h"
16 #include "SUPERVGUI_CanvasPort.h"
17 #include "SUPERVGUI_CanvasLink.h"
18 #include "SUPERVGUI_CanvasNodePrs.h"
19
20 #include "QAD_Config.h"
21 #include "QAD_MessageBox.h"
22
23 #include <qpixmap.h>
24 #include <qcolordialog.h>
25
26 #define MARGIN 2
27
28
29 /* XPM */
30 const char* imageZoomCursor[] = { 
31 "32 32 3 1",
32 ". c None",
33 "a c #000000",
34 "# c #ffffff",
35 "................................",
36 "................................",
37 ".#######........................",
38 "..aaaaaaa.......................",
39 "................................",
40 ".............#####..............",
41 "...........##.aaaa##............",
42 "..........#.aa.....a#...........",
43 ".........#.a.........#..........",
44 ".........#a..........#a.........",
45 "........#.a...........#.........",
46 "........#a............#a........",
47 "........#a............#a........",
48 "........#a............#a........",
49 "........#a............#a........",
50 ".........#...........#.a........",
51 ".........#a..........#a.........",
52 ".........##.........#.a.........",
53 "........#####.....##.a..........",
54 ".......###aaa#####.aa...........",
55 "......###aa...aaaaa.......#.....",
56 ".....###aa................#a....",
57 "....###aa.................#a....",
58 "...###aa...............#######..",
59 "....#aa.................aa#aaaa.",
60 ".....a....................#a....",
61 "..........................#a....",
62 "...........................a....",
63 "................................",
64 "................................",
65 "................................",
66 "................................"};
67
68 QPixmap zoomPix(imageZoomCursor);
69 QCursor zoom2Cursor(zoomPix);
70
71 #if QT_VERSION >= 0x030005
72 QCursor pan2Cursor(Qt::SizeAllCursor);
73 #else
74 QCursor pan2Cursor(SizeAllCursor);
75 #endif
76
77 SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGUI_Main* theMain):
78   QCanvasView(theCanvas, theMain),
79   myMain(theMain), myCurrentItem(0), myHilighted(0), myLinkBuilder(0)
80 {
81   setName("CanvasView");
82
83   myIsPanBtnClicked = false;
84   myIsPanActivated = false;
85   myIsZoomActivated = false;
86   myIsLinkCreating = false;
87
88   myAddStudyItem = 0;
89   myCursor = cursor();
90
91   myTimer = new QTimer(this);
92   connect(myTimer, SIGNAL(timeout()), this, SLOT(onTimeout()));
93
94   myPopup = new QPopupMenu(viewport());
95
96   const bool isEdit = myMain->isEditable();
97   if (isEdit) {
98     myPopup->insertItem(tr("MSG_ADD_NODE"), myMain, SLOT(addNode()));
99     myPopup->insertItem(tr("MSG_INS_FILE"), myMain, SLOT(insertFile()));
100     myPopup->insertSeparator();
101   }
102
103   QPopupMenu* aViewPopup = new QPopupMenu(viewport());
104   aViewPopup->insertItem(tr("POP_FULLVIEW"), myMain, SLOT(showCanvas()));
105   aViewPopup->insertItem(tr("POP_CONTROLVIEW"), myMain, SLOT(showContolFlow()));
106   aViewPopup->insertItem(tr("POP_TABLEVIEW"), myMain, SLOT(showCanvasTable()));
107
108   myPopup->insertItem(tr("POP_VIEW"), aViewPopup);
109   myPopup->insertSeparator();
110
111   QPopupMenu* aZoomPopup = new QPopupMenu(viewport());
112   aZoomPopup->insertItem("200%", this, SLOT(zoomIn()));
113   aZoomPopup->insertItem("100%", this, SLOT(zoomReset()));
114   aZoomPopup->insertItem("50%", this, SLOT(zoomOut()));
115   aZoomPopup->insertSeparator();
116   aZoomPopup->insertItem("Fit All", this, SLOT(fitAll()));
117
118   myPopup->insertItem("Zoom", aZoomPopup);
119   myPopup->insertSeparator();
120
121   myAddStudyItem = myPopup->insertItem(tr("MSG_ADD_STUDY"), this, SLOT(addToStudy()));
122   myPopup->insertItem(tr(isEdit ? "MSG_CHANGE_INFO" : "MSG_INFO"), myMain, SLOT(changeInformation()));
123   myPopup->insertSeparator();
124
125   myPopup->insertItem(tr("MSG_COPY_DATAFLOW"), myMain, SLOT(copy()));
126   myPopup->insertItem(tr("MSG_FILTER_NOTIFY"), myMain, SLOT(filterNotification()));
127
128   myPopup->insertSeparator();
129   myPopup->insertItem(tr("MSG_CHANGE_BACKGROUND"), this, SLOT(changeBackground()));
130
131   viewport()->setMouseTracking(true);
132
133   //create sketching popup menu
134   mySketchPopup = new QPopupMenu(viewport());
135   mySketchPopup->setCheckable(true);
136   myDelPntItem = mySketchPopup->insertItem(tr("MSG_DEL_LAST_PNT"), this, SLOT(deletePoint()));
137   mySketchPopup->insertItem(tr("MSG_DEL_LINK"), this, SLOT(cancelSketch()));
138   myOrtoItem = mySketchPopup->insertItem(tr("MSG_ORTHO_LINE"), this, SLOT(setOrthoMode()));
139 }
140  
141
142 SUPERVGUI_CanvasView::~SUPERVGUI_CanvasView()
143 {
144 }
145
146 void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent) 
147 {
148   //  MESSAGE("===> SUPERVGUI_CanvasView::contentsMousePressEvent(...) ");
149   myPoint = inverseWorldMatrix().map(theEvent->pos());
150   myGlobalPoint = theEvent->globalPos();
151   myCurrentItem = 0;
152
153   // compute collision rectangle
154   QRect aSel(myPoint.x()-MARGIN, myPoint.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
155
156   if (((theEvent->button() == Qt::MidButton) &&
157        (theEvent->state() == Qt::ControlButton)) || 
158       myIsPanBtnClicked) {
159     myIsPanActivated = true;
160     myCursor = cursor();
161     setCursor(pan2Cursor);
162     return;
163   }
164
165   if (((theEvent->button() == Qt::LeftButton) &&
166        (theEvent->state() == Qt::ControlButton)) || 
167       myIsZoomActivated) {
168     myIsZoomActivated = true;
169     myCursor = cursor();
170     setCursor(zoom2Cursor);
171     return;
172   }
173
174   if ( theEvent->button() == Qt::RightButton) {
175     if (myIsLinkCreating) {
176       myMain->showPopup(mySketchPopup, theEvent);
177       return;
178     }
179
180     QCanvasItemList l = canvas()->collisions(aSel);
181     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
182       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
183         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
184         QObject* anObj = aNodePrs->getObject(myPoint);
185         if (anObj->inherits("SUPERVGUI_CanvasNode")) {
186           myMain->showPopup(((SUPERVGUI_CanvasNode*)anObj)->getPopupMenu(viewport()), 
187                             theEvent);
188           return;
189         }
190         else if (anObj->inherits("SUPERVGUI_CanvasPort")) {
191           myMain->showPopup(((SUPERVGUI_CanvasPort*)anObj)->getPopupMenu(viewport()), 
192                             theEvent);
193           return;
194         }
195       }
196       if (myMain->isEditable() && !myMain->getCanvas()->isControlView()) {
197         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
198           SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
199           aPrs->getLink()->setSelectedObject(aPrs, myPoint);
200           myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
201           return;
202         }
203         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
204           SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
205           aPrs->getLink()->setSelectedObject(aPrs, myPoint);
206           myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
207           return;
208         }
209       }
210     }
211         
212     myPopup->setItemEnabled(myAddStudyItem, !myMain->isFromStudy());
213     myMain->showPopup(myPopup, theEvent);
214     return;
215   }
216
217   if (theEvent->button() == Qt::LeftButton) {
218     QCanvasItemList l = canvas()->collisions(myPoint);
219     if (myIsLinkCreating) {
220       for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
221         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
222           SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
223           QObject* anObj = aNodePrs->getObject(myPoint);
224           if (anObj->inherits("SUPERVGUI_CanvasPort")) {
225             endSketch((SUPERVGUI_CanvasPort*)anObj);
226             return;
227           }
228           else {
229             myCurrentItem = *it;
230             ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
231             ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
232             return;
233           }
234         }
235         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Hook) {
236           SUPERVGUI_CanvasHookPrs* aHookPrs = (SUPERVGUI_CanvasHookPrs*) (*it);
237           QObject* anObj = aHookPrs->getObject();
238           if (anObj->inherits("SUPERVGUI_CanvasPort")) {
239             endSketch((SUPERVGUI_CanvasPort*)anObj);
240             return;
241           }
242         }
243       }
244       if (myLinkBuilder) {
245         myLinkBuilder->addNextPoint(myPoint, mySketchPopup->isItemChecked(myOrtoItem));
246         canvas()->update();
247         mySketchPopup->setItemEnabled(myDelPntItem, true);
248         return;
249       }
250     }
251
252 //  if (myMain->isEditable()) { // allow to move nodes and link point on imported graph
253       for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
254         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
255           myCurrentItem = *it;
256           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
257           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
258           return;
259         }
260         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
261           SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
262           if (aPrs->getIndex() > 0) {
263             myCurrentItem = *it;
264             aPrs->setMoving(true);
265             return;
266           }
267         }
268         if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
269           //mkr: for moving segment of link
270           SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
271           if (aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->startPoint()
272               ||
273               aPrs->getLink()->getInputPort()->getConnectionPoint() == aPrs->endPoint()
274               ||
275               aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->startPoint()
276               ||
277               aPrs->getLink()->getOutputPort()->getConnectionPoint() == aPrs->endPoint()) {
278             return;
279           }
280           myCurrentItem = *it;
281           aPrs->setMoving(true);
282           return;
283         }
284       }
285 //  }
286   }
287 }
288
289 bool busy = false;
290
291 void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent) 
292 {
293   if (busy) return;
294       
295   busy = true;
296   QPoint p = inverseWorldMatrix().map(theEvent->pos());
297   QPoint g = theEvent->globalPos();
298       
299   if (myTimer->isActive()) myTimer->stop();
300
301   if (myIsLinkCreating && myLinkBuilder) {
302     myLinkBuilder->setFloatPoint(p);
303     canvas()->update();
304   }
305       
306   if (myCurrentItem) {
307     //    setHilighted(0);
308     if (myCurrentItem->x() && myCurrentItem->y()) {
309       double cx = myCurrentItem->x() - myPoint.x();
310       double cy = myCurrentItem->y() - myPoint.y();
311       
312       if (p.x()+cx < 0) p.setX(-(int)cx);
313       if (p.y()+cy < 0) p.setY(-(int)cy);
314     }
315     myCurrentItem->moveBy(p.x() - myPoint.x(), 
316                           p.y() - myPoint.y());
317     myPoint = p;
318     canvas()->update();
319         
320     // scroll contents if mouse is outside
321     QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
322     if (!r.contains(theEvent->pos())) {
323       int dx = 0, dy = 0;
324       if (theEvent->pos().x() < r.left()) dx = theEvent->pos().x() - r.left();
325       if (theEvent->pos().x() > r.right()) dx = theEvent->pos().x() - r.right();
326       if (theEvent->pos().y() < r.top()) dy = theEvent->pos().y() - r.top();
327       if (theEvent->pos().y() > r.bottom()) dy = theEvent->pos().y() - r.bottom();
328       scrollBy(dx, dy);
329       // start timer to scroll in silent mode
330       myDX = dx; myDY = dy;
331       myTimer->start(100);
332     }
333     busy = false;
334     return;
335   }
336
337   if (myIsPanActivated) {
338     setHilighted(0);
339     scrollBy(myGlobalPoint.x() - g.x(),
340              myGlobalPoint.y() - g.y());
341     myGlobalPoint = g;
342     busy = false;
343     return;
344   }
345       
346   if (myIsZoomActivated) {
347     setHilighted(0);
348     double dx = g.x() - myGlobalPoint.x();
349     double s = 1. + fabs(dx)/10.;
350     if (dx < 0) s = 1./s;
351     
352     QWMatrix m = worldMatrix();
353     m.scale(s, s);
354     setWorldMatrix(m);
355         
356     myGlobalPoint = g;
357     busy = false;
358     return;
359   }
360
361   if (!myIsLinkCreating && myMain->isEditable() &&
362       !myMain->getCanvas()->isControlView()) {
363     // compute collision rectangle
364     QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
365     QCanvasItemList l = canvas()->collisions(aSel);
366     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
367       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
368         SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
369         setHilighted(aPrs->getLink());
370         busy = false;
371         return;
372       }
373       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
374         SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
375         setHilighted(aPrs->getLink());
376         busy = false;
377         return;
378       }
379     }
380     setHilighted(0);
381   }
382
383   busy = false;
384 }
385
386 void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent) 
387 {
388   //  MESSAGE("===> SUPERVGUI_CanvasView::contentsMouseReleaseEvent(...) ");
389   if (myTimer->isActive()) myTimer->stop();
390
391   if (myCurrentItem) {
392     if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
393       ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(0);
394       ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(false);
395       canvas()->update();
396     }
397     if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
398       ((SUPERVGUI_CanvasPointPrs*)myCurrentItem)->setMoving(false);
399     }
400   }
401   myCurrentItem = 0;
402
403   if (myIsPanActivated) {
404     myIsPanActivated = false;
405     myIsPanBtnClicked = false;
406     setCursor(myCursor);
407   }
408
409   if (myIsZoomActivated) {
410     myIsZoomActivated = false;
411     setCursor(myCursor);
412   }
413 }
414
415 void SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* theEvent)
416 {
417   //  MESSAGE("===> SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(...) ");
418   QPoint p = inverseWorldMatrix().map(theEvent->pos());
419
420   // compute collision rectangle
421   QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
422
423   if (theEvent->button() == Qt::LeftButton) {
424     QCanvasItemList l = canvas()->collisions(p);
425     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
426       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
427         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
428         SUPERVGUI_CanvasNode* aNode = aNodePrs->getNode();
429         if (aNode->getEngine()->IsMacro() && !myIsLinkCreating) {
430           myMain->openSubGraph(aNode->getEngine(), true);
431           return;
432         }
433       }
434     }
435   }
436 }
437
438 void SUPERVGUI_CanvasView::onDestroyed(QObject* theObject)
439 {
440   if (theObject == myHilighted)
441     myHilighted = 0;
442 }
443
444 void SUPERVGUI_CanvasView::setHilighted(SUPERVGUI_CanvasLink* theLink)
445 {
446   if (theLink == myHilighted) return;
447   if (myHilighted) {
448     disconnect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
449     myHilighted->setHilighted(false);
450     myHilighted = 0;
451   }
452   if (theLink) {
453     myHilighted = theLink;
454     myHilighted->setHilighted(true);
455     connect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
456   }
457 }
458
459 void SUPERVGUI_CanvasView::onTimeout() 
460 {
461   if (myCurrentItem) {
462     scrollBy(myDX, myDY);
463
464     double cx, cy;
465     inverseWorldMatrix().map((double)myDX, (double)myDY, &cx, &cy);
466     if (myCurrentItem->x()+cx < 0) cx = -myCurrentItem->x();
467     if (myCurrentItem->y()+cy < 0) cy = -myCurrentItem->y();
468     myCurrentItem->moveBy(cx, cy);
469     myPoint.setX(myPoint.x()+(int)cx);
470     myPoint.setY(myPoint.y()+(int)cy);
471     canvas()->update();
472   }
473 }
474
475 void SUPERVGUI_CanvasView::changeBackground()
476 {
477   QColor aColor = QColorDialog::getColor(canvas()->backgroundColor(), this );
478   if ( aColor.isValid() ) {
479     canvas()->setBackgroundColor(aColor);
480     setPaletteBackgroundColor(aColor.light(120));
481   }
482 }
483
484 void SUPERVGUI_CanvasView::ActivatePanning()
485 {
486   myIsPanBtnClicked = true;
487 }
488
489 void SUPERVGUI_CanvasView::ResetView()
490 {
491   setContentsPos(0,0);
492   QWMatrix m;
493   setWorldMatrix(m);
494 }
495
496 void SUPERVGUI_CanvasView::startSketch(SUPERVGUI_CanvasPort* thePort)
497 {
498   if (myIsLinkCreating) return;
499
500   myIsLinkCreating = true;
501   myLinkBuilder = new SUPERVGUI_CanvasLinkBuilder(canvas(), myMain, thePort);
502   mySketchPopup->setItemEnabled(myDelPntItem, false);
503 }
504
505 void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
506 {
507   //  MESSAGE("===> SUPERVGUI_CanvasView::endSketch(" << thePort->name() << ")");
508   if (!myIsLinkCreating) return;
509
510   if (myLinkBuilder && myLinkBuilder->canCreateEngine(thePort)) {
511     bool input = thePort->getEngine()->IsInput();
512     SUPERV_Link aLinkEngine;
513     if (thePort->getEngine()->Kind() == SUPERV::DataStreamParameter) {
514       SUPERVGUI_CanvasStreamPortIn* aInPort = (SUPERVGUI_CanvasStreamPortIn*) 
515         (input ? thePort : myLinkBuilder->getStartPort());
516       SUPERVGUI_CanvasStreamPortOut* aOutPort = (SUPERVGUI_CanvasStreamPortOut*) 
517         (input ? myLinkBuilder->getStartPort() : thePort);
518 //       aLinkEngine = myMain->getDataflow()->StreamLink(aOutPort->getStreamEngine(), 
519 //                                                    aInPort->getStreamEngine());
520       if (myMain->getDataflow()->IsStreamGraph()) {
521         SUPERV_StreamGraph aSGraph = myMain->getDataflow()->ToStreamGraph();
522         if (!SUPERV_isNull(aSGraph))
523           aLinkEngine = aSGraph->StreamLink(aOutPort->getStreamEngine(), 
524                                             aInPort->getStreamEngine());
525       }
526     }
527     else {
528       SUPERVGUI_CanvasPort* aInPort = (input ? thePort : myLinkBuilder->getStartPort());
529       SUPERVGUI_CanvasPort* aOutPort = (input ? myLinkBuilder->getStartPort() : thePort);
530       aLinkEngine = myMain->getDataflow()->Link(aOutPort->getEngine(), aInPort->getEngine());
531     }
532     if (SUPERV_isNull(aLinkEngine)) 
533       return;    
534
535     myLinkBuilder->setCoords(aLinkEngine.in());
536
537     delete myLinkBuilder;
538     myLinkBuilder = 0;
539
540     SUPERVGUI_CanvasLink* aLink = new SUPERVGUI_CanvasLink(canvas(), myMain, aLinkEngine);
541     aLink->show();
542
543     canvas()->update();
544     myIsLinkCreating = false;
545
546     // asv : 13.12.04 : introducing a check for ports' types compatibility (Bugs and Improvements p.1.16, PAL7380)
547     if ( !aLinkEngine->IsValid() ) { 
548       const int id = QAD_MessageBox::warn2( this, tr( "TLT_INVALID_LINK" ), tr( "MSG_INVALID_LINK" ), 
549                                            tr( "Keep" ), tr( "Remove" ), 0, 1, 0 );
550       if ( id == 1 ) { // Remove selected
551         aLink->remove(); // it did not live long...
552       }
553     }
554   }
555 }
556
557 void SUPERVGUI_CanvasView::cancelSketch()
558 {
559   if (myLinkBuilder) {
560     delete myLinkBuilder;
561     myLinkBuilder = 0;
562     canvas()->update();
563   }
564   myIsLinkCreating = false;
565 }
566
567 void SUPERVGUI_CanvasView::deletePoint()
568 {
569   if (myIsLinkCreating && myLinkBuilder) {
570     myLinkBuilder->removeLastPoint();
571     canvas()->update();
572     mySketchPopup->setItemEnabled(myDelPntItem, myLinkBuilder->getPointCount());
573   }
574 }
575
576 void SUPERVGUI_CanvasView::setOrthoMode()
577 {
578   bool aIsOrtho = !mySketchPopup->isItemChecked(myOrtoItem);
579   mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
580 }
581
582
583 void SUPERVGUI_CanvasView::addToStudy() 
584 {
585   if (myMain->addStudy()) myMain->setAsFromStudy(true);
586 }
587
588 void SUPERVGUI_CanvasView::zoomIn() 
589 {
590   QWMatrix m;
591   m.scale(2.0, 2.0);
592   setWorldMatrix(m);
593   canvas()->update();
594 }
595
596 void SUPERVGUI_CanvasView::zoomReset() 
597 {
598   QWMatrix m;
599   m.scale(1.0, 1.0);
600   setWorldMatrix(m);
601   canvas()->update();
602 }
603
604 void SUPERVGUI_CanvasView::zoomOut() 
605 {
606   QWMatrix m;
607   m.scale(0.5, 0.5);
608   setWorldMatrix(m);
609   canvas()->update();
610 }
611
612 void SUPERVGUI_CanvasView::fitAll() 
613 {
614   int w = 0, h = 0;
615   QCanvasItemList l = canvas()->allItems();
616   for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
617     QRect r = (*it)->boundingRect();
618     if (w < r.right()) w = r.right();
619     if (h < r.bottom()) h = r.bottom();
620   }
621   w += GRAPH_MARGIN; h += GRAPH_MARGIN;
622   double s = ((double)visibleWidth())/((double)w);
623   double s1 = ((double)visibleHeight())/((double)h);
624   if (s > s1) s = s1;
625
626   setContentsPos(0,0);
627   QWMatrix m;
628   m.scale(s, s);
629   setWorldMatrix(m);
630   canvas()->update();
631 }