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