Salome HOME
Merge branch 'BR_LAND_COVER' of ssh://git.salome-platform.org/modules/hydro into...
[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     SUIT_AbstractModel* treeModel = 0;
739     LightApp_Application* app = dynamic_cast<LightApp_Application*>( module()->application() );
740     if ( app )
741         treeModel = dynamic_cast<SUIT_AbstractModel*>( app->objectBrowser()->model() );
742
743     if ( treeModel )
744     {
745       HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
746       bool isVisible = aModule->isObjectVisible( -1, theModelObject );
747       Qtx::VisibilityState aVisState = isVisible ? Qtx::ShownState : Qtx::HiddenState;
748       treeModel->setVisibilityState( aResObj->text( aResObj->customData( Qtx::IdType ).toInt() ), aVisState, false );
749     }
750   }
751
752   if ( theIsBuildTree )
753   {
754     buildObjectTree( theParent, aResObj, theParentEntry );
755   }
756
757   return aResObj;
758 }
759
760 LightApp_DataObject* HYDROGUI_DataModel::buildObject( SUIT_DataObject*     theParent,
761                                                       HYDROGUI_DataObject* theObject,
762                                                       const QString&       theParentEntry,
763                                                       const bool           theIsBuildTree,
764                                                       const bool           theIsInOperation )
765 {
766   if ( theIsBuildTree )
767   {
768     buildObjectTree( theParent, theObject, theParentEntry, theIsInOperation );
769   }
770   return theObject;
771 }
772
773 LightApp_DataObject* HYDROGUI_DataModel::createZone( SUIT_DataObject*       theParent,
774                                                      Handle(HYDROData_Zone) theModelObject,
775                                                      const QString&         theParentEntry,
776                                                      const bool             theIsBuildTree,
777                                                      const bool             theIsInOperation )
778 {
779   return buildObject( theParent, new HYDROGUI_Zone( theParent, theModelObject, theParentEntry, theIsInOperation ), 
780     theParentEntry, theIsBuildTree, theIsInOperation );
781 }
782
783 LightApp_DataObject* HYDROGUI_DataModel::createRegion( SUIT_DataObject*         theParent,
784                                                        Handle(HYDROData_Region) theModelObject,
785                                                        const QString&           theParentEntry,
786                                                        const bool               theIsBuildTree,
787                                                        const bool               theIsInOperation )
788 {
789   return buildObject( theParent, new HYDROGUI_Region( theParent, theModelObject, theParentEntry, theIsInOperation ), 
790     theParentEntry, theIsBuildTree, theIsInOperation );
791 }
792
793 void HYDROGUI_DataModel::createDefaultStricklerTable( const Handle(HYDROData_Document)& theDocument,
794                                                       LightApp_DataObject*              theParent )
795 {
796   // Create default Strickler table object
797   Handle(HYDROData_StricklerTable) aStricklerTableObj =
798     Handle(HYDROData_StricklerTable)::DownCast( theDocument->CreateObject(KIND_STRICKLER_TABLE) );      
799   if ( !aStricklerTableObj.IsNull() )
800   {
801     SUIT_ResourceMgr* resMgr = module()->application()->resourceMgr();
802     QString defTablePath = resMgr->path( "resources", module()->name(), tr( "DEFAULT_STRICKLER_TABLE_FILE" ) );
803     aStricklerTableObj->Import( HYDROGUI_Tool::ToAsciiString( defTablePath ) );
804         // Set name
805     QString aStricklerTableName;
806     if ( aStricklerTableObj->GetName().isEmpty() )
807     {
808       HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
809       if ( aModule )
810         aStricklerTableName = HYDROGUI_Tool::GenerateObjectName( aModule, tr( "DEFAULT_STRICKLER_TABLE_NAME" ) );
811     }
812     if ( aStricklerTableObj->GetName() != aStricklerTableName )
813       aStricklerTableObj->SetName( aStricklerTableName );
814
815     aStricklerTableObj->Update();
816
817     LightApp_DataObject* obj = createObject( theParent, aStricklerTableObj );
818   }
819 }
820
821 LightApp_DataObject* HYDROGUI_DataModel::createObject( SUIT_DataObject* theParent,
822                                                        const QString&   theName,
823                                                        const QString&   theParentEntry )
824 {
825   return new HYDROGUI_NamedObject( theParent, theName, theParentEntry );
826 }
827
828 void HYDROGUI_DataModel::buildObjectPartition( SUIT_DataObject*                   theObject,
829                                                const HYDROData_SequenceOfObjects& theObjects,
830                                                const QString&                     thePartName,
831                                                const bool                         theIsCreateEmpty )
832 {
833   if ( theObjects.IsEmpty() && !theIsCreateEmpty )
834     return;
835
836   HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>( theObject );
837   if ( !aGuiObj )
838     return;
839
840   LightApp_DataObject* aPartSect = 
841     createObject( aGuiObj, thePartName, aGuiObj->entry() );
842
843   HYDROData_SequenceOfObjects::Iterator anIter( theObjects );
844   for ( ; anIter.More(); anIter.Next() )
845   {
846     Handle(HYDROData_Entity) anObj = anIter.Value();
847     if( !anObj.IsNull() && !anObj->IsRemoved() )
848       createObject( aPartSect, anObj, aGuiObj->entry(), false );
849   }
850 }
851
852 void HYDROGUI_DataModel::buildObjectTree( SUIT_DataObject* theParent,
853                                           SUIT_DataObject* theObject,
854                                           const QString&   theParentEntry,
855                                           const bool       theIsInOperation )
856 {
857   HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>( theObject );
858   if ( !aGuiObj )
859     return;
860
861   Handle(HYDROData_Entity) aDataObj = aGuiObj->modelObject();
862   if ( aDataObj.IsNull() )
863     return;
864
865   if ( aDataObj->IsKind( STANDARD_TYPE(HYDROData_Object) ) )
866   {
867     Handle(HYDROData_Object) aGeomObj =
868       Handle(HYDROData_Object)::DownCast( aDataObj );
869
870     Handle(HYDROData_DummyObject3D) anObject3D = aGeomObj->GetObject3D();
871     if ( !anObject3D.IsNull() )
872       createObject( aGuiObj, anObject3D, "", false );
873
874 #ifdef DEB_GROUPS
875     HYDROData_SequenceOfObjects anObjGroups = aGeomObj->GetGroups();
876     buildObjectPartition( aGuiObj, anObjGroups, tr( "OBJECT_GROUPS" ), false );
877 #endif
878   }
879
880   ObjectKind anObjectKind = aDataObj->GetKind();
881
882   if ( anObjectKind == KIND_IMAGE )
883   {
884     Handle(HYDROData_Image) anImageObj =
885       Handle(HYDROData_Image)::DownCast( aDataObj );
886     for ( int anIndex = 0, aNbRef = anImageObj->NbReferences(); anIndex < aNbRef; anIndex++ )
887     {
888       Handle(HYDROData_Entity) aRefObj = anImageObj->Reference( anIndex );
889       if ( !aRefObj.IsNull() && !aRefObj->IsRemoved() )
890         createObject( aGuiObj, aRefObj, aGuiObj->entry(), false );
891     }
892   }
893   else if ( anObjectKind == KIND_IMMERSIBLE_ZONE )
894   {
895     Handle(HYDROData_ImmersibleZone) aZoneObj =
896       Handle(HYDROData_ImmersibleZone)::DownCast( aDataObj );
897
898     LightApp_DataObject* aPolylineSect = 
899       createObject( aGuiObj, tr( "ZONE_POLYLINE" ), aGuiObj->entry() );
900
901     Handle(HYDROData_PolylineXY) aPolyline = aZoneObj->GetPolyline();
902     if ( !aPolyline.IsNull() && !aPolyline->IsRemoved() )
903       createObject( aPolylineSect, aPolyline, aGuiObj->entry(), false );
904
905     LightApp_DataObject* aBathSect = 
906       createObject( aGuiObj, tr( "ZONE_BATHYMETRY" ), aGuiObj->entry() );
907
908     Handle(HYDROData_IAltitudeObject) anAltitudeObj = aZoneObj->GetAltitudeObject();
909     if ( !anAltitudeObj.IsNull() && !anAltitudeObj->IsRemoved() )
910       createObject( aBathSect, anAltitudeObj, aGuiObj->entry(), false );
911   }
912   else if ( anObjectKind == KIND_POLYLINE )
913   {
914     Handle(HYDROData_Polyline3D) aPolyline3D =
915       Handle(HYDROData_Polyline3D)::DownCast( aDataObj );
916
917     LightApp_DataObject* aPolylineSect = 
918       createObject( aGuiObj, tr( "POLYLINE3D_POLYLINE" ), aGuiObj->entry() );
919
920     Handle(HYDROData_PolylineXY) aPolylineXY = aPolyline3D->GetPolylineXY();
921     if ( !aPolylineXY.IsNull() && !aPolylineXY->IsRemoved() )
922       createObject( aPolylineSect, aPolylineXY, aGuiObj->entry(), false );
923
924     LightApp_DataObject* aProfileSect = 
925       createObject( aGuiObj, tr( "POLYLINE3D_PROFILE" ), aGuiObj->entry() );
926
927     Handle(HYDROData_ProfileUZ) aProfileUZ = aPolyline3D->GetProfileUZ();
928     if ( aProfileUZ.IsNull() || aProfileUZ->IsRemoved() )
929       aProfileUZ = aPolyline3D->GetChildProfileUZ( false );
930
931     if ( !aProfileUZ.IsNull() && !aProfileUZ->IsRemoved() )
932     {
933       Handle(HYDROData_Profile) aProfile = 
934         Handle(HYDROData_Profile)::DownCast( aProfileUZ->GetFatherObject() );
935       if ( !aProfile.IsNull() && !aProfile->IsRemoved() )
936         createObject( aProfileSect, aProfile, aGuiObj->entry(), false );
937     }
938
939     LightApp_DataObject* aBathSect = 
940       createObject( aGuiObj, tr( "POLYLINE3D_BATHYMETRY" ), aGuiObj->entry() );
941
942     Handle(HYDROData_IAltitudeObject) anAltitudeObj = aPolyline3D->GetAltitudeObject();
943     if ( !anAltitudeObj.IsNull() && !anAltitudeObj->IsRemoved() )
944       createObject( aBathSect, anAltitudeObj, aGuiObj->entry(), false );
945   }
946   else if ( anObjectKind == KIND_CALCULATION )
947   {
948     Handle(HYDROData_CalculationCase) aCaseObj =
949       Handle(HYDROData_CalculationCase)::DownCast( aDataObj );
950
951     LightApp_DataObject* aPolylineSect = 
952       createObject( aGuiObj, tr( "CASE_BOUNDARY" ), aGuiObj->entry() );
953
954     Handle(HYDROData_PolylineXY) aPolyline = aCaseObj->GetBoundaryPolyline();
955     if ( !aPolyline.IsNull() && !aPolyline->IsRemoved() )
956       createObject( aPolylineSect, aPolyline, aGuiObj->entry(), false );
957
958     LightApp_DataObject* aCaseAOSect = 
959       createObject( aGuiObj, tr( partitionName( KIND_ARTIFICIAL_OBJECT ).toAscii() ),
960                     aGuiObj->entry() );
961     LightApp_DataObject* aCaseNOSect = 
962       createObject( aGuiObj, tr( partitionName( KIND_NATURAL_OBJECT ).toAscii() ),
963                     aGuiObj->entry() );
964
965     HYDROData_SequenceOfObjects aSeq = aCaseObj->GetGeometryObjects();
966     HYDROData_SequenceOfObjects::Iterator aGOIter( aSeq );
967     Handle(HYDROData_Entity) anEntity;
968     Handle(HYDROData_ArtificialObject) anAObject;
969     Handle(HYDROData_NaturalObject) aNObject;
970     for ( ; aGOIter.More(); aGOIter.Next() )
971     {
972       anEntity = aGOIter.Value();
973       if ( anEntity.IsNull() )
974         continue;
975       anAObject = Handle(HYDROData_ArtificialObject)::DownCast( anEntity );
976       if ( !anAObject.IsNull() )
977         createObject( aCaseAOSect, anAObject, aGuiObj->entry(), false );
978       else
979       {
980         aNObject = Handle(HYDROData_NaturalObject)::DownCast( anEntity );
981         if ( !aNObject.IsNull() )
982           createObject( aCaseNOSect, aNObject, aGuiObj->entry(), false );
983       }
984     }
985     LightApp_DataObject* aCaseRegionsSect = 
986       createObject( aGuiObj, tr( "CASE_REGIONS" ), aGuiObj->entry() );
987
988     HYDROData_SequenceOfObjects aCaseRegions = aCaseObj->GetRegions();
989     HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions );
990     for ( ; anIter.More(); anIter.Next() )
991     {
992       Handle(HYDROData_Region) aCaseRegion =
993         Handle(HYDROData_Region)::DownCast( anIter.Value() );
994       if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() )
995         createRegion( aCaseRegionsSect, aCaseRegion, "", true, theIsInOperation );
996     }
997
998 #ifdef DEB_GROUPS
999     HYDROData_SequenceOfObjects aCalcGroups = aCaseObj->GetGeometryGroups();
1000     buildObjectPartition( aGuiObj, aCalcGroups, tr( "OBJECT_GROUPS" ), false );
1001
1002     HYDROData_SequenceOfObjects aCalcSplitGroups = aCaseObj->GetSplittedGroups();
1003     buildObjectPartition( aGuiObj, aCalcSplitGroups, tr( "CASE_SPLITTED_GROUPS" ), false );
1004 #endif
1005
1006   }
1007   else if ( anObjectKind == KIND_REGION )
1008   {
1009     Handle(HYDROData_Region) aRegionObj =
1010       Handle(HYDROData_Region)::DownCast( aDataObj );
1011
1012     HYDROData_SequenceOfObjects aRegionZones = aRegionObj->GetZones();
1013     HYDROData_SequenceOfObjects::Iterator anIter( aRegionZones );
1014     for ( ; anIter.More(); anIter.Next() )
1015     {
1016       Handle(HYDROData_Zone) aRegionZone =
1017         Handle(HYDROData_Zone)::DownCast( anIter.Value() );
1018       if( !aRegionZone.IsNull() && !aRegionZone->IsRemoved() )
1019         createZone( aGuiObj, aRegionZone, "", true, theIsInOperation );
1020     }
1021   }
1022   else if ( anObjectKind == KIND_PROFILE )
1023   {
1024     Handle(HYDROData_Profile) aProfileObj =
1025       Handle(HYDROData_Profile)::DownCast( aDataObj );
1026
1027     aGuiObj->setIsValid( aProfileObj->IsValid() );
1028   }
1029   else if ( anObjectKind == KIND_CHANNEL || anObjectKind == KIND_DIGUE )
1030   {
1031     Handle(HYDROData_Channel) aChannelObj =
1032       Handle(HYDROData_Channel)::DownCast( aDataObj );
1033
1034     LightApp_DataObject* aGuideLineSect = 
1035       createObject( aGuiObj, tr( "CHANNEL_GUIDE_LINE" ), aGuiObj->entry() );
1036     Handle(HYDROData_Polyline3D) aGuideLine = aChannelObj->GetGuideLine();
1037     if ( !aGuideLine.IsNull() && !aGuideLine->IsRemoved() ) {
1038       createObject( aGuideLineSect, aGuideLine, aGuiObj->entry(), false );
1039     }
1040
1041     LightApp_DataObject* aProfileSect = 
1042       createObject( aGuiObj, tr( "CHANNEL_PROFILE" ), aGuiObj->entry() );
1043     Handle(HYDROData_Profile) aProfile = aChannelObj->GetProfile();
1044     if ( !aProfile.IsNull() && !aProfile->IsRemoved() ) {
1045       createObject( aProfileSect, aProfile, aGuiObj->entry(), false );
1046     }
1047   }
1048   else if ( anObjectKind == KIND_STREAM )
1049   {
1050     Handle(HYDROData_Stream) aStreamObj =
1051       Handle(HYDROData_Stream)::DownCast( aDataObj );
1052
1053     LightApp_DataObject* aHydraulicAxisSect = 
1054       createObject( aGuiObj, tr( "STREAM_HYDRAULIC_AXIS" ), aGuiObj->entry() );
1055     Handle(HYDROData_PolylineXY) aHydraulicAxis = aStreamObj->GetHydraulicAxis();
1056     if ( !aHydraulicAxis.IsNull() && !aHydraulicAxis->IsRemoved() ) {
1057       createObject( aHydraulicAxisSect, aHydraulicAxis, aGuiObj->entry(), false );
1058     }
1059
1060     HYDROData_SequenceOfObjects aProfiles = aStreamObj->GetProfiles();
1061     buildObjectPartition( aGuiObj, aProfiles, tr( "STREAM_PROFILES" ), true );
1062
1063     Handle(HYDROData_Polyline3D) aBottomPolyline = aStreamObj->GetBottomPolyline();
1064     if ( !aBottomPolyline.IsNull() && !aBottomPolyline->IsRemoved() ) {
1065       createObject( aGuiObj, aBottomPolyline, aGuiObj->entry(), false );
1066     }
1067   }
1068 }
1069
1070 void HYDROGUI_DataModel::buildCaseTree( SUIT_DataObject* theParent, Handle(HYDROData_CalculationCase) theCase )
1071 {
1072   if ( !theCase.IsNull() )
1073   {
1074     if ( theParent )
1075     {
1076       // Remove previous objects tree
1077         DataObjectList aList;
1078         theParent->children( aList );
1079         QListIterator<SUIT_DataObject*> anIter( aList );
1080         while( anIter.hasNext() )
1081           removeChild( theParent, anIter.next() );
1082     }
1083
1084     new HYDROGUI_DropTargetObject( theParent, tr( "NEW_REGION" ), "", true );
1085
1086     HYDROData_SequenceOfObjects aCaseRegions = theCase->GetRegions();
1087     HYDROData_SequenceOfObjects::Iterator anIter( aCaseRegions );
1088     for ( ; anIter.More(); anIter.Next() )
1089     {
1090       Handle(HYDROData_Region) aCaseRegion =
1091         Handle(HYDROData_Region)::DownCast( anIter.Value() );
1092       if( !aCaseRegion.IsNull() && !aCaseRegion->IsRemoved() )
1093         createRegion( theParent, aCaseRegion, "", true, true );
1094     }
1095   }
1096 }
1097
1098 void HYDROGUI_DataModel::updateObjectTree( Handle(HYDROData_Entity)& theObj )
1099 {
1100   if ( !theObj.IsNull() )
1101   {
1102     HYDROGUI_DataObject* aGuiObj = dynamic_cast<HYDROGUI_DataObject*>(
1103       findObject( HYDROGUI_DataObject::dataObjectEntry( theObj ) ) );
1104     if ( aGuiObj )
1105     {
1106       // Remove previous objects tree
1107       DataObjectList aList;
1108       aGuiObj->children( aList );
1109       QListIterator<SUIT_DataObject*> anIter( aList );
1110       while( anIter.hasNext() )
1111         removeChild( aGuiObj, anIter.next() );
1112
1113       // Rebuild the subtree
1114       QString aParentEntry;
1115       HYDROGUI_DataObject* aParent = dynamic_cast<HYDROGUI_DataObject*>( aGuiObj->parent() );
1116       if ( aParent )
1117       {
1118         aParentEntry = aParent->entry();
1119       }
1120       buildObjectTree( aParent, aGuiObj, aParentEntry, aGuiObj->isInOperation() );
1121     } 
1122     else
1123     {
1124       // workaround for the bug in SalomeApp_Study::findObjectByEntry - it can't find LightApp_DataObjects
1125       HYDROGUI_Module* aModule = dynamic_cast<HYDROGUI_Module*>( module() );
1126       if( aModule )
1127       {
1128         aModule->getApp()->updateObjectBrowser();
1129       }
1130     }
1131   }
1132 }
1133
1134 void HYDROGUI_DataModel::removeChild( SUIT_DataObject* theParent,
1135                                       SUIT_DataObject* theChild )
1136 {
1137   SUIT_DataObject* aSubChild = theChild->firstChild();
1138   for( ; aSubChild; aSubChild = aSubChild->nextBrother() )
1139     removeChild( theChild, aSubChild );
1140   theParent->removeChild( theChild );
1141 }
1142
1143 SUIT_DataObject* HYDROGUI_DataModel::findChildByName( const SUIT_DataObject* theFather,
1144                                                       const QString& theName )
1145 {
1146   SUIT_DataObject* aChild = theFather->firstChild();
1147   while( aChild )
1148   {
1149     if( aChild->name() == theName )
1150       return aChild; // found
1151     aChild = aChild->nextBrother();
1152   }
1153   return NULL; // not found
1154 }
1155
1156 bool HYDROGUI_DataModel::createNewRegion( Handle(HYDROData_CalculationCase) theCase, 
1157                                          const QList<HYDROGUI_Zone*>& theZonesList )
1158 {
1159   bool isOk = !theCase.IsNull();
1160   if ( isOk )
1161   {
1162     Handle(HYDROData_Region) aRegion;
1163     Handle(HYDROData_Zone) aZone;
1164     for (int i = 0; i < theZonesList.length(); i++ )
1165     {
1166       aZone = Handle(HYDROData_Zone)::DownCast( theZonesList.at(i)->modelObject() );
1167       if ( !aZone.IsNull() )
1168       {
1169         if ( aRegion.IsNull() )
1170         {
1171           aRegion = theCase->AddNewRegion( aZone );
1172           isOk = !aRegion.IsNull();
1173         }
1174         else
1175         {
1176           if ( !( aRegion->AddZone( aZone ) ) )
1177           {
1178             isOk = false;
1179           }
1180         }
1181       }
1182     }
1183   }
1184   return isOk;
1185 }
1186
1187 bool HYDROGUI_DataModel::rename( Handle(HYDROData_Entity) theEntity, const QString& theName )
1188 {
1189   if ( theName.isEmpty() )
1190     return false;
1191
1192   try 
1193   {
1194     getDocument()->StartOperation();
1195     theEntity->SetName( theName );
1196     getDocument()->CommitOperation( HYDROGUI_Tool::ToExtString( tr("RENAME_TO").arg( theName ) ) );
1197     module()->application()->activeStudy()->Modified();
1198   }
1199   catch ( Standard_Failure )
1200   {
1201     getDocument()->AbortOperation();
1202     return false;
1203   }
1204   return true;
1205 }