Salome HOME
Merge branch 'BR_v14_rc' into BR_quadtree
[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::confirmLandCoverModeChange() 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 zones
736     // TODO: adapt HYDROData_CalculationCase class to process regions constructed for land covers
737     /*HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCoverRegions();
738     if ( aSeq.Length() > 0 )
739     {*/
740       // If there are already defined zones then ask a user to confirm zones recalculation
741       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
742                                tr( "MODE_CHANGED" ),
743                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_MODE" ),
744                                QMessageBox::Yes | QMessageBox::No,
745                                QMessageBox::No ) == QMessageBox::Yes );
746     /*}
747     else
748     {
749       isConfirmed = true; // No regions - no zones - nothing to recalculate
750     }*/
751   }
752   return isConfirmed;
753 }
754
755 bool HYDROGUI_CalculationOp::confirmLandCoverOrderChange() const
756 {
757   // Check if the case is already modified or not
758   bool isConfirmed = myEditedObject->IsMustBeUpdated();
759   if ( !isConfirmed )
760   {
761     // If not modified check if the case has already defined regions with zones
762     // TODO: adapt HYDROData_CalculationCase class to process regions constructed for land covers
763     /*HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCoverRegions();
764     if ( aSeq.Length() > 0 )
765     {*/
766       // If there are already defined zones then ask a user to confirm zones recalculation
767       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
768                                tr( "ORDER_CHANGED" ),
769                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_REGIONS" ),
770                                QMessageBox::Yes | QMessageBox::No,
771                                QMessageBox::No ) == QMessageBox::Yes );
772     /*}
773     else
774     {
775       isConfirmed = true; // No regions - no zones - nothing to recalculate
776     }*/
777   }
778   return isConfirmed;
779 }
780
781 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
782                                            QString& theErrorMsg,
783                                            QStringList& theBrowseObjectsEntries )
784 {
785   HYDROGUI_CalculationDlg* aPanel = 
786     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
787   if ( !aPanel )
788     return false;
789
790   if( !myIsEdit )
791   {
792     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( myEditedObject );
793     theBrowseObjectsEntries.append( anEntry );
794   }
795
796   // For manual mode priority rules are redundant
797   if ( aPanel->getMode() == HYDROData_CalculationCase::MANUAL ) {
798     myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, false );
799   }
800   if ( aPanel->getLandCoverMode() == HYDROData_CalculationCase::MANUAL ) {
801     myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, false );
802   }
803  
804   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init;
805
806   return true;
807 }
808
809 void HYDROGUI_CalculationOp::onApply()
810 {
811   // Check warnings
812   HYDROData_Warning aWarning = myEditedObject->GetLastWarning();
813   if ( aWarning.Type != WARN_OK ) {
814     if ( !confirmContinueWithWarning( aWarning ) ) {
815       // Go back to the first page
816       HYDROGUI_CalculationDlg* aPanel = 
817         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
818       if ( aPanel ) {
819         aPanel->onFirstPage();
820       }
821       return;
822     }
823   }
824
825   QApplication::setOverrideCursor( Qt::WaitCursor );
826
827   int anUpdateFlags = 0;
828   QString anErrorMsg;
829   QStringList aBrowseObjectsEntries;
830
831   bool aResult = false;
832   
833   try
834   {
835     aResult = processApply( anUpdateFlags, anErrorMsg, aBrowseObjectsEntries );
836   }
837   catch ( Standard_Failure )
838   {
839     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
840     anErrorMsg = aFailure->GetMessageString();
841     aResult = false;
842   }
843   catch ( ... )
844   {
845     aResult = false;
846   }
847   
848   QApplication::restoreOverrideCursor();
849
850   if ( aResult )
851   {
852     module()->update( anUpdateFlags );
853     commit();
854     browseObjects( aBrowseObjectsEntries );
855   }
856   else
857   {
858     abort();
859     QString aMsg = tr( "INPUT_VALID_DATA" );
860     if( !anErrorMsg.isEmpty() )
861       aMsg.prepend( anErrorMsg + "\n" );
862     SUIT_MessageBox::critical( module()->getApp()->desktop(),
863                                tr( "INSUFFICIENT_INPUT_DATA" ),
864                                aMsg ); 
865   }
866 }
867
868 void HYDROGUI_CalculationOp::onNext( const int theIndex )
869 {
870   if( theIndex==1 )
871   {
872     setAvailableGroups();
873   }
874   else if( theIndex==2 )
875   {
876     // Land covers panel
877      HYDROGUI_CalculationDlg* aPanel = 
878       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
879     if ( !aPanel )
880       return;
881
882     setLandCoversVisible( true );
883
884     QStringList aList;
885     QStringList anEntryList;
886     HYDROData_SequenceOfObjects aSeq;
887
888     Handle(HYDROData_StricklerTable) aStricklerTableObj;
889     QString aStricklerTableName;
890
891     // Get all Strickler table objects to fill in combo-box
892     aList.clear();
893     anEntryList.clear();
894     HYDROData_Iterator anIter( doc(), KIND_STRICKLER_TABLE );      
895     for ( ; anIter.More(); anIter.Next() )
896     {
897       aStricklerTableObj = Handle(HYDROData_StricklerTable)::DownCast( anIter.Current() );
898
899       if ( !aStricklerTableObj.IsNull() )
900       { 
901         aStricklerTableName = aStricklerTableObj->GetName();
902         if ( !aStricklerTableName.isEmpty() )
903         {
904           aList.append( aStricklerTableName );
905           anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aStricklerTableObj ) );
906         }        
907       }
908     }
909     aPanel->setStricklerTableNames( aList, anEntryList );
910     if ( !aList.isEmpty() )
911       aPanel->setStricklerTable( aList.at( 0 ), false );
912
913     // Fill in list widget with all available land covers
914     aSeq = HYDROGUI_Tool::GetLandCovers( module() );
915     getNamesAndEntries( aSeq, aList, anEntryList );
916     aPanel->setAllLandCovers( aList, anEntryList );
917
918     // Set list of included land covers
919     aSeq = myEditedObject->GetLandCovers();
920     getNamesAndEntries( aSeq, aList, anEntryList );
921     aPanel->includeLandCovers( aList, true );
922     
923     if ( !myEditedObject.IsNull() )
924     {
925       if ( myIsEdit )
926       {      
927         // Select the certain Strickler table object in combo-box
928         aStricklerTableObj = myEditedObject->GetStricklerTable();
929         if ( aStricklerTableObj.IsNull() )
930         {
931           aPanel->setStricklerTable( QString() );
932         }
933         else
934         {
935           aStricklerTableName = aStricklerTableObj->GetName();
936           aPanel->setStricklerTable( aStricklerTableName );
937         }
938
939         // Set mode (Auto or Manual) to defined priority of land covers
940         aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
941
942         // Set rules defined on land covers
943         setRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
944       }
945       else
946       {
947         myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getLandCoverMode() );
948       }
949     }
950
951     closePreview( false );
952     createPreview( true );
953   }
954   else if( theIndex==3 )
955   {
956     HYDROGUI_CalculationDlg* aPanel = 
957       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
958     if ( !aPanel )
959       return;
960
961     QApplication::setOverrideCursor( Qt::WaitCursor );
962
963     setGeomObjectsVisible( false );
964     setLandCoversVisible( false );
965
966     QString aNewCaseName = aPanel->getObjectName();
967     QString anOldCaseName = myEditedObject->GetName();
968     bool isNameChanged = anOldCaseName != aNewCaseName;
969   
970     bool anIsToUpdateOb = isNameChanged;
971
972     // At first we must to update the case name because of 
973     // automatic names generation for regions and zones
974     myEditedObject->SetName( aNewCaseName );
975     
976     // Set parameters for automatic mode
977     int aMode = aPanel->getMode();
978     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
979     {
980       // Set objects in the specified order
981       if( myEditedObject->IsMustBeUpdated() )
982       {
983         myEditedObject->RemoveGeometryObjects();
984         foreach ( const QString& aName, aPanel->getAllGeomObjects() )
985         {
986           Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
987             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
988           if ( anObject.IsNull() )
989           {
990             continue;
991           }
992           myEditedObject->AddGeometryObject( anObject );
993         }
994
995         // Clear priority rules
996         //@ASL if ( myEditedObject->GetRulesCount() > 0 ) {
997           myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, true );
998         //@ASL }
999         // Set priority rules
1000         foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) {
1001           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
1002                                   aRule.Object2, aRule.MergeType,
1003                                   HYDROData_CalculationCase::DataTag_CustomRules );
1004         }
1005       }
1006     }
1007     aPanel->setEditZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
1008          
1009     if ( myEditedObject->IsMustBeUpdated() )
1010     {
1011       myShowZones = true;
1012       myEditedObject->Update();
1013       
1014       AssignDefaultZonesColors( false );
1015
1016       //aPanel->setEditedObject( myEditedObject );
1017       aPanel->refreshZonesBrowser();
1018     
1019       closePreview( false );
1020       createPreview( false );
1021
1022       anIsToUpdateOb = true;
1023
1024       myEditedObject->SetToUpdate( true );
1025     }
1026     else
1027     {
1028       // Show zones
1029       setZonesVisible( true, false );
1030
1031       if ( isNameChanged ) {
1032         module()->getDataModel()->updateObjectTree( myEditedObject );
1033       }
1034     }
1035
1036     QApplication::restoreOverrideCursor();
1037   }
1038   else if( theIndex==4 )
1039   {
1040     // Partition of Land covers panel
1041     HYDROGUI_CalculationDlg* aPanel = 
1042       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1043     if ( !aPanel )
1044       return;
1045
1046     QApplication::setOverrideCursor( Qt::WaitCursor );
1047
1048     // Set parameters for automatic mode
1049     int aMode = aPanel->getLandCoverMode();
1050     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
1051     {
1052       // Set objects in the specified order
1053       if( myEditedObject->IsMustBeUpdated() )
1054       {
1055         myEditedObject->RemoveLandCovers();
1056         foreach ( const QString& aName, aPanel->getAllLandCovers() )
1057         {
1058           Handle(HYDROData_LandCover) aLandCover = Handle(HYDROData_LandCover)::DownCast( 
1059             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
1060           if ( aLandCover.IsNull() )
1061           {
1062             continue;
1063           }
1064           myEditedObject->AddLandCover( aLandCover );
1065         }
1066
1067         // Clear priority rules
1068         myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, true );
1069         // Set priority rules
1070         foreach ( const HYDROData_CustomRule& aRule, aPanel->getLandCoverRules() ) {
1071           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
1072                                    aRule.Object2, HYDROData_Zone::Merge_Object,
1073                                    HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
1074         }
1075       }
1076     }
1077     aPanel->setEditLandCoverZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
1078
1079     bool anIsToUpdateOb = false;
1080     bool anIsToUpdate = myEditedObject->IsMustBeUpdated();
1081     if ( anIsToUpdate )
1082     {
1083       myShowZones = true;
1084       myEditedObject->Update();
1085       
1086       AssignDefaultZonesColors( true );
1087
1088       aPanel->refreshLandCoverZonesBrowser();
1089
1090       anIsToUpdateOb = true;
1091     }
1092
1093     closePreview( false );
1094     createPreview( true );
1095     
1096     if ( !anIsToUpdate )
1097     {
1098       // Hide zones
1099       setZonesVisible( false, false );
1100       // Show land cover zones
1101       setZonesVisible( true, true );
1102     }
1103
1104     if ( anIsToUpdateOb ) {
1105       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
1106       if ( anObjBrowser ) {
1107         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
1108       }
1109     }
1110
1111     QApplication::restoreOverrideCursor();
1112   }
1113 }
1114
1115 void HYDROGUI_CalculationOp::onHideZones( const int theIndex )
1116 {
1117   if( theIndex==1 )
1118   {
1119     setGeomObjectsVisible( true );
1120
1121     closePreview( false );
1122     createPreview( false );
1123   }
1124   if( theIndex==2 )
1125   {
1126     setLandCoversVisible( true );
1127
1128     closePreview( false );
1129     createPreview( true );
1130
1131     // Hide zones
1132     setZonesVisible( false, false );
1133     // Hide land covers
1134     setZonesVisible( false, true );
1135   }
1136   else if( theIndex==3 )
1137   {
1138     AssignDefaultZonesColors( false );
1139
1140     closePreview( false );
1141     createPreview( false );
1142
1143     // Hide land cover zones
1144     setZonesVisible( false, true );
1145     // Show zones
1146     setZonesVisible( true, false );
1147   }
1148 }
1149
1150 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible, const bool theLandCover )
1151 {
1152   myShowZones = theIsVisible;
1153   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1154   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1155   HYDROData_SequenceOfObjects aZones;
1156   Handle(HYDROData_Region) aRegion;
1157   if ( myPreviewViewManager ) 
1158   {
1159     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1160     {
1161       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1162       if ( !aCtx.IsNull() )
1163       {
1164         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1165         {
1166           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1167           if ( !aRegion.IsNull() )
1168           {
1169             aZones = aRegion->GetZones();
1170             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1171             for ( ; aZonesIter.More(); aZonesIter.Next() )
1172             {
1173               setObjectVisibility( aZonesIter.Value(), theIsVisible );
1174             }
1175           }
1176         }
1177       }
1178
1179       module()->update( UF_OCCViewer );
1180     }
1181   }
1182 }
1183
1184 void HYDROGUI_CalculationOp::setGeomObjectsVisible( bool theIsVisible )
1185 {
1186   myShowGeomObjects = theIsVisible;
1187
1188   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
1189
1190   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1191   for ( ; anIter.More(); anIter.Next() ) {
1192     setObjectVisibility( anIter.Value(), theIsVisible );
1193   }
1194 }
1195
1196 void HYDROGUI_CalculationOp::setLandCoversVisible( bool theIsVisible )
1197 {
1198   myShowLandCovers = theIsVisible;
1199
1200   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
1201
1202   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1203   for ( ; anIter.More(); anIter.Next() ) {
1204     setObjectVisibility( anIter.Value(), theIsVisible );
1205   }
1206 }
1207
1208 void HYDROGUI_CalculationOp::AssignDefaultZonesColors( const bool theLandCover )
1209 {
1210   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1211   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1212   HYDROData_SequenceOfObjects aZones;
1213   Handle(HYDROData_Region) aRegion;
1214   if ( myPreviewViewManager ) 
1215   {
1216     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1217     {
1218       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1219       if ( !aCtx.IsNull() )
1220       {
1221         int aCounter = 0;        
1222         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1223         {
1224           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1225           if ( !aRegion.IsNull() )
1226           {
1227             aZones = aRegion->GetZones();
1228             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1229             for ( ; aZonesIter.More(); aZonesIter.Next() )
1230             {
1231               // Zone
1232               Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
1233               if ( !aZone.IsNull() )
1234               {
1235                 QColor aFillingColor = GenerateDefaultZonesColor(++aCounter);
1236                 while (aFillingColor == Qt::red)
1237                   aFillingColor = GenerateDefaultZonesColor(++aCounter);
1238                 
1239                 aZone->SetColor(aFillingColor);
1240               }
1241             }
1242           }
1243         }
1244       }
1245     }
1246   }
1247 }
1248
1249 QColor HYDROGUI_CalculationOp::GenerateDefaultZonesColor( int theIndex,
1250                                                           float theSaturation/* = 0.5*/,
1251                                                           float theValue/* = 0.95*/ ) const
1252 {
1253   float aGoldenRatioConjugate = (float)(360./582.);
1254   float aHue = (float)(rand()%100);
1255   aHue += aGoldenRatioConjugate*theIndex;
1256   aHue -= floor(aHue);
1257
1258   float aR = 0., aG = 0., aB = 0.;
1259   int aHueInt = (int)(aHue*6.);
1260   float aF = aHue*6. - aHueInt;
1261   float aP = theValue * (1. - theSaturation);
1262   float aQ = theValue * (1. - aF*theSaturation);
1263   float aT = theValue * (1. - (1. - aF) * theSaturation);
1264   switch (aHueInt)
1265   {
1266   case 0: { aR = theValue; aG = aT; aB = aP; break; }
1267   case 1: { aR = aQ; aG = theValue; aB = aP; break; }
1268   case 2: { aR = aP; aG = theValue; aB = aT; break; }
1269   case 3: { aR = aP; aG = aQ; aB = theValue; break; }
1270   case 4: { aR = aT; aG = aP; aB = theValue; break; }
1271   case 5: { aR = theValue; aG = aP; aB = aQ; break; }
1272   default: break;
1273   }
1274
1275   QColor aColor = QColor( (int)(aR*256.), (int)(aG*256.), (int)(aB*256.) );
1276   return ( aColor.isValid() ? aColor : HYDROData_ImmersibleZone::DefaultFillingColor() );
1277 }
1278
1279 void HYDROGUI_CalculationOp::setRules( HYDROData_CalculationCase::DataTag theDataTag )
1280 {
1281   HYDROGUI_CalculationDlg* aPanel = 
1282     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1283   if ( !aPanel )
1284     return;
1285
1286   HYDROData_ListOfRules aRules;
1287   Handle(HYDROData_Entity) anObject1, anObject2;
1288   HYDROData_PriorityType aPriority;
1289   HYDROData_Zone::MergeType aMergeType;
1290   HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
1291   for ( int anIndex = 0; ; anIndex++ )
1292   {
1293     if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType, theDataTag ) ) {
1294       HYDROData_CustomRule aRule;
1295       aRule.Object1 = anObject1;
1296       aRule.Object2 = anObject2;
1297       aRule.Priority = aPriority;
1298       aRule.MergeType = aMergeType;
1299
1300       aRules << aRule;
1301     }
1302     else
1303       break;
1304   }
1305
1306   if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomRules )
1307     aPanel->setRules( aRules );
1308   else if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomLandCoverRules )
1309     aPanel->setLandCoverRules( aRules );
1310 }
1311
1312 bool HYDROGUI_CalculationOp::createRegion( const QList<SUIT_DataObject*>& theZonesList,
1313                                            const bool theLandCover )
1314 {
1315   bool aRetValue = false;
1316
1317   QList<HYDROGUI_Zone*> aZonesList;
1318   HYDROGUI_Zone* aZone;
1319   // Get a list of dropped zones
1320   for ( int i = 0; i < theZonesList.length(); i++ )
1321   {
1322     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
1323     if ( aZone )
1324     {
1325       aZonesList.append( aZone );
1326     }
1327   }
1328   if ( aZonesList.length() > 0 )
1329   {
1330     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList, theLandCover );
1331     aRetValue = true;
1332   }
1333    
1334   return aRetValue;
1335 }
1336
1337 void HYDROGUI_CalculationOp::createPreview( const bool theLandCover )
1338 {
1339   LightApp_Application* anApp = module()->getApp();
1340   HYDROData_SequenceOfObjects aSeq;
1341   if ( theLandCover && myShowLandCovers )
1342   {
1343     HYDROData_SequenceOfObjects aSeqLC = myEditedObject->GetLandCovers();
1344     aSeq.Append( aSeqLC );
1345   }
1346   else if ( !theLandCover && myShowGeomObjects )
1347   {
1348     HYDROData_SequenceOfObjects aSeqGO = myEditedObject->GetGeometryObjects();
1349     aSeq.Append( aSeqGO );
1350   }
1351
1352   Handle(HYDROData_Entity) anEntity;
1353
1354   if ( myShowZones )
1355   {
1356     // Gather zones for displaying
1357     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1358     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1359     HYDROData_SequenceOfObjects aZones;
1360     Handle(HYDROData_Region) aRegion;
1361     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1362     {
1363       anEntity = aRegionsIter.Value();
1364       if ( !anEntity.IsNull() )
1365       {
1366         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
1367         if ( !aRegion.IsNull() )
1368         {
1369           aZones = aRegion->GetZones();
1370           aSeq.Append( aZones );
1371         }
1372       }
1373     }
1374   }
1375
1376   // Get a boundary polyline if any
1377   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
1378
1379   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
1380
1381   if ( !myActiveViewManager )
1382   {
1383     if ( aSeq.IsEmpty() )
1384       return;
1385
1386     myActiveViewManager = anApp->activeViewManager();
1387   }
1388
1389   if ( !myPreviewViewManager )
1390   {
1391     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
1392       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
1393     if ( myPreviewViewManager )
1394     {
1395       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1396                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1397
1398       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
1399       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
1400     }
1401   }
1402
1403   if ( !myPreviewViewManager )
1404     return;
1405
1406   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1407   {
1408     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1409     if ( !aCtx.IsNull() )
1410     {
1411       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1412       for ( ; anIter.More(); anIter.Next() )
1413       {
1414         setObjectVisibility( anIter.Value(), true );
1415       }
1416
1417       //Process the draw events for viewer
1418       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
1419       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
1420         vw->onTopView();
1421     }
1422
1423     module()->update( UF_OCCViewer | UF_FitAll );
1424   }
1425 }
1426
1427 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
1428 {
1429   if ( theEntity.IsNull() || !myPreviewViewManager ) {
1430     return;
1431   }
1432
1433   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1434   if ( aViewer ) {
1435     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
1436   }
1437 }
1438
1439 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
1440 {
1441   closePreview();
1442 }
1443
1444 void HYDROGUI_CalculationOp::closePreview( bool theRemoveViewManager )
1445 {
1446   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
1447   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
1448   QShortcut* aShortcut;
1449   foreach( aShortcut, aShortcuts )
1450   {
1451     if ( aShortcut->key() == 
1452       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
1453       SUIT_DataBrowser::RenameShortcut ) ) )
1454     {
1455       aShortcut->setEnabled( true );
1456     }
1457   }
1458
1459
1460   if( myPreviewViewManager )
1461   {
1462     // Hide all the displayed objects in the preview view
1463     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1464     if ( aViewer ) {
1465       size_t aViewId = (size_t)aViewer;
1466       HYDROData_Iterator anIterator( doc() );
1467       for( ; anIterator.More(); anIterator.Next() ) {
1468         Handle(HYDROData_Entity) anObject = anIterator.Current();
1469         if( !anObject.IsNull() ) {
1470           module()->setObjectVisible( aViewId, anObject, false );
1471         }
1472       }
1473     }
1474
1475     if ( theRemoveViewManager )
1476     {
1477       disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1478                   this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1479
1480       module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
1481       myPreviewViewManager = NULL;
1482     }
1483   }
1484
1485   if( myActiveViewManager && theRemoveViewManager )
1486   {
1487     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
1488     myActiveViewManager = NULL;
1489   }
1490 }
1491
1492 void HYDROGUI_CalculationOp::setAvailableGroups()
1493 {
1494   HYDROGUI_CalculationDlg* aPanel = 
1495       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1496
1497   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
1498   QStringList aList, anEntryList;
1499   getNamesAndEntries( aSeq, aList, anEntryList );
1500
1501   QStringList aGroupsNames;
1502
1503   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
1504   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
1505   {
1506     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
1507     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
1508     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
1509     {
1510       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
1511       aGroupsNames.append( aGroup->GetName() );
1512     }
1513   }
1514   if( myEditedObject->IsMustBeUpdated() ) {
1515     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
1516       Handle(HYDROData_ShapesGroup) aGeomGroup =
1517         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
1518       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
1519         myEditedObject->RemoveGeometryGroup( aGeomGroup );
1520       }
1521     }
1522   }
1523
1524   aPanel->setAvailableGroups( aGroupsNames );
1525   aPanel->includeGroups( aList );
1526
1527   bool isUpdated = myEditedObject->IsMustBeUpdated();
1528 }
1529
1530 void HYDROGUI_CalculationOp::onAddGroups()
1531 {
1532   HYDROGUI_CalculationDlg* aPanel = 
1533     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1534   if ( !aPanel )
1535     return;
1536
1537   // Add geometry objects selected in the module browser to the calculation case
1538   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
1539   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1540     return;
1541
1542   QStringList anAddedList;
1543   for (int i = 0; i < aSelectedList.length(); i++)
1544   {
1545     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1546       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1547     if ( aGroup.IsNull() )
1548       continue;
1549
1550     if ( myEditedObject->AddGeometryGroup( aGroup ) )
1551       anAddedList.append( aGroup->GetName() );
1552   }
1553
1554   if ( !anAddedList.isEmpty() )
1555   {
1556     aPanel->includeGroups( anAddedList );
1557   }
1558 }
1559
1560 void HYDROGUI_CalculationOp::onRemoveGroups()
1561 {
1562   // Remove selected objects from the calculation case
1563   HYDROGUI_CalculationDlg* aPanel = 
1564     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1565   if ( !aPanel )
1566     return;
1567
1568   QStringList aSelectedList = aPanel->getSelectedGroups();
1569   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1570     return;
1571
1572   for (int i = 0; i < aSelectedList.length(); i++)
1573   {
1574     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1575       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1576     if ( aGroup.IsNull() )
1577       continue;
1578
1579     myEditedObject->RemoveGeometryGroup( aGroup );
1580   }
1581
1582   aPanel->excludeGroups( aSelectedList );
1583 }
1584
1585 void HYDROGUI_CalculationOp::onChangeLandCoverMode( int theMode )
1586 {
1587   HYDROGUI_CalculationDlg* aPanel = 
1588     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1589   if ( !aPanel )
1590     return;
1591
1592   if ( !confirmLandCoverModeChange() ) {
1593     aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
1594     return;
1595   }
1596
1597   myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1598   aPanel->setLandCoverMode( theMode );
1599 }
1600
1601 void HYDROGUI_CalculationOp::onAddLandCovers()
1602 {
1603   HYDROGUI_CalculationDlg* aPanel = 
1604     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1605   if ( !aPanel )
1606     return;
1607
1608   // Add land covers selected in the module browser to the calculation case
1609   QStringList aSelectedList = aPanel->getSelectedAvailableLandCovers();
1610   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1611     return;
1612
1613   QStringList anAddedList;
1614   for (int i = 0; i < aSelectedList.length(); i++)
1615   {
1616     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1617       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1618     if ( anObject.IsNull() )
1619       continue;
1620
1621     if ( myEditedObject->AddLandCover( anObject ) )
1622       anAddedList.append( anObject->GetName() );
1623   }
1624
1625   if ( !anAddedList.isEmpty() )
1626   {
1627     aPanel->includeLandCovers( anAddedList, false );
1628     createPreview( true );
1629   }
1630 }
1631
1632 void HYDROGUI_CalculationOp::onRemoveLandCovers()
1633 {
1634   // Remove selected objects from the calculation case
1635   HYDROGUI_CalculationDlg* aPanel = 
1636     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1637   if ( !aPanel )
1638     return;
1639
1640   QStringList aSelectedList = aPanel->getSelectedLandCovers();
1641   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1642     return;
1643
1644   for (int i = 0; i < aSelectedList.length(); i++)
1645   {
1646     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1647       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1648     if ( anObject.IsNull() )
1649       continue;
1650
1651     setObjectVisibility( anObject, false );
1652     myEditedObject->RemoveLandCover( anObject );
1653   }
1654
1655   module()->update( UF_OCCViewer );
1656   aPanel->excludeLandCovers( aSelectedList );
1657 }
1658
1659 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1660 {
1661   HYDROGUI_CalculationDlg* aPanel = 
1662     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1663   if ( !aPanel )
1664     return;
1665
1666   if ( !confirmModeChange() ) {
1667     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1668     return;
1669   }
1670
1671   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1672   aPanel->setMode( theMode );
1673 }
1674
1675 void HYDROGUI_CalculationOp::onOrderChanged( bool& isConfirmed )
1676 {
1677   HYDROGUI_CalculationDlg* aPanel = 
1678     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1679   if ( !aPanel )
1680     return;
1681
1682   isConfirmed = confirmOrderChange();
1683   if( isConfirmed )
1684     myEditedObject->SetToUpdate( true );
1685 }
1686
1687 void HYDROGUI_CalculationOp::onOrderLandCoverChanged( bool& isConfirmed )
1688 {
1689   HYDROGUI_CalculationDlg* aPanel = 
1690     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1691   if ( !aPanel )
1692     return;
1693
1694   isConfirmed = confirmLandCoverOrderChange();
1695   if( isConfirmed )
1696     myEditedObject->SetToUpdate( true );
1697 }