Salome HOME
Merge remote-tracking branch 'origin/BR_SHP_FORMAT' 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->SetToUpdate( false );
1110       
1111       AssignDefaultZonesColors( true );
1112
1113       aPanel->refreshLandCoverZonesBrowser();
1114
1115       anIsToUpdateOb = true;
1116     }
1117
1118     closePreview( false );
1119     createPreview( true );
1120     
1121     if ( !anIsToUpdate )
1122     {
1123       // Hide zones
1124       setZonesVisible( false, false );
1125       // Show land cover zones
1126       setZonesVisible( true, true );
1127     }
1128
1129     if ( anIsToUpdateOb ) {
1130       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
1131       if ( anObjBrowser ) {
1132         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
1133       }
1134     }
1135
1136     QApplication::restoreOverrideCursor();
1137   }
1138 }
1139
1140 void HYDROGUI_CalculationOp::onHideZones( const int theIndex )
1141 {
1142   if( theIndex==1 )
1143   {
1144     setGeomObjectsVisible( true );
1145
1146     closePreview( false );
1147     createPreview( false );
1148   }
1149   if( theIndex==2 )
1150   {
1151     setLandCoversVisible( true );
1152
1153     closePreview( false );
1154     createPreview( true );
1155
1156     // Hide zones
1157     setZonesVisible( false, false );
1158     // Hide land covers
1159     setZonesVisible( false, true );
1160   }
1161   else if( theIndex==3 )
1162   {
1163     AssignDefaultZonesColors( false );
1164
1165     closePreview( false );
1166     createPreview( false );
1167
1168     // Hide land cover zones
1169     setZonesVisible( false, true );
1170     // Show zones
1171     setZonesVisible( true, false );
1172   }
1173 }
1174
1175 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible, const bool theLandCover )
1176 {
1177   myShowZones = theIsVisible;
1178   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1179   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1180   HYDROData_SequenceOfObjects aZones;
1181   Handle(HYDROData_Region) aRegion;
1182   if ( myPreviewViewManager ) 
1183   {
1184     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1185     {
1186       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1187       if ( !aCtx.IsNull() )
1188       {
1189         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1190         {
1191           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1192           if ( !aRegion.IsNull() )
1193           {
1194             aZones = aRegion->GetZones();
1195             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1196             for ( ; aZonesIter.More(); aZonesIter.Next() )
1197             {
1198               setObjectVisibility( aZonesIter.Value(), theIsVisible );
1199             }
1200           }
1201         }
1202       }
1203
1204       module()->update( UF_OCCViewer );
1205     }
1206   }
1207 }
1208
1209 void HYDROGUI_CalculationOp::setGeomObjectsVisible( bool theIsVisible )
1210 {
1211   myShowGeomObjects = theIsVisible;
1212
1213   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
1214
1215   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1216   for ( ; anIter.More(); anIter.Next() ) {
1217     setObjectVisibility( anIter.Value(), theIsVisible );
1218   }
1219 }
1220
1221 void HYDROGUI_CalculationOp::setLandCoversVisible( bool theIsVisible )
1222 {
1223   myShowLandCovers = theIsVisible;
1224
1225   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
1226
1227   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1228   for ( ; anIter.More(); anIter.Next() ) {
1229     setObjectVisibility( anIter.Value(), theIsVisible );
1230   }
1231 }
1232
1233 void HYDROGUI_CalculationOp::AssignDefaultZonesColors( const bool theLandCover )
1234 {
1235   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1236   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1237   HYDROData_SequenceOfObjects aZones;
1238   Handle(HYDROData_Region) aRegion;
1239   if ( myPreviewViewManager ) 
1240   {
1241     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1242     {
1243       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1244       if ( !aCtx.IsNull() )
1245       {
1246         int aCounter = 0;        
1247         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1248         {
1249           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1250           if ( !aRegion.IsNull() )
1251           {
1252             aZones = aRegion->GetZones();
1253             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1254             for ( ; aZonesIter.More(); aZonesIter.Next() )
1255             {
1256               // Zone
1257               Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
1258               if ( !aZone.IsNull() )
1259               {
1260                 QColor aFillingColor = GenerateDefaultZonesColor(++aCounter);
1261                 while (aFillingColor == Qt::red)
1262                   aFillingColor = GenerateDefaultZonesColor(++aCounter);
1263                 
1264                 aZone->SetColor(aFillingColor);
1265               }
1266             }
1267           }
1268         }
1269       }
1270     }
1271   }
1272 }
1273
1274 QColor HYDROGUI_CalculationOp::GenerateDefaultZonesColor( int theIndex,
1275                                                           float theSaturation/* = 0.5*/,
1276                                                           float theValue/* = 0.95*/ ) const
1277 {
1278   float aGoldenRatioConjugate = (float)(360./582.);
1279   float aHue = (float)(rand()%100);
1280   aHue += aGoldenRatioConjugate*theIndex;
1281   aHue -= floor(aHue);
1282
1283   float aR = 0., aG = 0., aB = 0.;
1284   int aHueInt = (int)(aHue*6.);
1285   float aF = aHue*6. - aHueInt;
1286   float aP = theValue * (1. - theSaturation);
1287   float aQ = theValue * (1. - aF*theSaturation);
1288   float aT = theValue * (1. - (1. - aF) * theSaturation);
1289   switch (aHueInt)
1290   {
1291   case 0: { aR = theValue; aG = aT; aB = aP; break; }
1292   case 1: { aR = aQ; aG = theValue; aB = aP; break; }
1293   case 2: { aR = aP; aG = theValue; aB = aT; break; }
1294   case 3: { aR = aP; aG = aQ; aB = theValue; break; }
1295   case 4: { aR = aT; aG = aP; aB = theValue; break; }
1296   case 5: { aR = theValue; aG = aP; aB = aQ; break; }
1297   default: break;
1298   }
1299
1300   QColor aColor = QColor( (int)(aR*256.), (int)(aG*256.), (int)(aB*256.) );
1301   return ( aColor.isValid() ? aColor : HYDROData_ImmersibleZone::DefaultFillingColor() );
1302 }
1303
1304 void HYDROGUI_CalculationOp::setRules( HYDROData_CalculationCase::DataTag theDataTag )
1305 {
1306   HYDROGUI_CalculationDlg* aPanel = 
1307     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1308   if ( !aPanel )
1309     return;
1310
1311   HYDROData_ListOfRules aRules;
1312   Handle(HYDROData_Entity) anObject1, anObject2;
1313   HYDROData_PriorityType aPriority;
1314   HYDROData_Zone::MergeType aMergeType;
1315   HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
1316   for ( int anIndex = 0; ; anIndex++ )
1317   {
1318     if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType, theDataTag ) ) {
1319       HYDROData_CustomRule aRule;
1320       aRule.Object1 = anObject1;
1321       aRule.Object2 = anObject2;
1322       aRule.Priority = aPriority;
1323       aRule.MergeType = aMergeType;
1324
1325       aRules << aRule;
1326     }
1327     else
1328       break;
1329   }
1330
1331   if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomRules )
1332     aPanel->setRules( aRules );
1333   else if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomLandCoverRules )
1334     aPanel->setLandCoverRules( aRules );
1335 }
1336
1337 bool HYDROGUI_CalculationOp::createRegion( const QList<SUIT_DataObject*>& theZonesList,
1338                                            const bool theLandCover )
1339 {
1340   bool aRetValue = false;
1341
1342   QList<HYDROGUI_Zone*> aZonesList;
1343   HYDROGUI_Zone* aZone;
1344   // Get a list of dropped zones
1345   for ( int i = 0; i < theZonesList.length(); i++ )
1346   {
1347     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
1348     if ( aZone )
1349     {
1350       aZonesList.append( aZone );
1351     }
1352   }
1353   if ( aZonesList.length() > 0 )
1354   {
1355     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList, theLandCover );
1356     aRetValue = true;
1357   }
1358    
1359   return aRetValue;
1360 }
1361
1362 void HYDROGUI_CalculationOp::createPreview( const bool theLandCover )
1363 {
1364   LightApp_Application* anApp = module()->getApp();
1365   HYDROData_SequenceOfObjects aSeq;
1366   if ( theLandCover && myShowLandCovers )
1367   {
1368     HYDROData_SequenceOfObjects aSeqLC = myEditedObject->GetLandCovers();
1369     aSeq.Append( aSeqLC );
1370   }
1371   else if ( !theLandCover && myShowGeomObjects )
1372   {
1373     HYDROData_SequenceOfObjects aSeqGO = myEditedObject->GetGeometryObjects();
1374     aSeq.Append( aSeqGO );
1375   }
1376
1377   Handle(HYDROData_Entity) anEntity;
1378
1379   if ( myShowZones )
1380   {
1381     // Gather zones for displaying
1382     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1383     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1384     HYDROData_SequenceOfObjects aZones;
1385     Handle(HYDROData_Region) aRegion;
1386     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1387     {
1388       anEntity = aRegionsIter.Value();
1389       if ( !anEntity.IsNull() )
1390       {
1391         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
1392         if ( !aRegion.IsNull() )
1393         {
1394           aZones = aRegion->GetZones();
1395           aSeq.Append( aZones );
1396         }
1397       }
1398     }
1399   }
1400
1401   // Get a boundary polyline if any
1402   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
1403
1404   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
1405
1406   if ( !myActiveViewManager )
1407   {
1408     if ( aSeq.IsEmpty() )
1409       return;
1410
1411     myActiveViewManager = anApp->activeViewManager();
1412   }
1413
1414   if ( !myPreviewViewManager )
1415   {
1416     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
1417       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
1418     if ( myPreviewViewManager )
1419     {
1420       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1421                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1422
1423       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
1424       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
1425     }
1426   }
1427
1428   if ( !myPreviewViewManager )
1429     return;
1430
1431   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1432   {
1433     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1434     if ( !aCtx.IsNull() )
1435     {
1436       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1437       for ( ; anIter.More(); anIter.Next() )
1438       {
1439         setObjectVisibility( anIter.Value(), true );
1440       }
1441
1442       //Process the draw events for viewer
1443       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
1444       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
1445         vw->onTopView();
1446     }
1447
1448     module()->update( UF_OCCViewer | UF_FitAll );
1449   }
1450 }
1451
1452 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
1453 {
1454   if ( theEntity.IsNull() || !myPreviewViewManager ) {
1455     return;
1456   }
1457
1458   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1459   if ( aViewer ) {
1460     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
1461   }
1462 }
1463
1464 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
1465 {
1466   closePreview();
1467 }
1468
1469 void HYDROGUI_CalculationOp::closePreview( bool theRemoveViewManager )
1470 {
1471   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
1472   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
1473   QShortcut* aShortcut;
1474   foreach( aShortcut, aShortcuts )
1475   {
1476     if ( aShortcut->key() == 
1477       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
1478       SUIT_DataBrowser::RenameShortcut ) ) )
1479     {
1480       aShortcut->setEnabled( true );
1481     }
1482   }
1483
1484
1485   if( myPreviewViewManager )
1486   {
1487     // Hide all the displayed objects in the preview view
1488     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1489     if ( aViewer ) {
1490       size_t aViewId = (size_t)aViewer;
1491       HYDROData_Iterator anIterator( doc() );
1492       for( ; anIterator.More(); anIterator.Next() ) {
1493         Handle(HYDROData_Entity) anObject = anIterator.Current();
1494         if( !anObject.IsNull() ) {
1495           module()->setObjectVisible( aViewId, anObject, false );
1496         }
1497       }
1498     }
1499
1500     if ( theRemoveViewManager )
1501     {
1502       disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1503                   this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1504
1505       module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
1506       myPreviewViewManager = NULL;
1507     }
1508   }
1509
1510   if( myActiveViewManager && theRemoveViewManager )
1511   {
1512     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
1513     myActiveViewManager = NULL;
1514   }
1515 }
1516
1517 void HYDROGUI_CalculationOp::setAvailableGroups()
1518 {
1519   HYDROGUI_CalculationDlg* aPanel = 
1520       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1521
1522   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
1523   QStringList aList, anEntryList;
1524   getNamesAndEntries( aSeq, aList, anEntryList );
1525
1526   QStringList aGroupsNames;
1527
1528   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
1529   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
1530   {
1531     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
1532     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
1533     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
1534     {
1535       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
1536       aGroupsNames.append( aGroup->GetName() );
1537     }
1538   }
1539   if( myEditedObject->IsMustBeUpdated() ) {
1540     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
1541       Handle(HYDROData_ShapesGroup) aGeomGroup =
1542         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
1543       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
1544         myEditedObject->RemoveGeometryGroup( aGeomGroup );
1545       }
1546     }
1547   }
1548
1549   aPanel->setAvailableGroups( aGroupsNames );
1550   aPanel->includeGroups( aList );
1551
1552   bool isUpdated = myEditedObject->IsMustBeUpdated();
1553 }
1554
1555 void HYDROGUI_CalculationOp::onAddGroups()
1556 {
1557   HYDROGUI_CalculationDlg* aPanel = 
1558     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1559   if ( !aPanel )
1560     return;
1561
1562   // Add geometry objects selected in the module browser to the calculation case
1563   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
1564   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1565     return;
1566
1567   QStringList anAddedList;
1568   for (int i = 0; i < aSelectedList.length(); i++)
1569   {
1570     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1571       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1572     if ( aGroup.IsNull() )
1573       continue;
1574
1575     if ( myEditedObject->AddGeometryGroup( aGroup ) )
1576       anAddedList.append( aGroup->GetName() );
1577   }
1578
1579   if ( !anAddedList.isEmpty() )
1580   {
1581     aPanel->includeGroups( anAddedList );
1582   }
1583 }
1584
1585 void HYDROGUI_CalculationOp::onRemoveGroups()
1586 {
1587   // Remove selected objects from the calculation case
1588   HYDROGUI_CalculationDlg* aPanel = 
1589     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1590   if ( !aPanel )
1591     return;
1592
1593   QStringList aSelectedList = aPanel->getSelectedGroups();
1594   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1595     return;
1596
1597   for (int i = 0; i < aSelectedList.length(); i++)
1598   {
1599     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1600       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1601     if ( aGroup.IsNull() )
1602       continue;
1603
1604     myEditedObject->RemoveGeometryGroup( aGroup );
1605   }
1606
1607   aPanel->excludeGroups( aSelectedList );
1608 }
1609
1610 void HYDROGUI_CalculationOp::onChangeLandCoverMode( int theMode )
1611 {
1612   HYDROGUI_CalculationDlg* aPanel = 
1613     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1614   if ( !aPanel )
1615     return;
1616
1617   if ( !confirmLandCoverModeChange() ) {
1618     aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
1619     return;
1620   }
1621
1622   myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1623   aPanel->setLandCoverMode( theMode );
1624 }
1625
1626 void HYDROGUI_CalculationOp::onAddLandCovers()
1627 {
1628   HYDROGUI_CalculationDlg* aPanel = 
1629     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1630   if ( !aPanel )
1631     return;
1632
1633   // Add land covers selected in the module browser to the calculation case
1634   QStringList aSelectedList = aPanel->getSelectedAvailableLandCovers();
1635   if ( aSelectedList.isEmpty() || !confirmLandCoverRegionsChange() )
1636     return;
1637
1638   QStringList anAddedList;
1639   for (int i = 0; i < aSelectedList.length(); i++)
1640   {
1641     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1642       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1643     if ( anObject.IsNull() )
1644       continue;
1645
1646     if ( myEditedObject->AddLandCover( anObject ) )
1647       anAddedList.append( anObject->GetName() );
1648   }
1649
1650   if ( !anAddedList.isEmpty() )
1651   {
1652     aPanel->includeLandCovers( anAddedList, false );
1653     createPreview( true );
1654   }
1655 }
1656
1657 void HYDROGUI_CalculationOp::onRemoveLandCovers()
1658 {
1659   // Remove selected objects from the calculation case
1660   HYDROGUI_CalculationDlg* aPanel = 
1661     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1662   if ( !aPanel )
1663     return;
1664
1665   QStringList aSelectedList = aPanel->getSelectedLandCovers();
1666   if ( aSelectedList.isEmpty() || !confirmLandCoverRegionsChange() )
1667     return;
1668
1669   for (int i = 0; i < aSelectedList.length(); i++)
1670   {
1671     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1672       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1673     if ( anObject.IsNull() )
1674       continue;
1675
1676     setObjectVisibility( anObject, false );
1677     myEditedObject->RemoveLandCover( anObject );
1678   }
1679
1680   module()->update( UF_OCCViewer );
1681   aPanel->excludeLandCovers( aSelectedList );
1682 }
1683
1684 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1685 {
1686   HYDROGUI_CalculationDlg* aPanel = 
1687     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1688   if ( !aPanel )
1689     return;
1690
1691   if ( !confirmModeChange() ) {
1692     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1693     return;
1694   }
1695
1696   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1697   aPanel->setMode( theMode );
1698 }
1699
1700 void HYDROGUI_CalculationOp::onOrderChanged( bool& isConfirmed )
1701 {
1702   HYDROGUI_CalculationDlg* aPanel = 
1703     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1704   if ( !aPanel )
1705     return;
1706
1707   isConfirmed = confirmOrderChange();
1708   if( isConfirmed )
1709     myEditedObject->SetToUpdate( true );
1710 }
1711
1712 void HYDROGUI_CalculationOp::onOrderLandCoverChanged( bool& isConfirmed )
1713 {
1714   HYDROGUI_CalculationDlg* aPanel = 
1715     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1716   if ( !aPanel )
1717     return;
1718
1719   isConfirmed = confirmLandCoverOrderChange();
1720   if( isConfirmed )
1721     myEditedObject->SetToUpdate( true );
1722 }