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