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