]> SALOME platform Git repositories - modules/superv.git/blobdiff - src/SUPERVGUI/SUPERVGUI_CanvasView.cxx
Salome HOME
DCQ:prepare 2.0.0
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasView.cxx
diff --git a/src/SUPERVGUI/SUPERVGUI_CanvasView.cxx b/src/SUPERVGUI/SUPERVGUI_CanvasView.cxx
new file mode 100644 (file)
index 0000000..2f6f04e
--- /dev/null
@@ -0,0 +1,599 @@
+//  SUPERV SUPERVGUI : GUI for Supervisor component
+//
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : SUPERVGUI_CanvasView.cxx
+//  Author : Natalia KOPNOVA
+//  Module : SUPERV
+
+using namespace std;
+#include "SUPERVGUI_CanvasView.h"
+#include "SUPERVGUI_Main.h"
+#include "SUPERVGUI_CanvasNode.h"
+#include "SUPERVGUI_CanvasPort.h"
+#include "SUPERVGUI_CanvasLink.h"
+#include "SUPERVGUI_CanvasNodePrs.h"
+#include "QAD_Config.h"
+
+#include <qpixmap.h>
+#include <qcolordialog.h>
+
+#define MARGIN 2
+
+
+/* XPM */
+const char* imageZoomCursor[] = { 
+"32 32 3 1",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"................................",
+"................................",
+".#######........................",
+"..aaaaaaa.......................",
+"................................",
+".............#####..............",
+"...........##.aaaa##............",
+"..........#.aa.....a#...........",
+".........#.a.........#..........",
+".........#a..........#a.........",
+"........#.a...........#.........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+"........#a............#a........",
+".........#...........#.a........",
+".........#a..........#a.........",
+".........##.........#.a.........",
+"........#####.....##.a..........",
+".......###aaa#####.aa...........",
+"......###aa...aaaaa.......#.....",
+".....###aa................#a....",
+"....###aa.................#a....",
+"...###aa...............#######..",
+"....#aa.................aa#aaaa.",
+".....a....................#a....",
+"..........................#a....",
+"...........................a....",
+"................................",
+"................................",
+"................................",
+"................................"};
+
+QPixmap zoomPix(imageZoomCursor);
+QCursor zoom2Cursor(zoomPix);
+
+#if QT_VERSION >= 0x030005
+QCursor pan2Cursor(Qt::SizeAllCursor);
+#else
+QCursor pan2Cursor(SizeAllCursor);
+#endif
+
+SUPERVGUI_CanvasView::SUPERVGUI_CanvasView(SUPERVGUI_Canvas* theCanvas, SUPERVGUI_Main* theMain):
+  QCanvasView(theCanvas, theMain),
+  myMain(theMain), myCurrentItem(0), myHilighted(0), myLinkBuilder(0)
+{
+  setName("CanvasView");
+
+  myIsPanActivated = false;
+  myIsZoomActivated = false;
+  myIsLinkCreating = false;
+
+  myAddStudyItem = 0;
+  myCursor = cursor();
+
+  myTimer = new QTimer(this);
+  connect(myTimer, SIGNAL(timeout()), this, SLOT(onTimeout()));
+
+  myPopup = new QPopupMenu(viewport());
+
+  if (myMain->isEditable()) {
+    myPopup->insertItem(tr("MSG_ADD_NODE"), myMain, SLOT(addNode()));
+    myPopup->insertItem(tr("MSG_INS_FILE"), myMain, SLOT(insertFile()));
+    myPopup->insertSeparator();
+  }
+
+  QPopupMenu* aViewPopup = new QPopupMenu(viewport());
+  //  aViewPopup->insertItem(tr("POP_FULLVIEW"), myMain, SLOT(showFullGraph()));
+  aViewPopup->insertItem(tr("POP_FULLVIEW"), myMain, SLOT(showCanvas()));
+  aViewPopup->insertItem(tr("POP_CONTROLVIEW"), myMain, SLOT(showContolFlow()));
+  aViewPopup->insertItem(tr("POP_TABLEVIEW"), myMain, SLOT(showTable()));
+  //  aViewPopup->insertItem("Previous Full View", myMain, SLOT(showFullGraph()));
+  //  aViewPopup->insertItem(tr("POP_CANVASVIEW"), myMain, SLOT(showCanvas()));
+
+  myPopup->insertItem(tr("POP_VIEW"), aViewPopup);
+  myPopup->insertSeparator();
+
+  QPopupMenu* aZoomPopup = new QPopupMenu(viewport());
+  aZoomPopup->insertItem("200%", this, SLOT(zoomIn()));
+  aZoomPopup->insertItem("100%", this, SLOT(zoomReset()));
+  aZoomPopup->insertItem("50%", this, SLOT(zoomOut()));
+  aZoomPopup->insertSeparator();
+  aZoomPopup->insertItem("Fit All", this, SLOT(fitAll()));
+
+  myPopup->insertItem("Zoom", aZoomPopup);
+  myPopup->insertSeparator();
+
+  myAddStudyItem = myPopup->insertItem(tr("MSG_ADD_STUDY"), this, SLOT(addToStudy()));
+  myPopup->insertItem(tr("MSG_CHANGE_INFO"), myMain, SLOT(changeInformation()));
+  myPopup->insertSeparator();
+
+  myPopup->insertItem(tr("MSG_COPY_DATAFLOW"), myMain, SLOT(copy()));
+  myPopup->insertItem(tr("MSG_FILTER_NOTIFY"), myMain, SLOT(filterNotification()));
+
+  myPopup->insertSeparator();
+  myPopup->insertItem(tr("MSG_CHANGE_BACKGROUND"), this, SLOT(changeBackground()));
+
+  viewport()->setMouseTracking(true);
+
+  //create sketching popup menu
+  mySketchPopup = new QPopupMenu(viewport());
+  mySketchPopup->setCheckable(true);
+  myDelPntItem = mySketchPopup->insertItem(tr("MSG_DEL_LAST_PNT"), this, SLOT(deletePoint()));
+  mySketchPopup->insertItem(tr("MSG_DEL_LINK"), this, SLOT(cancelSketch()));
+  myOrtoItem = mySketchPopup->insertItem(tr("MSG_ORTHO_LINE"), this, SLOT(setOrthoMode()));
+}
+
+SUPERVGUI_CanvasView::~SUPERVGUI_CanvasView()
+{
+}
+
+void SUPERVGUI_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent) 
+{
+  //  cout << "===> SUPERVGUI_CanvasView::contentsMousePressEvent(...) "   << endl;
+  myPoint = inverseWorldMatrix().map(theEvent->pos());
+  myGlobalPoint = theEvent->globalPos();
+  myCurrentItem = 0;
+
+  // compute collision rectangle
+  QRect aSel(myPoint.x()-MARGIN, myPoint.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
+
+  if (((theEvent->button() == Qt::MidButton) &&
+       (theEvent->state() == Qt::ControlButton)) || 
+      myIsPanActivated) {
+    myIsPanActivated = true;
+    myCursor = cursor();
+    setCursor(pan2Cursor);
+    return;
+  }
+
+  if (((theEvent->button() == Qt::LeftButton) &&
+       (theEvent->state() == Qt::ControlButton)) || 
+      myIsZoomActivated) {
+    myIsZoomActivated = true;
+    myCursor = cursor();
+    setCursor(zoom2Cursor);
+    return;
+  }
+
+  if ( theEvent->button() == Qt::RightButton) {
+    if (myIsLinkCreating) {
+      myMain->showPopup(mySketchPopup, theEvent);
+      return;
+    }
+
+    QCanvasItemList l = canvas()->collisions(aSel);
+    for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+      if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
+       SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
+       QObject* anObj = aNodePrs->getObject(myPoint);
+       if (anObj->inherits("SUPERVGUI_CanvasNode")) {
+         myMain->showPopup(((SUPERVGUI_CanvasNode*)anObj)->getPopupMenu(viewport()), 
+                           theEvent);
+         return;
+       }
+       else if (anObj->inherits("SUPERVGUI_CanvasPort")) {
+         myMain->showPopup(((SUPERVGUI_CanvasPort*)anObj)->getPopupMenu(viewport()), 
+                           theEvent);
+         return;
+       }
+      }
+      if (myMain->isEditable() && !myMain->getCanvas()->isControlView()) {
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
+         SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
+         aPrs->getLink()->setSelectedObject(aPrs, myPoint);
+         myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
+         return;
+       }
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
+         SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
+         aPrs->getLink()->setSelectedObject(aPrs, myPoint);
+         myMain->showPopup(aPrs->getLink()->getPopupMenu(viewport()), theEvent);
+         return;
+       }
+      }
+    }
+       
+    myPopup->setItemEnabled(myAddStudyItem, !myMain->isFromStudy());
+    myMain->showPopup(myPopup, theEvent);
+    return;
+  }
+
+  if (theEvent->button() == Qt::LeftButton) {
+    QCanvasItemList l = canvas()->collisions(myPoint);
+    if (myIsLinkCreating) {
+      for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
+         SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
+         QObject* anObj = aNodePrs->getObject(myPoint);
+         if (anObj->inherits("SUPERVGUI_CanvasPort")) {
+           endSketch((SUPERVGUI_CanvasPort*)anObj);
+           return;
+         }
+         else {
+           myCurrentItem = *it;
+           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
+           ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
+           return;
+         }
+       }
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Hook) {
+         SUPERVGUI_CanvasHookPrs* aHookPrs = (SUPERVGUI_CanvasHookPrs*) (*it);
+         QObject* anObj = aHookPrs->getObject();
+         if (anObj->inherits("SUPERVGUI_CanvasPort")) {
+           endSketch((SUPERVGUI_CanvasPort*)anObj);
+           return;
+         }
+       }
+      }
+      if (myLinkBuilder) {
+       myLinkBuilder->addNextPoint(myPoint, mySketchPopup->isItemChecked(myOrtoItem));
+       canvas()->update();
+       mySketchPopup->setItemEnabled(myDelPntItem, true);
+       return;
+      }
+    }
+
+//  if (myMain->isEditable()) { // allow to move nodes and link point on imported graph
+      for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
+         myCurrentItem = *it;
+         ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(2);
+         ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(true);
+         return;
+       }
+       if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
+         SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
+         if (aPrs->getIndex() > 0) {
+           myCurrentItem = *it;
+           aPrs->setMoving(true);
+           return;
+         }
+       }
+      }
+//  }
+  }
+}
+
+bool busy = false;
+
+void SUPERVGUI_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent) 
+{
+  if (busy) return;
+      
+  busy = true;
+  QPoint p = inverseWorldMatrix().map(theEvent->pos());
+  QPoint g = theEvent->globalPos();
+      
+  if (myTimer->isActive()) myTimer->stop();
+
+  if (myIsLinkCreating && myLinkBuilder) {
+    myLinkBuilder->setFloatPoint(p);
+    canvas()->update();
+  }
+      
+  if (myCurrentItem) {
+    //    setHilighted(0);
+    double cx = myCurrentItem->x() - myPoint.x();
+    double cy = myCurrentItem->y() - myPoint.y();
+    if (p.x()+cx < 0) p.setX(-(int)cx);
+    if (p.y()+cy < 0) p.setY(-(int)cy);
+    myCurrentItem->moveBy(p.x() - myPoint.x(), 
+                         p.y() - myPoint.y());
+    myPoint = p;
+    canvas()->update();
+       
+    // scroll contents if mouse is outside
+    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
+    if (!r.contains(theEvent->pos())) {
+      int dx = 0, dy = 0;
+      if (theEvent->pos().x() < r.left()) dx = theEvent->pos().x() - r.left();
+      if (theEvent->pos().x() > r.right()) dx = theEvent->pos().x() - r.right();
+      if (theEvent->pos().y() < r.top()) dy = theEvent->pos().y() - r.top();
+      if (theEvent->pos().y() > r.bottom()) dy = theEvent->pos().y() - r.bottom();
+      scrollBy(dx, dy);
+      // start timer to scroll in silent mode
+      myDX = dx; myDY = dy;
+      myTimer->start(100);
+    }
+    busy = false;
+    return;
+  }
+
+  if (myIsPanActivated) {
+    setHilighted(0);
+    scrollBy(myGlobalPoint.x() - g.x(),
+            myGlobalPoint.y() - g.y());
+    myGlobalPoint = g;
+    busy = false;
+    return;
+  }
+      
+  if (myIsZoomActivated) {
+    setHilighted(0);
+    double dx = g.x() - myGlobalPoint.x();
+    double s = 1. + fabs(dx)/10.;
+    if (dx < 0) s = 1./s;
+    
+    QWMatrix m = worldMatrix();
+    m.scale(s, s);
+    setWorldMatrix(m);
+       
+    myGlobalPoint = g;
+    busy = false;
+    return;
+  }
+
+  if (!myIsLinkCreating && myMain->isEditable() &&
+      !myMain->getCanvas()->isControlView()) {
+    // compute collision rectangle
+    QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
+    QCanvasItemList l = canvas()->collisions(aSel);
+    for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+      if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
+       SUPERVGUI_CanvasPointPrs* aPrs = (SUPERVGUI_CanvasPointPrs*) (*it);
+       setHilighted(aPrs->getLink());
+       busy = false;
+       return;
+      }
+      if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_LinkEdge) {
+       SUPERVGUI_CanvasEdgePrs* aPrs = (SUPERVGUI_CanvasEdgePrs*) (*it);
+       setHilighted(aPrs->getLink());
+       busy = false;
+       return;
+      }
+    }
+    setHilighted(0);
+  }
+
+  busy = false;
+}
+
+void SUPERVGUI_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent) 
+{
+  //  cout << "===> SUPERVGUI_CanvasView::contentsMouseReleaseEvent(...) "   << endl;
+  if (myTimer->isActive()) myTimer->stop();
+
+  if (myCurrentItem) {
+    if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
+      ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setZ(0);
+      ((SUPERVGUI_CanvasNodePrs*)myCurrentItem)->setMoving(false);
+      canvas()->update();
+    }
+    if (myCurrentItem->rtti() == SUPERVGUI_Canvas::Rtti_LinkPoint) {
+      ((SUPERVGUI_CanvasPointPrs*)myCurrentItem)->setMoving(false);
+    }
+  }
+  myCurrentItem = 0;
+
+  if (myIsPanActivated) {
+    myIsPanActivated = false;
+    setCursor(myCursor);
+  }
+
+  if (myIsZoomActivated) {
+    myIsZoomActivated = false;
+    setCursor(myCursor);
+  }
+}
+
+void SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* theEvent)
+{
+  //  cout << "===> SUPERVGUI_CanvasView::contentsMouseDoubleClickEvent(...) "   << endl;
+  QPoint p = inverseWorldMatrix().map(theEvent->pos());
+
+  // compute collision rectangle
+  QRect aSel(p.x()-MARGIN, p.y()-MARGIN, 1+2*MARGIN, 1+2*MARGIN);
+
+  if (theEvent->button() == Qt::LeftButton) {
+    QCanvasItemList l = canvas()->collisions(p);
+    for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+      if ((*it)->rtti() == SUPERVGUI_Canvas::Rtti_Node) {
+       SUPERVGUI_CanvasNodePrs* aNodePrs = (SUPERVGUI_CanvasNodePrs*) (*it);
+       SUPERVGUI_CanvasNode* aNode = aNodePrs->getNode();
+       if (aNode->getEngine()->IsMacro() && !myIsLinkCreating) {
+         myMain->openSubGraph(aNode->getEngine(), true);
+         return;
+       }
+      }
+    }
+  }
+}
+
+void SUPERVGUI_CanvasView::onDestroyed(QObject* theObject)
+{
+  if (theObject == myHilighted)
+    myHilighted = 0;
+}
+
+void SUPERVGUI_CanvasView::setHilighted(SUPERVGUI_CanvasLink* theLink)
+{
+  if (theLink == myHilighted) return;
+  if (myHilighted) {
+    disconnect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
+    myHilighted->setHilighted(false);
+    myHilighted = 0;
+  }
+  if (theLink) {
+    myHilighted = theLink;
+    myHilighted->setHilighted(true);
+    connect(myHilighted, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
+  }
+}
+
+void SUPERVGUI_CanvasView::onTimeout() 
+{
+  if (myCurrentItem) {
+    scrollBy(myDX, myDY);
+
+    double cx, cy;
+    inverseWorldMatrix().map((double)myDX, (double)myDY, &cx, &cy);
+    if (myCurrentItem->x()+cx < 0) cx = -myCurrentItem->x();
+    if (myCurrentItem->y()+cy < 0) cy = -myCurrentItem->y();
+    myCurrentItem->moveBy(cx, cy);
+    myPoint.setX(myPoint.x()+(int)cx);
+    myPoint.setY(myPoint.y()+(int)cy);
+    canvas()->update();
+  }
+}
+
+void SUPERVGUI_CanvasView::changeBackground()
+{
+  QColor aColor = QColorDialog::getColor(canvas()->backgroundColor(), this );
+  if ( aColor.isValid() ) {
+    canvas()->setBackgroundColor(aColor);
+    setPaletteBackgroundColor(aColor.light(120));
+  }
+}
+
+void SUPERVGUI_CanvasView::ActivatePanning()
+{
+  myIsPanActivated = true;
+}
+
+void SUPERVGUI_CanvasView::ResetView()
+{
+  setContentsPos(0,0);
+  QWMatrix m;
+  setWorldMatrix(m);
+}
+
+void SUPERVGUI_CanvasView::startSketch(SUPERVGUI_CanvasPort* thePort)
+{
+  if (myIsLinkCreating) return;
+
+  myIsLinkCreating = true;
+  myLinkBuilder = new SUPERVGUI_CanvasLinkBuilder(canvas(), myMain, thePort);
+  mySketchPopup->setItemEnabled(myDelPntItem, false);
+}
+
+void SUPERVGUI_CanvasView::endSketch(SUPERVGUI_CanvasPort* thePort)
+{
+  //  cout << "===> SUPERVGUI_CanvasView::endSketch(" << thePort->name() << ")"  << endl;
+  if (!myIsLinkCreating) return;
+
+  if (myLinkBuilder && myLinkBuilder->canCreateEngine(thePort)) {
+    bool input = thePort->getEngine()->IsInput();
+    SUPERV_Link aLinkEngine;
+    if (thePort->getEngine()->Kind() == SUPERV::DataStreamParameter) {
+      SUPERVGUI_CanvasStreamPortIn* aInPort = (SUPERVGUI_CanvasStreamPortIn*) 
+       (input ? thePort : myLinkBuilder->getStartPort());
+      SUPERVGUI_CanvasStreamPortOut* aOutPort = (SUPERVGUI_CanvasStreamPortOut*) 
+       (input ? myLinkBuilder->getStartPort() : thePort);
+//       aLinkEngine = myMain->getDataflow()->StreamLink(aOutPort->getStreamEngine(), 
+//                                                   aInPort->getStreamEngine());
+      if (myMain->getDataflow()->IsStreamGraph()) {
+       SUPERV_StreamGraph aSGraph = myMain->getDataflow()->ToStreamGraph();
+       if (!SUPERV_isNull(aSGraph))
+         aLinkEngine = aSGraph->StreamLink(aOutPort->getStreamEngine(), 
+                                           aInPort->getStreamEngine());
+      }
+    }
+    else {
+      SUPERVGUI_CanvasPort* aInPort = (input ? thePort : myLinkBuilder->getStartPort());
+      SUPERVGUI_CanvasPort* aOutPort = (input ? myLinkBuilder->getStartPort() : thePort);
+      aLinkEngine = myMain->getDataflow()->Link(aOutPort->getEngine(), aInPort->getEngine());
+    }
+    if (SUPERV_isNull(aLinkEngine)) return;
+
+    myLinkBuilder->setCoords(aLinkEngine.in());
+
+    delete myLinkBuilder;
+    myLinkBuilder = 0;
+
+    SUPERVGUI_CanvasLink* aLink = new SUPERVGUI_CanvasLink(canvas(), myMain, aLinkEngine);
+    aLink->show();
+
+    canvas()->update();
+    myIsLinkCreating = false;
+  }
+}
+
+void SUPERVGUI_CanvasView::cancelSketch()
+{
+  if (myLinkBuilder) {
+    delete myLinkBuilder;
+    myLinkBuilder = 0;
+    canvas()->update();
+  }
+  myIsLinkCreating = false;
+}
+
+void SUPERVGUI_CanvasView::deletePoint()
+{
+  if (myIsLinkCreating && myLinkBuilder) {
+    myLinkBuilder->removeLastPoint();
+    canvas()->update();
+    mySketchPopup->setItemEnabled(myDelPntItem, myLinkBuilder->getPointCount());
+  }
+}
+
+void SUPERVGUI_CanvasView::setOrthoMode()
+{
+  bool aIsOrtho = !mySketchPopup->isItemChecked(myOrtoItem);
+  mySketchPopup->setItemChecked(myOrtoItem, aIsOrtho);
+}
+
+
+void SUPERVGUI_CanvasView::addToStudy() 
+{
+  if (myMain->addStudy()) myMain->setAsFromStudy(true);
+}
+
+void SUPERVGUI_CanvasView::zoomIn() 
+{
+  QWMatrix m;
+  m.scale(2.0, 2.0);
+  setWorldMatrix(m);
+  canvas()->update();
+}
+
+void SUPERVGUI_CanvasView::zoomReset() 
+{
+  QWMatrix m;
+  m.scale(1.0, 1.0);
+  setWorldMatrix(m);
+  canvas()->update();
+}
+
+void SUPERVGUI_CanvasView::zoomOut() 
+{
+  QWMatrix m;
+  m.scale(0.5, 0.5);
+  setWorldMatrix(m);
+  canvas()->update();
+}
+
+void SUPERVGUI_CanvasView::fitAll() 
+{
+  int w = 0, h = 0;
+  QCanvasItemList l = canvas()->allItems();
+  for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+    QRect r = (*it)->boundingRect();
+    if (w < r.right()) w = r.right();
+    if (h < r.bottom()) h = r.bottom();
+  }
+  w += GRAPH_MARGIN; h += GRAPH_MARGIN;
+  double s = ((double)visibleWidth())/((double)w);
+  double s1 = ((double)visibleHeight())/((double)h);
+  if (s > s1) s = s1;
+
+  setContentsPos(0,0);
+  QWMatrix m;
+  m.scale(s, s);
+  setWorldMatrix(m);
+  canvas()->update();
+}