]> SALOME platform Git repositories - modules/gui.git/blob - src/QxGraph/QxGraph_CanvasView.cxx
Salome HOME
e7f726b13c72f999398e13da96d7aaf0e916c3c4
[modules/gui.git] / src / QxGraph / QxGraph_CanvasView.cxx
1 //  SALOME QxGraph : build Supervisor viewer into desktop
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
23 #include "QxGraph_CanvasView.h"
24 #include "QxGraph_Canvas.h"
25 #include "QxGraph_ViewWindow.h"
26 #include "QxGraph_ActiveItem.h"
27 #include "QxGraph_Def.h"
28
29 #include <qwmatrix.h>
30 #include <math.h>
31
32 const char* imageZoomCursor[] = { 
33 "32 32 3 1",
34 ". c None",
35 "a c #000000",
36 "# c #ffffff",
37 "................................",
38 "................................",
39 ".#######........................",
40 "..aaaaaaa.......................",
41 "................................",
42 ".............#####..............",
43 "...........##.aaaa##............",
44 "..........#.aa.....a#...........",
45 ".........#.a.........#..........",
46 ".........#a..........#a.........",
47 "........#.a...........#.........",
48 "........#a............#a........",
49 "........#a............#a........",
50 "........#a............#a........",
51 "........#a............#a........",
52 ".........#...........#.a........",
53 ".........#a..........#a.........",
54 ".........##.........#.a.........",
55 "........#####.....##.a..........",
56 ".......###aaa#####.aa...........",
57 "......###aa...aaaaa.......#.....",
58 ".....###aa................#a....",
59 "....###aa.................#a....",
60 "...###aa...............#######..",
61 "....#aa.................aa#aaaa.",
62 ".....a....................#a....",
63 "..........................#a....",
64 "...........................a....",
65 "................................",
66 "................................",
67 "................................",
68 "................................"};
69
70 const char* imageCrossCursor[] = { 
71   "32 32 3 1",
72   ". c None",
73   "a c #000000",
74   "# c #ffffff",
75   "................................",
76   "................................",
77   "................................",
78   "................................",
79   "................................",
80   "................................",
81   "................................",
82   "...............#................",
83   "...............#a...............",
84   "...............#a...............",
85   "...............#a...............",
86   "...............#a...............",
87   "...............#a...............",
88   "...............#a...............",
89   "...............#a...............",
90   ".......#################........",
91   "........aaaaaaa#aaaaaaaaa.......",
92   "...............#a...............",
93   "...............#a...............",
94   "...............#a...............",
95   "...............#a...............",
96   "...............#a...............",
97   "...............#a...............",
98   "...............#a...............",
99   "................a...............",
100   "................................",
101   "................................",
102   "................................",
103   "................................",
104   "................................",
105   "................................",
106   "................................"};
107
108 /*!
109   Constructor
110 */
111 QxGraph_CanvasView::QxGraph_CanvasView(QxGraph_Canvas* theCanvas, QxGraph_ViewWindow* theViewWindow) :
112   QCanvasView(theCanvas, theViewWindow, 0, Qt::WRepaintNoErase),
113   myCurrentItem(0),
114   myHilightedItem(0),
115   mySelectedItem(0),
116   myMovingDone(false),
117   myCenter(0,0)
118 {
119   printf("Construct QxGraph_CanvasView\n");
120   setName("QxGraph_CanvasView");
121
122   myOperation = NOTHING;
123   myCursor = cursor();
124   mySelectedRect = 0;
125
126   myTimer = new QTimer(this);
127   connect(myTimer, SIGNAL(timeout()), this, SLOT(onTimeout()));
128
129   viewport()->setMouseTracking(true);
130 }
131
132 /*!
133   Destructor
134 */
135 QxGraph_CanvasView::~QxGraph_CanvasView()
136 {
137 }
138
139 void QxGraph_CanvasView::contentsMousePressEvent(QMouseEvent* theEvent)
140 {
141   myPoint = inverseWorldMatrix().map(theEvent->pos());
142   myGlobalPoint = theEvent->globalPos();
143   myCurrentItem = 0;
144
145   if ( theEvent->button() == Qt::MidButton && theEvent->state() == Qt::ControlButton
146        || 
147        myOperation == PANVIEW )
148   { // Panning
149     if ( myOperation != PANVIEW ) {
150       myOperation = PANVIEW;
151       myCursor = cursor(); // save old cursor
152       QCursor panCursor (Qt::SizeAllCursor);
153       setCursor(panCursor);
154     }
155     return;
156   }
157
158   if ( myOperation == PANGLOBAL )
159   { // Global panning
160     return;
161   }
162
163   if ( myOperation == WINDOWFIT )
164   { // Fit area
165     return;
166   }
167
168   if ( theEvent->button() == Qt::LeftButton && theEvent->state() == Qt::ControlButton
169        || 
170        myOperation == ZOOMVIEW )
171   { // Zoom
172     if ( myOperation != ZOOMVIEW ) {
173       myOperation = ZOOMVIEW;
174       myCursor = cursor(); // save old cursor
175       QPixmap zoomPixmap (imageZoomCursor);
176       QCursor zoomCursor (zoomPixmap);
177       setCursor(zoomCursor);
178
179       // the center of the view before zooming
180       int aXVCenter = viewport()->width()/2;
181       int aYVCenter = viewport()->height()/2;
182       myCenter = viewportToContents(QPoint(aXVCenter,aYVCenter));
183     }
184     return;
185   }
186
187   if ( theEvent->button() == Qt::LeftButton )
188   {
189     QCanvasItemList aList = canvas()->collisions(myPoint);
190     // to move items on canvas view
191     for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
192       QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
193       int aCursorType;
194       if ( anActItem && anActItem->isResizable(myPoint,aCursorType) )
195       { // resize itself only active items if it is resizable
196         anActItem->beforeResizing(aCursorType);
197         myCurrentItem = *it;
198         return;
199       }
200       else if ( anActItem && anActItem->isMoveable() )
201       { // move itself only active items if it is moveable
202         anActItem->beforeMoving();
203         myCurrentItem = *it;
204         return;
205       }
206     }
207   }
208 }
209
210 void QxGraph_CanvasView::contentsMouseMoveEvent(QMouseEvent* theEvent)
211 {
212   QPoint aPoint = inverseWorldMatrix().map(theEvent->pos());
213   QPoint aGlobalPoint = theEvent->globalPos();
214
215   if (myTimer->isActive()) myTimer->stop();
216
217   if ( myOperation == PANVIEW )
218   { // Panning
219     scrollBy(myGlobalPoint.x() - aGlobalPoint.x(),
220              myGlobalPoint.y() - aGlobalPoint.y());
221     myGlobalPoint = aGlobalPoint;
222     myMovingDone = true;
223     return;
224   }
225
226   if ( myOperation == WINDOWFIT )
227   { // Fit within rectangle
228     int aLX, aTY; //left x and top y
229     if (myPoint.x() < aPoint.x()) aLX = myPoint.x();
230     else aLX = aPoint.x();
231     if (myPoint.y() < aPoint.y()) aTY = myPoint.y();
232     else aTY = aPoint.y();
233     QRect aRect(aLX, aTY, abs(myPoint.x()-aPoint.x()), abs(myPoint.y()-aPoint.y()));
234     QCanvasRectangle* aRect1 = new QCanvasRectangle(aRect, canvas());
235
236     //hide old selected rectangle
237     if (mySelectedRect)
238       mySelectedRect->hide();
239     //draw new selected rectangle
240     QPen pen(Qt::black,1,Qt::SolidLine);
241     aRect1->setPen(pen);
242     aRect1->setZ(1E+6);
243     aRect1->show();
244
245     mySelectedRect = aRect1;
246     canvas()->update();
247
248     return;
249   }
250
251   if ( myOperation == ZOOMVIEW )
252   { // Zoom
253     QCanvasItemList aList = canvas()->allItems();
254     for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it)
255       (*it)->hide();
256
257     int aXContCenter = myCenter.x();
258     int aYContCenter = myCenter.y();
259     
260     QWMatrix m = worldMatrix();
261
262     double dx = aGlobalPoint.x() - myGlobalPoint.x();
263     double s = 1. + fabs(dx)*( (m.m11() < 1) ? m.m11() : 1. )/70.;
264     if (dx < 0) s = 1./s;
265     
266     int aXContCenterScaled = aXContCenter*s;
267     int aYContCenterScaled = aYContCenter*s;
268     
269     m.scale(s, s);
270     setWorldMatrix(m);
271
272     center(aXContCenterScaled,aYContCenterScaled);
273
274     myCenter.setX(aXContCenterScaled);
275     myCenter.setY(aYContCenterScaled);
276
277     // remember the canvas view's current transformation matrix in all canvas items
278     aList = canvas()->allItems();
279     for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
280       QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
281       if ( anActItem ) anActItem->setTMatrix(m);
282       (*it)->show();
283     }
284         
285     myGlobalPoint = aGlobalPoint;
286     myMovingDone = true;
287
288     return;
289   }
290
291   if ( myCurrentItem )
292   {
293     QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( myCurrentItem );
294     if ( anActItem && anActItem->isResizing() )
295     { // to resize items on canvas view
296       anActItem->resize(aPoint);
297       myMovingDone = true;
298       return;
299     }
300
301     // to move items on canvas view
302     if ( myCurrentItem->x() && myCurrentItem->y() ) {
303       double cx = myCurrentItem->x() - myPoint.x();
304       double cy = myCurrentItem->y() - myPoint.y();
305         
306       if (aPoint.x()+cx < 0) aPoint.setX(-(int)cx);
307       if (aPoint.y()+cy < 0) aPoint.setY(-(int)cy);
308     }
309     myCurrentItem->moveBy(aPoint.x() - myPoint.x(), 
310                           aPoint.y() - myPoint.y());
311     myMovingDone = true;
312     myPoint = aPoint;
313     canvas()->update();
314
315     // scroll contents if mouse is outside
316     QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
317     if (!r.contains(theEvent->pos())) {
318       int dx = 0, dy = 0;
319       if (theEvent->pos().x() < r.left()) dx = theEvent->pos().x() - r.left();
320       if (theEvent->pos().x() > r.right()) dx = theEvent->pos().x() - r.right();
321       if (theEvent->pos().y() < r.top()) dy = theEvent->pos().y() - r.top();
322       if (theEvent->pos().y() > r.bottom()) dy = theEvent->pos().y() - r.bottom();
323       scrollBy(dx, dy);
324       // start timer to scroll in silent mode
325       myDX = dx; myDY = dy;
326       myTimer->start(100);
327     }
328     
329     return;
330   }
331   else
332   {
333     QCanvasItemList aList = canvas()->collisions(aPoint);
334     // perform actions for active items
335     bool isHilightPerformed = false;
336
337     for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
338       QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
339     
340       if (!isHilightPerformed && anActItem) {
341         // hilight
342         anActItem->hilight(aPoint);
343         if (anActItem != myHilightedItem) {
344           if (myHilightedItem)
345             myHilightedItem->hilight(aPoint, false);
346           myHilightedItem = anActItem;
347         }
348         isHilightPerformed = true;
349         
350         // show tooltip
351         QxGraph_ToolTip* aToolTip = new QxGraph_ToolTip(this);
352         aToolTip->maybeTip(aPoint);
353       }
354       
355       int aCursorType;
356       if ( anActItem && anActItem->isResizable(aPoint,aCursorType) ) {
357         // set resize cursor
358         QCursor resizeCursor;
359         switch (aCursorType)
360           {
361           case 1: //left
362           case 3: //right
363             resizeCursor = QCursor(Qt::SizeHorCursor);
364             break;
365           case 2: //top
366           case 4: //bottom
367             resizeCursor = QCursor(Qt::SizeVerCursor); 
368             break;
369           case 5: //left-top
370           case 7: //right-bottom
371             resizeCursor = QCursor(Qt::SizeFDiagCursor);
372             break;
373           case 6: //right-top
374           case 8: //left-bottom
375             resizeCursor = QCursor(Qt::SizeBDiagCursor); 
376             break;
377           default : 
378             resizeCursor = QCursor(Qt::ArrowCursor);
379             break;
380           }
381         setCursor(resizeCursor);
382         return;
383       }
384       else {
385         // reset old cursor
386         setCursor(QCursor(Qt::ArrowCursor));
387         return;
388       }
389     }
390     
391     if (!isHilightPerformed && myHilightedItem) {
392       myHilightedItem->hilight(aPoint, false);
393       myHilightedItem = 0;
394       QToolTip::hide(); //@ temporary solution
395     }
396
397     if ( cursor().shape() == Qt::SizeVerCursor || cursor().shape() == Qt::SizeHorCursor
398          || cursor().shape() == Qt::SizeBDiagCursor || cursor().shape() == Qt::SizeFDiagCursor)
399       setCursor(QCursor(Qt::ArrowCursor));
400   }
401 }
402
403 /*!
404   This method is called by QxGraph_Canvas when item is removed. 
405   QxGraph_CanvasView updates its own data accordingly
406 */
407 void QxGraph_CanvasView::itemRemoved( QCanvasItem* theItem )
408 {
409   if ( myCurrentItem == theItem )
410     myCurrentItem = 0;
411
412   QxGraph_ActiveItem* anActiveItem = dynamic_cast<QxGraph_ActiveItem*>( theItem );
413   if ( anActiveItem )
414   {
415     if ( myHilightedItem == anActiveItem )
416       myHilightedItem = 0;
417     if ( mySelectedItem == anActiveItem )
418       mySelectedItem = 0;
419   }
420 }
421
422 void QxGraph_CanvasView::setSelectedItem( QxGraph_ActiveItem* theItem )
423 {
424   mySelectedItem = theItem;
425 }
426
427 QxGraph_ActiveItem* QxGraph_CanvasView::getSelectedItem() const
428 {
429   return mySelectedItem;
430 }
431
432 void QxGraph_CanvasView::contentsMouseReleaseEvent(QMouseEvent* theEvent)
433 {
434   QPoint aPoint = inverseWorldMatrix().map(theEvent->pos());
435
436   if (myTimer->isActive()) myTimer->stop();
437
438   if (myCurrentItem)
439   { // to move items on canvas view    
440     QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( myCurrentItem );
441     if ( anActItem && anActItem->isResizing() )
442     {
443       anActItem->afterResizing();
444       // reset old cursor
445       setCursor(QCursor(Qt::ArrowCursor));
446     }
447     else if ( anActItem && anActItem->isMoveable() )
448       anActItem->afterMoving();
449   }
450   myCurrentItem = 0;
451
452   if ( myOperation == PANVIEW )
453   { // Panning
454     myOperation = NOTHING;
455     viewport()->setMouseTracking(true);
456     setCursor(myCursor);
457
458     emit viewOperationDone();
459   }
460
461   if ( myOperation == PANGLOBAL )
462   { // Global panning
463     myOperation = NOTHING;
464     center( theEvent->x(), theEvent->y() );
465     setCursor(myCursor);
466
467     emit viewOperationDone();
468   }
469
470   if ( myOperation == WINDOWFIT )
471   { // Fit within rectangle
472     myOperation = NOTHING;
473     
474     if (mySelectedRect) {
475       mySelectedRect->hide();
476       mySelectedRect = 0;
477       //canvas()->update();
478     }
479
480     //myPoint is the start point for selecting rectangle now
481     int aLX, aTY; //left x and top y
482     if (myPoint.x() < aPoint.x()) aLX = myPoint.x();
483     else aLX = aPoint.x();
484     if (myPoint.y() < aPoint.y()) aTY = myPoint.y();
485     else aTY = aPoint.y();
486
487     //calculate width and height for new view and new zoom factor
488     double aXzoom = ((double)visibleWidth())/((double)(abs(myPoint.x()-aPoint.x())));
489     double aYzoom = ((double)visibleHeight())/((double)(abs(myPoint.y()-aPoint.y())));
490     if (aXzoom > aYzoom) aXzoom = aYzoom;
491     
492     QWMatrix m;
493     m.scale(aXzoom, aXzoom);
494     setWorldMatrix(m);
495
496     // remember the canvas view's current transformation matrix in all canvas items
497     QCanvasItemList aList = canvas()->allItems();
498     for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
499       QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
500       if ( anActItem ) anActItem->setTMatrix(m);
501     }
502
503     setContentsPos((int)(aLX*aXzoom), (int)(aTY*aYzoom));
504
505     canvas()->update();
506     
507     viewport()->setMouseTracking(true);
508     setCursor(myCursor);
509
510     emit viewOperationDone();
511   }
512
513   if ( myOperation == ZOOMVIEW )
514   { // Zoom
515     myOperation = NOTHING;
516     viewport()->setMouseTracking(true);
517     setCursor(myCursor);
518
519     emit viewOperationDone();
520   }
521
522   if ( theEvent->button() == RightButton )
523   { 
524     // Selection mechanism
525     QCanvasItemList aList = canvas()->collisions(aPoint);
526     bool isSelectionPerformed = false;
527
528     for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
529       QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
530       if (!isSelectionPerformed && anActItem) 
531       {
532         anActItem->select(aPoint);
533         if (anActItem != mySelectedItem) 
534         {
535           if (mySelectedItem && isSelectedItemInCanvas() &&
536               !mySelectedItem->arePartsOfOtherItem(anActItem)) mySelectedItem->select(aPoint, false);
537           mySelectedItem = anActItem;
538
539           // unhilight hilighted item if selection was performed
540           if (myHilightedItem) {
541             myHilightedItem->hilight(aPoint, false);
542             myHilightedItem = 0;
543           }
544         }
545         isSelectionPerformed = true;
546       }
547     }
548
549     if (!isSelectionPerformed)
550     { 
551       if ( mySelectedItem )
552       {
553         if ( isSelectedItemInCanvas() ) mySelectedItem->select(aPoint, false);
554         mySelectedItem = 0;
555       }
556       
557       // Background popup
558       printf("Background popup\n");
559       QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
560                                 theEvent->pos(), theEvent->globalPos(),
561                                 theEvent->state() );
562       if ( getViewWindow() )
563         getViewWindow()->contextPopupEvent(&aEvent); // => emit contextMenuRequested( &aEvent );
564     }
565     else
566     { // show context popup for the selected item
567       mySelectedItem->showPopup(viewport(), theEvent, aPoint);
568     }
569   }
570
571   if ( theEvent->button() == LeftButton && !myMovingDone )
572   {
573     // Selection mechanism
574     QCanvasItemList aList = canvas()->collisions(aPoint);
575
576     if ( aList.empty() && mySelectedItem )
577     {
578       if ( isSelectedItemInCanvas() ) mySelectedItem->select(aPoint, false);
579       mySelectedItem = 0;
580     }
581     else
582     {
583       for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
584         QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
585         if (anActItem) 
586         {
587           anActItem->select(aPoint);
588           if (anActItem != mySelectedItem) 
589           {
590             if (mySelectedItem && isSelectedItemInCanvas() &&
591                 !mySelectedItem->arePartsOfOtherItem(anActItem)) mySelectedItem->select(aPoint, false);
592             mySelectedItem = anActItem;
593           }
594           break;
595         }
596       }
597     }
598   }
599
600   myMovingDone = false;
601 }
602
603 void QxGraph_CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* theEvent)
604 {
605   
606 }
607
608 bool QxGraph_CanvasView::isSelectedItemInCanvas()
609 {
610   // check if mySelectedItem is included into the canvas:
611   // if yes => unselect it
612   // if no => do nothing
613   bool anIsInCanvas = false;
614   QCanvasItemList aListC = canvas()->allItems();
615   for (QCanvasItemList::Iterator itC = aListC.begin(); itC != aListC.end(); ++itC) {
616     QxGraph_ActiveItem* anActItemC = dynamic_cast<QxGraph_ActiveItem*>( *itC );
617     if ( anActItemC && anActItemC == mySelectedItem ) {
618       anIsInCanvas = true;
619       break;
620     }
621   }
622   return anIsInCanvas;
623 }
624
625 void QxGraph_CanvasView::activateFitAll()
626 {
627   //myOperation = FITALL;
628   int w = 0, h = 0;
629   QCanvasItemList l = canvas()->allItems();
630   for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
631     QRect r = (*it)->boundingRect();
632     if (w < r.right()) w = r.right();
633     if (h < r.bottom()) h = r.bottom();
634   }
635   w += GRAPH_MARGIN; h += GRAPH_MARGIN;
636   double s = ((double)visibleWidth())/((double)w);
637   double s1 = ((double)visibleHeight())/((double)h);
638   if (s > s1) s = s1;
639
640   setContentsPos(0,0);
641   QWMatrix m;
642   m.scale(s, s);
643   setWorldMatrix(m);
644
645   // remember the canvas view's current transformation matrix in all canvas items
646   QCanvasItemList aList = canvas()->allItems();
647   for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
648     QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
649     if ( anActItem ) anActItem->setTMatrix(m);
650   }
651   
652   canvas()->update();
653   //myOperation = NOTHING;
654
655   emit viewOperationDone();
656 }
657
658 void QxGraph_CanvasView::activateFitRect()
659 {
660   myOperation = WINDOWFIT;
661   viewport()->setMouseTracking(false);
662   myCursor = cursor(); // save old cursor
663   QCursor handCursor (Qt::PointingHandCursor);
664   setCursor(handCursor);
665 }
666
667 void QxGraph_CanvasView::activateZoom()
668 {
669   myOperation = ZOOMVIEW;
670   viewport()->setMouseTracking(false);
671   myCursor = cursor(); // save old cursor
672   QPixmap zoomPixmap (imageZoomCursor);
673   QCursor zoomCursor (zoomPixmap);
674   setCursor(zoomCursor);
675 }
676
677 void QxGraph_CanvasView::activatePanning()
678 {
679   myOperation = PANVIEW;
680   viewport()->setMouseTracking(false);
681   myCursor = cursor(); // save old cursor
682   QCursor panCursor (Qt::SizeAllCursor);
683   setCursor(panCursor);
684 }
685
686 void QxGraph_CanvasView::activateGlobalPanning()
687 {
688   myOperation = PANGLOBAL;
689   myCursor = cursor(); // save old cursor
690   QPixmap globalPanPixmap (imageCrossCursor);
691   QCursor glPanCursor (globalPanPixmap);
692   setCursor(glPanCursor);
693 }
694
695 void QxGraph_CanvasView::activateReset()
696 {
697   //myOperation = RESETVIEW;
698   setContentsPos(0,0);
699   QWMatrix m;
700   setWorldMatrix(m);
701   
702   // remember the canvas view's current transformation matrix in all canvas items
703   QCanvasItemList aList = canvas()->allItems();
704   for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
705     QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
706     if ( anActItem ) anActItem->setTMatrix(m);
707   }
708
709   //myOperation = NOTHING;
710
711   emit viewOperationDone();
712 }
713
714 void QxGraph_CanvasView::onTimeout() 
715 {
716   if (myCurrentItem) {
717     scrollBy(myDX, myDY);
718
719     double cx, cy;
720     inverseWorldMatrix().map((double)myDX, (double)myDY, &cx, &cy);
721     if (myCurrentItem->x()+cx < 0) cx = -myCurrentItem->x();
722     if (myCurrentItem->y()+cy < 0) cy = -myCurrentItem->y();
723     myCurrentItem->moveBy(cx, cy);
724     myPoint.setX(myPoint.x()+(int)cx);
725     myPoint.setY(myPoint.y()+(int)cy);
726     canvas()->update();
727   }
728 }
729
730 QxGraph_ViewWindow* QxGraph_CanvasView::getViewWindow() const
731 {
732   return dynamic_cast<QxGraph_ViewWindow*>( parent() );
733 }
734
735 /*!
736   Shows tooltip if necessary
737 */
738 void QxGraph_ToolTip::maybeTip(const QPoint& theMousePos) {
739   QCanvasItemList aList = ((QCanvasView*)parentWidget())->canvas()->collisions(theMousePos);
740   
741   for (QCanvasItemList::Iterator it = aList.begin(); it != aList.end(); ++it) {
742     QxGraph_ActiveItem* anActItem = dynamic_cast<QxGraph_ActiveItem*>( *it );
743     if (anActItem)
744       {
745         QRect aRect;
746         QString aText = anActItem->getToolTipText(theMousePos, aRect);
747         int avX, avY;
748         QWMatrix aWM = ((QCanvasView*)parentWidget())->worldMatrix();
749         ((QCanvasView*)parentWidget())->contentsToViewport((int)(aRect.left()*aWM.m11()), 
750                                                            (int)(aRect.top()*aWM.m22()), 
751                                                            avX, avY);
752         QRect aTipRect(avX, avY, (int)(aRect.width()*aWM.m11()), (int)(aRect.height()*aWM.m22()));
753         if (!aText.isEmpty())
754           tip(aTipRect, aText);
755         return;
756       }
757   }
758 }
759
760
761