Salome HOME
88a0b888cf11d072d645feee32fccf3ef3632e07
[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 <SALOMEDSClient_ClientFactory.hxx>
35 #include <SALOMEDSClient_IParameters.hxx>
36
37 #include <vector>
38 #include <string>
39
40 /*!
41   Constructor.
42 */
43 SalomeApp_VisualState::SalomeApp_VisualState( SalomeApp_Application* app )
44   : myApp( app )
45 {
46 }  
47
48 /*!
49   Destructor.
50 */
51 SalomeApp_VisualState::~SalomeApp_VisualState()
52 {
53 }
54
55 /*!
56   Sets 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 void nameViewWindows( const ViewManagerList& lst )
66 {
67   QDict<int> viewersCounter; // map viewerType - to - index_of_this_viewer_type
68   viewersCounter.setAutoDelete( true );
69   for ( QPtrListIterator<SUIT_ViewManager> it(lst); it.current(); ++it) {
70     int view_count = it.current()->getViewsCount();
71     QString vType = it.current()->getType();
72     if ( !view_count )
73       continue; //No views is opened in the viewer
74     
75     int* viewerID = viewersCounter[ vType ];
76     if ( !viewerID ) {
77       viewerID = new int( 0 );
78       viewersCounter.insert( vType, viewerID );
79     }
80     else
81       ++(*viewerID);
82
83     QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
84     for ( int i = 0; i < view_count; i++ )  {
85       QString vName = QString( "%1_%2_%3" ).arg( vType ).arg( *viewerID ).arg( i );
86       views[i]->setName( vName );
87     }
88   }
89 }
90
91 /*!
92   Stores the visual parameters of the viewers
93 */
94 int SalomeApp_VisualState::storeState()
95 {
96   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
97   if ( !study )
98     return -1;
99
100   int savePoint = 1;
101   std::vector<int> savePoints = study->getSavePoints();
102   //Calculate a new savePoint number = the last save point number + 1
103   if ( savePoints.size() > 0) 
104     savePoint = savePoints[savePoints.size()-1] + 1;
105
106   _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName(), savePoint );
107   _PTR(IParameters) ip = ClientFactory::getIParameters( ap );
108
109   ViewManagerList lst;
110   myApp->viewManagers( lst );
111
112   // setting unique names for view windows in order to save this view inside 
113   // workstack's structure (see below).  On restore the views with the same names will
114   // be placed to the same place inside the workstack's splitters.
115   nameViewWindows( lst );
116
117   // store active window's name
118   SUIT_ViewWindow* win = myApp->desktop()->activeWindow();  
119   if ( win )
120     ip->setProperty("AP_ACTIVE_VIEW", win->name() );
121
122   int viewerID = 0;
123   SUIT_ViewManager* vm = 0;
124   for (QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it ) {
125     vm = it.current();
126     int view_count = vm->getViewsCount();
127     if ( !view_count ) 
128       continue; //No views is opened in the viewer
129       
130     std::string viewerEntry = QString( "%1_%2" ).arg( vm->getType() ).arg( ++viewerID ).latin1();
131     ip->append("AP_VIEWERS_LIST", viewerEntry);
132     
133     QPtrVector<SUIT_ViewWindow> views = vm->getViews();
134     for(int i = 0; i<view_count; i++) {
135       ip->append( viewerEntry, views[i]->caption().latin1() );
136       ip->append( viewerEntry, views[i]->getVisualParameters().latin1() );
137     }
138   }
139
140   //Save information about split areas
141   if ( myApp->desktop()->inherits( "STD_TabDesktop" ) ) {
142     QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
143     QString workstackInfo;
144     (*workstack) >> workstackInfo;
145     ip->setProperty( "AP_WORKSTACK_INFO", workstackInfo.latin1() );
146   }
147   
148   //Save a name of the active module
149   if ( CAM_Module* activeModule = myApp->activeModule() ) 
150     ip->setProperty( "AP_ACTIVE_MODULE", activeModule->moduleName().latin1() );
151
152   //Store visual parameters of the modules
153   QPtrList<CAM_Module> mlist; 
154   myApp->modules( mlist );
155   CAM_Module* module = 0;
156   for ( module = mlist.first(); module; module = mlist.next() ) {
157     if ( SalomeApp_Module* sModule = dynamic_cast<SalomeApp_Module*>( module ) ) {
158       ip->append( "AP_MODULES_LIST", sModule->moduleName().latin1() );
159       sModule->storeVisualParameters( savePoint );
160     }
161   }
162
163   // set default name of new savePoint
164   study->setNameOfSavePoint( savePoint, QObject::tr( "SAVE_POINT_DEF_NAME" ) + QString::number( savePoint ) );
165   
166   return savePoint;
167 }
168
169 /*!
170   Restores the visual parameters of the viewers
171 */
172 void SalomeApp_VisualState::restoreState(int savePoint)
173 {
174   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
175   if ( !study )
176     return;
177
178   _PTR(AttributeParameter) ap = study->studyDS()->GetCommonParameters( study->getVisualComponentName(), savePoint );
179   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
180
181   //Remove all already existent veiwers and their views
182   ViewManagerList lst;
183   myApp->viewManagers( lst );
184   for ( QPtrListIterator<SUIT_ViewManager> it(lst); it.current(); ++it ) {
185     myApp->removeViewManager( it.current() );
186     qApp->processEvents();
187   }
188   //Restore the viewers and view windows
189   int nbViewers = ip->nbValues( "AP_VIEWERS_LIST" );
190   SUIT_ViewWindow* viewWin = 0;
191
192   // parameters of view windows are stored in a map for restoring after restoring of the workstack
193   QMap<SUIT_ViewWindow*, QString> viewersParameters;
194
195   for ( int i = 0; i < nbViewers; i++ ) {
196     std::string viewerEntry = ip->getValue( "AP_VIEWERS_LIST", i );
197     std::vector<std::string> veiewerParams = ip->parseValue(viewerEntry,'_');
198     std::string type = veiewerParams[0];
199     std::string viewerID = veiewerParams[1];
200     SUIT_ViewManager* vm = myApp->newViewManager( type.c_str() );
201     if ( !vm ) 
202       continue; //Unknown viewer
203     
204     int nbViews = (ip->nbValues(viewerEntry))/2;
205     
206     //Create nbViews-1 view (-1 because 1 view is created by createViewManager)
207     for ( int i = 1; i< nbViews; i++ ) { 
208       SUIT_ViewWindow* aView = vm->createViewWindow();
209       aView->show();
210     }
211
212     int viewCount = vm->getViewsCount();
213     if (viewCount != nbViews) {
214       printf( "\nRestore visual state: Unknow error, Can't create a view!\n" );
215       continue;
216     }
217
218     //Resize the views, set their captions and apply visual parameters.
219     QPtrVector<SUIT_ViewWindow> views = vm->getViews();  
220     for (int i = 0, j = 0; i<viewCount; i++, j++) {
221       viewWin = views[i];
222       if ( !viewWin ) 
223         continue;
224
225       // wait untill the window is really shown.  This step fixes MANY bugs..
226       while ( !viewWin->isVisible() )
227         qApp->processEvents();
228       
229       viewWin->setCaption(ip->getValue(viewerEntry, j).c_str());
230       
231       //      printf ( "VP for viewWin \"%s\": %s\n", viewerEntry.c_str(), ip->getValue(viewerEntry, j+1).c_str() );
232       viewersParameters[ viewWin ] = ip->getValue(viewerEntry, j+1).c_str();
233       //viewWin->setVisualParameters(ip->getValue(viewerEntry, j+1).c_str());
234     }
235   }
236
237   // restore modules' visual parameters
238   std::vector<std::string> v = ip->getValues("AP_MODULES_LIST");
239   for ( int i = 0; i < v.size(); i++ ) {
240     myApp->activateModule( v[i].c_str() );
241     if ( SalomeApp_Module* module = dynamic_cast<SalomeApp_Module*>( myApp->activeModule() ) )
242       module->restoreVisualParameters( savePoint );
243   }
244
245   // new view windows may have been created in  module->restoreVisualParameters() [GAUSS]
246   // so here we store their visual parameters for later restoring..
247   lst.clear();
248   myApp->viewManagers(lst);
249   QPtrListIterator<SUIT_ViewManager> it( lst );
250   for ( ; it.current(); ++it ) {
251     int view_count = it.current()->getViewsCount();
252     QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
253     for ( int i = 0; i < view_count; i++ ) {
254       if ( !viewersParameters.contains( views[i] ) ) {
255         viewersParameters[ views[i] ] = views[i]->getVisualParameters();
256         //      printf ( "store VP for viewWin \"%s\": %s\n", views[i]->name(), views[i]->getVisualParameters().latin1() );
257       }
258     }
259   }  
260
261   // activate module that was active on save
262   QString activeModuleName( ip->getProperty("AP_ACTIVE_MODULE" ).c_str() );
263   if ( !activeModuleName.isEmpty() ) 
264     myApp->activateModule( activeModuleName );
265
266   // setting unique names for view windows in order to restore positions of view windows inside 
267   // workstack's structure (see below).  During save the same naming algorithm was used, 
268   // so the same views will get the same names.
269   nameViewWindows( lst );
270
271   // restore workstack parameters.  should be done after module's restoreVisualParameters(), because
272   // some modules can create their own viewers (like VISU creates GaussViewers)
273   if ( myApp->desktop()->inherits( "STD_TabDesktop" ) ) {
274     QtxWorkstack* workstack = ((STD_TabDesktop*)myApp->desktop())->workstack();
275     (*workstack) << ip->getProperty( "AP_WORKSTACK_INFO" ).c_str();
276   }
277
278   // restore visual parameters of view windows.  it must be done AFTER restoring workstack.
279   // also set active view
280   std::string activeViewName = ip->getProperty("AP_ACTIVE_VIEW");
281   QMap<SUIT_ViewWindow*, QString>::Iterator mapIt;
282   for ( mapIt = viewersParameters.begin(); mapIt != viewersParameters.end(); ++mapIt ) {
283     mapIt.key()->setVisualParameters( mapIt.data() );
284     if ( activeViewName == mapIt.key()->name() )
285       mapIt.key()->setFocus();
286   }
287   
288   //  for ( it.toFirst(); it.current(); ++it ) {
289   //    int view_count = it.current()->getViewsCount();
290   //    QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
291   //    for ( int i = 0; i < view_count; i++ )
292   //      views[i]->setVisualParameters( viewersParameters[ views[i]->name() ] );
293   //  }
294
295   // set focus to previously saved active view window
296   //  std::string activeViewName = ip->getProperty("AP_ACTIVE_VIEW");
297   //  for ( it.toFirst(); it.current(); ++it ) {
298   //    int view_count = it.current()->getViewsCount();
299   //    QPtrVector<SUIT_ViewWindow> views = it.current()->getViews();
300   //    for ( int i = 0; i < view_count; i++ )  {
301   //      if ( activeViewName == views[i]->name() )
302   //    views[i]->setFocus();
303   //    }
304   //  }
305 }