Salome HOME
c37a2ffc59695733d7941fa82f828c21043b419e
[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
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_Desktop.h>
47
48 #include <QApplication>
49
50 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
51 : HYDROGUI_Operation( theModule ),
52   myIsEdit( theIsEdit ),
53   myActiveViewManager( NULL ),
54   myPreviewViewManager( NULL )
55 {
56   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
57 }
58
59 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
60 {
61   closePreview();
62 }
63
64 void HYDROGUI_CalculationOp::startOperation()
65 {
66   HYDROGUI_Operation::startOperation();
67   
68   // Begin transaction
69   startDocOperation();
70
71   HYDROGUI_CalculationDlg* aPanel = 
72     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
73   if ( !aPanel )
74     return;
75
76   myRegionsList.clear();
77   aPanel->reset();
78
79   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), "Case" );
80
81   QStringList aSelectedObjects;
82
83   myEditedObject.Nullify();
84   if ( myIsEdit )
85   {
86     myEditedObject = Handle(HYDROData_CalculationCase)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
87     if ( !myEditedObject.IsNull() )
88     {
89       anObjectName = myEditedObject->GetName();
90       updateGeomObjectsList(aPanel);
91     }
92   }
93   else
94   {
95     myEditedObject =
96       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
97     myEditedObject->SetName(anObjectName);
98   }
99
100   aPanel->setObjectName( anObjectName );
101   aPanel->setEditedObject( myEditedObject );
102
103   createPreview();
104 }
105
106 void HYDROGUI_CalculationOp::updateGeomObjectsList( HYDROGUI_CalculationDlg* thePanel ) const
107 {
108   Handle(HYDROData_Object) anObject;
109   Handle(HYDROData_Entity) anEntity;
110   QStringList aList;
111   // Update the list in the dialog
112   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
113   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
114   for ( ; anIter.More(); anIter.Next() )
115   {
116     anEntity = anIter.Value();
117     if ( !anEntity.IsNull() )
118     {
119       anObject = Handle(HYDROData_Object)::DownCast( anEntity );
120       if ( !anObject.IsNull() )
121       {
122         aList.append( anObject->GetName() );
123       }
124     }
125   }
126   thePanel->setSelectedGeomObjects( aList );
127 }
128
129 void HYDROGUI_CalculationOp::abortOperation()
130 {
131   closePreview();
132   // Abort transaction
133   abortDocOperation();
134   HYDROGUI_Operation::abortOperation();
135 }
136
137 void HYDROGUI_CalculationOp::commitOperation()
138 {
139   closePreview();
140   // Commit transaction
141   commitDocOperation();
142   HYDROGUI_Operation::commitOperation();
143 }
144
145 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
146 {
147   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
148
149   // Connect signals and slots
150   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
151   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
152   connect( aPanel, SIGNAL( splitZones() ), SLOT( onSplitZones() ) );
153   connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
154   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
155   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
156     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
157   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
158     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
159
160   return aPanel;
161 }
162
163 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
164 {
165   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
166   if ( aRegion )
167   {
168     QList<HYDROGUI_Zone*> aZonesList;
169     HYDROGUI_Zone* aZone;
170     // Get a list of dropped zones
171     for ( int i = 0; i < theZonesList.length(); i++ )
172     {
173       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
174       if ( aZone )
175       {
176         aZonesList.append( aZone );
177       }
178     }
179     if ( aZonesList.length() > 0 )
180     {
181       aRegion->addZones( aZonesList );
182       HYDROGUI_CalculationDlg* aPanel = 
183         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
184       if ( aPanel )
185       {
186         aPanel->setEditedObject(myEditedObject);
187       }
188     }
189   }
190 }
191
192 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
193 {
194   QList<HYDROGUI_Zone*> aZonesList;
195   HYDROGUI_Zone* aZone;
196   // Get a list of dropped zones
197   for ( int i = 0; i < theZonesList.length(); i++ )
198   {
199     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
200     if ( aZone )
201     {
202       aZonesList.append( aZone );
203     }
204   }
205   if ( aZonesList.length() > 0 )
206   {
207     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
208     HYDROGUI_CalculationDlg* aPanel = 
209       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
210     if ( aPanel )
211     {
212       aPanel->setEditedObject(myEditedObject);
213     }
214   }
215 }
216
217 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theBathymetryName )
218 {
219   HYDROGUI_CalculationDlg* aPanel = 
220     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
221   if ( aPanel )
222   {
223     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
224     if ( aZone )
225     {
226       aZone->setMergeType( theMergeType, theBathymetryName );
227     }
228     aPanel->refreshZonesBrowser();
229   }
230 }
231
232 void HYDROGUI_CalculationOp::onAddObjects()
233 {
234   // Add geometry objects selected in the module browser to the calculation case
235   Handle(HYDROData_Object) anObject;
236   Handle(HYDROData_Entity) anEntity;
237   QStringList aList;
238   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( module() );
239   for( Standard_Integer anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ )
240   {
241     anEntity = aSeq.Value( anIndex );
242     if ( !anEntity.IsNull() )
243     {
244       anObject = Handle(HYDROData_Object)::DownCast( anEntity );
245       if( !anObject.IsNull() )
246       {
247         if (myEditedObject->AddGeometryObject( anObject ))
248         {
249           aList.append( anObject->GetName() );
250         }
251       }
252     }
253   }
254   HYDROGUI_CalculationDlg* aPanel = 
255     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
256   if ( aPanel )
257   {
258     updateGeomObjectsList( aPanel );
259   }
260   createPreview();
261 }
262
263 void HYDROGUI_CalculationOp::onRemoveObjects()
264 {
265   // Remove selected objects from the calculation case
266   HYDROGUI_CalculationDlg* aPanel = 
267     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
268   if ( aPanel )
269   {
270     QStringList aList = aPanel->getSelectedGeomObjects();
271     Handle(HYDROData_Object) anObject;
272     Handle(HYDROData_Entity) anEntity;
273     for (int i = 0; i < aList.length(); i++)
274     {
275       anEntity = HYDROGUI_Tool::FindObjectByName( module(), aList.at(i) );
276       if ( !anEntity.IsNull() )
277       {
278         anObject = Handle(HYDROData_Object)::DownCast( anEntity );
279         if ( !anObject.IsNull() )
280         {
281           module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject );
282           myEditedObject->RemoveGeometryObject( anObject );
283         }
284       }
285     }
286     updateGeomObjectsList( aPanel );
287   }
288 }
289
290 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
291                                            QString& theErrorMsg )
292 {
293   HYDROGUI_CalculationDlg* aPanel = 
294     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
295   if ( !aPanel )
296     return false;
297
298   theUpdateFlags = UF_Model;
299
300   return true;
301 }
302
303 void HYDROGUI_CalculationOp::onApply()
304 {
305   QApplication::setOverrideCursor( Qt::WaitCursor );
306
307   int anUpdateFlags = 0;
308   QString anErrorMsg;
309
310   bool aResult = false;
311   
312   try
313   {
314     aResult = processApply( anUpdateFlags, anErrorMsg );
315   }
316   catch ( Standard_Failure )
317   {
318     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
319     anErrorMsg = aFailure->GetMessageString();
320     aResult = false;
321   }
322   catch ( ... )
323   {
324     aResult = false;
325   }
326   
327   QApplication::restoreOverrideCursor();
328
329   if ( aResult )
330   {
331     module()->update( anUpdateFlags );
332     commit();
333   }
334   else
335   {
336     abort();
337     QString aMsg = tr( "INPUT_VALID_DATA" );
338     if( !anErrorMsg.isEmpty() )
339       aMsg.prepend( anErrorMsg + "\n" );
340     SUIT_MessageBox::critical( module()->getApp()->desktop(),
341                                tr( "INSUFFICIENT_INPUT_DATA" ),
342                                aMsg ); 
343   }
344 }
345
346 void HYDROGUI_CalculationOp::onSplitZones()
347 {
348   HYDROGUI_CalculationDlg* aPanel = 
349     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
350   if ( !aPanel )
351     return;
352
353   QApplication::setOverrideCursor( Qt::WaitCursor );
354
355   myEditedObject->SplitGeometryObjects();
356   aPanel->setEditedObject( myEditedObject );
357   createPreview();
358
359   QApplication::restoreOverrideCursor();
360 }
361
362 void HYDROGUI_CalculationOp::createPreview()
363 {
364   LightApp_Application* anApp = module()->getApp();
365   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
366   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
367
368   if ( !myActiveViewManager )
369   {
370     if ( aSeq.IsEmpty() )
371       return;
372
373     myActiveViewManager = anApp->activeViewManager();
374   }
375
376   if ( !myPreviewViewManager )
377   {
378     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
379       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
380     if ( myPreviewViewManager )
381     {
382       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
383                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
384
385       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
386       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
387     }
388   }
389
390   if ( !myPreviewViewManager )
391     return;
392
393   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
394   {
395     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
396     if ( !aCtx.IsNull() )
397     {
398       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
399       Handle(HYDROData_Object) anObject;
400       Handle(HYDROData_Entity) anEntity;
401       HYDROGUI_Shape* aShape;
402       for ( ; anIter.More(); anIter.Next() )
403       {
404         anEntity = anIter.Value();
405         if ( !anEntity.IsNull() )
406         {
407           anObject = Handle(HYDROData_Object)::DownCast( anEntity );
408           if ( !anObject.IsNull() )
409           {
410             aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject );
411             if ( !aShape )
412             {
413               aShape = new HYDROGUI_Shape( aCtx, anObject );
414             }
415             aShape->update();
416             module()->setObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject, aShape );
417           }
418         }
419       }
420
421       //Process the draw events for viewer
422       QApplication::processEvents();
423       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
424         vw->onTopView();
425     }
426   }
427 }
428
429 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
430 {
431   closePreview();
432 }
433
434 void HYDROGUI_CalculationOp::closePreview()
435 {
436   if( myPreviewViewManager )
437   {
438     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
439                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
440
441     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
442     myPreviewViewManager = NULL;
443   }
444
445   if( myActiveViewManager )
446   {
447     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
448     myActiveViewManager = NULL;
449   }
450 }
451
452