Salome HOME
Revert "Synchronize adm files"
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewFrame.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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 #include "OCCViewer_ViewFrame.h"
24 #include "OCCViewer_ViewWindow.h"
25 #include "OCCViewer_ViewModel.h"
26
27 #include <SUIT_ViewManager.h>
28 #include <SUIT_Session.h>
29 #include <SUIT_ResourceMgr.h>
30
31 #include <QtxResourceMgr.h>
32 #include <QtxWorkstackAction.h>
33
34 #include <QFrame>
35 #include <QLayout>
36 #include <QApplication>
37
38 OCCViewer_ViewFrame::OCCViewer_ViewFrame(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel)
39   : OCCViewer_ViewWindow( theDesktop, theModel ), myPopupRequestedView(0), mySplitMode(-1)
40 {
41   QFrame* centralFrame = new QFrame( this );
42   setCentralWidget( centralFrame );
43
44   OCCViewer_ViewWindow* view0 = theModel->createSubWindow();
45   updateWindowTitle( view0 );
46   view0->setParent( centralFrame );
47   myViews.append( view0 ); // MAIN_VIEW
48
49   myLayout = new QGridLayout( centralFrame );
50   myLayout->setMargin( 0 );
51   myLayout->setSpacing( 1 );
52
53   myLayout->addWidget( view0, 0, 0 );
54   myMaximizedView = view0;
55   connectViewSignals(view0);
56 }
57
58 OCCViewer_ViewFrame::~OCCViewer_ViewFrame()
59 {
60 }
61
62 bool OCCViewer_ViewFrame::event( QEvent* e )
63 {
64   if ( e->type() == QEvent::WindowTitleChange ) {
65     updateWindowTitle( getView( MAIN_VIEW ) );
66     updateWindowTitle( getView( BOTTOM_LEFT ) );
67     updateWindowTitle( getView( TOP_LEFT ) );
68     updateWindowTitle( getView( TOP_RIGHT ) );
69   }
70   return OCCViewer_ViewWindow::event( e );
71 }
72
73 //**************************************************************************************
74 OCCViewer_ViewWindow* OCCViewer_ViewFrame::getView( const int i ) const
75 {
76   return ( i >= 0 && i < myViews.count() ) ? myViews.at( i ) : 0 ;
77 }
78
79 //**************************************************************************************
80 void OCCViewer_ViewFrame::setViewManager( SUIT_ViewManager* theMgr )
81 {
82   OCCViewer_ViewWindow::setViewManager(theMgr);
83   foreach (OCCViewer_ViewWindow* aView, myViews) {
84     aView->setViewManager(theMgr); 
85   }
86 }
87
88 //**************************************************************************************
89 void OCCViewer_ViewFrame::returnTo3dView()
90 {
91   OCCViewer_ViewWindow* view = 0;
92   for (int i = BOTTOM_RIGHT; i <= TOP_RIGHT; i++ ) {
93     view = myViews.at(i);
94     view->setVisible( view->get2dMode() == No2dMode );
95     view->setMaximized( true, false );
96     if (view->get2dMode() == No2dMode) myMaximizedView = view;
97   }
98   myLayout->setColumnStretch(0, 0);
99   myLayout->setColumnStretch(1, 0);
100   myLayout->addWidget( myMaximizedView, 0, 0 );
101   mySplitMode = -1;
102   myViewsMode.clear();
103   myLayout->invalidate();
104 }
105
106 //**************************************************************************************
107 void OCCViewer_ViewFrame::onMaximizedView( OCCViewer_ViewWindow* theView, bool isMaximized)
108 {
109   myMaximizedView = theView;
110   if (isMaximized) {
111     if (myViews.count() <= 1)
112       return;
113     myLayout->setColumnStretch(0, 0);
114     myLayout->setColumnStretch(1, 0);
115     myLayout->addWidget( theView, 0, 0 );
116     int i = 0;
117     OCCViewer_ViewWindow* view = 0;
118     for ( i = BOTTOM_RIGHT; i <= TOP_RIGHT; i++ ) {
119       view = myViews.at(i);
120       view->setVisible( view == theView );
121       view->setMaximized( view == theView, false );
122     }
123     mySplitMode = -1;
124     myViewsMode.clear();
125   }
126   else {
127     createSubViews();
128
129     QtxSplitDlg CreateSubViewsDlg( this, NULL, CreateSubViews );
130     if ( CreateSubViewsDlg.exec() ) {
131       mySplitMode = CreateSubViewsDlg.getSplitMode();
132       myViewsMode = CreateSubViewsDlg.getViewsMode();
133       splitSubViews();
134     }
135     else {
136       myMaximizedView->setMaximized(true);
137     }
138   }
139   myLayout->invalidate();
140 }
141
142 //**************************************************************************************
143 void OCCViewer_ViewFrame::createSubViews()
144 {
145   OCCViewer_Viewer* aModel = dynamic_cast<OCCViewer_Viewer*>(myManager->getViewModel());
146   if (!aModel) return;
147   int i = 0;
148   if (myViews.count() == 1) {
149     //QColor aColor = myViews.at( MAIN_VIEW )->backgroundColor();
150     OCCViewer_ViewWindow* view = 0;
151     for ( i = BOTTOM_LEFT; i <= TOP_RIGHT; i++) {
152       view = aModel->createSubWindow();
153       view->set2dMode( (Mode2dType) i );
154       view->setParent( centralWidget() );
155       view->setViewManager(myManager);
156       updateWindowTitle( view );
157       myViews.append( view );
158       aModel->initView(view);
159       view->setMaximized(false, false);
160       view->setDropDownButtons( dropDownButtons() );
161       connectViewSignals(view);
162       view->setBackground(aModel->background(i));
163     }
164   }
165 }
166
167 void OCCViewer_ViewFrame::splitSubViews()
168 {
169         if( mySplitMode == -1 )
170                 return;
171
172   int aNbViews;
173   if ( mySplitMode >= 0 && mySplitMode < 2)
174     aNbViews = 2;
175   else if( mySplitMode >= 2 && mySplitMode < 8 )
176     aNbViews = 3;
177   else if( mySplitMode >=8 && mySplitMode < 29 )
178     aNbViews = 4;
179
180   if( aNbViews != myViewsMode.count() )
181         return;
182
183   int SubViews3Map[6][3][4] = {
184     { {0,0,1,1}, {0,1,1,1}, {0,2,1,1} },
185     { {0,0,1,1}, {1,0,1,1}, {2,0,1,1} },
186     { {0,0,1,1}, {1,0,1,1}, {0,1,2,1} },
187     { {0,0,2,1}, {0,1,1,1}, {1,1,1,1} },
188     { {0,0,1,2}, {1,0,1,1}, {1,1,1,1} },
189     { {0,0,1,1}, {0,1,1,1}, {1,0,1,2} }
190   };
191
192   int SubViews4Map[21][4][4] = {
193     { {0,0,1,1}, {0,1,1,1}, {0,2,1,1}, {0,3,1,1} },
194     { {0,0,1,1}, {1,0,1,1}, {2,0,1,1}, {3,0,1,1} },
195     { {0,0,1,1}, {0,1,1,1}, {1,0,1,1}, {1,1,1,1} },
196     { {0,0,1,1}, {1,0,1,1}, {0,1,2,1}, {0,2,2,1} },
197     { {0,0,2,1}, {0,1,1,1}, {1,1,1,1}, {0,2,2,1} },
198     { {0,0,2,1}, {0,1,2,1}, {0,2,1,1}, {1,2,1,1} },
199     { {0,0,1,1}, {0,1,1,1}, {1,0,1,2}, {2,0,1,2} },
200     { {0,0,1,2}, {1,0,1,1}, {1,1,1,1}, {2,0,1,2} },
201     { {0,0,1,2}, {1,0,1,2}, {2,0,1,1}, {2,1,1,1} },
202     { {0,0,1,1}, {1,0,1,1}, {0,1,2,1}, {2,0,1,2} },
203     { {0,0,2,1}, {0,1,1,1}, {1,1,1,1}, {2,0,1,2} },
204     { {0,0,1,2}, {1,0,1,1}, {2,0,1,1}, {1,1,2,1} },
205     { {0,0,1,2}, {1,0,2,1}, {1,1,1,1}, {2,1,1,1} },
206     { {0,0,2,1}, {0,1,1,1}, {0,2,1,1}, {1,1,1,2} },
207     { {0,0,2,1}, {0,1,1,2}, {1,1,1,1}, {1,2,1,1} },
208     { {0,0,1,1}, {0,1,1,1}, {1,0,1,2}, {0,2,2,1} },
209     { {0,0,1,2}, {1,0,1,1}, {1,1,1,1}, {0,2,2,1} },
210     { {0,0,1,3}, {1,0,1,1}, {1,1,1,1}, {1,2,1,1} },
211     { {0,0,1,1}, {0,1,1,1}, {0,2,1,1}, {1,0,1,3} },
212     { {0,0,1,1}, {1,0,1,1}, {2,0,1,1}, {0,1,3,1} },
213     { {0,0,3,1}, {0,1,1,1}, {1,1,1,1}, {2,1,1,1} },
214   };
215
216   if( aNbViews == 2 ) {
217     if( mySplitMode == 0 ) {
218       myLayout->addWidget( myViews.at(myViewsMode[0]), 0,0,2,1 );
219       myLayout->addWidget( myViews.at(myViewsMode[1]), 0,1,2,1 );
220     }
221     else if( mySplitMode == 1 ) {
222       myLayout->addWidget( myViews.at(myViewsMode[0]), 0,0,1,2 );
223       myLayout->addWidget( myViews.at(myViewsMode[1]), 1,0,1,2 );
224     }
225   }
226   else if( aNbViews == 3 ) {
227         int aSplitMode = mySplitMode - 2;
228     for( int i = 0; i < 3; i++ ) {
229     myLayout->addWidget( myViews.at(myViewsMode[i]),
230                          SubViews3Map[aSplitMode][i][0],
231                          SubViews3Map[aSplitMode][i][1],
232                          SubViews3Map[aSplitMode][i][2],
233                          SubViews3Map[aSplitMode][i][3]);
234     }
235   }
236   else if( aNbViews == 4 ) {
237         int aSplitMode = mySplitMode - 8;
238     for( int i = 0; i < 4; i++ ) {
239     myLayout->addWidget( myViews.at(myViewsMode[i]),
240                          SubViews4Map[aSplitMode][i][0],
241                          SubViews4Map[aSplitMode][i][1],
242                          SubViews4Map[aSplitMode][i][2],
243                          SubViews4Map[aSplitMode][i][3]);
244     }
245   }
246
247   OCCViewer_ViewWindow* view = 0;
248   bool isVisible3dView = false;
249   for ( int i = 0; i< myViews.count(); i++ ) {
250     view = myViews.at(i);
251     bool isShowed = false;
252     for( int j = 0; j < myViewsMode.count(); j++ ) {
253       OCCViewer_ViewWindow* view2 = 0;
254       view2 = myViews.at( myViewsMode[j] );
255       if( view == view2 )
256         isShowed = true;
257     }
258     if( isShowed ) {
259       view->show();
260       view->setMaximized( false, false );
261       if ( view->get2dMode() == No2dMode ) isVisible3dView = true;
262       ///////////////QApplication::processEvents(); // VSR: hangs up ?
263       if ( view != myMaximizedView )
264         view->onViewFitAll();
265     }
266     else
267       view->setVisible( false );
268   }
269   if ( !isVisible3dView ) {
270     for ( int i = 0; i< myViews.count(); i++ ){
271       view = myViews.at(i);
272       if( view->isVisible() )
273         view->setReturnedTo3dView( false );
274     }
275   }
276 }
277
278 //**************************************************************************************
279 OCCViewer_ViewPort3d* OCCViewer_ViewFrame::getViewPort(int theView) 
280
281   return getView(theView)? getView(theView)->getViewPort() : 0;
282 }
283   
284 //**************************************************************************************
285 void OCCViewer_ViewFrame::updateEnabledDrawMode() 
286
287   foreach (OCCViewer_ViewWindow* aView, myViews) {
288     aView->updateEnabledDrawMode(); 
289   }
290 }
291
292 //**************************************************************************************
293 void OCCViewer_ViewFrame::setCuttingPlane( bool on, const double x , const double y , const double z,
294                                            const double dx, const double dy, const double dz)  
295
296   foreach (OCCViewer_ViewWindow* aView, myViews) {
297     aView->setCuttingPlane(on, x, y, z, dx, dy, dz); 
298     aView->update();
299   }
300 }
301
302 //**************************************************************************************
303 void OCCViewer_ViewFrame::setCuttingPlane( bool on, const gp_Pln thePln ) 
304
305   foreach (OCCViewer_ViewWindow* aView, myViews) {
306     aView->setCuttingPlane(on, thePln); 
307     aView->update();
308   }
309 }
310   
311 //**************************************************************************************
312 void OCCViewer_ViewFrame::setInteractionStyle( const int i ) 
313
314   foreach (OCCViewer_ViewWindow* aView, myViews) {
315     aView->setInteractionStyle(i); 
316   }
317 }
318
319 //**************************************************************************************
320 void OCCViewer_ViewFrame::setZoomingStyle( const int i ) 
321
322   foreach (OCCViewer_ViewWindow* aView, myViews) {
323     aView->setZoomingStyle(i); 
324   }
325 }
326   
327 //**************************************************************************************
328 void OCCViewer_ViewFrame::connectViewSignals(OCCViewer_ViewWindow* theView)
329 {
330   connect( theView, SIGNAL( returnedTo3d( ) ), this, SLOT( returnTo3dView( ) ) );
331
332   connect( theView, SIGNAL( maximized( OCCViewer_ViewWindow*, bool ) ), 
333            this, SLOT( onMaximizedView( OCCViewer_ViewWindow*, bool ) ) );
334
335   connect( theView, SIGNAL( wheeling(SUIT_ViewWindow*, QWheelEvent*) ), 
336            this, SIGNAL( wheeling(SUIT_ViewWindow*, QWheelEvent*) ) );
337
338   connect( theView, SIGNAL( keyReleased(SUIT_ViewWindow*, QKeyEvent*) ), 
339            this, SIGNAL( keyReleased(SUIT_ViewWindow*, QKeyEvent*) ) );
340   connect( theView, SIGNAL( keyPressed(SUIT_ViewWindow*, QKeyEvent*) ), 
341            this, SIGNAL( keyPressed(SUIT_ViewWindow*, QKeyEvent*) ) );
342
343   connect( theView, SIGNAL( mouseDoubleClicked(SUIT_ViewWindow*, QMouseEvent*) ), 
344            this, SIGNAL( mouseDoubleClicked(SUIT_ViewWindow*, QMouseEvent*) ) );
345   connect( theView, SIGNAL( mousePressed(SUIT_ViewWindow*, QMouseEvent*) ), 
346            this, SIGNAL( mousePressed(SUIT_ViewWindow*, QMouseEvent*) ) );
347   connect( theView, SIGNAL( mouseReleased(SUIT_ViewWindow*, QMouseEvent*) ), 
348            this, SIGNAL( mouseReleased(SUIT_ViewWindow*, QMouseEvent*) ) );
349   connect( theView, SIGNAL( mouseMoving(SUIT_ViewWindow*, QMouseEvent*) ), 
350            this, SIGNAL( mouseMoving(SUIT_ViewWindow*, QMouseEvent*) ) );
351
352   // The signal is used to process get/set background color from popup
353   connect( theView, SIGNAL( contextMenuRequested(QContextMenuEvent*) ), 
354            this, SLOT( onContextMenuRequested(QContextMenuEvent*) ) );
355
356   connect( theView, SIGNAL( contextMenuRequested(QContextMenuEvent*) ), 
357            this, SIGNAL( contextMenuRequested(QContextMenuEvent*) ) );
358
359   connect( theView, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
360            this,    SIGNAL( viewCloned( SUIT_ViewWindow* ) ) );
361 }
362
363 // obsolete
364 void OCCViewer_ViewFrame::setBackgroundColor( const QColor& theColor )
365 {
366   if (myPopupRequestedView)
367     myPopupRequestedView->setBackgroundColor(theColor); 
368   else {
369     foreach (OCCViewer_ViewWindow* aView, myViews) {
370       if (aView->isVisible())
371         aView->setBackgroundColor(theColor); 
372     }
373   }
374 }
375 void OCCViewer_ViewFrame::setBackground( const Qtx::BackgroundData& theBackground )
376 {
377   if (myPopupRequestedView)
378     myPopupRequestedView->setBackground(theBackground); 
379   else {
380     foreach (OCCViewer_ViewWindow* aView, myViews) {
381       if (aView->isVisible())
382         aView->setBackground(theBackground); 
383     }
384   }
385 }
386
387 void OCCViewer_ViewFrame::onViewFitAll()
388 {
389   foreach (OCCViewer_ViewWindow* aView, myViews) {
390     aView->onViewFitAll(); 
391   }
392 }
393
394 void OCCViewer_ViewFrame::onFitAll()
395 {
396   foreach (OCCViewer_ViewWindow* aView, myViews) {
397     aView->onFitAll(); 
398   }
399 }
400
401 // obsolete  
402 QColor OCCViewer_ViewFrame::backgroundColor() const 
403
404   if (myPopupRequestedView)
405     return myPopupRequestedView->backgroundColor(); 
406
407   foreach (OCCViewer_ViewWindow* aView, myViews) {
408     if (aView->isVisible())
409       return aView->backgroundColor(); 
410   }
411   return getView(MAIN_VIEW)->backgroundColor(); 
412 }
413
414 Qtx::BackgroundData OCCViewer_ViewFrame::background() const 
415
416   if (myPopupRequestedView)
417     return myPopupRequestedView->background(); 
418
419   foreach (OCCViewer_ViewWindow* aView, myViews) {
420     if (aView->isVisible())
421       return aView->background(); 
422   }
423   return getView(MAIN_VIEW)->background(); 
424 }
425
426 void OCCViewer_ViewFrame::showStaticTrihedron( bool on )
427 {
428   if ( myPopupRequestedView )
429     myPopupRequestedView->showStaticTrihedron( on ); 
430   else {
431     foreach ( OCCViewer_ViewWindow* aView, myViews ) {
432       aView->showStaticTrihedron( on ); 
433     }
434   }
435 }
436
437 QImage OCCViewer_ViewFrame::dumpView()
438 {
439   foreach (OCCViewer_ViewWindow* aView, myViews) {
440     if (aView->isVisible())
441       return aView->dumpView();
442   }
443   return QImage();
444 }
445
446 bool OCCViewer_ViewFrame::dumpViewToFormat( const QImage& image, const QString& fileName, const QString& format )
447 {
448   foreach (OCCViewer_ViewWindow* aView, myViews) {
449     if (aView->isVisible())
450       return aView->dumpViewToFormat( image, fileName, format );
451   }
452   return false;
453 }
454
455 void OCCViewer_ViewFrame::onContextMenuRequested(QContextMenuEvent*)
456 {
457   myPopupRequestedView = dynamic_cast<OCCViewer_ViewWindow*>(sender());
458 }
459
460 void OCCViewer_ViewFrame::onDumpView()
461 {
462   if (myPopupRequestedView) {
463     myPopupRequestedView->onDumpView(); 
464   }
465   else {
466     getView(MAIN_VIEW)->onDumpView(); 
467   }
468 }
469
470 void OCCViewer_ViewFrame::setDropDownButtons( bool on )
471 {
472   foreach( OCCViewer_ViewWindow* aView, myViews ) {
473     aView->setDropDownButtons( on );
474   }
475   OCCViewer_ViewWindow::setDropDownButtons( on );
476 }
477
478 QString OCCViewer_ViewFrame::getVisualParameters()
479 {
480   QStringList params;
481   QStringList splitParams;
482   if( mySplitMode != -1 && myViewsMode.count() != 0 ) {
483     splitParams << QString::number( mySplitMode );
484     foreach ( int aViewMode, myViewsMode )
485       splitParams << QString::number( aViewMode );
486     params.append( splitParams.join("*") );
487   }
488   else
489     params.append( QString::number( mySplitMode ) );
490   int maximizedView = 999;
491   for ( int i = BOTTOM_RIGHT; i <= TOP_RIGHT && i < myViews.count(); i++) {
492     if ( getView(i)->isVisible() )
493       maximizedView = ( maximizedView != -1 ) ? ( maximizedView == 999 ? i : -1 ) : ( maximizedView );
494     params << getView(i)->getVisualParameters();
495   }
496   params.prepend( QString::number( maximizedView ) );
497   return params.join( "|" );
498 }
499
500 void OCCViewer_ViewFrame::setVisualParameters( const QString& parameters ) 
501 {
502   QStringList params = parameters.split( "|" );
503   if ( params.count() > 1 ) {
504     int maximizedView = params[0].toInt();
505     if ( myViews.count() < params.count()-2 )
506       createSubViews(); // secondary views are not created yet, but should be
507
508     for ( int i = 2; i < params.count(); i++ ) {
509       int idx = i-2;
510       getView( idx )->setVisualParameters( params[i] );
511     }
512
513     QStringList aSplitParams = params[1].split("*");
514     if( aSplitParams.count() > 1 ) {
515       mySplitMode = aSplitParams[0].toInt();
516       for( int i = 1; i < aSplitParams.count(); i++ )
517         myViewsMode << aSplitParams[i].toInt();
518     }
519     if( mySplitMode != -1 )
520       splitSubViews();
521     else
522       onMaximizedView( getView( maximizedView ), true ); // set proper sub-window maximized
523   }
524   else {
525     // handle obsolete versions - no parameters for xy, yz, xz views
526     getView(MAIN_VIEW)->setVisualParameters( parameters );
527   }
528 }
529
530 SUIT_CameraProperties OCCViewer_ViewFrame::cameraProperties()
531 {
532   // view frame does not have camera properties
533   return SUIT_CameraProperties();
534 }
535
536 void OCCViewer_ViewFrame::updateWindowTitle(OCCViewer_ViewWindow* theView)
537 {
538   if ( !theView )
539     return;
540   QString title;
541   switch ( theView->get2dMode() ) {
542   case No2dMode:
543     title = "3D"; break;
544   case XYPlane:
545     title = "YX"; break;
546   case XZPlane:
547     title = "XZ"; break;
548   case YZPlane:
549     title = "YZ"; break;
550   default:
551     break;
552   }
553   if ( !title.isEmpty() )
554     theView->setWindowTitle( windowTitle() + " - " + title );
555 }
556
557 void OCCViewer_ViewFrame::enableSelection( bool isEnabled )
558 {
559   foreach (OCCViewer_ViewWindow* aView, myViews) {
560     aView->enableSelection(isEnabled); 
561   }
562 }
563
564 void OCCViewer_ViewFrame::enablePreselection( bool isEnabled )
565 {
566   foreach (OCCViewer_ViewWindow* aView, myViews) {
567     aView->enablePreselection(isEnabled); 
568   }
569 }