Salome HOME
refs #567: add "POLYLINES" partition and modified icon for Land Cover object.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_DataModel.cxx
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.
6 //
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.
11 //
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
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROGUI_DataModel.h"
20
21 #include "HYDROGUI_DataObject.h"
22 #include "HYDROGUI_Module.h"
23 #include "HYDROGUI_Tool.h"
24 #include "HYDROGUI_Zone.h"
25 #include "HYDROGUI_Region.h"
26
27 #include <HYDROData_Bathymetry.h>
28 #include <HYDROData_CalculationCase.h>
29 #include <HYDROGUI_DataModelSync.h>
30 #include <HYDROData_Document.h>
31 #include <HYDROData_DummyObject3D.h>
32 #include <HYDROData_Image.h>
33 #include <HYDROData_ImmersibleZone.h>
34 #include <HYDROData_Iterator.h>
35 #include <HYDROData_Polyline3D.h>
36 #include <HYDROData_PolylineXY.h>
37 #include <HYDROData_Profile.h>
38 #include <HYDROData_VisualState.h>
39 #include <HYDROData_Region.h>
40 #include <HYDROData_Zone.h>
41 #include <HYDROData_Obstacle.h>
42 #include <HYDROData_Channel.h>
43 #include <HYDROData_Digue.h>
44 #include <HYDROData_River.h>
45 #include <HYDROData_Stream.h>
46 #include <HYDROData_StricklerTable.h>
47 #include <HYDROData_LandCover.h>
48
49 #include <CAM_Module.h>
50 #include <CAM_Study.h>
51
52 #include <LightApp_Application.h>
53 #include <LightApp_DataObject.h>
54 #include <LightApp_Study.h>
55
56 #include <SUIT_DataBrowser.h>
57 #include <SUIT_ResourceMgr.h>
58 #include <SUIT_Study.h>
59 #include <SUIT_Tools.h>
60 #include <SUIT_TreeSync.h>
61
62 #include <HYDROData_Document.h>
63
64 #include <TDF_Delta.hxx>
65 #include <TDF_ListIteratorOfDeltaList.hxx>
66
67 #include <QApplication>
68 #include <QDir>
69
70 // #define DEB_GROUPS 1
71 #ifdef DEB_GROUPS
72 #include <HYDROData_ShapesGroup.h>
73 #endif
74
75 static HYDROData_SequenceOfObjects myCopyingObjects;
76
77 const int ENTRY_COLUMN = 2;
78
79
80 HYDROGUI_DataModel::HYDROGUI_DataModel( CAM_Module* theModule )
81 : LightApp_DataModel( theModule )
82 {
83   update( module()->application()->activeStudy()->id() );
84 }
85
86 HYDROGUI_DataModel::~HYDROGUI_DataModel()
87 {
88 }
89
90 bool HYDROGUI_DataModel::open( const QString& theURL,
91                                CAM_Study* theStudy,
92                                QStringList theFileList )
93 {
94   LightApp_DataModel::open( theURL, theStudy, theFileList );
95   const int aStudyId = theStudy->id();
96
97   Data_DocError res = DocError_UnknownProblem;
98   if( theFileList.count() >= 2 )
99   {
100     QString aTmpDir = theFileList[0];
101     QString aDataFileName = theFileList[1];
102     QString aStatesFileName = theFileList.count() == 3 ? theFileList[2] : "";
103
104     myStudyURL = theURL;
105     QString aDataFullPath = SUIT_Tools::addSlash( aTmpDir ) + aDataFileName;
106     QString aStatesFullPath = aStatesFileName.isEmpty() ? "" : SUIT_Tools::addSlash( aTmpDir ) + aStatesFileName;
107
108     try
109     {
110       res = HYDROData_Document::Load( (char*)aDataFullPath.toLatin1().constData(), aStudyId );
111     }
112     catch(...)
113     {
114       res = DocError_UnknownProblem;
115     }
116     if( res != DocError_OK )
117     {
118       module()->application()->putInfo( tr( "LOAD_ERROR" ) );
119       return false;
120     }
121
122     if( !aStatesFullPath.isEmpty() )
123     {
124       QFile aFile( aStatesFullPath );
125       if( aFile.open( QFile::ReadOnly ) )
126       {
127         myStates = aFile.readAll();
128         aFile.close();
129       }
130     }
131   }
132
133   // if the document open was successful, the data model update happens
134   // in the set mode of the module
135   if( res == DocError_OK )
136     update( aStudyId );
137
138   return true;
139 }
140
141 bool HYDROGUI_DataModel::save( QStringList& theFileList )
142 {
143   if( !module()->application()->activeStudy() )
144     return false;
145   
146   LightApp_DataModel::save( theFileList );
147
148   QString aTmpDir;
149   SUIT_ResourceMgr* resMgr = module()->application()->resourceMgr();
150   bool isMultiFile = false;
151   if( resMgr )
152     isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
153
154   // save module data to temporary files
155   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
156   aTmpDir = aStudy->GetTmpDir( myStudyURL.toLatin1().constData(), isMultiFile ).c_str();
157   
158   // save OCAF data to a temporary file
159   QString aDataFileName = SUIT_Tools::file( myStudyURL, false ) + "_HYDRO.cbf";
160   QString aDataFullPath = aTmpDir + aDataFileName;
161   Data_DocError res = getDocument()->Save( (char*)aDataFullPath.toLatin1().constData() );
162   if( res != DocError_OK )
163   {
164     module()->application()->putInfo( tr( "SAVE_ERROR" ) );
165     return false;
166   }
167
168   // save tree state data to a temporary file
169   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
170   QByteArray aStatesData = anApp->objectBrowser()->getOpenStates( ENTRY_COLUMN );
171   QString aStatesFileName = SUIT_Tools::file( myStudyURL, false ) + "_HYDRO_tree_states.txt";
172   QString aStatesFullPath = aTmpDir + aStatesFileName;
173   QFile aFile( aStatesFullPath );
174   if( aFile.open( QFile::WriteOnly ) )
175   {
176     aFile.write( aStatesData );
177     aFile.close();
178   }
179
180   // add temporary files to the list
181   theFileList.append( aTmpDir );
182   theFileList.append( aDataFileName );
183   theFileList.append( aStatesFileName );
184
185   return true;
186 }
187
188 bool HYDROGUI_DataModel::saveAs( const QString& theURL,
189                                  CAM_Study*,
190                                  QStringList& theFileList )
191 {
192   myStudyURL = theURL;
193   return save( theFileList );
194 }
195
196 bool HYDROGUI_DataModel::close()
197 {
198   return true;
199 }
200
201 bool HYDROGUI_DataModel::dumpPython( const QString& theURL,
202                                      CAM_Study*     theStudy,
203                                      bool           isMultiFile,
204                                      QStringList&   theListOfFiles )
205 {
206   LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles );
207
208   int aStudyId = theStudy->id();
209
210   LightApp_Study* aStudy = ::qobject_cast<LightApp_Study*>( theStudy );
211   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( aStudyId );
212   if ( aDocument.IsNull() || !aStudy )
213     return false;
214
215   QString aDir = aStudy->GetTmpDir( theURL.toLatin1().constData(), isMultiFile ).c_str();
216   QString aFileToExport = aDir + QString( QDir::separator() ) + "HYDRO.py";
217
218   bool aRes = aDocument->DumpToPython( aFileToExport, isMultiFile );
219   if ( aRes )
220   {
221     theListOfFiles.append( aDir );
222     theListOfFiles.append( aFileToExport );
223   }
224
225   return aRes;
226 }
227
228 bool HYDROGUI_DataModel::isModified() const
229 {
230   return getDocument()->IsModified();
231 }
232
233 bool HYDROGUI_DataModel::isSaved() const
234 {
235   return true;
236 }
237
238 void HYDROGUI_DataModel::update( const int theStudyId )
239 {
240   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
241   if( !anApp )
242     return;
243
244   SUIT_DataObject* aStudyRoot = anApp->activeStudy()->root();
245   if( !aStudyRoot )
246     return;
247
248   // create a new root object
249   CAM_DataObject* aNewRootObj = new CAM_DataObject();
250
251   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( theStudyId );
252   if( aDocument.IsNull() )
253     return;
254
255   // Create root objects:
256
257   // IMAGES
258   LightApp_DataObject* anImageRootObj = createObject( aNewRootObj, tr( partitionName( KIND_IMAGE ).toAscii() ) );
259
260   // BATHYMETRY
261   LightApp_DataObject* aBathymetryRootObj = createObject( aNewRootObj, tr( partitionName( KIND_BATHYMETRY ).toAscii() ) );
262
263   // ARTIFICIAL OBJECTS
264   LightApp_DataObject* anArtificialObjectsRootObj = createObject( aNewRootObj, tr( partitionName( KIND_ARTIFICIAL_OBJECT ).toAscii() ) );
265
266   // NATURAL OBJECTS
267   LightApp_DataObject* aNaturalObjectsRootObj = createObject( aNewRootObj, tr( partitionName( KIND_NATURAL_OBJECT ).toAscii() ) );
268
269   // OBSTACLES
270   LightApp_DataObject* anObstaclesRootObj = createObject( aNewRootObj, tr( partitionName( KIND_OBSTACLE ).toAscii() ) );
271
272   // STRICKLER TABLES
273   LightApp_DataObject* aStricklerTablesRootObj = createObject( aNewRootObj, tr( partitionName( KIND_STRICKLER_TABLE ).toAscii() ) );
274
275   // LAND COVERS
276   LightApp_DataObject* aLandCoversRootObj = createObject( aNewRootObj, tr( partitionName( KIND_LAND_COVER ).toAscii() ) );
277
278   // CALCULATION CASES
279   LightApp_DataObject* aCalculRootObj = createObject( aNewRootObj, tr( partitionName( KIND_CALCULATION ).toAscii() ) );
280
281   // POLYLINES
282   LightApp_DataObject* aPolylineRootObj = createObject( aNewRootObj, tr( partitionName( KIND_POLYLINEXY ).toAscii() ) );
283
284   // POLYLINES
285   LightApp_DataObject* aPolyline3DRootObj = createObject( aNewRootObj, tr( partitionName( KIND_POLYLINE ).toAscii() ) );
286
287   // PROFILES
288   LightApp_DataObject* aProfileRootObj = createObject( aNewRootObj, tr( partitionName( KIND_PROFILE ).toAscii() ) );
289
290   // VISUAL STATES
291   LightApp_DataObject* aVisualStateRootObj = createObject( aNewRootObj, tr( partitionName( KIND_VISUAL_STATE ).toAscii() ) );
292
293   int aNoStricklerTableObj = 0;
294   HYDROData_Iterator anIterator( aDocument, KIND_UNKNOWN );
295   for( ; anIterator.More(); anIterator.Next() ) {
296     LightApp_DataObject* obj = 0;
297     Handle(HYDROData_Entity) anObj = anIterator.Current();
298
299     if ( !anObj.IsNull() )
300     {
301       switch ( anObj->GetKind() ) {
302         case KIND_IMAGE:
303         {
304           Handle(HYDROData_Image) anImageObj =
305             Handle(HYDROData_Image)::DownCast( anObj );
306           if( !anImageObj.IsNull() ) {
307             obj = createObject( anImageRootObj, anImageObj );
308           }
309
310           break;
311         }
312         case KIND_BATHYMETRY:
313         {
314           Handle(HYDROData_Bathymetry) aBathymetryObj =
315             Handle(HYDROData_Bathymetry)::DownCast( anObj );
316           if( !aBathymetryObj.IsNull() ) {
317             obj = createObject( aBathymetryRootObj, aBathymetryObj );
318           }
319
320           break;
321         }
322         case KIND_CHANNEL:
323         {
324           Handle(HYDROData_Channel) aChannelObj =
325             Handle(HYDROData_Channel)::DownCast( anObj );
326           if( !aChannelObj.IsNull() ) {
327             obj = createObject( anArtificialObjectsRootObj, aChannelObj );
328           }
329
330           break;
331         }
332         case KIND_DIGUE:
333         {
334           Handle(HYDROData_Digue) aDigueObj =
335             Handle(HYDROData_Digue)::DownCast( anObj );
336           if( !aDigueObj.IsNull() ) {
337             obj = createObject( anArtificialObjectsRootObj, aDigueObj );
338           }
339
340           break;
341         }
342         case KIND_IMMERSIBLE_ZONE:
343         {
344           Handle(HYDROData_ImmersibleZone) anImmersibleZoneObj =
345             Handle(HYDROData_ImmersibleZone)::DownCast( anObj );
346           if( !anImmersibleZoneObj.IsNull() ) {
347             obj = createObject( aNaturalObjectsRootObj, anImmersibleZoneObj );
348           }
349
350           break;
351         }
352         case KIND_RIVER:
353         {
354           Handle(HYDROData_River) aRiverObj =
355             Handle(HYDROData_River)::DownCast( anObj );
356           if( !aRiverObj.IsNull() ) {
357             obj = createObject( aNaturalObjectsRootObj, aRiverObj );
358           }
359
360           break;
361         }
362         case KIND_STREAM:
363         {
364           Handle(HYDROData_Stream) aStreamObj =
365             Handle(HYDROData_Stream)::DownCast( anObj );
366           if( !aStreamObj.IsNull() ) {
367             obj = createObject( aNaturalObjectsRootObj, aStreamObj );
368           }
369
370           break;
371         }
372         case KIND_OBSTACLE:
373         {
374           Handle(HYDROData_Obstacle) anObstacleObj =
375             Handle(HYDROData_Obstacle)::DownCast( anObj );
376           if( !anObstacleObj.IsNull() ) {
377             obj = createObject( anObstaclesRootObj, anObstacleObj );
378           }
379
380           break;
381         }
382                 case KIND_STRICKLER_TABLE:
383         {
384           Handle(HYDROData_StricklerTable) aStricklerTableObj =
385             Handle(HYDROData_StricklerTable)::DownCast( anObj );
386           if( !aStricklerTableObj.IsNull() ) {
387             obj = createObject( aStricklerTablesRootObj, aStricklerTableObj );
388           }
389                   aNoStricklerTableObj++;
390
391           break;
392         }
393         case KIND_LAND_COVER:
394         {
395           Handle(HYDROData_LandCover) aLandCoverObj =
396             Handle(HYDROData_LandCover)::DownCast( anObj );
397           if( !aLandCoverObj.IsNull() ) {
398             obj = createObject( aLandCoversRootObj, aLandCoverObj );
399           }
400
401           break;
402         }
403         case KIND_CALCULATION:
404         {
405           Handle(HYDROData_CalculationCase) aCalculObj =
406             Handle(HYDROData_CalculationCase)::DownCast( anObj );
407           if( !aCalculObj.IsNull() ) {
408             obj = createObject( aCalculRootObj, aCalculObj );
409           }
410
411           break;
412         }
413         case KIND_POLYLINEXY:
414         {
415           Handle(HYDROData_PolylineXY) aPolylineObj =
416             Handle(HYDROData_PolylineXY)::DownCast( anObj );
417           if( !aPolylineObj.IsNull() ) {
418             obj = createObject( aPolylineRootObj, aPolylineObj );
419           }
420
421           break;
422         }
423         case KIND_POLYLINE:
424         {
425           Handle(HYDROData_Polyline3D) aPolylineObj =
426             Handle(HYDROData_Polyline3D)::DownCast( anObj );
427           if( !aPolylineObj.IsNull() ) {
428             obj = createObject( aPolyline3DRootObj, aPolylineObj );
429           }
430
431           break;
432         }
433         case KIND_PROFILE:
434         {
435           Handle(HYDROData_Profile) aProfileObj =
436             Handle(HYDROData_Profile)::DownCast( anObj );
437           if( !aProfileObj.IsNull() ) {
438             obj = createObject( aProfileRootObj, aProfileObj );
439           }
440
441           break;
442         }
443         case KIND_VISUAL_STATE:
444         {
445           Handle(HYDROData_VisualState) aVisualStateObj =
446             Handle(HYDROData_VisualState)::DownCast( anObj );
447           if( !aVisualStateObj.IsNull() ) {
448             obj = createObject( aVisualStateRootObj, aVisualStateObj );
449           }
450
451           break;
452         }
453       }
454     }
455   }
456
457   // Create default Strickler table object
458   if ( aNoStricklerTableObj == 0 )
459     createDefaultStricklerTable( aDocument, aStricklerTablesRootObj );
460
461   //if( SUIT_DataBrowser* anObjectBrowser = anApp->objectBrowser() )
462   //{
463   //  anObjectBrowser->setAutoOpenLevel( 3 );
464   //  anObjectBrowser->openLevels();
465   //}
466
467   HYDROGUI_DataModelSync aSync( aNewRootObj );
468   SUIT_DataObject* aRoot = root();
469   bool isNewDoc = aRoot==0;
470   if( isNewDoc )
471     aRoot = createRootModuleObject( aStudyRoot );
472   ::synchronize < suitPtr, suitPtr, HYDROGUI_DataModelSync >
473     ( aNewRootObj, aRoot, aSync );
474
475   SUIT_DataBrowser* ob = anApp->objectBrowser();
476
477   if ( !myStates.isEmpty() )
478   {
479     ob->updateTree();
480     ob->setOpenStates( myStates, ENTRY_COLUMN );
481     myStates.clear();
482   }
483 }
484
485 HYDROGUI_DataObject* HYDROGUI_DataModel::getDataObject( const Handle(HYDROData_Entity)& theModelObject )
486 {
487   HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>(
488     findObject( HYDROGUI_DataObject::dataObjectEntry( theModelObject ) ) );
489   return aGuiObj;
490 }
491
492 HYDROGUI_DataObject* HYDROGUI_DataModel::getReferencedDataObject( HYDROGUI_DataObject* theObject )
493 {
494   return NULL; // to do if necessary
495 }
496
497 SUIT_DataObject* HYDROGUI_DataModel::findObject( const QString& theEntry ) const
498 {
499   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( module()->application() );
500   return anApp ? anApp->findObject( theEntry ) : 0;
501 }
502
503 void HYDROGUI_DataModel::update( LightApp_DataObject* theObject,
504                                  LightApp_Study* theStudy )
505 {
506   if( !theStudy )
507     theStudy = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy()) ;
508   if( theStudy )
509     update( theStudy->id() );
510 }
511
512 CAM_DataObject* HYDROGUI_DataModel::createRootModuleObject( SUIT_DataObject* theParent )
513 {
514   CAM_ModuleObject* aRootObj = createModuleObject( theParent );
515   aRootObj->setDataModel( this );
516   setRoot( aRootObj );
517   return aRootObj;
518 }
519
520 void HYDROGUI_DataModel::updateModel()
521 {
522   HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
523   if( aModule )
524     update( aModule->getStudyId() );
525 }
526
527 Handle(HYDROData_Entity) HYDROGUI_DataModel::objectByEntry( const QString& theEntry,
528                                                             const ObjectKind theObjectKind )
529 {
530   QString anEntry = theEntry;
531   if( anEntry.indexOf( "_" ) != -1 ) // reference object
532     anEntry = anEntry.section( "_", -1 );
533
534   Handle(HYDROData_Document) aDocument = getDocument();
535   if( !aDocument.IsNull() )
536   {
537     HYDROData_Iterator anIterator( aDocument, theObjectKind );
538     for( ; anIterator.More(); anIterator.Next() )
539     {
540       Handle(HYDROData_Entity) anObject = anIterator.Current();
541       if( !anObject.IsNull() )
542       {
543         QString anEntryRef = HYDROGUI_DataObject::dataObjectEntry( anObject );
544         if( anEntryRef == anEntry )
545           return anObject;
546       }
547     }
548   }
549   return NULL;
550 }
551
552 bool HYDROGUI_DataModel::canUndo() const
553 {
554   return getDocument()->CanUndo();
555 }
556
557 bool HYDROGUI_DataModel::canRedo() const
558 {
559   return getDocument()->CanRedo();
560 }
561
562 QStringList HYDROGUI_DataModel::undoNames() const
563 {
564   QStringList aNames;
565   for( TDF_ListIteratorOfDeltaList anIter( getDocument()->GetUndos() ); anIter.More(); anIter.Next() )
566     aNames.prepend( HYDROGUI_Tool::ToQString( anIter.Value()->Name() ) );
567   return aNames;
568 }
569
570 QStringList HYDROGUI_DataModel::redoNames() const
571 {
572   QStringList aNames;
573   for( TDF_ListIteratorOfDeltaList anIter( getDocument()->GetRedos() ); anIter.More(); anIter.Next() )
574     aNames.append( HYDROGUI_Tool::ToQString( anIter.Value()->Name() ) );
575   return aNames;
576 }
577
578 void HYDROGUI_DataModel::clearUndos()
579 {
580   getDocument()->ClearUndos();
581 }
582
583 void HYDROGUI_DataModel::clearRedos()
584 {
585   getDocument()->ClearRedos();
586 }
587
588 bool HYDROGUI_DataModel::undo()
589 {
590   try 
591   {
592     getDocument()->Undo();
593   }
594   catch ( Standard_Failure )
595   {
596     return false;
597   }
598   return true;
599 }
600
601 bool HYDROGUI_DataModel::redo()
602 {
603   try 
604   {
605     getDocument()->Redo();
606   }
607   catch ( Standard_Failure )
608   {
609     return false;
610   }
611   return true;
612 }
613
614 bool HYDROGUI_DataModel::canCopy()
615 {
616   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( (HYDROGUI_Module*)module() );
617   bool isCanCopy = !aSeq.IsEmpty();
618
619   for ( Standard_Integer anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
620     Handle(HYDROData_Entity) anObject = aSeq.Value( anIndex );
621     if( !anObject.IsNull() ) {
622       ObjectKind aKind = anObject->GetKind();
623       bool isUnrecognized = aKind <= KIND_UNKNOWN || aKind > KIND_LAST;
624       bool isChildObject = aKind == KIND_DUMMY_3D || 
625                            aKind == KIND_ZONE ||
626                            aKind == KIND_SHAPES_GROUP || 
627                            aKind == KIND_SPLITTED_GROUP;
628       if ( isUnrecognized || isChildObject ) {
629         isCanCopy = false;
630         break;
631       }
632     }
633   }
634   
635   return isCanCopy;
636 }
637
638 bool HYDROGUI_DataModel::canPaste()
639 {
640   for( int anIndex = 1, aLength = myCopyingObjects.Length(); anIndex <= aLength; anIndex++ )
641   {
642     Handle(HYDROData_Entity) anObject = myCopyingObjects.Value( anIndex );
643     if( !anObject.IsNull() && !anObject->IsRemoved() )
644       return true;
645   }
646   return false;
647 }
648
649 bool HYDROGUI_DataModel::copy()
650 {
651   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( (HYDROGUI_Module*)module() );
652   changeCopyingObjects( aSeq );
653   return true;
654 }
655
656 bool HYDROGUI_DataModel::paste()
657 {
658   bool anIsChanged = false;
659   for( int anIndex = 1, aLength = myCopyingObjects.Length(); anIndex <= aLength; anIndex++ )
660   {
661     Handle(HYDROData_Entity) anObject = myCopyingObjects.Value( anIndex );
662     if( !anObject.IsNull() && !anObject->IsRemoved() )
663     {
664       ObjectKind aKind = anObject->GetKind();
665       Handle(HYDROData_Entity) aClone = getDocument()->CreateObject( aKind );
666       if( !aClone.IsNull() )
667       {
668         anObject->CopyTo( aClone );
669         anIsChanged = true;
670
671         // remove Z layer
672         aClone->RemoveZLevel();
673       }
674     }
675   }
676   return anIsChanged;
677 }
678
679 void HYDROGUI_DataModel::changeCopyingObjects( const HYDROData_SequenceOfObjects& theSeq )
680 {
681   myCopyingObjects.Assign( theSeq );
682 }
683
684 QString HYDROGUI_DataModel::partitionName( const ObjectKind theObjectKind )
685 {
686   switch( theObjectKind )
687   {
688     case KIND_IMAGE:             return "IMAGES";
689     case KIND_POLYLINE:          return "POLYLINES_3D";
690     case KIND_POLYLINEXY:        return "POLYLINES";
691     case KIND_PROFILE:           return "PROFILES";
692     case KIND_VISUAL_STATE:      return "VISUAL_STATES";
693     case KIND_BATHYMETRY:        return "BATHYMETRIES";
694     case KIND_CALCULATION:       return "CALCULATION_CASES";
695     case KIND_OBSTACLE:          return "OBSTACLES";
696     case KIND_ARTIFICIAL_OBJECT: return "ARTIFICIAL_OBJECTS";
697     case KIND_NATURAL_OBJECT:    return "NATURAL_OBJECTS";
698     case KIND_STRICKLER_TABLE:   return "STRICKLER_TABLES";
699     case KIND_LAND_COVER:        return "LAND_COVERS";
700     default: break;
701   }
702   return QString();
703 }
704
705 Handle(HYDROData_Document) HYDROGUI_DataModel::getDocument() const
706 {
707   int aStudyId = module()->application()->activeStudy()->id();
708   return HYDROData_Document::Document( aStudyId );
709 }
710
711 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject*         theParent,
712                                                        Handle(HYDROData_Entity) theModelObject,
713                                                        const QString&           theParentEntry,
714                                                        const bool               theIsBuildTree )
715 {
716   HYDROGUI_DataObject* aResObj = new HYDROGUI_DataObject( theParent, theModelObject, theParentEntry );
717
718   const ObjectKind aKind = theModelObject->GetKind();
719   bool visibility = aKind == KIND_IMAGE || aKind == KIND_POLYLINEXY || aKind == KIND_POLYLINE ||
720                     aKind == KIND_SHAPES_GROUP || aKind == KIND_SPLITTED_GROUP || aKind == KIND_ZONE ||
721                     aKind == KIND_IMMERSIBLE_ZONE || aKind == KIND_REGION || aKind == KIND_BATHYMETRY ||
722                     aKind == KIND_OBSTACLE || aKind == KIND_STREAM || aKind == KIND_CHANNEL ||
723                     aKind == KIND_DIGUE || aKind == KIND_DUMMY_3D || aKind == KIND_LAND_COVER;
724   if ( !visibility )
725   {
726     Handle(HYDROData_Profile) aProfObj = Handle(HYDROData_Profile)::DownCast( theModelObject );
727     visibility = !aProfObj.IsNull() && aProfObj->IsValid();
728   }
729
730   if ( aKind == KIND_REGION )
731   {
732       QString an = aResObj->name();
733       int a = 0;
734   }
735
736   if ( visibility )
737   {
738     setObjectVisibilityState( theModelObject, aResObj );
739   }
740
741   if ( theIsBuildTree )
742   {
743     buildObjectTree( theParent, aResObj, theParentEntry );
744   }
745
746   return aResObj;
747 }
748
749 LightApp_DataObject* HYDROGUI_DataModel::buildObject( SUIT_DataObject*     theParent,
750                                                       HYDROGUI_DataObject* theObject,
751                                                       const QString&       theParentEntry,
752                                                       const bool           theIsBuildTree,
753                                                       const bool           theIsInOperation )
754 {
755   if ( theIsBuildTree )
756   {
757     buildObjectTree( theParent, theObject, theParentEntry, theIsInOperation );
758   }
759   return theObject;
760 }
761
762 LightApp_DataObject* HYDROGUI_DataModel::createZone( SUIT_DataObject*       theParent,
763                                                      Handle(HYDROData_Zone) theModelObject,
764                                                      const QString&         theParentEntry,
765                                                      const bool             theIsBuildTree,
766                                                      const bool             theIsInOperation )
767 {
768   HYDROGUI_Zone* aZone = new HYDROGUI_Zone( theParent, theModelObject, theParentEntry, theIsInOperation );
769   LightApp_DataObject* aDataObj = buildObject( theParent, aZone, theParentEntry, theIsBuildTree, theIsInOperation );
770
771   setObjectVisibilityState( theModelObject, aZone );
772
773   return aDataObj;
774 }
775
776 LightApp_DataObject* HYDROGUI_DataModel::createRegion( SUIT_DataObject*         theParent,
777                                                        Handle(HYDROData_Region) theModelObject,
778                                                        const QString&           theParentEntry,
779                                                        const bool               theIsBuildTree,
780                                                        const bool               theIsInOperation )
781 {
782   return buildObject( theParent, new HYDROGUI_Region( theParent, theModelObject, theParentEntry, theIsInOperation ), 
783     theParentEntry, theIsBuildTree, theIsInOperation );
784 }
785
786 void HYDROGUI_DataModel::createDefaultStricklerTable( const Handle(HYDROData_Document)& theDocument,
787                                                       LightApp_DataObject*              theParent )
788 {
789   // Create default Strickler table object
790   Handle(HYDROData_StricklerTable) aStricklerTableObj =
791     Handle(HYDROData_StricklerTable)::DownCast( theDocument->CreateObject(KIND_STRICKLER_TABLE) );      
792   if ( !aStricklerTableObj.IsNull() )
793   {
794     SUIT_ResourceMgr* resMgr = module()->application()->resourceMgr();
795     QString defTablePath = resMgr->path( "resources", module()->name(), tr( "DEFAULT_STRICKLER_TABLE_FILE" ) );
796     aStricklerTableObj->Import( HYDROGUI_Tool::ToAsciiString( defTablePath ) );
797         // Set name
798     QString aStricklerTableName;
799     if ( aStricklerTableObj->GetName().isEmpty() )
800     {
801       HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
802       if ( aModule )
803         aStricklerTableName = HYDROGUI_Tool::GenerateObjectName( aModule, tr( "DEFAULT_STRICKLER_TABLE_NAME" ) );
804     }
805     if ( aStricklerTableObj->GetName() != aStricklerTableName )
806       aStricklerTableObj->SetName( aStricklerTableName );
807
808     aStricklerTableObj->Update();
809
810     LightApp_DataObject* obj = createObject( theParent, aStricklerTableObj );
811   }
812 }
813
814 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject* theParent,
815                                                        const QString&   theName,
816                                                        const QString&   theParentEntry )
817 {
818   return new HYDROGUI_NamedObject( theParent, theName, theParentEntry );
819 }
820
821 void HYDROGUI_DataModel::buildObjectPartition( SUIT_DataObject*                   theObject,
822                                                const HYDROData_SequenceOfObjects& theObjects,
823                                                const QString&                     thePartName,
824                                                const bool                         theIsCreateEmpty )
825 {
826   if ( theObjects.IsEmpty() && !theIsCreateEmpty )
827     return;
828
829   HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>( theObject );
830   if ( !aGuiObj )
831     return;
832
833   LightApp_DataObject* aPartSect = 
834     createObject( aGuiObj, thePartName, aGuiObj->entry() );
835
836   HYDROData_SequenceOfObjects::Iterator anIter( theObjects );
837   for ( ; anIter.More(); anIter.Next() )
838   {
839     Handle(HYDROData_Entity) anObj = anIter.Value();
840     if( !anObj.IsNull() && !anObj->IsRemoved() )
841       createObject( aPartSect, anObj, aGuiObj->entry(), false );
842   }
843 }
844
845 void HYDROGUI_DataModel::buildObjectTree( SUIT_DataObject* theParent,
846                                           SUIT_DataObject* theObject,
847                                           const QString&   theParentEntry,
848                                           const bool       theIsInOperation )
849 {
850   HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>( theObject );
851   if ( !aGuiObj )
852     return;
853
854   Handle(HYDROData_Entity) aDataObj = aGuiObj->modelObject();
855   if ( aDataObj.IsNull() )
856     return;
857
858   if ( aDataObj->IsKind( STANDARD_TYPE(HYDROData_Object) ) )
859   {
860     Handle(HYDROData_Object) aGeomObj =
861       Handle(HYDROData_Object)::DownCast( aDataObj );
862
863     Handle(HYDROData_DummyObject3D) anObject3D = aGeomObj->GetObject3D();
864     if ( !anObject3D.IsNull() )
865       createObject( aGuiObj, anObject3D, "", false );
866
867 #ifdef DEB_GROUPS
868     HYDROData_SequenceOfObjects anObjGroups = aGeomObj->GetGroups();
869     buildObjectPartition( aGuiObj, anObjGroups, tr( "OBJECT_GROUPS" ), false );
870 #endif
871   }
872
873   ObjectKind anObjectKind = aDataObj->GetKind();
874
875   if ( anObjectKind == KIND_IMAGE )
876   {
877     Handle(HYDROData_Image) anImageObj =
878       Handle(HYDROData_Image)::DownCast( aDataObj );
879     for ( int anIndex = 0, aNbRef = anImageObj->NbReferences(); anIndex < aNbRef; anIndex++ )
880     {
881       Handle(HYDROData_Entity) aRefObj = anImageObj->Reference( anIndex );
882       if ( !aRefObj.IsNull() && !aRefObj->IsRemoved() )
883         createObject( aGuiObj, aRefObj, aGuiObj->entry(), false );
884     }
885   }
886   else if ( anObjectKind == KIND_IMMERSIBLE_ZONE )
887   {
888     Handle(HYDROData_ImmersibleZone) aZoneObj =
889       Handle(HYDROData_ImmersibleZone)::DownCast( aDataObj );
890
891     LightApp_DataObject* aPolylineSect = 
892       createObject( aGuiObj, tr( "ZONE_POLYLINE" ), aGuiObj->entry() );
893
894     Handle(HYDROData_PolylineXY) aPolyline = aZoneObj->GetPolyline();
895     if ( !aPolyline.IsNull() && !aPolyline->IsRemoved() )
896       createObject( aPolylineSect, aPolyline, aGuiObj->entry(), false );
897
898     LightApp_DataObject* aBathSect = 
899       createObject( aGuiObj, tr( "ZONE_BATHYMETRY" ), aGuiObj->entry() );
900
901     Handle(HYDROData_IAltitudeObject) anAltitudeObj = aZoneObj->GetAltitudeObject();
902     if ( !anAltitudeObj.IsNull() && !anAltitudeObj->IsRemoved() )
903       createObject( aBathSect, anAltitudeObj, aGuiObj->entry(), false );
904   }
905   else if ( anObjectKind == KIND_POLYLINE )
906   {
907     Handle(HYDROData_Polyline3D) aPolyline3D =
908       Handle(HYDROData_Polyline3D)::DownCast( aDataObj );
909
910     LightApp_DataObject* aPolylineSect = 
911       createObject( aGuiObj, tr( "POLYLINE3D_POLYLINE" ), aGuiObj->entry() );
912
913     Handle(HYDROData_PolylineXY) aPolylineXY = aPolyline3D->GetPolylineXY();
914     if ( !aPolylineXY.IsNull() && !aPolylineXY->IsRemoved() )
915       createObject( aPolylineSect, aPolylineXY, aGuiObj->entry(), false );
916
917     LightApp_DataObject* aProfileSect = 
918       createObject( aGuiObj, tr( "POLYLINE3D_PROFILE" ), aGuiObj->entry() );
919
920     Handle(HYDROData_ProfileUZ) aProfileUZ = aPolyline3D->GetProfileUZ();
921     if ( aProfileUZ.IsNull() || aProfileUZ->IsRemoved() )
922       aProfileUZ = aPolyline3D->GetChildProfileUZ( false );
923
924     if ( !aProfileUZ.IsNull() && !aProfileUZ->IsRemoved() )
925     {
926       Handle(HYDROData_Profile) aProfile = 
927         Handle(HYDROData_Profile)::DownCast( aProfileUZ->GetFatherObject() );
928       if ( !aProfile.IsNull() && !aProfile->IsRemoved() )
929         createObject( aProfileSect, aProfile, aGuiObj->entry(), false );
930     }
931
932     LightApp_DataObject* aBathSect = 
933       createObject( aGuiObj, tr( "POLYLINE3D_BATHYMETRY" ), aGuiObj->entry() );
934
935     Handle(HYDROData_IAltitudeObject) anAltitudeObj = aPolyline3D->GetAltitudeObject();
936     if ( !anAltitudeObj.IsNull() && !anAltitudeObj->IsRemoved() )
937       createObject( aBathSect, anAltitudeObj, aGuiObj->entry(), false );
938   }
939   else if ( anObjectKind == KIND_CALCULATION )
940   {
941     Handle(HYDROData_CalculationCase) aCaseObj =
942       Handle(HYDROData_CalculationCase)::DownCast( aDataObj );
943
944     LightApp_DataObject* aPolylineSect = 
945       createObject( aGuiObj, tr( "CASE_BOUNDARY" ), aGuiObj->entry() );
946
947     Handle(HYDROData_PolylineXY) aPolyline = aCaseObj->GetBoundaryPolyline();
948     if ( !aPolyline.IsNull() && !aPolyline->IsRemoved() )
949       createObject( aPolylineSect, aPolyline, aGuiObj->entry(), false );
950
951     LightApp_DataObject* aCaseAOSect = 
952       createObject( aGuiObj, tr( partitionName( KIND_ARTIFICIAL_OBJECT ).toAscii() ),
953                     aGuiObj->entry() );
954     LightApp_DataObject* aCaseNOSect = 
955       createObject( aGuiObj, tr( partitionName( KIND_NATURAL_OBJECT ).toAscii() ),
956                     aGuiObj->entry() );
957
958     HYDROData_SequenceOfObjects aSeq = aCaseObj->GetGeometryObjects();
959     HYDROData_SequenceOfObjects::Iterator aGOIter( aSeq );
960     Handle(HYDROData_Entity) anEntity;
961     Handle(HYDROData_ArtificialObject) anAObject;
962     Handle(HYDROData_NaturalObject) aNObject;
963     for ( ; aGOIter.More(); aGOIter.Next() )
964     {
965       anEntity = aGOIter.Value();
966       if ( anEntity.IsNull() )
967         continue;
968       anAObject = Handle(HYDROData_ArtificialObject)::DownCast( anEntity );
969       if ( !anAObject.IsNull() )
970         createObject( aCaseAOSect, anAObject, aGuiObj->entry(), false );
971       else
972       {
973         aNObject = Handle(HYDROData_NaturalObject)::DownCast( anEntity );
974         if ( !aNObject.IsNull() )
975           createObject( aCaseNOSect, aNObject, aGuiObj->entry(), false );
976       }
977     }
978     LightApp_DataObject* aCaseRegionsSect = 
979       createObject( aGuiObj, tr( "CASE_REGIONS" ), aGuiObj->entry() );
980
981     HYDROData_SequenceOfObjects aCaseRegions = aCaseObj->GetRegions( false );
982     HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions );
983     for ( ; anIter.More(); anIter.Next() )
984     {
985       Handle(HYDROData_Region) aCaseRegion =
986         Handle(HYDROData_Region)::DownCast( anIter.Value() );
987       if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() )
988         createRegion( aCaseRegionsSect, aCaseRegion, "", true, theIsInOperation );
989     }
990
991     LightApp_DataObject* aCaseLandCoverRegionsSect = 
992       createObject( aGuiObj, tr( "CASE_LAND_COVER_REGIONS" ), aGuiObj->entry() );
993
994     HYDROData_SequenceOfObjects aCaseLandCoverRegions = aCaseObj->GetRegions( true );
995     anIter.Init( aCaseLandCoverRegions );
996     for ( ; anIter.More(); anIter.Next() )
997     {
998       Handle(HYDROData_Region) aCaseLCRegion =
999         Handle(HYDROData_Region)::DownCast( anIter.Value() );
1000       if( !aCaseLCRegion.IsNull() && !aCaseLCRegion->IsRemoved() )
1001         createRegion( aCaseLandCoverRegionsSect, aCaseLCRegion, "", true, theIsInOperation );
1002     }
1003     
1004 #ifdef DEB_GROUPS
1005     HYDROData_SequenceOfObjects aCalcGroups = aCaseObj->GetGeometryGroups();
1006     buildObjectPartition( aGuiObj, aCalcGroups, tr( "OBJECT_GROUPS" ), false );
1007
1008     HYDROData_SequenceOfObjects aCalcSplitGroups = aCaseObj->GetSplittedGroups();
1009     buildObjectPartition( aGuiObj, aCalcSplitGroups, tr( "CASE_SPLITTED_GROUPS" ), false );
1010 #endif
1011
1012   }
1013   else if ( anObjectKind == KIND_REGION )
1014   {
1015     Handle(HYDROData_Region) aRegionObj =
1016       Handle(HYDROData_Region)::DownCast( aDataObj );
1017
1018     HYDROData_SequenceOfObjects aRegionZones = aRegionObj->GetZones();
1019     HYDROData_SequenceOfObjects::Iterator anIter( aRegionZones );
1020     for ( ; anIter.More(); anIter.Next() )
1021     {
1022       Handle(HYDROData_Zone) aRegionZone =
1023         Handle(HYDROData_Zone)::DownCast( anIter.Value() );
1024       if( !aRegionZone.IsNull() && !aRegionZone->IsRemoved() )
1025         createZone( aGuiObj, aRegionZone, "", true, theIsInOperation );
1026     }
1027   }
1028   else if ( anObjectKind == KIND_PROFILE )
1029   {
1030     Handle(HYDROData_Profile) aProfileObj =
1031       Handle(HYDROData_Profile)::DownCast( aDataObj );
1032
1033     aGuiObj->setIsValid( aProfileObj->IsValid() );
1034   }
1035   else if ( anObjectKind == KIND_CHANNEL || anObjectKind == KIND_DIGUE )
1036   {
1037     Handle(HYDROData_Channel) aChannelObj =
1038       Handle(HYDROData_Channel)::DownCast( aDataObj );
1039
1040     LightApp_DataObject* aGuideLineSect = 
1041       createObject( aGuiObj, tr( "CHANNEL_GUIDE_LINE" ), aGuiObj->entry() );
1042     Handle(HYDROData_Polyline3D) aGuideLine = aChannelObj->GetGuideLine();
1043     if ( !aGuideLine.IsNull() && !aGuideLine->IsRemoved() ) {
1044       createObject( aGuideLineSect, aGuideLine, aGuiObj->entry(), false );
1045     }
1046
1047     LightApp_DataObject* aProfileSect = 
1048       createObject( aGuiObj, tr( "CHANNEL_PROFILE" ), aGuiObj->entry() );
1049     Handle(HYDROData_Profile) aProfile = aChannelObj->GetProfile();
1050     if ( !aProfile.IsNull() && !aProfile->IsRemoved() ) {
1051       createObject( aProfileSect, aProfile, aGuiObj->entry(), false );
1052     }
1053   }
1054   else if ( anObjectKind == KIND_STREAM )
1055   {
1056     Handle(HYDROData_Stream) aStreamObj =
1057       Handle(HYDROData_Stream)::DownCast( aDataObj );
1058
1059     LightApp_DataObject* aHydraulicAxisSect = 
1060       createObject( aGuiObj, tr( "STREAM_HYDRAULIC_AXIS" ), aGuiObj->entry() );
1061     Handle(HYDROData_PolylineXY) aHydraulicAxis = aStreamObj->GetHydraulicAxis();
1062     if ( !aHydraulicAxis.IsNull() && !aHydraulicAxis->IsRemoved() ) {
1063       createObject( aHydraulicAxisSect, aHydraulicAxis, aGuiObj->entry(), false );
1064     }
1065
1066     HYDROData_SequenceOfObjects aProfiles = aStreamObj->GetProfiles();
1067     buildObjectPartition( aGuiObj, aProfiles, tr( "STREAM_PROFILES" ), true );
1068
1069     Handle(HYDROData_Polyline3D) aBottomPolyline = aStreamObj->GetBottomPolyline();
1070     if ( !aBottomPolyline.IsNull() && !aBottomPolyline->IsRemoved() ) {
1071       createObject( aGuiObj, aBottomPolyline, aGuiObj->entry(), false );
1072     }
1073   }
1074   else if ( anObjectKind == KIND_LAND_COVER )
1075   {
1076     Handle(HYDROData_LandCover) aLandCoverObj =
1077       Handle(HYDROData_LandCover)::DownCast( aDataObj );
1078
1079     HYDROData_SequenceOfObjects aPolylines = aLandCoverObj->GetPolylines();
1080     buildObjectPartition( aGuiObj, aPolylines, tr( "LAND_COVER_POLYLINES" ), true );
1081   }
1082   
1083 }
1084
1085 void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDROData_CalculationCase) theCase,
1086                                         const bool theLandCover )
1087 {
1088   if ( !theCase.IsNull() )
1089   {
1090     if ( theParent )
1091     {
1092       // Remove previous objects tree
1093         DataObjectList aList;
1094         theParent->children( aList );
1095         QListIterator<SUIT_DataObject*> anIter( aList );
1096         while( anIter.hasNext() )
1097           removeChild( theParent, anIter.next() );
1098     }
1099
1100     new HYDROGUI_DropTargetObject( theParent, tr( "NEW_REGION" ), "", true );
1101
1102     HYDROData_SequenceOfObjects aCaseRegions = theCase->GetRegions( theLandCover );
1103     HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions );
1104     for ( ; anIter.More(); anIter.Next() )
1105     {
1106       Handle(HYDROData_Region) aCaseRegion =
1107         Handle(HYDROData_Region)::DownCast( anIter.Value() );
1108       if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() )
1109         createRegion( theParent, aCaseRegion, "", true, true );
1110     }
1111   }
1112 }
1113
1114 void HYDROGUI_DataModel::updateObjectTree( Handle(HYDROData_Entity)& theObj )
1115 {
1116   if ( !theObj.IsNull() )
1117   {
1118     HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>(
1119       findObject( HYDROGUI_DataObject::dataObjectEntry( theObj ) ) );
1120     if ( aGuiObj )
1121     {
1122       // Remove previous objects tree
1123       DataObjectList aList;
1124       aGuiObj->children( aList );
1125       QListIterator<SUIT_DataObject*> anIter( aList );
1126       while( anIter.hasNext() )
1127         removeChild( aGuiObj, anIter.next() );
1128
1129       // Rebuild the subtree
1130       QString aParentEntry;
1131       HYDROGUI_DataObject* aParent = dynamic_cast<HYDROGUI_DataObject*>( aGuiObj->parent() );
1132       if ( aParent )
1133       {
1134         aParentEntry = aParent->entry();
1135       }
1136       buildObjectTree( aParent, aGuiObj, aParentEntry, aGuiObj->isInOperation() );
1137     } 
1138     else
1139     {
1140       // workaround for the bug in SalomeApp_Study::findObjectByEntry - it can't find LightApp_DataObjects
1141       HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
1142       if( aModule )
1143       {
1144         aModule->getApp()->updateObjectBrowser();
1145       }
1146     }
1147   }
1148 }
1149
1150 void HYDROGUI_DataModel::removeChild( SUIT_DataObject* theParent,
1151                                       SUIT_DataObject* theChild )
1152 {
1153   SUIT_DataObject* aSubChild = theChild->firstChild();
1154   for( ; aSubChild; aSubChild = aSubChild->nextBrother() )
1155     removeChild( theChild, aSubChild );
1156   theParent->removeChild( theChild );
1157 }
1158
1159 SUIT_DataObject* HYDROGUI_DataModel::findChildByName( const SUIT_DataObject* theFather,
1160                                                       const QString& theName )
1161 {
1162   SUIT_DataObject* aChild = theFather->firstChild();
1163   while( aChild )
1164   {
1165     if( aChild->name() == theName )
1166       return aChild; // found
1167     aChild = aChild->nextBrother();
1168   }
1169   return NULL; // not found
1170 }
1171
1172 bool HYDROGUI_DataModel::createNewRegion( Handle(HYDROData_CalculationCase) theCase, 
1173                                          const QList<HYDROGUI_Zone*>& theZonesList,
1174                                          const bool theLandCover )
1175 {
1176   bool isOk = !theCase.IsNull();
1177   if ( isOk )
1178   {
1179     Handle(HYDROData_Region) aRegion;
1180     Handle(HYDROData_Zone) aZone;
1181     for (int i = 0; i < theZonesList.length(); i++ )
1182     {
1183       aZone = Handle(HYDROData_Zone)::DownCast( theZonesList.at(i)->modelObject() );
1184       if ( !aZone.IsNull() )
1185       {
1186         if ( aRegion.IsNull() )
1187         {
1188           aRegion = theCase->AddNewRegion( aZone, theLandCover );
1189           isOk = !aRegion.IsNull();
1190         }
1191         else
1192         {
1193           if ( !( aRegion->AddZone( aZone ) ) )
1194           {
1195             isOk = false;
1196           }
1197         }
1198       }
1199     }
1200   }
1201   return isOk;
1202 }
1203
1204 bool HYDROGUI_DataModel::rename( Handle(HYDROData_Entity) theEntity, const QString& theName )
1205 {
1206   if ( theName.isEmpty() )
1207     return false;
1208
1209   try 
1210   {
1211     getDocument()->StartOperation();
1212     theEntity->SetName( theName );
1213     getDocument()->CommitOperation( HYDROGUI_Tool::ToExtString( tr("RENAME_TO").arg( theName ) ) );
1214     module()->application()->activeStudy()->Modified();
1215   }
1216   catch ( Standard_Failure )
1217   {
1218     getDocument()->AbortOperation();
1219     return false;
1220   }
1221   return true;
1222 }
1223
1224 void HYDROGUI_DataModel::setObjectVisibilityState( Handle(HYDROData_Entity) theModelObject,
1225                                                    HYDROGUI_DataObject* theObject )
1226 {
1227   SUIT_AbstractModel* treeModel = 0;
1228   LightApp_Application* app = dynamic_cast<LightApp_Application*>( module()->application() );
1229   if ( app )
1230     treeModel = dynamic_cast<SUIT_AbstractModel*>( app->objectBrowser()->model() );
1231
1232   if ( treeModel )
1233   {
1234     HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
1235     bool isVisible = aModule->isObjectVisible( -1, theModelObject );
1236     Qtx::VisibilityState aVisState = isVisible ? Qtx::ShownState : Qtx::HiddenState;
1237     treeModel->setVisibilityState( theObject->text( theObject->customData( Qtx::IdType ).toInt() ), aVisState, false );
1238   }
1239 }