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