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