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_DataModel.h"
25 #include "HYDROGUI_DataObject.h"
26 #include "HYDROGUI_Module.h"
27 #include "HYDROGUI_Tool.h"
29 #include <HYDROData_Bathymetry.h>
30 #include <HYDROData_Calculation.h>
31 #include <HYDROData_Document.h>
32 #include <HYDROData_Image.h>
33 #include <HYDROData_Iterator.h>
34 #include <HYDROData_Polyline.h>
35 #include <HYDROData_VisualState.h>
36 #include <HYDROData_Zone.h>
38 #include <CAM_Application.h>
39 #include <CAM_DataObject.h>
40 #include <CAM_Module.h>
41 #include <CAM_Study.h>
43 #include <LightApp_Application.h>
44 #include <LightApp_DataObject.h>
45 #include <LightApp_Study.h>
47 #include <SUIT_DataObject.h>
48 #include <SUIT_DataBrowser.h>
49 #include <SUIT_ResourceMgr.h>
50 #include <SUIT_Study.h>
51 #include <SUIT_Tools.h>
53 #include <HYDROData_Document.h>
55 #include <TDF_Delta.hxx>
56 #include <TDF_ListIteratorOfDeltaList.hxx>
58 #include <QApplication>
61 static HYDROData_SequenceOfObjects myCopyingObjects;
63 HYDROGUI_DataModel::HYDROGUI_DataModel( CAM_Module* theModule )
64 : LightApp_DataModel( theModule )
66 update( module()->application()->activeStudy()->id() );
69 HYDROGUI_DataModel::~HYDROGUI_DataModel()
73 bool HYDROGUI_DataModel::open( const QString& theURL,
75 QStringList theFileList )
77 LightApp_DataModel::open( theURL, theStudy, theFileList );
78 const int aStudyId = theStudy->id();
80 Data_DocError res = DocError_UnknownProblem;
81 if( theFileList.count() == 2 )
83 QString aTmpDir = theFileList[0];
84 QString aFileName = theFileList[1];
87 QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + aFileName;
91 res = HYDROData_Document::Load( (char*)aFullPath.toLatin1().constData(), aStudyId );
95 res = DocError_UnknownProblem;
97 if( res != DocError_OK )
99 module()->application()->putInfo( tr( "LOAD_ERROR" ) );
104 // if the document open was successful, the data model update happens
105 // in the set mode of the module
106 if( res == DocError_OK )
112 bool HYDROGUI_DataModel::save( QStringList& theFileList )
114 if( !module()->application()->activeStudy() )
117 LightApp_DataModel::save( theFileList );
121 SUIT_ResourceMgr* resMgr = module()->application()->resourceMgr();
122 bool isMultiFile = false;
124 isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
126 // save data to temporary files
127 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
128 aTmpDir = aStudy->GetTmpDir( myStudyURL.toLatin1().constData(), isMultiFile ).c_str();
129 aFileName = SUIT_Tools::file( myStudyURL, false ) + "_HYDRO.cbf";
131 QString aFullPath = aTmpDir + aFileName;
132 Data_DocError res = getDocument()->Save( (char*)aFullPath.toLatin1().constData() );
133 if( res != DocError_OK )
135 module()->application()->putInfo( tr( "SAVE_ERROR" ) );
139 theFileList.append( aTmpDir );
140 theFileList.append( aFileName );
145 bool HYDROGUI_DataModel::saveAs( const QString& theURL,
147 QStringList& theFileList )
150 return save( theFileList );
153 bool HYDROGUI_DataModel::close()
158 bool HYDROGUI_DataModel::dumpPython( const QString& theURL,
161 QStringList& theListOfFiles )
163 LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles );
165 int aStudyId = theStudy->id();
167 LightApp_Study* aStudy = ::qobject_cast<LightApp_Study*>( theStudy );
168 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( aStudyId );
169 if ( aDocument.IsNull() || !aStudy )
172 QString aFileToExport = aStudy->GetTmpDir( theURL.toLatin1().constData(), isMultiFile ).c_str();
173 aFileToExport += QString( QDir::separator() ) + "HYDRO.py";
175 bool aRes = aDocument->DumpToPython( aFileToExport );
179 theListOfFiles.append( aFileToExport );
185 bool HYDROGUI_DataModel::isModified() const
187 return getDocument()->IsModified();
190 bool HYDROGUI_DataModel::isSaved() const
195 void HYDROGUI_DataModel::update( const int theStudyId )
197 LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
201 SUIT_DataObject* aStudyRoot = anApp->activeStudy()->root();
205 // create root object if not exist
206 CAM_DataObject* aRootObj = root();
208 aRootObj = createRootModuleObject( aStudyRoot );
213 DataObjectList aList;
214 aRootObj->children( aList );
215 QListIterator<SUIT_DataObject*> anIter( aList );
216 while( anIter.hasNext() )
217 removeChild( aRootObj, anIter.next() );
219 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( theStudyId );
220 if( aDocument.IsNull() )
223 LightApp_DataObject* anImageRootObj = createObject( aRootObj, partitionName( KIND_IMAGE ) );
225 HYDROData_Iterator anIterator( aDocument, KIND_IMAGE );
226 for( ; anIterator.More(); anIterator.Next() )
228 Handle(HYDROData_Image) anImageObj =
229 Handle(HYDROData_Image)::DownCast( anIterator.Current() );
230 if( !anImageObj.IsNull() )
231 createObject( anImageRootObj, anImageObj );
234 LightApp_DataObject* aBathymetryRootObj = createObject( aRootObj, partitionName( KIND_BATHYMETRY ) );
236 anIterator = HYDROData_Iterator( aDocument, KIND_BATHYMETRY );
237 for( ; anIterator.More(); anIterator.Next() )
239 Handle(HYDROData_Bathymetry) aBathymetryObj =
240 Handle(HYDROData_Bathymetry)::DownCast( anIterator.Current() );
241 if( !aBathymetryObj.IsNull() )
242 createObject( aBathymetryRootObj, aBathymetryObj );
245 LightApp_DataObject* aCalculRootObj = createObject( aRootObj, partitionName( KIND_CALCULATION ) );
247 anIterator = HYDROData_Iterator( aDocument, KIND_CALCULATION );
248 for( ; anIterator.More(); anIterator.Next() )
250 Handle(HYDROData_Calculation) aCalculObj =
251 Handle(HYDROData_Calculation)::DownCast( anIterator.Current() );
252 if( !aCalculObj.IsNull() )
253 createObject( aCalculRootObj, aCalculObj );
256 LightApp_DataObject* aPolylineRootObj = createObject( aRootObj, partitionName( KIND_POLYLINE ) );
258 anIterator = HYDROData_Iterator( aDocument, KIND_POLYLINE );
259 for( ; anIterator.More(); anIterator.Next() )
261 Handle(HYDROData_Polyline) aPolylineObj =
262 Handle(HYDROData_Polyline)::DownCast( anIterator.Current() );
263 if( !aPolylineObj.IsNull() )
264 createObject( aPolylineRootObj, aPolylineObj );
267 LightApp_DataObject* aZonesRootObj = createObject( aRootObj, partitionName( KIND_ZONE ) );
269 anIterator = HYDROData_Iterator( aDocument, KIND_ZONE );
270 for( ; anIterator.More(); anIterator.Next() )
272 Handle(HYDROData_Zone) aZoneObj =
273 Handle(HYDROData_Zone)::DownCast( anIterator.Current() );
274 if( !aZoneObj.IsNull() )
275 createObject( aZonesRootObj, aZoneObj );
278 LightApp_DataObject* aVisualStateRootObj = createObject( aRootObj, partitionName( KIND_VISUAL_STATE ) );
280 anIterator = HYDROData_Iterator( aDocument, KIND_VISUAL_STATE );
281 for( ; anIterator.More(); anIterator.Next() )
283 Handle(HYDROData_VisualState) aVisualStateObj =
284 Handle(HYDROData_VisualState)::DownCast( anIterator.Current() );
285 if( !aVisualStateObj.IsNull() )
286 createObject( aVisualStateRootObj, aVisualStateObj );
289 if( SUIT_DataBrowser* anObjectBrowser = anApp->objectBrowser() )
291 anObjectBrowser->setAutoOpenLevel( 3 );
292 anObjectBrowser->openLevels();
296 HYDROGUI_DataObject* HYDROGUI_DataModel::getDataObject( const Handle(HYDROData_Object)& theModelObject )
298 return NULL; // to do if necessary
301 HYDROGUI_DataObject* HYDROGUI_DataModel::getReferencedDataObject( HYDROGUI_DataObject* theObject )
303 return NULL; // to do if necessary
306 SUIT_DataObject* HYDROGUI_DataModel::findObject( const QString& theEntry ) const
308 LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
309 return anApp ? anApp->findObject( theEntry ) : 0;
312 void HYDROGUI_DataModel::update( LightApp_DataObject* theObject,
313 LightApp_Study* theStudy )
316 theStudy = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy()) ;
318 update( theStudy->id() );
321 CAM_DataObject* HYDROGUI_DataModel::createRootModuleObject( SUIT_DataObject* theParent )
323 CAM_DataObject* aRootObj = createModuleObject( theParent );
328 void HYDROGUI_DataModel::updateModel()
330 HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
332 update( aModule->getStudyId() );
335 Handle(HYDROData_Object) HYDROGUI_DataModel::objectByEntry( const QString& theEntry,
336 const ObjectKind theObjectKind )
338 QString anEntry = theEntry;
339 if( anEntry.indexOf( "_" ) != -1 ) // reference object
340 anEntry = anEntry.section( "_", -1 );
342 Handle(HYDROData_Document) aDocument = getDocument();
343 if( !aDocument.IsNull() )
345 HYDROData_Iterator anIterator( aDocument, theObjectKind );
346 for( ; anIterator.More(); anIterator.Next() )
348 Handle(HYDROData_Object) anObject = anIterator.Current();
349 if( !anObject.IsNull() )
351 QString anEntryRef = HYDROGUI_DataObject::dataObjectEntry( anObject );
352 if( anEntryRef == anEntry )
360 bool HYDROGUI_DataModel::canUndo() const
362 return getDocument()->CanUndo();
365 bool HYDROGUI_DataModel::canRedo() const
367 return getDocument()->CanRedo();
370 QStringList HYDROGUI_DataModel::undoNames() const
373 for( TDF_ListIteratorOfDeltaList anIter( getDocument()->GetUndos() ); anIter.More(); anIter.Next() )
374 aNames.prepend( HYDROGUI_Tool::ToQString( anIter.Value()->Name() ) );
378 QStringList HYDROGUI_DataModel::redoNames() const
381 for( TDF_ListIteratorOfDeltaList anIter( getDocument()->GetRedos() ); anIter.More(); anIter.Next() )
382 aNames.append( HYDROGUI_Tool::ToQString( anIter.Value()->Name() ) );
386 void HYDROGUI_DataModel::clearUndos()
388 getDocument()->ClearUndos();
391 void HYDROGUI_DataModel::clearRedos()
393 getDocument()->ClearRedos();
396 bool HYDROGUI_DataModel::undo()
400 getDocument()->Undo();
402 catch ( Standard_Failure )
409 bool HYDROGUI_DataModel::redo()
413 getDocument()->Redo();
415 catch ( Standard_Failure )
422 bool HYDROGUI_DataModel::canCopy()
424 HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( (HYDROGUI_Module*)module() );
425 if( aSeq.Length() != 1 )
428 Handle(HYDROData_Object) anObject = aSeq.First();
429 if( anObject.IsNull() )
432 ObjectKind aKind = anObject->GetKind();
433 if( aKind == KIND_IMAGE ||
434 aKind == KIND_POLYLINE ||
435 aKind == KIND_CALCULATION )
441 bool HYDROGUI_DataModel::canPaste()
443 for( int anIndex = 1, aLength = myCopyingObjects.Length(); anIndex <= aLength; anIndex++ )
445 Handle(HYDROData_Object) anObject = myCopyingObjects.Value( anIndex );
446 if( !anObject.IsNull() && !anObject->IsRemoved() )
452 bool HYDROGUI_DataModel::copy()
454 HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( (HYDROGUI_Module*)module() );
455 changeCopyingObjects( aSeq );
459 bool HYDROGUI_DataModel::paste()
461 bool anIsChanged = false;
462 for( int anIndex = 1, aLength = myCopyingObjects.Length(); anIndex <= aLength; anIndex++ )
464 Handle(HYDROData_Object) anObject = myCopyingObjects.Value( anIndex );
465 if( !anObject.IsNull() && !anObject->IsRemoved() )
467 ObjectKind aKind = anObject->GetKind();
468 Handle(HYDROData_Object) aClone = getDocument()->CreateObject( aKind );
469 if( !aClone.IsNull() )
471 anObject->CopyTo( aClone );
474 // generate a new unique name for the clone object:
475 // case 1: Image_1 -> Image_2
476 // case 2: ImageObj -> ImageObj_1
477 QString aName = aClone->GetName();
478 QString aPrefix = aName;
479 if( aName.contains( '_' ) ) // case 1
481 QString aSuffix = aName.section( '_', -1 );
482 bool anIsInteger = false;
483 aSuffix.toInt( &anIsInteger );
485 aPrefix = aName.section( '_', 0, -2 );
489 aName = HYDROGUI_Tool::GenerateObjectName( (HYDROGUI_Module*)module(), aPrefix );
490 aClone->SetName( aName );
497 void HYDROGUI_DataModel::changeCopyingObjects( const HYDROData_SequenceOfObjects& theSeq )
499 myCopyingObjects.Assign( theSeq );
502 QString HYDROGUI_DataModel::partitionName( const ObjectKind theObjectKind )
504 switch( theObjectKind )
506 case KIND_IMAGE: return "IMAGES";
507 case KIND_POLYLINE: return "POLYLINES";
508 case KIND_VISUAL_STATE: return "VISUAL_STATES";
509 case KIND_BATHYMETRY: return "BATHYMETRIES";
510 case KIND_CALCULATION: return "CALCULATION_CASES";
511 case KIND_ZONE: return "ZONES";
517 Handle(HYDROData_Document) HYDROGUI_DataModel::getDocument() const
519 int aStudyId = module()->application()->activeStudy()->id();
520 return HYDROData_Document::Document( aStudyId );
523 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject* theParent,
524 Handle(HYDROData_Object) theModelObject,
525 const QString& theParentEntry )
527 HYDROGUI_DataObject* aResObj =
528 new HYDROGUI_DataObject( theParent, theModelObject, theParentEntry );
529 buildObjectTree( theParent, aResObj, theParentEntry );
533 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject* theParent,
534 const QString& theName,
535 const QString& theParentEntry )
537 return new HYDROGUI_NamedObject( theParent, theName, theParentEntry );
540 void HYDROGUI_DataModel::buildObjectTree( SUIT_DataObject* theParent,
541 SUIT_DataObject* theObject,
542 const QString& theParentEntry )
544 HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>( theObject );
548 Handle(HYDROData_Object) aDataObj = aGuiObj->modelObject();
549 if ( aDataObj.IsNull() )
552 ObjectKind anObjectKind = aDataObj->GetKind();
554 if ( anObjectKind == KIND_IMAGE )
556 Handle(HYDROData_Image) anImageObj =
557 Handle(HYDROData_Image)::DownCast( aDataObj );
558 for ( int anIndex = 0, aNbRef = anImageObj->NbReferences(); anIndex < aNbRef; anIndex++ )
560 Handle(HYDROData_Object) aRefObj = anImageObj->Reference( anIndex );
561 if ( !aRefObj.IsNull() && !aRefObj->IsRemoved() )
562 createObject( aGuiObj, aRefObj, aGuiObj->entry() );
565 else if ( anObjectKind == KIND_ZONE )
567 Handle(HYDROData_Zone) aZoneObj =
568 Handle(HYDROData_Zone)::DownCast( aDataObj );
570 LightApp_DataObject* aPolylineSect = createObject( aGuiObj, tr( "ZONE_POLYLINE" ), aGuiObj->entry() );
572 Handle(HYDROData_Polyline) aPolyline = aZoneObj->GetPolyline();
573 if ( !aPolyline.IsNull() && !aPolyline->IsRemoved() )
574 createObject( aPolylineSect, aPolyline, aGuiObj->entry() );
576 LightApp_DataObject* aBathsSect = createObject( aGuiObj, tr( "ZONE_BATHYMETRIES" ), aGuiObj->entry() );
578 HYDROData_SequenceOfObjects aZoneBaths = aZoneObj->GetBathymetries();
579 HYDROData_SequenceOfObjects::Iterator aBathsIter( aZoneBaths );
580 for ( ; aBathsIter.More(); aBathsIter.Next() )
582 Handle(HYDROData_Bathymetry) aRefBath =
583 Handle(HYDROData_Bathymetry)::DownCast( aBathsIter.Value() );
584 if( !aRefBath.IsNull() && !aRefBath->IsRemoved() )
585 createObject( aBathsSect, aRefBath, aGuiObj->entry() );
590 void HYDROGUI_DataModel::removeChild( SUIT_DataObject* theParent,
591 SUIT_DataObject* theChild )
593 SUIT_DataObject* aSubChild = theChild->firstChild();
594 for( ; aSubChild; aSubChild = aSubChild->nextBrother() )
595 removeChild( theChild, aSubChild );
596 theParent->removeChild( theChild );
599 SUIT_DataObject* HYDROGUI_DataModel::findChildByName( const SUIT_DataObject* theFather,
600 const QString& theName )
602 SUIT_DataObject* aChild = theFather->firstChild();
605 if( aChild->name() == theName )
606 return aChild; // found
607 aChild = aChild->nextBrother();
609 return NULL; // not found