Salome HOME
fd48bc169f2a73f5f80a6feb9beaa1e4c6394b30
[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
31 #include <HYDROData_Polyline.h>
32 #include <HYDROData_Iterator.h>
33 #include <HYDROData_Zone.h>
34
35 #include <OCCViewer_ViewManager.h>
36 #include <OCCViewer_ViewModel.h>
37 #include <OCCViewer_ViewWindow.h>
38
39 #include <LightApp_Application.h>
40 #include <LightApp_UpdateFlags.h>
41
42 #include <QApplication>
43
44 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
45 : HYDROGUI_Operation( theModule ),
46   myIsEdit( theIsEdit ),
47   myActiveViewManager( NULL ),
48   myPreviewViewManager( NULL )
49 {
50   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
51 }
52
53 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
54 {
55   closePreview();
56 }
57
58 void HYDROGUI_CalculationOp::startOperation()
59 {
60   HYDROGUI_Operation::startOperation();
61
62   HYDROGUI_CalculationDlg* aPanel = 
63     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
64   if ( !aPanel )
65     return;
66
67   myRegionsList.clear();
68   aPanel->reset();
69
70   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), "Case" );
71
72   QStringList aSelectedZones, aRegions;
73
74   myEditedObject.Nullify();
75   if ( myIsEdit )
76   {
77     myEditedObject = Handle(HYDROData_Calculation)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
78     if ( !myEditedObject.IsNull() )
79     {
80       anObjectName = myEditedObject->GetName();
81
82       Handle(HYDROData_Polyline) aBoundaryPolyline = myEditedObject->GetBoundaryPolyline();
83       if ( !aBoundaryPolyline.IsNull() )
84       {
85         QString aPolylineName = aBoundaryPolyline->GetName();
86         aPanel->setPolylineName( aPolylineName );
87       }
88
89       HYDROData_SequenceOfObjects aRefZones = myEditedObject->GetZones();
90       HYDROData_SequenceOfObjects::Iterator anIter( aRefZones );
91       for ( ; anIter.More(); anIter.Next() )
92       {
93         Handle(HYDROData_Zone) aRefZone = 
94           Handle(HYDROData_Zone)::DownCast( anIter.Value() );
95         if ( aRefZone.IsNull() )
96           continue;
97
98         QString aRefZoneName = aRefZone->GetName();
99         if ( aRefZoneName.isEmpty() )
100           continue;
101
102         aSelectedZones.append( aRefZoneName );
103       }
104
105       HYDROData_SequenceOfObjects aDataRegions = myEditedObject->GetRegions();
106       anIter.Init( aDataRegions );
107       for ( ; anIter.More(); anIter.Next() )
108       {
109         Handle(HYDROData_Region) aDataRegion = 
110           Handle(HYDROData_Region)::DownCast( anIter.Value() );
111         if ( aDataRegion.IsNull() )
112           continue;
113
114         QString aRegionName = aDataRegion->GetName();
115         if ( aRegionName.isEmpty() )
116           continue;
117
118         Region aRegion;
119         aRegion.SplitData.Shape = aDataRegion->Face();
120
121         aRegion.FillingColor = aDataRegion->GetFillingColor();
122         aRegion.BorderColor  = aDataRegion->GetBorderColor();
123
124         aRegion.RegionName = aRegionName;
125
126         aRegion.DataRegion = aDataRegion;
127
128         myRegionsList.append( aRegion );
129
130         aRegions.append( aRegionName );
131       }
132     }
133   }
134
135   // collect information about existing zones
136   QStringList aZones;
137
138   HYDROData_Iterator anIter( doc(), KIND_ZONE );
139   for ( ; anIter.More(); anIter.Next() )
140   {
141     Handle(HYDROData_Zone) aZoneObj = 
142       Handle(HYDROData_Zone)::DownCast( anIter.Current() );
143     if ( aZoneObj.IsNull() )
144       continue;
145
146     QString aZoneName = aZoneObj->GetName();
147     if ( aZoneName.isEmpty() )
148       continue;
149
150     aZones.append( aZoneName );
151   }
152
153   aPanel->setObjectName( anObjectName );
154
155   aPanel->setZones( aZones );
156   aPanel->setSelectedZones( aSelectedZones );
157   aPanel->setRegions( aRegions );
158
159   createPreview();
160 }
161
162 void HYDROGUI_CalculationOp::abortOperation()
163 {
164   closePreview();
165
166   HYDROGUI_Operation::abortOperation();
167 }
168
169 void HYDROGUI_CalculationOp::commitOperation()
170 {
171   closePreview();
172
173   HYDROGUI_Operation::commitOperation();
174 }
175
176 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
177 {
178   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
179
180   // Connect signals and slots
181   connect( aPanel, SIGNAL( SplitZones() ), this, SLOT( onSplitZones() ) );
182
183   return aPanel;
184 }
185
186 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
187                                            QString& theErrorMsg )
188 {
189   HYDROGUI_CalculationDlg* aPanel = 
190     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
191   if ( !aPanel )
192     return false;
193
194   QString anObjectName = aPanel->getObjectName().simplified();
195   if ( anObjectName.isEmpty() )
196   {
197     theErrorMsg = tr( "INCORRECT_OBJECT_NAME" );
198     return false;
199   }
200
201   // check that there are no other objects with the same name in the document
202   if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anObjectName ) )
203   {
204     Handle(HYDROData_Object) anObject = HYDROGUI_Tool::FindObjectByName( module(), anObjectName );
205     if ( !anObject.IsNull() )
206     {
207       theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anObjectName );
208       return false;
209     }
210   }
211
212   Handle(HYDROData_Document) aDocument = doc();
213
214   Handle(HYDROData_Calculation) aCalculObj = myIsEdit ? myEditedObject :
215     Handle(HYDROData_Calculation)::DownCast( aDocument->CreateObject( KIND_CALCULATION ) );
216   if ( aCalculObj.IsNull() )
217     return false;
218
219   aCalculObj->SetName( anObjectName );
220
221   QString aPolylineName = aPanel->getPolylineName();
222   Handle(HYDROData_Polyline) aBndPolyline = Handle(HYDROData_Polyline)::DownCast(
223       HYDROGUI_Tool::FindObjectByName( module(), aPolylineName, KIND_POLYLINE ) );
224
225   aCalculObj->SetBoundaryPolyline( aBndPolyline );
226
227   QStringList aRefZoneNames = aPanel->getSelectedZones();
228   HYDROData_SequenceOfObjects aRefZones = 
229     HYDROGUI_Tool::FindObjectsByNames( module(), aRefZoneNames, KIND_ZONE );
230
231   aCalculObj->SetZones( aRefZones );
232
233   HYDROData_SequenceOfObjects aRegions;
234
235   RegionsList::iterator anIter = myRegionsList.begin();
236   for ( ; anIter != myRegionsList.end(); ++anIter )
237   {
238     const Region& aRegion = *anIter;
239
240     if ( !aRegion.DataRegion.IsNull() )
241     {
242       //No need to create new but use old zone
243       aRegions.Append( aRegion.DataRegion );
244       continue;
245     }
246
247     Handle(HYDROData_Region) aDataRegion =
248       Handle(HYDROData_Region)::DownCast( aDocument->CreateObject( KIND_REGION ) );
249     if( aDataRegion.IsNull() )
250       continue;
251
252     // Fill the zone data
253     aDataRegion->SetFace( aRegion.SplitData.Face() );
254
255     aDataRegion->SetName( aRegion.RegionName );
256     aDataRegion->SetBorderColor( aRegion.BorderColor );
257     aDataRegion->SetFillingColor( aRegion.FillingColor );
258
259     aRegions.Append( aDataRegion );
260   }
261
262   aCalculObj->SetRegions( aRegions );
263
264   theUpdateFlags = UF_Model;
265
266   return true;
267 }
268
269 void HYDROGUI_CalculationOp::onSplitZones()
270 {
271   myRegionsList.clear();
272
273   HYDROGUI_CalculationDlg* aPanel = 
274     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
275   if ( !aPanel )
276     return;
277
278   QApplication::setOverrideCursor( Qt::WaitCursor );
279
280   QString aPolylineName = aPanel->getPolylineName();
281   Handle(HYDROData_Polyline) aBndPolyline = Handle(HYDROData_Polyline)::DownCast(
282       HYDROGUI_Tool::FindObjectByName( module(), aPolylineName, KIND_POLYLINE ) );
283
284   QStringList aZoneNames = aPanel->getSelectedZones();
285   HYDROData_SequenceOfObjects aZones = 
286     HYDROGUI_Tool::FindObjectsByNames( module(), aZoneNames, KIND_ZONE );
287
288   QStringList aResSplittedZones;
289
290   HYDROGUI_SplitZonesTool::SplitDataList aSplittedZones =
291     HYDROGUI_SplitZonesTool::SplitZones( aZones, aBndPolyline );
292
293   QString aSplitZonesPrefix = aPanel->getSplitZonesPrefix();
294   QStringList aUsedNames;
295
296   HYDROGUI_SplitZonesTool::SplitDataListIterator anIter( aSplittedZones );
297   while( anIter.hasNext() )
298   {
299     Region aRegion;
300     aRegion.SplitData = anIter.next();
301
302     aRegion.FillingColor = HYDROGUI_Tool::GenerateFillingColor( module(), aRegion.SplitData.ZoneNames );
303     aRegion.BorderColor  = QColor( HYDROData_Zone::DefaultBorderColor() );
304
305     aRegion.RegionName = HYDROGUI_Tool::GenerateObjectName( module(), aSplitZonesPrefix, aUsedNames );
306
307     aUsedNames.append( aRegion.RegionName );
308
309     aResSplittedZones.append( aRegion.RegionName );
310
311     myRegionsList.append( aRegion );
312   }
313
314   aPanel->setRegions( aResSplittedZones );
315   
316   createPreview();
317
318   QApplication::restoreOverrideCursor();
319 }
320
321 void HYDROGUI_CalculationOp::createPreview()
322 {
323   LightApp_Application* anApp = module()->getApp();
324
325   if ( !myActiveViewManager )
326   {
327     if ( myRegionsList.isEmpty() )
328       return;
329
330     myActiveViewManager = anApp->activeViewManager();
331   }
332
333   if ( !myPreviewViewManager )
334   {
335     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
336       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
337     if ( myPreviewViewManager )
338     {
339       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
340                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
341
342       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
343       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
344     }
345   }
346
347   if ( !myPreviewViewManager )
348     return;
349
350   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
351   {
352     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
353     if ( !aCtx.IsNull() )
354     {
355       RegionsList::iterator anIter = myRegionsList.begin();
356       for ( ; anIter != myRegionsList.end(); ++anIter )
357       {
358         Region& aRegion = *anIter;
359         if ( aRegion.Shape )
360         {
361           aRegion.Shape->erase( false );
362           delete aRegion.Shape;
363         }
364
365         aRegion.Shape = new HYDROGUI_Shape( aCtx, NULL );
366
367         aRegion.Shape->setFillingColor( aRegion.FillingColor, false, false );
368         aRegion.Shape->setBorderColor( aRegion.BorderColor, false, false );
369         aRegion.Shape->setFace( aRegion.SplitData.Face(), true, false );
370       }
371
372       //Process the draw events for viewer
373       QApplication::processEvents();
374       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
375         vw->onTopView();
376     }
377   }
378 }
379
380 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
381 {
382   closePreview();
383 }
384
385 void HYDROGUI_CalculationOp::closePreview()
386 {
387   RegionsList::iterator anIter= myRegionsList.begin();
388   for ( ; anIter != myRegionsList.end(); ++anIter )
389   {
390     Region& aRegion = *anIter;
391     if ( aRegion.Shape )
392     {
393       aRegion.Shape->erase( false );
394       delete aRegion.Shape;
395       aRegion.Shape = NULL;
396     }
397   }
398
399   if( myPreviewViewManager )
400   {
401     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
402                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
403
404     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
405     myPreviewViewManager = NULL;
406   }
407
408   if( myActiveViewManager )
409   {
410     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
411     myActiveViewManager = NULL;
412   }
413 }
414
415