Salome HOME
Fix for the bug #45: check and warning when the same image is used in 2 arguments.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_DataModel.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_DataModel.h"
24
25 #include "HYDROGUI_DataObject.h"
26 #include "HYDROGUI_Module.h"
27 #include "HYDROGUI_Tool.h"
28 #include "HYDROGUI_Zone.h"
29 #include "HYDROGUI_Region.h"
30
31 #include <HYDROData_Bathymetry.h>
32 #include <HYDROData_CalculationCase.h>
33 #include <HYDROData_Document.h>
34 #include <HYDROData_Image.h>
35 #include <HYDROData_ImmersibleZone.h>
36 #include <HYDROData_Iterator.h>
37 #include <HYDROData_Polyline3D.h>
38 #include <HYDROData_PolylineXY.h>
39 #include <HYDROData_Profile.h>
40 #include <HYDROData_VisualState.h>
41 #include <HYDROData_Region.h>
42 #include <HYDROData_Zone.h>
43 #include <HYDROData_Obstacle.h>
44 #include <HYDROData_Channel.h>
45 #include <HYDROData_Digue.h>
46 #include <HYDROData_River.h>
47 #include <HYDROData_Stream.h>
48
49 #include <CAM_Application.h>
50 #include <CAM_DataObject.h>
51 #include <CAM_Module.h>
52 #include <CAM_Study.h>
53
54 #include <LightApp_Application.h>
55 #include <LightApp_DataObject.h>
56 #include <LightApp_Study.h>
57
58 #include <SUIT_DataObject.h>
59 #include <SUIT_DataBrowser.h>
60 #include <SUIT_ResourceMgr.h>
61 #include <SUIT_Study.h>
62 #include <SUIT_Tools.h>
63
64 #include <HYDROData_Document.h>
65
66 #include <TDF_Delta.hxx>
67 #include <TDF_ListIteratorOfDeltaList.hxx>
68
69 #include <QApplication>
70 #include <QDir>
71
72 static HYDROData_SequenceOfObjects myCopyingObjects;
73
74 HYDROGUI_DataModel::HYDROGUI_DataModel( CAM_Module* theModule )
75 : LightApp_DataModel( theModule )
76 {
77   update( module()->application()->activeStudy()->id() );
78 }
79
80 HYDROGUI_DataModel::~HYDROGUI_DataModel()
81 {
82 }
83
84 bool HYDROGUI_DataModel::open( const QString& theURL,
85                                CAM_Study* theStudy,
86                                QStringList theFileList )
87 {
88   LightApp_DataModel::open( theURL, theStudy, theFileList );
89   const int aStudyId = theStudy->id();
90
91   Data_DocError res = DocError_UnknownProblem;
92   if( theFileList.count() == 2 )
93   {
94     QString aTmpDir = theFileList[0];
95     QString aFileName = theFileList[1];
96
97     myStudyURL = theURL;
98     QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + aFileName;
99
100     try
101     {
102       res = HYDROData_Document::Load( (char*)aFullPath.toLatin1().constData(), aStudyId );
103     }
104     catch(...)
105     {
106       res = DocError_UnknownProblem;
107     }
108     if( res != DocError_OK )
109     {
110       module()->application()->putInfo( tr( "LOAD_ERROR" ) );
111       return false;
112     }
113   }
114
115   // if the document open was successful, the data model update happens
116   // in the set mode of the module
117   if( res == DocError_OK )
118     update( aStudyId );
119
120   return true;
121 }
122
123 bool HYDROGUI_DataModel::save( QStringList& theFileList )
124 {
125   if( !module()->application()->activeStudy() )
126     return false;
127   
128   LightApp_DataModel::save( theFileList );
129
130   QString aTmpDir;
131   QString aFileName;
132   SUIT_ResourceMgr* resMgr = module()->application()->resourceMgr();
133   bool isMultiFile = false;
134   if( resMgr )
135     isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
136
137   // save data to temporary files
138   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
139   aTmpDir = aStudy->GetTmpDir( myStudyURL.toLatin1().constData(), isMultiFile ).c_str();
140   aFileName = SUIT_Tools::file( myStudyURL, false ) + "_HYDRO.cbf";
141
142   QString aFullPath = aTmpDir + aFileName;
143   Data_DocError res = getDocument()->Save( (char*)aFullPath.toLatin1().constData() );
144   if( res != DocError_OK )
145   {
146     module()->application()->putInfo( tr( "SAVE_ERROR" ) );
147     return false;
148   }
149
150   theFileList.append( aTmpDir );
151   theFileList.append( aFileName );
152
153   return true;
154 }
155
156 bool HYDROGUI_DataModel::saveAs( const QString& theURL,
157                                  CAM_Study*,
158                                  QStringList& theFileList )
159 {
160   myStudyURL = theURL;
161   return save( theFileList );
162 }
163
164 bool HYDROGUI_DataModel::close()
165 {
166   return true;
167 }
168
169 bool HYDROGUI_DataModel::dumpPython( const QString& theURL,
170                                      CAM_Study*     theStudy,
171                                      bool           isMultiFile,
172                                      QStringList&   theListOfFiles )
173 {
174   LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles );
175
176   int aStudyId = theStudy->id();
177
178   LightApp_Study* aStudy = ::qobject_cast<LightApp_Study*>( theStudy );
179   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( aStudyId );
180   if ( aDocument.IsNull() || !aStudy )
181     return false;
182
183   QString aFileToExport = aStudy->GetTmpDir( theURL.toLatin1().constData(), isMultiFile ).c_str();
184   aFileToExport += QString( QDir::separator() ) + "HYDRO.py";
185
186   bool aRes = aDocument->DumpToPython( aFileToExport );
187
188   if ( aRes )
189   {
190     theListOfFiles.append( aFileToExport );
191   }
192
193   return aRes;
194 }
195
196 bool HYDROGUI_DataModel::isModified() const
197 {
198   return getDocument()->IsModified();
199 }
200
201 bool HYDROGUI_DataModel::isSaved() const
202 {
203   return true;
204 }
205
206 void HYDROGUI_DataModel::update( const int theStudyId )
207 {
208   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
209   if( !anApp )
210     return;
211
212   SUIT_DataObject* aStudyRoot = anApp->activeStudy()->root();
213   if( !aStudyRoot )
214     return;
215
216   // create root object if not exist
217   CAM_DataObject* aRootObj = root();
218   if( !aRootObj )
219     aRootObj = createRootModuleObject( aStudyRoot );
220
221   if( !aRootObj )
222     return;
223
224   DataObjectList aList;
225   aRootObj->children( aList );
226   QListIterator<SUIT_DataObject*> anIter( aList );
227   while( anIter.hasNext() )
228     removeChild( aRootObj, anIter.next() );
229
230   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( theStudyId );
231   if( aDocument.IsNull() )
232     return;
233
234   // Create root objects:
235
236   // IMAGES
237   LightApp_DataObject* anImageRootObj = createObject( aRootObj, tr( partitionName( KIND_IMAGE ).toAscii() ) );
238
239   // BATHYMETRY
240   LightApp_DataObject* aBathymetryRootObj = createObject( aRootObj, tr( partitionName( KIND_BATHYMETRY ).toAscii() ) );
241
242   // ARTIFICIAL OBJECTS
243   LightApp_DataObject* anArtificialObjectsRootObj = createObject( aRootObj, tr( partitionName( KIND_ARTIFICIAL_OBJECT ).toAscii() ) );
244
245   // NATURAL OBJECTS
246   LightApp_DataObject* aNaturalObjectsRootObj = createObject( aRootObj, tr( partitionName( KIND_NATURAL_OBJECT ).toAscii() ) );
247
248   // OBSTACLES
249   LightApp_DataObject* anObstaclesRootObj = createObject( aRootObj, tr( partitionName( KIND_OBSTACLE ).toAscii() ) );
250
251   // CALCULATION CASES
252   LightApp_DataObject* aCalculRootObj = createObject( aRootObj, tr( partitionName( KIND_CALCULATION ).toAscii() ) );
253
254   // POLYLINES
255   LightApp_DataObject* aPolylineRootObj = createObject( aRootObj, tr( partitionName( KIND_POLYLINEXY ).toAscii() ) );
256
257   // POLYLINES
258   LightApp_DataObject* aPolyline3DRootObj = createObject( aRootObj, tr( partitionName( KIND_POLYLINE ).toAscii() ) );
259
260   // PROFILES
261   LightApp_DataObject* aProfileRootObj = createObject( aRootObj, tr( partitionName( KIND_PROFILE ).toAscii() ) );
262
263   // VISUAL STATES
264   LightApp_DataObject* aVisualStateRootObj = createObject( aRootObj, tr( partitionName( KIND_VISUAL_STATE ).toAscii() ) );
265
266   HYDROData_Iterator anIterator( aDocument, KIND_UNKNOWN );
267   for( ; anIterator.More(); anIterator.Next() ) {
268     Handle(HYDROData_Entity) anObj = anIterator.Current();
269
270     if ( !anObj.IsNull() )
271     {
272       switch ( anObj->GetKind() ) {
273         case KIND_IMAGE:
274         {
275           Handle(HYDROData_Image) anImageObj =
276             Handle(HYDROData_Image)::DownCast( anObj );
277           if( !anImageObj.IsNull() ) {
278             createObject( anImageRootObj, anImageObj );
279           }
280
281           break;
282         }
283         case KIND_BATHYMETRY:
284         {
285           Handle(HYDROData_Bathymetry) aBathymetryObj =
286             Handle(HYDROData_Bathymetry)::DownCast( anObj );
287           if( !aBathymetryObj.IsNull() ) {
288             createObject( aBathymetryRootObj, aBathymetryObj );
289           }
290
291           break;
292         }
293         case KIND_CHANNEL:
294         {
295           Handle(HYDROData_Channel) aChannelObj =
296             Handle(HYDROData_Channel)::DownCast( anObj );
297           if( !aChannelObj.IsNull() ) {
298             createObject( anArtificialObjectsRootObj, aChannelObj );
299           }
300
301           break;
302         }
303         case KIND_DIGUE:
304         {
305           Handle(HYDROData_Digue) aDigueObj =
306             Handle(HYDROData_Digue)::DownCast( anObj );
307           if( !aDigueObj.IsNull() ) {
308             createObject( anArtificialObjectsRootObj, aDigueObj );
309           }
310
311           break;
312         }
313         case KIND_IMMERSIBLE_ZONE:
314         {
315           Handle(HYDROData_ImmersibleZone) anImmersibleZoneObj =
316             Handle(HYDROData_ImmersibleZone)::DownCast( anObj );
317           if( !anImmersibleZoneObj.IsNull() ) {
318             createObject( aNaturalObjectsRootObj, anImmersibleZoneObj );
319           }
320
321           break;
322         }
323         case KIND_RIVER:
324         {
325           Handle(HYDROData_River) aRiverObj =
326             Handle(HYDROData_River)::DownCast( anObj );
327           if( !aRiverObj.IsNull() ) {
328             createObject( aNaturalObjectsRootObj, aRiverObj );
329           }
330
331           break;
332         }
333         case KIND_STREAM:
334         {
335           Handle(HYDROData_Stream) aStreamObj =
336             Handle(HYDROData_Stream)::DownCast( anObj );
337           if( !aStreamObj.IsNull() ) {
338             createObject( aNaturalObjectsRootObj, aStreamObj );
339           }
340
341           break;
342         }
343         case KIND_OBSTACLE:
344         {
345           Handle(HYDROData_Obstacle) anObstacleObj =
346             Handle(HYDROData_Obstacle)::DownCast( anObj );
347           if( !anObstacleObj.IsNull() ) {
348             createObject( anObstaclesRootObj, anObstacleObj );
349           }
350
351           break;
352         }
353         case KIND_CALCULATION:
354         {
355           Handle(HYDROData_CalculationCase) aCalculObj =
356             Handle(HYDROData_CalculationCase)::DownCast( anObj );
357           if( !aCalculObj.IsNull() ) {
358             createObject( aCalculRootObj, aCalculObj );
359           }
360
361           break;
362         }
363         case KIND_POLYLINEXY:
364         {
365           Handle(HYDROData_PolylineXY) aPolylineObj =
366             Handle(HYDROData_PolylineXY)::DownCast( anObj );
367           if( !aPolylineObj.IsNull() ) {
368             createObject( aPolylineRootObj, aPolylineObj );
369           }
370
371           break;
372         }
373         case KIND_POLYLINE:
374         {
375           Handle(HYDROData_Polyline3D) aPolylineObj =
376             Handle(HYDROData_Polyline3D)::DownCast( anObj );
377           if( !aPolylineObj.IsNull() ) {
378             createObject( aPolyline3DRootObj, aPolylineObj );
379           }
380
381           break;
382         }
383         case KIND_PROFILE:
384         {
385           Handle(HYDROData_Profile) aProfileObj =
386             Handle(HYDROData_Profile)::DownCast( anObj );
387           if( !aProfileObj.IsNull() ) {
388             createObject( aProfileRootObj, aProfileObj );
389           }
390
391           break;
392         }
393         case KIND_VISUAL_STATE:
394         {
395           Handle(HYDROData_VisualState) aVisualStateObj =
396             Handle(HYDROData_VisualState)::DownCast( anObj );
397           if( !aVisualStateObj.IsNull() ) {
398             createObject( aVisualStateRootObj, aVisualStateObj );
399           }
400
401           break;
402         }
403       }
404     }
405   }
406
407   if( SUIT_DataBrowser* anObjectBrowser = anApp->objectBrowser() )
408   {
409     anObjectBrowser->setAutoOpenLevel( 3 );
410     anObjectBrowser->openLevels();
411   }
412 }
413
414 HYDROGUI_DataObject* HYDROGUI_DataModel::getDataObject( const Handle(HYDROData_Entity)& theModelObject )
415 {
416   return NULL; // to do if necessary
417 }
418
419 HYDROGUI_DataObject* HYDROGUI_DataModel::getReferencedDataObject( HYDROGUI_DataObject* theObject )
420 {
421   return NULL; // to do if necessary
422 }
423
424 SUIT_DataObject* HYDROGUI_DataModel::findObject( const QString& theEntry ) const
425 {
426   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
427   return anApp ? anApp->findObject( theEntry ) : 0;
428 }
429
430 void HYDROGUI_DataModel::update( LightApp_DataObject* theObject,
431                                  LightApp_Study* theStudy )
432 {
433   if( !theStudy )
434     theStudy = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy()) ;
435   if( theStudy )
436     update( theStudy->id() );
437 }
438
439 CAM_DataObject* HYDROGUI_DataModel::createRootModuleObject( SUIT_DataObject* theParent )
440 {
441   CAM_ModuleObject* aRootObj = createModuleObject( theParent );
442   aRootObj->setDataModel( this );
443   setRoot( aRootObj );
444   return aRootObj;
445 }
446
447 void HYDROGUI_DataModel::updateModel()
448 {
449   HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
450   if( aModule )
451     update( aModule->getStudyId() );
452 }
453
454 Handle(HYDROData_Entity) HYDROGUI_DataModel::objectByEntry( const QString& theEntry,
455                                                             const ObjectKind theObjectKind )
456 {
457   QString anEntry = theEntry;
458   if( anEntry.indexOf( "_" ) != -1 ) // reference object
459     anEntry = anEntry.section( "_", -1 );
460
461   Handle(HYDROData_Document) aDocument = getDocument();
462   if( !aDocument.IsNull() )
463   {
464     HYDROData_Iterator anIterator( aDocument, theObjectKind );
465     for( ; anIterator.More(); anIterator.Next() )
466     {
467       Handle(HYDROData_Entity) anObject = anIterator.Current();
468       if( !anObject.IsNull() )
469       {
470         QString anEntryRef = HYDROGUI_DataObject::dataObjectEntry( anObject );
471         if( anEntryRef == anEntry )
472           return anObject;
473       }
474     }
475   }
476   return NULL;
477 }
478
479 bool HYDROGUI_DataModel::canUndo() const
480 {
481   return getDocument()->CanUndo();
482 }
483
484 bool HYDROGUI_DataModel::canRedo() const
485 {
486   return getDocument()->CanRedo();
487 }
488
489 QStringList HYDROGUI_DataModel::undoNames() const
490 {
491   QStringList aNames;
492   for( TDF_ListIteratorOfDeltaList anIter( getDocument()->GetUndos() ); anIter.More(); anIter.Next() )
493     aNames.prepend( HYDROGUI_Tool::ToQString( anIter.Value()->Name() ) );
494   return aNames;
495 }
496
497 QStringList HYDROGUI_DataModel::redoNames() const
498 {
499   QStringList aNames;
500   for( TDF_ListIteratorOfDeltaList anIter( getDocument()->GetRedos() ); anIter.More(); anIter.Next() )
501     aNames.append( HYDROGUI_Tool::ToQString( anIter.Value()->Name() ) );
502   return aNames;
503 }
504
505 void HYDROGUI_DataModel::clearUndos()
506 {
507   getDocument()->ClearUndos();
508 }
509
510 void HYDROGUI_DataModel::clearRedos()
511 {
512   getDocument()->ClearRedos();
513 }
514
515 bool HYDROGUI_DataModel::undo()
516 {
517   try 
518   {
519     getDocument()->Undo();
520   }
521   catch ( Standard_Failure )
522   {
523     return false;
524   }
525   return true;
526 }
527
528 bool HYDROGUI_DataModel::redo()
529 {
530   try 
531   {
532     getDocument()->Redo();
533   }
534   catch ( Standard_Failure )
535   {
536     return false;
537   }
538   return true;
539 }
540
541 bool HYDROGUI_DataModel::canCopy()
542 {
543   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( (HYDROGUI_Module*)module() );
544   if( aSeq.Length() != 1 )
545     return false;
546
547   Handle(HYDROData_Entity) anObject = aSeq.First();
548   if( anObject.IsNull() )
549     return false;
550
551   ObjectKind aKind = anObject->GetKind();
552   if( aKind == KIND_IMAGE ||
553       aKind == KIND_POLYLINE ||
554       aKind == KIND_PROFILE ||
555       aKind == KIND_CALCULATION )
556     return true;
557
558   return false;
559 }
560
561 bool HYDROGUI_DataModel::canPaste()
562 {
563   for( int anIndex = 1, aLength = myCopyingObjects.Length(); anIndex <= aLength; anIndex++ )
564   {
565     Handle(HYDROData_Entity) anObject = myCopyingObjects.Value( anIndex );
566     if( !anObject.IsNull() && !anObject->IsRemoved() )
567       return true;
568   }
569   return false;
570 }
571
572 bool HYDROGUI_DataModel::copy()
573 {
574   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( (HYDROGUI_Module*)module() );
575   changeCopyingObjects( aSeq );
576   return true;
577 }
578
579 bool HYDROGUI_DataModel::paste()
580 {
581   bool anIsChanged = false;
582   for( int anIndex = 1, aLength = myCopyingObjects.Length(); anIndex <= aLength; anIndex++ )
583   {
584     Handle(HYDROData_Entity) anObject = myCopyingObjects.Value( anIndex );
585     if( !anObject.IsNull() && !anObject->IsRemoved() )
586     {
587       ObjectKind aKind = anObject->GetKind();
588       Handle(HYDROData_Entity) aClone = getDocument()->CreateObject( aKind );
589       if( !aClone.IsNull() )
590       {
591         anObject->CopyTo( aClone );
592         anIsChanged = true;
593
594         // generate a new unique name for the clone object:
595         // case 1: Image_1 -> Image_2
596         // case 2: ImageObj -> ImageObj_1
597         QString aName = aClone->GetName();
598         QString aPrefix = aName;
599         if( aName.contains( '_' ) ) // case 1
600         {
601           QString aSuffix = aName.section( '_', -1 );
602           bool anIsInteger = false;
603           aSuffix.toInt( &anIsInteger );
604           if( anIsInteger )
605             aPrefix = aName.section( '_', 0, -2 );
606         }
607         else // case 2
608           aPrefix = aName;
609         aName = HYDROGUI_Tool::GenerateObjectName( (HYDROGUI_Module*)module(), aPrefix );
610         aClone->SetName( aName );
611       }
612     }
613   }
614   return anIsChanged;
615 }
616
617 void HYDROGUI_DataModel::changeCopyingObjects( const HYDROData_SequenceOfObjects& theSeq )
618 {
619   myCopyingObjects.Assign( theSeq );
620 }
621
622 QString HYDROGUI_DataModel::partitionName( const ObjectKind theObjectKind )
623 {
624   switch( theObjectKind )
625   {
626     case KIND_IMAGE:             return "IMAGES";
627     case KIND_POLYLINE:          return "POLYLINES_3D";
628     case KIND_POLYLINEXY:        return "POLYLINES";
629     case KIND_PROFILE:           return "PROFILES";
630     case KIND_VISUAL_STATE:      return "VISUAL_STATES";
631     case KIND_BATHYMETRY:        return "BATHYMETRIES";
632     case KIND_CALCULATION:       return "CALCULATION_CASES";
633     case KIND_OBSTACLE:          return "OBSTACLES";
634     case KIND_ARTIFICIAL_OBJECT: return "ARTIFICIAL_OBJECTS";
635     case KIND_NATURAL_OBJECT:    return "NATURAL_OBJECTS";
636     default: break;
637   }
638   return QString();
639 }
640
641 Handle(HYDROData_Document) HYDROGUI_DataModel::getDocument() const
642 {
643   int aStudyId = module()->application()->activeStudy()->id();
644   return HYDROData_Document::Document( aStudyId );
645 }
646
647 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject*         theParent,
648                                                        Handle(HYDROData_Entity) theModelObject,
649                                                        const QString&           theParentEntry,
650                                                        const bool               theIsBuildTree )
651 {
652   HYDROGUI_DataObject* aResObj = new HYDROGUI_DataObject( theParent, theModelObject, theParentEntry );
653   
654   if ( theIsBuildTree )
655   {
656     buildObjectTree( theParent, aResObj, theParentEntry );
657   }
658
659   return aResObj;
660 }
661
662 LightApp_DataObject* HYDROGUI_DataModel::buildObject( SUIT_DataObject*     theParent,
663                                                       HYDROGUI_DataObject* theObject,
664                                                       const QString&       theParentEntry,
665                                                       const bool           theIsBuildTree )
666 {
667   if ( theIsBuildTree )
668   {
669     buildObjectTree( theParent, theObject, theParentEntry );
670   }
671   return theObject;
672 }
673
674 LightApp_DataObject* HYDROGUI_DataModel::createZone( SUIT_DataObject*       theParent,
675                                                      Handle(HYDROData_Zone) theModelObject,
676                                                      const QString&         theParentEntry,
677                                                      const bool             theIsBuildTree )
678 {
679   return buildObject( theParent, new HYDROGUI_Zone( theParent, theModelObject, theParentEntry ), theParentEntry, theIsBuildTree );
680 }
681
682 LightApp_DataObject* HYDROGUI_DataModel::createRegion( SUIT_DataObject*         theParent,
683                                                        Handle(HYDROData_Region) theModelObject,
684                                                        const QString&           theParentEntry,
685                                                        const bool               theIsBuildTree )
686 {
687   return buildObject( theParent, new HYDROGUI_Region( theParent, theModelObject, theParentEntry ), theParentEntry, theIsBuildTree );
688 }
689
690 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject* theParent,
691                                                        const QString&   theName,
692                                                        const QString&   theParentEntry )
693 {
694   return new HYDROGUI_NamedObject( theParent, theName, theParentEntry );
695 }
696
697 void HYDROGUI_DataModel::buildObjectTree( SUIT_DataObject* theParent,
698                                           SUIT_DataObject* theObject,
699                                           const QString&   theParentEntry )
700 {
701   HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>( theObject );
702   if ( !aGuiObj )
703     return;
704
705   Handle(HYDROData_Entity) aDataObj = aGuiObj->modelObject();
706   if ( aDataObj.IsNull() )
707     return;
708
709   ObjectKind anObjectKind = aDataObj->GetKind();
710
711   if ( anObjectKind == KIND_IMAGE )
712   {
713     Handle(HYDROData_Image) anImageObj =
714       Handle(HYDROData_Image)::DownCast( aDataObj );
715     for ( int anIndex = 0, aNbRef = anImageObj->NbReferences(); anIndex < aNbRef; anIndex++ )
716     {
717       Handle(HYDROData_Entity) aRefObj = anImageObj->Reference( anIndex );
718       if ( !aRefObj.IsNull() && !aRefObj->IsRemoved() )
719         createObject( aGuiObj, aRefObj, aGuiObj->entry(), false );
720     }
721   }
722   else if ( anObjectKind == KIND_IMMERSIBLE_ZONE )
723   {
724     Handle(HYDROData_ImmersibleZone) aZoneObj =
725       Handle(HYDROData_ImmersibleZone)::DownCast( aDataObj );
726
727     LightApp_DataObject* aPolylineSect = 
728       createObject( aGuiObj, tr( "ZONE_POLYLINE" ), aGuiObj->entry() );
729
730     Handle(HYDROData_PolylineXY) aPolyline = aZoneObj->GetPolyline();
731     if ( !aPolyline.IsNull() && !aPolyline->IsRemoved() )
732       createObject( aPolylineSect, aPolyline, aGuiObj->entry(), false );
733
734     LightApp_DataObject* aBathSect = 
735       createObject( aGuiObj, tr( "ZONE_BATHYMETRY" ), aGuiObj->entry() );
736
737     Handle(HYDROData_Bathymetry) aBathymetry = aZoneObj->GetBathymetry();
738     if ( !aBathymetry.IsNull() && !aBathymetry->IsRemoved() )
739       createObject( aBathSect, aBathymetry, aGuiObj->entry(), false );
740   }
741   else if ( anObjectKind == KIND_CALCULATION )
742   {
743     Handle(HYDROData_CalculationCase) aCaseObj =
744       Handle(HYDROData_CalculationCase)::DownCast( aDataObj );
745
746     LightApp_DataObject* aCaseRegionsSect = 
747       createObject( aGuiObj, tr( "CASE_REGIONS" ), aGuiObj->entry() );
748
749     HYDROData_SequenceOfObjects aCaseRegions = aCaseObj->GetRegions();
750     HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions );
751     for ( ; anIter.More(); anIter.Next() )
752     {
753       Handle(HYDROData_Region) aCaseRegion =
754         Handle(HYDROData_Region)::DownCast( anIter.Value() );
755       if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() )
756         createRegion( aCaseRegionsSect, aCaseRegion, "", true );
757     }
758   }
759   else if ( anObjectKind == KIND_REGION )
760   {
761     Handle(HYDROData_Region) aRegionObj =
762       Handle(HYDROData_Region)::DownCast( aDataObj );
763
764     HYDROData_SequenceOfObjects aRegionZones = aRegionObj->GetZones();
765     HYDROData_SequenceOfObjects::Iterator anIter( aRegionZones );
766     for ( ; anIter.More(); anIter.Next() )
767     {
768       Handle(HYDROData_Zone) aRegionZone =
769         Handle(HYDROData_Zone)::DownCast( anIter.Value() );
770       if( !aRegionZone.IsNull() && !aRegionZone->IsRemoved() )
771         createZone( aGuiObj, aRegionZone, "", true );
772     }
773   }
774   else if ( anObjectKind == KIND_PROFILE )
775   {
776     Handle(HYDROData_Profile) aProfileObj =
777       Handle(HYDROData_Profile)::DownCast( aDataObj );
778
779     aGuiObj->setIsValid( aProfileObj->IsValid() );
780   }
781 }
782
783 void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDROData_CalculationCase) theCase )
784 {
785   if ( !theCase.IsNull() )
786   {
787     new HYDROGUI_DropTargetObject( theParent, tr( "NEW_REGION" ), "" );
788
789     HYDROData_SequenceOfObjects aCaseRegions = theCase->GetRegions();
790     HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions );
791     for ( ; anIter.More(); anIter.Next() )
792     {
793       Handle(HYDROData_Region) aCaseRegion =
794         Handle(HYDROData_Region)::DownCast( anIter.Value() );
795       if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() )
796         createRegion( theParent, aCaseRegion, "", true );
797     }
798   }
799 }
800
801 void HYDROGUI_DataModel::removeChild( SUIT_DataObject* theParent,
802                                       SUIT_DataObject* theChild )
803 {
804   SUIT_DataObject* aSubChild = theChild->firstChild();
805   for( ; aSubChild; aSubChild = aSubChild->nextBrother() )
806     removeChild( theChild, aSubChild );
807   theParent->removeChild( theChild );
808 }
809
810 SUIT_DataObject* HYDROGUI_DataModel::findChildByName( const SUIT_DataObject* theFather,
811                                                       const QString& theName )
812 {
813   SUIT_DataObject* aChild = theFather->firstChild();
814   while( aChild )
815   {
816     if( aChild->name() == theName )
817       return aChild; // found
818     aChild = aChild->nextBrother();
819   }
820   return NULL; // not found
821 }
822
823 bool HYDROGUI_DataModel::createNewRegion( Handle(HYDROData_CalculationCase) theCase, 
824                                          const QList<HYDROGUI_Zone*>& theZonesList )
825 {
826   bool isOk = !theCase.IsNull();
827   if ( isOk )
828   {
829     Handle(HYDROData_Region) aRegion;
830     Handle(HYDROData_Zone) aZone;
831     for (int i = 0; i < theZonesList.length(); i++ )
832     {
833       aZone = Handle(HYDROData_Zone)::DownCast( theZonesList.at(i)->modelObject() );
834       if ( !aZone.IsNull() )
835       {
836         if ( aRegion.IsNull() )
837         {
838           aRegion = theCase->AddNewRegion( aZone );
839           isOk = !aRegion.IsNull();
840         }
841         else
842         {
843           if ( !( aRegion->AddZone( aZone ) ) )
844           {
845             isOk = false;
846           }
847         }
848       }
849     }
850   }
851   return isOk;
852 }
853
854 bool HYDROGUI_DataModel::rename( Handle(HYDROData_Entity) theEntity, const QString& theName )
855 {
856   if ( theName.isEmpty() )
857     return false;
858
859   try 
860   {
861     getDocument()->StartOperation();
862     theEntity->SetName( theName );
863     getDocument()->CommitOperation( HYDROGUI_Tool::ToExtString( tr("RENAME_TO").arg( theName ) ) );
864     module()->application()->activeStudy()->Modified();
865   }
866   catch ( Standard_Failure )
867   {
868     getDocument()->AbortOperation();
869     return false;
870   }
871   return true;
872 }
873