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