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