Salome HOME
Changes in source code within porting on CentOS 6.3
[modules/shaper.git] / src / XGUI / XGUI_ViewWindow.cpp
1 #include "XGUI_ViewWindow.h"
2 #include "XGUI_ViewPort.h"
3 #include "XGUI_Viewer.h"
4 #include "XGUI_Tools.h"
5 #include "XGUI_RubberBand.h"
6
7 #include <QLayout>
8 #include <QLabel>
9 #include <QToolBar>
10 #include <QAction>
11 #include <QResizeEvent>
12 #include <QApplication>
13 #include <QMdiArea>
14 #include <QMdiSubWindow>
15 #include <QPainter>
16 #include <QTimer>
17 #include <QFileDialog>
18
19 #include <TopoDS_Shape.hxx>
20 #include <BRep_Tool.hxx>
21 #include <TopoDS.hxx>
22 #include <Visual3d_View.hxx>
23
24 #define BORDER_SIZE 2
25
26 const char* imageZoomCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
27     "................................", "................................",
28     ".#######........................", "..aaaaaaa.......................",
29     "................................", ".............#####..............",
30     "...........##.aaaa##............", "..........#.aa.....a#...........",
31     ".........#.a.........#..........", ".........#a..........#a.........",
32     "........#.a...........#.........", "........#a............#a........",
33     "........#a............#a........", "........#a............#a........",
34     "........#a............#a........", ".........#...........#.a........",
35     ".........#a..........#a.........", ".........##.........#.a.........",
36     "........#####.....##.a..........", ".......###aaa#####.aa...........",
37     "......###aa...aaaaa.......#.....", ".....###aa................#a....",
38     "....###aa.................#a....", "...###aa...............#######..",
39     "....#aa.................aa#aaaa.", ".....a....................#a....",
40     "..........................#a....", "...........................a....",
41     "................................", "................................",
42     "................................", "................................" };
43
44 const char* imageRotateCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
45     "................................", "................................",
46     "................................", "................................",
47     "........#.......................", ".......#.a......................",
48     "......#######...................", ".......#aaaaa#####..............",
49     "........#..##.a#aa##........##..", ".........a#.aa..#..a#.....##.aa.",
50     ".........#.a.....#...#..##.aa...", ".........#a.......#..###.aa.....",
51     "........#.a.......#a..#aa.......", "........#a.........#..#a........",
52     "........#a.........#a.#a........", "........#a.........#a.#a........",
53     "........#a.........#a.#a........", ".........#.........#a#.a........",
54     "........##a........#a#a.........", "......##.a#.......#.#.a.........",
55     "....##.aa..##.....##.a..........", "..##.aa.....a#####.aa...........",
56     "...aa.........aaa#a.............", "................#.a.............",
57     "...............#.a..............", "..............#.a...............",
58     "...............a................", "................................",
59     "................................", "................................",
60     "................................", "................................" };
61
62 const char* imageCrossCursor[] = { "32 32 3 1", ". c None", "a c #000000", "# c #ffffff",
63     "................................", "................................",
64     "................................", "................................",
65     "................................", "................................",
66     "................................", "...............#................",
67     "...............#a...............", "...............#a...............",
68     "...............#a...............", "...............#a...............",
69     "...............#a...............", "...............#a...............",
70     "...............#a...............", ".......#################........",
71     "........aaaaaaa#aaaaaaaaa.......", "...............#a...............",
72     "...............#a...............", "...............#a...............",
73     "...............#a...............", "...............#a...............",
74     "...............#a...............", "...............#a...............",
75     "................a...............", "................................",
76     "................................", "................................",
77     "................................", "................................",
78     "................................", "................................" };
79
80 //**************************************************************************
81 void ViewerToolbar::repaintBackground()
82 {
83   QRect aRect = rect();
84   QRect aVPRect = myVPort->rect();
85   QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
86   QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
87
88   QRect aImgRect(QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), 
89                        aRect.width(), aRect.height()));
90   QPainter(this).drawImage(aRect, myVPort->dumpView(aImgRect, false));
91 }
92
93 void ViewerToolbar::paintEvent(QPaintEvent* theEvent)
94 {
95   repaintBackground();
96   //QToolBar::paintEvent(theEvent);
97 }
98
99 //**************************************************************************
100 void ViewerLabel::repaintBackground()
101 {
102   QRect aRect = rect();
103   QRect aVPRect = myVPort->rect();
104   QPoint aGlobPnt = mapToGlobal(aRect.topLeft());
105   QPoint aPnt = myVPort->mapFromGlobal(aGlobPnt);
106
107   QRect aImgRect(QRect(aPnt.x(), aPnt.y() + aVPRect.height() - aRect.height(), 
108                  aRect.width(), aRect.height()));
109   QPainter(this).drawImage(aRect, myVPort->dumpView(aImgRect, false));
110 }
111
112 void ViewerLabel::paintEvent(QPaintEvent* theEvent)
113 {
114   repaintBackground();
115   QLabel::paintEvent(theEvent);
116 }
117
118 //**************************************************************************
119 //**************************************************************************
120 //**************************************************************************
121 XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, V3d_TypeOfView theType)
122     : QFrame(), 
123     myViewer(theViewer), 
124     myMoving(false), 
125     MinimizeIco(":pictures/wnd_minimize.png"), 
126     MaximizeIco(":pictures/wnd_maximize.png"), 
127     CloseIco(":pictures/wnd_close.png"), 
128     RestoreIco(":pictures/wnd_restore.png"), 
129     myInteractionStyle(XGUI::STANDARD), 
130     myRectBand(0), 
131     myIsKeyFree(false), 
132     my2dMode(XGUI::No2dMode), 
133     myCurrPointType(XGUI::GRAVITY), 
134     myPrevPointType(XGUI::GRAVITY), 
135     myRotationPointSelection(false),
136     myClosable(true),
137     myStartX(0), myStartY(0), myCurrX(0), myCurrY(0), myCurScale(0.0), myCurSketch(0),
138     myDrawRect(false), myEnableDrawMode(false), myCursorIsHand(false), myEventStarted(false),
139     myLastState(WindowNormalState), myOperation(NOTHING)
140 {
141   mySelectedPoint = gp_Pnt(0., 0., 0.);
142   setFrameStyle(QFrame::Raised);
143   setFrameShape(QFrame::Panel);
144   setLineWidth(BORDER_SIZE);
145   setMouseTracking(true);
146
147   QVBoxLayout* aLay = new QVBoxLayout(this);
148   aLay->setContentsMargins(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
149   myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType);
150   myViewPort->installEventFilter(this);
151   aLay->addWidget(myViewPort);
152
153   myPicture = new QLabel(this);
154   myPicture->setFrameStyle(QFrame::Sunken);
155   myPicture->setFrameShape(QFrame::Panel);
156   myPicture->setMouseTracking(true);
157   myPicture->installEventFilter(this);
158   aLay->addWidget(myPicture);
159   myPicture->hide();
160
161   myGripWgt = new ViewerLabel(this, myViewPort);
162   myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png"));
163   myGripWgt->setGeometry(BORDER_SIZE + 2, BORDER_SIZE + 2, 19, 32);
164   myGripWgt->setMouseTracking(true);
165   myGripWgt->installEventFilter(this);
166
167     // Create Viewer management buttons
168   myViewBar = new ViewerToolbar(this, myViewPort);
169
170   QAction* aBtn;
171
172   // Dump view
173   aBtn = new QAction(QIcon(":pictures/occ_view_camera_dump.png"), tr("Dump view"), myViewBar);
174   connect(aBtn, SIGNAL(triggered()), SLOT(dumpView()));
175   myViewBar->addAction(aBtn);
176   // Fit all
177   aBtn = new QAction(QIcon(":pictures/occ_view_fitall.png"), tr("Fit all"), myViewBar);
178   connect(aBtn, SIGNAL(triggered()), SLOT(fitAll()));
179   myViewBar->addAction(aBtn);
180   // Fit area
181   aBtn = new QAction(QIcon(":pictures/occ_view_fitarea.png"), tr("Fit area"), myViewBar);
182   connect(aBtn, SIGNAL(triggered()), SLOT(activateWindowFit()));
183   myViewBar->addAction(aBtn);
184   // Zoom
185   aBtn = new QAction(QIcon(":pictures/occ_view_zoom.png"), tr("Zoom"), myViewBar);
186   connect(aBtn, SIGNAL(triggered()), SLOT(activateZoom()));
187   myViewBar->addAction(aBtn);
188   // Pan
189   aBtn = new QAction(QIcon(":pictures/occ_view_pan.png"), tr("Panning"), myViewBar);
190   connect(aBtn, SIGNAL(triggered()), SLOT(activatePanning()));
191   myViewBar->addAction(aBtn);
192   // Global Panning
193   aBtn = new QAction(QIcon(":pictures/occ_view_glpan.png"), tr("Global panning"), myViewBar);
194   connect(aBtn, SIGNAL(triggered()), SLOT(activateGlobalPanning()));
195   myViewBar->addAction(aBtn);
196   // Rotation
197   aBtn = new QAction(QIcon(":pictures/occ_view_rotate.png"), tr("Rotate"), myViewBar);
198   connect(aBtn, SIGNAL(triggered()), SLOT(activateRotation()));
199   myViewBar->addAction(aBtn);
200   // Reset
201   aBtn = new QAction(QIcon(":pictures/occ_view_reset.png"), tr("Reset"), myViewBar);
202   connect(aBtn, SIGNAL(triggered()), SLOT(reset()));
203   myViewBar->addAction(aBtn);
204   // Front view
205   aBtn = new QAction(QIcon(":pictures/occ_view_front.png"), tr("Front"), myViewBar);
206   connect(aBtn, SIGNAL(triggered()), SLOT(frontView()));
207   myViewBar->addAction(aBtn);
208   // Back view
209   aBtn = new QAction(QIcon(":pictures/occ_view_back.png"), tr("Back"), myViewBar);
210   connect(aBtn, SIGNAL(triggered()), SLOT(backView()));
211   myViewBar->addAction(aBtn);
212   // Top view
213   aBtn = new QAction(QIcon(":pictures/occ_view_top.png"), tr("Top"), myViewBar);
214   connect(aBtn, SIGNAL(triggered()), SLOT(topView()));
215   myViewBar->addAction(aBtn);
216   // Bottom view
217   aBtn = new QAction(QIcon(":pictures/occ_view_bottom.png"), tr("Bottom"), myViewBar);
218   connect(aBtn, SIGNAL(triggered()), SLOT(bottomView()));
219   myViewBar->addAction(aBtn);
220   // Left view
221   aBtn = new QAction(QIcon(":pictures/occ_view_left.png"), tr("Left"), myViewBar);
222   connect(aBtn, SIGNAL(triggered()), SLOT(leftView()));
223   myViewBar->addAction(aBtn);
224   // Right view
225   aBtn = new QAction(QIcon(":pictures/occ_view_right.png"), tr("Right"), myViewBar);
226   connect(aBtn, SIGNAL(triggered()), SLOT(rightView()));
227   myViewBar->addAction(aBtn);
228   // Clone view
229   aBtn = new QAction(QIcon(":pictures/occ_view_clone.png"), tr("Clone"), myViewBar);
230   connect(aBtn, SIGNAL(triggered()), SLOT(cloneView()));
231   myViewBar->addAction(aBtn);
232
233     // Create Window management buttons
234   myWindowBar = new ViewerToolbar(this, myViewPort);
235
236   myMinimizeBtn = new QAction(myWindowBar);
237   myMinimizeBtn->setIcon(MinimizeIco);
238   myWindowBar->addAction(myMinimizeBtn);
239   connect(myMinimizeBtn, SIGNAL(triggered()), SLOT(onMinimize()));
240
241   myMaximizeBtn = new QAction(myWindowBar);
242   myMaximizeBtn->setIcon(MaximizeIco);
243   myWindowBar->addAction(myMaximizeBtn);
244   connect(myMaximizeBtn, SIGNAL(triggered()), SLOT(onMaximize()));
245
246   aBtn = new QAction(myWindowBar);
247   aBtn->setIcon(CloseIco);
248   myWindowBar->addAction(aBtn);
249   connect(aBtn, SIGNAL(triggered()), SLOT(onClose()));
250
251   myViewBar->hide();
252   myWindowBar->hide();
253   myGripWgt->hide();
254
255   //Support copy of background on updating of viewer
256   connect(myViewPort, SIGNAL(vpTransformed()), this, SLOT(updateToolBar()));
257   connect(myViewPort, SIGNAL(vpUpdated()), this, SLOT(updateToolBar()));
258   connect(this, SIGNAL(vpTransformationFinished(XGUI_ViewWindow::OperationType)), 
259           this, SLOT(updateToolBar()));
260
261 }
262
263 //****************************************************************
264 XGUI_ViewWindow::~XGUI_ViewWindow()
265 {
266 }
267
268 //****************************************************************
269 void XGUI_ViewWindow::resizeEvent(QResizeEvent* theEvent)
270 {
271   QSize aSize = theEvent->size();
272   QSize aWndBarSize = myWindowBar->sizeHint();
273   QSize myViewBarSize = myViewBar->sizeHint();
274
275   myWindowBar->move(aSize.width() - aWndBarSize.width() - BORDER_SIZE - 4,
276   BORDER_SIZE + 2);
277   int aViewBarWidth = aSize.width() - aWndBarSize.width() - myGripWgt->width() - 8;
278   if (aViewBarWidth > myViewBarSize.width())
279     aViewBarWidth = myViewBarSize.width();
280   myViewBar->setGeometry(BORDER_SIZE + 18, BORDER_SIZE + 2, aViewBarWidth, myViewBarSize.height());
281 }
282
283 //****************************************************************
284 void XGUI_ViewWindow::changeEvent(QEvent* theEvent)
285 {
286
287   if (theEvent->type() == QEvent::WindowStateChange) {
288     if (isMinimized()) {
289             myViewBar->hide();
290             myGripWgt->hide(); 
291             myWindowBar->hide();
292             myViewPort->hide();
293       myPicture->show();
294     } else {
295       myPicture->hide();
296             myViewPort->show();
297       if (isMaximized()) {
298         myMinimizeBtn->setIcon(MinimizeIco);
299         myMaximizeBtn->setIcon(RestoreIco);
300       }
301     }
302   } else
303     QWidget::changeEvent(theEvent);
304 }
305
306
307 //****************************************************************
308 void XGUI_ViewWindow::onClose()
309 {
310   if (parentWidget()) {
311     emit tryClosing(this);
312     if (closable()) {
313       emit closed(static_cast<QMdiSubWindow*>(parentWidget()));
314       parentWidget()->close();
315     }
316   }
317 }
318
319 //****************************************************************
320 void XGUI_ViewWindow::enterEvent(QEvent* theEvent)
321 {
322   if (!isMinimized()) {
323     myViewBar->show();
324     myWindowBar->show();
325     if (!isMaximized())
326       myGripWgt->show();
327   }
328 }
329
330 //****************************************************************
331 void XGUI_ViewWindow::leaveEvent(QEvent* theEvent)
332 {
333   myViewBar->hide();
334   myGripWgt->hide();
335   myWindowBar->hide();
336 }
337
338 //****************************************************************
339 void XGUI_ViewWindow::onMinimize()
340 {
341   QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView());
342   int aW = width();
343   int aH = height();
344   double aR = aW / 100.;
345     int aNewH = int(aH / aR);
346     myPicture->setPixmap(aPMap.scaled(100,  aNewH));
347
348   myLastState = isMaximized() ? MaximizedState : WindowNormalState;
349   showMinimized();
350     parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(),
351                                 100, aNewH);
352 }
353
354 //****************************************************************
355 void XGUI_ViewWindow::onMaximize()
356 {
357   if (isMaximized()) {
358     myMaximizeBtn->setIcon(MaximizeIco);
359     myGripWgt->show();
360     showNormal();
361   } else {
362     myMaximizeBtn->setIcon(RestoreIco);
363     myGripWgt->hide();
364     showMaximized();
365   }
366   myMinimizeBtn->setIcon(MinimizeIco);
367 }
368
369 //****************************************************************
370 bool XGUI_ViewWindow::processWindowControls(QObject *theObj, QEvent *theEvent)
371 {
372   switch(theEvent->type()) {
373   case QEvent::MouseButtonPress: {
374     QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
375     if ((aEvent->button() == Qt::LeftButton) && (!myMoving)) {
376       myMoving = true;
377       myMousePnt = aEvent->globalPos();
378       return true;
379     }
380   }
381     break;
382   case QEvent::MouseButtonRelease: {
383     QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
384     if ((aEvent->button() == Qt::LeftButton) && myMoving) {
385       myMoving = false;
386       return true;
387     }
388   }
389     break;
390   case QEvent::MouseMove: {
391     QMouseEvent* aEvent = static_cast<QMouseEvent*>(theEvent);
392     if (myMoving) {
393       QMdiSubWindow* aParent = static_cast<QMdiSubWindow*>(parentWidget());
394       QMdiArea* aMDIArea = aParent->mdiArea();
395
396       QPoint aPnt = aEvent->globalPos();
397       QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt);
398       if (aMDIArea->rect().contains(aMDIPnt)) {
399                     int aX = aParent->x() + (aPnt.x() - myMousePnt.x());
400                     int aY = aParent->y() + (aPnt.y() - myMousePnt.y());
401                     aParent->move(aX, aY);
402         myMousePnt = aPnt;
403       }
404       return true;
405     }
406   }
407     break;
408   case QEvent::MouseButtonDblClick:
409     if (theObj == myPicture) {
410       myMoving = false;
411       if (myLastState == MaximizedState)
412         showMaximized();
413       else
414         showNormal();
415       return true;
416     }
417   }
418   return false;
419 }
420
421 //****************************************************************
422 bool XGUI_ViewWindow::processViewPort(QEvent *theEvent)
423 {
424   switch(theEvent->type()) {
425   case QEvent::MouseButtonPress:
426     vpMousePressEvent((QMouseEvent*) theEvent);
427     return true;
428
429   case QEvent::MouseButtonRelease:
430     vpMouseReleaseEvent((QMouseEvent*) theEvent);
431     return true;
432
433   case QEvent::MouseMove:
434     vpMouseMoveEvent((QMouseEvent*) theEvent);
435     return true;
436
437   case QEvent::MouseButtonDblClick:
438     emit mouseDoubleClicked(this, (QMouseEvent*) theEvent);
439     return true;
440     case QEvent::Wheel:
441         {
442             QWheelEvent* aEvent = (QWheelEvent*) theEvent;
443             myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
444             double aDelta = (double)( aEvent->delta() ) / ( 15 * 8 );
445             int x  = aEvent->x();
446             int y  = aEvent->y();
447             int x1 = (int)( aEvent->x() + width()*aDelta/100 );
448             int y1 = (int)( aEvent->y() + height()*aDelta/100 );
449             myViewPort->zoom( x, y, x1, y1 );
450         }
451         return true;
452   }
453   return false;
454 }
455
456 //****************************************************************
457 bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent)
458 {
459   if ((theObj == myGripWgt) || (theObj == myPicture)) {
460     if (processWindowControls(theObj, theEvent))
461       return true;
462   } else if (theObj == myViewPort) {
463     if (processViewPort(theEvent)) {
464       return true;
465     }
466   }
467   return QFrame::eventFilter(theObj, theEvent);
468 }
469
470 //****************************************************************
471 XGUI_ViewWindow::OperationType XGUI_ViewWindow::getButtonState(
472     QMouseEvent* theEvent, XGUI::InteractionStyle theInteractionStyle)
473 {
474   OperationType aOp = NOTHING;
475   XGUI::InteractionStyle aStyle = (XGUI::InteractionStyle) theInteractionStyle;
476   if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ZOOM])
477       && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ZOOM]))
478     aOp = ZOOMVIEW;
479   else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::PAN])
480       && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::PAN]))
481     aOp = PANVIEW;
482   else if ((theEvent->modifiers() == XGUI_Viewer::myStateMap[aStyle][XGUI::ROTATE])
483       && (theEvent->buttons() == XGUI_Viewer::myButtonMap[aStyle][XGUI::ROTATE])
484       && (my2dMode == XGUI::No2dMode))
485     aOp = ROTATE;
486
487   return aOp;
488 }
489
490 //****************************************************************
491 void XGUI_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
492 {
493   myStartX = theEvent->x();
494   myStartY = theEvent->y();
495   XGUI::InteractionStyle anInteractionStyle = interactionStyle();
496
497   // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
498   // which are assigned for pan and rotate - these operations are activated immediately after pressing 
499   // of the first button, so it is necessary to switch to zoom when the second button is pressed
500   bool aSwitchToZoom = false;
501   if ((anInteractionStyle == XGUI::KEY_FREE) && (myOperation == PANVIEW || myOperation == ROTATE)) {
502     aSwitchToZoom = getButtonState(theEvent, anInteractionStyle) == ZOOMVIEW;
503   }
504
505   switch(myOperation) {
506   case WINDOWFIT:
507     if (theEvent->button() == Qt::LeftButton)
508       emit vpTransformationStarted(WINDOWFIT);
509     break;
510
511   case PANGLOBAL:
512     if (theEvent->button() == Qt::LeftButton)
513       emit vpTransformationStarted(PANGLOBAL);
514     break;
515
516   case ZOOMVIEW:
517     if (theEvent->button() == Qt::LeftButton) {
518       myViewPort->startZoomAtPoint(myStartX, myStartY);
519       emit vpTransformationStarted(ZOOMVIEW);
520     }
521     break;
522
523   case PANVIEW:
524     if (aSwitchToZoom) {
525       myViewPort->startZoomAtPoint(myStartX, myStartY);
526       activateZoom();
527     } else if (theEvent->button() == Qt::LeftButton)
528       emit vpTransformationStarted(PANVIEW);
529     break;
530
531   case ROTATE:
532     if (aSwitchToZoom) {
533       myViewPort->startZoomAtPoint(myStartX, myStartY);
534       activateZoom();
535     } else if (theEvent->button() == Qt::LeftButton) {
536       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
537       emit vpTransformationStarted(ROTATE);
538     }
539     break;
540
541   default:
542     /*  Try to activate a transformation */
543     OperationType aState;
544     if (interactionStyle() == XGUI::STANDARD)
545       aState = getButtonState(theEvent, anInteractionStyle);
546     else {
547       aState = XGUI_ViewWindow::NOTHING;
548       myIsKeyFree = true;
549     }
550     switch(aState) {
551     case ZOOMVIEW:
552       myViewPort->startZoomAtPoint(myStartX, myStartY);
553       activateZoom();
554       break;
555     case PANVIEW:
556       activatePanning();
557       break;
558     case ROTATE:
559       activateRotation();
560       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
561       break;
562     default:
563       if (myRotationPointSelection) {
564         if (theEvent->button() == Qt::LeftButton) {
565           Handle(AIS_InteractiveContext) ic = myViewer->AISContext();
566           ic->Select();
567           for(ic->InitSelected(); ic->MoreSelected(); ic->NextSelected()) {
568             TopoDS_Shape aShape = ic->SelectedShape();
569             if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) {
570               gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(ic->SelectedShape()));
571               /*if ( mySetRotationPointDlg ) {
572                myRotationPointSelection = false;
573                mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
574                }*/
575             } else {
576               myCurrPointType = myPrevPointType;
577               break;
578             }
579           }
580           if (ic->NbSelected() == 0)
581             myCurrPointType = myPrevPointType;
582           //if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
583           ic->CloseAllContexts();
584           myOperation = NOTHING;
585           myViewPort->setCursor(myCursor);
586           myCursorIsHand = false;
587           myRotationPointSelection = false;
588         }
589       } else
590         emit mousePressed(this, theEvent);
591       break;
592     }
593     /* notify that we start a transformation */
594     if (transformRequested())
595       emit vpTransformationStarted(myOperation);
596   }
597   if (transformRequested())
598     setTransformInProcess(true);
599
600   /* we may need it for sketching... */
601   /*    if ( l_mbPressEvent )
602    delete l_mbPressEvent;
603    l_mbPressEvent = new QMouseEvent( *theEvent );*/
604 }
605
606 //****************************************************************
607 void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
608 {
609   switch(myOperation) {
610   case NOTHING: {
611     int prevState = myCurSketch;
612     /*            if(theEvent->button() == Qt::RightButton) {
613      QList<OCCViewer_ViewSketcher*>::Iterator it;
614      for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) {
615      OCCViewer_ViewSketcher* sk = (*it);
616      if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
617      myCurSketch = -1;
618      }
619      }
620      */
621     emit mouseReleased(this, theEvent);
622     if (theEvent->button() == Qt::RightButton && prevState == -1) {
623       QContextMenuEvent aEvent(QContextMenuEvent::Mouse, theEvent->pos(), theEvent->globalPos());
624       emit contextMenuRequested(&aEvent);
625     }
626   }
627     break;
628   case ROTATE:
629     myViewPort->endRotation();
630     resetState();
631     break;
632
633   case PANVIEW:
634   case ZOOMVIEW:
635     resetState();
636     break;
637
638   case PANGLOBAL:
639     if (theEvent->button() == Qt::LeftButton) {
640       myViewPort->setCenter(theEvent->x(), theEvent->y());
641       myViewPort->getView()->SetScale(myCurScale);
642       resetState();
643     }
644     break;
645
646   case WINDOWFIT:
647     if (theEvent->button() == Qt::LeftButton) {
648       myCurrX = theEvent->x();
649       myCurrY = theEvent->y();
650       drawRect();
651       QRect rect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
652       if (!rect.isEmpty())
653         myViewPort->fitRect(rect);
654       endDrawRect();
655       resetState();
656     }
657     break;
658   }
659
660   // NOTE: viewer 3D detects a rectangle of selection using this event
661   // so we must emit it BEFORE resetting the selection rectangle
662   if (theEvent->button() == Qt::LeftButton && myDrawRect) {
663     drawRect();
664     endDrawRect();
665     resetState();
666     myViewPort->update();
667   }
668   /*    if ( l_mbPressEvent ) {
669    delete l_mbPressEvent;
670    l_mbPressEvent = 0;
671    }*/
672 }
673
674 //****************************************************************
675 void XGUI_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
676 {
677   if (myIsKeyFree && interactionStyle() == XGUI::KEY_FREE) {
678     myIsKeyFree = false;
679     switch(getButtonState(theEvent, interactionStyle())) {
680     case ZOOMVIEW:
681       myViewPort->startZoomAtPoint(myStartX, myStartY);
682       activateZoom();
683       break;
684     case PANVIEW:
685       activatePanning();
686       break;
687     case ROTATE:
688       activateRotation();
689       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
690       break;
691     default:
692       break;
693     }
694   }
695
696   myCurrX = theEvent->x();
697   myCurrY = theEvent->y();
698   switch(myOperation) {
699   case ROTATE:
700     myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
701     break;
702
703   case ZOOMVIEW:
704     myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
705     myStartX = myCurrX;
706     myStartY = myCurrY;
707     break;
708
709   case PANVIEW:
710     myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
711     myStartX = myCurrX;
712     myStartY = myCurrY;
713     break;
714
715   case PANGLOBAL:
716     break;
717
718   default:
719     if (myRotationPointSelection /*|| isSketcherStyle()*/) {
720       emit mouseMoving(this, theEvent);
721     } else {
722       int aState = theEvent->modifiers();
723       int aButton = theEvent->buttons();
724       int anInteractionStyle = interactionStyle();
725       if (((anInteractionStyle == XGUI::STANDARD) && (aButton == Qt::LeftButton)
726           && (aState == Qt::NoModifier || Qt::ShiftModifier))
727           || ((anInteractionStyle == XGUI::KEY_FREE) && (aButton == Qt::LeftButton)
728               && (aState == Qt::ControlModifier
729                   || aState == (Qt::ControlModifier | Qt::ShiftModifier)))) {
730         myDrawRect = myEnableDrawMode;
731         if (myDrawRect) {
732           drawRect();
733           if (!myCursorIsHand) {   // we are going to sketch a rectangle
734             QCursor handCursor(Qt::PointingHandCursor);
735             myCursorIsHand = true;
736             myCursor = cursor();
737             myViewPort->setCursor(handCursor);
738           }
739         }
740         emit mouseMoving(this, theEvent);
741       } /* else if ( ( (anInteractionStyle == XGUI::STANDARD) &&
742        (aButton == Qt::RightButton) && 
743        ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
744        ( (anInteractionStyle == XGUI::KEY_FREE) &&
745        (aButton == Qt::RightButton) && 
746        ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
747        OCCViewer_ViewSketcher* sketcher = 0;
748        QList<OCCViewer_ViewSketcher*>::Iterator it;
749        for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) {
750        OCCViewer_ViewSketcher* sk = (*it);
751        if( sk->isDefault() && sk->sketchButton() == aButton )
752        sketcher = sk;
753        }
754        if ( sketcher && myCurSketch == -1 ) {
755        activateSketching( sketcher->type() );
756        if ( mypSketcher ) {
757        myCurSketch = mypSketcher->sketchButton();
758
759        if ( l_mbPressEvent )  {
760        QApplication::sendEvent( getViewPort(), l_mbPressEvent );
761        delete l_mbPressEvent;
762        l_mbPressEvent = 0;
763        }
764        QApplication::sendEvent( getViewPort(), theEvent );
765        }
766        }
767        } */else
768         emit mouseMoving(this, theEvent);
769     }
770   }
771 }
772
773 /*!
774  \brief Draw rubber band rectangle.
775  */
776 void XGUI_ViewWindow::drawRect()
777 {
778   if (!myRectBand) {
779     myRectBand = new XGUI_RectRubberBand(myViewPort);
780   }
781
782   myRectBand->setUpdatesEnabled(false);
783   QRect aRect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
784   myRectBand->initGeometry(aRect);
785
786   if (!myRectBand->isVisible())
787     myRectBand->show();
788
789   myRectBand->setUpdatesEnabled(true);
790 }
791
792 /*!
793  \brief Clear rubber band rectangle on the end on the dragging operation.
794  */
795 void XGUI_ViewWindow::endDrawRect()
796 {
797   if (myRectBand) {
798     myRectBand->clearGeometry();
799     myRectBand->hide();
800   }
801 }
802
803 void XGUI_ViewWindow::activateZoom()
804 {
805   if (!transformRequested() && !myCursorIsHand)
806     myCursor = cursor(); /* save old cursor */
807
808   if (myOperation != ZOOMVIEW) {
809     QPixmap zoomPixmap(imageZoomCursor);
810     QCursor zoomCursor(zoomPixmap);
811     if (setTransformRequested(ZOOMVIEW))
812       myViewPort->setCursor(zoomCursor);
813   }
814 }
815
816 bool XGUI_ViewWindow::transformRequested() const
817 {
818   return (myOperation != NOTHING);
819 }
820
821 /*!
822  \brief Start delayed viewer operation.
823  */
824 bool XGUI_ViewWindow::setTransformRequested(OperationType op)
825 {
826   bool ok = transformEnabled(op);
827   myOperation = ok ? op : NOTHING;
828   myViewPort->setMouseTracking(myOperation == NOTHING);
829   return ok;
830 }
831
832 /*!
833  Set enabled state of transformation (rotate, zoom, etc)
834  */
835 void XGUI_ViewWindow::setTransformEnabled(const OperationType id, const bool on)
836 {
837   if (id != NOTHING)
838     myStatus.insert(id, on);
839 }
840
841 /*!
842  \return enabled state of transformation (rotate, zoom, etc)
843  */
844 bool XGUI_ViewWindow::transformEnabled(const OperationType id) const
845 {
846   return myStatus.contains(id) ? myStatus[id] : true;
847 }
848
849 /*!
850  \brief Start panning operation.
851
852  Sets the corresponding cursor for the widget.
853  */
854 void XGUI_ViewWindow::activatePanning()
855 {
856   if (!transformRequested() && !myCursorIsHand)
857     myCursor = cursor();                // save old cursor
858
859   if (myOperation != PANVIEW) {
860     QCursor panCursor(Qt::SizeAllCursor);
861     if (setTransformRequested(PANVIEW))
862       myViewPort->setCursor(panCursor);
863   }
864 }
865
866 /*!
867   \brief Start global panning operation
868
869   Sets the corresponding cursor for the widget.
870 */
871 void XGUI_ViewWindow::activateGlobalPanning()
872 {
873   Handle(V3d_View) aView3d = myViewPort->getView();
874   if ( !aView3d.IsNull() ) {
875     QPixmap globalPanPixmap (imageCrossCursor);
876     QCursor glPanCursor (globalPanPixmap);
877     myCurScale = aView3d->Scale();
878     aView3d->FitAll(0.01, false);
879     myCursor = cursor();                // save old cursor
880     myViewPort->fitAll(); // fits view before selecting a new scene center
881     if( setTransformRequested( PANGLOBAL ) )
882       myViewPort->setCursor( glPanCursor );
883   }
884 }
885
886 /*!
887  \brief Start rotation operation
888
889  Sets the corresponding cursor for the widget.
890  */
891 void XGUI_ViewWindow::activateRotation()
892 {
893   if (!transformRequested() && !myCursorIsHand)
894     myCursor = cursor();                // save old cursor
895
896   if (myOperation != ROTATE) {
897     QPixmap rotatePixmap(imageRotateCursor);
898     QCursor rotCursor(rotatePixmap);
899     if (setTransformRequested(ROTATE))
900       myViewPort->setCursor(rotCursor);
901   }
902 }
903
904 /*!
905  \brief Reset the viewport to its initial state
906  ( no transformations in process etc. )
907  */
908 void XGUI_ViewWindow::resetState()
909 {
910   myDrawRect = false;
911
912   if (myRotationPointSelection) {
913     QCursor handCursor(Qt::PointingHandCursor);
914     myViewPort->setCursor(handCursor);
915   } else {
916     if (transformRequested() || myCursorIsHand)
917       myViewPort->setCursor(myCursor);
918     myCursorIsHand = false;
919   }
920
921   if (transformRequested())
922     emit vpTransformationFinished(myOperation);
923
924   setTransformInProcess(false);
925   setTransformRequested(NOTHING);
926 }
927
928 XGUI_ViewBackground XGUI_ViewWindow::background() const
929 {
930   return myViewPort ? myViewPort->background() : XGUI_ViewBackground();
931 }
932
933 void XGUI_ViewWindow::setBackground(const XGUI_ViewBackground& theBackground)
934 {
935   if (myViewPort) 
936         myViewPort->setBackground( theBackground );
937 }
938
939 /*!
940    \brief Create one more window with same content.
941 */
942 void XGUI_ViewWindow::cloneView()
943 {
944   QMdiSubWindow* vw = myViewer->createView();
945   XGUI_ViewWindow* aNewWnd = static_cast<XGUI_ViewWindow*>(vw->widget());
946   aNewWnd->viewPort()->syncronizeWith(myViewPort);
947   emit viewCloned( vw );
948 }
949
950 void XGUI_ViewWindow::dumpView()
951 {
952   QString aFilter(tr("Images Files (*.bmp *.png *.jpg *.jpeg *.eps *.ps)"));
953   QString aSelectedFilter;
954   QString aFileName = QFileDialog::getSaveFileName(this, "Save picture", QString(), aFilter, &aSelectedFilter);
955   if (!aFileName.isNull()) {
956     QApplication::setOverrideCursor( Qt::WaitCursor );
957     QImage aPicture = myViewPort->dumpView();
958
959     QString aFmt = extension(aFileName).toUpper();
960     if( aFmt.isEmpty() )
961       aFmt = QString( "BMP" ); // default format
962     else if( aFmt == "JPG" )
963       aFmt = "JPEG";
964
965     Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
966     if (aFmt == "PS")
967       a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_PostScript);
968     else if (aFmt == "EPS")
969       a3dView->Export(strdup(qPrintable(aFileName)), Graphic3d_EF_EnhPostScript);
970     else
971       aPicture.save( aFileName, aFmt.toLatin1() );
972     QApplication::restoreOverrideCursor();
973   }
974 }
975
976 void XGUI_ViewWindow::fitAll()
977 {
978   emit vpTransformationStarted( FITALLVIEW );
979   myViewPort->fitAll();
980   emit vpTransformationFinished( FITALLVIEW );
981 }
982
983 /*!
984   \brief Starts fit operation.
985
986   Sets the corresponding cursor for the widget.
987 */
988 void XGUI_ViewWindow::activateWindowFit()
989 {
990   if ( !transformRequested() && !myCursorIsHand )
991     myCursor = cursor();                /* save old cursor */
992
993   if ( myOperation != WINDOWFIT ) {
994     QCursor handCursor (Qt::PointingHandCursor);
995     if( setTransformRequested ( WINDOWFIT ) ) {
996       myViewPort->setCursor ( handCursor );
997       myCursorIsHand = true;
998     }
999   }
1000 }
1001
1002
1003 /*!
1004   \brief Perform "front view" transformation.
1005 */
1006 void XGUI_ViewWindow::frontView()
1007 {
1008   emit vpTransformationStarted ( FRONTVIEW );
1009   Handle(V3d_View) aView3d = myViewPort->getView();
1010   if ( !aView3d.IsNull() ) 
1011     aView3d->SetProj (V3d_Xpos);
1012   myViewPort->fitAll();
1013   emit vpTransformationFinished ( FRONTVIEW );
1014 }
1015
1016 /*!
1017   \brief Perform "back view" transformation.
1018 */
1019 void XGUI_ViewWindow::backView()
1020 {
1021   emit vpTransformationStarted ( BACKVIEW );
1022   Handle(V3d_View) aView3d = myViewPort->getView();
1023   if ( !aView3d.IsNull() ) 
1024     aView3d->SetProj (V3d_Xneg);
1025   myViewPort->fitAll();
1026   emit vpTransformationFinished ( BACKVIEW );
1027 }
1028
1029 /*!
1030   \brief Perform "top view" transformation.
1031 */
1032 void XGUI_ViewWindow::topView()
1033 {
1034   emit vpTransformationStarted ( TOPVIEW );
1035   Handle(V3d_View) aView3d = myViewPort->getView();
1036   if ( !aView3d.IsNull() ) 
1037     aView3d->SetProj (V3d_Zpos);
1038   myViewPort->fitAll();
1039   emit vpTransformationFinished ( TOPVIEW );
1040 }
1041
1042 /*!
1043   \brief Perform "bottom view" transformation.
1044 */
1045 void XGUI_ViewWindow::bottomView()
1046 {
1047   emit vpTransformationStarted ( BOTTOMVIEW );
1048   Handle(V3d_View) aView3d = myViewPort->getView();
1049   if ( !aView3d.IsNull() ) 
1050     aView3d->SetProj (V3d_Zneg);
1051   myViewPort->fitAll();
1052   emit vpTransformationFinished ( BOTTOMVIEW );
1053 }
1054
1055 /*!
1056   \brief Perform "left view" transformation.
1057 */
1058 void XGUI_ViewWindow::leftView()
1059 {
1060   emit vpTransformationStarted ( LEFTVIEW );
1061   Handle(V3d_View) aView3d = myViewPort->getView();
1062   if ( !aView3d.IsNull() ) 
1063     aView3d->SetProj (V3d_Yneg);
1064   myViewPort->fitAll();
1065   emit vpTransformationFinished ( LEFTVIEW );
1066 }
1067
1068 /*!
1069   \brief Perform "right view" transformation.
1070 */
1071 void XGUI_ViewWindow::rightView()
1072 {
1073   emit vpTransformationStarted ( RIGHTVIEW );
1074   Handle(V3d_View) aView3d = myViewPort->getView();
1075   if ( !aView3d.IsNull() ) 
1076     aView3d->SetProj (V3d_Ypos);
1077   myViewPort->fitAll();
1078   emit vpTransformationFinished ( RIGHTVIEW );
1079 }
1080
1081 void XGUI_ViewWindow::reset()
1082 {
1083   emit vpTransformationStarted( RESETVIEW );
1084   bool upd = myViewPort->getView()->SetImmediateUpdate( false );
1085   myViewPort->getView()->Reset( false );
1086   myViewPort->fitAll( false, true, false );
1087   myViewPort->getView()->SetImmediateUpdate( upd );
1088   myViewPort->getView()->Update();
1089   emit vpTransformationFinished( RESETVIEW );
1090 }
1091
1092
1093 void XGUI_ViewWindow::updateToolBar()
1094 {
1095   myGripWgt->update();
1096   myViewBar->update();
1097   myWindowBar->update();
1098   //QTimer::singleShot(50, Qt::VeryCoarseTimer, this, SLOT(repaintToolBar()));
1099 }
1100
1101 /*void XGUI_ViewWindow::repaintToolBar()
1102 {
1103   QApplication::sync();
1104   myGripWgt->repaint();
1105   myViewBar->repaint();
1106   myWindowBar->repaint();
1107 }*/