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