Salome HOME
Fix for the #trefs 121: undo leads error
[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_Polyline.h>
34 #include <HYDROData_Iterator.h>
35 #include <HYDROData_ImmersibleZone.h>
36 #include <HYDROData_Object.h>
37
38 #include <OCCViewer_ViewManager.h>
39 #include <OCCViewer_ViewModel.h>
40 #include <OCCViewer_ViewWindow.h>
41
42 #include <LightApp_Application.h>
43 #include <LightApp_UpdateFlags.h>
44 #include <LightApp_SelectionMgr.h>
45 #include <LightApp_DataOwner.h>
46
47 #include <SUIT_MessageBox.h>
48 #include <SUIT_Desktop.h>
49
50 #include <QApplication>
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   aPanel->reset();
79   QStringList aList;
80   QStringList anEntryList;
81   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetGeometryObjects( module() );
82   getNamesAndEntries( aSeq, aList, anEntryList );
83   aPanel->setAllGeomObjects( aList, anEntryList );
84
85   // Get all polylines
86   aList.clear();
87   anEntryList.clear();
88   HYDROData_Iterator anIter( doc(), KIND_POLYLINE );
89   Handle(HYDROData_Polyline) aPolylineObj;
90   QString aPolylineName;
91   for ( ; anIter.More(); anIter.Next() )
92   {
93     aPolylineObj = Handle(HYDROData_Polyline)::DownCast( anIter.Current() );
94
95     if ( !aPolylineObj.IsNull() && aPolylineObj->IsClosed() )
96     {
97       aPolylineName = aPolylineObj->GetName();
98       if ( !aPolylineName.isEmpty() )
99       {
100         aList.append( aPolylineName );
101         anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aPolylineObj ) );
102       }
103     }
104   }
105   aPanel->setPolylineNames( aList, anEntryList );
106
107   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_CALCULATION_CASE_NAME" ) );
108
109   myEditedObject.Nullify();
110   if ( myIsEdit )
111   {
112     myEditedObject = Handle(HYDROData_CalculationCase)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
113     if ( !myEditedObject.IsNull() )
114     {
115       anObjectName = myEditedObject->GetName();
116       aPolylineObj = myEditedObject->GetBoundaryPolyline();
117       if ( aPolylineObj.IsNull() )
118       {
119         aPanel->setBoundary( QString() );
120       }
121       else
122       {
123         aPolylineName = aPolylineObj->GetName();
124         aPanel->setBoundary( aPolylineName );
125       }
126       aSeq = myEditedObject->GetGeometryObjects();
127       getNamesAndEntries( aSeq, aList, anEntryList );
128       aPanel->includeGeomObjects( aList );
129     }
130   }
131   else
132   {
133     myEditedObject =
134       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
135     myEditedObject->SetName(anObjectName);
136   }
137
138   aPanel->setObjectName( anObjectName );
139   aPanel->setEditedObject( myEditedObject );
140
141   createPreview();
142 }
143
144 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
145                                                 QStringList& theNames, QStringList& theEntries ) const
146 {
147   Handle(HYDROData_Object) anObject;
148   Handle(HYDROData_Entity) anEntity;
149   theNames.clear();
150   theEntries.clear();
151   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
152   for ( ; anIter.More(); anIter.Next() )
153   {
154     anEntity = anIter.Value();
155     if ( !anEntity.IsNull() )
156     {
157       // Temporary solution will be revised later
158       //anObject = Handle(HYDROData_Object)::DownCast( anEntity );
159       anObject = Handle(HYDROData_ImmersibleZone)::DownCast( anEntity );
160       if ( !anObject.IsNull() )
161       {
162         theNames.append( anObject->GetName() );
163         theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anObject ) );
164       }
165     }
166   }
167 }
168
169 void HYDROGUI_CalculationOp::abortOperation()
170 {
171   closePreview();
172   // Abort transaction
173   abortDocOperation();
174   HYDROGUI_Operation::abortOperation();
175 }
176
177 void HYDROGUI_CalculationOp::commitOperation()
178 {
179   closePreview();
180   // Commit transaction
181   commitDocOperation();
182   HYDROGUI_Operation::commitOperation();
183 }
184
185 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
186 {
187   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
188
189   // Connect signals and slots
190   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
191   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
192   connect( aPanel, SIGNAL( splitZones() ), SLOT( onSplitZones() ) );
193   connect( aPanel, SIGNAL( hideZones() ), SLOT( onHideZones() ) );
194   connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
195   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
196   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
197     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
198   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
199     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
200   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
201     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
202   connect( aPanel, SIGNAL( objectSelected( const QString & ) ), 
203     SLOT( onObjectSelected( const QString & ) ) );
204   connect( aPanel, SIGNAL( boundarySelected( const QString & ) ), 
205     SLOT( onBoundarySelected( const QString & ) ) );
206
207   return aPanel;
208 }
209
210 void HYDROGUI_CalculationOp::onBoundarySelected ( const QString & theObjName )
211 {
212   // Set the selected boundary polyline to the calculation case
213   Handle(HYDROData_Polyline) anObject;
214   Handle(AIS_InteractiveContext) aCtx;
215   if ( myPreviewViewManager ) 
216   {
217     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
218     {
219       aCtx = aViewer->getAISContext();
220     }
221   }
222   // Remove the old boundary from the operation viewer
223   anObject = myEditedObject->GetBoundaryPolyline();
224   if ( !anObject.IsNull() )
225   {
226     module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject );
227   }
228
229   if ( theObjName.trimmed().isEmpty() )
230   {
231     // No polyline is selected
232     myEditedObject->RemoveBoundaryPolyline();
233   }
234   else
235   {
236     Handle(HYDROData_Entity) anEntity = 
237       HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_POLYLINE );
238     if ( !anEntity.IsNull() )
239     {
240       anObject = Handle(HYDROData_Polyline)::DownCast( anEntity );
241       if ( !anObject.IsNull() )
242       {
243         myEditedObject->SetBoundaryPolyline( anObject );
244         if ( !aCtx.IsNull() )
245         {
246           showObject( anEntity, aCtx );
247         }
248       }
249     }
250   }
251 }
252
253 void HYDROGUI_CalculationOp::onObjectSelected ( const QString & theObjName )
254 {
255   // Select the appropriate geometry object shape in the viewer
256   selectionMgr()->clearSelected();
257
258   // Unhighlight all objects except selected
259   HYDROGUI_Shape* aShape;
260   HYDROGUI_Shape* aSelectedShape = 0;
261   Handle(HYDROData_Entity) anEntity;
262   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
263   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
264   bool isSelected;
265   QString aName;
266   for ( ; anIter.More(); anIter.Next() )
267   {
268     anEntity = anIter.Value();
269     if ( !anEntity.IsNull() )
270     {
271       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
272       if ( aShape )
273       {
274         aName = anEntity->GetName();
275         isSelected = ( aName == theObjName );
276         if ( isSelected )
277         {
278           aSelectedShape = aShape;
279         }
280         if ( aShape->isHighlighted() != isSelected )
281         {
282           if ( !isSelected )
283           {
284             aShape->highlight( isSelected );
285             aShape->update();
286           }
287         }
288       }
289     }
290   }
291   if ( aSelectedShape )
292   {
293     aSelectedShape->highlight( true );
294     aSelectedShape->update();
295   }
296 }
297
298 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
299 {
300   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
301   HYDROGUI_Zone* aZoneItem;
302   selectionMgr()->clearSelected();
303   if ( aRegionItem )
304   {
305     // Select a region in preview
306     SUIT_DataOwnerPtrList aList( true );
307     DataObjectList aZones = aRegionItem->children();
308     for ( int i = 0; i < aZones.length(); i++ )
309     {
310       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
311       if ( aZoneItem )
312       {
313         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
314       }
315     }
316     selectionMgr()->setSelected( aList );
317   }
318   else
319   {
320     // select a single zone
321     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
322     if ( aZoneItem )
323     {
324       SUIT_DataOwnerPtrList aList( true );
325       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
326       selectionMgr()->setSelected( aList );
327     }
328   }
329 }
330
331 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
332 {
333   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
334   if ( aRegion )
335   {
336     QList<HYDROGUI_Zone*> aZonesList;
337     HYDROGUI_Zone* aZone;
338     // Get a list of dropped zones
339     for ( int i = 0; i < theZonesList.length(); i++ )
340     {
341       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
342       if ( aZone )
343       {
344         aZonesList.append( aZone );
345       }
346     }
347     if ( aZonesList.length() > 0 )
348     {
349       aRegion->addZones( aZonesList );
350       HYDROGUI_CalculationDlg* aPanel = 
351         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
352       if ( aPanel )
353       {
354         aPanel->setEditedObject(myEditedObject);
355       }
356       createPreview();
357     }
358   }
359 }
360
361 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
362 {
363   QList<HYDROGUI_Zone*> aZonesList;
364   HYDROGUI_Zone* aZone;
365   // Get a list of dropped zones
366   for ( int i = 0; i < theZonesList.length(); i++ )
367   {
368     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
369     if ( aZone )
370     {
371       aZonesList.append( aZone );
372     }
373   }
374   if ( aZonesList.length() > 0 )
375   {
376     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
377     HYDROGUI_CalculationDlg* aPanel = 
378       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
379     if ( aPanel )
380     {
381       aPanel->setEditedObject(myEditedObject);
382     }
383     createPreview();
384   }
385 }
386
387 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theBathymetryName )
388 {
389   HYDROGUI_CalculationDlg* aPanel = 
390     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
391   if ( aPanel )
392   {
393     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
394     if ( aZone )
395     {
396       aZone->setMergeType( theMergeType, theBathymetryName );
397       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
398       if ( aShape )
399       {
400         aShape->update();
401       }
402     }
403     aPanel->refreshZonesBrowser();
404   }
405 }
406
407 void HYDROGUI_CalculationOp::onAddObjects()
408 {
409   HYDROGUI_CalculationDlg* aPanel = 
410     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
411   if ( aPanel )
412   {
413     // Add geometry objects selected in the module browser to the calculation case
414     QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
415     if ( ( !aSelectedList.isEmpty() ) && ( confirmRegionsChange() ) )
416     {
417       Handle(HYDROData_Object) anObject;
418       Handle(HYDROData_Entity) anEntity;
419       QStringList aList;
420       for (int i = 0; i < aSelectedList.length(); i++)
421       {
422         anEntity = HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) );
423         if ( !anEntity.IsNull() )
424         {
425           anObject = Handle(HYDROData_Object)::DownCast( anEntity );
426           if ( !anObject.IsNull() )
427           {
428             if (myEditedObject->AddGeometryObject( anObject ))
429             {
430               aList.append( anObject->GetName() );
431             }
432           }
433         }
434       }
435       if ( !aList.isEmpty() )
436       {
437         aPanel->includeGeomObjects( aList );
438         createPreview();
439       }
440     }
441   }
442 }
443
444 void HYDROGUI_CalculationOp::onRemoveObjects()
445 {
446   // Remove selected objects from the calculation case
447   HYDROGUI_CalculationDlg* aPanel = 
448     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
449   if ( aPanel )
450   {
451     QStringList aList = aPanel->getSelectedGeomObjects();
452     if ( ( !aList.isEmpty() ) && ( confirmRegionsChange() ) )
453     {
454       Handle(HYDROData_Object) anObject;
455       Handle(HYDROData_Entity) anEntity;
456       for (int i = 0; i < aList.length(); i++)
457       {
458         anEntity = HYDROGUI_Tool::FindObjectByName( module(), aList.at(i) );
459         if ( !anEntity.IsNull() )
460         {
461           anObject = Handle(HYDROData_Object)::DownCast( anEntity );
462           if ( !anObject.IsNull() )
463           {
464             module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject );
465             myEditedObject->RemoveGeometryObject( anObject );
466           }
467         }
468       }
469       if ( !aList.isEmpty() )
470       {
471         aPanel->excludeGeomObjects( aList );
472       }
473     }
474   }
475 }
476
477 bool HYDROGUI_CalculationOp::confirmRegionsChange() const
478 {
479   // Check if the case is already modified or not
480   bool isConfirmed = myEditedObject->IsMustBeUpdated();
481   if ( !isConfirmed )
482   {
483     // If not modified check if the case has already defined regions with zones
484     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
485     if ( aSeq.Length() > 0 )
486     {
487       // If there are already defined zones then ask a user to confirm zones recalculation
488       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
489                                tr( "REGIONS_CHANGED" ),
490                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION" ),
491                                QMessageBox::Yes | QMessageBox::No,
492                                QMessageBox::No ) == QMessageBox::Yes );
493     }
494     else
495     {
496       isConfirmed = true; // No regions - no zones - nothing to recalculate
497     }
498   }
499   return isConfirmed;
500 }
501
502 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
503                                            QString& theErrorMsg )
504 {
505   HYDROGUI_CalculationDlg* aPanel = 
506     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
507   if ( !aPanel )
508     return false;
509
510   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced;
511
512   return true;
513 }
514
515 void HYDROGUI_CalculationOp::onApply()
516 {
517   QApplication::setOverrideCursor( Qt::WaitCursor );
518
519   int anUpdateFlags = 0;
520   QString anErrorMsg;
521
522   bool aResult = false;
523   
524   try
525   {
526     aResult = processApply( anUpdateFlags, anErrorMsg );
527   }
528   catch ( Standard_Failure )
529   {
530     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
531     anErrorMsg = aFailure->GetMessageString();
532     aResult = false;
533   }
534   catch ( ... )
535   {
536     aResult = false;
537   }
538   
539   QApplication::restoreOverrideCursor();
540
541   if ( aResult )
542   {
543     module()->update( anUpdateFlags );
544     commit();
545   }
546   else
547   {
548     abort();
549     QString aMsg = tr( "INPUT_VALID_DATA" );
550     if( !anErrorMsg.isEmpty() )
551       aMsg.prepend( anErrorMsg + "\n" );
552     SUIT_MessageBox::critical( module()->getApp()->desktop(),
553                                tr( "INSUFFICIENT_INPUT_DATA" ),
554                                aMsg ); 
555   }
556 }
557
558 void HYDROGUI_CalculationOp::onSplitZones()
559 {
560   HYDROGUI_CalculationDlg* aPanel = 
561     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
562   if ( !aPanel )
563     return;
564
565   QApplication::setOverrideCursor( Qt::WaitCursor );
566
567   QString aNewCaseName = aPanel->getObjectName();
568   QString anOldCaseName = myEditedObject->GetName();
569
570   bool anIsToUpdateOb = myIsEdit && anOldCaseName != aNewCaseName;
571   
572   // At first we must to update the case name because of 
573   // automatic names generation for regions and zones
574   myEditedObject->SetName( aNewCaseName );
575   
576   if ( myEditedObject->IsMustBeUpdated() )
577   {
578     myShowZones = true;
579     myEditedObject->SplitGeometryObjects();
580
581     aPanel->setEditedObject( myEditedObject );
582
583     createPreview();
584   }
585   else
586   {
587     setZonesVisible( true );
588   }
589
590   if ( anIsToUpdateOb )
591     module()->getApp()->updateObjectBrowser( false );
592
593   QApplication::restoreOverrideCursor();
594 }
595
596 void HYDROGUI_CalculationOp::onHideZones()
597 {
598   setZonesVisible( false );
599 }
600
601 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible )
602 {
603   myShowZones = theIsVisible;
604   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
605   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
606   HYDROData_SequenceOfObjects aZones;
607   Handle(HYDROData_Region) aRegion;
608   if ( myPreviewViewManager ) 
609   {
610     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
611     {
612       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
613       if ( !aCtx.IsNull() )
614       {
615         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
616         {
617           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
618           if ( !aRegion.IsNull() )
619           {
620             aZones = aRegion->GetZones();
621             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
622             for ( ; aZonesIter.More(); aZonesIter.Next() )
623             {
624               if ( theIsVisible )
625               {
626                 showObject( aZonesIter.Value(), aCtx );
627               }
628               else
629               {
630                 module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZonesIter.Value() );
631               }
632             }
633           }
634         }
635       }
636     }
637   }
638 }
639
640 void HYDROGUI_CalculationOp::createPreview()
641 {
642   LightApp_Application* anApp = module()->getApp();
643   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
644   Handle(HYDROData_Entity) anEntity;
645
646   if ( myShowZones )
647   {
648     // Gather zones for displaying
649     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
650     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
651     HYDROData_SequenceOfObjects aZones;
652     Handle(HYDROData_Region) aRegion;
653     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
654     {
655       anEntity = aRegionsIter.Value();
656       if ( !anEntity.IsNull() )
657       {
658         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
659         if ( !aRegion.IsNull() )
660         {
661           aZones = aRegion->GetZones();
662           aSeq.Append( aZones );
663         }
664       }
665     }
666   }
667
668   // Get a boundary polyline if any
669   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
670
671   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
672
673   if ( !myActiveViewManager )
674   {
675     if ( aSeq.IsEmpty() )
676       return;
677
678     myActiveViewManager = anApp->activeViewManager();
679   }
680
681   if ( !myPreviewViewManager )
682   {
683     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
684       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
685     if ( myPreviewViewManager )
686     {
687       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
688                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
689
690       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
691       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
692     }
693   }
694
695   if ( !myPreviewViewManager )
696     return;
697
698   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
699   {
700     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
701     if ( !aCtx.IsNull() )
702     {
703       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
704       for ( ; anIter.More(); anIter.Next() )
705       {
706         showObject( anIter.Value(), aCtx );
707       }
708
709       //Process the draw events for viewer
710       QApplication::processEvents();
711       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
712         vw->onTopView();
713     }
714   }
715 }
716
717 void HYDROGUI_CalculationOp::showObject( Handle(HYDROData_Entity) theEntity, Handle(AIS_InteractiveContext) theCtx )
718 {
719   if ( !theEntity.IsNull() )
720   {
721     HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, theEntity );
722     if ( !aShape )
723     {
724       aShape = new HYDROGUI_Shape( theCtx, theEntity );
725       module()->setObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, theEntity, aShape );
726     }
727     aShape->update();
728   }
729 }
730
731 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
732 {
733   closePreview();
734 }
735
736 void HYDROGUI_CalculationOp::closePreview()
737 {
738   if( myPreviewViewManager )
739   {
740     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
741                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
742
743     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
744     myPreviewViewManager = NULL;
745   }
746
747   if( myActiveViewManager )
748   {
749     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
750     myActiveViewManager = NULL;
751   }
752 }
753
754