Salome HOME
bug #270: restore of included groups in calc.case
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_CalculationOp.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_CalculationOp.h"
24
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_CalculationDlg.h"
27 #include "HYDROGUI_Module.h"
28 #include "HYDROGUI_Tool.h"
29 #include "HYDROGUI_UpdateFlags.h"
30 #include "HYDROGUI_Zone.h"
31 #include "HYDROGUI_Region.h"
32
33 #include <HYDROData_PolylineXY.h>
34 #include <HYDROData_ShapesGroup.h>
35 #include <HYDROData_Iterator.h>
36 #include <HYDROData_Object.h>
37 #include <HYDROData_Tool.h>
38
39 #include <OCCViewer_ViewManager.h>
40 #include <OCCViewer_ViewModel.h>
41 #include <OCCViewer_ViewWindow.h>
42
43 #include <LightApp_Application.h>
44 #include <LightApp_UpdateFlags.h>
45 #include <LightApp_SelectionMgr.h>
46 #include <LightApp_DataOwner.h>
47
48 #include <SUIT_MessageBox.h>
49 #include <SUIT_Desktop.h>
50 #include <SUIT_DataBrowser.h>
51
52 #include <QApplication>
53 #include <QKeySequence>
54 #include <QShortcut>
55
56 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
57 : HYDROGUI_Operation( theModule ),
58   myIsEdit( theIsEdit ),
59   myActiveViewManager( NULL ),
60   myPreviewViewManager( NULL )
61 {
62   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
63 }
64
65 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
66 {
67   closePreview();
68 }
69
70 void HYDROGUI_CalculationOp::startOperation()
71 {
72   HYDROGUI_Operation::startOperation();
73   
74   // Begin transaction
75   startDocOperation();
76
77   HYDROGUI_CalculationDlg* aPanel = 
78     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
79   if ( !aPanel )
80     return;
81
82   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
83   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
84   QShortcut* aShortcut;
85   foreach( aShortcut, aShortcuts )
86   {
87     if ( aShortcut->key() == 
88       QKeySequence(((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
89       SUIT_DataBrowser::RenameShortcut ) ) )
90     {
91       aShortcut->setEnabled( false );
92     }
93   }
94
95
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       anObjectName = myEditedObject->GetName();
138       aPolylineObj = myEditedObject->GetBoundaryPolyline();
139       if ( aPolylineObj.IsNull() )
140       {
141         aPanel->setBoundary( QString() );
142       }
143       else
144       {
145         aPolylineName = aPolylineObj->GetName();
146         aPanel->setBoundary( aPolylineName );
147       }
148
149       aSeq = myEditedObject->GetGeometryObjects();
150       getNamesAndEntries( aSeq, aList, anEntryList );
151       aPanel->includeGeomObjects( aList );
152     }
153   }
154   else
155   {
156     myEditedObject =
157       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
158     myEditedObject->SetName(anObjectName);
159   }
160
161   aPanel->setObjectName( anObjectName );
162   aPanel->setEditedObject( myEditedObject );
163
164   createPreview();
165 }
166
167 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
168                                                 QStringList& theNames, QStringList& theEntries ) const
169 {
170  
171   theNames.clear();
172   theEntries.clear();
173   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
174   for ( ; anIter.More(); anIter.Next() )
175   {
176     Handle(HYDROData_Entity) anEntity = anIter.Value();
177     //if ( !HYDROData_Tool::IsGeometryObject( anEntity ) )
178     //  continue;
179
180     theNames.append( anEntity->GetName() );
181     theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anEntity ) );
182   }
183 }
184
185 void HYDROGUI_CalculationOp::abortOperation()
186 {
187   closePreview();
188   // Abort transaction
189   abortDocOperation();
190   HYDROGUI_Operation::abortOperation();
191   module()->getApp()->updateObjectBrowser();
192 }
193
194 void HYDROGUI_CalculationOp::commitOperation()
195 {
196   closePreview();
197   // Commit transaction
198   commitDocOperation();
199   HYDROGUI_Operation::commitOperation();
200 }
201
202 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
203 {
204   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
205
206   // Connect signals and slots
207   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
208   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
209   connect( aPanel, SIGNAL( addGroups() ), SLOT( onAddGroups() ) );
210   connect( aPanel, SIGNAL( removeGroups() ), SLOT( onRemoveGroups() ) );
211   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
212   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onHideZones() ) );
213   //connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
214   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
215   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
216     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
217   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
218     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
219   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
220     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
221   connect( aPanel, SIGNAL( objectsSelected() ), 
222            SLOT( onObjectsSelected() ) );
223   connect( aPanel, SIGNAL( boundarySelected( const QString & ) ), 
224     SLOT( onBoundarySelected( const QString & ) ) );
225
226   return aPanel;
227 }
228
229 void HYDROGUI_CalculationOp::onBoundarySelected ( const QString & theObjName )
230 {
231   bool anIsToUpdateViewer = false;
232
233   // Remove the old boundary from the operation viewer
234   Handle(HYDROData_PolylineXY) aPrevPolyline = 
235     myEditedObject->GetBoundaryPolyline();
236   if ( !aPrevPolyline.IsNull() )
237   {
238     module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aPrevPolyline );
239     anIsToUpdateViewer = true;
240   }
241
242   // Set the selected boundary polyline to the calculation case
243   Handle(HYDROData_PolylineXY) aNewPolyline = Handle(HYDROData_PolylineXY)::DownCast(
244     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_POLYLINEXY ) );
245   myEditedObject->SetBoundaryPolyline( aNewPolyline );
246
247   if ( myPreviewViewManager )
248   {
249     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
250     if ( aViewer )
251     {
252       if ( !aNewPolyline.IsNull() )
253       {
254         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
255         if ( !aCtx.IsNull() )
256         {
257           showObject( aNewPolyline, aCtx );
258           anIsToUpdateViewer = true;
259         }
260       }
261
262       if ( anIsToUpdateViewer )
263         aViewer->update();
264     }
265   }
266 }
267
268 void HYDROGUI_CalculationOp::onObjectsSelected()
269 {
270   HYDROGUI_CalculationDlg* aPanel = 
271     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
272
273   QStringList aSelectedObjs = aPanel->getSelectedGeomObjects();
274   QMap<QString, bool> aSelectedObjsMap;
275   foreach( QString aName, aSelectedObjs )
276     aSelectedObjsMap[aName] = true;
277
278
279   // Select the appropriate geometry object shape in the viewer
280   selectionMgr()->clearSelected();
281
282   // Unhighlight all objects except selected
283   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
284   Handle(HYDROData_Entity) anEntity;
285   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
286   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
287   bool isSelected;
288   QString aName;
289   for ( ; anIter.More(); anIter.Next() )
290   {
291     anEntity = anIter.Value();
292     if ( !anEntity.IsNull() )
293     {
294       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
295       if ( aShape )
296       {
297         aName = anEntity->GetName();
298         isSelected = aSelectedObjsMap.contains( aName );
299         aShape->highlight( isSelected, false );
300         aShape->update( false );
301         aLastShape = aShape;
302       }
303     }
304   }
305   if( aLastShape )
306     aLastShape->update( true );
307 }
308
309 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
310 {
311   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
312   HYDROGUI_Zone* aZoneItem;
313   selectionMgr()->clearSelected();
314   if ( aRegionItem )
315   {
316     // Select a region in preview
317     SUIT_DataOwnerPtrList aList( true );
318     DataObjectList aZones = aRegionItem->children();
319     for ( int i = 0; i < aZones.length(); i++ )
320     {
321       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
322       if ( aZoneItem )
323       {
324         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
325       }
326     }
327     selectionMgr()->setSelected( aList );
328   }
329   else
330   {
331     // select a single zone
332     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
333     if ( aZoneItem )
334     {
335       SUIT_DataOwnerPtrList aList( true );
336       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
337       selectionMgr()->setSelected( aList );
338     }
339   }
340 }
341
342 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
343 {
344   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
345   if ( aRegion )
346   {
347     QList<HYDROGUI_Zone*> aZonesList;
348     HYDROGUI_Zone* aZone;
349     // Get a list of dropped zones
350     for ( int i = 0; i < theZonesList.length(); i++ )
351     {
352       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
353       if ( aZone )
354       {
355         aZonesList.append( aZone );
356       }
357     }
358     if ( aZonesList.length() > 0 )
359     {
360       aRegion->addZones( aZonesList );
361       HYDROGUI_CalculationDlg* aPanel = 
362         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
363       if ( aPanel )
364       {
365         aPanel->refreshZonesBrowser();
366       }
367       createPreview();
368     }
369   }
370 }
371
372 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
373 {
374   QList<HYDROGUI_Zone*> aZonesList;
375   HYDROGUI_Zone* aZone;
376   // Get a list of dropped zones
377   for ( int i = 0; i < theZonesList.length(); i++ )
378   {
379     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
380     if ( aZone )
381     {
382       aZonesList.append( aZone );
383     }
384   }
385   if ( aZonesList.length() > 0 )
386   {
387     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
388     HYDROGUI_CalculationDlg* aPanel = 
389       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
390     if ( aPanel )
391     {
392       aPanel->refreshZonesBrowser();
393     }
394     createPreview();
395   }
396 }
397
398 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theAltitudeName )
399 {
400   HYDROGUI_CalculationDlg* aPanel = 
401     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
402   if ( aPanel )
403   {
404     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
405     if ( aZone )
406     {
407       aZone->setMergeType( theMergeType, theAltitudeName );
408       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
409       if ( aShape )
410       {
411         aShape->update();
412       }
413     }
414     aPanel->refreshZonesBrowser();
415   }
416 }
417
418 void HYDROGUI_CalculationOp::onAddObjects()
419 {
420   HYDROGUI_CalculationDlg* aPanel = 
421     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
422   if ( !aPanel )
423     return;
424
425   // Add geometry objects selected in the module browser to the calculation case
426   QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
427   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
428     return;
429
430   QStringList anAddedList;
431   for (int i = 0; i < aSelectedList.length(); i++)
432   {
433     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
434       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
435     if ( anObject.IsNull() )
436       continue;
437
438     if ( myEditedObject->AddGeometryObject( anObject ) )
439       anAddedList.append( anObject->GetName() );
440   }
441
442   if ( !anAddedList.isEmpty() )
443   {
444     aPanel->includeGeomObjects( anAddedList );
445     createPreview();
446   }
447 }
448
449 void HYDROGUI_CalculationOp::onRemoveObjects()
450 {
451   // Remove selected objects from the calculation case
452   HYDROGUI_CalculationDlg* aPanel = 
453     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
454   if ( !aPanel )
455     return;
456
457   QStringList aSelectedList = aPanel->getSelectedGeomObjects();
458   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
459     return;
460
461   for (int i = 0; i < aSelectedList.length(); i++)
462   {
463     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
464       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
465     if ( anObject.IsNull() )
466       continue;
467
468     module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject );
469     myEditedObject->RemoveGeometryObject( anObject );
470   }
471
472   aPanel->excludeGeomObjects( aSelectedList );
473 }
474
475 bool HYDROGUI_CalculationOp::confirmRegionsChange() const
476 {
477   // Check if the case is already modified or not
478   bool isConfirmed = myEditedObject->IsMustBeUpdated();
479   if ( !isConfirmed )
480   {
481     // If not modified check if the case has already defined regions with zones
482     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
483     if ( aSeq.Length() > 0 )
484     {
485       // If there are already defined zones then ask a user to confirm zones recalculation
486       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
487                                tr( "REGIONS_CHANGED" ),
488                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION" ),
489                                QMessageBox::Yes | QMessageBox::No,
490                                QMessageBox::No ) == QMessageBox::Yes );
491     }
492     else
493     {
494       isConfirmed = true; // No regions - no zones - nothing to recalculate
495     }
496   }
497   return isConfirmed;
498 }
499
500 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
501                                            QString& theErrorMsg )
502 {
503   HYDROGUI_CalculationDlg* aPanel = 
504     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
505   if ( !aPanel )
506     return false;
507
508   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced;
509
510   return true;
511 }
512
513 void HYDROGUI_CalculationOp::onApply()
514 {
515   QApplication::setOverrideCursor( Qt::WaitCursor );
516
517   int anUpdateFlags = 0;
518   QString anErrorMsg;
519
520   bool aResult = false;
521   
522   try
523   {
524     aResult = processApply( anUpdateFlags, anErrorMsg );
525   }
526   catch ( Standard_Failure )
527   {
528     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
529     anErrorMsg = aFailure->GetMessageString();
530     aResult = false;
531   }
532   catch ( ... )
533   {
534     aResult = false;
535   }
536   
537   QApplication::restoreOverrideCursor();
538
539   if ( aResult )
540   {
541     module()->update( anUpdateFlags );
542     commit();
543   }
544   else
545   {
546     abort();
547     QString aMsg = tr( "INPUT_VALID_DATA" );
548     if( !anErrorMsg.isEmpty() )
549       aMsg.prepend( anErrorMsg + "\n" );
550     SUIT_MessageBox::critical( module()->getApp()->desktop(),
551                                tr( "INSUFFICIENT_INPUT_DATA" ),
552                                aMsg ); 
553   }
554 }
555
556 void HYDROGUI_CalculationOp::onNext( const int theIndex )
557 {
558   if( theIndex==1 )
559   {
560     setAvailableGroups();
561   }
562   else if( theIndex==2 )
563   {
564     HYDROGUI_CalculationDlg* aPanel = 
565       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
566     if ( !aPanel )
567       return;
568
569     QApplication::setOverrideCursor( Qt::WaitCursor );
570   
571     QString aNewCaseName = aPanel->getObjectName();
572     QString anOldCaseName = myEditedObject->GetName();
573   
574     bool anIsToUpdateOb = myIsEdit && anOldCaseName != aNewCaseName;
575   
576     // At first we must to update the case name because of 
577     // automatic names generation for regions and zones
578     myEditedObject->SetName( aNewCaseName );
579   
580     if ( myEditedObject->IsMustBeUpdated() )
581     {
582       myShowZones = true;
583       myEditedObject->Update();
584
585       //aPanel->setEditedObject( myEditedObject );
586       aPanel->refreshZonesBrowser();
587
588       createPreview();
589     }
590     else
591     {
592       setZonesVisible( true );
593     }
594
595     if ( anIsToUpdateOb )
596       module()->getApp()->updateObjectBrowser( false );
597
598     QApplication::restoreOverrideCursor();
599   }
600 }
601
602 void HYDROGUI_CalculationOp::onHideZones()
603 {
604   setZonesVisible( false );
605 }
606
607 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible )
608 {
609   myShowZones = theIsVisible;
610   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
611   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
612   HYDROData_SequenceOfObjects aZones;
613   Handle(HYDROData_Region) aRegion;
614   if ( myPreviewViewManager ) 
615   {
616     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
617     {
618       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
619       if ( !aCtx.IsNull() )
620       {
621         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
622         {
623           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
624           if ( !aRegion.IsNull() )
625           {
626             aZones = aRegion->GetZones();
627             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
628             for ( ; aZonesIter.More(); aZonesIter.Next() )
629             {
630               if ( theIsVisible )
631               {
632                 showObject( aZonesIter.Value(), aCtx );
633               }
634               else
635               {
636                 module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZonesIter.Value() );
637               }
638             }
639           }
640         }
641       }
642
643       aViewer->update();
644     }
645   }
646 }
647
648 void HYDROGUI_CalculationOp::createPreview()
649 {
650   LightApp_Application* anApp = module()->getApp();
651   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
652   Handle(HYDROData_Entity) anEntity;
653
654   if ( myShowZones )
655   {
656     // Gather zones for displaying
657     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
658     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
659     HYDROData_SequenceOfObjects aZones;
660     Handle(HYDROData_Region) aRegion;
661     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
662     {
663       anEntity = aRegionsIter.Value();
664       if ( !anEntity.IsNull() )
665       {
666         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
667         if ( !aRegion.IsNull() )
668         {
669           aZones = aRegion->GetZones();
670           aSeq.Append( aZones );
671         }
672       }
673     }
674   }
675
676   // Get a boundary polyline if any
677   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
678
679   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
680
681   if ( !myActiveViewManager )
682   {
683     if ( aSeq.IsEmpty() )
684       return;
685
686     myActiveViewManager = anApp->activeViewManager();
687   }
688
689   if ( !myPreviewViewManager )
690   {
691     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
692       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
693     if ( myPreviewViewManager )
694     {
695       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
696                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
697
698       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
699       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
700     }
701   }
702
703   if ( !myPreviewViewManager )
704     return;
705
706   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
707   {
708     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
709     if ( !aCtx.IsNull() )
710     {
711       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
712       for ( ; anIter.More(); anIter.Next() )
713       {
714         showObject( anIter.Value(), aCtx );
715       }
716
717       //Process the draw events for viewer
718       QApplication::processEvents();
719       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
720         vw->onTopView();
721     }
722
723     aViewer->update();
724   }
725 }
726
727 void HYDROGUI_CalculationOp::showObject( Handle(HYDROData_Entity) theEntity, Handle(AIS_InteractiveContext) theCtx )
728 {
729   if ( !theEntity.IsNull() )
730   {
731     HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, theEntity );
732     if ( !aShape )
733     {
734       aShape = new HYDROGUI_Shape( theCtx, theEntity );
735       module()->setObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, theEntity, aShape );
736     }
737     aShape->update( false );
738   }
739 }
740
741 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
742 {
743   closePreview();
744 }
745
746 void HYDROGUI_CalculationOp::closePreview()
747 {
748   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
749   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
750   QShortcut* aShortcut;
751   foreach( aShortcut, aShortcuts )
752   {
753     if ( aShortcut->key() == 
754       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
755       SUIT_DataBrowser::RenameShortcut ) ) )
756     {
757       aShortcut->setEnabled( true );
758     }
759   }
760
761
762   if( myPreviewViewManager )
763   {
764     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
765                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
766
767     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
768     myPreviewViewManager = NULL;
769   }
770
771   if( myActiveViewManager )
772   {
773     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
774     myActiveViewManager = NULL;
775   }
776 }
777
778 void HYDROGUI_CalculationOp::setAvailableGroups()
779 {
780   HYDROGUI_CalculationDlg* aPanel = 
781       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
782
783   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
784   QStringList aList, anEntryList;
785   getNamesAndEntries( aSeq, aList, anEntryList );
786
787   QStringList aGroupsNames;
788
789   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
790   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
791   {
792     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
793     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
794     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
795     {
796       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
797       aGroupsNames.append( aGroup->GetName() );
798     }
799   }
800   if( myEditedObject->IsMustBeUpdated() )
801     myEditedObject->RemoveGeometryGroups();
802
803   aPanel->setAvailableGroups( aGroupsNames );
804   aPanel->includeGroups( aList );
805
806   bool isUpdated = myEditedObject->IsMustBeUpdated();
807 }
808
809 void HYDROGUI_CalculationOp::onAddGroups()
810 {
811   HYDROGUI_CalculationDlg* aPanel = 
812     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
813   if ( !aPanel )
814     return;
815
816   // Add geometry objects selected in the module browser to the calculation case
817   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
818   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
819     return;
820
821   QStringList anAddedList;
822   for (int i = 0; i < aSelectedList.length(); i++)
823   {
824     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
825       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
826     if ( aGroup.IsNull() )
827       continue;
828
829     if ( myEditedObject->AddGeometryGroup( aGroup ) )
830       anAddedList.append( aGroup->GetName() );
831   }
832
833   if ( !anAddedList.isEmpty() )
834   {
835     aPanel->includeGroups( anAddedList );
836   }
837 }
838
839 void HYDROGUI_CalculationOp::onRemoveGroups()
840 {
841   // Remove selected objects from the calculation case
842   HYDROGUI_CalculationDlg* aPanel = 
843     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
844   if ( !aPanel )
845     return;
846
847   QStringList aSelectedList = aPanel->getSelectedGroups();
848   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
849     return;
850
851   for (int i = 0; i < aSelectedList.length(); i++)
852   {
853     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
854       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
855     if ( aGroup.IsNull() )
856       continue;
857
858     myEditedObject->RemoveGeometryGroup( aGroup );
859   }
860
861   aPanel->excludeGroups( aSelectedList );
862 }