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