1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROGUI_VisualStateOp.h"
21 #include "HYDROGUI_Module.h"
22 #include "HYDROGUI_Tool2.h"
23 #include "HYDROGUI_UpdateFlags.h"
25 #include <HYDROData_Document.h>
26 #include <HYDROData_VisualState.h>
28 #include <GraphicsView_Viewer.h>
30 #include <LightApp_Application.h>
32 #include <QtxWorkstack.h>
34 #include <STD_TabDesktop.h>
36 #include <SUIT_Desktop.h>
37 #include <SUIT_ViewManager.h>
38 #include <SUIT_ViewWindow.h>
40 #include <QApplication>
42 HYDROGUI_VisualStateOp::HYDROGUI_VisualStateOp( HYDROGUI_Module* theModule,
43 const bool theIsLoad )
44 : HYDROGUI_Operation( theModule ),
47 setName( theIsLoad ? tr( "LOAD_VISUAL_STATE" ) : tr( "SAVE_VISUAL_STATE" ) );
50 HYDROGUI_VisualStateOp::~HYDROGUI_VisualStateOp()
54 void HYDROGUI_VisualStateOp::startOperation()
56 HYDROGUI_Operation::startOperation();
63 aResult = loadVisualState();
65 aResult = saveVisualState();
81 bool HYDROGUI_VisualStateOp::saveVisualState()
83 LightApp_Application* anApp = module()->getApp();
85 Handle(HYDROData_VisualState) aVisualState =
86 Handle(HYDROData_VisualState)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
87 if( aVisualState.IsNull() )
89 // Create new visual state
90 aVisualState = Handle(HYDROData_VisualState)::DownCast( doc()->CreateObject( KIND_VISUAL_STATE ) );
91 if( aVisualState.IsNull() )
94 QString aName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_VISUAL_STATE_NAME" ) );
95 aVisualState->SetName( aName );
99 PropertyMap aPropertyMap;
101 // A. Setting unique names for view windows in order to save this view inside
102 // workstack's structure (see below). On restore the views with the same names will
103 // be placed to the same place inside the workstack's splitters.
104 ViewManagerList aViewManagerList;
105 anApp->viewManagers( aViewManagerList );
106 nameViewWindows( aViewManagerList );
108 // B. Store active window.
109 if( SUIT_ViewWindow* aViewWindow = anApp->desktop()->activeWindow() )
110 setVisualProperty( aPropertyMap, "AP_ACTIVE_VIEW", aViewWindow->objectName() );
112 // C. Store view properties.
114 QListIterator<SUIT_ViewManager*> anIter( aViewManagerList );
115 while( anIter.hasNext() )
117 if( SUIT_ViewManager* aViewManager = anIter.next() )
119 size_t aViewId = (size_t)aViewManager->getViewModel();
120 if( SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView() )
122 QString aType = aViewManager->getType();
123 QString aViewerEntry = QString( "%1_%2" ).arg( aType ).arg( ++aViewerId );
124 setVisualProperty( aPropertyMap, "AP_VIEWERS_LIST", aViewerEntry, true );
126 setVisualProperty( aPropertyMap, aViewerEntry, aViewWindow->windowTitle(), true );
127 setVisualProperty( aPropertyMap, aViewerEntry, aViewWindow->getVisualParameters(), true );
129 // C1. Store parameters of presentations.
130 HYDROData_SequenceOfObjects aSeq;
131 if( aType == GraphicsView_Viewer::Type() )
132 HYDROGUI_Tool::GetPrsSubObjects( module(), aSeq );
134 for( int anObjIndex = 1, aLength = aSeq.Length(); anObjIndex <= aLength; anObjIndex++ )
136 Handle(HYDROData_Entity) anObject = aSeq.Value( anObjIndex );
137 if( !anObject.IsNull() )
139 // Format: "Name|Visibility[|CoordX|CoordY]"
140 QString aParameters = anObject->GetName();
142 int aVisibility = (int)( module()->isObjectVisible( aViewId, anObject ) );
143 aParameters.append( QString( "|%1" ).arg( aVisibility ) );
145 setVisualProperty( aPropertyMap, aViewerEntry, aParameters, true );
152 // D. Store split areas.
153 if( anApp->desktop()->inherits( "STD_TabDesktop" ) )
155 QtxWorkstack* aWorkstack = ( (STD_TabDesktop*)anApp->desktop() )->workstack();
156 QByteArray aWorkstackState = aWorkstack->saveState( 0 );
157 QString aWorkstackInfo = aWorkstackState.toHex();
158 setVisualProperty( aPropertyMap, "AP_WORKSTACK_INFO", aWorkstackInfo );
161 // E. Store module preferences.
162 //ouv: currently, nothing to do
164 QString aState = encodePropertyMap( aPropertyMap );
165 //printf( "--- SetState -----------\n" );
166 //printf( "%s\n", qPrintable( aState ) );
167 //printf( "------------------------\n" );
168 aVisualState->SetState( aState.toStdString() );
170 module()->update( UF_Model );
175 bool HYDROGUI_VisualStateOp::loadVisualState()
177 LightApp_Application* anApp = module()->getApp();
179 Handle(HYDROData_VisualState) aVisualState =
180 Handle(HYDROData_VisualState)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
181 if( aVisualState.IsNull() )
184 QString aState = QString::fromStdString( aVisualState->GetState() );
185 //printf( "--- GetState -----------\n" );
186 //printf( "%s\n", qPrintable( aState ) );
187 //printf( "------------------------\n" );
188 PropertyMap aPropertyMap = decodePropertyMap( aState );
190 // Restore parameters.
192 // Preparation. Remove the existing viewers.
193 anApp->clearViewManagers();
195 // E. Restore module preferences
196 //ouv: currently, nothing to do
198 // C. Restore view properties (step 1).
199 QMap<SUIT_ViewWindow*, QString> aViewParameters;
200 int aNbViewers = nbVisualProperties( aPropertyMap, "AP_VIEWERS_LIST" );
201 for( int anIndex = 0; anIndex < aNbViewers; anIndex++ )
203 QString aViewerEntry = getVisualProperty( aPropertyMap, "AP_VIEWERS_LIST", anIndex );
204 QString aType = aViewerEntry.section( '_', 0, -2 );
205 QString aViewerId = aViewerEntry.section( '_', -1 ); // unused
206 if( SUIT_ViewManager* aViewManager = anApp->createViewManager( aType ) )
208 size_t aViewId = (size_t)aViewManager->getViewModel();
209 if( SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView() )
211 // Wait until the window is really shown. This step fixes MANY bugs.
212 //while( !aViewManager->isVisible() )
213 // qApp->processEvents();
215 int aNbViewerProps = nbVisualProperties( aPropertyMap, aViewerEntry );
217 aViewWindow->setWindowTitle( getVisualProperty( aPropertyMap, aViewerEntry, 0 ) );
219 // Parameters of view windows are restoring after the workstack (see below).
220 aViewParameters[ aViewWindow ] = getVisualProperty( aPropertyMap, aViewerEntry, 1 );
222 // C1. Restore parameters of presentations.
223 QMap< QString, QStringList > anObject2ParametersMap;
224 for( int aPropIndex1 = 2; aPropIndex1 < aNbViewerProps; aPropIndex1++ )
226 QString aProperty = getVisualProperty( aPropertyMap, aViewerEntry, aPropIndex1 );
227 QStringList aParameters = aProperty.split( "|" );
228 if( aParameters.count() > 1 )
230 QString aName = aParameters.front();
231 aParameters.pop_front();
232 anObject2ParametersMap[ aName ] = aParameters;
236 HYDROData_SequenceOfObjects aSeq;
237 if( aType == GraphicsView_Viewer::Type() )
238 HYDROGUI_Tool::GetPrsSubObjects( module(), aSeq );
240 for( int anObjIndex = 1, aLength = aSeq.Length(); anObjIndex <= aLength; anObjIndex++ )
242 Handle(HYDROData_Entity) anObject = aSeq.Value( anObjIndex );
243 if( !anObject.IsNull() )
245 QString aName = anObject->GetName();
246 if( anObject2ParametersMap.find( aName ) != anObject2ParametersMap.end() )
248 QStringList aParameters = anObject2ParametersMap[ aName ];
249 int aParamCount = aParameters.count();
250 QVector<bool> anIsOk( aParamCount, false );
252 int aParamIndex = -1;
253 if( aParamCount - aParamIndex - 1 >= 1 )
255 bool anIsVisible = aParameters[ aParamIndex ].toInt( &anIsOk[ ++aParamIndex ] );
257 module()->setObjectVisible( aViewId, anObject, anIsVisible );
266 // A. 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 ViewManagerList aViewManagerList;
270 anApp->viewManagers( aViewManagerList );
271 nameViewWindows( aViewManagerList );
273 qApp->processEvents();
275 // D. Restore split areas.
276 QtxWorkstack* aWorkstack = 0;
277 if( anApp->desktop()->inherits( "STD_TabDesktop" ) )
279 if( aWorkstack = ((STD_TabDesktop*)anApp->desktop())->workstack() )
281 QString aWorkstackInfo = getVisualProperty( aPropertyMap, "AP_WORKSTACK_INFO" );
282 QByteArray aWorkstackState = QByteArray::fromHex( aWorkstackInfo.toLatin1() );
283 aWorkstack->restoreState( aWorkstackState, 0 );
287 qApp->processEvents();
289 // C. Restore view properties (step 2).
290 // B. Restore active window. (currently doesn't work)
291 QString anActiveViewName = getVisualProperty( aPropertyMap, "AP_ACTIVE_VIEW" );
292 QMap<SUIT_ViewWindow*, QString>::Iterator aMapIter;
293 for( aMapIter = aViewParameters.begin(); aMapIter != aViewParameters.end(); ++aMapIter )
295 if( SUIT_ViewWindow* aViewWindow = aMapIter.key() )
297 aViewWindow->setVisualParameters( aMapIter.value() );
298 if( anActiveViewName == aViewWindow->objectName() )
300 aWorkstack->setActiveWindow( aViewWindow );
304 module()->update( UF_Viewer );
309 void HYDROGUI_VisualStateOp::nameViewWindows( const ViewManagerList& theList )
311 QMap<QString, int> aViewersCounter;
312 for( ViewManagerList::const_iterator anIter = theList.begin(); anIter != theList.end(); ++anIter )
314 SUIT_ViewManager* aViewManager = *anIter;
318 int aViewCount = aViewManager->getViewsCount();
319 QString aType = aViewManager->getType();
323 if( !aViewersCounter.contains( aType ) )
324 aViewersCounter.insert( aType, 0 );
326 int& aViewerId = aViewersCounter[ aType ];
328 QVector<SUIT_ViewWindow*> aViews = aViewManager->getViews();
329 for( int i = 0; i < aViewCount; i++ )
331 QString aName = QString( "%1_%2_%3" ).arg( aType ).arg( aViewerId ).arg( i );
332 aViews[i]->setObjectName( aName );
338 QString HYDROGUI_VisualStateOp::encodePropertyMap( const PropertyMap& thePropertyMap )
340 QStringList aPropertyDataStringList;
341 PropertyMapIterator anIter( thePropertyMap );
342 while( anIter.hasNext() )
344 QString aPropertyName = anIter.next().key();
345 QStringList aPropertyData = anIter.value();
347 if( !aPropertyData.isEmpty() )
349 aPropertyData.prepend( aPropertyName );
350 QString aPropertyDataString = aPropertyData.join( "||" );
351 aPropertyDataStringList.append( aPropertyDataString );
355 QString aResult = aPropertyDataStringList.join( "|||" );
359 HYDROGUI_VisualStateOp::PropertyMap
360 HYDROGUI_VisualStateOp::decodePropertyMap( const QString& theString )
362 PropertyMap aPropertyMap;
363 QStringList aPropertyDataStringList = theString.split( "|||" );
364 QStringListIterator anIter( aPropertyDataStringList );
365 while( anIter.hasNext() )
367 QString aPropertyDataString = anIter.next();
368 QStringList aPropertyData = aPropertyDataString.split( "||" );
369 if( aPropertyData.count() >= 2 )
371 QString aPropertyName = aPropertyData.front();
372 aPropertyData.pop_front();
373 aPropertyMap[ aPropertyName ] = aPropertyData;
379 void HYDROGUI_VisualStateOp::setVisualProperty( PropertyMap& thePropertyMap,
380 const QString& thePropertyName,
381 const QString& thePropertyData,
382 const bool theIsAppend )
384 QStringList& aPropertyDataList = thePropertyMap[ thePropertyName ];
386 aPropertyDataList.clear();
387 aPropertyDataList.append( thePropertyData );
390 QString HYDROGUI_VisualStateOp::getVisualProperty( const PropertyMap& thePropertyMap,
391 const QString& thePropertyName,
394 PropertyMap::const_iterator anIter = thePropertyMap.find( thePropertyName );
395 if( anIter != thePropertyMap.end() )
397 const QStringList aPropertyData = anIter.value();
398 if( theIndex >= 0 && theIndex < aPropertyData.count() )
399 return aPropertyData[ theIndex ];
404 int HYDROGUI_VisualStateOp::nbVisualProperties( const PropertyMap& thePropertyMap,
405 const QString& thePropertyName )
407 PropertyMap::const_iterator anIter = thePropertyMap.find( thePropertyName );
408 if( anIter != thePropertyMap.end() )
410 const QStringList aPropertyData = anIter.value();
411 return aPropertyData.count();