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