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