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