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