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