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