1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "HYDROGUI_VisualStateOp.h"
25 #include "HYDROGUI_Module.h"
26 #include "HYDROGUI_Tool.h"
27 #include "HYDROGUI_UpdateFlags.h"
29 #include <HYDROData_Document.h>
30 #include <HYDROData_VisualState.h>
32 #include <GraphicsView_Viewer.h>
34 #include <LightApp_Application.h>
36 #include <QtxWorkstack.h>
38 #include <STD_TabDesktop.h>
40 #include <SUIT_Desktop.h>
41 #include <SUIT_ViewManager.h>
42 #include <SUIT_ViewWindow.h>
44 #include <QApplication>
46 HYDROGUI_VisualStateOp::HYDROGUI_VisualStateOp( HYDROGUI_Module* theModule,
47 const bool theIsLoad )
48 : HYDROGUI_Operation( theModule ),
51 setName( theIsLoad ? tr( "LOAD_VISUAL_STATE" ) : tr( "SAVE_VISUAL_STATE" ) );
54 HYDROGUI_VisualStateOp::~HYDROGUI_VisualStateOp()
58 void HYDROGUI_VisualStateOp::startOperation()
60 HYDROGUI_Operation::startOperation();
67 aResult = loadVisualState();
69 aResult = saveVisualState();
85 bool HYDROGUI_VisualStateOp::saveVisualState()
87 LightApp_Application* anApp = module()->getApp();
89 Handle(HYDROData_VisualState) aVisualState =
90 Handle(HYDROData_VisualState)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
91 if( aVisualState.IsNull() )
93 // Create new visual state
94 aVisualState = Handle(HYDROData_VisualState)::DownCast( doc()->CreateObject( KIND_VISUAL_STATE ) );
95 if( aVisualState.IsNull() )
98 QString aName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_VISUAL_STATE_NAME" ) );
99 aVisualState->SetName( aName );
103 PropertyMap aPropertyMap;
105 // A. Setting unique names for view windows in order to save this view inside
106 // workstack's structure (see below). On restore the views with the same names will
107 // be placed to the same place inside the workstack's splitters.
108 ViewManagerList aViewManagerList;
109 anApp->viewManagers( aViewManagerList );
110 nameViewWindows( aViewManagerList );
112 // B. Store active window.
113 if( SUIT_ViewWindow* aViewWindow = anApp->desktop()->activeWindow() )
114 setVisualProperty( aPropertyMap, "AP_ACTIVE_VIEW", aViewWindow->objectName() );
116 // C. Store view properties.
118 QListIterator<SUIT_ViewManager*> anIter( aViewManagerList );
119 while( anIter.hasNext() )
121 if( SUIT_ViewManager* aViewManager = anIter.next() )
123 size_t aViewId = (size_t)aViewManager->getViewModel();
124 if( SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView() )
126 QString aType = aViewManager->getType();
127 QString aViewerEntry = QString( "%1_%2" ).arg( aType ).arg( ++aViewerId );
128 setVisualProperty( aPropertyMap, "AP_VIEWERS_LIST", aViewerEntry, true );
130 setVisualProperty( aPropertyMap, aViewerEntry, aViewWindow->windowTitle(), true );
131 setVisualProperty( aPropertyMap, aViewerEntry, aViewWindow->getVisualParameters(), true );
133 // C1. Store parameters of presentations.
134 HYDROData_SequenceOfObjects aSeq;
135 if( aType == GraphicsView_Viewer::Type() )
136 HYDROGUI_Tool::GetPrsSubObjects( module(), aSeq );
138 for( int anObjIndex = 1, aLength = aSeq.Length(); anObjIndex <= aLength; anObjIndex++ )
140 Handle(HYDROData_Entity) anObject = aSeq.Value( anObjIndex );
141 if( !anObject.IsNull() )
143 // Format: "Name|Visibility[|CoordX|CoordY]"
144 QString aParameters = anObject->GetName();
146 int aVisibility = (int)( module()->isObjectVisible( aViewId, anObject ) );
147 aParameters.append( QString( "|%1" ).arg( aVisibility ) );
149 setVisualProperty( aPropertyMap, aViewerEntry, aParameters, true );
156 // D. Store split areas.
157 if( anApp->desktop()->inherits( "STD_TabDesktop" ) )
159 QtxWorkstack* aWorkstack = ( (STD_TabDesktop*)anApp->desktop() )->workstack();
160 QByteArray aWorkstackState = aWorkstack->saveState( 0 );
161 QString aWorkstackInfo = aWorkstackState.toHex();
162 setVisualProperty( aPropertyMap, "AP_WORKSTACK_INFO", aWorkstackInfo );
165 // E. Store module preferences.
166 //ouv: currently, nothing to do
168 QString aState = encodePropertyMap( aPropertyMap );
169 //printf( "--- SetState -----------\n" );
170 //printf( "%s\n", qPrintable( aState ) );
171 //printf( "------------------------\n" );
172 aVisualState->SetState( aState );
174 module()->update( UF_Model );
179 bool HYDROGUI_VisualStateOp::loadVisualState()
181 LightApp_Application* anApp = module()->getApp();
183 Handle(HYDROData_VisualState) aVisualState =
184 Handle(HYDROData_VisualState)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
185 if( aVisualState.IsNull() )
188 QString aState = aVisualState->GetState();
189 //printf( "--- GetState -----------\n" );
190 //printf( "%s\n", qPrintable( aState ) );
191 //printf( "------------------------\n" );
192 PropertyMap aPropertyMap = decodePropertyMap( aState );
194 // Restore parameters.
196 // Preparation. Remove the existing viewers.
197 anApp->clearViewManagers();
199 // E. Restore module preferences
200 //ouv: currently, nothing to do
202 // C. Restore view properties (step 1).
203 QMap<SUIT_ViewWindow*, QString> aViewParameters;
204 int aNbViewers = nbVisualProperties( aPropertyMap, "AP_VIEWERS_LIST" );
205 for( int anIndex = 0; anIndex < aNbViewers; anIndex++ )
207 QString aViewerEntry = getVisualProperty( aPropertyMap, "AP_VIEWERS_LIST", anIndex );
208 QString aType = aViewerEntry.section( '_', 0, -2 );
209 QString aViewerId = aViewerEntry.section( '_', -1 ); // unused
210 if( SUIT_ViewManager* aViewManager = anApp->createViewManager( aType ) )
212 size_t aViewId = (size_t)aViewManager->getViewModel();
213 if( SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView() )
215 // Wait until the window is really shown. This step fixes MANY bugs.
216 //while( !aViewManager->isVisible() )
217 // qApp->processEvents();
219 int aNbViewerProps = nbVisualProperties( aPropertyMap, aViewerEntry );
221 aViewWindow->setWindowTitle( getVisualProperty( aPropertyMap, aViewerEntry, 0 ) );
223 // Parameters of view windows are restoring after the workstack (see below).
224 aViewParameters[ aViewWindow ] = getVisualProperty( aPropertyMap, aViewerEntry, 1 );
226 // C1. Restore parameters of presentations.
227 QMap< QString, QStringList > anObject2ParametersMap;
228 for( int aPropIndex1 = 2; aPropIndex1 < aNbViewerProps; aPropIndex1++ )
230 QString aProperty = getVisualProperty( aPropertyMap, aViewerEntry, aPropIndex1 );
231 QStringList aParameters = aProperty.split( "|" );
232 if( aParameters.count() > 1 )
234 QString aName = aParameters.front();
235 aParameters.pop_front();
236 anObject2ParametersMap[ aName ] = aParameters;
240 HYDROData_SequenceOfObjects aSeq;
241 if( aType == GraphicsView_Viewer::Type() )
242 HYDROGUI_Tool::GetPrsSubObjects( module(), aSeq );
244 for( int anObjIndex = 1, aLength = aSeq.Length(); anObjIndex <= aLength; anObjIndex++ )
246 Handle(HYDROData_Entity) anObject = aSeq.Value( anObjIndex );
247 if( !anObject.IsNull() )
249 QString aName = anObject->GetName();
250 if( anObject2ParametersMap.find( aName ) != anObject2ParametersMap.end() )
252 QStringList aParameters = anObject2ParametersMap[ aName ];
253 int aParamCount = aParameters.count();
254 QVector<bool> anIsOk( aParamCount, false );
256 int aParamIndex = -1;
257 if( aParamCount - aParamIndex - 1 >= 1 )
259 bool anIsVisible = aParameters[ aParamIndex ].toInt( &anIsOk[ ++aParamIndex ] );
261 module()->setObjectVisible( aViewId, anObject, anIsVisible );
270 // A. Setting unique names for view windows in order to restore positions of view windows inside
271 // workstack's structure (see below). During save the same naming algorithm was used,
272 // so the same views will get the same names.
273 ViewManagerList aViewManagerList;
274 anApp->viewManagers( aViewManagerList );
275 nameViewWindows( aViewManagerList );
277 qApp->processEvents();
279 // D. Restore split areas.
280 QtxWorkstack* aWorkstack = 0;
281 if( anApp->desktop()->inherits( "STD_TabDesktop" ) )
283 if( aWorkstack = ((STD_TabDesktop*)anApp->desktop())->workstack() )
285 QString aWorkstackInfo = getVisualProperty( aPropertyMap, "AP_WORKSTACK_INFO" );
286 QByteArray aWorkstackState = QByteArray::fromHex( aWorkstackInfo.toLatin1() );
287 aWorkstack->restoreState( aWorkstackState, 0 );
291 qApp->processEvents();
293 // C. Restore view properties (step 2).
294 // B. Restore active window. (currently doesn't work)
295 QString anActiveViewName = getVisualProperty( aPropertyMap, "AP_ACTIVE_VIEW" );
296 QMap<SUIT_ViewWindow*, QString>::Iterator aMapIter;
297 for( aMapIter = aViewParameters.begin(); aMapIter != aViewParameters.end(); ++aMapIter )
299 if( SUIT_ViewWindow* aViewWindow = aMapIter.key() )
301 aViewWindow->setVisualParameters( aMapIter.value() );
302 if( anActiveViewName == aViewWindow->objectName() )
304 aWorkstack->setActiveWindow( aViewWindow );
308 module()->update( UF_Viewer );
313 void HYDROGUI_VisualStateOp::nameViewWindows( const ViewManagerList& theList )
315 QMap<QString, int> aViewersCounter;
316 for( ViewManagerList::const_iterator anIter = theList.begin(); anIter != theList.end(); ++anIter )
318 SUIT_ViewManager* aViewManager = *anIter;
322 int aViewCount = aViewManager->getViewsCount();
323 QString aType = aViewManager->getType();
327 if( !aViewersCounter.contains( aType ) )
328 aViewersCounter.insert( aType, 0 );
330 int& aViewerId = aViewersCounter[ aType ];
332 QVector<SUIT_ViewWindow*> aViews = aViewManager->getViews();
333 for( int i = 0; i < aViewCount; i++ )
335 QString aName = QString( "%1_%2_%3" ).arg( aType ).arg( aViewerId ).arg( i );
336 aViews[i]->setObjectName( aName );
342 QString HYDROGUI_VisualStateOp::encodePropertyMap( const PropertyMap& thePropertyMap )
344 QStringList aPropertyDataStringList;
345 PropertyMapIterator anIter( thePropertyMap );
346 while( anIter.hasNext() )
348 QString aPropertyName = anIter.next().key();
349 QStringList aPropertyData = anIter.value();
351 if( !aPropertyData.isEmpty() )
353 aPropertyData.prepend( aPropertyName );
354 QString aPropertyDataString = aPropertyData.join( "||" );
355 aPropertyDataStringList.append( aPropertyDataString );
359 QString aResult = aPropertyDataStringList.join( "|||" );
363 HYDROGUI_VisualStateOp::PropertyMap
364 HYDROGUI_VisualStateOp::decodePropertyMap( const QString& theString )
366 PropertyMap aPropertyMap;
367 QStringList aPropertyDataStringList = theString.split( "|||" );
368 QStringListIterator anIter( aPropertyDataStringList );
369 while( anIter.hasNext() )
371 QString aPropertyDataString = anIter.next();
372 QStringList aPropertyData = aPropertyDataString.split( "||" );
373 if( aPropertyData.count() >= 2 )
375 QString aPropertyName = aPropertyData.front();
376 aPropertyData.pop_front();
377 aPropertyMap[ aPropertyName ] = aPropertyData;
383 void HYDROGUI_VisualStateOp::setVisualProperty( PropertyMap& thePropertyMap,
384 const QString& thePropertyName,
385 const QString& thePropertyData,
386 const bool theIsAppend )
388 QStringList& aPropertyDataList = thePropertyMap[ thePropertyName ];
390 aPropertyDataList.clear();
391 aPropertyDataList.append( thePropertyData );
394 QString HYDROGUI_VisualStateOp::getVisualProperty( const PropertyMap& thePropertyMap,
395 const QString& thePropertyName,
398 PropertyMap::const_iterator anIter = thePropertyMap.find( thePropertyName );
399 if( anIter != thePropertyMap.end() )
401 const QStringList aPropertyData = anIter.value();
402 if( theIndex >= 0 && theIndex < aPropertyData.count() )
403 return aPropertyData[ theIndex ];
408 int HYDROGUI_VisualStateOp::nbVisualProperties( const PropertyMap& thePropertyMap,
409 const QString& thePropertyName )
411 PropertyMap::const_iterator anIter = thePropertyMap.find( thePropertyName );
412 if( anIter != thePropertyMap.end() )
414 const QStringList aPropertyData = anIter.value();
415 return aPropertyData.count();