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