Salome HOME
Merge branch 'BR_v14_rc' of ssh://git.salome-platform.org/modules/hydro into BR_v14_rc
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_CalculationOp.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_CalculationOp.h"
20
21 #include "HYDROGUI_DataModel.h"
22 #include "HYDROGUI_CalculationDlg.h"
23 #include "HYDROGUI_Module.h"
24 #include "HYDROGUI_Tool.h"
25 #include "HYDROGUI_UpdateFlags.h"
26 #include "HYDROGUI_Zone.h"
27 #include "HYDROGUI_Region.h"
28
29 #include <HYDROData_PolylineXY.h>
30 #include <HYDROData_ShapesGroup.h>
31 #include <HYDROData_Iterator.h>
32 #include <HYDROData_ImmersibleZone.h>
33 #include <HYDROData_Object.h>
34 #include <HYDROData_Tool.h>
35 #include <HYDROData_StricklerTable.h>
36
37 #include <OCCViewer_ViewManager.h>
38 #include <OCCViewer_ViewModel.h>
39 #include <OCCViewer_ViewWindow.h>
40
41 #include <LightApp_Application.h>
42 #include <LightApp_UpdateFlags.h>
43 #include <LightApp_SelectionMgr.h>
44 #include <LightApp_DataOwner.h>
45
46 #include <SUIT_MessageBox.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_DataBrowser.h>
49
50 #include <QApplication>
51 #include <QKeySequence>
52 #include <QShortcut>
53
54 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
55 : HYDROGUI_Operation( theModule ),
56   myIsEdit( theIsEdit ),
57   myActiveViewManager( NULL ),
58   myPreviewViewManager( NULL ),
59   myShowGeomObjects( true ),
60   myShowLandCovers( false ),
61   myShowZones( false )
62 {
63   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
64 }
65
66 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
67 {
68   closePreview();
69 }
70
71 void HYDROGUI_CalculationOp::startOperation()
72 {
73   HYDROGUI_Operation::startOperation();
74   
75   // Begin transaction
76   startDocOperation();
77
78   HYDROGUI_CalculationDlg* aPanel = 
79     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
80   if ( !aPanel )
81     return;
82
83   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
84   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
85   QShortcut* aShortcut;
86   foreach( aShortcut, aShortcuts )
87   {
88     if ( aShortcut->key() == 
89       QKeySequence(((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
90       SUIT_DataBrowser::RenameShortcut ) ) )
91     {
92       aShortcut->setEnabled( false );
93     }
94   }
95
96   aPanel->reset();
97   QStringList aList;
98   QStringList anEntryList;
99   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetGeometryObjects( module() );
100   getNamesAndEntries( aSeq, aList, anEntryList );
101   aPanel->setAllGeomObjects( aList, anEntryList );
102
103   // Get all polylines
104   aList.clear();
105   anEntryList.clear();
106   HYDROData_Iterator anIter( doc(), KIND_POLYLINEXY );
107   Handle(HYDROData_PolylineXY) aPolylineObj;
108   QString aPolylineName;
109   for ( ; anIter.More(); anIter.Next() )
110   {
111     aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( anIter.Current() );
112
113     if ( !aPolylineObj.IsNull() && aPolylineObj->IsClosed() )
114     { 
115       // Check the polyline shape
116       TopoDS_Shape aPolylineShape = aPolylineObj->GetShape();
117       if ( !aPolylineShape.IsNull() && aPolylineShape.ShapeType() == TopAbs_WIRE ) {
118         aPolylineName = aPolylineObj->GetName();
119         if ( !aPolylineName.isEmpty() )
120         {
121           aList.append( aPolylineName );
122           anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aPolylineObj ) );
123         }
124       }
125     }
126   }
127   aPanel->setPolylineNames( aList, anEntryList );
128
129   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_CALCULATION_CASE_NAME" ) );
130
131   myEditedObject.Nullify();
132   if ( myIsEdit )
133   {
134     myEditedObject = Handle(HYDROData_CalculationCase)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
135     if ( !myEditedObject.IsNull() )
136     {
137       aPanel->setMode( myEditedObject->GetAssignmentMode() );
138       anObjectName = myEditedObject->GetName();
139       aPolylineObj = myEditedObject->GetBoundaryPolyline();
140       if ( aPolylineObj.IsNull() )
141       {
142         aPanel->setBoundary( QString() );
143       }
144       else
145       {
146         aPolylineName = aPolylineObj->GetName();
147         aPanel->setBoundary( aPolylineName );
148       }
149
150       aSeq = myEditedObject->GetGeometryObjects();
151       getNamesAndEntries( aSeq, aList, anEntryList );
152       aPanel->includeGeomObjects( aList );
153
154       // set rules
155       setRules( HYDROData_CalculationCase::DataTag_CustomRules );      
156     }
157   }
158   else
159   {
160     myEditedObject =
161       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
162     myEditedObject->SetName( anObjectName );
163     myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getMode() );
164   }
165
166   aPanel->setObjectName( anObjectName );
167   aPanel->setEditedObject( myEditedObject );
168
169   createPreview( false );
170 }
171
172 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
173                                                 QStringList& theNames, QStringList& theEntries ) const
174 {
175  
176   theNames.clear();
177   theEntries.clear();
178   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
179   for ( ; anIter.More(); anIter.Next() )
180   {
181     Handle(HYDROData_Entity) anEntity = anIter.Value();
182     //if ( !HYDROData_Tool::IsGeometryObject( anEntity ) )
183     //  continue;
184
185     theNames.append( anEntity->GetName() );
186     theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anEntity ) );
187   }
188 }
189
190 void HYDROGUI_CalculationOp::abortOperation()
191 {
192   closePreview();
193   // Abort transaction
194   abortDocOperation();
195   HYDROGUI_Operation::abortOperation();
196   module()->getApp()->updateObjectBrowser();
197 }
198
199 void HYDROGUI_CalculationOp::commitOperation()
200 {
201   closePreview();
202   // Commit transaction
203   commitDocOperation();
204   HYDROGUI_Operation::commitOperation();
205 }
206
207 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
208 {
209   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
210
211   // Connect signals and slots
212   connect( aPanel, SIGNAL( changeMode( int ) ), SLOT( onChangeMode( int ) ) );  
213   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
214   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
215   connect( aPanel, SIGNAL( addGroups() ), SLOT( onAddGroups() ) );
216   connect( aPanel, SIGNAL( removeGroups() ), SLOT( onRemoveGroups() ) );
217
218   connect( aPanel, SIGNAL( changeLandCoverMode( int ) ), SLOT( onChangeLandCoverMode( int ) ) );
219   connect( aPanel, SIGNAL( addLandCovers() ), SLOT( onAddLandCovers() ) );
220   connect( aPanel, SIGNAL( removeLandCovers() ), SLOT( onRemoveLandCovers() ) );
221   
222   connect( aPanel, SIGNAL( orderChanged( bool& ) ), SLOT( onOrderChanged( bool& ) ) );
223   connect( aPanel, SIGNAL( orderLandCoverChanged( bool& ) ), SLOT( onOrderLandCoverChanged( bool& ) ) );
224     
225   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
226   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onHideZones( const int ) ) );
227   //connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
228   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
229   connect( aPanel, SIGNAL( setMergeStricklerType( int, QString& ) ), SLOT( onSetMergeStricklerType( int, QString& ) ) );
230   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>&, bool ) ),
231     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>&, bool ) ) );
232   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
233     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
234   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
235     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
236   connect( aPanel, SIGNAL( objectsSelected() ), 
237            SLOT( onObjectsSelected() ) );
238   connect( aPanel, SIGNAL( landCoversSelected() ), 
239            SLOT( onLandCoversSelected() ) );
240   connect( aPanel, SIGNAL( createLandCoverRegion( const QList<SUIT_DataObject*>& ) ),
241     SLOT( onCreateLandCoverRegion( const QList<SUIT_DataObject*>& ) ) );
242   connect( aPanel, SIGNAL( boundarySelected( const QString & ) ), 
243     SLOT( onBoundarySelected( const QString & ) ) );
244   connect( aPanel, SIGNAL( StricklerTableSelected( const QString & ) ), 
245     SLOT( onStricklerTableSelected( const QString & ) ) );
246
247   return aPanel;
248 }
249
250 void HYDROGUI_CalculationOp::onBoundarySelected ( const QString & theObjName )
251 {
252   bool anIsToUpdateViewer = false;
253
254   // Remove the old boundary from the operation viewer
255   Handle(HYDROData_PolylineXY) aPrevPolyline = 
256     myEditedObject->GetBoundaryPolyline();
257   if ( !aPrevPolyline.IsNull() )
258   {
259     setObjectVisibility( aPrevPolyline, false );
260     anIsToUpdateViewer = true;
261   }
262
263   // Set the selected boundary polyline to the calculation case
264   Handle(HYDROData_PolylineXY) aNewPolyline = Handle(HYDROData_PolylineXY)::DownCast(
265     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_POLYLINEXY ) );
266   myEditedObject->SetBoundaryPolyline( aNewPolyline );
267
268   if ( myPreviewViewManager )
269   {
270     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
271     if ( aViewer )
272     {
273       if ( !aNewPolyline.IsNull() )
274       {
275         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
276         if ( !aCtx.IsNull() )
277         {
278           setObjectVisibility( aNewPolyline, true );
279           anIsToUpdateViewer = true;
280         }
281       }
282
283       if ( anIsToUpdateViewer )
284         module()->update( UF_OCCViewer );
285     }
286   }
287 }
288
289 void HYDROGUI_CalculationOp::onStricklerTableSelected ( const QString & theObjName )
290 {
291   bool anIsToUpdateViewer = false;
292
293   // Remove old presentations of land covers from the operation viewer  
294   Handle(HYDROData_Entity) anEntity;
295   Handle(HYDROData_LandCover) aLandCover;
296   HYDROData_SequenceOfObjects aLandCovers;
297   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
298   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
299   for ( ; anIter.More(); anIter.Next() )
300   {
301     anEntity = anIter.Value();
302     if ( !anEntity.IsNull() )
303     {
304       aLandCover = Handle(HYDROData_LandCover)::DownCast( anEntity );
305       if ( !aLandCover.IsNull() )
306       {
307         aLandCovers.Append( aLandCover );
308         setObjectVisibility( aLandCover, false );
309         anIsToUpdateViewer = true;
310       }
311     }
312   }
313
314   // Set the selected Strickler table to the calculation case
315   Handle(HYDROData_StricklerTable) aNewStricklerTable = Handle(HYDROData_StricklerTable)::DownCast(
316     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_STRICKLER_TABLE ) );
317   myEditedObject->SetStricklerTable( aNewStricklerTable );
318
319   if ( myPreviewViewManager )
320   {
321     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
322     if ( aViewer )
323     {
324       if ( !aNewStricklerTable.IsNull() )
325       {
326         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
327         if ( !aCtx.IsNull() )
328         {
329           HYDROData_SequenceOfObjects::Iterator anIter( aLandCovers );
330           for ( ; anIter.More(); anIter.Next() )
331           {
332             anEntity = anIter.Value();
333             if ( !anEntity.IsNull() )
334             {
335               aLandCover = Handle(HYDROData_LandCover)::DownCast( anEntity );
336               if ( !aLandCover.IsNull() )
337               {
338                 setObjectVisibility( aLandCover, true );
339                 anIsToUpdateViewer = true;
340               }
341             }
342           }          
343         }
344       }
345
346       if ( anIsToUpdateViewer )
347         module()->update( UF_OCCViewer );
348     }
349   }
350 }
351
352 void HYDROGUI_CalculationOp::onObjectsSelected()
353 {
354   HYDROGUI_CalculationDlg* aPanel = 
355     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
356
357   QStringList aSelectedObjs = aPanel->getSelectedGeomObjects();
358   QMap<QString, bool> aSelectedObjsMap;
359   foreach( QString aName, aSelectedObjs )
360     aSelectedObjsMap[aName] = true;
361
362
363   // Select the appropriate geometry object shape in the viewer
364   selectionMgr()->clearSelected();
365
366   // Unhighlight all objects except selected
367   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
368   Handle(HYDROData_Entity) anEntity;
369   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
370   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
371   bool isSelected;
372   QString aName;
373   for ( ; anIter.More(); anIter.Next() )
374   {
375     anEntity = anIter.Value();
376     if ( !anEntity.IsNull() )
377     {
378       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
379       if ( aShape )
380       {
381         aName = anEntity->GetName();
382         isSelected = aSelectedObjsMap.contains( aName );
383         aShape->highlight( isSelected, false );
384         aShape->update( false, false );
385         aLastShape = aShape;
386       }
387     }
388   }
389   if( aLastShape )
390     aLastShape->update( true, false );
391 }
392
393 void HYDROGUI_CalculationOp::onLandCoversSelected()
394 {
395   HYDROGUI_CalculationDlg* aPanel = 
396     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
397
398   QStringList aSelectedObjs = aPanel->getSelectedLandCovers();
399   QMap<QString, bool> aSelectedObjsMap;
400   foreach( QString aName, aSelectedObjs )
401     aSelectedObjsMap[aName] = true;
402
403
404   // Select the appropriate land cover shape in the viewer
405   selectionMgr()->clearSelected();
406
407   // Unhighlight all land covers except selected
408   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
409   Handle(HYDROData_Entity) anEntity;
410   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
411   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
412   bool isSelected;
413   QString aName;
414   for ( ; anIter.More(); anIter.Next() )
415   {
416     anEntity = anIter.Value();
417     if ( !anEntity.IsNull() )
418     {
419       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
420       if ( aShape )
421       {
422         aName = anEntity->GetName();
423         isSelected = aSelectedObjsMap.contains( aName );
424         aShape->highlight( isSelected, false );
425         aShape->update( false, false );
426         aLastShape = aShape;
427       }
428     }
429   }
430   if( aLastShape )
431     aLastShape->update( true, false );
432 }
433
434 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
435 {
436   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
437   HYDROGUI_Zone* aZoneItem;
438   selectionMgr()->clearSelected();
439   if ( aRegionItem )
440   {
441     // Select a region in preview
442     SUIT_DataOwnerPtrList aList( true );
443     DataObjectList aZones = aRegionItem->children();
444     for ( int i = 0; i < aZones.length(); i++ )
445     {
446       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
447       if ( aZoneItem )
448       {
449         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
450       }
451     }
452     selectionMgr()->setSelected( aList );
453   }
454   else
455   {
456     // select a single zone
457     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
458     if ( aZoneItem )
459     {
460       SUIT_DataOwnerPtrList aList( true );
461       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
462       selectionMgr()->setSelected( aList );
463     }
464   }
465 }
466
467 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem,
468                                           const QList<SUIT_DataObject*>& theZonesList,
469                                           bool theLandCover )
470 {
471   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
472   if ( aRegion )
473   {
474     QList<HYDROGUI_Zone*> aZonesList;
475     HYDROGUI_Zone* aZone;
476     // Get a list of dropped zones
477     for ( int i = 0; i < theZonesList.length(); i++ )
478     {
479       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
480       if ( aZone )
481       {
482         aZonesList.append( aZone );
483       }
484     }
485     if ( aZonesList.length() > 0 )
486     {
487       aRegion->addZones( aZonesList );
488       HYDROGUI_CalculationDlg* aPanel = 
489         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
490       if ( aPanel )
491       {
492         theLandCover ? aPanel->refreshLandCoverZonesBrowser(): aPanel->refreshZonesBrowser();
493       }
494       createPreview( theLandCover );
495     }
496   }
497 }
498
499 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
500 {
501   if ( createRegion( theZonesList, false ) )
502   {
503     HYDROGUI_CalculationDlg* aPanel = 
504       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
505     if ( aPanel )
506     {
507       aPanel->refreshZonesBrowser();
508     }
509     createPreview( false );
510   }
511 }
512
513 void HYDROGUI_CalculationOp::onCreateLandCoverRegion( const QList<SUIT_DataObject*>& theZonesList )
514 {
515   if ( createRegion( theZonesList, true ) )
516   {
517     HYDROGUI_CalculationDlg* aPanel = 
518       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
519     if ( aPanel )
520     {
521       aPanel->refreshLandCoverZonesBrowser();
522     }
523     createPreview( true );
524   }
525 }
526
527 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theMergeObjectName )
528 {
529   HYDROGUI_CalculationDlg* aPanel = 
530     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
531   if ( aPanel )
532   {
533     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
534     if ( aZone )
535     {
536       aZone->setMergeType( theMergeType, theMergeObjectName );
537       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
538       if ( aShape )
539       {
540         aShape->update( true, false );
541       }
542     }
543     aPanel->refreshZonesBrowser();
544   }
545 }
546
547 void HYDROGUI_CalculationOp::onSetMergeStricklerType( int theMergeType, QString& theStricklerTypeName )
548 {
549   HYDROGUI_CalculationDlg* aPanel = 
550     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
551   if ( aPanel )
552   {
553     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
554     if ( aZone )
555     {
556       aZone->setMergeType( theMergeType, theStricklerTypeName );
557       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
558       if ( aShape )
559       {
560         aShape->update( true, false );
561       }
562     }
563     aPanel->refreshLandCoverZonesBrowser();
564   }
565 }
566
567 void HYDROGUI_CalculationOp::onAddObjects()
568 {
569   HYDROGUI_CalculationDlg* aPanel = 
570     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
571   if ( !aPanel )
572     return;
573
574   // Add geometry objects selected in the module browser to the calculation case
575   QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
576   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
577     return;
578
579   QStringList anAddedList;
580   for (int i = 0; i < aSelectedList.length(); i++)
581   {
582     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
583       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
584     if ( anObject.IsNull() )
585       continue;
586
587     if ( myEditedObject->AddGeometryObject( anObject ) )
588       anAddedList.append( anObject->GetName() );
589   }
590
591   if ( !anAddedList.isEmpty() )
592   {
593     aPanel->includeGeomObjects( anAddedList );
594     createPreview( false );
595   }
596 }
597
598 void HYDROGUI_CalculationOp::onRemoveObjects()
599 {
600   // Remove selected objects from the calculation case
601   HYDROGUI_CalculationDlg* aPanel = 
602     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
603   if ( !aPanel )
604     return;
605
606   QStringList aSelectedList = aPanel->getSelectedGeomObjects();
607   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
608     return;
609
610   for (int i = 0; i < aSelectedList.length(); i++)
611   {
612     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
613       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
614     if ( anObject.IsNull() )
615       continue;
616
617     setObjectVisibility( anObject, false );
618     myEditedObject->RemoveGeometryObject( anObject );
619   }
620
621   module()->update( UF_OCCViewer );
622   aPanel->excludeGeomObjects( aSelectedList );
623 }
624
625 bool HYDROGUI_CalculationOp::confirmRegionsChange() const
626 {
627   // Check if the case is already modified or not
628   bool isConfirmed = myEditedObject->IsMustBeUpdated();
629   if ( !isConfirmed )
630   {
631     // If not modified check if the case has already defined regions with zones
632     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions( false );
633     if ( aSeq.Length() > 0 )
634     {
635       // If there are already defined zones then ask a user to confirm zones recalculation
636       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
637                                tr( "REGIONS_CHANGED" ),
638                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_REGIONS" ),
639                                QMessageBox::Yes | QMessageBox::No,
640                                QMessageBox::No ) == QMessageBox::Yes );
641     }
642     else
643     {
644       isConfirmed = true; // No regions - no zones - nothing to recalculate
645     }
646   }
647   return isConfirmed;
648 }
649
650 bool HYDROGUI_CalculationOp::confirmOrderChange() const
651 {
652   // Check if the case is already modified or not
653   bool isConfirmed = myEditedObject->IsMustBeUpdated();
654   if ( !isConfirmed )
655   {
656     // If not modified check if the case has already defined regions with zones
657     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions( false );
658     if ( aSeq.Length() > 0 )
659     {
660       // If there are already defined zones then ask a user to confirm zones recalculation
661       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
662                                tr( "ORDER_CHANGED" ),
663                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_REGIONS" ),
664                                QMessageBox::Yes | QMessageBox::No,
665                                QMessageBox::No ) == QMessageBox::Yes );
666     }
667     else
668     {
669       isConfirmed = true; // No regions - no zones - nothing to recalculate
670     }
671   }
672   return isConfirmed;
673 }
674
675 bool HYDROGUI_CalculationOp::confirmModeChange() const
676 {
677   // Check if the case is already modified or not
678   bool isConfirmed = myEditedObject->IsMustBeUpdated();
679   if ( !isConfirmed )
680   {
681     // If not modified check if the case has already defined regions with zones
682     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions( false );
683     if ( aSeq.Length() > 0 )
684     {
685       // If there are already defined zones then ask a user to confirm zones recalculation
686       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
687                                tr( "MODE_CHANGED" ),
688                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_MODE" ),
689                                QMessageBox::Yes | QMessageBox::No,
690                                QMessageBox::No ) == QMessageBox::Yes );
691     }
692     else
693     {
694       isConfirmed = true; // No regions - no zones - nothing to recalculate
695     }
696   }
697   return isConfirmed;
698 }
699
700 bool HYDROGUI_CalculationOp::confirmContinueWithWarning( const HYDROData_Warning& theWarning ) const
701 {
702   HYDROData_WarningType aType = theWarning.Type;
703   if ( aType == WARN_OK ) {
704     return true;
705   }
706
707   QString aTitle;
708   QString aMsg;
709   switch ( aType )
710   {
711     case WARN_EMPTY_REGIONS:
712       aTitle = tr( "EMPTY_REGIONS" );
713       aMsg = tr( "CONFIRM_CONTINUE_WITH_OBJECTS_NOT_INCLUDED_TO_REGION" ).arg( theWarning.Data );
714       break;
715     default:
716       aTitle = tr( "WARNING" );
717       aMsg = theWarning.Data;
718   }
719
720
721   int anAnswer = SUIT_MessageBox::warning( module()->getApp()->desktop(),
722                                            aTitle, aMsg,
723                                            QMessageBox::Yes | QMessageBox::No,
724                                            QMessageBox::No );
725
726   return ( anAnswer == QMessageBox::Yes );
727 }
728
729 bool HYDROGUI_CalculationOp::confirmLandCoverRegionsChange() const
730 {
731   // Check if the case is already modified or not
732   bool isConfirmed = myEditedObject->IsMustBeUpdated();
733   if ( !isConfirmed )
734   {
735     // If not modified check if the case has already defined regions with land cover zones
736     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions( true );
737     if ( aSeq.Length() > 0 )
738     {
739       // If there are already defined land cover zones then ask a user to confirm land cover zones recalculation
740       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
741                                tr( "REGIONS_CHANGED" ),
742                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_REGIONS" ),
743                                QMessageBox::Yes | QMessageBox::No,
744                                QMessageBox::No ) == QMessageBox::Yes );
745     }
746     else
747     {
748       isConfirmed = true; // No regions - no land cover zones - nothing to recalculate
749     }
750   }
751   return isConfirmed;
752 }
753
754 bool HYDROGUI_CalculationOp::confirmLandCoverModeChange() const
755 {
756   // Check if the case is already modified or not
757   bool isConfirmed = myEditedObject->IsMustBeUpdated();
758   if ( !isConfirmed )
759   {
760     // If not modified check if the case has already defined regions with land cover zones
761     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions( true );
762     if ( aSeq.Length() > 0 )
763     {
764       // If there are already defined land cover zones then ask a user to confirm land cover zones recalculation
765       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
766                                tr( "MODE_CHANGED" ),
767                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_MODE" ),
768                                QMessageBox::Yes | QMessageBox::No,
769                                QMessageBox::No ) == QMessageBox::Yes );
770     }
771     else
772     {
773       isConfirmed = true; // No regions - no land cover zones - nothing to recalculate
774     }
775   }
776   return isConfirmed;
777 }
778
779 bool HYDROGUI_CalculationOp::confirmLandCoverOrderChange() const
780 {
781   // Check if the case is already modified or not
782   bool isConfirmed = myEditedObject->IsMustBeUpdated();
783   if ( !isConfirmed )
784   {
785     // If not modified check if the case has already defined regions with land cover zones
786     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions( true );
787     if ( aSeq.Length() > 0 )
788     {
789       // If there are already defined land cover zones then ask a user to confirm land cover zones recalculation
790       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
791                                tr( "ORDER_CHANGED" ),
792                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_REGIONS" ),
793                                QMessageBox::Yes | QMessageBox::No,
794                                QMessageBox::No ) == QMessageBox::Yes );
795     }
796     else
797     {
798       isConfirmed = true; // No regions - no land cover zones - nothing to recalculate
799     }
800   }
801   return isConfirmed;
802 }
803
804 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
805                                            QString& theErrorMsg,
806                                            QStringList& theBrowseObjectsEntries )
807 {
808   HYDROGUI_CalculationDlg* aPanel = 
809     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
810   if ( !aPanel )
811     return false;
812
813   if( !myIsEdit )
814   {
815     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( myEditedObject );
816     theBrowseObjectsEntries.append( anEntry );
817   }
818
819   // For manual mode priority rules are redundant
820   if ( aPanel->getMode() == HYDROData_CalculationCase::MANUAL ) {
821     myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, false );
822   }
823   if ( aPanel->getLandCoverMode() == HYDROData_CalculationCase::MANUAL ) {
824     myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, false );
825   }
826  
827   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init;
828
829   return true;
830 }
831
832 void HYDROGUI_CalculationOp::onApply()
833 {
834   // Check warnings
835   HYDROData_Warning aWarning = myEditedObject->GetLastWarning();
836   if ( aWarning.Type != WARN_OK ) {
837     if ( !confirmContinueWithWarning( aWarning ) ) {
838       // Go back to the first page
839       HYDROGUI_CalculationDlg* aPanel = 
840         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
841       if ( aPanel ) {
842         aPanel->onFirstPage();
843       }
844       return;
845     }
846   }
847
848   QApplication::setOverrideCursor( Qt::WaitCursor );
849
850   int anUpdateFlags = 0;
851   QString anErrorMsg;
852   QStringList aBrowseObjectsEntries;
853
854   bool aResult = false;
855   
856   try
857   {
858     aResult = processApply( anUpdateFlags, anErrorMsg, aBrowseObjectsEntries );
859   }
860   catch ( Standard_Failure )
861   {
862     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
863     anErrorMsg = aFailure->GetMessageString();
864     aResult = false;
865   }
866   catch ( ... )
867   {
868     aResult = false;
869   }
870   
871   QApplication::restoreOverrideCursor();
872
873   if ( aResult )
874   {
875     module()->update( anUpdateFlags );
876     commit();
877     browseObjects( aBrowseObjectsEntries );
878   }
879   else
880   {
881     abort();
882     QString aMsg = tr( "INPUT_VALID_DATA" );
883     if( !anErrorMsg.isEmpty() )
884       aMsg.prepend( anErrorMsg + "\n" );
885     SUIT_MessageBox::critical( module()->getApp()->desktop(),
886                                tr( "INSUFFICIENT_INPUT_DATA" ),
887                                aMsg ); 
888   }
889 }
890
891 void HYDROGUI_CalculationOp::onNext( const int theIndex )
892 {
893   if( theIndex==1 )
894   {
895     setAvailableGroups();
896   }
897   else if( theIndex==2 )
898   {
899     // Land covers panel
900      HYDROGUI_CalculationDlg* aPanel = 
901       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
902     if ( !aPanel )
903       return;
904
905     setLandCoversVisible( true );
906
907     QStringList aList;
908     QStringList anEntryList;
909     HYDROData_SequenceOfObjects aSeq;
910
911     Handle(HYDROData_StricklerTable) aStricklerTableObj;
912     QString aStricklerTableName;
913
914     // Get all Strickler table objects to fill in combo-box
915     aList.clear();
916     anEntryList.clear();
917     HYDROData_Iterator anIter( doc(), KIND_STRICKLER_TABLE );      
918     for ( ; anIter.More(); anIter.Next() )
919     {
920       aStricklerTableObj = Handle(HYDROData_StricklerTable)::DownCast( anIter.Current() );
921
922       if ( !aStricklerTableObj.IsNull() )
923       { 
924         aStricklerTableName = aStricklerTableObj->GetName();
925         if ( !aStricklerTableName.isEmpty() )
926         {
927           aList.append( aStricklerTableName );
928           anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aStricklerTableObj ) );
929         }        
930       }
931     }
932     aPanel->setStricklerTableNames( aList, anEntryList );
933     bool anUpdateState = myEditedObject->IsMustBeUpdated();
934     if ( !aList.isEmpty() )
935       aPanel->setStricklerTable( aList.at( 0 ), false );
936     myEditedObject->SetToUpdate( anUpdateState );
937
938     // Fill in list widget with all available land covers
939     aSeq = HYDROGUI_Tool::GetLandCovers( module() );
940     getNamesAndEntries( aSeq, aList, anEntryList );
941     aPanel->setAllLandCovers( aList, anEntryList );
942
943     // Set list of included land covers
944     aSeq = myEditedObject->GetLandCovers();
945     getNamesAndEntries( aSeq, aList, anEntryList );
946     aPanel->includeLandCovers( aList, true );
947     
948     if ( !myEditedObject.IsNull() )
949     {
950       if ( myIsEdit )
951       {      
952         // Select the certain Strickler table object in combo-box
953         aStricklerTableObj = myEditedObject->GetStricklerTable();
954         if ( aStricklerTableObj.IsNull() )
955         {
956           aPanel->setStricklerTable( QString() );
957         }
958         else
959         {
960           aStricklerTableName = aStricklerTableObj->GetName();
961           aPanel->setStricklerTable( aStricklerTableName );
962         }
963
964         // Set mode (Auto or Manual) to defined priority of land covers
965         aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
966
967         // Set rules defined on land covers
968         setRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
969       }
970       else
971       {
972         myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getLandCoverMode() );
973       }
974     }
975
976     closePreview( false );
977     createPreview( true );
978   }
979   else if( theIndex==3 )
980   {
981     HYDROGUI_CalculationDlg* aPanel = 
982       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
983     if ( !aPanel )
984       return;
985
986     QApplication::setOverrideCursor( Qt::WaitCursor );
987
988     setGeomObjectsVisible( false );
989     setLandCoversVisible( false );
990
991     QString aNewCaseName = aPanel->getObjectName();
992     QString anOldCaseName = myEditedObject->GetName();
993     bool isNameChanged = anOldCaseName != aNewCaseName;
994   
995     bool anIsToUpdateOb = isNameChanged;
996
997     // At first we must to update the case name because of 
998     // automatic names generation for regions and zones
999     myEditedObject->SetName( aNewCaseName );
1000     
1001     // Set parameters for automatic mode
1002     int aMode = aPanel->getMode();
1003     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
1004     {
1005       // Set objects in the specified order
1006       if( myEditedObject->IsMustBeUpdated() )
1007       {
1008         myEditedObject->RemoveGeometryObjects();
1009         foreach ( const QString& aName, aPanel->getAllGeomObjects() )
1010         {
1011           Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
1012             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
1013           if ( anObject.IsNull() )
1014           {
1015             continue;
1016           }
1017           myEditedObject->AddGeometryObject( anObject );
1018         }
1019
1020         // Clear priority rules
1021         //@ASL if ( myEditedObject->GetRulesCount() > 0 ) {
1022           myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, true );
1023         //@ASL }
1024         // Set priority rules
1025         foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) {
1026           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
1027                                   aRule.Object2, aRule.MergeType,
1028                                   HYDROData_CalculationCase::DataTag_CustomRules );
1029         }
1030       }
1031     }
1032     aPanel->setEditZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
1033          
1034     if ( myEditedObject->IsMustBeUpdated() )
1035     {
1036       myShowZones = true;
1037       myEditedObject->Update();
1038       
1039       AssignDefaultZonesColors( false );
1040
1041       //aPanel->setEditedObject( myEditedObject );
1042       aPanel->refreshZonesBrowser();
1043     
1044       closePreview( false );
1045       createPreview( false );
1046
1047       anIsToUpdateOb = true;
1048
1049       myEditedObject->SetToUpdate( true );
1050     }
1051     else
1052     {
1053       // Show zones
1054       setZonesVisible( true, false );
1055
1056       if ( isNameChanged ) {
1057         module()->getDataModel()->updateObjectTree( myEditedObject );
1058       }
1059     }
1060
1061     QApplication::restoreOverrideCursor();
1062   }
1063   else if( theIndex==4 )
1064   {
1065     // Partition of Land covers panel
1066     HYDROGUI_CalculationDlg* aPanel = 
1067       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1068     if ( !aPanel )
1069       return;
1070
1071     QApplication::setOverrideCursor( Qt::WaitCursor );
1072
1073     // Set parameters for automatic mode
1074     int aMode = aPanel->getLandCoverMode();
1075     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
1076     {
1077       // Set objects in the specified order
1078       if( myEditedObject->IsMustBeUpdated() )
1079       {
1080         myEditedObject->RemoveLandCovers();
1081         foreach ( const QString& aName, aPanel->getAllLandCovers() )
1082         {
1083           Handle(HYDROData_LandCover) aLandCover = Handle(HYDROData_LandCover)::DownCast( 
1084             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
1085           if ( aLandCover.IsNull() )
1086           {
1087             continue;
1088           }
1089           myEditedObject->AddLandCover( aLandCover );
1090         }
1091
1092         // Clear priority rules
1093         myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, true );
1094         // Set priority rules
1095         foreach ( const HYDROData_CustomRule& aRule, aPanel->getLandCoverRules() ) {
1096           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
1097                                    aRule.Object2, HYDROData_Zone::Merge_Object,
1098                                    HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
1099         }
1100       }
1101     }
1102     aPanel->setEditLandCoverZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
1103
1104     bool anIsToUpdateOb = false;
1105     bool anIsToUpdate = myEditedObject->IsMustBeUpdated();
1106     if ( anIsToUpdate )
1107     {
1108       myShowZones = true;
1109       //myEditedObject->Update();
1110       myEditedObject->SetToUpdate( false );
1111       
1112       AssignDefaultZonesColors( true );
1113
1114       aPanel->refreshLandCoverZonesBrowser();
1115
1116       anIsToUpdateOb = true;
1117     }
1118
1119     closePreview( false );
1120     createPreview( true );
1121     
1122     if ( !anIsToUpdate )
1123     {
1124       // Hide zones
1125       setZonesVisible( false, false );
1126       // Show land cover zones
1127       setZonesVisible( true, true );
1128     }
1129
1130     if ( anIsToUpdateOb ) {
1131       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
1132       if ( anObjBrowser ) {
1133         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
1134       }
1135     }
1136
1137     QApplication::restoreOverrideCursor();
1138   }
1139 }
1140
1141 void HYDROGUI_CalculationOp::onHideZones( const int theIndex )
1142 {
1143   if( theIndex==1 )
1144   {
1145     setGeomObjectsVisible( true );
1146
1147     closePreview( false );
1148     createPreview( false );
1149   }
1150   if( theIndex==2 )
1151   {
1152     setLandCoversVisible( true );
1153
1154     closePreview( false );
1155     createPreview( true );
1156
1157     // Hide zones
1158     setZonesVisible( false, false );
1159     // Hide land covers
1160     setZonesVisible( false, true );
1161   }
1162   else if( theIndex==3 )
1163   {
1164     AssignDefaultZonesColors( false );
1165
1166     closePreview( false );
1167     createPreview( false );
1168
1169     // Hide land cover zones
1170     setZonesVisible( false, true );
1171     // Show zones
1172     setZonesVisible( true, false );
1173   }
1174 }
1175
1176 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible, const bool theLandCover )
1177 {
1178   myShowZones = theIsVisible;
1179   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1180   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1181   HYDROData_SequenceOfObjects aZones;
1182   Handle(HYDROData_Region) aRegion;
1183   if ( myPreviewViewManager ) 
1184   {
1185     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1186     {
1187       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1188       if ( !aCtx.IsNull() )
1189       {
1190         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1191         {
1192           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1193           if ( !aRegion.IsNull() )
1194           {
1195             aZones = aRegion->GetZones();
1196             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1197             for ( ; aZonesIter.More(); aZonesIter.Next() )
1198             {
1199               setObjectVisibility( aZonesIter.Value(), theIsVisible );
1200             }
1201           }
1202         }
1203       }
1204
1205       module()->update( UF_OCCViewer );
1206     }
1207   }
1208 }
1209
1210 void HYDROGUI_CalculationOp::setGeomObjectsVisible( bool theIsVisible )
1211 {
1212   myShowGeomObjects = theIsVisible;
1213
1214   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
1215
1216   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1217   for ( ; anIter.More(); anIter.Next() ) {
1218     setObjectVisibility( anIter.Value(), theIsVisible );
1219   }
1220 }
1221
1222 void HYDROGUI_CalculationOp::setLandCoversVisible( bool theIsVisible )
1223 {
1224   myShowLandCovers = theIsVisible;
1225
1226   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
1227
1228   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1229   for ( ; anIter.More(); anIter.Next() ) {
1230     setObjectVisibility( anIter.Value(), theIsVisible );
1231   }
1232 }
1233
1234 void HYDROGUI_CalculationOp::AssignDefaultZonesColors( const bool theLandCover )
1235 {
1236   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1237   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1238   HYDROData_SequenceOfObjects aZones;
1239   Handle(HYDROData_Region) aRegion;
1240   if ( myPreviewViewManager ) 
1241   {
1242     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1243     {
1244       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1245       if ( !aCtx.IsNull() )
1246       {
1247         int aCounter = 0;        
1248         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1249         {
1250           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1251           if ( !aRegion.IsNull() )
1252           {
1253             aZones = aRegion->GetZones();
1254             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1255             for ( ; aZonesIter.More(); aZonesIter.Next() )
1256             {
1257               // Zone
1258               Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
1259               if ( !aZone.IsNull() )
1260               {
1261                 QColor aFillingColor = GenerateDefaultZonesColor(++aCounter);
1262                 while (aFillingColor == Qt::red)
1263                   aFillingColor = GenerateDefaultZonesColor(++aCounter);
1264                 
1265                 aZone->SetColor(aFillingColor);
1266               }
1267             }
1268           }
1269         }
1270       }
1271     }
1272   }
1273 }
1274
1275 QColor HYDROGUI_CalculationOp::GenerateDefaultZonesColor( int theIndex,
1276                                                           float theSaturation/* = 0.5*/,
1277                                                           float theValue/* = 0.95*/ ) const
1278 {
1279   float aGoldenRatioConjugate = (float)(360./582.);
1280   float aHue = (float)(rand()%100);
1281   aHue += aGoldenRatioConjugate*theIndex;
1282   aHue -= floor(aHue);
1283
1284   float aR = 0., aG = 0., aB = 0.;
1285   int aHueInt = (int)(aHue*6.);
1286   float aF = aHue*6. - aHueInt;
1287   float aP = theValue * (1. - theSaturation);
1288   float aQ = theValue * (1. - aF*theSaturation);
1289   float aT = theValue * (1. - (1. - aF) * theSaturation);
1290   switch (aHueInt)
1291   {
1292   case 0: { aR = theValue; aG = aT; aB = aP; break; }
1293   case 1: { aR = aQ; aG = theValue; aB = aP; break; }
1294   case 2: { aR = aP; aG = theValue; aB = aT; break; }
1295   case 3: { aR = aP; aG = aQ; aB = theValue; break; }
1296   case 4: { aR = aT; aG = aP; aB = theValue; break; }
1297   case 5: { aR = theValue; aG = aP; aB = aQ; break; }
1298   default: break;
1299   }
1300
1301   QColor aColor = QColor( (int)(aR*256.), (int)(aG*256.), (int)(aB*256.) );
1302   return ( aColor.isValid() ? aColor : HYDROData_ImmersibleZone::DefaultFillingColor() );
1303 }
1304
1305 void HYDROGUI_CalculationOp::setRules( HYDROData_CalculationCase::DataTag theDataTag )
1306 {
1307   HYDROGUI_CalculationDlg* aPanel = 
1308     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1309   if ( !aPanel )
1310     return;
1311
1312   HYDROData_ListOfRules aRules;
1313   Handle(HYDROData_Entity) anObject1, anObject2;
1314   HYDROData_PriorityType aPriority;
1315   HYDROData_Zone::MergeType aMergeType;
1316   HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
1317   for ( int anIndex = 0; ; anIndex++ )
1318   {
1319     if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType, theDataTag ) ) {
1320       HYDROData_CustomRule aRule;
1321       aRule.Object1 = anObject1;
1322       aRule.Object2 = anObject2;
1323       aRule.Priority = aPriority;
1324       aRule.MergeType = aMergeType;
1325
1326       aRules << aRule;
1327     }
1328     else
1329       break;
1330   }
1331
1332   if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomRules )
1333     aPanel->setRules( aRules );
1334   else if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomLandCoverRules )
1335     aPanel->setLandCoverRules( aRules );
1336 }
1337
1338 bool HYDROGUI_CalculationOp::createRegion( const QList<SUIT_DataObject*>& theZonesList,
1339                                            const bool theLandCover )
1340 {
1341   bool aRetValue = false;
1342
1343   QList<HYDROGUI_Zone*> aZonesList;
1344   HYDROGUI_Zone* aZone;
1345   // Get a list of dropped zones
1346   for ( int i = 0; i < theZonesList.length(); i++ )
1347   {
1348     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
1349     if ( aZone )
1350     {
1351       aZonesList.append( aZone );
1352     }
1353   }
1354   if ( aZonesList.length() > 0 )
1355   {
1356     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList, theLandCover );
1357     aRetValue = true;
1358   }
1359    
1360   return aRetValue;
1361 }
1362
1363 void HYDROGUI_CalculationOp::createPreview( const bool theLandCover )
1364 {
1365   LightApp_Application* anApp = module()->getApp();
1366   HYDROData_SequenceOfObjects aSeq;
1367   if ( theLandCover && myShowLandCovers )
1368   {
1369     HYDROData_SequenceOfObjects aSeqLC = myEditedObject->GetLandCovers();
1370     aSeq.Append( aSeqLC );
1371   }
1372   else if ( !theLandCover && myShowGeomObjects )
1373   {
1374     HYDROData_SequenceOfObjects aSeqGO = myEditedObject->GetGeometryObjects();
1375     aSeq.Append( aSeqGO );
1376   }
1377
1378   Handle(HYDROData_Entity) anEntity;
1379
1380   if ( myShowZones )
1381   {
1382     // Gather zones for displaying
1383     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1384     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1385     HYDROData_SequenceOfObjects aZones;
1386     Handle(HYDROData_Region) aRegion;
1387     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1388     {
1389       anEntity = aRegionsIter.Value();
1390       if ( !anEntity.IsNull() )
1391       {
1392         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
1393         if ( !aRegion.IsNull() )
1394         {
1395           aZones = aRegion->GetZones();
1396           aSeq.Append( aZones );
1397         }
1398       }
1399     }
1400   }
1401
1402   // Get a boundary polyline if any
1403   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
1404
1405   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
1406
1407   if ( !myActiveViewManager )
1408   {
1409     if ( aSeq.IsEmpty() )
1410       return;
1411
1412     myActiveViewManager = anApp->activeViewManager();
1413   }
1414
1415   if ( !myPreviewViewManager )
1416   {
1417     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
1418       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
1419     if ( myPreviewViewManager )
1420     {
1421       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1422                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1423
1424       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
1425       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
1426     }
1427   }
1428
1429   if ( !myPreviewViewManager )
1430     return;
1431
1432   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1433   {
1434     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1435     if ( !aCtx.IsNull() )
1436     {
1437       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1438       for ( ; anIter.More(); anIter.Next() )
1439       {
1440         setObjectVisibility( anIter.Value(), true );
1441       }
1442
1443       //Process the draw events for viewer
1444       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
1445       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
1446         vw->onTopView();
1447     }
1448
1449     module()->update( UF_OCCViewer | UF_FitAll );
1450   }
1451 }
1452
1453 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
1454 {
1455   if ( theEntity.IsNull() || !myPreviewViewManager ) {
1456     return;
1457   }
1458
1459   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1460   if ( aViewer ) {
1461     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
1462   }
1463 }
1464
1465 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
1466 {
1467   closePreview();
1468 }
1469
1470 void HYDROGUI_CalculationOp::closePreview( bool theRemoveViewManager )
1471 {
1472   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
1473   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
1474   QShortcut* aShortcut;
1475   foreach( aShortcut, aShortcuts )
1476   {
1477     if ( aShortcut->key() == 
1478       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
1479       SUIT_DataBrowser::RenameShortcut ) ) )
1480     {
1481       aShortcut->setEnabled( true );
1482     }
1483   }
1484
1485
1486   if( myPreviewViewManager )
1487   {
1488     // Hide all the displayed objects in the preview view
1489     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1490     if ( aViewer ) {
1491       size_t aViewId = (size_t)aViewer;
1492       HYDROData_Iterator anIterator( doc() );
1493       for( ; anIterator.More(); anIterator.Next() ) {
1494         Handle(HYDROData_Entity) anObject = anIterator.Current();
1495         if( !anObject.IsNull() ) {
1496           module()->setObjectVisible( aViewId, anObject, false );
1497         }
1498       }
1499     }
1500
1501     if ( theRemoveViewManager )
1502     {
1503       disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1504                   this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1505
1506       module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
1507       myPreviewViewManager = NULL;
1508     }
1509   }
1510
1511   if( myActiveViewManager && theRemoveViewManager )
1512   {
1513     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
1514     myActiveViewManager = NULL;
1515   }
1516 }
1517
1518 void HYDROGUI_CalculationOp::setAvailableGroups()
1519 {
1520   HYDROGUI_CalculationDlg* aPanel = 
1521       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1522
1523   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
1524   QStringList aList, anEntryList;
1525   getNamesAndEntries( aSeq, aList, anEntryList );
1526
1527   QStringList aGroupsNames;
1528
1529   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
1530   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
1531   {
1532     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
1533     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
1534     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
1535     {
1536       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
1537       aGroupsNames.append( aGroup->GetName() );
1538     }
1539   }
1540   if( myEditedObject->IsMustBeUpdated() ) {
1541     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
1542       Handle(HYDROData_ShapesGroup) aGeomGroup =
1543         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
1544       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
1545         myEditedObject->RemoveGeometryGroup( aGeomGroup );
1546       }
1547     }
1548   }
1549
1550   aPanel->setAvailableGroups( aGroupsNames );
1551   aPanel->includeGroups( aList );
1552
1553   bool isUpdated = myEditedObject->IsMustBeUpdated();
1554 }
1555
1556 void HYDROGUI_CalculationOp::onAddGroups()
1557 {
1558   HYDROGUI_CalculationDlg* aPanel = 
1559     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1560   if ( !aPanel )
1561     return;
1562
1563   // Add geometry objects selected in the module browser to the calculation case
1564   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
1565   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1566     return;
1567
1568   QStringList anAddedList;
1569   for (int i = 0; i < aSelectedList.length(); i++)
1570   {
1571     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1572       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1573     if ( aGroup.IsNull() )
1574       continue;
1575
1576     if ( myEditedObject->AddGeometryGroup( aGroup ) )
1577       anAddedList.append( aGroup->GetName() );
1578   }
1579
1580   if ( !anAddedList.isEmpty() )
1581   {
1582     aPanel->includeGroups( anAddedList );
1583   }
1584 }
1585
1586 void HYDROGUI_CalculationOp::onRemoveGroups()
1587 {
1588   // Remove selected objects from the calculation case
1589   HYDROGUI_CalculationDlg* aPanel = 
1590     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1591   if ( !aPanel )
1592     return;
1593
1594   QStringList aSelectedList = aPanel->getSelectedGroups();
1595   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1596     return;
1597
1598   for (int i = 0; i < aSelectedList.length(); i++)
1599   {
1600     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1601       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1602     if ( aGroup.IsNull() )
1603       continue;
1604
1605     myEditedObject->RemoveGeometryGroup( aGroup );
1606   }
1607
1608   aPanel->excludeGroups( aSelectedList );
1609 }
1610
1611 void HYDROGUI_CalculationOp::onChangeLandCoverMode( int theMode )
1612 {
1613   HYDROGUI_CalculationDlg* aPanel = 
1614     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1615   if ( !aPanel )
1616     return;
1617
1618   if ( !confirmLandCoverModeChange() ) {
1619     aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
1620     return;
1621   }
1622
1623   myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1624   aPanel->setLandCoverMode( theMode );
1625 }
1626
1627 void HYDROGUI_CalculationOp::onAddLandCovers()
1628 {
1629   HYDROGUI_CalculationDlg* aPanel = 
1630     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1631   if ( !aPanel )
1632     return;
1633
1634   // Add land covers selected in the module browser to the calculation case
1635   QStringList aSelectedList = aPanel->getSelectedAvailableLandCovers();
1636   if ( aSelectedList.isEmpty() || !confirmLandCoverRegionsChange() )
1637     return;
1638
1639   QStringList anAddedList;
1640   for (int i = 0; i < aSelectedList.length(); i++)
1641   {
1642     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1643       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1644     if ( anObject.IsNull() )
1645       continue;
1646
1647     if ( myEditedObject->AddLandCover( anObject ) )
1648       anAddedList.append( anObject->GetName() );
1649   }
1650
1651   if ( !anAddedList.isEmpty() )
1652   {
1653     aPanel->includeLandCovers( anAddedList, false );
1654     createPreview( true );
1655   }
1656 }
1657
1658 void HYDROGUI_CalculationOp::onRemoveLandCovers()
1659 {
1660   // Remove selected objects from the calculation case
1661   HYDROGUI_CalculationDlg* aPanel = 
1662     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1663   if ( !aPanel )
1664     return;
1665
1666   QStringList aSelectedList = aPanel->getSelectedLandCovers();
1667   if ( aSelectedList.isEmpty() || !confirmLandCoverRegionsChange() )
1668     return;
1669
1670   for (int i = 0; i < aSelectedList.length(); i++)
1671   {
1672     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1673       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1674     if ( anObject.IsNull() )
1675       continue;
1676
1677     setObjectVisibility( anObject, false );
1678     myEditedObject->RemoveLandCover( anObject );
1679   }
1680
1681   module()->update( UF_OCCViewer );
1682   aPanel->excludeLandCovers( aSelectedList );
1683 }
1684
1685 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1686 {
1687   HYDROGUI_CalculationDlg* aPanel = 
1688     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1689   if ( !aPanel )
1690     return;
1691
1692   if ( !confirmModeChange() ) {
1693     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1694     return;
1695   }
1696
1697   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1698   aPanel->setMode( theMode );
1699 }
1700
1701 void HYDROGUI_CalculationOp::onOrderChanged( bool& isConfirmed )
1702 {
1703   HYDROGUI_CalculationDlg* aPanel = 
1704     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1705   if ( !aPanel )
1706     return;
1707
1708   isConfirmed = confirmOrderChange();
1709   if( isConfirmed )
1710     myEditedObject->SetToUpdate( true );
1711 }
1712
1713 void HYDROGUI_CalculationOp::onOrderLandCoverChanged( bool& isConfirmed )
1714 {
1715   HYDROGUI_CalculationDlg* aPanel = 
1716     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1717   if ( !aPanel )
1718     return;
1719
1720   isConfirmed = confirmLandCoverOrderChange();
1721   if( isConfirmed )
1722     myEditedObject->SetToUpdate( true );
1723 }