4f140d282f2d0b3e8e1043f2a181cf0cbfeb1f4a
[occt.git] / samples / qt / Common / src / View.cxx
1 #if !defined _WIN32
2 #define QT_CLEAN_NAMESPACE         /* avoid definition of INT32 and INT8 */
3 #endif
4
5 #include "View.h"
6 #include "ApplicationCommon.h"
7
8 #include <Standard_WarningsDisable.hxx>
9 #include <QApplication>
10 #include <QPainter>
11 #include <QMenu>
12 #include <QColorDialog>
13 #include <QCursor>
14 #include <QFileInfo>
15 #include <QFileDialog>
16 #include <QMouseEvent>
17 #include <QRubberBand>
18 #include <QMdiSubWindow>
19 #include <QStyleFactory>
20 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && QT_VERSION < 0x050000
21   #include <QX11Info>
22 #endif
23 #include <Standard_WarningsRestore.hxx>
24
25
26 #include <Graphic3d_GraphicDriver.hxx>
27 #include <Graphic3d_TextureEnv.hxx>
28
29 #include <OcctWindow.h>
30 #include <Aspect_DisplayConnection.hxx>
31
32 // the key for multi selection :
33 #define MULTISELECTIONKEY Qt::ShiftModifier
34
35 // the key for shortcut ( use to activate dynamic rotation, panning )
36 #define CASCADESHORTCUTKEY Qt::ControlModifier
37
38 // for elastic bean selection
39 #define ValZWMin 1
40
41 static QCursor* defCursor     = NULL;
42 static QCursor* handCursor    = NULL;
43 static QCursor* panCursor     = NULL;
44 static QCursor* globPanCursor = NULL;
45 static QCursor* zoomCursor    = NULL;
46 static QCursor* rotCursor     = NULL;
47
48 View::View( Handle(AIS_InteractiveContext) theContext, QWidget* parent )
49 : QWidget( parent ),
50   myIsRaytracing( false ),
51   myIsShadowsEnabled (true),
52   myIsReflectionsEnabled (false),
53   myIsAntialiasingEnabled (false),
54   myViewActions( 0 ),
55   myRaytraceActions( 0 ),
56   myBackMenu( NULL )
57 {
58 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && QT_VERSION < 0x050000
59   XSynchronize(x11Info().display(),true);
60 #endif
61   myContext = theContext;
62
63   myXmin = 0;
64   myYmin = 0;
65   myXmax = 0;
66   myYmax = 0;
67   myCurZoom = 0;
68   myRectBand = 0;
69
70   setAttribute(Qt::WA_PaintOnScreen);
71   setAttribute(Qt::WA_NoSystemBackground);
72
73   myCurrentMode = CurAction3d_Nothing;
74   myHlrModeIsOn = Standard_False;
75   setMouseTracking( true );
76
77   initViewActions();
78   initCursors();
79
80   setBackgroundRole( QPalette::NoRole );//NoBackground );
81   // set focus policy to threat QContextMenuEvent from keyboard  
82   setFocusPolicy( Qt::StrongFocus );
83   setAttribute( Qt::WA_PaintOnScreen );
84   setAttribute( Qt::WA_NoSystemBackground );
85   init();
86 }
87
88 View::~View()
89 {
90   delete myBackMenu;
91 }
92
93 void View::init()
94 {
95   if ( myView.IsNull() )
96     myView = myContext->CurrentViewer()->CreateView();
97
98   Handle(OcctWindow) hWnd = new OcctWindow ( this );
99   myView->SetWindow (hWnd);
100   if ( !hWnd->IsMapped() )
101   {
102     hWnd->Map();
103   }
104   myView->SetBackgroundColor (Quantity_NOC_BLACK);
105   myView->MustBeResized();
106
107   if (myIsRaytracing)
108     myView->ChangeRenderingParams().Method = Graphic3d_RM_RAYTRACING;
109 }
110
111 void View::paintEvent( QPaintEvent *  )
112 {
113 //  QApplication::syncX();
114   myView->Redraw();
115 }
116
117 void View::resizeEvent( QResizeEvent * )
118 {
119 //  QApplication::syncX();
120   if( !myView.IsNull() )
121   {
122     myView->MustBeResized();
123   }
124 }
125
126 void View::fitAll()
127 {
128   myView->FitAll();
129   myView->ZFitAll();
130   myView->Redraw();
131 }
132
133 void View::fitArea()
134 {
135   myCurrentMode = CurAction3d_WindowZooming;
136 }
137
138 void View::zoom()
139 {
140   myCurrentMode = CurAction3d_DynamicZooming;
141 }
142
143 void View::pan()
144 {
145   myCurrentMode = CurAction3d_DynamicPanning;
146 }
147
148 void View::rotation()
149 {
150   myCurrentMode = CurAction3d_DynamicRotation;
151 }
152
153 void View::globalPan()
154 {
155   // save the current zoom value
156   myCurZoom = myView->Scale();
157   // Do a Global Zoom
158   myView->FitAll();
159   // Set the mode
160   myCurrentMode = CurAction3d_GlobalPanning;
161 }
162
163 void View::front()
164 {
165   myView->SetProj( V3d_Yneg );
166 }
167
168 void View::back()
169 {
170   myView->SetProj( V3d_Ypos );
171 }
172
173 void View::top()
174 {
175   myView->SetProj( V3d_Zpos );
176 }
177
178 void View::bottom()
179 {
180   myView->SetProj( V3d_Zneg );
181 }
182
183 void View::left()
184 {
185   myView->SetProj( V3d_Xneg );
186 }
187
188 void View::right()
189 {
190   myView->SetProj( V3d_Xpos );
191 }
192
193 void View::axo()
194 {
195   myView->SetProj( V3d_XposYnegZpos );
196 }
197
198 void View::reset()
199 {
200   myView->Reset();
201 }
202
203 void View::hlrOff()
204 {
205   QApplication::setOverrideCursor( Qt::WaitCursor );
206   myHlrModeIsOn = Standard_False;
207   myView->SetComputedMode (myHlrModeIsOn);
208   myView->Redraw();
209   QApplication::restoreOverrideCursor();
210 }
211
212 void View::hlrOn()
213 {
214   QApplication::setOverrideCursor( Qt::WaitCursor );
215   myHlrModeIsOn = Standard_True;
216   myView->SetComputedMode (myHlrModeIsOn);
217   myView->Redraw();
218   QApplication::restoreOverrideCursor();
219 }
220
221 void View::SetRaytracedShadows (bool theState)
222 {
223   myView->ChangeRenderingParams().IsShadowEnabled = theState;
224
225   myIsShadowsEnabled = theState;
226
227   myContext->UpdateCurrentViewer();
228 }
229
230 void View::SetRaytracedReflections (bool theState)
231 {
232   myView->ChangeRenderingParams().IsReflectionEnabled = theState;
233
234   myIsReflectionsEnabled = theState;
235
236   myContext->UpdateCurrentViewer();
237 }
238
239 void View::onRaytraceAction()
240 {
241   QAction* aSentBy = (QAction*)sender();
242   
243   if (aSentBy == myRaytraceActions->at (ToolRaytracingId))
244   {
245     bool aState = myRaytraceActions->at (ToolRaytracingId)->isChecked(); 
246
247     QApplication::setOverrideCursor (Qt::WaitCursor);
248     if (aState)
249       EnableRaytracing();
250     else
251       DisableRaytracing();
252     QApplication::restoreOverrideCursor();
253   }
254
255   if (aSentBy == myRaytraceActions->at (ToolShadowsId))
256   {
257     bool aState = myRaytraceActions->at (ToolShadowsId)->isChecked(); 
258     SetRaytracedShadows (aState);
259   }
260
261   if (aSentBy == myRaytraceActions->at (ToolReflectionsId))
262   {
263     bool aState = myRaytraceActions->at (ToolReflectionsId)->isChecked();
264     SetRaytracedReflections (aState);
265   }
266
267   if (aSentBy == myRaytraceActions->at (ToolAntialiasingId))
268   {
269     bool aState = myRaytraceActions->at (ToolAntialiasingId)->isChecked();
270     SetRaytracedAntialiasing (aState);
271   }
272 }
273
274 void View::SetRaytracedAntialiasing (bool theState)
275 {
276   myView->ChangeRenderingParams().IsAntialiasingEnabled = theState;
277
278   myIsAntialiasingEnabled = theState;
279
280   myContext->UpdateCurrentViewer();
281 }
282
283 void View::EnableRaytracing()
284 {
285   if (!myIsRaytracing)
286     myView->ChangeRenderingParams().Method = Graphic3d_RM_RAYTRACING;
287
288   myIsRaytracing = true;
289
290   myContext->UpdateCurrentViewer();
291 }
292
293 void View::DisableRaytracing()
294 {
295   if (myIsRaytracing)
296     myView->ChangeRenderingParams().Method = Graphic3d_RM_RASTERIZATION;
297
298   myIsRaytracing = false;
299
300   myContext->UpdateCurrentViewer();
301 }
302
303 void View::updateToggled( bool isOn )
304 {
305   QAction* sentBy = (QAction*)sender();
306
307   if( !isOn )
308     return;
309
310   for ( int i = ViewFitAllId; i < ViewHlrOffId; i++ )
311   {
312     QAction* anAction = myViewActions->at( i );
313     
314     if ( ( anAction == myViewActions->at( ViewFitAreaId ) ) ||
315          ( anAction == myViewActions->at( ViewZoomId ) ) ||
316          ( anAction == myViewActions->at( ViewPanId ) ) ||
317          ( anAction == myViewActions->at( ViewGlobalPanId ) ) ||
318          ( anAction == myViewActions->at( ViewRotationId ) ) )
319     {
320       if ( anAction && ( anAction != sentBy ) )
321       {
322         anAction->setCheckable( true );
323         anAction->setChecked( false );
324       }
325       else
326       {
327         if ( sentBy == myViewActions->at( ViewFitAreaId ) )
328           setCursor( *handCursor );
329         else if ( sentBy == myViewActions->at( ViewZoomId ) )
330           setCursor( *zoomCursor );
331         else if ( sentBy == myViewActions->at( ViewPanId ) )
332           setCursor( *panCursor );
333         else if ( sentBy == myViewActions->at( ViewGlobalPanId ) )
334           setCursor( *globPanCursor );
335         else if ( sentBy == myViewActions->at( ViewRotationId ) )
336           setCursor( *rotCursor );
337         else
338           setCursor( *defCursor );
339
340         sentBy->setCheckable( false );
341       }
342     }
343   }
344 }
345
346 void View::initCursors()
347 {
348   if ( !defCursor )
349     defCursor = new QCursor( Qt::ArrowCursor );
350   if ( !handCursor )
351     handCursor = new QCursor( Qt::PointingHandCursor );
352   if ( !panCursor )
353     panCursor = new QCursor( Qt::SizeAllCursor );
354   if ( !globPanCursor )
355     globPanCursor = new QCursor( Qt::CrossCursor );
356   if ( !zoomCursor )
357     zoomCursor = new QCursor( QPixmap( ApplicationCommonWindow::getResourceDir() + QString( "/" ) + QObject::tr( "ICON_CURSOR_ZOOM" ) ) );
358   if ( !rotCursor )
359     rotCursor = new QCursor( QPixmap( ApplicationCommonWindow::getResourceDir() + QString( "/" ) + QObject::tr( "ICON_CURSOR_ROTATE" ) ) );
360 }
361
362 QList<QAction*>* View::getViewActions()
363 {
364   initViewActions();
365   return myViewActions;
366 }
367
368 QList<QAction*>* View::getRaytraceActions()
369 {
370   initRaytraceActions();
371   return myRaytraceActions;
372 }
373
374 /*!
375   Get paint engine for the OpenGL viewer. [ virtual public ]
376 */
377 QPaintEngine* View::paintEngine() const
378 {
379   return 0;
380 }
381
382 void View::initViewActions()
383 {
384   if ( myViewActions )
385     return;
386
387   myViewActions = new QList<QAction*>();
388   QString dir = ApplicationCommonWindow::getResourceDir() + QString( "/" );
389   QAction* a;
390
391   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_FITALL") ), QObject::tr("MNU_FITALL"), this );
392   a->setToolTip( QObject::tr("TBR_FITALL") );
393   a->setStatusTip( QObject::tr("TBR_FITALL") );
394   connect( a, SIGNAL( triggered() ) , this, SLOT( fitAll() ) );
395   myViewActions->insert(ViewFitAllId, a);
396
397   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_FITAREA") ), QObject::tr("MNU_FITAREA"), this );
398   a->setToolTip( QObject::tr("TBR_FITAREA") );
399   a->setStatusTip( QObject::tr("TBR_FITAREA") );
400   connect( a, SIGNAL( triggered() ) , this, SLOT( fitArea() ) );
401
402   a->setCheckable( true );
403   connect( a, SIGNAL( toggled( bool ) ) , this, SLOT( updateToggled( bool ) ) );
404   myViewActions->insert( ViewFitAreaId, a );
405
406   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_ZOOM") ), QObject::tr("MNU_ZOOM"), this );
407   a->setToolTip( QObject::tr("TBR_ZOOM") );
408   a->setStatusTip( QObject::tr("TBR_ZOOM") );
409   connect( a, SIGNAL( triggered() ) , this, SLOT( zoom() ) );
410
411   a->setCheckable( true );
412   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
413   myViewActions->insert( ViewZoomId, a );
414
415   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_PAN") ), QObject::tr("MNU_PAN"), this );
416   a->setToolTip( QObject::tr("TBR_PAN") );
417   a->setStatusTip( QObject::tr("TBR_PAN") );
418   connect( a, SIGNAL( triggered() ) , this, SLOT( pan() ) );
419
420   a->setCheckable( true );
421   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
422   myViewActions->insert( ViewPanId, a );
423
424   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_GLOBALPAN") ), QObject::tr("MNU_GLOBALPAN"), this );
425   a->setToolTip( QObject::tr("TBR_GLOBALPAN") );
426   a->setStatusTip( QObject::tr("TBR_GLOBALPAN") );
427   connect( a, SIGNAL( triggered() ) , this, SLOT( globalPan() ) );
428
429   a->setCheckable( true );
430   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
431   myViewActions->insert( ViewGlobalPanId, a );
432
433   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_FRONT") ), QObject::tr("MNU_FRONT"), this );
434   a->setToolTip( QObject::tr("TBR_FRONT") );
435   a->setStatusTip( QObject::tr("TBR_FRONT") );
436   connect( a, SIGNAL( triggered() ) , this, SLOT( front() ) );
437   myViewActions->insert( ViewFrontId, a );
438
439   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_BACK") ), QObject::tr("MNU_BACK"), this );
440   a->setToolTip( QObject::tr("TBR_BACK") );
441   a->setStatusTip( QObject::tr("TBR_BACK") );
442   connect( a, SIGNAL( triggered() ) , this, SLOT( back() ) );
443   myViewActions->insert(ViewBackId, a);
444
445   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_TOP") ), QObject::tr("MNU_TOP"), this );
446   a->setToolTip( QObject::tr("TBR_TOP") );
447   a->setStatusTip( QObject::tr("TBR_TOP") );
448   connect( a, SIGNAL( triggered() ) , this, SLOT( top() ) );
449   myViewActions->insert( ViewTopId, a );
450
451   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_BOTTOM") ), QObject::tr("MNU_BOTTOM"), this );
452   a->setToolTip( QObject::tr("TBR_BOTTOM") );
453   a->setStatusTip( QObject::tr("TBR_BOTTOM") );
454   connect( a, SIGNAL( triggered() ) , this, SLOT( bottom() ) );
455   myViewActions->insert( ViewBottomId, a );
456
457   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_LEFT") ), QObject::tr("MNU_LEFT"), this );
458   a->setToolTip( QObject::tr("TBR_LEFT") );
459   a->setStatusTip( QObject::tr("TBR_LEFT") );
460   connect( a, SIGNAL( triggered() ) , this, SLOT( left() ) );
461   myViewActions->insert( ViewLeftId, a );
462
463   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_RIGHT") ), QObject::tr("MNU_RIGHT"), this );
464   a->setToolTip( QObject::tr("TBR_RIGHT") );
465   a->setStatusTip( QObject::tr("TBR_RIGHT") );
466   connect( a, SIGNAL( triggered() ) , this, SLOT( right() ) );
467   myViewActions->insert( ViewRightId, a );
468
469   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_AXO") ), QObject::tr("MNU_AXO"), this );
470   a->setToolTip( QObject::tr("TBR_AXO") );
471   a->setStatusTip( QObject::tr("TBR_AXO") );
472   connect( a, SIGNAL( triggered() ) , this, SLOT( axo() ) );
473   myViewActions->insert( ViewAxoId, a );
474
475   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_ROTATION") ), QObject::tr("MNU_ROTATION"), this );
476   a->setToolTip( QObject::tr("TBR_ROTATION") );
477   a->setStatusTip( QObject::tr("TBR_ROTATION") );
478   connect( a, SIGNAL( triggered() ) , this, SLOT( rotation() ) );
479   a->setCheckable( true );
480   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
481   myViewActions->insert( ViewRotationId, a );
482
483   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_RESET") ), QObject::tr("MNU_RESET"), this );
484   a->setToolTip( QObject::tr("TBR_RESET") );
485   a->setStatusTip( QObject::tr("TBR_RESET") );
486   connect( a, SIGNAL( triggered() ) , this, SLOT( reset() ) );
487   myViewActions->insert( ViewResetId, a );
488
489   QActionGroup* ag = new QActionGroup( this );
490
491   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_HLROFF") ), QObject::tr("MNU_HLROFF"), this );
492   a->setToolTip( QObject::tr("TBR_HLROFF") );
493   a->setStatusTip( QObject::tr("TBR_HLROFF") );
494   connect( a, SIGNAL( triggered() ) , this, SLOT( hlrOff() ) );
495   a->setCheckable( true );
496   ag->addAction(a);
497   myViewActions->insert(ViewHlrOffId, a);
498
499   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_HLRON") ), QObject::tr("MNU_HLRON"), this );
500   a->setToolTip( QObject::tr("TBR_HLRON") );
501   a->setStatusTip( QObject::tr("TBR_HLRON") );
502   connect( a, SIGNAL( triggered() ) ,this, SLOT( hlrOn() ) );
503   
504   a->setCheckable( true );
505   ag->addAction(a);
506   myViewActions->insert( ViewHlrOnId, a );
507 }
508
509 void View::initRaytraceActions()
510 {
511   if ( myRaytraceActions )
512     return;
513
514   myRaytraceActions = new QList<QAction*>();
515   QString dir = ApplicationCommonWindow::getResourceDir() + QString( "/" );
516   QAction* a;
517
518   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_RAYTRACING") ), QObject::tr("MNU_TOOL_RAYTRACING"), this );
519   a->setToolTip( QObject::tr("TBR_TOOL_RAYTRACING") );
520   a->setStatusTip( QObject::tr("TBR_TOOL_RAYTRACING") );
521   a->setCheckable( true );
522   a->setChecked( false );
523   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
524   myRaytraceActions->insert( ToolRaytracingId, a );
525
526   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_SHADOWS") ), QObject::tr("MNU_TOOL_SHADOWS"), this );
527   a->setToolTip( QObject::tr("TBR_TOOL_SHADOWS") );
528   a->setStatusTip( QObject::tr("TBR_TOOL_SHADOWS") );
529   a->setCheckable( true );
530   a->setChecked( true );
531   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
532   myRaytraceActions->insert( ToolShadowsId, a );
533
534   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_REFLECTIONS") ), QObject::tr("MNU_TOOL_REFLECTIONS"), this );
535   a->setToolTip( QObject::tr("TBR_TOOL_REFLECTIONS") );
536   a->setStatusTip( QObject::tr("TBR_TOOL_REFLECTIONS") );
537   a->setCheckable( true );
538   a->setChecked( false );
539   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
540   myRaytraceActions->insert( ToolReflectionsId, a );
541
542   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_ANTIALIASING") ), QObject::tr("MNU_TOOL_ANTIALIASING"), this );
543   a->setToolTip( QObject::tr("TBR_TOOL_ANTIALIASING") );
544   a->setStatusTip( QObject::tr("TBR_TOOL_ANTIALIASING") );
545   a->setCheckable( true );
546   a->setChecked( false );
547   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
548   myRaytraceActions->insert( ToolAntialiasingId, a );
549 }
550
551 void View::mousePressEvent( QMouseEvent* e )
552 {
553   if ( e->button() == Qt::LeftButton )
554     onLButtonDown( ( e->buttons() | e->modifiers() ), e->pos() );
555   else if ( e->button() == Qt::MidButton )
556     onMButtonDown( e->buttons() | e->modifiers(), e->pos() );
557   else if ( e->button() == Qt::RightButton )
558     onRButtonDown( e->buttons() | e->modifiers(), e->pos() );
559 }
560
561 void View::mouseReleaseEvent(QMouseEvent* e)
562 {
563   if ( e->button() == Qt::LeftButton )
564     onLButtonUp( e->buttons(), e->pos() );
565   else if ( e->button() == Qt::MidButton )
566     onMButtonUp( e->buttons(), e->pos() );
567   else if( e->button() == Qt::RightButton )
568     onRButtonUp( e->buttons(), e->pos() );
569 }
570
571 void View::mouseMoveEvent(QMouseEvent* e)
572 {
573   onMouseMove( e->buttons(), e->pos() );
574 }
575
576 void View::activateCursor( const CurrentAction3d mode )
577 {
578   switch( mode )
579   {
580     case CurAction3d_DynamicPanning:
581       setCursor( *panCursor );
582       break;
583     case CurAction3d_DynamicZooming:
584       setCursor( *zoomCursor );
585       break;
586     case CurAction3d_DynamicRotation:
587       setCursor( *rotCursor );
588       break;
589     case CurAction3d_GlobalPanning:
590       setCursor( *globPanCursor );
591       break;
592     case CurAction3d_WindowZooming:
593       setCursor( *handCursor );
594       break;
595     case CurAction3d_Nothing:
596     default:
597       setCursor( *defCursor );
598       break;
599   }
600 }
601
602 void View::onLButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint point )
603 {
604   //  save the current mouse coordinate in min
605   myXmin = point.x();
606   myYmin = point.y();
607   myXmax = point.x();
608   myYmax = point.y();
609
610   if ( nFlags & CASCADESHORTCUTKEY )
611   {
612     myCurrentMode = CurAction3d_DynamicZooming;
613   }
614   else
615   {
616     switch ( myCurrentMode )
617     {
618       case CurAction3d_Nothing:
619            if ( nFlags & MULTISELECTIONKEY )
620              MultiDragEvent( myXmax, myYmax, -1 );
621            else
622              DragEvent( myXmax, myYmax, -1 );
623            break;
624       case CurAction3d_DynamicZooming:
625            break;
626       case CurAction3d_WindowZooming:
627            break;
628       case CurAction3d_DynamicPanning:
629            break;
630       case CurAction3d_GlobalPanning:
631            break;
632       case CurAction3d_DynamicRotation:
633            if (myHlrModeIsOn)
634            {
635              myView->SetComputedMode (Standard_False);
636            }
637            myView->StartRotation( point.x(), point.y() );
638            break;
639       default:
640            throw Standard_Failure( "incompatible Current Mode" );
641            break;
642     }
643   }
644   activateCursor( myCurrentMode );
645 }
646
647 void View::onMButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint /*point*/ )
648 {
649   if ( nFlags & CASCADESHORTCUTKEY )
650     myCurrentMode = CurAction3d_DynamicPanning;
651   activateCursor( myCurrentMode );
652 }
653
654 void View::onRButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint point )
655 {
656   if ( nFlags & CASCADESHORTCUTKEY )
657   {
658     if (myHlrModeIsOn)
659     {
660       myView->SetComputedMode (Standard_False);
661     }
662     myCurrentMode = CurAction3d_DynamicRotation;
663     myView->StartRotation( point.x(), point.y() );
664   }
665   else
666   {
667     Popup( point.x(), point.y() );
668   }
669   activateCursor( myCurrentMode );
670 }
671
672 void View::onLButtonUp( Qt::MouseButtons nFlags, const QPoint point )
673 {
674     switch( myCurrentMode )
675     {
676         case CurAction3d_Nothing:
677             if ( point.x() == myXmin && point.y() == myYmin )
678             {
679               // no offset between down and up --> selectEvent
680               myXmax = point.x();
681               myYmax = point.y();
682               if ( nFlags & MULTISELECTIONKEY )
683                   MultiInputEvent( point.x(), point.y() );
684               else
685                   InputEvent( point.x(), point.y() );
686             }
687             else
688             {
689               DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );
690               myXmax = point.x();
691               myYmax = point.y();
692               if ( nFlags & MULTISELECTIONKEY )
693                   MultiDragEvent( point.x(), point.y(), 1 );
694               else
695                   DragEvent( point.x(), point.y(), 1 );
696             }
697             break;
698         case CurAction3d_DynamicZooming:
699             myCurrentMode = CurAction3d_Nothing;
700             noActiveActions();
701             break;
702         case CurAction3d_WindowZooming:
703             DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );//,LongDash);
704             myXmax = point.x();
705             myYmax = point.y();
706             if ( (abs( myXmin - myXmax ) > ValZWMin ) ||
707                  (abs( myYmin - myYmax ) > ValZWMin ) )
708               myView->WindowFitAll( myXmin, myYmin, myXmax, myYmax );
709             myCurrentMode = CurAction3d_Nothing;
710             noActiveActions();
711             break;
712         case CurAction3d_DynamicPanning:
713             myCurrentMode = CurAction3d_Nothing;
714             noActiveActions();
715             break;
716         case CurAction3d_GlobalPanning :
717             myView->Place( point.x(), point.y(), myCurZoom );
718             myCurrentMode = CurAction3d_Nothing;
719             noActiveActions();
720             break;
721         case CurAction3d_DynamicRotation:
722             myCurrentMode = CurAction3d_Nothing;
723             noActiveActions();
724             break;
725         default:
726             throw Standard_Failure(" incompatible Current Mode ");
727             break;
728     }
729     activateCursor( myCurrentMode );
730     ApplicationCommonWindow::getApplication()->onSelectionChanged();
731 }
732
733 void View::onMButtonUp( Qt::MouseButtons /*nFlags*/, const QPoint /*point*/ )
734 {
735     myCurrentMode = CurAction3d_Nothing;
736     activateCursor( myCurrentMode );
737 }
738
739 void View::onRButtonUp( Qt::MouseButtons /*nFlags*/, const QPoint point )
740 {
741     if ( myCurrentMode == CurAction3d_Nothing )
742         Popup( point.x(), point.y() );
743     else
744     {
745         QApplication::setOverrideCursor( Qt::WaitCursor );
746         // reset tyhe good Degenerated mode according to the strored one
747         //   --> dynamic rotation may have change it
748         if (myHlrModeIsOn)
749         {
750           myView->SetComputedMode (myHlrModeIsOn);
751           myView->Redraw();
752         }
753         QApplication::restoreOverrideCursor();
754         myCurrentMode = CurAction3d_Nothing;
755     }
756     activateCursor( myCurrentMode );
757 }
758
759 void View::onMouseMove( Qt::MouseButtons nFlags, const QPoint point )
760 {
761     if ( nFlags & Qt::LeftButton || nFlags & Qt::RightButton || nFlags & Qt::MidButton )
762     {
763     switch ( myCurrentMode )
764     {
765         case CurAction3d_Nothing:
766           myXmax = point.x();
767           myYmax = point.y();
768           DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );
769           if ( nFlags & MULTISELECTIONKEY )
770               MultiDragEvent( myXmax, myYmax, 0 );
771           else
772             DragEvent( myXmax, myYmax, 0 );
773             DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_True );
774             break;
775         case CurAction3d_DynamicZooming:
776           myView->Zoom( myXmax, myYmax, point.x(), point.y() );
777           myXmax = point.x();
778           myYmax = point.y();
779           break;
780         case CurAction3d_WindowZooming:
781           myXmax = point.x();
782           myYmax = point.y();
783           DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );
784           DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_True );
785           break;
786         case CurAction3d_DynamicPanning:
787           myView->Pan( point.x() - myXmax, myYmax - point.y() );
788           myXmax = point.x();
789           myYmax = point.y();
790           break;
791         case CurAction3d_GlobalPanning:
792           break;
793         case CurAction3d_DynamicRotation:
794           myView->Rotation( point.x(), point.y() );
795           myView->Redraw();
796           break;
797         default:
798           throw Standard_Failure( "incompatible Current Mode" );
799           break;
800     }
801     }
802     else
803     {
804         myXmax = point.x();
805         myYmax = point.y();
806       if ( nFlags & MULTISELECTIONKEY )
807           MultiMoveEvent( point.x(), point.y() );
808       else
809           MoveEvent( point.x(), point.y() );
810     }
811 }
812
813 void View::DragEvent( const int x, const int y, const int TheState )
814 {
815     // TheState == -1  button down
816     // TheState ==  0  move
817     // TheState ==  1  button up
818
819     static Standard_Integer theButtonDownX = 0;
820     static Standard_Integer theButtonDownY = 0;
821
822     if ( TheState == -1 )
823     {
824         theButtonDownX = x;
825         theButtonDownY = y;
826     }
827
828     if ( TheState == 1 )
829     {
830         myContext->Select( theButtonDownX, theButtonDownY, x, y, myView, Standard_True );
831         emit selectionChanged();
832     }
833 }
834
835 void View::InputEvent( const int /*x*/, const int /*y*/ )
836 {
837   myContext->Select (Standard_True);
838   emit selectionChanged();
839 }
840
841 void View::MoveEvent( const int x, const int y )
842 {
843   myContext->MoveTo( x, y, myView, Standard_True );
844 }
845
846 void View::MultiMoveEvent( const int x, const int y )
847 {
848   myContext->MoveTo( x, y, myView, Standard_True );
849 }
850
851 void View::MultiDragEvent( const int x, const int y, const int TheState )
852 {
853     static Standard_Integer theButtonDownX = 0;
854     static Standard_Integer theButtonDownY = 0;
855
856     if ( TheState == -1 )
857     {
858         theButtonDownX = x;
859         theButtonDownY = y;
860     }
861     if ( TheState == 0 )
862     {
863         myContext->ShiftSelect( theButtonDownX, theButtonDownY, x, y, myView, Standard_True );
864         emit selectionChanged();
865     }
866 }
867
868 void View::MultiInputEvent( const int /*x*/, const int /*y*/ )
869 {
870   myContext->ShiftSelect (Standard_True);
871   emit selectionChanged();
872 }
873
874 void View::Popup( const int /*x*/, const int /*y*/ )
875 {
876   ApplicationCommonWindow* stApp = ApplicationCommonWindow::getApplication();
877   QMdiArea* ws = ApplicationCommonWindow::getWorkspace();
878   QMdiSubWindow* w = ws->activeSubWindow();
879   if ( myContext->NbSelected() )
880   {
881     QList<QAction*>* aList = stApp->getToolActions();
882     QMenu* myToolMenu = new QMenu( 0 );
883     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolWireframeId ) );
884     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolShadingId ) );
885     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolColorId ) );
886         
887     QMenu* myMaterMenu = new QMenu( myToolMenu );
888
889     QList<QAction*>* aMeterActions = ApplicationCommonWindow::getApplication()->getMaterialActions();
890         
891     QString dir = ApplicationCommonWindow::getResourceDir() + QString( "/" );
892     myMaterMenu = myToolMenu->addMenu( QPixmap( dir+QObject::tr("ICON_TOOL_MATER")), QObject::tr("MNU_MATER") );
893     for ( int i = 0; i < aMeterActions->size(); i++ )
894       myMaterMenu->addAction( aMeterActions->at( i ) );
895        
896     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolTransparencyId ) );
897     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolDeleteId ) );
898     addItemInPopup(myToolMenu);
899     myToolMenu->exec( QCursor::pos() );
900     delete myToolMenu;
901   }
902   else
903   {
904     if (!myBackMenu)
905     {
906       myBackMenu = new QMenu( 0 );
907
908       QAction* a = new QAction( QObject::tr("MNU_CH_BACK"), this );
909       a->setToolTip( QObject::tr("TBR_CH_BACK") );
910       connect( a, SIGNAL( triggered() ), this, SLOT( onBackground() ) );
911       myBackMenu->addAction( a );  
912       addItemInPopup(myBackMenu);
913
914       a = new QAction( QObject::tr("MNU_CH_ENV_MAP"), this );
915       a->setToolTip( QObject::tr("TBR_CH_ENV_MAP") );
916       connect( a, SIGNAL( triggered() ), this, SLOT( onEnvironmentMap() ) );
917       a->setCheckable( true );
918       a->setChecked( false );
919       myBackMenu->addAction( a );  
920       addItemInPopup(myBackMenu);
921     }
922
923     myBackMenu->exec( QCursor::pos() );
924   }
925   if ( w )
926     w->setFocus();
927 }
928
929 void View::addItemInPopup( QMenu* /*theMenu*/)
930 {
931 }
932
933 void View::DrawRectangle(const int MinX, const int MinY,
934        const int MaxX, const int MaxY, const bool Draw)
935
936   static Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
937   static Standard_Boolean m_IsVisible;
938
939   StoredMinX = (MinX < MaxX) ? MinX: MaxX ;
940   StoredMinY = (MinY < MaxY) ? MinY: MaxY ;
941   StoredMaxX = (MinX > MaxX) ? MinX: MaxX ;
942   StoredMaxY = (MinY > MaxY) ? MinY: MaxY ;
943
944   QRect aRect;
945   aRect.setRect( StoredMinX, StoredMinY, abs(StoredMaxX-StoredMinX), abs(StoredMaxY-StoredMinY));
946
947   if ( !myRectBand ) 
948   {
949     myRectBand = new QRubberBand( QRubberBand::Rectangle, this );
950     myRectBand->setStyle( QStyleFactory::create("windows") );
951     myRectBand->setGeometry( aRect );
952     myRectBand->show();
953
954     /*QPalette palette;
955     palette.setColor(myRectBand->foregroundRole(), Qt::white);
956     myRectBand->setPalette(palette);*/
957   }
958
959   if ( m_IsVisible && !Draw ) // move or up  : erase at the old position
960   {
961     myRectBand->hide();
962     delete myRectBand;
963     myRectBand = 0;
964     m_IsVisible = false;
965   }
966
967   if (Draw) // move : draw
968   {
969     //aRect.setRect( StoredMinX, StoredMinY, abs(StoredMaxX-StoredMinX), abs(StoredMaxY-StoredMinY));
970     m_IsVisible = true;
971     myRectBand->setGeometry( aRect );
972     //myRectBand->show();
973   }
974 }
975
976 void View::noActiveActions()
977 {
978     for ( int i = ViewFitAllId; i < ViewHlrOffId ; i++ )
979     {
980         QAction* anAction = myViewActions->at( i );
981         if( ( anAction == myViewActions->at( ViewFitAreaId ) ) ||
982             ( anAction == myViewActions->at( ViewZoomId ) ) ||
983             ( anAction == myViewActions->at( ViewPanId ) ) ||
984             ( anAction == myViewActions->at( ViewGlobalPanId ) ) ||
985             ( anAction == myViewActions->at( ViewRotationId ) ) )
986         {
987             setCursor( *defCursor );
988             anAction->setCheckable( true );
989             anAction->setChecked( false );
990         }
991     }
992 }
993
994 void View::onBackground()
995 {
996     QColor aColor ;
997     Standard_Real R1;
998     Standard_Real G1;
999     Standard_Real B1;
1000     myView->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
1001     aColor.setRgb((Standard_Integer)(R1 * 255), (Standard_Integer)(G1 * 255), (Standard_Integer)(B1 * 255));
1002
1003     QColor aRetColor = QColorDialog::getColor(aColor);
1004
1005     if( aRetColor.isValid() )
1006     {
1007         R1 = aRetColor.red()/255.;
1008         G1 = aRetColor.green()/255.;
1009         B1 = aRetColor.blue()/255.;
1010         myView->SetBackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
1011     }
1012     myView->Redraw();
1013 }
1014
1015 void View::onEnvironmentMap()
1016 {
1017   if (myBackMenu->actions().at(1)->isChecked())
1018   {
1019     QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
1020                            tr("All Image Files (*.bmp *.gif *.jpg *.jpeg *.png *.tga)"));
1021     
1022     const TCollection_AsciiString anUtf8Path (fileName.toUtf8().data());
1023     
1024     Handle(Graphic3d_TextureEnv) aTexture = new Graphic3d_TextureEnv( anUtf8Path );
1025
1026     myView->SetTextureEnv (aTexture);
1027   }
1028   else
1029   {
1030     myView->SetTextureEnv (Handle(Graphic3d_TextureEnv)());
1031   }
1032   
1033   myView->Redraw();
1034 }
1035
1036 bool View::dump(Standard_CString theFile)
1037 {
1038   return myView->Dump(theFile);
1039 }
1040
1041 Handle(V3d_View)& View::getView()
1042 {
1043   return myView;
1044 }
1045
1046 Handle(AIS_InteractiveContext)& View::getContext()
1047 {
1048   return myContext;
1049 }
1050
1051 View::CurrentAction3d View::getCurrentMode()
1052 {
1053   return myCurrentMode;
1054 }
1055
1056
1057