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