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