Salome HOME
copyrights are updated
[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_Object.h>
33 #include <HYDROData_Tool.h>
34
35 #include <OCCViewer_ViewManager.h>
36 #include <OCCViewer_ViewModel.h>
37 #include <OCCViewer_ViewWindow.h>
38
39 #include <LightApp_Application.h>
40 #include <LightApp_UpdateFlags.h>
41 #include <LightApp_SelectionMgr.h>
42 #include <LightApp_DataOwner.h>
43
44 #include <SUIT_MessageBox.h>
45 #include <SUIT_Desktop.h>
46 #include <SUIT_DataBrowser.h>
47
48 #include <QApplication>
49 #include <QKeySequence>
50 #include <QShortcut>
51
52 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
53 : HYDROGUI_Operation( theModule ),
54   myIsEdit( theIsEdit ),
55   myActiveViewManager( NULL ),
56   myPreviewViewManager( NULL )
57 {
58   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
59 }
60
61 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
62 {
63   closePreview();
64 }
65
66 void HYDROGUI_CalculationOp::startOperation()
67 {
68   HYDROGUI_Operation::startOperation();
69   
70   // Begin transaction
71   startDocOperation();
72
73   HYDROGUI_CalculationDlg* aPanel = 
74     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
75   if ( !aPanel )
76     return;
77
78   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
79   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
80   QShortcut* aShortcut;
81   foreach( aShortcut, aShortcuts )
82   {
83     if ( aShortcut->key() == 
84       QKeySequence(((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
85       SUIT_DataBrowser::RenameShortcut ) ) )
86     {
87       aShortcut->setEnabled( false );
88     }
89   }
90
91   aPanel->reset();
92   QStringList aList;
93   QStringList anEntryList;
94   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetGeometryObjects( module() );
95   getNamesAndEntries( aSeq, aList, anEntryList );
96   aPanel->setAllGeomObjects( aList, anEntryList );
97
98   // Get all polylines
99   aList.clear();
100   anEntryList.clear();
101   HYDROData_Iterator anIter( doc(), KIND_POLYLINEXY );
102   Handle(HYDROData_PolylineXY) aPolylineObj;
103   QString aPolylineName;
104   for ( ; anIter.More(); anIter.Next() )
105   {
106     aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( anIter.Current() );
107
108     if ( !aPolylineObj.IsNull() && aPolylineObj->IsClosed() )
109     { 
110       // Check the polyline shape
111       TopoDS_Shape aPolylineShape = aPolylineObj->GetShape();
112       if ( !aPolylineShape.IsNull() && aPolylineShape.ShapeType() == TopAbs_WIRE ) {
113         aPolylineName = aPolylineObj->GetName();
114         if ( !aPolylineName.isEmpty() )
115         {
116           aList.append( aPolylineName );
117           anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aPolylineObj ) );
118         }
119       }
120     }
121   }
122   aPanel->setPolylineNames( aList, anEntryList );
123
124   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_CALCULATION_CASE_NAME" ) );
125
126   myEditedObject.Nullify();
127   if ( myIsEdit )
128   {
129     myEditedObject = Handle(HYDROData_CalculationCase)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
130     if ( !myEditedObject.IsNull() )
131     {
132       aPanel->setMode( myEditedObject->GetAssignmentMode() );
133       anObjectName = myEditedObject->GetName();
134       aPolylineObj = myEditedObject->GetBoundaryPolyline();
135       if ( aPolylineObj.IsNull() )
136       {
137         aPanel->setBoundary( QString() );
138       }
139       else
140       {
141         aPolylineName = aPolylineObj->GetName();
142         aPanel->setBoundary( aPolylineName );
143       }
144
145       aSeq = myEditedObject->GetGeometryObjects();
146       getNamesAndEntries( aSeq, aList, anEntryList );
147       aPanel->includeGeomObjects( aList );
148
149       // set rules
150       HYDROData_ListOfRules aRules;
151       Handle(HYDROData_Object) anObject1, anObject2;
152       HYDROData_PriorityType aPriority;
153       HYDROData_Zone::MergeAltitudesType aMergeType;
154       for ( int anIndex = 0; ; anIndex++ )
155       {
156         if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType ) ) {
157           HYDROData_CustomRule aRule;
158           aRule.Object1 = anObject1;
159           aRule.Object2 = anObject2;
160           aRule.Priority = aPriority;
161           aRule.MergeType = aMergeType;
162
163           aRules << aRule;
164         }
165         else
166           break;
167       }
168       aPanel->setRules( aRules );
169     }
170   }
171   else
172   {
173     myEditedObject =
174       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
175     myEditedObject->SetName( anObjectName );
176     myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getMode() );
177   }
178
179   aPanel->setObjectName( anObjectName );
180   aPanel->setEditedObject( myEditedObject );
181
182   createPreview();
183 }
184
185 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
186                                                 QStringList& theNames, QStringList& theEntries ) const
187 {
188  
189   theNames.clear();
190   theEntries.clear();
191   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
192   for ( ; anIter.More(); anIter.Next() )
193   {
194     Handle(HYDROData_Entity) anEntity = anIter.Value();
195     //if ( !HYDROData_Tool::IsGeometryObject( anEntity ) )
196     //  continue;
197
198     theNames.append( anEntity->GetName() );
199     theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anEntity ) );
200   }
201 }
202
203 void HYDROGUI_CalculationOp::abortOperation()
204 {
205   closePreview();
206   // Abort transaction
207   abortDocOperation();
208   HYDROGUI_Operation::abortOperation();
209   module()->getApp()->updateObjectBrowser();
210 }
211
212 void HYDROGUI_CalculationOp::commitOperation()
213 {
214   closePreview();
215   // Commit transaction
216   commitDocOperation();
217   HYDROGUI_Operation::commitOperation();
218 }
219
220 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
221 {
222   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
223
224   // Connect signals and slots
225   connect( aPanel, SIGNAL( changeMode( int ) ), SLOT( onChangeMode( int ) ) );
226   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
227   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
228   connect( aPanel, SIGNAL( addGroups() ), SLOT( onAddGroups() ) );
229   connect( aPanel, SIGNAL( removeGroups() ), SLOT( onRemoveGroups() ) );
230   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
231   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onHideZones() ) );
232   //connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
233   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
234   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
235     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
236   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
237     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
238   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
239     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
240   connect( aPanel, SIGNAL( objectsSelected() ), 
241            SLOT( onObjectsSelected() ) );
242   connect( aPanel, SIGNAL( boundarySelected( const QString & ) ), 
243     SLOT( onBoundarySelected( const QString & ) ) );
244
245   return aPanel;
246 }
247
248 void HYDROGUI_CalculationOp::onBoundarySelected ( const QString & theObjName )
249 {
250   bool anIsToUpdateViewer = false;
251
252   // Remove the old boundary from the operation viewer
253   Handle(HYDROData_PolylineXY) aPrevPolyline = 
254     myEditedObject->GetBoundaryPolyline();
255   if ( !aPrevPolyline.IsNull() )
256   {
257     setObjectVisibility( aPrevPolyline, false );
258     anIsToUpdateViewer = true;
259   }
260
261   // Set the selected boundary polyline to the calculation case
262   Handle(HYDROData_PolylineXY) aNewPolyline = Handle(HYDROData_PolylineXY)::DownCast(
263     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_POLYLINEXY ) );
264   myEditedObject->SetBoundaryPolyline( aNewPolyline );
265
266   if ( myPreviewViewManager )
267   {
268     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
269     if ( aViewer )
270     {
271       if ( !aNewPolyline.IsNull() )
272       {
273         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
274         if ( !aCtx.IsNull() )
275         {
276           setObjectVisibility( aNewPolyline, true );
277           anIsToUpdateViewer = true;
278         }
279       }
280
281       if ( anIsToUpdateViewer )
282         module()->update( UF_OCCViewer );
283     }
284   }
285 }
286
287 void HYDROGUI_CalculationOp::onObjectsSelected()
288 {
289   HYDROGUI_CalculationDlg* aPanel = 
290     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
291
292   QStringList aSelectedObjs = aPanel->getSelectedGeomObjects();
293   QMap<QString, bool> aSelectedObjsMap;
294   foreach( QString aName, aSelectedObjs )
295     aSelectedObjsMap[aName] = true;
296
297
298   // Select the appropriate geometry object shape in the viewer
299   selectionMgr()->clearSelected();
300
301   // Unhighlight all objects except selected
302   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
303   Handle(HYDROData_Entity) anEntity;
304   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
305   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
306   bool isSelected;
307   QString aName;
308   for ( ; anIter.More(); anIter.Next() )
309   {
310     anEntity = anIter.Value();
311     if ( !anEntity.IsNull() )
312     {
313       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
314       if ( aShape )
315       {
316         aName = anEntity->GetName();
317         isSelected = aSelectedObjsMap.contains( aName );
318         aShape->highlight( isSelected, false );
319         aShape->update( false, false );
320         aLastShape = aShape;
321       }
322     }
323   }
324   if( aLastShape )
325     aLastShape->update( true, false );
326 }
327
328 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
329 {
330   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
331   HYDROGUI_Zone* aZoneItem;
332   selectionMgr()->clearSelected();
333   if ( aRegionItem )
334   {
335     // Select a region in preview
336     SUIT_DataOwnerPtrList aList( true );
337     DataObjectList aZones = aRegionItem->children();
338     for ( int i = 0; i < aZones.length(); i++ )
339     {
340       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
341       if ( aZoneItem )
342       {
343         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
344       }
345     }
346     selectionMgr()->setSelected( aList );
347   }
348   else
349   {
350     // select a single zone
351     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
352     if ( aZoneItem )
353     {
354       SUIT_DataOwnerPtrList aList( true );
355       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
356       selectionMgr()->setSelected( aList );
357     }
358   }
359 }
360
361 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
362 {
363   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
364   if ( aRegion )
365   {
366     QList<HYDROGUI_Zone*> aZonesList;
367     HYDROGUI_Zone* aZone;
368     // Get a list of dropped zones
369     for ( int i = 0; i < theZonesList.length(); i++ )
370     {
371       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
372       if ( aZone )
373       {
374         aZonesList.append( aZone );
375       }
376     }
377     if ( aZonesList.length() > 0 )
378     {
379       aRegion->addZones( aZonesList );
380       HYDROGUI_CalculationDlg* aPanel = 
381         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
382       if ( aPanel )
383       {
384         aPanel->refreshZonesBrowser();
385       }
386       createPreview();
387     }
388   }
389 }
390
391 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
392 {
393   QList<HYDROGUI_Zone*> aZonesList;
394   HYDROGUI_Zone* aZone;
395   // Get a list of dropped zones
396   for ( int i = 0; i < theZonesList.length(); i++ )
397   {
398     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
399     if ( aZone )
400     {
401       aZonesList.append( aZone );
402     }
403   }
404   if ( aZonesList.length() > 0 )
405   {
406     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
407     HYDROGUI_CalculationDlg* aPanel = 
408       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
409     if ( aPanel )
410     {
411       aPanel->refreshZonesBrowser();
412     }
413     createPreview();
414   }
415 }
416
417 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theAltitudeName )
418 {
419   HYDROGUI_CalculationDlg* aPanel = 
420     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
421   if ( aPanel )
422   {
423     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
424     if ( aZone )
425     {
426       aZone->setMergeType( theMergeType, theAltitudeName );
427       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
428       if ( aShape )
429       {
430         aShape->update( true, false );
431       }
432     }
433     aPanel->refreshZonesBrowser();
434   }
435 }
436
437 void HYDROGUI_CalculationOp::onAddObjects()
438 {
439   HYDROGUI_CalculationDlg* aPanel = 
440     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
441   if ( !aPanel )
442     return;
443
444   // Add geometry objects selected in the module browser to the calculation case
445   QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
446   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
447     return;
448
449   QStringList anAddedList;
450   for (int i = 0; i < aSelectedList.length(); i++)
451   {
452     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
453       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
454     if ( anObject.IsNull() )
455       continue;
456
457     if ( myEditedObject->AddGeometryObject( anObject ) )
458       anAddedList.append( anObject->GetName() );
459   }
460
461   if ( !anAddedList.isEmpty() )
462   {
463     aPanel->includeGeomObjects( anAddedList );
464     createPreview();
465   }
466 }
467
468 void HYDROGUI_CalculationOp::onRemoveObjects()
469 {
470   // Remove selected objects from the calculation case
471   HYDROGUI_CalculationDlg* aPanel = 
472     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
473   if ( !aPanel )
474     return;
475
476   QStringList aSelectedList = aPanel->getSelectedGeomObjects();
477   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
478     return;
479
480   for (int i = 0; i < aSelectedList.length(); i++)
481   {
482     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
483       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
484     if ( anObject.IsNull() )
485       continue;
486
487     setObjectVisibility( anObject, false );
488     myEditedObject->RemoveGeometryObject( anObject );
489   }
490
491   module()->update( UF_OCCViewer );
492   aPanel->excludeGeomObjects( aSelectedList );
493 }
494
495 bool HYDROGUI_CalculationOp::confirmRegionsChange() const
496 {
497   // Check if the case is already modified or not
498   bool isConfirmed = myEditedObject->IsMustBeUpdated();
499   if ( !isConfirmed )
500   {
501     // If not modified check if the case has already defined regions with zones
502     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
503     if ( aSeq.Length() > 0 )
504     {
505       // If there are already defined zones then ask a user to confirm zones recalculation
506       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
507                                tr( "REGIONS_CHANGED" ),
508                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_REGIONS" ),
509                                QMessageBox::Yes | QMessageBox::No,
510                                QMessageBox::No ) == QMessageBox::Yes );
511     }
512     else
513     {
514       isConfirmed = true; // No regions - no zones - nothing to recalculate
515     }
516   }
517   return isConfirmed;
518 }
519
520 bool HYDROGUI_CalculationOp::confirmModeChange() const
521 {
522   // Check if the case is already modified or not
523   bool isConfirmed = myEditedObject->IsMustBeUpdated();
524   if ( !isConfirmed )
525   {
526     // If not modified check if the case has already defined regions with zones
527     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
528     if ( aSeq.Length() > 0 )
529     {
530       // If there are already defined zones then ask a user to confirm zones recalculation
531       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
532                                tr( "MODE_CHANGED" ),
533                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_MODE" ),
534                                QMessageBox::Yes | QMessageBox::No,
535                                QMessageBox::No ) == QMessageBox::Yes );
536     }
537     else
538     {
539       isConfirmed = true; // No regions - no zones - nothing to recalculate
540     }
541   }
542   return isConfirmed;
543 }
544
545 bool HYDROGUI_CalculationOp::confirmContinueWithWarning( const HYDROData_Warning& theWarning ) const
546 {
547   HYDROData_WarningType aType = theWarning.Type;
548   if ( aType == WARN_OK ) {
549     return true;
550   }
551
552   QString aTitle;
553   QString aMsg;
554   switch ( aType )
555   {
556     case WARN_EMPTY_REGIONS:
557       aTitle = tr( "EMPTY_REGIONS" );
558       aMsg = tr( "CONFIRM_CONTINUE_WITH_OBJECTS_NOT_INCLUDED_TO_REGION" ).arg( theWarning.Data );
559       break;
560     default:
561       aTitle = tr( "WARNING" );
562       aMsg = theWarning.Data;
563   }
564
565
566   int anAnswer = SUIT_MessageBox::warning( module()->getApp()->desktop(),
567                                            aTitle, aMsg,
568                                            QMessageBox::Yes | QMessageBox::No,
569                                            QMessageBox::No );
570
571   return ( anAnswer == QMessageBox::Yes );
572 }
573
574 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
575                                            QString& theErrorMsg,
576                                            QStringList& theBrowseObjectsEntries )
577 {
578   HYDROGUI_CalculationDlg* aPanel = 
579     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
580   if ( !aPanel )
581     return false;
582
583   if( !myIsEdit )
584   {
585     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( myEditedObject );
586     theBrowseObjectsEntries.append( anEntry );
587   }
588
589   // For manual mode priority rules are redundant
590   if ( aPanel->getMode() == HYDROData_CalculationCase::MANUAL ) {
591     myEditedObject->ClearRules( false );
592   }
593  
594   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init;
595
596   return true;
597 }
598
599 void HYDROGUI_CalculationOp::onApply()
600 {
601   // Check warnings
602   HYDROData_Warning aWarning = myEditedObject->GetLastWarning();
603   if ( aWarning.Type != WARN_OK ) {
604     if ( !confirmContinueWithWarning( aWarning ) ) {
605       // Go back to the first page
606       HYDROGUI_CalculationDlg* aPanel = 
607         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
608       if ( aPanel ) {
609         aPanel->onFirstPage();
610       }
611       return;
612     }
613   }
614
615   QApplication::setOverrideCursor( Qt::WaitCursor );
616
617   int anUpdateFlags = 0;
618   QString anErrorMsg;
619   QStringList aBrowseObjectsEntries;
620
621   bool aResult = false;
622   
623   try
624   {
625     aResult = processApply( anUpdateFlags, anErrorMsg, aBrowseObjectsEntries );
626   }
627   catch ( Standard_Failure )
628   {
629     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
630     anErrorMsg = aFailure->GetMessageString();
631     aResult = false;
632   }
633   catch ( ... )
634   {
635     aResult = false;
636   }
637   
638   QApplication::restoreOverrideCursor();
639
640   if ( aResult )
641   {
642     module()->update( anUpdateFlags );
643     commit();
644     browseObjects( aBrowseObjectsEntries );
645   }
646   else
647   {
648     abort();
649     QString aMsg = tr( "INPUT_VALID_DATA" );
650     if( !anErrorMsg.isEmpty() )
651       aMsg.prepend( anErrorMsg + "\n" );
652     SUIT_MessageBox::critical( module()->getApp()->desktop(),
653                                tr( "INSUFFICIENT_INPUT_DATA" ),
654                                aMsg ); 
655   }
656 }
657
658 void HYDROGUI_CalculationOp::onNext( const int theIndex )
659 {
660   if( theIndex==1 )
661   {
662     setAvailableGroups();
663   }
664   else if( theIndex==2 )
665   {
666     HYDROGUI_CalculationDlg* aPanel = 
667       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
668     if ( !aPanel )
669       return;
670
671     QApplication::setOverrideCursor( Qt::WaitCursor );
672   
673     QString aNewCaseName = aPanel->getObjectName();
674     QString anOldCaseName = myEditedObject->GetName();
675     bool isNameChanged = anOldCaseName != aNewCaseName;
676   
677     bool anIsToUpdateOb = isNameChanged;
678
679     // At first we must to update the case name because of 
680     // automatic names generation for regions and zones
681     myEditedObject->SetName( aNewCaseName );
682     
683     // Set parameters for automatic mode
684     int aMode = aPanel->getMode();
685     if ( aMode == HYDROData_CalculationCase::AUTOMATIC ) {
686       // Set objects in the specified order
687       myEditedObject->RemoveGeometryObjects();
688       foreach ( const QString& aName, aPanel->getAllGeomObjects() ) {
689         Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
690           HYDROGUI_Tool::FindObjectByName( module(), aName ) );
691         if ( anObject.IsNull() ) {
692           continue;
693         }
694
695         myEditedObject->AddGeometryObject( anObject );
696       }
697
698       // Clear priority rules
699       //@ASL if ( myEditedObject->GetRulesCount() > 0 ) {
700         myEditedObject->ClearRules( true );
701       //@ASL }
702       // Set priority rules
703       foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) {
704         myEditedObject->AddRule( aRule.Object1, aRule.Priority,
705                                  aRule.Object2, aRule.MergeType );
706       }
707     }
708     aPanel->setEditZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
709          
710     if ( myEditedObject->IsMustBeUpdated() )
711     {
712       myShowZones = true;
713       myEditedObject->Update();
714       
715       //aPanel->setEditedObject( myEditedObject );
716       aPanel->refreshZonesBrowser();
717     
718       closePreview();
719       createPreview();
720
721       anIsToUpdateOb = true;
722     }
723     else
724     {
725       setZonesVisible( true );
726
727       if ( isNameChanged ) {
728         module()->getDataModel()->updateObjectTree( myEditedObject );
729       }
730     }
731
732     if ( anIsToUpdateOb ) {
733       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
734       if ( anObjBrowser ) {
735         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
736       }
737     }
738
739     QApplication::restoreOverrideCursor();
740   }
741 }
742
743 void HYDROGUI_CalculationOp::onHideZones()
744 {
745   setZonesVisible( false );
746 }
747
748 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible )
749 {
750   myShowZones = theIsVisible;
751   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
752   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
753   HYDROData_SequenceOfObjects aZones;
754   Handle(HYDROData_Region) aRegion;
755   if ( myPreviewViewManager ) 
756   {
757     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
758     {
759       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
760       if ( !aCtx.IsNull() )
761       {
762         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
763         {
764           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
765           if ( !aRegion.IsNull() )
766           {
767             aZones = aRegion->GetZones();
768             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
769             for ( ; aZonesIter.More(); aZonesIter.Next() )
770             {
771               setObjectVisibility( aZonesIter.Value(), theIsVisible );
772             }
773           }
774         }
775       }
776
777       module()->update( UF_OCCViewer );
778     }
779   }
780 }
781
782 void HYDROGUI_CalculationOp::createPreview()
783 {
784   LightApp_Application* anApp = module()->getApp();
785   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
786   Handle(HYDROData_Entity) anEntity;
787
788   if ( myShowZones )
789   {
790     // Gather zones for displaying
791     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
792     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
793     HYDROData_SequenceOfObjects aZones;
794     Handle(HYDROData_Region) aRegion;
795     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
796     {
797       anEntity = aRegionsIter.Value();
798       if ( !anEntity.IsNull() )
799       {
800         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
801         if ( !aRegion.IsNull() )
802         {
803           aZones = aRegion->GetZones();
804           aSeq.Append( aZones );
805         }
806       }
807     }
808   }
809
810   // Get a boundary polyline if any
811   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
812
813   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
814
815   if ( !myActiveViewManager )
816   {
817     if ( aSeq.IsEmpty() )
818       return;
819
820     myActiveViewManager = anApp->activeViewManager();
821   }
822
823   if ( !myPreviewViewManager )
824   {
825     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
826       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
827     if ( myPreviewViewManager )
828     {
829       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
830                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
831
832       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
833       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
834     }
835   }
836
837   if ( !myPreviewViewManager )
838     return;
839
840   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
841   {
842     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
843     if ( !aCtx.IsNull() )
844     {
845       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
846       for ( ; anIter.More(); anIter.Next() )
847       {
848         setObjectVisibility( anIter.Value(), true );
849       }
850
851       //Process the draw events for viewer
852       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
853       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
854         vw->onTopView();
855     }
856
857     module()->update( UF_OCCViewer | UF_FitAll );
858   }
859 }
860
861 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
862 {
863   if ( theEntity.IsNull() || !myPreviewViewManager ) {
864     return;
865   }
866
867   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
868   if ( aViewer ) {
869     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
870   }
871 }
872
873 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
874 {
875   closePreview();
876 }
877
878 void HYDROGUI_CalculationOp::closePreview()
879 {
880   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
881   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
882   QShortcut* aShortcut;
883   foreach( aShortcut, aShortcuts )
884   {
885     if ( aShortcut->key() == 
886       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
887       SUIT_DataBrowser::RenameShortcut ) ) )
888     {
889       aShortcut->setEnabled( true );
890     }
891   }
892
893
894   if( myPreviewViewManager )
895   {
896     // Hide all the displayed objects in the preview view
897     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
898     if ( aViewer ) {
899       size_t aViewId = (size_t)aViewer;
900       HYDROData_Iterator anIterator( doc() );
901       for( ; anIterator.More(); anIterator.Next() ) {
902         Handle(HYDROData_Entity) anObject = anIterator.Current();
903         if( !anObject.IsNull() ) {
904           module()->setObjectVisible( aViewId, anObject, false );
905         }
906       }
907     }
908
909     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
910                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
911
912     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
913     myPreviewViewManager = NULL;
914   }
915
916   if( myActiveViewManager )
917   {
918     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
919     myActiveViewManager = NULL;
920   }
921 }
922
923 void HYDROGUI_CalculationOp::setAvailableGroups()
924 {
925   HYDROGUI_CalculationDlg* aPanel = 
926       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
927
928   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
929   QStringList aList, anEntryList;
930   getNamesAndEntries( aSeq, aList, anEntryList );
931
932   QStringList aGroupsNames;
933
934   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
935   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
936   {
937     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
938     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
939     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
940     {
941       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
942       aGroupsNames.append( aGroup->GetName() );
943     }
944   }
945   if( myEditedObject->IsMustBeUpdated() ) {
946     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
947       Handle(HYDROData_ShapesGroup) aGeomGroup =
948         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
949       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
950         myEditedObject->RemoveGeometryGroup( aGeomGroup );
951       }
952     }
953   }
954
955   aPanel->setAvailableGroups( aGroupsNames );
956   aPanel->includeGroups( aList );
957
958   bool isUpdated = myEditedObject->IsMustBeUpdated();
959 }
960
961 void HYDROGUI_CalculationOp::onAddGroups()
962 {
963   HYDROGUI_CalculationDlg* aPanel = 
964     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
965   if ( !aPanel )
966     return;
967
968   // Add geometry objects selected in the module browser to the calculation case
969   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
970   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
971     return;
972
973   QStringList anAddedList;
974   for (int i = 0; i < aSelectedList.length(); i++)
975   {
976     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
977       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
978     if ( aGroup.IsNull() )
979       continue;
980
981     if ( myEditedObject->AddGeometryGroup( aGroup ) )
982       anAddedList.append( aGroup->GetName() );
983   }
984
985   if ( !anAddedList.isEmpty() )
986   {
987     aPanel->includeGroups( anAddedList );
988   }
989 }
990
991 void HYDROGUI_CalculationOp::onRemoveGroups()
992 {
993   // Remove selected objects from the calculation case
994   HYDROGUI_CalculationDlg* aPanel = 
995     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
996   if ( !aPanel )
997     return;
998
999   QStringList aSelectedList = aPanel->getSelectedGroups();
1000   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1001     return;
1002
1003   for (int i = 0; i < aSelectedList.length(); i++)
1004   {
1005     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1006       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1007     if ( aGroup.IsNull() )
1008       continue;
1009
1010     myEditedObject->RemoveGeometryGroup( aGroup );
1011   }
1012
1013   aPanel->excludeGroups( aSelectedList );
1014 }
1015
1016 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1017 {
1018   HYDROGUI_CalculationDlg* aPanel = 
1019     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1020   if ( !aPanel )
1021     return;
1022
1023   if ( !confirmModeChange() ) {
1024     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1025     return;
1026   }
1027
1028   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1029   aPanel->setMode( theMode );
1030 }