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