Salome HOME
e6b9ea7248c52770ed199955b3765dd8e553c3e7
[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& theAltitudeName )
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, theAltitudeName );
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->setMergeStricklerType( 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   else if( theIndex==3 )
947   {
948     HYDROGUI_CalculationDlg* aPanel = 
949       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
950     if ( !aPanel )
951       return;
952
953     QApplication::setOverrideCursor( Qt::WaitCursor );
954   
955     QString aNewCaseName = aPanel->getObjectName();
956     QString anOldCaseName = myEditedObject->GetName();
957     bool isNameChanged = anOldCaseName != aNewCaseName;
958   
959     bool anIsToUpdateOb = isNameChanged;
960
961     // At first we must to update the case name because of 
962     // automatic names generation for regions and zones
963     myEditedObject->SetName( aNewCaseName );
964     
965     // Set parameters for automatic mode
966     int aMode = aPanel->getMode();
967     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
968     {
969       // Set objects in the specified order
970       if( myEditedObject->IsMustBeUpdated() )
971       {
972         myEditedObject->RemoveGeometryObjects();
973         foreach ( const QString& aName, aPanel->getAllGeomObjects() )
974         {
975           Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
976             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
977           if ( anObject.IsNull() )
978           {
979             continue;
980           }
981           myEditedObject->AddGeometryObject( anObject );
982         }
983
984         // Clear priority rules
985         //@ASL if ( myEditedObject->GetRulesCount() > 0 ) {
986           myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, true );
987         //@ASL }
988         // Set priority rules
989         foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) {
990           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
991                                   aRule.Object2, aRule.MergeType,
992                                   HYDROData_CalculationCase::DataTag_CustomRules );
993         }
994       }
995     }
996     aPanel->setEditZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
997          
998     if ( myEditedObject->IsMustBeUpdated() )
999     {
1000       myShowZones = true;
1001       myEditedObject->Update();
1002       
1003       AssignDefaultZonesColors( false );
1004
1005       //aPanel->setEditedObject( myEditedObject );
1006       aPanel->refreshZonesBrowser();
1007     
1008       closePreview();
1009       createPreview( false );
1010
1011       anIsToUpdateOb = true;
1012
1013       myEditedObject->SetToUpdate( true );
1014     }
1015     else
1016     {
1017       // Show zones
1018       setZonesVisible( true, false );
1019
1020       if ( isNameChanged ) {
1021         module()->getDataModel()->updateObjectTree( myEditedObject );
1022       }
1023     }
1024
1025     QApplication::restoreOverrideCursor();
1026   }
1027   else if( theIndex==4 )
1028   {
1029     // Partition of Land covers panel
1030     HYDROGUI_CalculationDlg* aPanel = 
1031       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1032     if ( !aPanel )
1033       return;
1034
1035     QApplication::setOverrideCursor( Qt::WaitCursor );
1036
1037     // Set parameters for automatic mode
1038     int aMode = aPanel->getLandCoverMode();
1039     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
1040     {
1041       // Set objects in the specified order
1042       if( myEditedObject->IsMustBeUpdated() )
1043       {
1044         myEditedObject->RemoveLandCovers();
1045         foreach ( const QString& aName, aPanel->getAllLandCovers() )
1046         {
1047           Handle(HYDROData_LandCover) aLandCover = Handle(HYDROData_LandCover)::DownCast( 
1048             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
1049           if ( aLandCover.IsNull() )
1050           {
1051             continue;
1052           }
1053           myEditedObject->AddLandCover( aLandCover );
1054         }
1055
1056         // Clear priority rules
1057         myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, true );
1058         // Set priority rules
1059         foreach ( const HYDROData_CustomRule& aRule, aPanel->getLandCoverRules() ) {
1060           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
1061                                    aRule.Object2, HYDROData_Zone::Merge_Object,
1062                                    HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
1063         }
1064       }
1065     }
1066     aPanel->setEditLandCoverZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
1067
1068     bool anIsToUpdateOb = false;
1069     if ( myEditedObject->IsMustBeUpdated() )
1070     {
1071       myShowZones = true;
1072       myEditedObject->Update();
1073       
1074       AssignDefaultZonesColors( true );
1075
1076       aPanel->refreshLandCoverZonesBrowser();
1077     
1078       closePreview();
1079       createPreview( true );
1080
1081       anIsToUpdateOb = true;
1082
1083       myEditedObject->SetToUpdate( true );
1084     }
1085     else
1086     {
1087       // Hide zones
1088       setZonesVisible( false, false );
1089       // Show land cover zones
1090       setZonesVisible( true, true );
1091     }
1092
1093     if ( anIsToUpdateOb ) {
1094       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
1095       if ( anObjBrowser ) {
1096         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
1097       }
1098     }
1099
1100     QApplication::restoreOverrideCursor();
1101   }
1102 }
1103
1104 void HYDROGUI_CalculationOp::onHideZones( const int theIndex )
1105 {
1106   if( theIndex==3 )
1107   {
1108     // Hide zones
1109     setZonesVisible( false, false );
1110   }
1111   else if( theIndex==4 )
1112   {
1113     // Hide land cover zones
1114     setZonesVisible( false, true );
1115   }
1116 }
1117
1118 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible, const bool theLandCover )
1119 {
1120   myShowZones = theIsVisible;
1121   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1122   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1123   HYDROData_SequenceOfObjects aZones;
1124   Handle(HYDROData_Region) aRegion;
1125   if ( myPreviewViewManager ) 
1126   {
1127     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1128     {
1129       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1130       if ( !aCtx.IsNull() )
1131       {
1132         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1133         {
1134           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1135           if ( !aRegion.IsNull() )
1136           {
1137             aZones = aRegion->GetZones();
1138             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1139             for ( ; aZonesIter.More(); aZonesIter.Next() )
1140             {
1141               setObjectVisibility( aZonesIter.Value(), theIsVisible );
1142             }
1143           }
1144         }
1145       }
1146
1147       module()->update( UF_OCCViewer );
1148     }
1149   }
1150 }
1151
1152 void HYDROGUI_CalculationOp::AssignDefaultZonesColors( const bool theLandCover )
1153 {
1154   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1155   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1156   HYDROData_SequenceOfObjects aZones;
1157   Handle(HYDROData_Region) aRegion;
1158   if ( myPreviewViewManager ) 
1159   {
1160     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1161     {
1162       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1163       if ( !aCtx.IsNull() )
1164       {
1165         int aCounter = 0;        
1166         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1167         {
1168           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1169           if ( !aRegion.IsNull() )
1170           {
1171             aZones = aRegion->GetZones();
1172             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1173             for ( ; aZonesIter.More(); aZonesIter.Next() )
1174             {
1175               // Zone
1176               Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
1177               if ( !aZone.IsNull() )
1178               {
1179                 QColor aFillingColor = GenerateDefaultZonesColor(++aCounter);
1180                 while (aFillingColor == Qt::red)
1181                   aFillingColor = GenerateDefaultZonesColor(++aCounter);
1182                 
1183                 aZone->SetColor(aFillingColor);
1184               }
1185             }
1186           }
1187         }
1188       }
1189     }
1190   }
1191 }
1192
1193 QColor HYDROGUI_CalculationOp::GenerateDefaultZonesColor( int theIndex,
1194                                                           float theSaturation/* = 0.5*/,
1195                                                           float theValue/* = 0.95*/ ) const
1196 {
1197   float aGoldenRatioConjugate = (float)(360./582.);
1198   float aHue = (float)rand();
1199   aHue += aGoldenRatioConjugate*theIndex;
1200   aHue -= floor(aHue);
1201
1202   float aR = 0., aG = 0., aB = 0.;
1203   int aHueInt = (int)(aHue*6.);
1204   float aF = aHue*6. - aHueInt;
1205   float aP = theValue * (1. - theSaturation);
1206   float aQ = theValue * (1. - aF*theSaturation);
1207   float aT = theValue * (1. - (1. - aF) * theSaturation);
1208   switch (aHueInt)
1209   {
1210   case 0: { aR = theValue; aG = aT; aB = aP; break; }
1211   case 1: { aR = aQ; aG = theValue; aB = aP; break; }
1212   case 2: { aR = aP; aG = theValue; aB = aT; break; }
1213   case 3: { aR = aP; aG = aQ; aB = theValue; break; }
1214   case 4: { aR = aT; aG = aP; aB = theValue; break; }
1215   case 5: { aR = theValue; aG = aP; aB = aQ; break; }
1216   default: break;
1217   }
1218
1219   QColor aColor = QColor( (int)(aR*256.), (int)(aG*256.), (int)(aB*256.) );
1220   return ( aColor.isValid() ? aColor : HYDROData_ImmersibleZone::DefaultFillingColor() );
1221 }
1222
1223 void HYDROGUI_CalculationOp::setRules( HYDROData_CalculationCase::DataTag theDataTag )
1224 {
1225   HYDROGUI_CalculationDlg* aPanel = 
1226     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1227   if ( !aPanel )
1228     return;
1229
1230   HYDROData_ListOfRules aRules;
1231   Handle(HYDROData_Entity) anObject1, anObject2;
1232   HYDROData_PriorityType aPriority;
1233   HYDROData_Zone::MergeAltitudesType aMergeType;
1234   HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
1235   for ( int anIndex = 0; ; anIndex++ )
1236   {
1237     if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType, theDataTag ) ) {
1238       HYDROData_CustomRule aRule;
1239       aRule.Object1 = anObject1;
1240       aRule.Object2 = anObject2;
1241       aRule.Priority = aPriority;
1242       aRule.MergeType = aMergeType;
1243
1244       aRules << aRule;
1245     }
1246     else
1247       break;
1248   }
1249
1250   if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomRules )
1251     aPanel->setRules( aRules );
1252   else if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomLandCoverRules )
1253     aPanel->setLandCoverRules( aRules );
1254 }
1255
1256 bool HYDROGUI_CalculationOp::createRegion( const QList<SUIT_DataObject*>& theZonesList,
1257                                            const bool theLandCover )
1258 {
1259   bool aRetValue = false;
1260
1261   QList<HYDROGUI_Zone*> aZonesList;
1262   HYDROGUI_Zone* aZone;
1263   // Get a list of dropped zones
1264   for ( int i = 0; i < theZonesList.length(); i++ )
1265   {
1266     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
1267     if ( aZone )
1268     {
1269       aZonesList.append( aZone );
1270     }
1271   }
1272   if ( aZonesList.length() > 0 )
1273   {
1274     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList, theLandCover );
1275     aRetValue = true;
1276   }
1277    
1278   return aRetValue;
1279 }
1280
1281 void HYDROGUI_CalculationOp::createPreview( const bool theLandCover )
1282 {
1283   LightApp_Application* anApp = module()->getApp();
1284   HYDROData_SequenceOfObjects aSeq;
1285   if ( theLandCover )
1286     aSeq = myEditedObject->GetLandCovers();
1287   else
1288     aSeq = myEditedObject->GetGeometryObjects();
1289   Handle(HYDROData_Entity) anEntity;
1290
1291   if ( myShowZones )
1292   {
1293     // Gather zones for displaying
1294     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions( theLandCover );
1295     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1296     HYDROData_SequenceOfObjects aZones;
1297     Handle(HYDROData_Region) aRegion;
1298     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1299     {
1300       anEntity = aRegionsIter.Value();
1301       if ( !anEntity.IsNull() )
1302       {
1303         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
1304         if ( !aRegion.IsNull() )
1305         {
1306           aZones = aRegion->GetZones();
1307           aSeq.Append( aZones );
1308         }
1309       }
1310     }
1311   }
1312
1313   // Get a boundary polyline if any
1314   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
1315
1316   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
1317
1318   if ( !myActiveViewManager )
1319   {
1320     if ( aSeq.IsEmpty() )
1321       return;
1322
1323     myActiveViewManager = anApp->activeViewManager();
1324   }
1325
1326   if ( !myPreviewViewManager )
1327   {
1328     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
1329       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
1330     if ( myPreviewViewManager )
1331     {
1332       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1333                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1334
1335       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
1336       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
1337     }
1338   }
1339
1340   if ( !myPreviewViewManager )
1341     return;
1342
1343   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1344   {
1345     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1346     if ( !aCtx.IsNull() )
1347     {
1348       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1349       for ( ; anIter.More(); anIter.Next() )
1350       {
1351         setObjectVisibility( anIter.Value(), true );
1352       }
1353
1354       //Process the draw events for viewer
1355       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
1356       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
1357         vw->onTopView();
1358     }
1359
1360     module()->update( UF_OCCViewer | UF_FitAll );
1361   }
1362 }
1363
1364 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
1365 {
1366   if ( theEntity.IsNull() || !myPreviewViewManager ) {
1367     return;
1368   }
1369
1370   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1371   if ( aViewer ) {
1372     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
1373   }
1374 }
1375
1376 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
1377 {
1378   closePreview();
1379 }
1380
1381 void HYDROGUI_CalculationOp::closePreview()
1382 {
1383   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
1384   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
1385   QShortcut* aShortcut;
1386   foreach( aShortcut, aShortcuts )
1387   {
1388     if ( aShortcut->key() == 
1389       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
1390       SUIT_DataBrowser::RenameShortcut ) ) )
1391     {
1392       aShortcut->setEnabled( true );
1393     }
1394   }
1395
1396
1397   if( myPreviewViewManager )
1398   {
1399     // Hide all the displayed objects in the preview view
1400     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1401     if ( aViewer ) {
1402       size_t aViewId = (size_t)aViewer;
1403       HYDROData_Iterator anIterator( doc() );
1404       for( ; anIterator.More(); anIterator.Next() ) {
1405         Handle(HYDROData_Entity) anObject = anIterator.Current();
1406         if( !anObject.IsNull() ) {
1407           module()->setObjectVisible( aViewId, anObject, false );
1408         }
1409       }
1410     }
1411
1412     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1413                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1414
1415     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
1416     myPreviewViewManager = NULL;
1417   }
1418
1419   if( myActiveViewManager )
1420   {
1421     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
1422     myActiveViewManager = NULL;
1423   }
1424 }
1425
1426 void HYDROGUI_CalculationOp::setAvailableGroups()
1427 {
1428   HYDROGUI_CalculationDlg* aPanel = 
1429       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1430
1431   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
1432   QStringList aList, anEntryList;
1433   getNamesAndEntries( aSeq, aList, anEntryList );
1434
1435   QStringList aGroupsNames;
1436
1437   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
1438   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
1439   {
1440     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
1441     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
1442     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
1443     {
1444       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
1445       aGroupsNames.append( aGroup->GetName() );
1446     }
1447   }
1448   if( myEditedObject->IsMustBeUpdated() ) {
1449     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
1450       Handle(HYDROData_ShapesGroup) aGeomGroup =
1451         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
1452       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
1453         myEditedObject->RemoveGeometryGroup( aGeomGroup );
1454       }
1455     }
1456   }
1457
1458   aPanel->setAvailableGroups( aGroupsNames );
1459   aPanel->includeGroups( aList );
1460
1461   bool isUpdated = myEditedObject->IsMustBeUpdated();
1462 }
1463
1464 void HYDROGUI_CalculationOp::onAddGroups()
1465 {
1466   HYDROGUI_CalculationDlg* aPanel = 
1467     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1468   if ( !aPanel )
1469     return;
1470
1471   // Add geometry objects selected in the module browser to the calculation case
1472   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
1473   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1474     return;
1475
1476   QStringList anAddedList;
1477   for (int i = 0; i < aSelectedList.length(); i++)
1478   {
1479     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1480       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1481     if ( aGroup.IsNull() )
1482       continue;
1483
1484     if ( myEditedObject->AddGeometryGroup( aGroup ) )
1485       anAddedList.append( aGroup->GetName() );
1486   }
1487
1488   if ( !anAddedList.isEmpty() )
1489   {
1490     aPanel->includeGroups( anAddedList );
1491   }
1492 }
1493
1494 void HYDROGUI_CalculationOp::onRemoveGroups()
1495 {
1496   // Remove selected objects from the calculation case
1497   HYDROGUI_CalculationDlg* aPanel = 
1498     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1499   if ( !aPanel )
1500     return;
1501
1502   QStringList aSelectedList = aPanel->getSelectedGroups();
1503   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1504     return;
1505
1506   for (int i = 0; i < aSelectedList.length(); i++)
1507   {
1508     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1509       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1510     if ( aGroup.IsNull() )
1511       continue;
1512
1513     myEditedObject->RemoveGeometryGroup( aGroup );
1514   }
1515
1516   aPanel->excludeGroups( aSelectedList );
1517 }
1518
1519 void HYDROGUI_CalculationOp::onChangeLandCoverMode( int theMode )
1520 {
1521   HYDROGUI_CalculationDlg* aPanel = 
1522     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1523   if ( !aPanel )
1524     return;
1525
1526   if ( !confirmLandCoverModeChange() ) {
1527     aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
1528     return;
1529   }
1530
1531   myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1532   aPanel->setLandCoverMode( theMode );
1533 }
1534
1535 void HYDROGUI_CalculationOp::onAddLandCovers()
1536 {
1537   HYDROGUI_CalculationDlg* aPanel = 
1538     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1539   if ( !aPanel )
1540     return;
1541
1542   // Add land covers selected in the module browser to the calculation case
1543   QStringList aSelectedList = aPanel->getSelectedAvailableLandCovers();
1544   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1545     return;
1546
1547   QStringList anAddedList;
1548   for (int i = 0; i < aSelectedList.length(); i++)
1549   {
1550     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1551       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1552     if ( anObject.IsNull() )
1553       continue;
1554
1555     if ( myEditedObject->AddLandCover( anObject ) )
1556       anAddedList.append( anObject->GetName() );
1557   }
1558
1559   if ( !anAddedList.isEmpty() )
1560   {
1561     aPanel->includeLandCovers( anAddedList, false );
1562     createPreview( true );
1563   }
1564 }
1565
1566 void HYDROGUI_CalculationOp::onRemoveLandCovers()
1567 {
1568   // Remove selected objects from the calculation case
1569   HYDROGUI_CalculationDlg* aPanel = 
1570     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1571   if ( !aPanel )
1572     return;
1573
1574   QStringList aSelectedList = aPanel->getSelectedLandCovers();
1575   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1576     return;
1577
1578   for (int i = 0; i < aSelectedList.length(); i++)
1579   {
1580     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1581       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1582     if ( anObject.IsNull() )
1583       continue;
1584
1585     setObjectVisibility( anObject, false );
1586     myEditedObject->RemoveLandCover( anObject );
1587   }
1588
1589   module()->update( UF_OCCViewer );
1590   aPanel->excludeLandCovers( aSelectedList );
1591 }
1592
1593 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1594 {
1595   HYDROGUI_CalculationDlg* aPanel = 
1596     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1597   if ( !aPanel )
1598     return;
1599
1600   if ( !confirmModeChange() ) {
1601     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1602     return;
1603   }
1604
1605   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1606   aPanel->setMode( theMode );
1607 }
1608
1609 void HYDROGUI_CalculationOp::onOrderChanged( bool& isConfirmed )
1610 {
1611   HYDROGUI_CalculationDlg* aPanel = 
1612     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1613   if ( !aPanel )
1614     return;
1615
1616   isConfirmed = confirmOrderChange();
1617   if( isConfirmed )
1618     myEditedObject->SetToUpdate( true );
1619 }
1620
1621 void HYDROGUI_CalculationOp::onOrderLandCoverChanged( bool& isConfirmed )
1622 {
1623   HYDROGUI_CalculationDlg* aPanel = 
1624     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1625   if ( !aPanel )
1626     return;
1627
1628   isConfirmed = confirmLandCoverOrderChange();
1629   if( isConfirmed )
1630     myEditedObject->SetToUpdate( true );
1631 }