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