Salome HOME
Minor changes.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PolylineOp.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_PolylineOp.h"
24
25 #include "HYDROGUI_Module.h"
26 #include "HYDROGUI_PolylineDlg.h"
27 #include "HYDROGUI_Tool.h"
28 #include "HYDROGUI_UpdateFlags.h"
29
30 #include <HYDROData_Document.h>
31
32 #include <CurveCreator_Curve.hxx>
33 #include <CurveCreator_Displayer.h>
34
35 #include <LightApp_Application.h>
36 #include <LightApp_SelectionMgr.h>
37 #include <LightApp_UpdateFlags.h>
38
39 #include <OCCViewer_ViewManager.h>
40 #include <OCCViewer_ViewModel.h>
41 #include <OCCViewer_ViewWindow.h>
42
43 #include <OCCViewer_AISSelector.h>
44
45 #include <Precision.hxx>
46
47 #include <SUIT_MessageBox.h>
48 #include <SUIT_Desktop.h>
49
50 //static int ZValueIncrement = 0;
51
52 HYDROGUI_PolylineOp::HYDROGUI_PolylineOp( HYDROGUI_Module* theModule, bool theIsEdit )
53 : HYDROGUI_Operation( theModule ), 
54   myIsEdit( theIsEdit ),
55   myCurve( NULL )
56 {
57   setName( theIsEdit ? tr( "EDIT_POLYLINE" ) : tr( "CREATE_POLYLINE" ) );
58 }
59
60 HYDROGUI_PolylineOp::~HYDROGUI_PolylineOp()
61 {
62   erasePreview();
63 }
64
65 /**
66  * Redirect the delete action to input panel
67  */
68 void HYDROGUI_PolylineOp::deleteSelected()
69 {
70   HYDROGUI_PolylineDlg* aPanel = (HYDROGUI_PolylineDlg*)inputPanel();
71   aPanel->deleteSelected();
72 }
73
74 /**
75  * Checks whether there are some to delete
76  */
77 bool HYDROGUI_PolylineOp::deleteEnabled()
78 {
79   HYDROGUI_PolylineDlg* aPanel = (HYDROGUI_PolylineDlg*)inputPanel();
80   return aPanel->deleteEnabled();
81 }
82
83 /**
84  * Set Z layer for the operation preview.
85  \param theLayer a layer position
86  */
87 void HYDROGUI_PolylineOp::updatePreviewZLayer( int theLayer )
88 {
89   HYDROGUI_Operation::updatePreviewZLayer( theLayer );
90
91   int aZLayer = getPreviewZLayer();
92   if ( aZLayer >= 0 )
93   {
94     if( getPreviewManager() )
95     {
96       if ( OCCViewer_Viewer* aViewer = getPreviewManager()->getOCCViewer() )
97       {
98         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
99         if( !aCtx.IsNull() )
100         {
101           Handle(AIS_InteractiveObject) anObject = myCurve->getAISObject( true );
102           aCtx->SetZLayer( anObject, aZLayer );
103         }
104       }
105     }
106   }
107 }
108
109 void HYDROGUI_PolylineOp::startOperation()
110 {
111   if( myIsEdit )
112   {
113     myEditedObject = Handle(HYDROData_PolylineXY)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
114     if ( !myEditedObject.IsNull() && !myEditedObject->IsEditable() )
115     {
116       // Polyline is imported from GEOM module an is not recognized as
117       // polyline or spline and exist only as shape presentation
118       SUIT_MessageBox::critical( module()->getApp()->desktop(),
119                                  tr( "POLYLINE_IS_UNEDITABLE_TLT" ),
120                                  tr( "POLYLINE_IS_UNEDITABLE_MSG" ) );
121       abort();
122       return;
123     }
124   }
125
126   if( myCurve )
127     delete myCurve;
128
129   myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
130
131   HYDROGUI_Operation::startOperation();
132
133   HYDROGUI_PolylineDlg* aPanel = (HYDROGUI_PolylineDlg*)inputPanel();
134   aPanel->reset();
135
136   LightApp_Application* anApp = module()->getApp();
137   OCCViewer_ViewManager* aViewManager =
138     dynamic_cast<OCCViewer_ViewManager*>( anApp->getViewManager( OCCViewer_Viewer::Type(), true ) );
139   aPanel->setOCCViewer( aViewManager ? aViewManager->getOCCViewer() : 0 );
140   setPreviewManager( aViewManager );
141
142   QString aPolylineName;
143   if( !myEditedObject.IsNull() )
144   {
145     NCollection_Sequence<TCollection_AsciiString>           aSectNames;
146     NCollection_Sequence<HYDROData_PolylineXY::SectionType> aSectTypes;
147     NCollection_Sequence<bool>                              aSectClosures;
148     myEditedObject->GetSections( aSectNames, aSectTypes, aSectClosures );
149
150     for ( int i = 1, n = aSectNames.Size(); i <= n; ++i )
151     {
152       QString aSectName = HYDROGUI_Tool::ToQString( aSectNames.Value( i ) );
153       HYDROData_PolylineXY::SectionType aSectType = aSectTypes.Value( i );
154       bool aSectClosure = aSectClosures.Value( i );
155
156       CurveCreator::SectionType aCurveType = CurveCreator::Polyline;
157       if( aSectType == HYDROData_PolylineXY::SECTION_SPLINE )
158         aCurveType = CurveCreator::Spline;
159
160       CurveCreator::Coordinates aCurveCoords;
161
162       HYDROData_PolylineXY::PointsList aSectPointsList = myEditedObject->GetPoints( i - 1 );
163       for ( int k = 1, aNbPoints = aSectPointsList.Size(); k <= aNbPoints; ++k )
164       {
165         const HYDROData_PolylineXY::Point& aSectPoint = aSectPointsList.Value( k );
166         aCurveCoords.push_back( aSectPoint.X() );
167         aCurveCoords.push_back( aSectPoint.Y() );
168       }
169
170       myCurve->addSectionInternal( aSectName.toStdString(), aCurveType, aSectClosure, aCurveCoords );
171     }
172
173     aPolylineName = myEditedObject->GetName();
174   }
175   else
176   {
177     aPolylineName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_POLYLINE_NAME" ) );
178   }
179
180   aPanel->setPolylineName( aPolylineName );
181   aPanel->setCurve( myCurve );
182
183   displayPreview();
184 }
185
186 void HYDROGUI_PolylineOp::abortOperation()
187 {
188   HYDROGUI_PolylineDlg* aPanel = (HYDROGUI_PolylineDlg*)inputPanel();
189   if ( aPanel )
190     aPanel->setOCCViewer( 0 );
191   erasePreview();
192
193   HYDROGUI_Operation::abortOperation();
194 }
195
196 void HYDROGUI_PolylineOp::commitOperation()
197 {
198   HYDROGUI_PolylineDlg* aPanel = (HYDROGUI_PolylineDlg*)inputPanel();
199   if ( aPanel )
200     aPanel->setOCCViewer( 0 );
201   erasePreview();
202
203   HYDROGUI_Operation::commitOperation();
204 }
205
206 HYDROGUI_InputPanel* HYDROGUI_PolylineOp::createInputPanel() const
207 {
208   HYDROGUI_PolylineDlg* aDlg = new HYDROGUI_PolylineDlg( module(), getName() );
209   connect( aDlg, SIGNAL( selectionChanged() ), this, SLOT( onEditorSelectionChanged() ) );
210   return aDlg;
211 }
212
213 bool HYDROGUI_PolylineOp::processApply( int& theUpdateFlags,
214                                         QString& theErrorMsg )
215 {
216   HYDROGUI_PolylineDlg* aPanel = ::qobject_cast<HYDROGUI_PolylineDlg*>( inputPanel() );
217   if ( !aPanel )
218     return false;
219
220   QString aPolylineName = aPanel->getPolylineName().simplified();
221   if ( aPolylineName.isEmpty() )
222   {
223     theErrorMsg = tr( "INCORRECT_OBJECT_NAME" );
224     return false;
225   }
226
227   if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != aPolylineName ) )
228   {
229     // check that there are no other objects with the same name in the document
230     Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), aPolylineName );
231     if( !anObject.IsNull() )
232     {
233       theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( aPolylineName );
234       return false;
235     }
236   }
237
238   if ( myCurve->getNbSections() <= 0 )
239   {
240     theErrorMsg = tr( "EMPTY_POLYLINE_DATA" );
241     return false;
242   }
243
244   Handle(HYDROData_PolylineXY) aPolylineObj;
245   if( myIsEdit )
246   {
247     aPolylineObj = myEditedObject;
248     aPolylineObj->RemoveSections();
249   }
250   else
251   {
252     aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
253   }
254
255   if( aPolylineObj.IsNull() )
256     return false;
257
258   aPolylineObj->SetName( aPolylineName );
259
260   for ( int i = 0 ; i < myCurve->getNbSections() ; i++ )
261   {
262     TCollection_AsciiString aSectName = HYDROGUI_Tool::ToAsciiString( myCurve->getSectionName( i ).c_str() );
263     CurveCreator::SectionType aCurveType =  myCurve->getSectionType( i );
264     bool aSectClosure = myCurve->isClosed( i );
265
266     HYDROData_PolylineXY::SectionType aSectType = HYDROData_PolylineXY::SECTION_POLYLINE;
267
268     if ( aCurveType == CurveCreator::Spline )
269       aSectType = HYDROData_PolylineXY::SECTION_SPLINE;
270
271     aPolylineObj->AddSection( aSectName, aSectType, aSectClosure );
272
273     // Add the points fro section
274     CurveCreator::Coordinates aCurveCoords = myCurve->getPoints( i );
275
276     if ( aCurveCoords.size() <= 2 )
277     {
278       theErrorMsg = tr( "NUMBER_OF_SECTION_POINTS_INCORRECT" );
279       return false;
280     }
281
282     for ( int k = 0 ; k + 1 < aCurveCoords.size() ; k++ )
283     {
284       HYDROData_PolylineXY::Point aSectPoint;
285
286       aSectPoint.SetX( aCurveCoords.at( k ) );
287       k++;
288       aSectPoint.SetY( aCurveCoords.at( k ) );
289
290       aPolylineObj->AddPoint( i, aSectPoint );
291     }
292   }
293
294   if ( !myIsEdit )
295   {
296     aPolylineObj->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
297   }
298
299   // Update the wire of polyline
300   aPolylineObj->Update();
301   module()->setIsToUpdate( aPolylineObj );
302
303   // the viewer should be release from the widget before the module update it
304   // because it has an opened local context and updated presentation should not be displayed in it
305   if ( aPanel )
306     aPanel->setOCCViewer( 0 );
307
308   theUpdateFlags = UF_Model;
309
310   // the polyline should be rebuild in all viewers, where it is displayed
311   theUpdateFlags |= UF_Viewer | UF_GV_Forced;
312   theUpdateFlags |= UF_OCCViewer | UF_OCC_Forced;
313   theUpdateFlags |= UF_VTKViewer;
314
315   size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module() );
316   if ( anActiveViewId == 0 )
317   {
318     anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module() );
319   }
320
321   if( !myIsEdit )
322   {
323     module()->setObjectVisible( anActiveViewId, aPolylineObj, true );
324   }  
325
326   return true;
327 }
328
329 void HYDROGUI_PolylineOp::onEditorSelectionChanged()
330 {
331   HYDROGUI_PolylineDlg* aPanel = (HYDROGUI_PolylineDlg*)inputPanel();
332   if( !aPanel )
333     return;
334   if( !myCurve )
335     return;
336   CurveCreator_Displayer* aDisplayer = myCurve->getDisplayer();
337   if( !aDisplayer )
338     return;
339   //QList<int> aSelSections = aPanel->getSelectedSections();
340   bool aIsHl = false;
341   //if( aSelSections.contains(i) ){
342   // TODO
343   //aDisplayer->highlight( myCurve->getAISObject(), aIsHl );
344   //}
345 }
346
347 void HYDROGUI_PolylineOp::displayPreview()
348 {
349   if( getPreviewManager() )
350   {
351     if( OCCViewer_Viewer* aViewer = getPreviewManager()->getOCCViewer() )
352     {
353       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
354       if( !aCtx.IsNull() )
355       {
356         CurveCreator_Displayer* aDisplayer = new CurveCreator_Displayer( aCtx, getPreviewZLayer() );
357         myCurve->setDisplayer( aDisplayer );
358         aDisplayer->display( myCurve->getAISObject( true ), true );
359       }
360     }
361   }
362 }
363
364 void HYDROGUI_PolylineOp::erasePreview()
365 {
366   CurveCreator_Displayer* aDisplayer = myCurve ? myCurve->getDisplayer() : 0;
367   if( getPreviewManager() && aDisplayer )
368   {
369     if( OCCViewer_Viewer* aViewer = getPreviewManager()->getOCCViewer() )
370     {
371       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
372       if( !aCtx.IsNull() )
373       {
374         aDisplayer->eraseAll( true );
375       }
376     }
377   }
378
379   setPreviewManager( NULL );
380   if ( myCurve )
381   {
382     delete myCurve;
383     myCurve = NULL;
384   }
385 }