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