Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewWindow.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // OCCViewer_ViewWindow.cxx: implementation of the OCCViewer_ViewWindow class.
20
21
22 #include "OCCViewer_ViewWindow.h"
23 #include "OCCViewer_ViewModel.h"
24 #include "OCCViewer_ViewPort3d.h"
25 #include "OCCViewer_ViewManager.h"
26 #include "OCCViewer_ViewSketcher.h"
27 #include "OCCViewer_CreateRestoreViewDlg.h"
28 #include "OCCViewer_ClippingDlg.h"
29 #include "OCCViewer_SetRotationPointDlg.h"
30
31 #include "SUIT_Desktop.h"
32 #include "SUIT_Session.h"
33 #include "SUIT_ToolButton.h"
34
35 #include "SUIT_Tools.h"
36 #include "SUIT_ResourceMgr.h"
37 #include "SUIT_MessageBox.h"
38
39 #include <qptrlist.h>
40 #include <qhbox.h>
41 #include <qlabel.h>
42 #include <qcolor.h>
43 #include <qpainter.h>
44 #include <qapplication.h>
45 #include <qdatetime.h>
46 #include <qimage.h>
47
48 #include <V3d_Plane.hxx>
49 #include <gp_Dir.hxx>
50 #include <gp_Pln.hxx>
51 #include <TColgp_Array1OfPnt2d.hxx>
52
53 #include <AIS_ListIteratorOfListOfInteractive.hxx>
54 #include <AIS_Shape.hxx>
55
56 #include <BRep_Tool.hxx>
57 #include <TopoDS.hxx>
58
59 #include <BRepBndLib.hxx>
60 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
61 #include <Visual3d_View.hxx>
62 #include <Graphic3d_MapOfStructure.hxx>
63 #include <Graphic3d_Structure.hxx>
64
65 static QEvent* l_mbPressEvent = 0;
66
67 const char* imageZoomCursor[] = { 
68 "32 32 3 1",
69 ". c None",
70 "a c #000000",
71 "# c #ffffff",
72 "................................",
73 "................................",
74 ".#######........................",
75 "..aaaaaaa.......................",
76 "................................",
77 ".............#####..............",
78 "...........##.aaaa##............",
79 "..........#.aa.....a#...........",
80 ".........#.a.........#..........",
81 ".........#a..........#a.........",
82 "........#.a...........#.........",
83 "........#a............#a........",
84 "........#a............#a........",
85 "........#a............#a........",
86 "........#a............#a........",
87 ".........#...........#.a........",
88 ".........#a..........#a.........",
89 ".........##.........#.a.........",
90 "........#####.....##.a..........",
91 ".......###aaa#####.aa...........",
92 "......###aa...aaaaa.......#.....",
93 ".....###aa................#a....",
94 "....###aa.................#a....",
95 "...###aa...............#######..",
96 "....#aa.................aa#aaaa.",
97 ".....a....................#a....",
98 "..........................#a....",
99 "...........................a....",
100 "................................",
101 "................................",
102 "................................",
103 "................................"};
104
105 const char* imageRotateCursor[] = { 
106 "32 32 3 1",
107 ". c None",
108 "a c #000000",
109 "# c #ffffff",
110 "................................",
111 "................................",
112 "................................",
113 "................................",
114 "........#.......................",
115 ".......#.a......................",
116 "......#######...................",
117 ".......#aaaaa#####..............",
118 "........#..##.a#aa##........##..",
119 ".........a#.aa..#..a#.....##.aa.",
120 ".........#.a.....#...#..##.aa...",
121 ".........#a.......#..###.aa.....",
122 "........#.a.......#a..#aa.......",
123 "........#a.........#..#a........",
124 "........#a.........#a.#a........",
125 "........#a.........#a.#a........",
126 "........#a.........#a.#a........",
127 ".........#.........#a#.a........",
128 "........##a........#a#a.........",
129 "......##.a#.......#.#.a.........",
130 "....##.aa..##.....##.a..........",
131 "..##.aa.....a#####.aa...........",
132 "...aa.........aaa#a.............",
133 "................#.a.............",
134 "...............#.a..............",
135 "..............#.a...............",
136 "...............a................",
137 "................................",
138 "................................",
139 "................................",
140 "................................",
141 "................................"};
142
143 const char* imageCrossCursor[] = { 
144   "32 32 3 1",
145   ". c None",
146   "a c #000000",
147   "# c #ffffff",
148   "................................",
149   "................................",
150   "................................",
151   "................................",
152   "................................",
153   "................................",
154   "................................",
155   "...............#................",
156   "...............#a...............",
157   "...............#a...............",
158   "...............#a...............",
159   "...............#a...............",
160   "...............#a...............",
161   "...............#a...............",
162   "...............#a...............",
163   ".......#################........",
164   "........aaaaaaa#aaaaaaaaa.......",
165   "...............#a...............",
166   "...............#a...............",
167   "...............#a...............",
168   "...............#a...............",
169   "...............#a...............",
170   "...............#a...............",
171   "...............#a...............",
172   "................a...............",
173   "................................",
174   "................................",
175   "................................",
176   "................................",
177   "................................",
178   "................................",
179   "................................"};
180
181
182 /*!
183   Constructor
184   \param theDesktop - main window of application
185   \param theModel - OCC 3D viewer
186 */
187 OCCViewer_ViewWindow::OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel)
188 : SUIT_ViewWindow(theDesktop)
189 {
190   myModel = theModel;
191   myRestoreFlag = 0;
192   myEnableDrawMode = false;
193   updateEnabledDrawMode();
194   myClippingDlg = 0;
195   mySetRotationPointDlg = 0;
196
197   mypSketcher = 0;
198   myCurSketch = -1;
199 }
200
201 /*!
202   Initialization of view window
203 */
204 void OCCViewer_ViewWindow::initLayout()
205 {
206   myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC );
207   myViewPort->setBackgroundColor(black);
208   myViewPort->installEventFilter(this);
209   setCentralWidget(myViewPort);
210   myOperation = NOTHING;
211
212   myCurrPointType = GRAVITY;
213   myPrevPointType = GRAVITY;
214   mySelectedPoint = gp_Pnt(0.,0.,0.);
215   myRotationPointSelection = false;
216
217   setTransformRequested ( NOTHING );
218   setTransformInProcess ( false );
219
220   myToolBar = new QToolBar(this);
221   myToolBar->setCloseMode(QDockWindow::Undocked);
222   myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
223
224   createActions();
225   createToolBar();
226 }
227
228 /*!
229   \return type of operation by states of mouse and keyboard buttons
230   \param theEvent - mouse event
231 */
232 OCCViewer_ViewWindow::OperationType OCCViewer_ViewWindow::getButtonState(QMouseEvent* theEvent)
233 {
234   OperationType aOp = NOTHING;
235   if( (theEvent->state() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::ZOOM]) &&
236       (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::ZOOM]) )
237     aOp = ZOOMVIEW;
238   else if( (theEvent->state() == SUIT_ViewModel::myStateMap[SUIT_ViewModel::PAN]) && 
239            (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::PAN]) )
240     aOp = PANVIEW;
241   else if( (theEvent->state()  == SUIT_ViewModel::myStateMap[SUIT_ViewModel::ROTATE]) &&
242            (theEvent->button() == SUIT_ViewModel::myButtonMap[SUIT_ViewModel::ROTATE]) )
243     aOp = ROTATE;
244
245   return aOp;
246 }
247
248 /*!
249   Custom event handler
250 */
251 bool OCCViewer_ViewWindow::eventFilter(QObject* watched, QEvent* e)
252 {
253   if ( watched == myViewPort ) {
254     int aType = e->type();
255     switch(aType) {
256     case QEvent::MouseButtonPress:
257       vpMousePressEvent((QMouseEvent*) e);
258       return true;
259
260     case QEvent::MouseButtonRelease:
261       vpMouseReleaseEvent((QMouseEvent*) e);
262       return true;
263
264     case QEvent::MouseMove:
265       vpMouseMoveEvent((QMouseEvent*) e);
266       return true;
267
268     case QEvent::MouseButtonDblClick:
269       emit mouseDoubleClicked(this, (QMouseEvent*)e);
270       return true;
271
272     case QEvent::Wheel:
273       {
274         QWheelEvent* aEvent = (QWheelEvent*) e;
275         double aDelta = aEvent->delta();
276         double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.; 
277         myViewPort->getView()->SetZoom(aScale);
278       }
279       return true;
280
281     case QEvent::ContextMenu:
282       {
283         QContextMenuEvent * aEvent = (QContextMenuEvent*)e;
284         if ( aEvent->reason() != QContextMenuEvent::Mouse )
285           emit contextMenuRequested( aEvent );
286       }
287       return true;
288
289     default:
290       break;
291     }
292   }
293   return SUIT_ViewWindow::eventFilter(watched, e);
294 }
295
296 /*!
297   Updates state of enable draw mode state
298 */
299 void OCCViewer_ViewWindow::updateEnabledDrawMode()
300 {
301   if ( myModel )
302     myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled();
303 }
304
305 /*!
306   Handler of mouse press event
307 */
308 void OCCViewer_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent)
309 {
310   myStartX = theEvent->x();
311   myStartY = theEvent->y();
312   switch ( myOperation ) {
313   case WINDOWFIT:
314     if ( theEvent->button() == Qt::LeftButton )
315       emit vpTransformationStarted ( WINDOWFIT );
316     break;    
317    
318   case PANGLOBAL:
319     if ( theEvent->button() == Qt::LeftButton )
320       emit vpTransformationStarted ( PANGLOBAL );
321     break;    
322     
323   case ZOOMVIEW:
324     if ( theEvent->button() == Qt::LeftButton )
325       emit vpTransformationStarted ( ZOOMVIEW );
326     break;
327     
328   case PANVIEW:
329     if ( theEvent->button() == Qt::LeftButton )
330       emit vpTransformationStarted ( PANVIEW );
331     break;
332
333   case ROTATE:
334     if ( theEvent->button() == Qt::LeftButton ) {
335             myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
336             emit vpTransformationStarted ( ROTATE );
337           }
338     break;
339       
340   default:
341   /*  Try to activate a transformation */
342     switch ( getButtonState(theEvent) ) {
343     case ZOOMVIEW:
344             activateZoom();
345       break;
346     case PANVIEW:
347             activatePanning();
348       break;
349     case ROTATE:
350             activateRotation();
351             myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
352       break;
353     default:
354       if ( myRotationPointSelection )
355       {
356         if ( theEvent->button() == Qt::LeftButton )
357         {
358           Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
359           ic->Select();
360           for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() )
361           {
362             TopoDS_Shape aShape = ic->SelectedShape();
363             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
364             {
365               gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) ); 
366               if ( mySetRotationPointDlg )
367               {
368                 myRotationPointSelection = false;
369                 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
370               }
371             }    
372             else 
373             {
374               myCurrPointType = myPrevPointType;
375               break;
376             }
377           }
378           if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType;
379           if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
380           ic->CloseAllContexts();
381           myOperation = NOTHING; 
382           setCursor( myCursor );
383           myCursorIsHand = false;
384           myRotationPointSelection = false;
385         }
386       }
387       else
388         emit mousePressed(this, theEvent);
389       break;
390     }
391     /* notify that we start a transformation */
392     if ( transformRequested() ) 
393             emit vpTransformationStarted ( myOperation );
394   }
395   if ( transformRequested() ) 
396     setTransformInProcess( true );               
397
398   /* we may need it for sketching... */
399   if ( l_mbPressEvent )
400     delete l_mbPressEvent;
401   l_mbPressEvent = new QMouseEvent( *theEvent );
402 }
403
404
405 /*!
406   Starts zoom operation, sets corresponding cursor
407 */
408 void OCCViewer_ViewWindow::activateZoom()
409 {
410   if ( !transformRequested() && !myCursorIsHand )
411     myCursor = cursor();                /* save old cursor */
412   
413   if ( myOperation != ZOOMVIEW ) {
414     QPixmap zoomPixmap (imageZoomCursor);
415     QCursor zoomCursor (zoomPixmap);
416     setTransformRequested ( ZOOMVIEW );         
417     setCursor( zoomCursor );
418   }
419 }
420
421
422 /*!
423   Starts panning operation, sets corresponding cursor
424 */
425 void OCCViewer_ViewWindow::activatePanning()
426 {
427   if ( !transformRequested() && !myCursorIsHand )
428     myCursor = cursor();                // save old cursor 
429   
430   if ( myOperation != PANVIEW ) {
431     QCursor panCursor (Qt::SizeAllCursor);
432     setTransformRequested ( PANVIEW );
433     setCursor( panCursor );
434   }
435 }
436
437 /*!
438   Starts rotation operation, sets corresponding cursor
439 */
440 void OCCViewer_ViewWindow::activateRotation()
441 {
442   if ( !transformRequested() && !myCursorIsHand )
443     myCursor = cursor();                // save old cursor 
444   
445   if ( myOperation != ROTATE ) {
446     QPixmap rotatePixmap (imageRotateCursor);
447     QCursor rotCursor (rotatePixmap);
448     setTransformRequested ( ROTATE );
449     setCursor( rotCursor );     
450   }
451 }
452
453 /*!
454   Compute the gravity center
455 */
456 bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ )
457 {
458   Handle(Visual3d_View) aView = myViewPort->getView()->View();
459
460   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ;
461   Standard_Real Umin,Vmin,Umax,Vmax ;
462   Standard_Integer Nstruct,Npoint ;
463   Graphic3d_MapOfStructure MySetOfStructures;
464   
465   aView->DisplayedStructures (MySetOfStructures);
466   Nstruct = MySetOfStructures.Extent() ;
467   
468   Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
469   aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax) ;
470   Npoint = 0 ; theX = theY = theZ = 0. ;
471   for( ; MyIterator.More(); MyIterator.Next()) {
472     if (!(MyIterator.Key())->IsEmpty()) {
473       (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin,
474                                          Xmax,Ymax,Zmax) ;
475     
476       Standard_Real LIM = ShortRealLast() -1.;
477       if (!    (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM 
478                 ||  fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) {
479         
480         aView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
481         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
482           Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ;
483         }
484         aView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
485         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
486           Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ;
487         }
488         aView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
489         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
490           Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ;
491         }
492         aView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
493         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
494           Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ;
495         }
496         aView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
497         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
498           Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ;
499         }
500         aView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
501         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
502           Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ;
503         }
504         aView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
505         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
506           Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ;
507         }
508         aView->Projects(Xmax,Ymax,Zmax,U,V,W) ;
509         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
510           Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ;
511         }
512       }
513     }
514   }
515   if( Npoint > 0 ) {
516     theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ;
517   }
518   return true;
519 }
520
521 /*!
522   Set the gravity center as a rotation point
523 */
524 void OCCViewer_ViewWindow::activateSetRotationGravity()
525 {
526   if ( myRotationPointSelection )
527   {
528     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
529     ic->CloseAllContexts();
530     myOperation = NOTHING; 
531     setCursor( myCursor );
532     myCursorIsHand = false;
533     myRotationPointSelection = false;
534   }
535
536   myPrevPointType = myCurrPointType;
537   myCurrPointType = GRAVITY;
538
539   Standard_Real Xcenter, Ycenter, Zcenter;
540   if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
541     mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
542 }
543
544 /*!
545   Update gravity center in the SetRotationPointDlg
546 */
547 void OCCViewer_ViewWindow::updateGravityCoords()
548 {
549   if ( mySetRotationPointDlg && mySetRotationPointDlg->isShown() && myCurrPointType == GRAVITY )
550   {
551     Standard_Real Xcenter, Ycenter, Zcenter;
552     if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
553       mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
554   }
555 }
556
557 /*!
558   Set the point selected by user as a rotation point
559 */
560 void OCCViewer_ViewWindow::activateSetRotationSelected(double theX, double theY, double theZ)
561 {
562   if ( myRotationPointSelection )
563   {
564     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
565     ic->CloseAllContexts();
566     myOperation = NOTHING; 
567     setCursor( myCursor );
568     myCursorIsHand = false;
569     myRotationPointSelection = false;
570   }
571
572   myPrevPointType = myCurrPointType;
573   myCurrPointType = SELECTED;
574   mySelectedPoint.SetCoord(theX,theY,theZ);
575 }
576
577 /*!
578   Start the point selection process
579 */
580 void OCCViewer_ViewWindow::activateStartPointSelection()
581 {
582   myPrevPointType = myCurrPointType;
583   myCurrPointType = SELECTED;
584
585   // activate selection ------>
586   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
587
588   ic->OpenLocalContext();
589
590   AIS_ListOfInteractive aList;
591   ic->DisplayedObjects( aList );
592   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) 
593   {
594     Handle(AIS_InteractiveObject) anObj = it.Value();
595     if ( !anObj.IsNull() && anObj->HasPresentation() &&
596          anObj->IsKind( STANDARD_TYPE(AIS_Shape) ) )
597     {
598       ic->Load(anObj,-1);
599       ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX));
600      }
601   }  
602   // activate selection <------
603
604   if ( !myCursorIsHand )
605   {
606     QCursor handCursor (Qt::PointingHandCursor);
607     myCursorIsHand = true;              
608     myCursor = cursor();
609     setCursor( handCursor );
610   }
611   myRotationPointSelection = true;
612 }
613
614 /*!
615   Starts global panning operation, sets corresponding cursor
616 */
617 void OCCViewer_ViewWindow::activateGlobalPanning()
618 {
619   Handle(V3d_View) aView3d = myViewPort->getView();
620   if ( !aView3d.IsNull() ) {
621     QPixmap globalPanPixmap (imageCrossCursor);
622     QCursor glPanCursor (globalPanPixmap);
623     myCurScale = aView3d->Scale();
624     aView3d->FitAll(0.01, false);
625     myCursor = cursor();                // save old cursor 
626     myViewPort->fitAll(); // fits view before selecting a new scene center 
627     setTransformRequested( PANGLOBAL );
628     setCursor( glPanCursor );
629   }
630 }
631
632 /*!
633   Starts fit operation, sets corresponding cursor
634 */
635 void OCCViewer_ViewWindow::activateWindowFit()
636 {
637   if ( !transformRequested() && !myCursorIsHand )
638     myCursor = cursor();                /* save old cursor */
639
640   if ( myOperation != WINDOWFIT ) {
641     QCursor handCursor (Qt::PointingHandCursor);
642     setTransformRequested ( WINDOWFIT );                
643     setCursor ( handCursor );
644     myCursorIsHand = true;
645   }
646 }
647
648 /*!
649   Stores which viewer operation is requesting
650 */
651 void OCCViewer_ViewWindow::setTransformRequested ( OperationType op )
652 {    
653   myOperation = op;
654   myViewPort->setMouseTracking( myOperation == NOTHING );
655 }
656
657
658 /*!
659   Handler of mouse move event
660 */
661 void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent)
662 {
663   myCurrX = theEvent->x();
664   myCurrY = theEvent->y();
665   switch (myOperation) {
666   case ROTATE:
667     myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
668     break;
669     
670   case ZOOMVIEW:
671     myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
672     myStartX = myCurrX;
673     myStartY = myCurrY;
674     break;
675     
676   case PANVIEW:
677     myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
678     myStartX = myCurrX;
679     myStartY = myCurrY;
680     break;
681     
682 /*    case WINDOWFIT:
683     myDrawRect = true;
684     repaint();
685     break;
686 */      
687   case PANGLOBAL:
688     break;
689     
690   default:
691     if ( myRotationPointSelection )
692       emit mouseMoving( this, theEvent ); 
693     else
694     {
695       int aState = theEvent->state();
696       if ( aState == Qt::LeftButton ||
697            aState == ( Qt::LeftButton | Qt::ShiftButton) ) {
698         myDrawRect = myEnableDrawMode;
699         if ( myDrawRect ) {
700           drawRect();
701           if ( !myCursorIsHand )        {   // we are going to sketch a rectangle
702             QCursor handCursor (Qt::PointingHandCursor);
703             myCursorIsHand = true;              
704             myCursor = cursor();
705             setCursor( handCursor );
706           }
707         }
708       } 
709       else if ( aState == Qt::RightButton || 
710                 aState == ( Qt::RightButton | Qt::ShiftButton ) ) {
711         OCCViewer_ViewSketcher* sketcher = 0;
712         for ( OCCViewer_ViewSketcher* sk = mySketchers.first();
713               sk && !sketcher; sk = mySketchers.next() )
714         {
715           if( sk->isDefault() && sk->sketchButton() & ( aState & Qt::MouseButtonMask ) )
716             sketcher = sk;
717         }
718         if ( sketcher && myCurSketch == -1 )
719         {
720           activateSketching( sketcher->type() );
721           if ( mypSketcher )
722           {
723             myCurSketch = mypSketcher->sketchButton();
724
725             if ( l_mbPressEvent )
726             {
727               QApplication::sendEvent( getViewPort(), l_mbPressEvent );
728               delete l_mbPressEvent;
729               l_mbPressEvent = 0;
730             }
731             QApplication::sendEvent( getViewPort(), theEvent );
732           }
733         }
734       }
735       else {
736         emit mouseMoving( this, theEvent ); 
737       } 
738     }   
739   }
740 }
741
742 /*!
743   Handler of mouse release event
744 */
745 void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
746 {
747   switch ( myOperation ) {
748   case NOTHING:
749     {
750       int prevState = myCurSketch;
751       if(theEvent->state() == RightButton)
752       {
753         for ( OCCViewer_ViewSketcher* sk = mySketchers.first();
754               sk && myCurSketch != -1; sk = mySketchers.next() )
755         {
756           if( ( sk->sketchButton() & theEvent->state() ) && sk->sketchButton() == myCurSketch )
757             myCurSketch = -1;
758         }
759       }
760
761       emit mouseReleased(this, theEvent);
762       if(theEvent->button() == RightButton && prevState == -1)
763       {
764         QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
765                                   theEvent->pos(), theEvent->globalPos(),
766                                   theEvent->state() );
767         emit contextMenuRequested( &aEvent );
768       }
769     }
770     break;
771   case ROTATE:
772     myViewPort->endRotation();
773     resetState();
774     break;
775     
776   case PANVIEW:
777   case ZOOMVIEW:
778     resetState();
779     break;
780     
781   case PANGLOBAL:
782     if ( theEvent->button() == Qt::LeftButton ) {
783             myViewPort->setCenter( theEvent->x(), theEvent->y() );
784       myViewPort->getView()->SetScale(myCurScale);
785             resetState();
786           }
787     break;
788       
789   case WINDOWFIT:
790     if ( theEvent->state() == Qt::LeftButton ) {
791             myCurrX = theEvent->x();
792             myCurrY = theEvent->y();
793             QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
794             if ( !rect.isEmpty() ) myViewPort->fitRect(rect);
795             resetState();
796           }
797     break;
798   }
799   
800   // NOTE: viewer 3D detects a rectangle of selection using this event
801   // so we must emit it BEFORE resetting the selection rectangle
802   
803   if ( theEvent->button() == Qt::LeftButton && myDrawRect ) {
804     myDrawRect = false;
805     drawRect();
806     resetState(); 
807     myViewPort->update();
808   }
809
810   if ( l_mbPressEvent )
811   {
812     delete l_mbPressEvent;
813     l_mbPressEvent = 0;
814   }
815 }
816
817 /*!
818   Sets the viewport to its initial state
819   ( no transformations in process etc. )
820 */
821 void OCCViewer_ViewWindow::resetState()
822 {
823   myDrawRect = false;
824   
825   /* make rectangle empty (left > right) */
826   myRect.setLeft(2);
827   myRect.setRight(0);
828   
829   if ( myRotationPointSelection )
830   {
831     QCursor handCursor (Qt::PointingHandCursor);
832     setCursor( handCursor );
833   }
834   else
835   { 
836     if ( transformRequested() || myCursorIsHand ) 
837       setCursor( myCursor );
838     myCursorIsHand = false;
839   }
840   
841   if ( transformRequested() ) 
842     emit vpTransformationFinished (myOperation);
843   
844   setTransformInProcess( false );               
845   setTransformRequested( NOTHING );     
846 }
847
848
849 /*!
850   Draws rectangle by starting and current points
851 */
852 void OCCViewer_ViewWindow::drawRect()
853 {
854   QPainter aPainter(myViewPort);
855   aPainter.setRasterOp(Qt::XorROP);
856   aPainter.setPen(Qt::white);
857   QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
858   if ( !myRect.isEmpty() )
859           aPainter.drawRect( myRect );
860   aPainter.drawRect(aRect);
861   myRect = aRect;
862 }
863
864 /*!
865   Creates actions of OCC view window
866 */
867 void OCCViewer_ViewWindow::createActions()
868 {
869   if (!myActionsMap.isEmpty()) return;
870   
871   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
872   
873   QtxAction* aAction;
874
875   // Dump view
876   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ),
877                            tr( "MNU_DUMP_VIEW" ), 0, this);
878   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
879   connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
880         myActionsMap[ DumpId ] = aAction;
881
882   // FitAll
883   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ),
884                            tr( "MNU_FITALL" ), 0, this);
885   aAction->setStatusTip(tr("DSC_FITALL"));
886   connect(aAction, SIGNAL(activated()), this, SLOT(onFitAll()));
887         myActionsMap[ FitAllId ] = aAction;
888
889   // FitRect
890   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ),
891                            tr( "MNU_FITRECT" ), 0, this);
892   aAction->setStatusTip(tr("DSC_FITRECT"));
893   connect(aAction, SIGNAL(activated()), this, SLOT(activateWindowFit()));
894         myActionsMap[ FitRectId ] = aAction;
895
896   // Zoom
897   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ),
898                            tr( "MNU_ZOOM_VIEW" ), 0, this);
899   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
900   connect(aAction, SIGNAL(activated()), this, SLOT(activateZoom()));
901         myActionsMap[ ZoomId ] = aAction;
902
903   // Panning
904   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ),
905                            tr( "MNU_PAN_VIEW" ), 0, this);
906   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
907   connect(aAction, SIGNAL(activated()), this, SLOT(activatePanning()));
908         myActionsMap[ PanId ] = aAction;
909
910   // Global Panning
911   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ),
912                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
913   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
914   connect(aAction, SIGNAL(activated()), this, SLOT(activateGlobalPanning()));
915   myActionsMap[ GlobalPanId ] = aAction;
916
917   // Rotation Point
918   mySetRotationPointAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATION_POINT" ) ),
919                            tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this);
920   mySetRotationPointAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW"));
921   mySetRotationPointAction->setToggleAction( true );
922   connect(mySetRotationPointAction, SIGNAL(toggled( bool )), this, SLOT(onSetRotationPoint( bool )));
923   myActionsMap[ ChangeRotationPointId ] = mySetRotationPointAction;
924
925   // Rotation
926   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ),
927                            tr( "MNU_ROTATE_VIEW" ), 0, this);
928   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
929   connect(aAction, SIGNAL(activated()), this, SLOT(activateRotation()));
930         myActionsMap[ RotationId ] = aAction;
931
932   // Projections
933   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ),
934                            tr( "MNU_FRONT_VIEW" ), 0, this);
935   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
936   connect(aAction, SIGNAL(activated()), this, SLOT(onFrontView()));
937         myActionsMap[ FrontId ] = aAction;
938
939   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ),
940                            tr( "MNU_BACK_VIEW" ), 0, this);
941   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
942   connect(aAction, SIGNAL(activated()), this, SLOT(onBackView()));
943         myActionsMap[ BackId ] = aAction;
944
945   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ),
946                            tr( "MNU_TOP_VIEW" ), 0, this);
947   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
948   connect(aAction, SIGNAL(activated()), this, SLOT(onTopView()));
949         myActionsMap[ TopId ] = aAction;
950
951   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ),
952                            tr( "MNU_BOTTOM_VIEW" ), 0, this);
953   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
954   connect(aAction, SIGNAL(activated()), this, SLOT(onBottomView()));
955         myActionsMap[ BottomId ] = aAction;
956
957   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ),
958                            tr( "MNU_LEFT_VIEW" ), 0, this);
959   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
960   connect(aAction, SIGNAL(activated()), this, SLOT(onLeftView()));
961         myActionsMap[ LeftId ] = aAction;
962
963   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ),
964                            tr( "MNU_RIGHT_VIEW" ), 0, this);
965   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
966   connect(aAction, SIGNAL(activated()), this, SLOT(onRightView()));
967         myActionsMap[ RightId ] = aAction;
968
969   // Reset
970   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ),
971                            tr( "MNU_RESET_VIEW" ), 0, this);
972   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
973   connect(aAction, SIGNAL(activated()), this, SLOT(onResetView()));
974         myActionsMap[ ResetId ] = aAction;
975
976   // Reset
977   aAction = new QtxAction(tr("MNU_CLONE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLONE_VIEW" ) ),
978                            tr( "MNU_CLONE_VIEW" ), 0, this);
979   aAction->setStatusTip(tr("DSC_CLONE_VIEW"));
980   connect(aAction, SIGNAL(activated()), this, SLOT(onCloneView()));
981         myActionsMap[ CloneId ] = aAction;
982
983   myClippingAction = new QtxAction(tr("MNU_CLIPPING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ) ),
984                            tr( "MNU_CLIPPING" ), 0, this);
985   myClippingAction->setStatusTip(tr("DSC_CLIPPING"));
986   myClippingAction->setToggleAction( true );
987   connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool )));
988   myActionsMap[ ClippingId ] = myClippingAction;
989
990   aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ),
991                            tr( "MNU_SHOOT_VIEW" ), 0, this);
992   aAction->setStatusTip(tr("DSC_SHOOT_VIEW"));
993   connect(aAction, SIGNAL(activated()), this, SLOT(onMemorizeView()));
994         myActionsMap[ MemId ] = aAction;
995
996   aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ),
997                            tr( "MNU_PRESETS_VIEW" ), 0, this);
998   aAction->setStatusTip(tr("DSC_PRESETS_VIEW"));
999   connect(aAction, SIGNAL(activated()), this, SLOT(onRestoreView()));
1000         myActionsMap[ RestoreId ] = aAction;
1001
1002   if (myModel->trihedronActivated()) {
1003     aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ),
1004                              tr( "MNU_SHOW_TRIHEDRE" ), 0, this);
1005     aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE"));
1006     connect(aAction, SIGNAL(activated()), this, SLOT(onTrihedronShow()));
1007           myActionsMap[ TrihedronShowId ] = aAction;
1008   }
1009 }
1010
1011 /*!
1012   Creates toolbar of OCC view window
1013 */
1014 void OCCViewer_ViewWindow::createToolBar()
1015 {
1016   myActionsMap[DumpId]->addTo(myToolBar);  
1017   if ( myModel->trihedronActivated() ) 
1018     myActionsMap[TrihedronShowId]->addTo(myToolBar);
1019
1020   SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar, "scale");
1021   aScaleBtn->AddAction(myActionsMap[FitAllId]);
1022   aScaleBtn->AddAction(myActionsMap[FitRectId]);
1023   aScaleBtn->AddAction(myActionsMap[ZoomId]);
1024
1025   SUIT_ToolButton* aPanningBtn = new SUIT_ToolButton(myToolBar, "pan");
1026   aPanningBtn->AddAction(myActionsMap[PanId]);
1027   aPanningBtn->AddAction(myActionsMap[GlobalPanId]);
1028
1029   myActionsMap[ChangeRotationPointId]->addTo(myToolBar);
1030
1031   myActionsMap[RotationId]->addTo(myToolBar);
1032
1033   SUIT_ToolButton* aViewsBtn = new SUIT_ToolButton(myToolBar, "projection");
1034   aViewsBtn->AddAction(myActionsMap[FrontId]);
1035   aViewsBtn->AddAction(myActionsMap[BackId]);
1036   aViewsBtn->AddAction(myActionsMap[TopId]);
1037   aViewsBtn->AddAction(myActionsMap[BottomId]);
1038   aViewsBtn->AddAction(myActionsMap[LeftId]);
1039   aViewsBtn->AddAction(myActionsMap[RightId]);
1040
1041   myActionsMap[ResetId]->addTo(myToolBar);
1042
1043   SUIT_ToolButton* aMemBtn = new SUIT_ToolButton(myToolBar, "view");
1044   aMemBtn->AddAction(myActionsMap[MemId]);
1045   aMemBtn->AddAction(myActionsMap[RestoreId]);
1046
1047   myToolBar->addSeparator();
1048   myActionsMap[CloneId]->addTo(myToolBar);
1049   
1050   myToolBar->addSeparator();
1051   myActionsMap[ClippingId]->addTo(myToolBar);
1052 }
1053
1054 /*!
1055   Processes operation fit all
1056 */
1057 void OCCViewer_ViewWindow::onViewFitAll()
1058 {
1059   myViewPort->fitAll();
1060 }
1061
1062 /*!
1063   Processes transformation "front view"
1064 */
1065 void OCCViewer_ViewWindow::onFrontView()
1066 {
1067   emit vpTransformationStarted ( FRONTVIEW );
1068   Handle(V3d_View) aView3d = myViewPort->getView();
1069   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos);
1070   onViewFitAll();
1071 }
1072
1073 /*!
1074   Processes transformation "back view"
1075 */
1076 void OCCViewer_ViewWindow::onBackView()
1077 {
1078   emit vpTransformationStarted ( BACKVIEW );
1079   Handle(V3d_View) aView3d = myViewPort->getView();
1080   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg);
1081   onViewFitAll();
1082 }
1083
1084 /*!
1085   Processes transformation "top view"
1086 */
1087 void OCCViewer_ViewWindow::onTopView()
1088 {
1089   emit vpTransformationStarted ( TOPVIEW );
1090   Handle(V3d_View) aView3d = myViewPort->getView();
1091   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos);
1092   onViewFitAll();
1093 }
1094
1095 /*!
1096   Processes transformation "bottom view"
1097 */
1098 void OCCViewer_ViewWindow::onBottomView()
1099 {
1100   emit vpTransformationStarted ( BOTTOMVIEW );
1101   Handle(V3d_View) aView3d = myViewPort->getView();
1102   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg);
1103   onViewFitAll();
1104 }
1105
1106 /*!
1107   Processes transformation "left view"
1108 */
1109 void OCCViewer_ViewWindow::onLeftView()
1110 {
1111   emit vpTransformationStarted ( LEFTVIEW );
1112   Handle(V3d_View) aView3d = myViewPort->getView();
1113   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg);
1114   onViewFitAll();
1115 }
1116
1117 /*!
1118   Processes transformation "right view"
1119 */
1120 void OCCViewer_ViewWindow::onRightView()
1121 {
1122   emit vpTransformationStarted ( RIGHTVIEW );
1123   Handle(V3d_View) aView3d = myViewPort->getView();
1124   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos);
1125   onViewFitAll();
1126 }
1127
1128 /*!
1129   Processes transformation "reset view": sets default orientation of viewport camera
1130 */
1131 void OCCViewer_ViewWindow::onResetView()
1132 {
1133   emit vpTransformationStarted( RESETVIEW );
1134   bool upd = myViewPort->getView()->SetImmediateUpdate( false );
1135   myViewPort->getView()->Reset( false );
1136   myViewPort->fitAll( false, true, false );
1137   myViewPort->getView()->SetImmediateUpdate( upd );
1138   myViewPort->getView()->Update();
1139 }
1140
1141 /*!
1142   Processes transformation "fit all"
1143 */
1144 void OCCViewer_ViewWindow::onFitAll()
1145 {
1146   emit vpTransformationStarted( FITALLVIEW );
1147   myViewPort->fitAll();
1148 }
1149
1150 /*!
1151   SLOT: called if change rotation point operation is activated
1152 */
1153 void OCCViewer_ViewWindow::onSetRotationPoint( bool on )
1154 {
1155   if ( on )
1156     {
1157       if ( !mySetRotationPointDlg )
1158         {
1159           mySetRotationPointDlg = new OCCViewer_SetRotationPointDlg( this, myDesktop );
1160           mySetRotationPointDlg->SetAction( mySetRotationPointAction );
1161         }
1162
1163       if ( !mySetRotationPointDlg->isShown() )
1164       {
1165         if ( mySetRotationPointDlg->IsFirstShown() )
1166         { 
1167           Standard_Real Xcenter, Ycenter, Zcenter;
1168           if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
1169             mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
1170         }
1171         mySetRotationPointDlg->show();
1172       }
1173     }
1174   else
1175     {
1176       if ( mySetRotationPointDlg->isShown() )
1177         mySetRotationPointDlg->hide();
1178     }
1179 }
1180
1181 /*!
1182   Creates one more window with same content
1183 */
1184 void OCCViewer_ViewWindow::onCloneView()
1185 {
1186   SUIT_ViewWindow* vw = myManager->createViewWindow();
1187   vw->show();
1188 }
1189
1190 /*!
1191   SLOT: called if clipping operation is activated, enables/disables of clipping plane
1192 */
1193 void OCCViewer_ViewWindow::onClipping( bool on )
1194 {
1195   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1196   if ( on )
1197     myActionsMap[ ClippingId ]->setIconSet(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING_PRESSED" )));
1198   else
1199     myActionsMap[ ClippingId ]->setIconSet(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" )));
1200   
1201   if ( on )
1202     {
1203       if ( !myClippingDlg )
1204         {
1205           myClippingDlg = new OCCViewer_ClippingDlg( this, myDesktop );
1206           myClippingDlg->SetAction( myClippingAction );
1207         }
1208
1209       if ( !myClippingDlg->isShown() )
1210         myClippingDlg->show();
1211     }
1212   else
1213     {
1214       if ( myClippingDlg->isShown() )
1215         myClippingDlg->hide();
1216       setCuttingPlane(false);
1217     }
1218 }
1219
1220 /*!
1221   Stores view parameters
1222 */
1223 void OCCViewer_ViewWindow::onMemorizeView()
1224 {
1225   myModel->appendViewAspect( getViewParams() );
1226 }
1227
1228 /*!
1229   Restores view parameters
1230 */
1231 void OCCViewer_ViewWindow::onRestoreView()
1232 {
1233         OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), myModel );
1234         connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) );
1235         aDlg->exec();
1236         myModel->updateViewAspects( aDlg->parameters() );
1237         if( myRestoreFlag && aDlg->parameters().count() )
1238                 performRestoring( aDlg->currentItem() );
1239 }
1240
1241 /*!
1242   Restores view parameters from structure viewAspect
1243 */
1244 void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem )
1245 {
1246         Handle(V3d_View) aView3d = myViewPort->getView();
1247
1248         Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
1249         aView3d->SetScale( anItem.scale );
1250         aView3d->SetCenter( anItem.centerX, anItem.centerY );
1251         aView3d->SetTwist( anItem.twist );
1252         aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ );
1253         aView3d->SetImmediateUpdate( prev );
1254         aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ );
1255         aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
1256                 
1257         myRestoreFlag = 0;
1258 }
1259
1260 /*!
1261   Sets restore flag
1262 */
1263 void OCCViewer_ViewWindow::setRestoreFlag()
1264 {
1265         myRestoreFlag = 1;
1266 }
1267
1268 /*!
1269   SLOT: called when action "show/hide" trihedron is activated
1270 */
1271 void OCCViewer_ViewWindow::onTrihedronShow()
1272 {
1273   myModel->toggleTrihedron();
1274 }
1275
1276 /*!
1277   \return QImage, containing all scene rendering in window
1278 */
1279 QImage OCCViewer_ViewWindow::dumpView()
1280 {
1281   QPixmap px = QPixmap::grabWindow( myViewPort->winId() );
1282   return px.convertToImage();
1283 }
1284
1285 /*!
1286   Sets parameters of cutting plane
1287   \param on - is cutting plane enabled
1288   \param x - x-position of plane point 
1289   \param y - y-position of plane point 
1290   \param z - z-position of plane point 
1291   \param dx - x-coordinate of plane normal
1292   \param dy - y-coordinate of plane normal
1293   \param dz - z-coordinate of plane normal
1294 */
1295 void  OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x,  const double y,  const double z,
1296                                                       const double dx, const double dy, const double dz )
1297 {
1298   Handle(V3d_View) view = myViewPort->getView();
1299   if ( view.IsNull() )
1300     return;
1301
1302   if ( on ) {
1303     Handle(V3d_Viewer) viewer = myViewPort->getViewer();
1304     
1305     // try to use already existing plane or create a new one
1306     Handle(V3d_Plane) clipPlane;
1307     view->InitActivePlanes();
1308     if ( view->MoreActivePlanes() )
1309       clipPlane = view->ActivePlane();
1310     else
1311       clipPlane = new V3d_Plane( viewer );
1312     
1313     // set new a,b,c,d values for the plane
1314     gp_Pln pln( gp_Pnt( x, y, z ), gp_Dir( dx, dy, dz ) );
1315     double a, b, c, d;
1316     pln.Coefficients( a, b, c, d );
1317     clipPlane->SetPlane( a, b, c, d );
1318     
1319     view->SetPlaneOn( clipPlane );
1320   } 
1321   else
1322     view->SetPlaneOff();
1323   
1324   view->Update();
1325   view->Redraw();
1326 }
1327
1328 /*!
1329   \return true if there is at least one cutting plane
1330 */
1331 bool OCCViewer_ViewWindow::isCuttingPlane()
1332 {
1333   Handle(V3d_View) view = myViewPort->getView();
1334   view->InitActivePlanes();
1335   return (view->MoreActivePlanes());
1336 }
1337
1338 /*!
1339   The method returns the visual parameters of this view as a viewAspect object
1340 */
1341 viewAspect OCCViewer_ViewWindow::getViewParams() const
1342 {
1343   double centerX, centerY, projX, projY, projZ, twist;
1344   double atX, atY, atZ, eyeX, eyeY, eyeZ;
1345
1346   Handle(V3d_View) aView3d = myViewPort->getView();
1347
1348   aView3d->Center( centerX, centerY );
1349   aView3d->Proj( projX, projY, projZ );
1350   aView3d->At( atX, atY, atZ );
1351   aView3d->Eye( eyeX, eyeY, eyeZ );
1352   twist = aView3d->Twist();
1353
1354   QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" );
1355
1356   viewAspect params;
1357   params.scale    = aView3d->Scale();
1358   params.centerX  = centerX;
1359   params.centerY  = centerY;
1360   params.projX    = projX;
1361   params.projY    = projY;
1362   params.projZ    = projZ;
1363   params.twist    = twist;
1364   params.atX      = atX;
1365   params.atY      = atY;
1366   params.atZ      = atZ;
1367   params.eyeX     = eyeX;
1368   params.eyeY     = eyeY;
1369   params.eyeZ     = eyeZ;
1370   params.name     = aName;
1371
1372   return params;
1373 }
1374
1375
1376 /*!
1377   The method returns the visual parameters of this view as a formated string
1378 */
1379 QString OCCViewer_ViewWindow::getVisualParameters()
1380 {
1381   viewAspect params = getViewParams();
1382   QString retStr;
1383   retStr.sprintf( "%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e", params.scale,
1384                   params.centerX, params.centerY, params.projX, params.projY, params.projZ, params.twist,
1385                   params.atX, params.atY, params.atZ, params.eyeX, params.eyeY, params.eyeZ );
1386   return retStr;
1387 }
1388
1389 /*!
1390   The method restors visual parameters of this view from a formated string
1391 */
1392 void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
1393 {
1394   QStringList paramsLst = QStringList::split( '*', parameters, true );
1395   if ( paramsLst.size() == 13 ) {
1396     viewAspect params;
1397     params.scale    = paramsLst[0].toDouble();
1398     params.centerX  = paramsLst[1].toDouble();
1399     params.centerY  = paramsLst[2].toDouble();
1400     params.projX    = paramsLst[3].toDouble();
1401     params.projY    = paramsLst[4].toDouble();
1402     params.projZ    = paramsLst[5].toDouble();
1403     params.twist    = paramsLst[6].toDouble();
1404     params.atX      = paramsLst[7].toDouble();
1405     params.atY      = paramsLst[8].toDouble();
1406     params.atZ      = paramsLst[9].toDouble();
1407     params.eyeX     = paramsLst[10].toDouble();
1408     params.eyeY     = paramsLst[11].toDouble();
1409     params.eyeZ     = paramsLst[12].toDouble();
1410
1411     performRestoring( params );
1412   }
1413 }
1414
1415 /*!
1416   Custom show event handler
1417 */
1418 void OCCViewer_ViewWindow::showEvent( QShowEvent * theEvent ) 
1419 {
1420   emit Show( theEvent );
1421 }
1422
1423 /*!
1424   Custom hide event handler
1425 */
1426 void OCCViewer_ViewWindow::hideEvent( QHideEvent * theEvent ) 
1427 {
1428   emit Hide( theEvent );
1429 }
1430
1431
1432 /*!
1433     Creates default sketcher. [ virtual protected ]
1434 */
1435 OCCViewer_ViewSketcher* OCCViewer_ViewWindow::createSketcher( int type )
1436 {
1437   if ( type == Rect )
1438     return new OCCViewer_RectSketcher( this, type );
1439   if ( type == Polygon )
1440     return new OCCViewer_PolygonSketcher( this, type );
1441   return 0;
1442 }
1443
1444 void OCCViewer_ViewWindow::initSketchers()
1445 {
1446   if ( mySketchers.isEmpty() )
1447   {
1448     mySketchers.append( createSketcher( Rect ) );
1449     mySketchers.append( createSketcher( Polygon ) );
1450   }
1451 }
1452
1453 OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ )
1454 {
1455   OCCViewer_ViewSketcher* sketcher = 0;
1456   for ( OCCViewer_ViewSketcher* sk = mySketchers.first();
1457         sk && !sketcher; sk = mySketchers.next() )
1458   {
1459     if ( sk->type() == typ )
1460       sketcher = sk;
1461   }
1462   return sketcher;
1463 }
1464
1465 /*!
1466     Handles requests for sketching in the active view. [ virtual public ]
1467 */
1468 void OCCViewer_ViewWindow::activateSketching( int type )
1469 {
1470   OCCViewer_ViewPort3d* vp = getViewPort();
1471   if ( !vp )
1472     return;
1473
1474   if ( !vp->isSketchingEnabled() )
1475     return;
1476
1477   /* Finish current sketching */
1478   if ( type == NoSketching )
1479   {
1480     if ( mypSketcher )
1481     {
1482       onSketchingFinished();
1483       mypSketcher->deactivate();
1484       mypSketcher = 0;
1485     }
1486   }
1487   /* Activate new sketching */
1488   else
1489   {
1490     activateSketching( NoSketching );  /* concurrency not suported */
1491     mypSketcher = getSketcher( type );
1492     if ( mypSketcher )
1493     {
1494       mypSketcher->activate();
1495       onSketchingStarted();
1496     }
1497   }
1498 }
1499
1500 /*!
1501     Unhilights detected entities. [ virtual protected ]
1502 */
1503 void OCCViewer_ViewWindow::onSketchingStarted()
1504 {
1505 }
1506
1507 /*!
1508     Selection by rectangle or polygon. [ virtual protected ]
1509 */
1510 void OCCViewer_ViewWindow::onSketchingFinished()
1511 {
1512   if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept )
1513   {
1514     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
1515     bool append = bool( mypSketcher->buttonState() & Qt::ShiftButton );
1516     switch( mypSketcher->type() )
1517     {
1518     case Rect:
1519       {
1520         QRect* aRect = (QRect*)mypSketcher->data();
1521         if( aRect )
1522         {
1523           int aLeft = aRect->left();
1524           int aRight = aRect->right();
1525           int aTop = aRect->top();
1526           int aBottom = aRect->bottom();
1527
1528           if( append )
1529             ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
1530           else
1531             ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
1532         }
1533       }
1534       break;
1535     case Polygon:
1536       {
1537         QPointArray* aPolygon = (QPointArray*)mypSketcher->data();
1538         if( aPolygon )
1539         {
1540           int size = aPolygon->size();
1541           TColgp_Array1OfPnt2d anArray( 1, size );
1542
1543           QPointArray::Iterator it = aPolygon->begin();
1544           QPointArray::Iterator itEnd = aPolygon->end();
1545           for( int index = 1; it != itEnd; ++it, index++ )
1546           {
1547             QPoint aPoint = *it;
1548             anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) );
1549           }
1550
1551           if( append )
1552             ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False );
1553           else
1554             ic->Select( anArray, getViewPort()->getView(), Standard_False );
1555         }
1556       }
1557       break;
1558     default:
1559       break;
1560     }
1561
1562     OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager();
1563     aViewMgr->getOCCViewer()->performSelectionChanged();
1564   }
1565 }