Salome HOME
Initial version
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewWindow.cxx
1 // OCCViewer_ViewWindow.cxx: implementation of the OCCViewer_ViewWindow class.
2 //
3 //////////////////////////////////////////////////////////////////////
4
5 #include "OCCViewer_ViewWindow.h"
6 #include "OCCViewer_ViewModel.h"
7 #include "OCCViewer_ViewPort3d.h"
8 #include "OCCViewer_CreateRestoreViewDlg.h"
9
10 #include "SUIT_Desktop.h"
11 #include "SUIT_Session.h"
12 #include "SUIT_ToolButton.h"
13
14 #include "SUIT_Tools.h"
15 #include "SUIT_ResourceMgr.h"
16 #include "SUIT_FileDlg.h"
17 #include "SUIT_MessageBox.h"
18
19 #include <qptrlist.h>
20 #include <qhbox.h>
21 #include <qlabel.h>
22 #include <qcolor.h>
23 #include <qpainter.h>
24 #include <qapplication.h>
25
26
27 const char* imageZoomCursor[] = { 
28 "32 32 3 1",
29 ". c None",
30 "a c #000000",
31 "# c #ffffff",
32 "................................",
33 "................................",
34 ".#######........................",
35 "..aaaaaaa.......................",
36 "................................",
37 ".............#####..............",
38 "...........##.aaaa##............",
39 "..........#.aa.....a#...........",
40 ".........#.a.........#..........",
41 ".........#a..........#a.........",
42 "........#.a...........#.........",
43 "........#a............#a........",
44 "........#a............#a........",
45 "........#a............#a........",
46 "........#a............#a........",
47 ".........#...........#.a........",
48 ".........#a..........#a.........",
49 ".........##.........#.a.........",
50 "........#####.....##.a..........",
51 ".......###aaa#####.aa...........",
52 "......###aa...aaaaa.......#.....",
53 ".....###aa................#a....",
54 "....###aa.................#a....",
55 "...###aa...............#######..",
56 "....#aa.................aa#aaaa.",
57 ".....a....................#a....",
58 "..........................#a....",
59 "...........................a....",
60 "................................",
61 "................................",
62 "................................",
63 "................................"};
64
65 const char* imageRotateCursor[] = { 
66 "32 32 3 1",
67 ". c None",
68 "a c #000000",
69 "# c #ffffff",
70 "................................",
71 "................................",
72 "................................",
73 "................................",
74 "........#.......................",
75 ".......#.a......................",
76 "......#######...................",
77 ".......#aaaaa#####..............",
78 "........#..##.a#aa##........##..",
79 ".........a#.aa..#..a#.....##.aa.",
80 ".........#.a.....#...#..##.aa...",
81 ".........#a.......#..###.aa.....",
82 "........#.a.......#a..#aa.......",
83 "........#a.........#..#a........",
84 "........#a.........#a.#a........",
85 "........#a.........#a.#a........",
86 "........#a.........#a.#a........",
87 ".........#.........#a#.a........",
88 "........##a........#a#a.........",
89 "......##.a#.......#.#.a.........",
90 "....##.aa..##.....##.a..........",
91 "..##.aa.....a#####.aa...........",
92 "...aa.........aaa#a.............",
93 "................#.a.............",
94 "...............#.a..............",
95 "..............#.a...............",
96 "...............a................",
97 "................................",
98 "................................",
99 "................................",
100 "................................",
101 "................................"};
102
103 const char* imageCrossCursor[] = { 
104   "32 32 3 1",
105   ". c None",
106   "a c #000000",
107   "# c #ffffff",
108   "................................",
109   "................................",
110   "................................",
111   "................................",
112   "................................",
113   "................................",
114   "................................",
115   "...............#................",
116   "...............#a...............",
117   "...............#a...............",
118   "...............#a...............",
119   "...............#a...............",
120   "...............#a...............",
121   "...............#a...............",
122   "...............#a...............",
123   ".......#################........",
124   "........aaaaaaa#aaaaaaaaa.......",
125   "...............#a...............",
126   "...............#a...............",
127   "...............#a...............",
128   "...............#a...............",
129   "...............#a...............",
130   "...............#a...............",
131   "...............#a...............",
132   "................a...............",
133   "................................",
134   "................................",
135   "................................",
136   "................................",
137   "................................",
138   "................................",
139   "................................"};
140   
141
142 QPixmap zoomPixmap(imageZoomCursor);
143 QPixmap rotatePixmap(imageRotateCursor);
144 QPixmap globalPanPixmap(imageCrossCursor);
145
146 QCursor defCursor(Qt::ArrowCursor);
147 QCursor handCursor(Qt::PointingHandCursor);
148 QCursor panCursor(Qt::SizeAllCursor);
149 QCursor zoomCursor(zoomPixmap);
150 QCursor rotCursor(rotatePixmap);
151 QCursor glPanCursor(globalPanPixmap);
152
153
154
155 //////////////////////////////////////////////////////////////////////
156 // Construction/Destruction
157 //////////////////////////////////////////////////////////////////////
158
159 OCCViewer_ViewWindow::OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel)
160 : SUIT_ViewWindow(theDesktop)
161 {
162   myModel = theModel;
163   myEnableDrawMode = true;
164   myRestoreFlag = 0;
165 }
166
167 //****************************************************************
168 void OCCViewer_ViewWindow::initLayout()
169 {
170   myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC );
171   myViewPort->setBackgroundColor(black);
172   myViewPort->installEventFilter(this);
173         setCentralWidget(myViewPort);
174   myOperation = NOTHING;
175
176   setTransformRequested ( NOTHING );
177   setTransformInProcess ( false );
178
179   myToolBar = new QToolBar(this);
180   myToolBar->setCloseMode(QDockWindow::Undocked);
181   myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
182
183   createActions();
184   createToolBar();
185 }
186
187 //****************************************************************
188 OCCViewer_ViewWindow::OperationType OCCViewer_ViewWindow::getButtonState(QMouseEvent* theEvent)
189 {
190   OperationType aOp = NOTHING;
191   if( (theEvent->state() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::ZOOM]) &&
192       (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::ZOOM]) )
193     aOp = ZOOMVIEW;
194   else if( (theEvent->state() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::PAN]) && 
195            (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::PAN]) )
196     aOp = PANVIEW;
197   else if( (theEvent->state()  == SUIT_ViewModel::myStateMap[SUIT_ViewModel::ROTATE]) &&
198            (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::ROTATE]) )
199     aOp = ROTATE;
200
201   return aOp;
202 }
203
204 //****************************************************************
205 bool OCCViewer_ViewWindow::eventFilter(QObject* watched, QEvent* e)
206 {
207   if ( watched == myViewPort ) {
208     int aType = e->type();
209     switch(aType) {
210     case QEvent::MouseButtonPress:
211       vpMousePressEvent((QMouseEvent*) e);
212       return true;
213
214     case QEvent::MouseButtonRelease:
215       vpMouseReleaseEvent((QMouseEvent*) e);
216       return true;
217
218     case QEvent::MouseMove:
219       vpMouseMoveEvent((QMouseEvent*) e);
220       return true;
221
222     case QEvent::MouseButtonDblClick:
223       emit mouseDoubleClicked(this, (QMouseEvent*)e);
224       return true;
225
226     case QEvent::Wheel:
227       {
228         QWheelEvent* aEvent = (QWheelEvent*) e;
229         double aDelta = aEvent->delta();
230         double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
231         myViewPort->getView()->SetZoom(aScale);
232       }
233       return true;
234
235     case QEvent::ContextMenu:
236       {
237         QContextMenuEvent * aEvent = (QContextMenuEvent*)e;
238         if ( aEvent->reason() != QContextMenuEvent::Mouse )
239           emit contextMenuRequested( aEvent );
240       }
241       return true;
242
243     default:
244       break;
245     }
246   }
247   return SUIT_ViewWindow::eventFilter(watched, e);
248 }
249
250
251 //****************************************************************
252 void OCCViewer_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
253 {
254   myStartX = theEvent->x();
255   myStartY = theEvent->y();
256   switch ( myOperation ) {
257   case WINDOWFIT:
258     if ( theEvent->button() == Qt::LeftButton )
259       emit vpTransformationStarted ( WINDOWFIT );
260     break;    
261    
262   case PANGLOBAL:
263     if ( theEvent->button() == Qt::LeftButton )
264       emit vpTransformationStarted ( PANGLOBAL );
265     break;    
266     
267   case ZOOMVIEW:
268     if ( theEvent->button() == Qt::LeftButton )
269       emit vpTransformationStarted ( ZOOMVIEW );
270     break;
271     
272   case PANVIEW:
273     if ( theEvent->button() == Qt::LeftButton )
274       emit vpTransformationStarted ( PANVIEW );
275     break;
276
277   case ROTATE:
278     if ( theEvent->button() == Qt::LeftButton ) {
279             myViewPort->startRotation(myStartX, myStartY);
280             emit vpTransformationStarted ( ROTATE );
281           }
282     break;
283       
284   default:
285   /*  Try to activate a transformation */
286     switch ( getButtonState(theEvent) ) {
287     case ZOOMVIEW:
288             activateZoom();
289       break;
290     case PANVIEW:
291             activatePanning();
292       break;
293     case ROTATE:
294             activateRotation();
295             myViewPort->startRotation(myStartX, myStartY);
296       break;
297     default:
298       emit mousePressed(this, theEvent);
299       break;
300     }
301     /* notify that we start a transformation */
302     if ( transformRequested() ) 
303             emit vpTransformationStarted ( myOperation );
304   }
305   if ( transformRequested() ) 
306     setTransformInProcess( true );               
307 }
308
309
310 //****************************************************************
311 void OCCViewer_ViewWindow::activateZoom()
312 {
313   if ( !transformRequested() && !myCursorIsHand )
314     myCursor = cursor();                /* save old cursor */
315   
316   if ( myOperation != ZOOMVIEW ) {
317     setTransformRequested ( ZOOMVIEW );         
318     setCursor( zoomCursor );
319   }
320 }
321
322
323 //****************************************************************
324 /*!
325     Activates 'panning' transformation
326 */
327 void OCCViewer_ViewWindow::activatePanning()
328 {
329   if ( !transformRequested() && !myCursorIsHand )
330     myCursor = cursor();                // save old cursor 
331   
332   if ( myOperation != PANVIEW ) {
333     setTransformRequested ( PANVIEW );
334     setCursor( panCursor );
335   }
336 }
337
338 //****************************************************************
339 /*!
340     Activates 'rotation' transformation
341 */
342 void OCCViewer_ViewWindow::activateRotation()
343 {
344   if ( !transformRequested() && !myCursorIsHand )
345     myCursor = cursor();                // save old cursor 
346   
347   if ( myOperation != ROTATE ) {
348     setTransformRequested ( ROTATE );
349     setCursor( rotCursor );     
350   }
351 }
352
353 //****************************************************************
354 void OCCViewer_ViewWindow::activateGlobalPanning()
355 {
356   Handle(V3d_View) aView3d = myViewPort->getView();
357   if ( !aView3d.IsNull() ) {
358     myCurScale = aView3d->Scale();
359     aView3d->FitAll(0.01, false);
360     myCursor = cursor();                // save old cursor 
361     myViewPort->fitAll(); // fits view before selecting a new scene center 
362     setTransformRequested( PANGLOBAL );
363     setCursor( glPanCursor );
364   }
365 }
366
367 //****************************************************************
368 /*!
369     Activates 'fit' transformation
370 */
371 void OCCViewer_ViewWindow::activateWindowFit()
372 {
373   if ( !transformRequested() && !myCursorIsHand )
374     myCursor = cursor();                /* save old cursor */
375
376   if ( myOperation != WINDOWFIT ) {
377     setTransformRequested ( WINDOWFIT );                
378     setCursor ( handCursor );
379     myCursorIsHand = true;
380   }
381 }
382
383 //****************************************************************
384 /*!
385     Sets the active operation 'op'
386 */
387 void OCCViewer_ViewWindow::setTransformRequested ( OperationType op )
388 {    
389   myOperation = op;
390   myViewPort->setMouseTracking( myOperation == NOTHING );  
391 }
392
393
394 //****************************************************************
395 void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
396 {
397   myCurrX = theEvent->x();
398   myCurrY = theEvent->y();
399   switch (myOperation) {
400   case ROTATE:
401     myViewPort->rotate(myCurrX, myCurrY);
402     break;
403     
404   case ZOOMVIEW:
405     myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
406     myStartX = myCurrX;
407     myStartY = myCurrY;
408     break;
409     
410   case PANVIEW:
411     myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
412     myStartX = myCurrX;
413     myStartY = myCurrY;
414     break;
415     
416 /*    case WINDOWFIT:
417     myDrawRect = true;
418     repaint();
419     break;
420 */      
421   case PANGLOBAL:
422     break;
423     
424   default:
425     int aState = theEvent->state();
426     //int aButton = theEvent->button();
427     if ( aState == Qt::LeftButton ||
428         aState == ( Qt::LeftButton | Qt::ShiftButton) ) {
429       myDrawRect = myEnableDrawMode;
430       if ( myDrawRect ) {
431         drawRect();
432         if ( !myCursorIsHand )  {   // we are going to sketch a rectangle
433           myCursorIsHand = true;                
434           myCursor = cursor();
435           setCursor( handCursor );
436         }
437       }
438     } 
439     else {
440       emit mouseMoving( this, theEvent ); 
441     }           
442   }
443 }
444
445 //****************************************************************
446 void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
447 {
448   switch ( myOperation ) {
449   case NOTHING:
450     {
451       emit mouseReleased(this, theEvent);
452       if(theEvent->button() == RightButton)
453       {
454         QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
455                                   theEvent->pos(), theEvent->globalPos(),
456                                   theEvent->state() );
457         emit contextMenuRequested( &aEvent );
458         break;
459       }
460     }
461   case ROTATE:
462     myViewPort->endRotation();
463     resetState();
464     break;
465     
466   case PANVIEW:
467   case ZOOMVIEW:
468     resetState();
469     break;
470     
471   case PANGLOBAL:
472     if ( theEvent->button() == Qt::LeftButton ) {
473             myViewPort->setCenter( theEvent->x(), theEvent->y() );
474       myViewPort->getView()->SetScale(myCurScale);
475             resetState();
476           }
477     break;
478       
479   case WINDOWFIT:
480     if ( theEvent->state() == Qt::LeftButton ) {
481             myCurrX = theEvent->x();
482             myCurrY = theEvent->y();
483             QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
484             if ( !rect.isEmpty() ) myViewPort->fitRect(rect);
485             resetState();
486           }
487     break;
488   }
489   
490   // NOTE: viewer 3D detects a rectangle of selection using this event
491   // so we must emit it BEFORE resetting the selection rectangle
492   
493   if ( theEvent->button() == Qt::LeftButton && myDrawRect ) {
494     myDrawRect = false;
495     drawRect();
496     resetState(); 
497     myViewPort->update();
498   }
499 }
500
501 //****************************************************************
502 /*!
503     Sets the viewport to its initial state
504     ( no transformations in process etc. )
505 */
506 void OCCViewer_ViewWindow::resetState()
507 {
508   myDrawRect = false;
509   
510   /* make rectangle empty (left > right) */
511   myRect.setLeft(2);
512   myRect.setRight(0);
513   
514   if ( transformRequested() || myCursorIsHand ) 
515     setCursor( myCursor );
516   myCursorIsHand = false;
517   
518   if ( transformRequested() ) 
519     emit vpTransformationFinished (myOperation);
520   
521   setTransformInProcess( false );               
522   setTransformRequested( NOTHING );     
523 }
524
525
526 //****************************************************************
527 void OCCViewer_ViewWindow::drawRect()
528 {
529   QPainter aPainter(myViewPort);
530   aPainter.setRasterOp(Qt::XorROP);
531   aPainter.setPen(Qt::white);
532   QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
533   if ( !myRect.isEmpty() )
534           aPainter.drawRect( myRect );
535   aPainter.drawRect(aRect);
536   myRect = aRect;
537 }
538
539 //****************************************************************
540 void OCCViewer_ViewWindow::createActions()
541 {
542   if (!myActionsMap.isEmpty()) return;
543   
544   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
545   
546   QtxAction* aAction;
547
548   // Dump view
549   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ),
550                            tr( "MNU_DUMP_VIEW" ), 0, this);
551   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
552   connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
553         myActionsMap[ DumpId ] = aAction;
554
555   // FitAll
556   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ),
557                            tr( "MNU_FITALL" ), 0, this);
558   aAction->setStatusTip(tr("DSC_FITALL"));
559   connect(aAction, SIGNAL(activated()), this, SLOT(onFitAll()));
560         myActionsMap[ FitAllId ] = aAction;
561
562   // FitRect
563   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ),
564                            tr( "MNU_FITRECT" ), 0, this);
565   aAction->setStatusTip(tr("DSC_FITRECT"));
566   connect(aAction, SIGNAL(activated()), this, SLOT(activateWindowFit()));
567         myActionsMap[ FitRectId ] = aAction;
568
569   // Zoom
570   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ),
571                            tr( "MNU_ZOOM_VIEW" ), 0, this);
572   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
573   connect(aAction, SIGNAL(activated()), this, SLOT(activateZoom()));
574         myActionsMap[ ZoomId ] = aAction;
575
576   // Panning
577   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ),
578                            tr( "MNU_PAN_VIEW" ), 0, this);
579   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
580   connect(aAction, SIGNAL(activated()), this, SLOT(activatePanning()));
581         myActionsMap[ PanId ] = aAction;
582
583   // Global Panning
584   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ),
585                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
586   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
587   connect(aAction, SIGNAL(activated()), this, SLOT(activateGlobalPanning()));
588         myActionsMap[ GlobalPanId ] = aAction;
589
590   // Rotation
591   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ),
592                            tr( "MNU_ROTATE_VIEW" ), 0, this);
593   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
594   connect(aAction, SIGNAL(activated()), this, SLOT(activateRotation()));
595         myActionsMap[ RotationId ] = aAction;
596
597   // Projections
598   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ),
599                            tr( "MNU_FRONT_VIEW" ), 0, this);
600   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
601   connect(aAction, SIGNAL(activated()), this, SLOT(onFrontView()));
602         myActionsMap[ FrontId ] = aAction;
603
604   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ),
605                            tr( "MNU_BACK_VIEW" ), 0, this);
606   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
607   connect(aAction, SIGNAL(activated()), this, SLOT(onBackView()));
608         myActionsMap[ BackId ] = aAction;
609
610   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ),
611                            tr( "MNU_TOP_VIEW" ), 0, this);
612   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
613   connect(aAction, SIGNAL(activated()), this, SLOT(onTopView()));
614         myActionsMap[ TopId ] = aAction;
615
616   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ),
617                            tr( "MNU_BOTTOM_VIEW" ), 0, this);
618   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
619   connect(aAction, SIGNAL(activated()), this, SLOT(onBottomView()));
620         myActionsMap[ BottomId ] = aAction;
621
622   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ),
623                            tr( "MNU_LEFT_VIEW" ), 0, this);
624   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
625   connect(aAction, SIGNAL(activated()), this, SLOT(onLeftView()));
626         myActionsMap[ LeftId ] = aAction;
627
628   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ),
629                            tr( "MNU_RIGHT_VIEW" ), 0, this);
630   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
631   connect(aAction, SIGNAL(activated()), this, SLOT(onRightView()));
632         myActionsMap[ RightId ] = aAction;
633
634   // Reset
635   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ),
636                            tr( "MNU_RESET_VIEW" ), 0, this);
637   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
638   connect(aAction, SIGNAL(activated()), this, SLOT(onResetView()));
639         myActionsMap[ ResetId ] = aAction;
640
641   // Reset
642   aAction = new QtxAction(tr("MNU_CLONE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLONE_VIEW" ) ),
643                            tr( "MNU_CLONE_VIEW" ), 0, this);
644   aAction->setStatusTip(tr("DSC_CLONE_VIEW"));
645   connect(aAction, SIGNAL(activated()), this, SLOT(onCloneView()));
646         myActionsMap[ CloneId ] = aAction;
647
648   aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ),
649                            tr( "MNU_SHOOT_VIEW" ), 0, this);
650   aAction->setStatusTip(tr("DSC_SHOOT_VIEW"));
651   connect(aAction, SIGNAL(activated()), this, SLOT(onMemorizeView()));
652         myActionsMap[ MemId ] = aAction;
653
654   aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ),
655                            tr( "MNU_PRESETS_VIEW" ), 0, this);
656   aAction->setStatusTip(tr("DSC_PRESETS_VIEW"));
657   connect(aAction, SIGNAL(activated()), this, SLOT(onRestoreView()));
658         myActionsMap[ RestoreId ] = aAction;
659 }
660
661 //****************************************************************
662 void OCCViewer_ViewWindow::createToolBar()
663 {
664   myActionsMap[DumpId]->addTo(myToolBar);
665
666   SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar, "scale");
667   aScaleBtn->AddAction(myActionsMap[FitAllId]);
668   aScaleBtn->AddAction(myActionsMap[FitRectId]);
669   aScaleBtn->AddAction(myActionsMap[ZoomId]);
670
671   SUIT_ToolButton* aPanningBtn = new SUIT_ToolButton(myToolBar, "pan");
672   aPanningBtn->AddAction(myActionsMap[PanId]);
673   aPanningBtn->AddAction(myActionsMap[GlobalPanId]);
674
675   myActionsMap[RotationId]->addTo(myToolBar);
676
677   SUIT_ToolButton* aViewsBtn = new SUIT_ToolButton(myToolBar, "projection");
678   aViewsBtn->AddAction(myActionsMap[FrontId]);
679   aViewsBtn->AddAction(myActionsMap[BackId]);
680   aViewsBtn->AddAction(myActionsMap[TopId]);
681   aViewsBtn->AddAction(myActionsMap[BottomId]);
682   aViewsBtn->AddAction(myActionsMap[LeftId]);
683   aViewsBtn->AddAction(myActionsMap[RightId]);
684
685   myActionsMap[ResetId]->addTo(myToolBar);
686
687   SUIT_ToolButton* aMemBtn = new SUIT_ToolButton(myToolBar, "view");
688   aMemBtn->AddAction(myActionsMap[MemId]);
689   aMemBtn->AddAction(myActionsMap[RestoreId]);
690
691   myToolBar->addSeparator();
692   myActionsMap[CloneId]->addTo(myToolBar);
693 }
694
695 //****************************************************************
696 void OCCViewer_ViewWindow::onViewFitAll()
697 {
698   myViewPort->fitAll();
699 }
700
701 //****************************************************************
702 void OCCViewer_ViewWindow::onFrontView()
703 {
704   emit vpTransformationStarted ( FRONTVIEW );
705   Handle(V3d_View) aView3d = myViewPort->getView();
706   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos);
707   onViewFitAll();
708 }
709
710 //****************************************************************
711 void OCCViewer_ViewWindow::onBackView()
712 {
713   emit vpTransformationStarted ( BACKVIEW );
714   Handle(V3d_View) aView3d = myViewPort->getView();
715   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg);
716   onViewFitAll();
717 }
718
719 //****************************************************************
720 void OCCViewer_ViewWindow::onTopView()
721 {
722   emit vpTransformationStarted ( TOPVIEW );
723   Handle(V3d_View) aView3d = myViewPort->getView();
724   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos);
725   onViewFitAll();
726 }
727
728 //****************************************************************
729 void OCCViewer_ViewWindow::onBottomView()
730 {
731   emit vpTransformationStarted ( BOTTOMVIEW );
732   Handle(V3d_View) aView3d = myViewPort->getView();
733   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg);
734   onViewFitAll();
735 }
736
737 //****************************************************************
738 void OCCViewer_ViewWindow::onLeftView()
739 {
740   emit vpTransformationStarted ( LEFTVIEW );
741   Handle(V3d_View) aView3d = myViewPort->getView();
742   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg);
743   onViewFitAll();
744 }
745
746 //****************************************************************
747 void OCCViewer_ViewWindow::onRightView()
748 {
749   emit vpTransformationStarted ( RIGHTVIEW );
750   Handle(V3d_View) aView3d = myViewPort->getView();
751   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos);
752   onViewFitAll();
753 }
754
755 //****************************************************************
756 void OCCViewer_ViewWindow::onResetView()
757 {
758   emit vpTransformationStarted( RESETVIEW );
759   myViewPort->getView()->Reset();
760   myViewPort->fitAll();
761 }
762
763 //****************************************************************
764 void OCCViewer_ViewWindow::onFitAll()
765 {
766   emit vpTransformationStarted( FITALLVIEW );
767   myViewPort->fitAll();
768 }
769
770 //****************************************************************
771 /*
772    Dumps 3d-Viewer contents into image file
773    File format is defined by file's extension; supported formats : PNG, BMP, GIF, JPG
774 */
775 void OCCViewer_ViewWindow::onDumpView()
776 {
777   QApplication::setOverrideCursor( Qt::waitCursor );
778   QPixmap px = QPixmap::grabWindow(myViewPort->winId());
779   QApplication::restoreOverrideCursor();
780   
781   QString fileName = SUIT_FileDlg::getFileName(this,
782                                               QString::null,
783                                               tr("OCC_IMAGE_FILES"),
784                                               tr("INF_APP_DUMP_VIEW"),
785                                               false);
786   if (!fileName.isNull()) {
787     QApplication::setOverrideCursor( Qt::waitCursor );
788     QString fmt = SUIT_Tools::extension(fileName).upper();
789     if (fmt.isEmpty())
790       fmt = QString("BMP"); // default format
791     if (fmt == "JPG")
792       fmt = "JPEG";
793     bool bOk = px.save(fileName, fmt.latin1());
794     QApplication::restoreOverrideCursor();
795     if (!bOk) {
796       SUIT_MessageBox::error1(this, tr("ERROR"), tr("ERR_DOC_CANT_SAVE_FILE"), tr("BUT_OK"));
797     }
798   }
799 }
800
801 //****************************************************************
802 void OCCViewer_ViewWindow::onCloneView()
803 {
804   myManager->createView();
805 }
806
807 //****************************************************************
808 void OCCViewer_ViewWindow::onMemorizeView()
809 {
810   double centerX, centerY, projX, projY, projZ, twist;
811   double atX, atY, atZ, eyeX, eyeY, eyeZ;
812
813   Handle(V3d_View) aView3d = myViewPort->getView();
814
815   aView3d->Center( centerX, centerY );
816   aView3d->Proj( projX, projY, projZ );
817   aView3d->At( atX, atY, atZ );
818   aView3d->Eye( eyeX, eyeY, eyeZ );
819   twist = aView3d->Twist();
820
821   viewAspect params;
822   QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" );
823
824   params.scale    = aView3d->Scale();
825   params.centerX  = centerX;
826   params.centerY  = centerY;
827   params.projX    = projX;
828   params.projY    = projY;
829   params.projZ    = projZ;
830   params.twist    = twist;
831   params.atX      = atX;
832   params.atY      = atY;
833   params.atZ      = atZ;
834   params.eyeX     = eyeX;
835   params.eyeY     = eyeY;
836   params.eyeZ     = eyeZ;
837   params.name     = aName;
838
839   myModel->appendViewAspect( params );
840
841 }
842
843 //****************************************************************
844 void OCCViewer_ViewWindow::onRestoreView()
845 {
846         OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), myModel );
847         connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) );
848         aDlg->exec();
849         myModel->updateViewAspects( aDlg->parameters() );
850         if( myRestoreFlag && aDlg->parameters().count() )
851                 performRestoring( aDlg->currentItem() );
852 }
853
854 //****************************************************************
855
856 void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem )
857 {
858         Handle(V3d_View) aView3d = myViewPort->getView();
859
860         Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
861         aView3d->SetScale( anItem.scale );
862         aView3d->SetCenter( anItem.centerX, anItem.centerY );
863         aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
864         aView3d->SetTwist( anItem.twist );
865         aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ );
866         aView3d->SetImmediateUpdate( prev );
867         aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ );
868                 
869         myRestoreFlag = 0;
870 }
871
872 void OCCViewer_ViewWindow::setRestoreFlag()
873 {
874         myRestoreFlag = 1;
875 }
876