Salome HOME
Initial solution for bug #141: Stream object.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_StreamOp.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_StreamOp.h"
24
25 #include "HYDROGUI_Module.h"
26 #include "HYDROGUI_Shape.h"
27 #include "HYDROGUI_StreamDlg.h"
28 #include "HYDROGUI_Tool.h"
29 #include "HYDROGUI_UpdateFlags.h"
30
31 #include <HYDROData_Document.h>
32 #include <HYDROData_PolylineXY.h>
33 #include <HYDROData_Profile.h>
34
35 #include <LightApp_Application.h>
36 #include <LightApp_SelectionMgr.h>
37 #include <LightApp_UpdateFlags.h>
38
39 #include <SUIT_MessageBox.h>
40 #include <SUIT_Desktop.h>
41
42 #include <OCCViewer_ViewManager.h>
43 #include <OCCViewer_ViewModel.h>
44 #include <OCCViewer_ViewWindow.h>
45
46 HYDROGUI_StreamOp::HYDROGUI_StreamOp( HYDROGUI_Module* theModule, bool theIsEdit )
47 : HYDROGUI_Operation( theModule ), 
48   myIsEdit( theIsEdit ),
49   myViewManager( NULL ),
50   myPreviewPrs( NULL )
51 {
52   setName( theIsEdit ? tr( "EDIT_STREAM" ) : tr( "CREATE_STREAM" ) );
53 }
54
55 HYDROGUI_StreamOp::~HYDROGUI_StreamOp()
56 {
57   erasePreview();
58 }
59
60 void HYDROGUI_StreamOp::startOperation()
61 {
62   HYDROGUI_Operation::startOperation();
63
64   // We start operation in the document
65   startDocOperation();
66
67   HYDROGUI_StreamDlg* aPanel = (HYDROGUI_StreamDlg*)inputPanel();
68
69   if( myIsEdit )
70     myEditedObject = Handle(HYDROData_Stream)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
71   else 
72     myEditedObject = Handle(HYDROData_Stream)::DownCast( doc()->CreateObject( KIND_STREAM ) );
73
74   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_STREAM_NAME" ) );
75   if ( myIsEdit && !myEditedObject.IsNull() ) {
76     anObjectName = myEditedObject->GetName();
77   }
78
79   // Update panel data
80   aPanel->blockSignals( true );
81   aPanel->reset();
82   aPanel->setObjectName( anObjectName );
83   aPanel->setAxisNames( HYDROGUI_Tool::FindExistingObjectsNames( doc(), KIND_POLYLINEXY ) );
84   aPanel->blockSignals( false );
85
86   if ( myIsEdit ) {
87     updatePanel();
88   } else {
89     onAxisChanged( aPanel->getAxisName() );
90   }
91
92   // Create preview
93   onCreatePreview();
94 }
95
96 void HYDROGUI_StreamOp::abortOperation()
97 {
98   erasePreview();
99   abortDocOperation();
100
101   HYDROGUI_Operation::abortOperation();
102 }
103
104 void HYDROGUI_StreamOp::commitOperation()
105 {
106   erasePreview();
107
108   HYDROGUI_Operation::commitOperation();
109 }
110
111 HYDROGUI_InputPanel* HYDROGUI_StreamOp::createInputPanel() const
112 {
113   HYDROGUI_StreamDlg* aPanel = new HYDROGUI_StreamDlg( module(), getName() );
114   //TODO connect( aPanel, SIGNAL( CreatePreview() ), this, SLOT( onCreatePreview() ) );
115   connect( aPanel, SIGNAL( AddProfiles() ), this, SLOT( onAddProfiles() ) );
116   connect( aPanel, SIGNAL( RemoveProfiles( const QStringList& ) ), 
117            this, SLOT( onRemoveProfiles( const QStringList& ) ) );
118   connect( aPanel, SIGNAL( AxisChanged( const QString& ) ), 
119            this, SLOT( onAxisChanged( const QString& ) ) );
120   return aPanel;
121 }
122
123 bool HYDROGUI_StreamOp::processApply( int& theUpdateFlags,
124                                       QString& theErrorMsg )
125 {
126   HYDROGUI_StreamDlg* aPanel = ::qobject_cast<HYDROGUI_StreamDlg*>( inputPanel() );
127   if ( !aPanel )
128     return false;
129
130   QString anObjectName = aPanel->getObjectName().simplified();
131   if ( anObjectName.isEmpty() )
132   {
133     theErrorMsg = tr( "INCORRECT_OBJECT_NAME" );
134     return false;
135   }
136
137   if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anObjectName ) )
138   {
139     // check that there are no other objects with the same name in the document
140     Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), anObjectName );
141     if( !anObject.IsNull() )
142     {
143       theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anObjectName );
144       return false;
145     }
146   }
147
148   if ( myEditedObject.IsNull() )
149     return false;
150
151   // Check if the axis is set
152   Handle(HYDROData_PolylineXY) aHydraulicAxis = myEditedObject->GetHydraulicAxis();
153   if ( aHydraulicAxis.IsNull() ) {
154     theErrorMsg = tr( "AXIS_NOT_DEFINED" );
155     return false;
156   }
157
158   // Check if the axis is set
159   HYDROData_SequenceOfObjects aProfiles = myEditedObject->GetProfiles();
160   if ( aProfiles.Length() < 2 ) {
161     theErrorMsg = tr( "PROFILES_NOT_DEFINED" );
162     return false;
163   }
164
165   myEditedObject->SetName( anObjectName );
166
167   erasePreview();
168
169   if( !myIsEdit )
170     module()->setObjectVisible( HYDROGUI_Tool::GetActiveOCCViewId( module() ), myEditedObject, true );
171
172   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced;
173
174   return true;
175 }
176
177 void HYDROGUI_StreamOp::onCreatePreview()
178 {
179   if ( myEditedObject.IsNull() )
180     return;
181
182   LightApp_Application* anApp = module()->getApp();
183   if ( !myViewManager )
184     myViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
185       anApp->getViewManager( OCCViewer_Viewer::Type(), true ) );
186
187   if ( myViewManager && !myPreviewPrs )
188   {
189     if ( OCCViewer_Viewer* aViewer = myViewManager->getOCCViewer() )
190     {
191       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
192       if ( !aCtx.IsNull() )
193         myPreviewPrs = new HYDROGUI_Shape( aCtx, myEditedObject );
194     }
195   }
196
197   if ( !myViewManager || !myPreviewPrs )
198     return;
199
200   myPreviewPrs->update();
201 }
202
203 void HYDROGUI_StreamOp::erasePreview()
204 {
205   if( myPreviewPrs )
206   {
207     delete myPreviewPrs;
208     myPreviewPrs = 0;
209   }
210 }
211
212 void HYDROGUI_StreamOp::onAddProfiles()
213 {
214   if ( myEditedObject.IsNull() ) {
215     return;
216   }
217
218   // Get the current profiles list
219   HYDROData_SequenceOfObjects aProfiles = myEditedObject->GetProfiles();
220
221   // TODO: to be optimized
222   QStringList aCurrentProfiles;
223   for( int anIndex = 1, aLength = aProfiles.Length(); anIndex <= aLength; anIndex++ ) {
224     Handle(HYDROData_Profile) aProfile =
225       Handle(HYDROData_Profile)::DownCast( aProfiles.Value( anIndex ) );
226     if ( !aProfile.IsNull() ) {
227       aCurrentProfiles << aProfile->GetName();
228     }
229   }
230     
231   // Get the selected profiles ( in the Object Browser )
232   QStringList anInvalidProfiles, anExistingProfiles, aHasNoIntersectionProfiles;
233
234   HYDROData_SequenceOfObjects aSeqOfProfiles;
235   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( module() );
236   for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
237     Handle(HYDROData_Profile) aProfile =
238       Handle(HYDROData_Profile)::DownCast( aSeq.Value( anIndex ) );
239     if ( !aProfile.IsNull() ) {
240       QString aProfileName = aProfile->GetName();
241
242       // Check the profile, if all is ok - add it to the list
243       if ( !aProfile->IsValid() ) { // check whether the profile is valid
244         anInvalidProfiles << aProfileName;
245       } else if ( aCurrentProfiles.contains( aProfileName ) ) { // check whether the profile is already added
246         anExistingProfiles << aProfileName;
247       } else if ( !myEditedObject->HasIntersection( aProfile ) ) {  // check whether the profile has intersection
248         aHasNoIntersectionProfiles << aProfile->GetName();
249       } else {
250         aSeqOfProfiles.Append( aProfile );
251       }
252     }
253   }
254  
255   // Show message box with the ignored profiles
256   QStringList anIgnoredProfiles;
257   anIgnoredProfiles << anInvalidProfiles << anExistingProfiles << aHasNoIntersectionProfiles;
258   if ( !anIgnoredProfiles.isEmpty() ) {
259     QString aMessage = tr( "IGNORED_PROFILES" ).arg( anIgnoredProfiles.join( "\n" ) );
260     SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "WARNING" ), aMessage );
261   }
262   
263   // Update the stream object
264   for( int anIndex = 1, aLength = aSeqOfProfiles.Length(); anIndex <= aLength; anIndex++ ) {
265     Handle(HYDROData_Profile) aProfile =
266       Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( anIndex ) );
267     myEditedObject->AddProfile( aProfile );
268   }
269   myEditedObject->Update();
270
271   // Update the panel
272   updatePanel();
273
274   // Update preview
275   onCreatePreview();
276 }
277
278 void HYDROGUI_StreamOp::onRemoveProfiles( const QStringList& theProfilesToRemove )
279 {
280   if ( myEditedObject.IsNull() ) {
281     return;
282   }
283
284   // Remove profiles
285   foreach( const QString& aProfileName, theProfilesToRemove ) {
286     Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast(
287       HYDROGUI_Tool::FindObjectByName( module(), aProfileName, KIND_PROFILE ) );
288     myEditedObject->RemoveProfile( aProfile );
289   }
290   myEditedObject->Update();
291
292   // Update the panel
293   updatePanel();
294
295   // Update preview
296   onCreatePreview();
297 }
298
299 void HYDROGUI_StreamOp::onAxisChanged( const QString& theNewAxis )
300 {
301   if ( myEditedObject.IsNull() ) {
302     return;
303   }
304
305   // Get axis object   
306   Handle(HYDROData_PolylineXY) anAxis = Handle(HYDROData_PolylineXY)::DownCast(
307     HYDROGUI_Tool::FindObjectByName( module(), theNewAxis, KIND_POLYLINEXY ) );
308
309   // Get list of profiles which do not intersect the axis
310   QStringList aHasNoIntersectionProfiles;
311   HYDROData_SequenceOfObjects aCurrentProfiles = myEditedObject->GetProfiles();
312   for( int anIndex = 1, aLength = aCurrentProfiles.Length(); anIndex <= aLength; anIndex++ ) {
313     Handle(HYDROData_Profile) aProfile =
314       Handle(HYDROData_Profile)::DownCast( aCurrentProfiles.Value( anIndex ) );
315     if ( !aProfile.IsNull() ) {
316       // TODO check intersection
317     }
318   }
319
320   // Show message box to confirm
321   bool isConfirmed = true;
322   if ( !aHasNoIntersectionProfiles.isEmpty() ) {
323     // TODO show message box
324   }
325
326   // Check if the user has confirmed axis change
327   if ( !isConfirmed ) {
328     updatePanel();
329   } else {
330     // Set axis
331     myEditedObject->SetHydraulicAxis( anAxis );
332     myEditedObject->Update();
333
334     // Update the panel
335     updatePanel();
336
337     // Update preview
338     onCreatePreview();
339   }
340 }
341
342 void HYDROGUI_StreamOp::updatePanel()
343 {
344   HYDROGUI_StreamDlg* aPanel = ::qobject_cast<HYDROGUI_StreamDlg*>( inputPanel() );
345   if ( !aPanel ) {
346     return;
347   }
348
349   // Hydraulic axis
350   Handle(HYDROData_PolylineXY) aHydraulicAxis = myEditedObject->GetHydraulicAxis();
351   if ( !aHydraulicAxis.IsNull() ) {
352     aPanel->setAxisName( aHydraulicAxis->GetName() );
353   }
354
355   // Stream profiles
356   QStringList aSelectedProfiles;
357
358   HYDROData_SequenceOfObjects aProfiles = myEditedObject->GetProfiles();
359   for ( int i = 1, n = aProfiles.Length(); i <= n; ++i ) {
360     Handle(HYDROData_Profile) aProfile = 
361       Handle(HYDROData_Profile)::DownCast( aProfiles.Value( i ) );
362     if ( aProfile.IsNull() ) {
363       continue;
364     }
365
366     QString aProfileName = aProfile->GetName();
367     aSelectedProfiles << aProfileName;
368   }
369
370   aPanel->setSelectedProfiles( aSelectedProfiles );
371 }