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