Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[modules/gui.git] / src / SalomeApp / SalomeApp_VisualState.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "SalomeApp_VisualState.h"
20
21 #include "SalomeApp_Module.h"
22 #include "SalomeApp_Study.h"
23 #include "SalomeApp_Application.h"
24
25 #include <SUIT_ResourceMgr.h>
26 #include <QtxWorkstack.h>
27
28 #include <STD_TabDesktop.h>
29
30 #include <qptrlist.h>
31 #include <qapplication.h>
32 #include <qdict.h>
33
34 #include <SALOMEDS_IParameters.hxx>
35
36 #include <vector>
37 #include <string>
38
39 /*!
40   Constructor.
41 */
42 SalomeApp_VisualState::SalomeApp_VisualState( SalomeApp_Application* app )
43   : myApp( app )
44 {
45 }  
46
47 /*!
48   Destructor.
49 */
50 SalomeApp_VisualState::~SalomeApp_VisualState()
51 {
52 }
53
54 //================================================================
55 // Function : nameViewWindows
56 /*! Purpose : set names of all view windows in given list.  This is used
57 //  in order to apply the same naming algorithm when saving and restoring
58 //  view windows.  Names of view windows must be the same before saving
59 //  workstack (splitters) information, and before its restoring! 
60 //  Naming rule: ViewerType_IndexOfViewerOfThisType_IndexOfViewInThisViewer
61 //               VTKViewer_0_0
62 //               OCCViewer_0_0  OCCViewer_0_1  OCCViewer_0_2
63 //               VTKViewer_1_0
64 */
65 //================================================================
66 void nameViewWindows( const ViewManagerList& lst )
67 {
68   QDict<int> viewersCounter; // map viewerType - to - index_of_this_viewer_type
69   viewersCounter.setAutoDelete( true );
70   for ( QPtrListIterator<SUIT_ViewManager> it(lst); it.current(); ++it) {
71     int view_count = it.current()->getViewsCount();
72     QString vType = it.current()->getType();
73     if ( !view_count )
74       continue; //No views is opened in the viewer
75     
76     int* viewerID = viewersCounter[ vType ];
77     if ( !viewerID ) {
78       viewerID = new int( 0 );
79       viewersCounter.insert( vType, viewerID );
80     }
81     else
82       ++(*viewerID);
83
84     QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
85     for ( int i = 0; i < view_count; i++ )  {
86       QString vName = QString( "%1_%2_%3" ).arg( vType ).arg( *viewerID ).arg( i );
87       views[i]->setName( vName );
88     }
89   }
90 }
91
92 //================================================================
93 // Function : storeState
94 /*! Purpose : store the visual parameters of the viewers
95 */
96 //================================================================
97 int SalomeApp_VisualState::storeState()
98 {
99   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
100   if ( !study )
101     return -1;
102
103   int savePoint = 1;
104   std::vector<int> savePoints = study->getSavePoints();
105   //Calculate a new savePoint number = the last save point number + 1
106   if ( savePoints.size() > 0) 
107     savePoint = savePoints[savePoints.size()-1] + 1;
108
109   _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName(), savePoint );
110   SALOMEDS_IParameters ip( ap );
111
112   ViewManagerList lst;
113   myApp->viewManagers( lst );
114
115   // setting unique names for view windows in order to save this view inside 
116   // workstack's structure (see below).  On restore the views with the same names will
117   // be placed to the same place inside the workstack's splitters.
118   nameViewWindows( lst );
119
120   // store active window's name
121   SUIT_ViewWindow* win = myApp->desktop()->activeWindow();  
122   if ( win )
123     ip.setProperty("AP_ACTIVE_VIEW", win->name() );
124
125   int viewerID = 0;
126   SUIT_ViewManager* vm = 0;
127   for (QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it ) {
128     vm = it.current();
129     int view_count = vm->getViewsCount();
130     if ( !view_count ) 
131       continue; //No views is opened in the viewer
132       
133     std::string viewerEntry = QString( "%1_%2" ).arg( vm->getType() ).arg( ++viewerID ).latin1();
134     ip.append("AP_VIEWERS_LIST", viewerEntry);
135     
136     QPtrVector<SUIT_ViewWindow> views = vm->getViews();
137     for(int i = 0; i<view_count; i++) {
138       ip.append( viewerEntry, views[i]->caption() );
139       ip.append( viewerEntry, views[i]->getVisualParameters().latin1() );
140     }
141   }
142
143   //Save information about split areas
144   if ( myApp->desktop()->inherits( "STD_TabDesktop" ) ) {
145     QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
146     QString workstackInfo;
147     (*workstack) >> workstackInfo;
148     ip.setProperty( "AP_WORKSTACK_INFO", workstackInfo.latin1() );
149   }
150   
151   //Save a name of the active module
152   if ( CAM_Module* activeModule = myApp->activeModule() ) 
153     ip.setProperty( "AP_ACTIVE_MODULE", activeModule->moduleName().latin1() );
154
155   //Store visual parameters of the modules
156   QPtrList<CAM_Module> mlist; 
157   myApp->modules( mlist );
158   CAM_Module* module = 0;
159   for ( module = mlist.first(); module; module = mlist.next() ) {
160     if ( SalomeApp_Module* sModule = dynamic_cast<SalomeApp_Module*>( module ) ) {
161       ip.append( "AP_MODULES_LIST", sModule->moduleName().latin1() );
162       sModule->storeVisualParameters( savePoint );
163     }
164   }
165
166   // set default name of new savePoint
167   study->setNameOfSavePoint( savePoint, QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( savePoint ) );
168   
169   return savePoint;
170 }
171
172 //================================================================
173 // Function : restoreState
174 /*! Purpose : restore the visual parameters of the viewers
175 */
176 //================================================================
177 void SalomeApp_VisualState::restoreState(int savePoint)
178 {
179   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
180   if ( !study )
181     return;
182
183   _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName(), savePoint );
184   SALOMEDS_IParameters ip(ap);
185
186   //Remove all already existent veiwers and their views
187   ViewManagerList lst;
188   myApp->viewManagers( lst );
189   for ( QPtrListIterator<SUIT_ViewManager> it(lst); it.current(); ++it )
190     myApp->removeViewManager( it.current() );
191
192   //Restore the viewers and view windows
193   int nbViewers = ip.nbValues( "AP_VIEWERS_LIST" );
194   SUIT_ViewWindow* viewWin = 0;
195
196   for ( int i = 0; i < nbViewers; i++ ) {
197     std::string viewerEntry = ip.getValue( "AP_VIEWERS_LIST", i );
198     std::vector<std::string> veiewerParams = ip.parseValue(viewerEntry,'_');
199     std::string type = veiewerParams[0];
200     std::string viewerID = veiewerParams[1];
201     SUIT_ViewManager* vm = myApp->newViewManager( type.c_str() );
202     if ( !vm ) 
203       continue; //Unknown viewer
204     
205     int nbViews = (ip.nbValues(viewerEntry))/2;
206     
207     //Create nbViews-1 view (-1 because 1 view is created by createViewManager)
208     for ( int i = 1; i< nbViews; i++ ) { 
209       SUIT_ViewWindow* aView = vm->createViewWindow();
210       aView->show();
211     }
212
213     int viewCount = vm->getViewsCount();
214     if (viewCount != nbViews) {
215       printf( "\nRestore visual state: Unknow error, Can't create a view!\n" );
216       continue;
217     }
218
219     //Resize the views, set their captions and apply visual parameters.
220     QPtrVector<SUIT_ViewWindow> views = vm->getViews();  
221     for (int i = 0, j = 0; i<viewCount; i++, j++) {
222       viewWin = views[i];
223       if ( !viewWin ) 
224         continue;
225
226       // wait untill the window is really shown.  This step fixes MANY bugs..
227       while ( !viewWin->isVisible() )
228         qApp->processEvents();
229       
230       viewWin->setCaption(ip.getValue(viewerEntry, j).c_str());
231       viewWin->setVisualParameters(ip.getValue(viewerEntry, j+1).c_str());
232     }
233   }
234
235   // restore modules' visual parameters
236   std::vector<std::string> v = ip.getValues("AP_MODULES_LIST");
237   for ( int i = 0; i < v.size(); i++ ) {
238     myApp->activateModule( v[i].c_str() );
239     if ( SalomeApp_Module* module = dynamic_cast<SalomeApp_Module*>( myApp->activeModule() ) )
240       module->restoreVisualParameters( savePoint );
241   }
242
243   // activate module that was active on save
244   QString activeModuleName( ip.getProperty("AP_ACTIVE_MODULE" ).c_str() );
245   if ( !activeModuleName.isEmpty() ) 
246     myApp->activateModule( activeModuleName );
247
248   // setting unique names for view windows in order to restore positions of view windows inside 
249   // workstack's structure (see below).  During save the same naming algorithm was used, 
250   // so the same views will get the same names.
251   lst.clear();
252   myApp->viewManagers(lst);
253   nameViewWindows( lst );
254
255   // work-around to bug of setting visual parameters of views: all view windows now have
256   // correct visual parameters, bug after restoring the workstack the visual parameters 
257   // are messted, and must be re-set again.  So here we store them in a map and set them
258   // later back again.  why we don't store these parameters in a map on views creation?
259   // because 1) names of view windows are not set at that time 2) some view windows
260   // are created by modules' restoreVisualParameters (like Gauss Viewers), which is NOT here..
261   QMap<QString, QString> viewersParameters;
262   QPtrListIterator<SUIT_ViewManager> it( lst );
263   for ( ; it.current(); ++it ) {
264     int view_count = it.current()->getViewsCount();
265     QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
266     for ( int i = 0; i < view_count; i++ )
267       viewersParameters[ views[i]->name() ] = views[i]->getVisualParameters();
268   }  
269
270   // restore workstack parameters.  should be done after module's restoreVisualParameters(), because
271   // some modules can create their own viewers (like VISU creates GaussViewers)
272   if ( myApp->desktop()->inherits( "STD_TabDesktop" ) ) {
273     QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
274     (*workstack) << ip.getProperty( "AP_WORKSTACK_INFO" ).c_str();
275   }
276
277   // restore visual parameters of view windows.  it must be done AFTER restoring workstack.
278   for ( it.toFirst(); it.current(); ++it ) {
279     int view_count = it.current()->getViewsCount();
280     QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
281     for ( int i = 0; i < view_count; i++ )
282       views[i]->setVisualParameters( viewersParameters[ views[i]->name() ] );
283   }
284
285   // set focus to previously saved active view window
286   std::string activeViewName = ip.getProperty("AP_ACTIVE_VIEW");
287   for ( it.toFirst(); it.current(); ++it ) {
288     int view_count = it.current()->getViewsCount();
289     QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
290     for ( int i = 0; i < view_count; i++ )  {
291       if ( activeViewName == views[i]->name() )
292         views[i]->setFocus();
293     }
294   }
295 }