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