Salome HOME
0022077: EDF 2272 : Selection with the Paraview interaction mode in GEOM/SMESH
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewWindow.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File   : OCCViewer_ViewWindow.cxx
24 // Author :
25
26 #include "OCCViewer_ViewWindow.h"
27 #include "OCCViewer_ViewModel.h"
28 #include "OCCViewer_ViewPort3d.h"
29 #include "OCCViewer_ViewManager.h"
30 #include "OCCViewer_ViewSketcher.h"
31 #include "OCCViewer_CreateRestoreViewDlg.h"
32 #include "OCCViewer_ClippingDlg.h"
33 #include "OCCViewer_SetRotationPointDlg.h"
34 #include "OCCViewer_AxialScaleDlg.h"
35 #include "OCCViewer_CubeAxesDlg.h"
36
37 #include <Basics_OCCTVersion.hxx>
38
39 #include <SUIT_Desktop.h>
40 #include <SUIT_Session.h>
41 #include <SUIT_ViewManager.h>
42 #include <SUIT_Tools.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_MessageBox.h>
45 #include <SUIT_Application.h>
46
47 #include <QtxActionToolMgr.h>
48 #include <QtxMultiAction.h>
49 #include <QtxRubberBand.h>
50
51 #include <OpenGLUtils_FrameBuffer.h>
52
53 #include <QPainter>
54 #include <QTime>
55 #include <QImage>
56 #include <QKeyEvent>
57 #include <QMouseEvent>
58 #include <QApplication>
59 #include <QMenu>
60
61 #include <AIS_ListOfInteractive.hxx>
62 #include <AIS_ListIteratorOfListOfInteractive.hxx>
63 #include <AIS_Shape.hxx>
64
65 #include <BRep_Tool.hxx>
66 #include <BRepBndLib.hxx>
67 #include <TopoDS.hxx>
68
69 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
70 #include <Graphic3d_MapOfStructure.hxx>
71 #include <Graphic3d_Structure.hxx>
72 #include <Graphic3d_ExportFormat.hxx>
73
74 #include <Visual3d_View.hxx>
75 #include <V3d_Plane.hxx>
76 #include <V3d_Light.hxx>
77
78 #include <gp_Dir.hxx>
79 #include <gp_Pln.hxx>
80 #include <TColgp_Array1OfPnt2d.hxx>
81
82 #include <Standard_Version.hxx>
83
84 #include "utilities.h"
85
86 // // OpenCV includes
87 // #include <cv.h>
88 // #include <highgui.h>
89
90 static QEvent* l_mbPressEvent = 0;
91
92 #ifdef WIN32
93 # include <QWindowsStyle>
94 #endif
95
96 #include <GL/gl.h>
97
98 const char* imageZoomCursor[] = {
99 "32 32 3 1",
100 ". c None",
101 "a c #000000",
102 "# c #ffffff",
103 "................................",
104 "................................",
105 ".#######........................",
106 "..aaaaaaa.......................",
107 "................................",
108 ".............#####..............",
109 "...........##.aaaa##............",
110 "..........#.aa.....a#...........",
111 ".........#.a.........#..........",
112 ".........#a..........#a.........",
113 "........#.a...........#.........",
114 "........#a............#a........",
115 "........#a............#a........",
116 "........#a............#a........",
117 "........#a............#a........",
118 ".........#...........#.a........",
119 ".........#a..........#a.........",
120 ".........##.........#.a.........",
121 "........#####.....##.a..........",
122 ".......###aaa#####.aa...........",
123 "......###aa...aaaaa.......#.....",
124 ".....###aa................#a....",
125 "....###aa.................#a....",
126 "...###aa...............#######..",
127 "....#aa.................aa#aaaa.",
128 ".....a....................#a....",
129 "..........................#a....",
130 "...........................a....",
131 "................................",
132 "................................",
133 "................................",
134 "................................"};
135
136 const char* imageRotateCursor[] = {
137 "32 32 3 1",
138 ". c None",
139 "a c #000000",
140 "# c #ffffff",
141 "................................",
142 "................................",
143 "................................",
144 "................................",
145 "........#.......................",
146 ".......#.a......................",
147 "......#######...................",
148 ".......#aaaaa#####..............",
149 "........#..##.a#aa##........##..",
150 ".........a#.aa..#..a#.....##.aa.",
151 ".........#.a.....#...#..##.aa...",
152 ".........#a.......#..###.aa.....",
153 "........#.a.......#a..#aa.......",
154 "........#a.........#..#a........",
155 "........#a.........#a.#a........",
156 "........#a.........#a.#a........",
157 "........#a.........#a.#a........",
158 ".........#.........#a#.a........",
159 "........##a........#a#a.........",
160 "......##.a#.......#.#.a.........",
161 "....##.aa..##.....##.a..........",
162 "..##.aa.....a#####.aa...........",
163 "...aa.........aaa#a.............",
164 "................#.a.............",
165 "...............#.a..............",
166 "..............#.a...............",
167 "...............a................",
168 "................................",
169 "................................",
170 "................................",
171 "................................",
172 "................................"};
173
174 const char* imageCrossCursor[] = {
175   "32 32 3 1",
176   ". c None",
177   "a c #000000",
178   "# c #ffffff",
179   "................................",
180   "................................",
181   "................................",
182   "................................",
183   "................................",
184   "................................",
185   "................................",
186   "...............#................",
187   "...............#a...............",
188   "...............#a...............",
189   "...............#a...............",
190   "...............#a...............",
191   "...............#a...............",
192   "...............#a...............",
193   "...............#a...............",
194   ".......#################........",
195   "........aaaaaaa#aaaaaaaaa.......",
196   "...............#a...............",
197   "...............#a...............",
198   "...............#a...............",
199   "...............#a...............",
200   "...............#a...............",
201   "...............#a...............",
202   "...............#a...............",
203   "................a...............",
204   "................................",
205   "................................",
206   "................................",
207   "................................",
208   "................................",
209   "................................",
210   "................................"};
211
212
213 /*!
214   \brief Constructor
215   \param theDesktop main window of application
216   \param theModel OCC 3D viewer
217 */
218 OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop*     theDesktop,
219                                             OCCViewer_Viewer* theModel )
220 : SUIT_ViewWindow( theDesktop )
221 {
222   myModel = theModel;
223   myRestoreFlag = 0;
224   myEnableDrawMode = false;
225   myDrawRect=false;
226   updateEnabledDrawMode();
227   myClippingDlg = 0;
228   myScalingDlg = 0;
229   mySetRotationPointDlg = 0;
230   myRectBand = 0;
231   
232   IsSketcherStyle = false;
233   myIsKeyFree = false;
234
235   mypSketcher = 0;
236   myCurSketch = -1;
237   my2dMode = No2dMode;
238
239   myInteractionStyle = SUIT_ViewModel::STANDARD;
240
241   clearViewAspects();
242   
243 }
244
245 /*!
246   \brief Destructor.
247 */
248 OCCViewer_ViewWindow::~OCCViewer_ViewWindow()
249 {
250   endDrawRect();
251   qDeleteAll( mySketchers );
252 }
253
254 /*!
255   \brief Internal initialization.
256 */
257 void OCCViewer_ViewWindow::initLayout()
258 {
259   myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC );
260   myViewPort->installEventFilter(this);
261   setCentralWidget(myViewPort);
262   myOperation = NOTHING;
263
264   myCurrPointType = GRAVITY;
265   myPrevPointType = GRAVITY;
266   mySelectedPoint = gp_Pnt(0.,0.,0.);
267   myRotationPointSelection = false;
268
269   setTransformRequested ( NOTHING );
270   setTransformInProcess ( false );
271
272   createActions();
273   createToolBar();
274
275   switch (my2dMode) {
276   case XYPlane:
277     onTopView();
278     break;
279   case XZPlane:
280     onLeftView();
281     break;
282   case YZPlane:
283     onFrontView();
284     break;
285   }
286
287   // Graduated axes dialog
288   QtxAction* anAction = dynamic_cast<QtxAction*>( toolMgr()->action( GraduatedAxesId ) );
289   myCubeAxesDlg = new OCCViewer_CubeAxesDlg( anAction, this, "OCCViewer_CubeAxesDlg" );
290   myCubeAxesDlg->initialize();
291   
292   connect( myViewPort, SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), this, SLOT( emitViewModified() ) );
293 }
294
295 OCCViewer_ViewWindow* OCCViewer_ViewWindow::getView( const int mode ) const
296 {
297   return mode == get2dMode() ? const_cast<OCCViewer_ViewWindow*>( this ) : 0;
298 }
299
300 /*!
301   \brief Detect viewer operation according the the mouse button pressed
302   and key modifiers used.
303   \param theEvent mouse event
304   \return type of the operation
305 */
306 OCCViewer_ViewWindow::OperationType
307 OCCViewer_ViewWindow::getButtonState( QMouseEvent* theEvent, int theInteractionStyle )
308 {
309   OperationType aOp = NOTHING;
310   SUIT_ViewModel::InteractionStyle aStyle = (SUIT_ViewModel::InteractionStyle)theInteractionStyle;
311   if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ZOOM]) &&
312       (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ZOOM]) )
313     aOp = ZOOMVIEW;
314   else if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::PAN]) &&
315            (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::PAN]) )
316     aOp = PANVIEW;
317   else if( (theEvent->modifiers()  == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ROTATE]) &&
318            (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ROTATE]) &&
319            (my2dMode == No2dMode))
320     aOp = ROTATE;
321
322   return aOp;
323 }
324
325 /*!
326   \brief Customize event handling
327   \param watched event receiver object
328   \param e event
329   \return \c true if the event processing should be stopped
330 */
331 bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
332 {
333   if ( watched == myViewPort ) {
334     int aType = e->type();
335     switch(aType) {
336     case QEvent::MouseButtonPress:
337       vpMousePressEvent((QMouseEvent*) e);
338       return true;
339
340     case QEvent::MouseButtonRelease:
341       vpMouseReleaseEvent((QMouseEvent*) e);
342       return true;
343
344     case QEvent::MouseMove:
345       vpMouseMoveEvent((QMouseEvent*) e);
346       return true;
347
348     case QEvent::MouseButtonDblClick:
349       emit mouseDoubleClicked(this, (QMouseEvent*)e);
350       return true;
351
352     case QEvent::Wheel:
353       {
354         QWheelEvent* aEvent = (QWheelEvent*) e;
355         myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
356         double delta = (double)( aEvent->delta() ) / ( 15 * 8 );
357         int x  = aEvent->x();
358         int y  = aEvent->y();
359         int x1 = (int)( aEvent->x() + width()*delta/100 );
360         int y1 = (int)( aEvent->y() + height()*delta/100 );
361         myViewPort->zoom( x, y, x1, y1 );
362       }
363       return true;
364
365     case QEvent::ContextMenu:
366       {
367         QContextMenuEvent * aEvent = (QContextMenuEvent*)e;
368         if ( aEvent->reason() != QContextMenuEvent::Mouse )
369           emit contextMenuRequested( aEvent );
370       }
371       return true;
372
373     case QEvent::KeyPress:
374       emit keyPressed(this, (QKeyEvent*) e);
375       return true;
376
377     default:
378       break;
379     }
380   }
381   return SUIT_ViewWindow::eventFilter(watched, e);
382 }
383
384 /*!
385   \brief Update state of enable draw mode state.
386 */
387 void OCCViewer_ViewWindow::updateEnabledDrawMode()
388 {
389   if ( myModel )
390     myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled();
391 }
392
393 /*!
394   \brief Handle mouse press event
395   \param theEvent mouse event
396 */
397 void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent )
398 {
399   myStartX = theEvent->x();
400   myStartY = theEvent->y();
401   int anInteractionStyle = interactionStyle();
402
403   // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
404   // which are assigned for pan and rotate - these operations are activated immediately after pressing 
405   // of the first button, so it is necessary to switch to zoom when the second button is pressed
406   bool aSwitchToZoom = false;
407   if ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && 
408        ( myOperation == PANVIEW || myOperation == ROTATE ) ) {
409     aSwitchToZoom = getButtonState( theEvent, anInteractionStyle ) == ZOOMVIEW;
410   }
411
412   switch ( myOperation ) {
413   case WINDOWFIT:
414     if ( theEvent->button() == Qt::LeftButton )
415       emit vpTransformationStarted ( WINDOWFIT );
416     break;
417
418   case PANGLOBAL:
419     if ( theEvent->button() == Qt::LeftButton )
420       emit vpTransformationStarted ( PANGLOBAL );
421     break;
422
423   case ZOOMVIEW:
424     if ( theEvent->button() == Qt::LeftButton ) {
425       myViewPort->startZoomAtPoint( myStartX, myStartY );
426       emit vpTransformationStarted ( ZOOMVIEW );
427     }
428     break;
429
430   case PANVIEW:
431     if ( aSwitchToZoom ) {
432       myViewPort->startZoomAtPoint( myStartX, myStartY );
433       activateZoom();
434     }
435     else if ( theEvent->button() == Qt::LeftButton )
436       emit vpTransformationStarted ( PANVIEW );
437     break;
438
439   case ROTATE:
440     if ( aSwitchToZoom ) {
441       myViewPort->startZoomAtPoint( myStartX, myStartY );
442       activateZoom();
443     }
444     else if ( theEvent->button() == Qt::LeftButton ) {
445       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
446       emit vpTransformationStarted ( ROTATE );
447     }
448     break;
449
450   default:
451   /*  Try to activate a transformation */
452     OperationType aState;
453     if ( interactionStyle() == SUIT_ViewModel::STANDARD )
454       aState = getButtonState(theEvent, anInteractionStyle);
455     else {
456       aState = OCCViewer_ViewWindow::NOTHING;
457       myIsKeyFree = true;
458     }
459     switch ( aState ) {
460     case ZOOMVIEW:
461       myViewPort->startZoomAtPoint( myStartX, myStartY );
462       activateZoom();
463       break;
464     case PANVIEW:
465       activatePanning();
466       break;
467     case ROTATE:
468       activateRotation();
469       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
470       break;
471     default:
472       if ( myRotationPointSelection )
473       {
474         if ( theEvent->button() == Qt::LeftButton )
475         {
476           Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
477           ic->Select();
478           for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() )
479           {
480             TopoDS_Shape aShape = ic->SelectedShape();
481             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
482             {
483               gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
484               if ( mySetRotationPointDlg )
485               {
486                 myRotationPointSelection = false;
487                 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
488               }
489             }
490             else
491             {
492               myCurrPointType = myPrevPointType;
493               break;
494             }
495           }
496           if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType;
497           if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
498           ic->CloseAllContexts();
499           myOperation = NOTHING;
500           myViewPort->setCursor( myCursor );
501           myCursorIsHand = false;
502           myRotationPointSelection = false;
503         }
504       }
505       else
506         emit mousePressed(this, theEvent);
507       break;
508     }
509     /* notify that we start a transformation */
510     if ( transformRequested() )
511             emit vpTransformationStarted ( myOperation );
512   }
513   if ( transformRequested() )
514     setTransformInProcess( true );
515
516   /* we may need it for sketching... */
517   if ( l_mbPressEvent )
518     delete l_mbPressEvent;
519   l_mbPressEvent = new QMouseEvent( *theEvent );
520 }
521
522
523 /*!
524   \brief Start zooming operation.
525
526   Sets the corresponding cursor for the widget.
527 */
528 void OCCViewer_ViewWindow::activateZoom()
529 {
530   if ( !transformRequested() && !myCursorIsHand )
531     myCursor = cursor();                /* save old cursor */
532
533   if ( myOperation != ZOOMVIEW ) {
534     QPixmap zoomPixmap (imageZoomCursor);
535     QCursor zoomCursor (zoomPixmap);
536     if( setTransformRequested ( ZOOMVIEW ) )
537       myViewPort->setCursor( zoomCursor );
538   }
539 }
540
541
542 /*!
543   \brief Start panning operation.
544
545   Sets the corresponding cursor for the widget.
546 */
547 void OCCViewer_ViewWindow::activatePanning()
548 {
549   if ( !transformRequested() && !myCursorIsHand )
550     myCursor = cursor();                // save old cursor
551
552   if ( myOperation != PANVIEW ) {
553     QCursor panCursor (Qt::SizeAllCursor);
554     if( setTransformRequested ( PANVIEW ) )
555       myViewPort->setCursor( panCursor );
556   }
557 }
558
559 /*!
560   \brief Start rotation operation
561
562   Sets the corresponding cursor for the widget.
563 */
564 void OCCViewer_ViewWindow::activateRotation()
565 {
566   if ( !transformRequested() && !myCursorIsHand )
567     myCursor = cursor();                // save old cursor
568
569   if ( myOperation != ROTATE ) {
570     QPixmap rotatePixmap (imageRotateCursor);
571     QCursor rotCursor (rotatePixmap);
572     if( setTransformRequested ( ROTATE ) )
573       myViewPort->setCursor( rotCursor );
574   }
575 }
576
577 /*!
578   \brief Compute the gravity center.
579   \param theX used to return X coordinate of the gravity center
580   \param theY used to return Y coordinate of the gravity center
581   \param theZ used to return Z coordinate of the gravity center
582   \return \c true if the gravity center is computed
583 */
584 bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ )
585 {
586   Handle(Visual3d_View) aView = myViewPort->getView()->View();
587
588   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ;
589   Standard_Real Umin,Vmin,Umax,Vmax ;
590   Standard_Integer Nstruct,Npoint ;
591   Graphic3d_MapOfStructure MySetOfStructures;
592
593   aView->DisplayedStructures (MySetOfStructures);
594   Nstruct = MySetOfStructures.Extent() ;
595
596   Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
597   aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax) ;
598   Npoint = 0 ; theX = theY = theZ = 0. ;
599   for( ; MyIterator.More(); MyIterator.Next()) {
600     if (!(MyIterator.Key())->IsEmpty()) {
601       (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin,
602                                          Xmax,Ymax,Zmax) ;
603
604       Standard_Real LIM = ShortRealLast() -1.;
605       if (!    (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM
606                 ||  fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) {
607
608         aView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
609         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
610           Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ;
611         }
612         aView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
613         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
614           Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ;
615         }
616         aView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
617         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
618           Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ;
619         }
620         aView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
621         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
622           Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ;
623         }
624         aView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
625         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
626           Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ;
627         }
628         aView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
629         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
630           Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ;
631         }
632         aView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
633         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
634           Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ;
635         }
636         aView->Projects(Xmax,Ymax,Zmax,U,V,W) ;
637         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
638           Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ;
639         }
640       }
641     }
642   }
643   if( Npoint > 0 ) {
644     theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ;
645   }
646   return true;
647 }
648
649 /*!
650   \brief Set the gravity center as a rotation point.
651 */
652 void OCCViewer_ViewWindow::activateSetRotationGravity()
653 {
654   if ( myRotationPointSelection )
655   {
656     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
657     ic->CloseAllContexts();
658     myOperation = NOTHING;
659     myViewPort->setCursor( myCursor );
660     myCursorIsHand = false;
661     myRotationPointSelection = false;
662   }
663
664   myPrevPointType = myCurrPointType;
665   myCurrPointType = GRAVITY;
666
667   Standard_Real Xcenter, Ycenter, Zcenter;
668   if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
669     mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
670 }
671
672 /*!
673   \brief Update gravity center in the "Set Rotation Point" dialog box.
674   \sa OCCViewer_SetRotationPointDlg class
675 */
676 void OCCViewer_ViewWindow::updateGravityCoords()
677 {
678   if ( mySetRotationPointDlg && mySetRotationPointDlg->isVisible() && myCurrPointType == GRAVITY )
679   {
680     Standard_Real Xcenter, Ycenter, Zcenter;
681     if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
682       mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
683   }
684 }
685
686 /*!
687   \brief Set the point selected by the user as a rotation point.
688   \param theX X coordinate of the rotation point
689   \param theY Y coordinate of the rotation point
690   \param theZ Z coordinate of the rotation point
691 */
692 void OCCViewer_ViewWindow::activateSetRotationSelected( double theX, double theY, double theZ )
693 {
694   if ( myRotationPointSelection )
695   {
696     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
697     ic->CloseAllContexts();
698     myOperation = NOTHING;
699     myViewPort->setCursor( myCursor );
700     myCursorIsHand = false;
701     myRotationPointSelection = false;
702   }
703
704   myPrevPointType = myCurrPointType;
705   myCurrPointType = SELECTED;
706   mySelectedPoint.SetCoord(theX,theY,theZ);
707 }
708
709 /*!
710   \brief Start the point selection process.
711 */
712 void OCCViewer_ViewWindow::activateStartPointSelection()
713 {
714   myPrevPointType = myCurrPointType;
715   myCurrPointType = SELECTED;
716
717   // activate selection ------>
718   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
719
720   ic->OpenLocalContext();
721
722   AIS_ListOfInteractive aList;
723   ic->DisplayedObjects( aList );
724   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
725   {
726     Handle(AIS_InteractiveObject) anObj = it.Value();
727     if ( !anObj.IsNull() && anObj->HasPresentation() &&
728          anObj->IsKind( STANDARD_TYPE(AIS_Shape) ) )
729     {
730       ic->Load(anObj,-1);
731       ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX));
732      }
733   }
734   // activate selection <------
735
736   if ( !myCursorIsHand )
737   {
738     QCursor handCursor (Qt::PointingHandCursor);
739     myCursorIsHand = true;
740     myCursor = cursor();
741     myViewPort->setCursor( handCursor );
742   }
743   myRotationPointSelection = true;
744 }
745
746 /*!
747   \brief Start global panning operation
748
749   Sets the corresponding cursor for the widget.
750 */
751 void OCCViewer_ViewWindow::activateGlobalPanning()
752 {
753   Handle(V3d_View) aView3d = myViewPort->getView();
754   if ( !aView3d.IsNull() ) {
755     QPixmap globalPanPixmap (imageCrossCursor);
756     QCursor glPanCursor (globalPanPixmap);
757     myCurScale = aView3d->Scale();
758     aView3d->FitAll(0.01, false);
759     myCursor = cursor();                // save old cursor
760     myViewPort->fitAll(); // fits view before selecting a new scene center
761     if( setTransformRequested( PANGLOBAL ) )
762       myViewPort->setCursor( glPanCursor );
763   }
764 }
765
766 /*!
767   \brief Starts fit operation.
768
769   Sets the corresponding cursor for the widget.
770 */
771 void OCCViewer_ViewWindow::activateWindowFit()
772 {
773   if ( !transformRequested() && !myCursorIsHand )
774     myCursor = cursor();                /* save old cursor */
775
776   if ( myOperation != WINDOWFIT ) {
777     QCursor handCursor (Qt::PointingHandCursor);
778     if( setTransformRequested ( WINDOWFIT ) )
779     {
780       myViewPort->setCursor ( handCursor );
781       myCursorIsHand = true;
782     }
783   }
784 }
785
786 /*!
787   \brief Start delayed viewer operation.
788 */
789 bool OCCViewer_ViewWindow::setTransformRequested( OperationType op )
790 {
791   bool ok = transformEnabled( op );
792   myOperation = ok ? op : NOTHING;
793   myViewPort->setMouseTracking( myOperation == NOTHING );  
794   return ok;
795 }
796
797 /*!
798   \brief Handle mouse move event.
799   \param theEvent mouse event
800 */
801 void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent )
802 {
803   if ( myIsKeyFree && interactionStyle() == SUIT_ViewModel::KEY_FREE ) {
804     myIsKeyFree = false;
805     switch ( getButtonState( theEvent, interactionStyle() ) ) {
806     case ZOOMVIEW:
807       myViewPort->startZoomAtPoint( myStartX, myStartY );
808       activateZoom();
809       break;
810     case PANVIEW:
811       activatePanning();
812       break;
813     case ROTATE:
814       activateRotation();
815       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
816       break;
817     default:
818       break;
819     }
820   }
821
822   myCurrX = theEvent->x();
823   myCurrY = theEvent->y();
824   switch (myOperation) {
825   case ROTATE:
826     myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
827     break;
828
829   case ZOOMVIEW:
830     myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
831     myStartX = myCurrX;
832     myStartY = myCurrY;
833     break;
834
835   case PANVIEW:
836     myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
837     myStartX = myCurrX;
838     myStartY = myCurrY;
839     break;
840
841 /*    case WINDOWFIT:
842     myDrawRect = true;
843     repaint();
844     break;
845 */
846   case PANGLOBAL:
847     break;
848
849   default:
850     if ( myRotationPointSelection || isSketcherStyle() )
851     {
852       emit mouseMoving( this, theEvent );
853     }
854     else
855     {
856       int aState = theEvent->modifiers();
857       int aButton = theEvent->buttons();
858       int anInteractionStyle = interactionStyle();
859       if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD &&
860            aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
861            ( anInteractionStyle == SUIT_ViewModel::KEY_FREE &&
862            aButton == Qt::LeftButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
863         myDrawRect = myEnableDrawMode;
864         if ( myDrawRect ) {
865           drawRect();
866           if ( !myCursorIsHand )        {   // we are going to sketch a rectangle
867             QCursor handCursor (Qt::PointingHandCursor);
868             myCursorIsHand = true;
869             myCursor = cursor();
870             myViewPort->setCursor( handCursor );
871           }
872         }
873         emit mouseMoving( this, theEvent );
874       }
875       else if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD &&
876                 aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
877                 ( anInteractionStyle == SUIT_ViewModel::KEY_FREE &&
878                 aButton == Qt::RightButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
879         OCCViewer_ViewSketcher* sketcher = 0;
880         QList<OCCViewer_ViewSketcher*>::Iterator it;
881         for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
882         {
883           OCCViewer_ViewSketcher* sk = (*it);
884           if( sk->isDefault() && sk->sketchButton() == aButton )
885             sketcher = sk;
886         }
887         if ( sketcher && myCurSketch == -1 )
888         {
889           activateSketching( sketcher->type() );
890           if ( mypSketcher )
891           {
892             myCurSketch = mypSketcher->sketchButton();
893
894             if ( l_mbPressEvent )
895             {
896               QApplication::sendEvent( getViewPort(), l_mbPressEvent );
897               delete l_mbPressEvent;
898               l_mbPressEvent = 0;
899             }
900             QApplication::sendEvent( getViewPort(), theEvent );
901           }
902         }
903       }
904       else
905         emit mouseMoving( this, theEvent );
906     }
907   }
908 }
909
910 /*!
911   \brief Handle mouse release event.
912   \param theEvent mouse event
913 */
914 void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
915 {
916   switch ( myOperation ) {
917   case NOTHING:
918     {
919       int prevState = myCurSketch;
920       if(theEvent->button() == Qt::RightButton)
921       {
922         QList<OCCViewer_ViewSketcher*>::Iterator it;
923         for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it )
924         {
925           OCCViewer_ViewSketcher* sk = (*it);
926           if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
927             myCurSketch = -1;
928         }
929       }
930
931       emit mouseReleased(this, theEvent);
932       if(theEvent->button() == Qt::RightButton && prevState == -1)
933       {
934         QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
935                                   theEvent->pos(), theEvent->globalPos() );
936         emit contextMenuRequested( &aEvent );
937       }
938     }
939     break;
940   case ROTATE:
941     myViewPort->endRotation();
942     resetState();
943     break;
944
945   case PANVIEW:
946   case ZOOMVIEW:
947     resetState();
948     break;
949
950   case PANGLOBAL:
951     if ( theEvent->button() == Qt::LeftButton ) {
952       myViewPort->setCenter( theEvent->x(), theEvent->y() );
953       myViewPort->getView()->SetScale(myCurScale);
954       resetState();
955     }
956     break;
957
958   case WINDOWFIT:
959     if ( theEvent->button() == Qt::LeftButton ) {
960       myCurrX = theEvent->x();
961       myCurrY = theEvent->y();
962       drawRect();
963       QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
964       if ( !rect.isEmpty() ) myViewPort->fitRect(rect);
965       endDrawRect();
966       resetState();
967     }
968     break;
969   }
970
971   // NOTE: viewer 3D detects a rectangle of selection using this event
972   // so we must emit it BEFORE resetting the selection rectangle
973
974   if ( theEvent->button() == Qt::LeftButton && myDrawRect ) {
975     drawRect();
976     endDrawRect();
977     resetState();
978     myViewPort->update();
979   }
980
981   if ( l_mbPressEvent )
982   {
983     delete l_mbPressEvent;
984     l_mbPressEvent = 0;
985   }
986 }
987
988 /*!
989   \brief Reset the viewport to its initial state
990   ( no transformations in process etc. )
991 */
992 void OCCViewer_ViewWindow::resetState()
993 {
994   myDrawRect = false;
995
996   if ( myRotationPointSelection )
997   {
998     QCursor handCursor (Qt::PointingHandCursor);
999     myViewPort->setCursor( handCursor );
1000   }
1001   else
1002   {
1003     if ( transformRequested() || myCursorIsHand )
1004       myViewPort->setCursor( myCursor );
1005     myCursorIsHand = false;
1006   }
1007
1008   if ( transformRequested() )
1009     emit vpTransformationFinished (myOperation);
1010
1011   setTransformInProcess( false );
1012   setTransformRequested( NOTHING );
1013 }
1014
1015
1016 /*!
1017   \brief Draw rubber band rectangle.
1018 */
1019 void OCCViewer_ViewWindow::drawRect()
1020 {
1021   if ( !myRectBand ) {
1022     myRectBand = new QtxRectRubberBand( myViewPort );
1023     //QPalette palette;
1024     //palette.setColor(myRectBand->foregroundRole(), Qt::white);
1025     //myRectBand->setPalette(palette);
1026   }
1027   //myRectBand->hide();
1028   
1029   myRectBand->setUpdatesEnabled ( false );
1030   QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
1031   myRectBand->initGeometry( aRect );
1032
1033   if ( !myRectBand->isVisible() )
1034     myRectBand->show();
1035
1036   myRectBand->setUpdatesEnabled ( true );
1037   //myRectBand->repaint();
1038
1039   //myRectBand->setVisible( aRect.isValid() );
1040   //if ( myRectBand->isVisible() )
1041   //  myRectBand->repaint();
1042   //else
1043   //  myRectBand->show();
1044   //myRectBand->repaint();
1045 }
1046
1047 /*!
1048   \brief Clear rubber band rectangle on the end on the dragging operation.
1049 */
1050 void OCCViewer_ViewWindow::endDrawRect()
1051 {
1052   //delete myRectBand;
1053   //myRectBand = 0;
1054   if ( myRectBand )
1055     {
1056       myRectBand->clearGeometry();
1057       myRectBand->hide();
1058     }
1059 }
1060
1061 /*!
1062   \brief Create actions.
1063 */
1064 void OCCViewer_ViewWindow::createActions()
1065 {
1066   if( !toolMgr()->isEmpty() )
1067     return;
1068   
1069   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1070
1071   QtxAction* aAction;
1072
1073   // Dump view
1074   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ),
1075                            tr( "MNU_DUMP_VIEW" ), 0, this);
1076   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
1077   connect(aAction, SIGNAL(triggered()), this, SLOT(onDumpView()));
1078   toolMgr()->registerAction( aAction, DumpId );
1079
1080   // FitAll
1081   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ),
1082                            tr( "MNU_FITALL" ), 0, this);
1083   aAction->setStatusTip(tr("DSC_FITALL"));
1084   connect(aAction, SIGNAL(triggered()), this, SLOT(onFitAll()));
1085   toolMgr()->registerAction( aAction, FitAllId );
1086
1087   // FitRect
1088   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ),
1089                            tr( "MNU_FITRECT" ), 0, this);
1090   aAction->setStatusTip(tr("DSC_FITRECT"));
1091   connect(aAction, SIGNAL(triggered()), this, SLOT(activateWindowFit()));
1092   toolMgr()->registerAction( aAction, FitRectId );
1093   
1094   // Zoom
1095   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ),
1096                            tr( "MNU_ZOOM_VIEW" ), 0, this);
1097   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
1098   connect(aAction, SIGNAL(triggered()), this, SLOT(activateZoom()));
1099   toolMgr()->registerAction( aAction, ZoomId );
1100
1101   // Panning
1102   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ),
1103                            tr( "MNU_PAN_VIEW" ), 0, this);
1104   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
1105   connect(aAction, SIGNAL(triggered()), this, SLOT(activatePanning()));
1106   toolMgr()->registerAction( aAction, PanId );
1107
1108   // Global Panning
1109   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ),
1110                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
1111   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
1112   connect(aAction, SIGNAL(triggered()), this, SLOT(activateGlobalPanning()));
1113   toolMgr()->registerAction( aAction, GlobalPanId );
1114
1115   // Rotation Point
1116   mySetRotationPointAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATION_POINT" ) ),
1117                            tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this);
1118   mySetRotationPointAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW"));
1119   mySetRotationPointAction->setCheckable( true );
1120   connect(mySetRotationPointAction, SIGNAL(toggled( bool )), this, SLOT(onSetRotationPoint( bool )));
1121   toolMgr()->registerAction( mySetRotationPointAction, ChangeRotationPointId );
1122
1123   // Rotation
1124   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ),
1125                            tr( "MNU_ROTATE_VIEW" ), 0, this);
1126   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
1127   connect(aAction, SIGNAL(triggered()), this, SLOT(activateRotation()));
1128   toolMgr()->registerAction( aAction, RotationId );
1129
1130   // Projections
1131   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ),
1132                            tr( "MNU_FRONT_VIEW" ), 0, this, false, "Viewers:Front view");
1133   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
1134   connect(aAction, SIGNAL(triggered()), this, SLOT(onFrontView()));
1135   this->addAction(aAction);
1136   toolMgr()->registerAction( aAction, FrontId );
1137
1138   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ),
1139                            tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view");
1140   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
1141   connect(aAction, SIGNAL(triggered()), this, SLOT(onBackView()));
1142   this->addAction(aAction);
1143   toolMgr()->registerAction( aAction, BackId );
1144
1145   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ),
1146                            tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view");
1147   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
1148   connect(aAction, SIGNAL(triggered()), this, SLOT(onTopView()));
1149   this->addAction(aAction);
1150   toolMgr()->registerAction( aAction, TopId );
1151
1152   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ),
1153                            tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view");
1154   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
1155   connect(aAction, SIGNAL(triggered()), this, SLOT(onBottomView()));
1156   this->addAction(aAction);
1157   toolMgr()->registerAction( aAction, BottomId );
1158   
1159   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ),
1160                            tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view");
1161   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
1162   connect(aAction, SIGNAL(triggered()), this, SLOT(onLeftView()));
1163   this->addAction(aAction);
1164   toolMgr()->registerAction( aAction, LeftId );
1165
1166   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ),
1167                            tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view");
1168   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
1169   connect(aAction, SIGNAL(triggered()), this, SLOT(onRightView()));
1170   this->addAction(aAction);
1171   toolMgr()->registerAction( aAction, RightId );
1172
1173   // rotate anticlockwise
1174   aAction = new QtxAction(tr("MNU_ANTICLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ANTICLOCKWISE" ) ),
1175                            tr( "MNU_ANTICLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate anticlockwise");
1176   aAction->setStatusTip(tr("DSC_ANTICLOCKWISE_VIEW"));
1177   connect(aAction, SIGNAL(triggered()), this, SLOT(onAntiClockWiseView()));
1178   this->addAction(aAction);
1179   toolMgr()->registerAction( aAction, AntiClockWiseId );
1180
1181   // rotate clockwise
1182   aAction = new QtxAction(tr("MNU_CLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_CLOCKWISE" ) ),
1183                            tr( "MNU_CLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate clockwise");
1184   aAction->setStatusTip(tr("DSC_CLOCKWISE_VIEW"));
1185   connect(aAction, SIGNAL(triggered()), this, SLOT(onClockWiseView()));
1186   this->addAction(aAction);
1187   toolMgr()->registerAction( aAction, ClockWiseId );
1188
1189   // Reset
1190   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ),
1191                            tr( "MNU_RESET_VIEW" ), 0, this, false, "Viewers:Reset view");
1192   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
1193   connect(aAction, SIGNAL(triggered()), this, SLOT(onResetView()));
1194   this->addAction(aAction);
1195   toolMgr()->registerAction( aAction, ResetId );
1196
1197   // Clone
1198   aAction = new QtxAction(tr("MNU_CLONE_VIEW"),
1199                           aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_CLONE_VIEW")),
1200                           tr("MNU_CLONE_VIEW"), 0, this);
1201   aAction->setStatusTip(tr("DSC_CLONE_VIEW"));
1202   connect(aAction, SIGNAL(triggered()), this, SLOT(onCloneView()));
1203   toolMgr()->registerAction( aAction, CloneId );
1204
1205   myClippingAction = new QtxAction(tr("MNU_CLIPPING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ) ),
1206                            tr( "MNU_CLIPPING" ), 0, this);
1207   myClippingAction->setStatusTip(tr("DSC_CLIPPING"));
1208   myClippingAction->setCheckable( true );
1209   connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool )));
1210   toolMgr()->registerAction( myClippingAction, ClippingId );
1211
1212   aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ),
1213                            tr( "MNU_SHOOT_VIEW" ), 0, this);
1214   aAction->setStatusTip(tr("DSC_SHOOT_VIEW"));
1215   connect(aAction, SIGNAL(triggered()), this, SLOT(onMemorizeView()));
1216   toolMgr()->registerAction( aAction, MemId );
1217
1218   aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ),
1219                            tr( "MNU_PRESETS_VIEW" ), 0, this);
1220   aAction->setStatusTip(tr("DSC_PRESETS_VIEW"));
1221   connect(aAction, SIGNAL(triggered()), this, SLOT(onRestoreView()));
1222   toolMgr()->registerAction( aAction, RestoreId );
1223
1224   if (myModel->trihedronActivated()) {
1225     aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ),
1226                              tr( "MNU_SHOW_TRIHEDRE" ), 0, this);
1227     aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE"));
1228     connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow()));
1229     toolMgr()->registerAction( aAction, TrihedronShowId );
1230   }
1231
1232   // Scale
1233   aAction = new QtxAction(tr("MNU_SCALING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SCALING" ) ),
1234                            tr( "MNU_SCALING" ), 0, this);
1235   aAction->setStatusTip(tr("DSC_SCALING"));
1236   connect(aAction, SIGNAL(triggered()), this, SLOT(onAxialScale()));
1237   toolMgr()->registerAction( aAction, AxialScaleId );
1238
1239   // Graduated axes 
1240   aAction = new QtxAction(tr("MNU_GRADUATED_AXES"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_GRADUATED_AXES" ) ),
1241                            tr( "MNU_GRADUATED_AXES" ), 0, this);
1242   aAction->setStatusTip(tr("DSC_GRADUATED_AXES"));
1243   connect(aAction, SIGNAL(triggered()), this, SLOT(onGraduatedAxes()));
1244   toolMgr()->registerAction( aAction, GraduatedAxesId );
1245
1246   // Active only ambient light or not
1247   aAction = new QtxAction(tr("MNU_AMBIENT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_AMBIENT" ) ),
1248                            tr( "MNU_AMBIENT" ), 0, this);
1249   aAction->setStatusTip(tr("DSC_AMBIENT"));
1250   connect(aAction, SIGNAL(triggered()), this, SLOT(onAmbientToogle()));
1251   toolMgr()->registerAction( aAction, AmbientId );
1252
1253   // Switch between interaction styles
1254   aAction = new QtxAction(tr("MNU_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_STYLE_SWITCH" ) ),
1255                           tr( "MNU_STYLE_SWITCH" ), 0, this);
1256   aAction->setStatusTip(tr("DSC_STYLE_SWITCH"));
1257   aAction->setCheckable(true);
1258   connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchInteractionStyle(bool)));
1259   toolMgr()->registerAction( aAction, SwitchInteractionStyleId );
1260
1261   // Switch between zooming styles
1262   aAction = new QtxAction(tr("MNU_ZOOMING_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH" ) ),
1263                           tr( "MNU_ZOOMING_STYLE_SWITCH" ), 0, this);
1264   aAction->setStatusTip(tr("DSC_ZOOMING_STYLE_SWITCH"));
1265   aAction->setCheckable(true);
1266   connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool)));
1267   toolMgr()->registerAction( aAction, SwitchZoomingStyleId );
1268
1269   // Maximized view
1270   aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ),
1271                           tr( "MNU_MINIMIZE_VIEW" ), 0, this );
1272   aAction->setStatusTip(tr("DSC_MINIMIZE_VIEW"));
1273   connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView()));
1274   toolMgr()->registerAction( aAction, MaximizedId );
1275
1276   // Synchronize View 
1277   toolMgr()->registerAction( synchronizeAction(), SynchronizeId );
1278 }
1279
1280 /*!
1281   \brief Create toolbar.
1282 */
1283 void OCCViewer_ViewWindow::createToolBar()
1284 {
1285   QString aToolbarName;
1286   switch (my2dMode) {
1287   case XYPlane:
1288     aToolbarName = tr( "LBL_XYTOOLBAR_LABEL" );
1289     break;
1290   case XZPlane:
1291     aToolbarName = tr( "LBL_XZTOOLBAR_LABEL" );
1292     break;
1293   case YZPlane:
1294     aToolbarName = tr( "LBL_YZTOOLBAR_LABEL" );
1295     break;
1296   default:
1297     aToolbarName = tr( "LBL_3DTOOLBAR_LABEL" );
1298   }
1299   
1300   int tid = toolMgr()->createToolBar( aToolbarName, false );
1301
1302   toolMgr()->append( DumpId, tid );
1303   toolMgr()->append( SwitchInteractionStyleId, tid );
1304 #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
1305   toolMgr()->append( SwitchZoomingStyleId, tid );
1306 #endif
1307   if( myModel->trihedronActivated() )
1308     toolMgr()->append( TrihedronShowId, tid );
1309
1310   QtxMultiAction* aScaleAction = new QtxMultiAction( this );
1311   aScaleAction->insertAction( toolMgr()->action( FitAllId ) );
1312   aScaleAction->insertAction( toolMgr()->action( FitRectId ) );
1313   aScaleAction->insertAction( toolMgr()->action( ZoomId ) );
1314   toolMgr()->append( aScaleAction, tid );
1315
1316   QtxMultiAction* aPanningAction = new QtxMultiAction( this );
1317   aPanningAction->insertAction( toolMgr()->action( PanId ) );
1318   aPanningAction->insertAction( toolMgr()->action( GlobalPanId ) );
1319   toolMgr()->append( aPanningAction, tid );
1320
1321   if (my2dMode == No2dMode) {
1322     toolMgr()->append( ChangeRotationPointId, tid );
1323     toolMgr()->append( RotationId, tid );
1324
1325     QtxMultiAction* aViewsAction = new QtxMultiAction( this );
1326     aViewsAction->insertAction( toolMgr()->action( FrontId ) );
1327     aViewsAction->insertAction( toolMgr()->action( BackId ) );
1328     aViewsAction->insertAction( toolMgr()->action( TopId ) );
1329     aViewsAction->insertAction( toolMgr()->action( BottomId ) );
1330     aViewsAction->insertAction( toolMgr()->action( LeftId ) );
1331     aViewsAction->insertAction( toolMgr()->action( RightId ) );
1332     toolMgr()->append( aViewsAction, tid );
1333
1334     toolMgr()->append( AntiClockWiseId, tid );
1335     toolMgr()->append( ClockWiseId, tid );
1336
1337     toolMgr()->append( ResetId, tid );
1338   }
1339
1340   QtxMultiAction* aMemAction = new QtxMultiAction( this );
1341   aMemAction->insertAction( toolMgr()->action( MemId ) );
1342   aMemAction->insertAction( toolMgr()->action( RestoreId ) );
1343   toolMgr()->append( aMemAction, tid );
1344
1345   toolMgr()->append( toolMgr()->separator(), tid );
1346   toolMgr()->append( CloneId, tid );
1347   
1348   toolMgr()->append( toolMgr()->separator(), tid );
1349   toolMgr()->append( ClippingId, tid );
1350   toolMgr()->append( AxialScaleId, tid );
1351 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
1352   toolMgr()->append( GraduatedAxesId, tid );
1353 #endif
1354   toolMgr()->append( AmbientId, tid );
1355
1356   toolMgr()->append( MaximizedId, tid );
1357   toolMgr()->append( SynchronizeId, tid );
1358 }
1359
1360 /*!
1361   \brief Perform 'fit all' operation.
1362 */
1363 void OCCViewer_ViewWindow::onViewFitAll()
1364 {
1365   myViewPort->fitAll();
1366 }
1367
1368 /*!
1369   \brief Perform "front view" transformation.
1370 */
1371 void OCCViewer_ViewWindow::onFrontView()
1372 {
1373   emit vpTransformationStarted ( FRONTVIEW );
1374   Handle(V3d_View) aView3d = myViewPort->getView();
1375   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos);
1376   onViewFitAll();
1377   emit vpTransformationFinished ( FRONTVIEW );
1378 }
1379
1380 /*!
1381   \brief Perform "back view" transformation.
1382 */
1383 void OCCViewer_ViewWindow::onBackView()
1384 {
1385   emit vpTransformationStarted ( BACKVIEW );
1386   Handle(V3d_View) aView3d = myViewPort->getView();
1387   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg);
1388   onViewFitAll();
1389   emit vpTransformationFinished ( BACKVIEW );
1390 }
1391
1392 /*!
1393   \brief Perform "top view" transformation.
1394 */
1395 void OCCViewer_ViewWindow::onTopView()
1396 {
1397   emit vpTransformationStarted ( TOPVIEW );
1398   Handle(V3d_View) aView3d = myViewPort->getView();
1399   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos);
1400   onViewFitAll();
1401   emit vpTransformationFinished ( TOPVIEW );
1402 }
1403
1404 /*!
1405   \brief Perform "bottom view" transformation.
1406 */
1407 void OCCViewer_ViewWindow::onBottomView()
1408 {
1409   emit vpTransformationStarted ( BOTTOMVIEW );
1410   Handle(V3d_View) aView3d = myViewPort->getView();
1411   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg);
1412   onViewFitAll();
1413   emit vpTransformationFinished ( BOTTOMVIEW );
1414 }
1415
1416 /*!
1417   \brief Perform "left view" transformation.
1418 */
1419 void OCCViewer_ViewWindow::onLeftView()
1420 {
1421   emit vpTransformationStarted ( LEFTVIEW );
1422   Handle(V3d_View) aView3d = myViewPort->getView();
1423   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg);
1424   onViewFitAll();
1425   emit vpTransformationFinished ( LEFTVIEW );
1426 }
1427
1428 /*!
1429   \brief Perform "right view" transformation.
1430 */
1431 void OCCViewer_ViewWindow::onRightView()
1432 {
1433   emit vpTransformationStarted ( RIGHTVIEW );
1434   Handle(V3d_View) aView3d = myViewPort->getView();
1435   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos);
1436   onViewFitAll();
1437   emit vpTransformationFinished ( RIGHTVIEW );
1438 }
1439
1440 /*!
1441   \brief Rotate view 90 degrees clockwise
1442 */
1443 void OCCViewer_ViewWindow::onClockWiseView()
1444 {
1445   emit vpTransformationStarted ( CLOCKWISEVIEW );
1446   myViewPort->rotateXY( 90. );
1447   emit vpTransformationFinished ( CLOCKWISEVIEW );
1448 }
1449
1450 /*!
1451   \brief Rotate view 90 degrees conterclockwise
1452 */
1453 void OCCViewer_ViewWindow::onAntiClockWiseView()
1454 {
1455   emit vpTransformationStarted ( ANTICLOCKWISEVIEW );
1456   myViewPort->rotateXY( -90. );
1457   emit vpTransformationFinished ( ANTICLOCKWISEVIEW );
1458 }
1459
1460 /*!
1461   \brief Perform "reset view" transformation.
1462
1463   Sets default orientation of the viewport camera.
1464 */
1465 void OCCViewer_ViewWindow::onResetView()
1466 {
1467   emit vpTransformationStarted( RESETVIEW );
1468   bool upd = myViewPort->getView()->SetImmediateUpdate( false );
1469   myViewPort->getView()->Reset( false );
1470   myViewPort->fitAll( false, true, false );
1471   myViewPort->getView()->SetImmediateUpdate( upd );
1472   myViewPort->getView()->Update();
1473   emit vpTransformationFinished( RESETVIEW );
1474 }
1475
1476 /*!
1477   \brief Perform "fit all" transformation.
1478 */
1479 void OCCViewer_ViewWindow::onFitAll()
1480 {
1481   emit vpTransformationStarted( FITALLVIEW );
1482   myViewPort->fitAll();
1483   emit vpTransformationFinished( FITALLVIEW );
1484 }
1485
1486 /*!
1487   \brief Called if 'change rotation point' operation is activated.
1488   \param on action state
1489 */
1490 void OCCViewer_ViewWindow::onSetRotationPoint( bool on )
1491 {
1492   if (on)
1493   {
1494     if (!mySetRotationPointDlg)
1495     {
1496       mySetRotationPointDlg = new OCCViewer_SetRotationPointDlg (this);
1497       mySetRotationPointDlg->SetAction(mySetRotationPointAction);
1498     }
1499
1500     if (!mySetRotationPointDlg->isVisible())
1501     {
1502       //if (mySetRotationPointDlg->IsFirstShown())
1503       if (myCurrPointType == GRAVITY)
1504       {
1505         Standard_Real Xcenter, Ycenter, Zcenter;
1506         if (computeGravityCenter(Xcenter, Ycenter, Zcenter))
1507           mySetRotationPointDlg->setCoords(Xcenter, Ycenter, Zcenter);
1508       }
1509       mySetRotationPointDlg->show();
1510     }
1511   }
1512   else
1513   {
1514     if (mySetRotationPointDlg->isVisible())
1515       mySetRotationPointDlg->hide();
1516   }
1517 }
1518
1519 /*!
1520    \brief Create one more window with same content.
1521 */
1522 void OCCViewer_ViewWindow::onCloneView()
1523 {
1524   SUIT_ViewWindow* vw = myManager->createViewWindow();
1525   //vw->show();
1526   emit viewCloned( vw );
1527 }
1528
1529 /*!
1530   \brief called if clipping operation is activated.
1531
1532   Enables/disables clipping plane displaying.
1533
1534   \parma on action state
1535 */
1536 void OCCViewer_ViewWindow::onClipping( bool on )
1537 {
1538   /*
1539   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1540   if ( on )
1541     myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING_PRESSED" )));
1542   else
1543     myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" )));
1544   */
1545   OCCViewer_ViewWindow* aParent = dynamic_cast<OCCViewer_ViewWindow*>(parent()->parent());
1546   if (!aParent)
1547     aParent = this;
1548   if ( on )
1549     {
1550       if ( !myClippingDlg )
1551         {
1552           myClippingDlg = new OCCViewer_ClippingDlg( aParent );
1553           myClippingDlg->SetAction( myClippingAction );
1554         }
1555     
1556       if ( !myClippingDlg->isVisible() )
1557         myClippingDlg->show();
1558     }
1559   else
1560     {
1561       if ( myClippingDlg->isVisible() )
1562         myClippingDlg->hide();
1563       aParent->setCuttingPlane(false);
1564     }
1565 }
1566
1567 /*!
1568   Creates one more window with same content
1569 */
1570 void OCCViewer_ViewWindow::onAxialScale()
1571 {
1572   if ( !myScalingDlg )
1573     myScalingDlg = new OCCViewer_AxialScaleDlg( this );
1574   
1575   if ( !myScalingDlg->isVisible() )
1576   {
1577     myScalingDlg->Update();
1578     myScalingDlg->show();
1579   }
1580 }
1581
1582 /*!
1583   Shows Graduated Axes dialog
1584 */
1585 void OCCViewer_ViewWindow::onGraduatedAxes()
1586 {
1587   myCubeAxesDlg->Update();
1588   myCubeAxesDlg->show();
1589 }
1590
1591 void OCCViewer_ViewWindow::onAmbientToogle()
1592 {
1593   Handle(V3d_Viewer) viewer = myViewPort->getViewer();
1594   viewer->InitDefinedLights();
1595   while(viewer->MoreDefinedLights())
1596     {
1597       Handle(V3d_Light) light = viewer->DefinedLight();
1598       if(light->Type() != V3d_AMBIENT)
1599         {
1600           Handle(V3d_View) aView3d = myViewPort->getView();
1601           if( aView3d->IsActiveLight(light) ) viewer->SetLightOff(light);
1602           else viewer->SetLightOn(light);
1603         }
1604       viewer->NextDefinedLights();
1605     }
1606   viewer->Update();
1607 }
1608
1609 /*!
1610   \brief Store view parameters.
1611 */
1612 void OCCViewer_ViewWindow::onMemorizeView()
1613 {
1614   appendViewAspect( getViewParams() );
1615 }
1616
1617 /*!
1618   \brief Restore view parameters.
1619 */
1620 void OCCViewer_ViewWindow::onRestoreView()
1621 {
1622   OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), this );
1623   connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) );
1624   aDlg->exec();
1625   updateViewAspects( aDlg->parameters() );
1626   if( myRestoreFlag && aDlg->parameters().count() )
1627     performRestoring( aDlg->currentItem() );
1628 }
1629
1630 /*!
1631   \brief Restore view parameters.
1632   \param anItem view parameters
1633 */
1634 void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool baseParamsOnly )
1635 {
1636   Handle(V3d_View) aView3d = myViewPort->getView();
1637
1638   Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
1639   aView3d->SetScale( anItem.scale );
1640   aView3d->SetCenter( anItem.centerX, anItem.centerY );
1641   aView3d->SetTwist( anItem.twist );
1642   aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ );
1643   aView3d->SetImmediateUpdate( prev );
1644   aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ );
1645   aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
1646   aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ );
1647
1648   if ( !baseParamsOnly ) {
1649
1650     myModel->setTrihedronShown( anItem.isVisible );
1651     myModel->setTrihedronSize( anItem.size );
1652         
1653 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
1654     // graduated trihedron
1655     bool anIsVisible = anItem.gtIsVisible;
1656     OCCViewer_AxisWidget::AxisData anAxisData[3];
1657     anAxisData[0].DrawName = anItem.gtDrawNameX;
1658     anAxisData[1].DrawName = anItem.gtDrawNameZ;
1659     anAxisData[2].DrawName = anItem.gtDrawNameZ;
1660     anAxisData[0].Name = anItem.gtNameX;
1661     anAxisData[1].Name = anItem.gtNameZ;
1662     anAxisData[2].Name = anItem.gtNameZ;
1663     anAxisData[0].NameColor = QColor( anItem.gtNameColorRX,
1664                                       anItem.gtNameColorGX,
1665                                       anItem.gtNameColorBX );
1666     anAxisData[1].NameColor = QColor( anItem.gtNameColorRY,
1667                                       anItem.gtNameColorGY,
1668                                       anItem.gtNameColorBY );
1669     anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ,
1670                                       anItem.gtNameColorGZ,
1671                                       anItem.gtNameColorBZ );
1672     anAxisData[0].DrawValues = anItem.gtDrawValuesX;
1673     anAxisData[1].DrawValues = anItem.gtDrawValuesY;
1674     anAxisData[2].DrawValues = anItem.gtDrawValuesZ;
1675     anAxisData[0].NbValues = anItem.gtNbValuesX;
1676     anAxisData[1].NbValues = anItem.gtNbValuesY;
1677     anAxisData[2].NbValues = anItem.gtNbValuesZ;
1678     anAxisData[0].Offset = anItem.gtOffsetX;
1679     anAxisData[1].Offset = anItem.gtOffsetY;
1680     anAxisData[2].Offset = anItem.gtOffsetZ;
1681     anAxisData[0].Color = QColor( anItem.gtColorRX,
1682                                   anItem.gtColorGX,
1683                                   anItem.gtColorBX );
1684     anAxisData[1].Color = QColor( anItem.gtColorRY,
1685                                   anItem.gtColorGY,
1686                                   anItem.gtColorBY );
1687     anAxisData[2].Color = QColor( anItem.gtColorRZ,
1688                                   anItem.gtColorGZ,
1689                                   anItem.gtColorBZ );
1690     anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX;
1691     anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY;
1692     anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ;
1693     anAxisData[0].TickmarkLength = anItem.gtTickmarkLengthX;
1694     anAxisData[1].TickmarkLength = anItem.gtTickmarkLengthY;
1695     anAxisData[2].TickmarkLength = anItem.gtTickmarkLengthZ;
1696
1697     myCubeAxesDlg->SetData( anIsVisible, anAxisData );
1698     myCubeAxesDlg->ApplyData( aView3d );
1699 #endif
1700
1701   } // if ( !baseParamsOnly )
1702
1703   myRestoreFlag = 0;
1704 }
1705
1706 /*!
1707   \brief Set restore flag.
1708 */
1709 void OCCViewer_ViewWindow::setRestoreFlag()
1710 {
1711   myRestoreFlag = 1;
1712 }
1713
1714 /*!
1715   \brief Called when action "show/hide trihedron" is activated.
1716 */
1717 void OCCViewer_ViewWindow::onTrihedronShow()
1718 {
1719   myModel->toggleTrihedron();
1720 }
1721
1722 /*!
1723   \brief Switches "keyboard free" interaction style on/off
1724 */
1725 void OCCViewer_ViewWindow::onSwitchInteractionStyle( bool on )
1726 {
1727   myInteractionStyle = on ? (int)SUIT_ViewModel::KEY_FREE : (int)SUIT_ViewModel::STANDARD;
1728
1729   // update action state if method is called outside
1730   QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchInteractionStyleId ) );
1731   if ( a->isChecked() != on )
1732     a->setChecked( on );
1733 }
1734
1735 /*!
1736   \brief Toogles advanced zooming style (relatively to the cursor position) on/off
1737 */
1738 void OCCViewer_ViewWindow::onSwitchZoomingStyle( bool on )
1739 {
1740   myViewPort->setAdvancedZoomingEnabled( on );
1741
1742   // update action state if method is called outside
1743   QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchZoomingStyleId ) );
1744   if ( a->isChecked() != on )
1745     a->setChecked( on );
1746 }
1747
1748 /*!
1749   \brief Get current interaction style
1750   \return interaction style
1751 */
1752 int OCCViewer_ViewWindow::interactionStyle() const
1753 {
1754   return myInteractionStyle;
1755 }
1756
1757 /*!
1758   \brief Set current interaction style
1759   \param theStyle interaction style
1760 */
1761 void OCCViewer_ViewWindow::setInteractionStyle( const int theStyle )
1762 {
1763   onSwitchInteractionStyle( theStyle == (int)SUIT_ViewModel::KEY_FREE );
1764 }
1765
1766 /*!
1767   \brief Get current zooming style
1768   \return zooming style
1769 */
1770 int OCCViewer_ViewWindow::zoomingStyle() const
1771 {
1772   return myViewPort->isAdvancedZoomingEnabled() ? 1 : 0;
1773 }
1774
1775 /*!
1776   \brief Set current zooming style
1777   \param theStyle zooming style
1778 */
1779 void OCCViewer_ViewWindow::setZoomingStyle( const int theStyle )
1780 {
1781   onSwitchZoomingStyle( theStyle == 1 );
1782 }
1783
1784 /*!
1785   \brief Dump view window contents to the pixmap.
1786   \return pixmap containing all scene rendered in the window
1787 */
1788 QImage OCCViewer_ViewWindow::dumpView()
1789 {
1790   Handle(V3d_View) view = myViewPort->getView();
1791   if ( view.IsNull() )
1792     return QImage();
1793   
1794   int aWidth = myViewPort->width();
1795   int aHeight = myViewPort->height();
1796   QApplication::syncX();
1797   view->Redraw(); // In order to reactivate GL context
1798   //view->Update();
1799
1800   OpenGLUtils_FrameBuffer aFrameBuffer;
1801   if( aFrameBuffer.init( aWidth, aHeight ) )
1802   {
1803     QImage anImage( aWidth, aHeight, QImage::Format_RGB32 );
1804    
1805     glPushAttrib( GL_VIEWPORT_BIT );
1806     glViewport( 0, 0, aWidth, aHeight );
1807     aFrameBuffer.bind();
1808
1809     // draw scene
1810     view->Redraw();
1811
1812     aFrameBuffer.unbind();
1813     glPopAttrib();
1814
1815     aFrameBuffer.bind();
1816     glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() );
1817     aFrameBuffer.unbind();
1818
1819     anImage = anImage.rgbSwapped();
1820     anImage = anImage.mirrored();
1821     return anImage;
1822   }
1823   // if frame buffers are unsupported, use old functionality
1824   //view->Redraw();
1825
1826   unsigned char* data = new unsigned char[ aWidth*aHeight*4 ];
1827
1828   QPoint p = myViewPort->mapFromParent(myViewPort->geometry().topLeft());
1829
1830   glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE,
1831                 data);
1832
1833   QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 );
1834   anImage = anImage.mirrored();
1835   anImage = anImage.rgbSwapped();
1836   return anImage;
1837 }
1838
1839 bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, 
1840                                              const QString& fileName, 
1841                                              const QString& format )
1842 {
1843   if ( format != "PS" && format != "EPS")
1844     return SUIT_ViewWindow::dumpViewToFormat( img, fileName, format );
1845
1846   Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1847
1848   if (format == "PS")
1849     a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript);
1850   else if (format == "EPS")
1851     a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript);
1852
1853   return true;
1854 }
1855
1856
1857 QString OCCViewer_ViewWindow::filter() const
1858 {
1859   return tr( "OCC_IMAGE_FILES" );
1860 }
1861
1862
1863 /*!
1864   \brief Set parameters of the cutting plane
1865   \param on if \c true, cutting plane is enabled
1866   \param x X position of plane point
1867   \param y Y position of plane point
1868   \param z Z position of plane point
1869   \param dx X coordinate of plane normal
1870   \param dy Y coordinate of plane normal
1871   \param dz Z coordinate of plane normal
1872 */
1873 void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x,  const double y,  const double z,
1874                                             const double dx, const double dy, const double dz )
1875 {
1876   Handle(V3d_View) view = myViewPort->getView();
1877   if ( view.IsNull() )
1878     return;
1879
1880   if ( on ) {
1881     Handle(V3d_Viewer) viewer = myViewPort->getViewer();
1882
1883     // try to use already existing plane or create a new one
1884     Handle(V3d_Plane) clipPlane;
1885     view->InitActivePlanes();
1886
1887     // calculate new a,b,c,d values for the plane
1888     gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz));
1889     double a, b, c, d;
1890     pln.Coefficients(a, b, c, d);
1891
1892 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
1893     if (view->MoreActivePlanes()) {
1894       clipPlane = view->ActivePlane();
1895       clipPlane->SetPlane(a, b, c, d);
1896     }
1897     else
1898       clipPlane = new V3d_Plane (a, b, c, d);
1899 #else
1900     if (view->MoreActivePlanes())
1901       clipPlane = view->ActivePlane();
1902     else
1903       clipPlane = new V3d_Plane (viewer);
1904
1905     clipPlane->SetPlane(a, b, c, d);
1906 #endif
1907
1908     view->SetPlaneOn(clipPlane);
1909   }
1910   else
1911     view->SetPlaneOff();
1912
1913   view->Update();
1914   view->Redraw();
1915 }
1916
1917 void OCCViewer_ViewWindow::setCuttingPlane( bool on, const gp_Pln pln )
1918 {
1919   gp_Dir aDir = pln.Axis().Direction();
1920   gp_Pnt aPnt = pln.Location();
1921   setCuttingPlane(on, aPnt.X(), aPnt.Y(), aPnt.Z(), aDir.X(), aDir.Y(), aDir.Z());
1922 }
1923
1924
1925 /*!
1926   \brief Check if any cutting plane is enabled
1927   \return \c true if at least one cutting plane is enabled
1928 */
1929 bool OCCViewer_ViewWindow::isCuttingPlane()
1930 {
1931   Handle(V3d_View) view = myViewPort->getView();
1932   view->InitActivePlanes();
1933   return (view->MoreActivePlanes());
1934 }
1935
1936 /*!
1937   \brief Get the visual parameters of the view window.
1938   \return visual parameters of view window
1939 */
1940 viewAspect OCCViewer_ViewWindow::getViewParams() const
1941 {
1942   double centerX, centerY, projX, projY, projZ, twist;
1943   double atX, atY, atZ, eyeX, eyeY, eyeZ;
1944   double aScaleX, aScaleY, aScaleZ;
1945
1946   Handle(V3d_View) aView3d = myViewPort->getView();
1947
1948   aView3d->Center( centerX, centerY );
1949   aView3d->Proj( projX, projY, projZ );
1950   aView3d->At( atX, atY, atZ );
1951   aView3d->Eye( eyeX, eyeY, eyeZ );
1952   twist = aView3d->Twist();
1953
1954   aView3d->AxialScale(aScaleX,aScaleY,aScaleZ);
1955
1956   bool isShown = myModel->isTrihedronVisible();
1957   double size = myModel->trihedronSize();
1958
1959   QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" );
1960
1961   viewAspect params;
1962   params.scale    = aView3d->Scale();
1963   params.centerX  = centerX;
1964   params.centerY  = centerY;
1965   params.projX    = projX;
1966   params.projY    = projY;
1967   params.projZ    = projZ;
1968   params.twist    = twist;
1969   params.atX      = atX;
1970   params.atY      = atY;
1971   params.atZ      = atZ;
1972   params.eyeX     = eyeX;
1973   params.eyeY     = eyeY;
1974   params.eyeZ     = eyeZ;
1975   params.scaleX   = aScaleX;
1976   params.scaleY   = aScaleY;
1977   params.scaleZ   = aScaleZ;
1978   params.name     = aName;
1979   params.isVisible= isShown;
1980   params.size     = size;
1981
1982 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
1983   // graduated trihedron
1984   bool anIsVisible = false;
1985   OCCViewer_AxisWidget::AxisData anAxisData[3];
1986   myCubeAxesDlg->GetData( anIsVisible, anAxisData );
1987
1988   params.gtIsVisible = anIsVisible;
1989   params.gtDrawNameX = anAxisData[0].DrawName;
1990   params.gtDrawNameY = anAxisData[1].DrawName;
1991   params.gtDrawNameZ = anAxisData[2].DrawName;
1992   params.gtNameX = anAxisData[0].Name;
1993   params.gtNameY = anAxisData[1].Name;
1994   params.gtNameZ = anAxisData[2].Name;
1995   params.gtNameColorRX = anAxisData[0].NameColor.red();
1996   params.gtNameColorGX = anAxisData[0].NameColor.green();
1997   params.gtNameColorBX = anAxisData[0].NameColor.blue();
1998   params.gtNameColorRY = anAxisData[1].NameColor.red();
1999   params.gtNameColorGY = anAxisData[1].NameColor.green();
2000   params.gtNameColorBY = anAxisData[1].NameColor.blue();
2001   params.gtNameColorRZ = anAxisData[2].NameColor.red();
2002   params.gtNameColorGZ = anAxisData[2].NameColor.green();
2003   params.gtNameColorBZ = anAxisData[2].NameColor.blue();
2004   params.gtDrawValuesX = anAxisData[0].DrawValues;
2005   params.gtDrawValuesY = anAxisData[1].DrawValues;
2006   params.gtDrawValuesZ = anAxisData[2].DrawValues;
2007   params.gtNbValuesX = anAxisData[0].NbValues;
2008   params.gtNbValuesY = anAxisData[1].NbValues;
2009   params.gtNbValuesZ = anAxisData[2].NbValues;
2010   params.gtOffsetX = anAxisData[0].Offset;
2011   params.gtOffsetY = anAxisData[1].Offset;
2012   params.gtOffsetZ = anAxisData[2].Offset;
2013   params.gtColorRX = anAxisData[0].Color.red();
2014   params.gtColorGX = anAxisData[0].Color.green();
2015   params.gtColorBX = anAxisData[0].Color.blue();
2016   params.gtColorRY = anAxisData[1].Color.red();
2017   params.gtColorGY = anAxisData[1].Color.green();
2018   params.gtColorBY = anAxisData[1].Color.blue();
2019   params.gtColorRZ = anAxisData[2].Color.red();
2020   params.gtColorGZ = anAxisData[2].Color.green();
2021   params.gtColorBZ = anAxisData[2].Color.blue();
2022   params.gtDrawTickmarksX = anAxisData[0].DrawTickmarks;
2023   params.gtDrawTickmarksY = anAxisData[1].DrawTickmarks;
2024   params.gtDrawTickmarksZ = anAxisData[2].DrawTickmarks;
2025   params.gtTickmarkLengthX = anAxisData[0].TickmarkLength;
2026   params.gtTickmarkLengthY = anAxisData[1].TickmarkLength;
2027   params.gtTickmarkLengthZ = anAxisData[2].TickmarkLength;
2028 #endif
2029
2030   return params;
2031 }
2032
2033
2034 /*!
2035   \brief Get visual parameters of this view window.
2036   \return visual parameters of view window
2037 */
2038 QString OCCViewer_ViewWindow::getVisualParameters()
2039 {
2040   viewAspect params = getViewParams();
2041
2042   QStringList data;
2043
2044   data << QString( "scale=%1" )    .arg( params.scale,   0, 'e', 12 );
2045   data << QString( "centerX=%1" )  .arg( params.centerX, 0, 'e', 12 );
2046   data << QString( "centerY=%1" )  .arg( params.centerY, 0, 'e', 12 );
2047   data << QString( "projX=%1" )    .arg( params.projX,   0, 'e', 12 );
2048   data << QString( "projY=%1" )    .arg( params.projY,   0, 'e', 12 );
2049   data << QString( "projZ=%1" )    .arg( params.projZ,   0, 'e', 12 );
2050   data << QString( "twist=%1" )    .arg( params.twist,   0, 'e', 12 );
2051   data << QString( "atX=%1" )      .arg( params.atX,     0, 'e', 12 );
2052   data << QString( "atY=%1" )      .arg( params.atY,     0, 'e', 12 );
2053   data << QString( "atZ=%1" )      .arg( params.atZ,     0, 'e', 12 );
2054   data << QString( "eyeX=%1" )     .arg( params.eyeX,    0, 'e', 12 );
2055   data << QString( "eyeY=%1" )     .arg( params.eyeY,    0, 'e', 12 );
2056   data << QString( "eyeZ=%1" )     .arg( params.eyeZ,    0, 'e', 12 );
2057   data << QString( "scaleX=%1" )   .arg( params.scaleX,  0, 'e', 12 );
2058   data << QString( "scaleY=%1" )   .arg( params.scaleY,  0, 'e', 12 );
2059   data << QString( "scaleZ=%1" )   .arg( params.scaleZ,  0, 'e', 12 );
2060   data << QString( "isVisible=%1" ).arg( params.isVisible );
2061   data << QString( "size=%1" )     .arg( params.size,    0, 'f',  2 );
2062
2063 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 or newer version
2064   // graduated trihedron
2065   data << QString( "gtIsVisible=%1" )      .arg( params.gtIsVisible );
2066   data << QString( "gtDrawNameX=%1" )      .arg( params.gtDrawNameX );
2067   data << QString( "gtDrawNameY=%1" )      .arg( params.gtDrawNameY );
2068   data << QString( "gtDrawNameZ=%1" )      .arg( params.gtDrawNameZ );
2069   data << QString( "gtNameX=%1" )          .arg( params.gtNameX );
2070   data << QString( "gtNameY=%1" )          .arg( params.gtNameY );
2071   data << QString( "gtNameZ=%1" )          .arg( params.gtNameZ );
2072   data << QString( "gtNameColorRX=%1" )    .arg( params.gtNameColorRX );
2073   data << QString( "gtNameColorGX=%1" )    .arg( params.gtNameColorGX );
2074   data << QString( "gtNameColorBX=%1" )    .arg( params.gtNameColorBX );
2075   data << QString( "gtNameColorRY=%1" )    .arg( params.gtNameColorRY );
2076   data << QString( "gtNameColorGY=%1" )    .arg( params.gtNameColorGY );
2077   data << QString( "gtNameColorBY=%1" )    .arg( params.gtNameColorBY );
2078   data << QString( "gtNameColorRZ=%1" )    .arg( params.gtNameColorRZ );
2079   data << QString( "gtNameColorGZ=%1" )    .arg( params.gtNameColorGZ );
2080   data << QString( "gtNameColorBZ=%1" )    .arg( params.gtNameColorBZ );
2081   data << QString( "gtDrawValuesX=%1" )    .arg( params.gtDrawValuesX );
2082   data << QString( "gtDrawValuesY=%1" )    .arg( params.gtDrawValuesY );
2083   data << QString( "gtDrawValuesZ=%1" )    .arg( params.gtDrawValuesZ );
2084   data << QString( "gtNbValuesX=%1" )      .arg( params.gtNbValuesX );
2085   data << QString( "gtNbValuesY=%1" )      .arg( params.gtNbValuesY );
2086   data << QString( "gtNbValuesZ=%1" )      .arg( params.gtNbValuesZ );
2087   data << QString( "gtOffsetX=%1" )        .arg( params.gtOffsetX );
2088   data << QString( "gtOffsetY=%1" )        .arg( params.gtOffsetY );
2089   data << QString( "gtOffsetZ=%1" )        .arg( params.gtOffsetZ );
2090   data << QString( "gtColorRX=%1" )        .arg( params.gtColorRX );
2091   data << QString( "gtColorGX=%1" )        .arg( params.gtColorGX );
2092   data << QString( "gtColorBX=%1" )        .arg( params.gtColorBX );
2093   data << QString( "gtColorRY=%1" )        .arg( params.gtColorRY );
2094   data << QString( "gtColorGY=%1" )        .arg( params.gtColorGY );
2095   data << QString( "gtColorBY=%1" )        .arg( params.gtColorBY );
2096   data << QString( "gtColorRZ=%1" )        .arg( params.gtColorRZ );
2097   data << QString( "gtColorGZ=%1" )        .arg( params.gtColorGZ );
2098   data << QString( "gtColorBZ=%1" )        .arg( params.gtColorBZ );
2099   data << QString( "gtDrawTickmarksX=%1" ) .arg( params.gtDrawTickmarksX );
2100   data << QString( "gtDrawTickmarksY=%1" ) .arg( params.gtDrawTickmarksY );
2101   data << QString( "gtDrawTickmarksZ=%1" ) .arg( params.gtDrawTickmarksZ );
2102   data << QString( "gtTickmarkLengthX=%1" ).arg( params.gtTickmarkLengthX );
2103   data << QString( "gtTickmarkLengthY=%1" ).arg( params.gtTickmarkLengthY );
2104   data << QString( "gtTickmarkLengthZ=%1" ).arg( params.gtTickmarkLengthZ );
2105 #endif
2106   QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" );
2107   data << QString( "background=%1" ).arg( bg );
2108
2109   return data.join("*");
2110 }
2111
2112 /*!
2113   \brief Restore visual parameters of the view window.
2114   \param parameters visual parameters of view window
2115 */
2116 void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
2117 {
2118   viewAspect params;
2119
2120   QStringList data = parameters.split( '*' );
2121   Qtx::BackgroundData bgData;
2122   if ( parameters.contains( '=' )  ) // new format - "scale=1.000e+00*centerX=0.000e+00..."
2123   {
2124     foreach( QString param, data ) {
2125       QString paramName  = param.section( '=', 0, 0 ).trimmed();
2126       QString paramValue = param.section( '=', 1, 1 ).trimmed();
2127       if      ( paramName == "scale" )             params.scale             = paramValue.toDouble();
2128       else if ( paramName == "centerX" )           params.centerX           = paramValue.toDouble();
2129       else if ( paramName == "centerY" )           params.centerY           = paramValue.toDouble();
2130       else if ( paramName == "projX" )             params.projX             = paramValue.toDouble();
2131       else if ( paramName == "projY" )             params.projY             = paramValue.toDouble();
2132       else if ( paramName == "projZ" )             params.projZ             = paramValue.toDouble();
2133       else if ( paramName == "twist" )             params.twist             = paramValue.toDouble();
2134       else if ( paramName == "atX" )               params.atX               = paramValue.toDouble();
2135       else if ( paramName == "atY" )               params.atY               = paramValue.toDouble();
2136       else if ( paramName == "atZ" )               params.atZ               = paramValue.toDouble();
2137       else if ( paramName == "eyeX" )              params.eyeX              = paramValue.toDouble();
2138       else if ( paramName == "eyeY" )              params.eyeY              = paramValue.toDouble();
2139       else if ( paramName == "eyeZ" )              params.eyeZ              = paramValue.toDouble();
2140       else if ( paramName == "scaleX" )            params.scaleX            = paramValue.toDouble();
2141       else if ( paramName == "scaleY" )            params.scaleY            = paramValue.toDouble();
2142       else if ( paramName == "scaleZ" )            params.scaleZ            = paramValue.toDouble();
2143       else if ( paramName == "isVisible" )         params.isVisible         = paramValue.toInt();
2144       else if ( paramName == "size" )              params.size              = paramValue.toDouble();
2145       // graduated trihedron
2146       else if ( paramName == "gtIsVisible" )       params.gtIsVisible       = paramValue.toInt();
2147       else if ( paramName == "gtDrawNameX" )       params.gtDrawNameX       = paramValue.toInt();
2148       else if ( paramName == "gtDrawNameY" )       params.gtDrawNameY       = paramValue.toInt();
2149       else if ( paramName == "gtDrawNameZ" )       params.gtDrawNameZ       = paramValue.toInt();
2150       else if ( paramName == "gtNameX" )           params.gtNameX           = paramValue;
2151       else if ( paramName == "gtNameY" )           params.gtNameY           = paramValue;
2152       else if ( paramName == "gtNameZ" )           params.gtNameZ           = paramValue;
2153       else if ( paramName == "gtNameColorRX" )     params.gtNameColorRX     = paramValue.toInt();
2154       else if ( paramName == "gtNameColorGX" )     params.gtNameColorGX     = paramValue.toInt();
2155       else if ( paramName == "gtNameColorBX" )     params.gtNameColorBX     = paramValue.toInt();
2156       else if ( paramName == "gtNameColorRY" )     params.gtNameColorRY     = paramValue.toInt();
2157       else if ( paramName == "gtNameColorGY" )     params.gtNameColorGY     = paramValue.toInt();
2158       else if ( paramName == "gtNameColorBY" )     params.gtNameColorBY     = paramValue.toInt();
2159       else if ( paramName == "gtNameColorRZ" )     params.gtNameColorRZ     = paramValue.toInt();
2160       else if ( paramName == "gtNameColorGZ" )     params.gtNameColorGZ     = paramValue.toInt();
2161       else if ( paramName == "gtNameColorBZ" )     params.gtNameColorBZ     = paramValue.toInt();
2162       else if ( paramName == "gtDrawValuesX" )     params.gtDrawValuesX     = paramValue.toInt();
2163       else if ( paramName == "gtDrawValuesY" )     params.gtDrawValuesY     = paramValue.toInt();
2164       else if ( paramName == "gtDrawValuesZ" )     params.gtDrawValuesZ     = paramValue.toInt();
2165       else if ( paramName == "gtNbValuesX" )       params.gtNbValuesX       = paramValue.toInt();
2166       else if ( paramName == "gtNbValuesY" )       params.gtNbValuesY       = paramValue.toInt();
2167       else if ( paramName == "gtNbValuesZ" )       params.gtNbValuesZ       = paramValue.toInt();
2168       else if ( paramName == "gtOffsetX" )         params.gtOffsetX         = paramValue.toInt();
2169       else if ( paramName == "gtOffsetY" )         params.gtOffsetY         = paramValue.toInt();
2170       else if ( paramName == "gtOffsetZ" )         params.gtOffsetZ         = paramValue.toInt();
2171       else if ( paramName == "gtColorRX" )         params.gtColorRX         = paramValue.toInt();
2172       else if ( paramName == "gtColorGX" )         params.gtColorGX         = paramValue.toInt();
2173       else if ( paramName == "gtColorBX" )         params.gtColorBX         = paramValue.toInt();
2174       else if ( paramName == "gtColorRY" )         params.gtColorRY         = paramValue.toInt();
2175       else if ( paramName == "gtColorGY" )         params.gtColorGY         = paramValue.toInt();
2176       else if ( paramName == "gtColorBY" )         params.gtColorBY         = paramValue.toInt();
2177       else if ( paramName == "gtColorRZ" )         params.gtColorRZ         = paramValue.toInt();
2178       else if ( paramName == "gtColorGZ" )         params.gtColorGZ         = paramValue.toInt();
2179       else if ( paramName == "gtColorBZ" )         params.gtColorBZ         = paramValue.toInt();
2180       else if ( paramName == "gtDrawTickmarksX" )  params.gtDrawTickmarksX  = paramValue.toInt();
2181       else if ( paramName == "gtDrawTickmarksY" )  params.gtDrawTickmarksY  = paramValue.toInt();
2182       else if ( paramName == "gtDrawTickmarksZ" )  params.gtDrawTickmarksZ  = paramValue.toInt();
2183       else if ( paramName == "gtTickmarkLengthX" ) params.gtTickmarkLengthX = paramValue.toInt();
2184       else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt();
2185       else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt();
2186       else if ( paramName == "background" )        {
2187         QString bg = paramValue.replace( "$", "=" );
2188         bgData = Qtx::stringToBackground( bg );
2189       }
2190     }
2191   }
2192   else // old format - "1.000e+00*0.000e+00..."
2193   {
2194     int idx = 0;
2195     params.scale     = data.count() > idx ? data[idx++].toDouble() : 1.0;
2196     params.centerX   = data.count() > idx ? data[idx++].toDouble() : 0.0;
2197     params.centerY   = data.count() > idx ? data[idx++].toDouble() : 0.0;
2198     params.projX     = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3);
2199     params.projY     = data.count() > idx ? data[idx++].toDouble() : -sqrt(1./3);
2200     params.projZ     = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3);
2201     params.twist     = data.count() > idx ? data[idx++].toDouble() : 0.0;
2202     params.atX       = data.count() > idx ? data[idx++].toDouble() : 0.0;
2203     params.atY       = data.count() > idx ? data[idx++].toDouble() : 0.0;
2204     params.atZ       = data.count() > idx ? data[idx++].toDouble() : 0.0;
2205     params.eyeX      = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3);
2206     params.eyeY      = data.count() > idx ? data[idx++].toDouble() : -sqrt(250000./3);
2207     params.eyeZ      = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3);
2208     params.scaleX    = data.count() > idx ? data[idx++].toDouble() : 1.0;
2209     params.scaleY    = data.count() > idx ? data[idx++].toDouble() : 1.0;
2210     params.scaleZ    = data.count() > idx ? data[idx++].toDouble() : 1.0;
2211     params.isVisible = data.count() > idx ? data[idx++].toInt()    : 1;
2212     params.size      = data.count() > idx ? data[idx++].toDouble() : 100.0;
2213   }
2214   performRestoring( params );
2215   setBackground( bgData );
2216 }
2217
2218 /*!
2219   \brief Handle show event.
2220
2221   Emits Show() signal.
2222
2223   \param theEvent show event
2224 */
2225 void OCCViewer_ViewWindow::showEvent( QShowEvent* theEvent )
2226 {
2227   emit Show( theEvent );
2228 }
2229
2230 /*!
2231   \brief Handle hide event.
2232
2233   Emits Hide() signal.
2234
2235   \param theEvent hide event
2236 */
2237 void OCCViewer_ViewWindow::hideEvent( QHideEvent* theEvent )
2238 {
2239   emit Hide( theEvent );
2240 }
2241
2242
2243 /*!
2244     Creates default sketcher. [ virtual protected ]
2245 */
2246 OCCViewer_ViewSketcher* OCCViewer_ViewWindow::createSketcher( int type )
2247 {
2248   if ( type == Rect )
2249     return new OCCViewer_RectSketcher( this, type );
2250   if ( type == Polygon )
2251     return new OCCViewer_PolygonSketcher( this, type );
2252   return 0;
2253 }
2254
2255 void OCCViewer_ViewWindow::initSketchers()
2256 {
2257   if ( mySketchers.isEmpty() )
2258   {
2259     mySketchers.append( createSketcher( Rect ) );
2260     mySketchers.append( createSketcher( Polygon ) );
2261   }
2262 }
2263
2264 OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ )
2265 {
2266   OCCViewer_ViewSketcher* sketcher = 0;
2267   QList<OCCViewer_ViewSketcher*>::Iterator it;
2268   for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
2269   {
2270     OCCViewer_ViewSketcher* sk = (*it);
2271     if ( sk->type() == typ )
2272       sketcher = sk;
2273   }
2274   return sketcher;
2275 }
2276
2277 /*!
2278     Handles requests for sketching in the active view. [ virtual public ]
2279 */
2280 void OCCViewer_ViewWindow::activateSketching( int type )
2281 {
2282   OCCViewer_ViewPort3d* vp = getViewPort();
2283   if ( !vp )
2284     return;
2285
2286   if ( !vp->isSketchingEnabled() )
2287     return;
2288
2289   /* Finish current sketching */
2290   if ( type == NoSketching )
2291   {
2292     if ( mypSketcher )
2293     {
2294       onSketchingFinished();
2295       mypSketcher->deactivate();
2296       mypSketcher = 0;
2297     }
2298   }
2299   /* Activate new sketching */
2300   else
2301   {
2302     activateSketching( NoSketching );  /* concurrency not suported */
2303     mypSketcher = getSketcher( type );
2304     if ( mypSketcher )
2305     {
2306       mypSketcher->activate();
2307       onSketchingStarted();
2308     }
2309   }
2310 }
2311
2312 /*!
2313     Unhilights detected entities. [ virtual protected ]
2314 */
2315 void OCCViewer_ViewWindow::onSketchingStarted()
2316 {
2317 }
2318
2319 /*!
2320     Selection by rectangle or polygon. [ virtual protected ]
2321 */
2322 void OCCViewer_ViewWindow::onSketchingFinished()
2323 {
2324   MESSAGE("OCCViewer_ViewWindow::onSketchingFinished()")
2325   if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept )
2326   {
2327     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
2328     bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() );
2329     switch( mypSketcher->type() )
2330     {
2331     case Rect:
2332       {
2333         QRect* aRect = (QRect*)mypSketcher->data();
2334         if( aRect )
2335         {
2336           int aLeft = aRect->left();
2337           int aRight = aRect->right();
2338           int aTop = aRect->top();
2339           int aBottom = aRect->bottom();
2340 //           myRect = aRect;
2341
2342           if( append )
2343             ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
2344           else
2345             ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
2346         }
2347       }
2348       break;
2349     case Polygon:
2350       {
2351         QPolygon* aPolygon = (QPolygon*)mypSketcher->data();
2352         if( aPolygon )
2353         {
2354           int size = aPolygon->size();
2355           TColgp_Array1OfPnt2d anArray( 1, size );
2356
2357           QPolygon::Iterator it = aPolygon->begin();
2358           QPolygon::Iterator itEnd = aPolygon->end();
2359           for( int index = 1; it != itEnd; ++it, index++ )
2360           {
2361             QPoint aPoint = *it;
2362             anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) );
2363           }
2364
2365           if( append )
2366             ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False );
2367           else
2368             ic->Select( anArray, getViewPort()->getView(), Standard_False );
2369         }
2370       }
2371       break;
2372     default:
2373       break;
2374     }
2375
2376     OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager();
2377     aViewMgr->getOCCViewer()->performSelectionChanged();
2378   }
2379 }
2380
2381 OCCViewer_ViewPort3d* OCCViewer_ViewWindow::getViewPort()
2382 {
2383   return myViewPort;
2384 }
2385
2386 bool OCCViewer_ViewWindow::transformRequested() const
2387 {
2388   return ( myOperation != NOTHING );
2389 }
2390
2391 bool OCCViewer_ViewWindow::transformInProcess() const
2392 {
2393   return myEventStarted;
2394 }
2395
2396 void OCCViewer_ViewWindow::setTransformInProcess( bool bOn )
2397 {
2398   myEventStarted = bOn;
2399 }
2400
2401 /*!
2402   Set enabled state of transformation (rotate, zoom, etc)
2403 */
2404 void OCCViewer_ViewWindow::setTransformEnabled( const OperationType id, const bool on )
2405 {
2406   if ( id != NOTHING ) myStatus.insert( id, on );
2407 }
2408
2409 /*!
2410   \return enabled state of transformation (rotate, zoom, etc)
2411 */
2412 bool OCCViewer_ViewWindow::transformEnabled( const OperationType id ) const
2413 {
2414   return myStatus.contains( id ) ? myStatus[ id ] : true;
2415 }
2416
2417 void OCCViewer_ViewWindow::onMaximizedView()
2418 {
2419   setMaximized(!isMaximized());
2420 }
2421
2422
2423 void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal)
2424 {
2425   QAction* anAction =  toolMgr()->action( MaximizedId );
2426   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
2427   if ( toMaximize ) {
2428     anAction->setText( tr( "MNU_MINIMIZE_VIEW" ) );  
2429     anAction->setToolTip( tr( "MNU_MINIMIZE_VIEW" ) );  
2430     anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ) );
2431     anAction->setStatusTip( tr( "DSC_MINIMIZE_VIEW" ) );
2432     if (toSendSignal) {
2433       emit maximized( this, true );
2434     }
2435   }
2436   else {
2437     anAction->setText( tr( "MNU_MAXIMIZE_VIEW" ) );  
2438     anAction->setToolTip( tr( "MNU_MAXIMIZE_VIEW" ) );  
2439     anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MAXIMIZE" ) ) );
2440     anAction->setStatusTip( tr( "DSC_MAXIMIZE_VIEW" ) );
2441     if (toSendSignal) {
2442       emit maximized( this, false );
2443     }
2444   }
2445 }
2446
2447
2448 bool OCCViewer_ViewWindow::isMaximized() const
2449 {
2450   return !(toolMgr()->action( MaximizedId )->text() == tr( "MNU_MAXIMIZE_VIEW" ));
2451 }
2452
2453 void OCCViewer_ViewWindow::setSketcherStyle( bool enable )
2454
2455   IsSketcherStyle = enable; 
2456 }
2457
2458 bool OCCViewer_ViewWindow::isSketcherStyle() const 
2459
2460   return IsSketcherStyle; 
2461 }
2462
2463
2464 void OCCViewer_ViewWindow::set2dMode(Mode2dType theType)
2465 {
2466   my2dMode = theType;
2467 }
2468
2469 // obsolete   
2470 QColor OCCViewer_ViewWindow::backgroundColor() const
2471 {
2472   return myViewPort ? myViewPort->backgroundColor() : Qt::black;
2473 }
2474    
2475 // obsolete
2476 void OCCViewer_ViewWindow::setBackgroundColor( const QColor& theColor )
2477 {
2478   if ( myViewPort ) myViewPort->setBackgroundColor( theColor );
2479 }
2480
2481 Qtx::BackgroundData OCCViewer_ViewWindow::background() const
2482 {
2483   return myViewPort ? myViewPort->background() : Qtx::BackgroundData();
2484 }
2485    
2486 void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackground )
2487 {
2488   if ( myViewPort ) myViewPort->setBackground( theBackground );
2489 }
2490
2491 /*!
2492   Clears view aspects
2493 */
2494 void OCCViewer_ViewWindow::clearViewAspects()
2495 {
2496   myViewAspects.clear();
2497 }
2498
2499 /*!
2500   \return const reference to list of view aspects
2501 */
2502 const viewAspectList& OCCViewer_ViewWindow::getViewAspects()
2503 {
2504   return myViewAspects;
2505 }
2506
2507 /*!
2508   Appends new view aspect
2509   \param aParams - new view aspects
2510 */
2511 void OCCViewer_ViewWindow::appendViewAspect( const viewAspect& aParams )
2512 {
2513   myViewAspects.append( aParams );
2514 }
2515
2516 /*!
2517   Replaces old view aspects by new ones
2518   \param aViewList - list of new view aspects
2519 */
2520 void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList )
2521 {
2522   myViewAspects = aViewList;
2523 }
2524
2525 /*!
2526   Get camera properties for the OCC view window.
2527   \return shared pointer on camera properties.
2528 */
2529 SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
2530 {
2531   SUIT_CameraProperties aProps;
2532
2533   Handle(V3d_View) aSourceView = getViewPort()->getView();
2534   if ( aSourceView.IsNull() )
2535     return aProps;
2536
2537   if ( get2dMode() == No2dMode ) {
2538     aProps.setDimension( SUIT_CameraProperties::Dim3D );
2539   }
2540   else {
2541     aProps.setDimension( SUIT_CameraProperties::Dim2D );
2542     aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() );
2543   }
2544   
2545   // read common properites of the view
2546   Standard_Real anUpDir[3];
2547   Standard_Real aPrjDir[3];
2548   Standard_Real aMapScale[2];
2549   Standard_Real aTranslation[3];
2550   Standard_Real anAxialScale[3];
2551   
2552   aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]);
2553   aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]);
2554   aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
2555   aSourceView->Size(aMapScale[0], aMapScale[1]);
2556
2557   getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2558
2559   // we use similar depth to the one used in perspective projection 
2560   // to proivde a convinience synchronization with other camera views that
2561   // can switch between orthogonal & perspective projection. otherwise,
2562   // the camera will get to close when switching from orthogonal to perspective.
2563   Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5;
2564
2565   // store common props
2566   aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
2567   aProps.setMappingScale(aMapScale[1] / 2.0);
2568   aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2569   
2570   // generate view orientation matrix for transforming OCC projection reference point
2571   // into a camera (eye) position.
2572   gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
2573     gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2]));
2574
2575   gp_Trsf aTrsf;
2576   aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0],
2577                    aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1],
2578                    aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2],
2579                    Precision::Confusion(),
2580                    Precision::Confusion() );
2581
2582   // get projection reference point in view coordinates
2583   Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint();
2584   
2585   // transform to world-space coordinate system
2586   gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf);
2587   
2588   // compute focal point
2589   double aFocalPoint[3];
2590
2591   aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth;
2592   aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth;
2593   aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth;
2594
2595   aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
2596   aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z());
2597
2598   return aProps;
2599 }
2600
2601 /*!
2602   Synchronize views.
2603   This implementation synchronizes OCC view's camera propreties.
2604 */
2605 void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
2606 {
2607   bool blocked = blockSignals( true );
2608
2609   SUIT_CameraProperties aProps = theView->cameraProperties();
2610   if ( !cameraProperties().isCompatible( aProps ) ) {
2611     // other view, this one is being currently synchronized to, seems has become incompatible
2612     // we have to break synchronization
2613     updateSyncViews();
2614     return;
2615   }
2616
2617   Handle(V3d_View) aDestView = getViewPort()->getView();
2618
2619   aDestView->SetImmediateUpdate( Standard_False );
2620
2621   double anUpDir[3];
2622   double aPosition[3];
2623   double aFocalPoint[3];
2624   double aMapScaling;
2625   double anAxialScale[3];
2626
2627   // get common properties
2628   aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
2629   aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]);
2630   aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
2631   aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2632   aMapScaling = aProps.getMappingScale() * 2.0;
2633
2634   gp_Dir aProjDir(aPosition[0] - aFocalPoint[0],
2635                   aPosition[1] - aFocalPoint[1],
2636                   aPosition[2] - aFocalPoint[2]);
2637   
2638   // get custom view translation
2639   Standard_Real aTranslation[3];
2640   aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
2641
2642   gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
2643     gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z()));
2644
2645   // convert camera position into a view reference point
2646   gp_Trsf aTrsf;
2647   aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0],
2648                    aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1],
2649                    aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], 
2650                    Precision::Confusion(),
2651                    Precision::Confusion() );
2652   aTrsf.Invert();
2653
2654   // transform to view-space coordinate system
2655   gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]);
2656   aProjRef.Transform(aTrsf);
2657
2658   // set view camera properties using low-level approach. this is done
2659   // in order to avoid interference with static variables in v3d view used
2660   // when rotation is in process in another view.
2661   Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping();
2662   Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation();
2663
2664   Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z());
2665   Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]);
2666
2667   aMappingProj.Normalize();
2668   aMappingUp.Normalize();
2669
2670   anOrientation.SetViewReferencePlane(aMappingProj);
2671   anOrientation.SetViewReferenceUp(aMappingUp);
2672
2673   aDestView->SetViewMapping(aMapping);
2674   aDestView->SetViewOrientation(anOrientation);
2675
2676   // set panning
2677   aDestView->SetCenter(aProjRef.X(), aProjRef.Y());
2678
2679   // set mapping scale
2680   Standard_Real aWidth, aHeight;
2681   aDestView->Size(aWidth, aHeight);
2682   
2683   if ( aWidth > aHeight )
2684     aDestView->SetSize (aMapScaling * (aWidth / aHeight));
2685   else
2686     aDestView->SetSize (aMapScaling);
2687
2688   getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2689
2690   aDestView->ZFitAll();
2691   aDestView->SetImmediateUpdate( Standard_True );
2692   aDestView->Redraw();
2693
2694   blockSignals( blocked );
2695 }