Salome HOME
fd66a6b69052c075b0af2665025cfb53dd4f31de
[modules/hydro.git] / src / HYDROCurveCreator / CurveCreator_Widget.cxx
1 // Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "CurveCreator_Widget.h"
21 #include "CurveCreator_TreeView.h"
22 #include "CurveCreator_ICurve.hxx"
23 //#include "CurveCreator_CurveEditor.hxx"
24 #include "CurveCreator.hxx"
25 //#include "CurveCreator_NewPointDlg.h"
26 #include "CurveCreator_NewSectionDlg.h"
27 #include "CurveCreator_Utils.h"
28 #include "CurveCreator_TableView.h"
29
30 #include <SUIT_Session.h>
31 #include <SUIT_Desktop.h>
32 #include <SUIT_ResourceMgr.h>
33 #include <SUIT_ViewManager.h>
34
35 #include <OCCViewer_ViewWindow.h>
36 #include <OCCViewer_ViewManager.h>
37 #include <OCCViewer_ViewPort3d.h>
38 #include "OCCViewer_Utilities.h"
39 #include "OCCViewer_ViewWidget.h"
40
41 #include <BRep_Tool.hxx>
42 #include <TopoDS.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopoDS_Wire.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <gp_Lin.hxx>
47 #include <gp_Dir.hxx>
48 #include <TopExp_Explorer.hxx>
49
50 #include <GeomAPI_ProjectPointOnCurve.hxx>
51
52 #include <AIS_ListOfInteractive.hxx>
53 #include <AIS_ListIteratorOfListOfInteractive.hxx>
54 #include <AIS_Shape.hxx>
55 #include <AIS_Point.hxx>
56 #include <AIS_Line.hxx>
57 #include <Geom_Point.hxx>
58 #include <Geom_BSplineCurve.hxx>
59 #include <Geom_Line.hxx>
60 #include <StdSelect_BRepOwner.hxx>
61
62 #include <QHBoxLayout>
63 #include <QVBoxLayout>
64 #include <QLabel>
65 #include <QLineEdit>
66 #include <QGroupBox>
67 #include <QToolButton>
68 #include <QToolBar>
69 #include <QAction>
70 #include <QMenu>
71 #include <QMouseEvent>
72 #include <QApplication>
73 #include <QTableWidget>
74
75 const double LOCAL_SELECTION_TOLERANCE = 0.0001;
76 const int SECTION_NAME_COLUMN_WIDTH = 75;
77 const int POINT_INDEX_COLUMN_WIDTH = 40;
78
79 const int SCENE_PIXEL_TOLERANCE = 10;
80
81 CurveCreator_Widget::CurveCreator_Widget(QWidget* parent,
82                                          CurveCreator_ICurve *theCurve,
83                                          Qt::WindowFlags fl)
84 : QWidget(parent), myNewSectionEditor(NULL), myCurve(theCurve), mySection(0),
85   myDragStarted( false ), myDragInteractionStyle( SUIT_ViewModel::STANDARD ),
86   myOCCViewer( 0 ), myOCCViewWidget( 0 )
87 {
88   myNewSectionEditor = new CurveCreator_NewSectionDlg( this );
89   myNewSectionEditor->hide();
90   connect( myNewSectionEditor, SIGNAL(addSection()), this, SLOT(onAddNewSection()) );
91   connect( myNewSectionEditor, SIGNAL(modifySection()), this, SLOT(onModifySection()) );
92   connect( myNewSectionEditor, SIGNAL(cancelSection()), this, SLOT(onCancelSection()) );
93
94   QGroupBox* aSectionGroup = new QGroupBox(tr("Sections"),this);
95
96   mySectionView = new CurveCreator_TreeView(myCurve, aSectionGroup);
97   connect( mySectionView, SIGNAL(selectionChanged()), this, SLOT( onSelectionChanged() ) );
98   connect( mySectionView, SIGNAL(sectionEntered(int)), this, SLOT(onEditSection(int)) );
99   connect( mySectionView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onContextMenu(QPoint)) );
100
101   myLocalPointView = new QTableWidget();
102   myLocalPointView->setItemDelegate( new CurveCreator_TableItemDelegate( myLocalPointView ) );
103   myLocalPointView->setVisible( false );
104   myLocalPointView->setColumnCount( 4 );
105   myLocalPointView->setColumnWidth( 0, SECTION_NAME_COLUMN_WIDTH );
106   myLocalPointView->setColumnWidth( 1, POINT_INDEX_COLUMN_WIDTH );
107   QStringList aLabels;
108   //aLabels << tr( "SECTION_LABEL" ) << tr( "IDENTIFIER_LABEL" ) << tr( "X_POSITION_LBL" ) << tr( "Y_POSITION_LBL" );
109   aLabels << tr( "Section" ) << "Index" << tr( "X" ) << tr( "Y" );
110   myLocalPointView->setHorizontalHeaderLabels( aLabels );
111   connect( myLocalPointView, SIGNAL( cellChanged( int, int ) ),
112            this, SLOT( onCellChanged( int, int ) ) );
113
114   QToolBar* aTB = new QToolBar(tr("TOOL_BAR_TLT"), aSectionGroup);
115 //    QToolButton* anUndoBtn = new QToolButton(aTB);
116
117   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
118   QPixmap anUndoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_UNDO")));
119   QPixmap aRedoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_REDO")));
120   QPixmap aNewSectionPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_SECTION")));
121   QPixmap aNewPointPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_POINT")));
122   QPixmap anEditPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
123   QPixmap aDetectPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
124   QPixmap aPolylinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
125   QPixmap aSplinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
126   QPixmap aRemovePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_DELETE")));
127   QPixmap aJoinPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_JOIN")));
128   QPixmap aStepUpPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_UP")));
129   QPixmap aStepDownPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_DOWN")));
130
131   QAction* anAct = createAction( UNDO_ID, tr("UNDO"), anUndoPixmap, tr("UNDO_TLT"), 
132                                  QKeySequence(Qt::ControlModifier|Qt::Key_Z) );
133   connect(anAct, SIGNAL(triggered()), this, SLOT(onUndo()) );
134   aTB->addAction(anAct);
135
136   anAct = createAction( REDO_ID, tr("REDO"), aRedoPixmap, tr("REDO_TLT"), 
137                         QKeySequence(Qt::ControlModifier|Qt::Key_Y) );
138   connect(anAct, SIGNAL(triggered()), this, SLOT(onRedo()) );
139   aTB->addAction(anAct);
140
141   aTB->addSeparator();
142
143   anAct = createAction( NEW_SECTION_ID, tr("NEW_SECTION"), aNewSectionPixmap, tr("NEW_SECTION_TLT"), 
144                         QKeySequence(Qt::ControlModifier|Qt::Key_N) );
145   connect(anAct, SIGNAL(triggered()), this, SLOT(onNewSection()) );
146   aTB->addAction(anAct);
147   aTB->addSeparator();
148
149   anAct = createAction( ADDITION_MODE_ID, tr("ADDITION_MODE"), aNewPointPixmap, tr("ADDITION_MODE_TLT"), 
150                         QKeySequence() );
151   anAct->setCheckable(true);
152   connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onAdditionMode(bool)) );
153   connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
154   aTB->addAction(anAct);
155   
156   anAct = createAction( MODIFICATION_MODE_ID, tr("MODIFICATION_MODE"), anEditPointsPixmap, tr("MODIFICATION_MODE_TLT"), 
157                         QKeySequence() );
158   anAct->setCheckable(true);
159   connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onModificationMode(bool)) );
160   connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
161   aTB->addAction(anAct);
162
163   anAct = createAction( DETECTION_MODE_ID, tr("DETECTION_MODE"), aDetectPointsPixmap, tr("DETECTION_MODE_TLT"), 
164                         QKeySequence() );
165   anAct->setCheckable(true);
166   connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onDetectionMode(bool)) );
167   connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
168   aTB->addAction(anAct);
169
170   anAct = createAction( CLOSE_SECTIONS_ID, tr("CLOSE_SECTIONS"), QPixmap(), tr("CLOSE_SECTIONS_TLT"), 
171                         QKeySequence(Qt::ControlModifier|Qt::Key_W) );
172   connect(anAct, SIGNAL(triggered()), this, SLOT(onCloseSections()) );
173
174   anAct = createAction( UNCLOSE_SECTIONS_ID, tr("UNCLOSE_SECTIONS"), QPixmap(), 
175                         tr("UNCLOSE_SECTIONS_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_S) );
176   connect(anAct, SIGNAL(triggered()), this, SLOT(onUncloseSections()) );
177
178   anAct = createAction( SET_SECTIONS_POLYLINE_ID, tr("SET_SECTIONS_POLYLINE"), 
179                         aPolylinePixmap, tr("SET_POLYLINE_TLT"), 
180                         QKeySequence(Qt::ControlModifier|Qt::Key_E) );
181   connect(anAct, SIGNAL(triggered()), this, SLOT(onSetPolyline()) );
182
183   anAct = createAction( SET_SECTIONS_SPLINE_ID, tr("SET_SECTIONS_SPLINE"), aSplinePixmap, 
184                         tr("SET_SPLINE_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_R) );
185   connect(anAct, SIGNAL(triggered()), this, SLOT(onSetSpline()) );
186
187   anAct = createAction( REMOVE_ID, tr("REMOVE"), aRemovePixmap, tr("REMOVE_TLT"), 
188                         QKeySequence(Qt::ControlModifier|Qt::Key_Delete ) );
189   connect(anAct, SIGNAL(triggered()), this, SLOT(onRemove()) );
190   aTB->addAction(anAct);
191   // TODO join
192   //aTB->addSeparator();
193
194   //anAct = createAction( JOIN_ID, tr("JOIN"), aJoinPixmap, tr("JOIN_TLT"), 
195   //                      QKeySequence(Qt::ControlModifier|Qt::Key_Plus ) );
196   //connect( anAct, SIGNAL(triggered()), this, SLOT(onJoin()) );
197   //aTB->addAction(anAct);
198
199   anAct = createAction( CLEAR_ALL_ID, tr("CLEAR_ALL"), QPixmap(), tr("CLEAR_ALL_TLT"), 
200                         QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Delete ) );
201   connect( anAct, SIGNAL(triggered()), this, SLOT( onClearAll()) );
202
203   // TODO join
204   //anAct = createAction( JOIN_ALL_ID, tr("JOIN_ALL"), QPixmap(), tr("JOIN_ALL_TLT"), 
205   //                      QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Plus ) );
206   //connect( anAct, SIGNAL(triggered()), this, SLOT(onJoinAll()) );
207
208   QVBoxLayout* aSectLayout = new QVBoxLayout();
209   aSectLayout->setMargin( 5 );
210   aSectLayout->setSpacing( 5 );
211   aSectLayout->addWidget(aTB);
212   aSectLayout->addWidget(mySectionView);
213   aSectLayout->addWidget( myLocalPointView );
214   aSectionGroup->setLayout(aSectLayout);
215   QVBoxLayout* aLay = new QVBoxLayout();
216   aLay->setMargin( 0 );
217   aLay->setSpacing( 5 );
218 //    aLay->addLayout(aNameLayout);
219   aLay->addWidget(aSectionGroup);
220   setLayout(aLay);
221   onSelectionChanged();
222 }
223
224 /**
225  * Set an OCC viewer
226  */
227 void CurveCreator_Widget::setOCCViewer( OCCViewer_Viewer* theViewer )
228 {
229   if ( myOCCViewer == theViewer )
230     return;
231
232   if ( myOCCViewer ) {
233     OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
234                                                     ( myOCCViewer->getViewManager() );
235     disconnect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
236            this, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ) );
237     disconnect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
238            this, SLOT( onMouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ) );
239     disconnect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
240            this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
241     disconnect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
242            this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
243     // restore normal mode in the viewer
244     OCCViewer_Utilities::setViewer2DMode( myOCCViewer, OCCViewer_ViewWindow::No2dMode );
245     // all local contexts should be closed if the viewer is not more used
246     setLocalPointContext( false, true );
247   }
248
249   myOCCViewer = theViewer;
250   if ( myOCCViewer ) {
251     OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
252                                                     ( myOCCViewer->getViewManager() );
253     connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
254            this, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ) );
255     connect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
256            this, SLOT( onMouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ) );
257     connect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
258            this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
259     connect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
260            this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
261     OCCViewer_Utilities::setViewer2DMode( myOCCViewer, OCCViewer_ViewWindow::XYPlane );
262   }
263 }
264
265 /**
266  * Returns current OCC viewer
267  */
268 OCCViewer_Viewer* CurveCreator_Widget::getOCCViewer()
269 {
270   return myOCCViewer;
271 }
272
273 /**
274  * Set an OCC viewer
275  */
276 void CurveCreator_Widget::setOCCViewWidget( OCCViewer_ViewWidget* theViewWidget )
277 {
278   if ( myOCCViewWidget == theViewWidget )
279     return;
280
281   if ( myOCCViewWidget ) {
282     disconnect( myOCCViewWidget, SIGNAL( mousePressed( QMouseEvent* ) ),
283            this, SLOT( onMousePress( QMouseEvent* ) ) );
284     disconnect( myOCCViewWidget, SIGNAL( mouseReleased( QMouseEvent* ) ),
285            this, SLOT( onMouseRelease( QMouseEvent* ) ) );
286     disconnect( myOCCViewWidget, SIGNAL( mouseMoving( QMouseEvent* ) ),
287            this, SLOT( onMouseMove( QMouseEvent* ) ) );
288     //disconnect( myOCCViewWidget, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
289     //       this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
290
291     // restore normal mode in the viewer
292     OCCViewer_Utilities::setViewWidget2DMode( myOCCViewWidget, OCCViewer_ViewWidget::No2dMode );
293     // all local contexts should be closed if the viewer is not more used
294     setLocalPointContext( false, true );
295   }
296
297   myOCCViewWidget = theViewWidget;
298   if ( myOCCViewWidget ) {
299     connect( myOCCViewWidget, SIGNAL( mousePressed( QMouseEvent* ) ),
300            this, SLOT( onMousePress( QMouseEvent* ) ) );
301     connect( myOCCViewWidget, SIGNAL( mouseReleased( QMouseEvent* ) ),
302            this, SLOT( onMouseRelease( QMouseEvent* ) ) );
303     connect( myOCCViewWidget, SIGNAL( mouseMoving( QMouseEvent* ) ),
304            this, SLOT( onMouseMove( QMouseEvent* ) ) );
305     //connect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
306     //       this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
307     OCCViewer_Utilities::setViewWidget2DMode( myOCCViewWidget, OCCViewer_ViewWidget::XYPlane );
308   }
309 }
310
311 /**
312  * Returns current OCC viewer
313  */
314 OCCViewer_ViewWidget* CurveCreator_Widget::getOCCViewWidget()
315 {
316   return myOCCViewWidget;
317 }
318
319 /**
320  * Returns OCC viewer context
321  */
322 Handle(AIS_InteractiveContext) CurveCreator_Widget::getAISContext()
323 {
324   Handle(AIS_InteractiveContext) aContext;
325   OCCViewer_Viewer* aViewer = getOCCViewer();
326   if ( aViewer )
327     aContext = aViewer->getAISContext();
328   else if ( myOCCViewWidget )
329     aContext = myOCCViewWidget->getAISContext();
330
331   return aContext;
332 }
333
334 /**
335  * Returns OCC viewer view port
336  */
337 OCCViewer_ViewPort3d* CurveCreator_Widget::getViewPort()
338 {
339   OCCViewer_ViewPort3d* aViewPort = 0;
340   OCCViewer_Viewer* aViewer = getOCCViewer();
341   if ( aViewer )
342     aViewPort = ((OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView())->getViewPort();
343   else if ( myOCCViewWidget )
344     aViewPort = myOCCViewWidget->getViewPort();
345     
346   return aViewPort;
347 }
348
349 /**
350  * Set interaction style in the OCC viewer
351  * \param theStyle a new style
352  * \return the previous style
353  */
354 int CurveCreator_Widget::changeInteractionStyle( int theStyle )
355 {
356   OCCViewer_Viewer* aViewer = getOCCViewer();
357   if ( !aViewer )
358     return -1;
359
360   int aPrevStyle = aViewer->interactionStyle();
361   aViewer->setInteractionStyle( theStyle );
362
363   return aPrevStyle;
364 }
365
366 /**
367  * Set interaction style in the OCC viewer
368  * \param theStyle a new style
369  * \return the previous style
370  */
371 void CurveCreator_Widget::setObjectsSelected(const AIS_ListOfInteractive& theList)
372 {
373   OCCViewer_Viewer* aViewer = getOCCViewer();
374   if ( aViewer )
375     aViewer->setObjectsSelected(theList);
376   else if ( myOCCViewWidget ) {
377     Handle(AIS_InteractiveContext) aContext = myOCCViewWidget->getAISContext();
378     
379     AIS_ListIteratorOfListOfInteractive aIt;
380     for (aIt.Initialize(theList); aIt.More(); aIt.Next())
381       aContext->AddOrRemoveSelected(aIt.Value(), false);
382     aContext->UpdateCurrentViewer();
383   }
384 }
385
386 //=======================================================================
387 // function: getUniqSectionName
388 // purpose: return unique section name
389 //=======================================================================
390 std::string CurveCreator_Widget::getUniqSectionName( CurveCreator_ICurve* theCurve ) const
391 {
392   for( int i = 0 ; i < 1000000 ; i++ ){
393       char aBuffer[255];
394       sprintf( aBuffer, "Section_%d", i+1 );
395       std::string aName(aBuffer);
396       int j;
397       for( j = 0 ; j < theCurve->getNbSections() ; j++ ){
398         if( theCurve->getSectionName(j) == aName )
399             break;
400       }
401       if( j == theCurve->getNbSections() )
402           return aName;
403   }
404   return "";
405 }
406
407 void CurveCreator_Widget::setCurve( CurveCreator_ICurve* theCurve )
408 {
409   myCurve = theCurve;
410   mySectionView->setCurve(myCurve);
411   onSelectionChanged();
412   updateUndoRedo();
413 }
414
415 void CurveCreator_Widget::onSelectionChanged()
416 {
417   QList<ActionId> anEnabledAct;
418   if( myCurve ){
419     anEnabledAct << NEW_SECTION_ID << MODIFICATION_MODE_ID;
420     if ( removeEnabled() )
421       anEnabledAct << REMOVE_ID;
422     QList<int> aSelSections = mySectionView->getSelectedSections();
423     QList< QPair< int, int > > aSelPoints = mySectionView->getSelectedPoints();
424     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
425     switch( aSelType ){
426     case CurveCreator_TreeView::ST_NOSEL:{
427       break;
428     }
429     case CurveCreator_TreeView::ST_SECTIONS:{
430       /*if( aSelSections[0] > 0 ){
431         anEnabledAct << UP_ID;
432       }*/
433       if( aSelSections.size() == 1 ){
434         anEnabledAct << ADDITION_MODE_ID << DETECTION_MODE_ID;
435       }
436       switch ( getActionMode() ) {
437         case AdditionMode: {
438           mySection = -1;
439           myPointNum = -1;
440           QList<int> aSelSection = mySectionView->getSelectedSections();
441           if( aSelSection.size() > 0 ){
442             mySection = aSelSection[0];
443             myPointNum = myCurve->getNbPoints(mySection);
444           }
445         }
446         break;
447         case ModificationMode: {
448          anEnabledAct << CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID << SET_SECTIONS_SPLINE_ID;
449           int aSectCnt = myCurve->getNbSections();
450           if( aSectCnt > 0 )
451             anEnabledAct << CLEAR_ALL_ID;
452           // TODO
453           //if( aSectCnt > 1 )
454           //  anEnabledAct << JOIN_ALL_ID;
455           //if( aSelSections.size() > 1 ){
456           //  anEnabledAct << JOIN_ID;
457           //}
458         }
459         break;
460         case DetectionMode: {
461         }
462         break;
463         case NoneMode:
464         default:
465         break;
466       }
467       /*if( aSelSections[ aSelSections.size() - 1 ] < ( myCurve->getNbSections() - 1 ) ){
468         anEnabledAct << DOWN_ID;
469       }*/
470       break;
471     }
472     /*case CurveCreator_TreeView::ST_POINTS_ONE_SECTION:{
473       if( aSelPoints[0].second > 0 ){
474         anEnabledAct << UP_ID;
475       }
476       int aLastIndex = aSelPoints.size()-1;
477       int aSect = aSelPoints[0].first;
478       if( aSelPoints[aLastIndex].second < (myCurve->getNbPoints(aSect) - 1)){
479         anEnabledAct << DOWN_ID;
480       }
481       if( aSelPoints.size() == 1){
482         anEnabledAct << INSERT_POINT_BEFORE_ID << INSERT_POINT_AFTER_ID;
483       }
484       break;
485     }*/
486
487     }
488     
489     /*int aSelObjsCnt = aSelPoints.size() + aSelSections.size();
490     if( aSelObjsCnt > 0 ){
491       anEnabledAct << REMOVE_ID;
492     }
493     if( (myCurve->getNbSections() + myCurve->getNbPoints()) > 0 ){
494       anEnabledAct << REMOVE_ALL_ID;
495     }*/
496     // TODO
497     //if( myCurve->getNbSections() > 1 ){
498     //  anEnabledAct << JOIN_ALL_ID;
499     //}
500   }
501   QList<ActionId> anIds = myActionMap.keys();
502   for( int i = 0 ; i < anIds.size() ; i++ ){
503     if( myActionMap.contains(anIds[i]) ){
504       if( anEnabledAct.contains(anIds[i]) ){
505         myActionMap[anIds[i]]->setEnabled(true);
506       }
507       else{
508         myActionMap[anIds[i]]->setEnabled(false);
509       }
510     }
511   }
512   updateUndoRedo();
513   emit selectionChanged();
514 }
515
516 void CurveCreator_Widget::onAdditionMode(bool checked)
517 {
518   if (!checked)
519     return;
520
521   Handle(AIS_InteractiveContext) aContext = getAISContext();
522   if( !myCurve || !aContext )
523     return;
524
525   mySection= -1;
526   myPointNum = -1;
527   QList<int> aSelSection = mySectionView->getSelectedSections();
528   if( aSelSection.size() > 0 ){
529     mySection = aSelSection[0];
530   }
531   else{
532     QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
533     if( aSelPoints.size() > 0 ){
534       mySection = aSelPoints[0].first;
535       myPointNum = aSelPoints[0].second + 1;
536     }
537   }
538 //  emit subOperationStarted( myNewPointEditor );
539 }
540
541 void CurveCreator_Widget::onModificationMode(bool checked)
542 {
543   myLocalPointView->setVisible( checked );
544 }
545
546 void CurveCreator_Widget::onDetectionMode(bool checked)
547 {
548 }
549
550 void CurveCreator_Widget::onModeChanged(bool checked)
551 {
552   ActionMode aMode = NoneMode;
553   if (checked) {
554     QAction* anAction = (QAction*)sender();
555     switch(myActionMap.key(anAction)) {
556       case ADDITION_MODE_ID:
557         aMode = AdditionMode;
558         if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
559           myActionMap[MODIFICATION_MODE_ID]->trigger();
560         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
561           myActionMap[DETECTION_MODE_ID]->trigger();
562         break;
563       case MODIFICATION_MODE_ID:
564         aMode = ModificationMode;
565         if (myActionMap[ADDITION_MODE_ID]->isChecked())
566           myActionMap[ADDITION_MODE_ID]->trigger();
567         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
568           myActionMap[DETECTION_MODE_ID]->trigger();
569         break;
570       case DETECTION_MODE_ID:
571         aMode = DetectionMode;
572         if (myActionMap[ADDITION_MODE_ID]->isChecked())
573           myActionMap[ADDITION_MODE_ID]->trigger();
574         else if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
575           myActionMap[MODIFICATION_MODE_ID]->trigger();
576         break;
577     }
578   }
579   onSelectionChanged();
580   setLocalPointContext( aMode == ModificationMode, true );
581 }
582
583 void CurveCreator_Widget::onAddNewPoint(const CurveCreator::Coordinates& theCoords)
584 {
585   if( !myCurve )
586     return;
587   //myCurve->addPoints(theCoords, mySection, myPointNum );
588   //mySectionView->pointsAdded( mySection, myPointNum );
589   //myPointNum++;
590   QList<int> aSections = mySectionView->getSelectedSections();
591   if( aSections.size() == 0 ){
592     return;
593   }
594   int aSection = aSections[0];
595   myCurve->addPoints(theCoords, aSection); // add to the end of section
596   mySectionView->pointsAdded( aSection, myCurve->getNbPoints( aSection ) );
597   onSelectionChanged();
598   updateUndoRedo();
599 }
600
601 void CurveCreator_Widget::onNewSection()
602 {
603   if( !myCurve )
604     return;
605   myNewSectionEditor->clear();
606   myNewSectionEditor->setEditMode(false);
607   QString aSectName = QString( getUniqSectionName(myCurve).c_str() );
608   myNewSectionEditor->setSectionParameters(aSectName, true, CurveCreator::Polyline );
609   emit subOperationStarted( myNewSectionEditor );
610 }
611
612 void CurveCreator_Widget::onAddNewSection()
613 {
614   if( !myCurve )
615     return;
616   myCurve->addSection( myNewSectionEditor->getName().toStdString(), myNewSectionEditor->getSectionType(),
617                       myNewSectionEditor->isClosed() );
618   mySectionView->sectionAdded( -1 ); // add a new section to the end of list
619   QString aNewName = QString(getUniqSectionName(myCurve).c_str());
620   myNewSectionEditor->setSectionName(aNewName);
621   onSelectionChanged();
622   updateUndoRedo();
623   onCancelSection();
624 }
625
626 void CurveCreator_Widget::onCancelSection()
627 {
628   emit subOperationFinished( myNewSectionEditor );
629 }
630
631 QAction* CurveCreator_Widget::createAction( ActionId theId, const QString& theName, const QPixmap& theImage,
632                                             const QString& theToolTip, const QKeySequence& theShortcut )
633 {
634   QAction* anAct = new QAction(theName,this);
635   if( !theImage.isNull() ){
636     anAct->setIcon(theImage);
637   }
638   anAct->setShortcut(theShortcut);
639   anAct->setToolTip(theToolTip);
640   myActionMap[theId] = anAct;
641   return anAct;
642 }
643
644 QAction* CurveCreator_Widget::getAction(ActionId theId)
645 {
646   if( myActionMap.contains(theId) )
647     return myActionMap[theId];
648   return NULL;
649 }
650
651 CurveCreator_Widget::ActionMode CurveCreator_Widget::getActionMode() const
652 {
653   ActionMode aMode = NoneMode;
654
655   if ( myActionMap[ADDITION_MODE_ID]->isChecked() )
656     aMode = AdditionMode;
657   else if ( myActionMap[MODIFICATION_MODE_ID]->isChecked() )
658     aMode = ModificationMode;
659   else if ( myActionMap[DETECTION_MODE_ID]->isChecked() )
660     aMode = DetectionMode;
661
662   return aMode;
663 }
664
665 void CurveCreator_Widget::onEditSection( int theSection )
666 {
667   if( !myCurve )
668     return;
669   mySection = theSection;
670   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
671   bool isClosed = myCurve->isClosed(theSection);
672   CurveCreator::SectionType aType = myCurve->getSectionType(theSection);
673   myNewSectionEditor->setEditMode(true);
674   myNewSectionEditor->setSectionParameters( aSectName, isClosed, aType );
675
676   emit subOperationStarted( myNewSectionEditor );
677 }
678
679 void CurveCreator_Widget::onModifySection()
680 {
681   if( !myCurve )
682     return;
683   QString aName = myNewSectionEditor->getName();
684   bool isClosed = myNewSectionEditor->isClosed();
685   CurveCreator::SectionType aSectType = myNewSectionEditor->getSectionType();
686 //  myCurve->startOperation();
687   if( myCurve->getSectionName(mySection) != aName.toStdString() )
688     myCurve->setSectionName( mySection , aName.toStdString() );
689
690   if( myCurve->getSectionType(mySection) != aSectType )
691     myCurve->setSectionType( mySection, aSectType );
692
693   if( myCurve->isClosed(mySection) != isClosed )
694     myCurve->setClosed( mySection, isClosed );
695 //  myCurve->finishOperation();
696   mySectionView->sectionChanged(mySection);
697   updateUndoRedo();
698   onCancelSection();
699 }
700
701 /*void CurveCreator_Widget::onEditPoint( int theSection, int thePoint )
702 {
703   if( !myNewPointEditor || !myEdit )
704     return;
705   mySection = theSection;
706   myPointNum = thePoint;
707   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
708   myNewPointEditor->setEditMode(true);
709   myNewPointEditor->setSectionName(aSectName);
710   myNewPointEditor->setDimension( myCurve->getDimension() );
711   CurveCreator::Coordinates aCoords = myCurve->getCoordinates(theSection,thePoint);
712   myNewPointEditor->setCoordinates(aCoords);
713   emit subOperationStarted( myNewPointEditor );
714 }
715
716 void CurveCreator_Widget::onModifyPoint()
717 {
718   if( !myEdit )
719     return;
720   CurveCreator::Coordinates aCoords = myNewPointEditor->getCoordinates();
721   myEdit->setCoordinates( aCoords, mySection, myPointNum );
722   mySectionView->pointDataChanged( mySection, myPointNum );
723   updateUndoRedo();
724   onCancelPoint();
725 }*/
726
727 void CurveCreator_Widget::onJoin()
728 {
729   if( !myCurve )
730     return;
731   QList<int> aSections = mySectionView->getSelectedSections();
732   if( aSections.size() == 0 ){
733     return;
734   }
735   int aMainSect = aSections[0];
736   int aMainSectSize = myCurve->getNbPoints(aMainSect);
737 //  myCurve->startOperation();
738   for( int i = 1 ; i < aSections.size() ; i++ ){
739     int aSectNum = aSections[i] - (i-1);
740     myCurve->join( aMainSect, aSectNum );
741     mySectionView->sectionsRemoved( aSectNum );
742   }
743 //  myCurve->finishOperation();
744   int aNewSectSize = myCurve->getNbPoints(aMainSect);
745   if( aNewSectSize != aMainSectSize )
746     mySectionView->pointsAdded( aMainSect, aMainSectSize, aNewSectSize-aMainSectSize );
747   updateUndoRedo();
748 }
749
750 void CurveCreator_Widget::onRemove()
751 {
752   if( !myCurve )
753     return;
754
755   switch( getActionMode() ) {
756     case NoneMode:
757       removeSection();
758     break;
759     case ModificationMode:
760       removePoint();
761     break;
762     default:
763       break;
764   }
765 }
766
767 void CurveCreator_Widget::onClearAll()
768 {
769   if( !myCurve )
770     return;
771   myCurve->clear();
772   mySectionView->reset();
773   onSelectionChanged();
774   updateUndoRedo();
775 }
776
777 void CurveCreator_Widget::onJoinAll()
778 {
779   if( !myCurve )
780     return;
781   myCurve->join();
782   mySectionView->reset();
783   onSelectionChanged();
784   updateUndoRedo();
785 }
786
787 void CurveCreator_Widget::onUndoSettings()
788 {
789
790 }
791
792 void CurveCreator_Widget::onSetSpline()
793 {
794   if( !myCurve )
795     return;
796   QList<int> aSelSections = mySectionView->getSelectedSections();
797 //  myCurve->startOperation();
798   for( int i = 0 ; i < aSelSections.size() ; i++ ){
799     myCurve->setSectionType(aSelSections[i], CurveCreator::Spline );
800     mySectionView->sectionChanged(aSelSections[i]);
801   }
802 //  myCurve->finishOperation();
803   updateUndoRedo();
804 }
805
806 void CurveCreator_Widget::onSetPolyline()
807 {
808   if( !myCurve )
809     return;
810 //  myCurve->startOperation();
811   QList<int> aSelSections = mySectionView->getSelectedSections();
812   for( int i = 0 ; i < aSelSections.size() ; i++ ){
813     myCurve->setSectionType( aSelSections[i], CurveCreator::Polyline );
814     mySectionView->sectionChanged( aSelSections[i] );
815   }
816 //  myCurve->finishOperation();
817   updateUndoRedo();
818 }
819
820 void CurveCreator_Widget::onCloseSections()
821 {
822   if( !myCurve )
823     return;
824 //  myCurve->startOperation();
825   QList<int> aSelSections = mySectionView->getSelectedSections();
826   for( int i = 0 ; i < aSelSections.size() ; i++ ){
827     myCurve->setClosed(aSelSections[i], true);
828     mySectionView->sectionChanged(aSelSections[i]);
829   }
830 //  myCurve->finishOperation();
831   updateUndoRedo();
832 }
833
834 void CurveCreator_Widget::onUncloseSections()
835 {
836   if( !myCurve )
837     return;
838 //  myCurve->startOperation();
839   QList<int> aSelSections = mySectionView->getSelectedSections();
840   for( int i = 0 ; i < aSelSections.size() ; i++ ){
841     myCurve->setClosed(aSelSections[i], false);
842     mySectionView->sectionChanged(aSelSections[i]);
843   }
844 //  myCurve->finishOperation();
845   updateUndoRedo();
846 }
847
848 void CurveCreator_Widget::onUndo()
849 {
850     if( !myCurve )
851       return;
852
853     CurveCreator_Widget::SectionToPointList aPoints;
854     startCurveModification( aPoints, false );
855     myCurve->undo();
856     finishCurveModification();
857     mySectionView->reset();
858 }
859
860 void CurveCreator_Widget::onRedo()
861 {
862     if( !myCurve )
863       return;
864     CurveCreator_Widget::SectionToPointList aPoints;
865     startCurveModification( aPoints, false );
866     myCurve->redo();
867     finishCurveModification();
868     mySectionView->reset();
869 }
870
871 void CurveCreator_Widget::updateUndoRedo()
872 {
873   if( !myCurve )
874     return;
875   QAction* anAct = myActionMap[UNDO_ID];
876   if( anAct != 0 ){
877     if( myCurve->getNbUndo() != 0 ){
878       anAct->setEnabled(true);
879     }
880     else{
881       anAct->setDisabled(true);
882     }
883   }
884   anAct = myActionMap[REDO_ID];
885   if( anAct != 0 ){
886     if( myCurve->getNbRedo() != 0 ){
887       anAct->setEnabled(true);
888     }
889     else{
890       anAct->setDisabled(true);
891     }
892   }
893 }
894
895 void CurveCreator_Widget::onContextMenu( QPoint thePoint )
896 {
897   QList<ActionId> aContextActions;
898   aContextActions << CLEAR_ALL_ID << JOIN_ALL_ID << SEPARATOR_ID <<
899                      CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID <<
900                      SET_SECTIONS_SPLINE_ID;
901   QPoint aGlPoint = mySectionView->mapToGlobal(thePoint);
902   bool isVis = false;
903   QList<ActionId> aResAct;
904   for( int i = 0 ; i < aContextActions.size() ; i++ ){
905     if( aContextActions[i] != SEPARATOR_ID ){
906       if( myActionMap.contains(aContextActions[i]) ){
907         QAction* anAct = myActionMap[aContextActions[i]];
908         if( anAct->isEnabled() ){
909           aResAct << aContextActions[i];
910           isVis = true;
911         }
912       }
913     }
914     else{
915       aResAct << SEPARATOR_ID;
916     }
917   }
918   if( !isVis )
919     return;
920
921   QMenu* aMenu = new QMenu(this);
922   for( int i = 0 ; i < aResAct.size() ; i++ ){
923     if( aResAct[i] == SEPARATOR_ID ){
924       aMenu->addSeparator();
925     }
926     else{
927       QAction* anAct = myActionMap[aResAct[i]];
928       aMenu->insertAction(NULL, anAct);
929     }
930   }
931   aMenu->exec(aGlPoint);
932 }
933
934 QList<int> CurveCreator_Widget::getSelectedSections()
935 {
936   return mySectionView->getSelectedSections();
937 }
938
939 QList< QPair< int, int > > CurveCreator_Widget::getSelectedPoints()
940 {
941   return mySectionView->getSelectedPoints();
942 }
943
944 /**
945  * According to the widget state, performs the remove action
946  */
947 void CurveCreator_Widget::removeSelected()
948 {
949   onRemove();
950 }
951
952 /**
953  * Checks whether there are some selection to be removed
954  */
955 bool CurveCreator_Widget::removeEnabled()
956 {
957   bool isEnabled = getActionMode() == ModificationMode;
958   if ( !isEnabled ) {
959     QList<int> aSelSections = mySectionView->getSelectedSections();
960     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
961     isEnabled = aSelType == CurveCreator_TreeView::ST_SECTIONS &&
962                 aSelSections.size() == 1;
963   }
964   return isEnabled;
965 }
966
967
968 //=================================================================================
969 // function : GeometryGUI::onGetCoordsByClick()
970 // purpose  : Manage mouse press events in Additon mode
971 //=================================================================================
972 void CurveCreator_Widget::onGetCoordsByClick( QMouseEvent* pe )
973 {
974   if (pe->button() != Qt::LeftButton)
975     return;
976
977   if ( pe->modifiers() != Qt::ControlModifier ) {
978     Handle(AIS_InteractiveContext) ic = getAISContext();
979     if ( !ic )
980       return;
981
982     gp_Pnt aPnt;    
983
984     ic->InitSelected();
985     if ( pe->modifiers() == Qt::ShiftModifier )
986       ic->ShiftSelect();  // Append selection
987     else
988       ic->Select();       // New selection
989
990     /*TopoDS_Shape aShape;
991
992     ic->InitSelected();
993     if ( ic->MoreSelected() )
994       aShape = ic->SelectedShape();
995
996     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
997       aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
998     else*/
999     {
1000       OCCViewer_ViewPort3d* vp = getViewPort();
1001       aPnt = CurveCreator_Utils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
1002     }
1003     // set the coordinates into dialog
1004     CurveCreator::Coordinates aCoords;
1005     aCoords.push_back( aPnt.X() );
1006     aCoords.push_back( aPnt.Y() );
1007     if ( myCurve->getDimension() == 3 ) {
1008       aCoords.push_back( aPnt.Z() );
1009     }
1010     onAddNewPoint(aCoords);
1011 //    myNewPointEditor->setCoordinates( aCoords );
1012   }
1013 }
1014
1015 /**
1016  * Manage mouse press events
1017  * \param theWindow an owner of the signal
1018  * \param theEvent a mouse event
1019  */
1020 void CurveCreator_Widget::onMousePress( SUIT_ViewWindow*, QMouseEvent* theEvent )
1021 {
1022   if ( theEvent->button() != Qt::LeftButton )
1023     return;
1024
1025   switch( getActionMode() ) {
1026     case ModificationMode: {
1027       //store initial cursor position for Drag&Drop
1028       setDragStarted( true, theEvent->pos() );
1029       break;
1030     }
1031     case AdditionMode: {
1032       onGetCoordsByClick( theEvent );
1033       break;
1034     }
1035     default:
1036       break;
1037   }
1038 }
1039
1040 /**
1041  * Manage mouse release events in Modification mode
1042  * \param theWindow an owner of the signal
1043  * \param theEvent a mouse event
1044  */
1045 void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow*, QMouseEvent* theEvent )
1046 {
1047   if ( getActionMode() != ModificationMode )
1048     return;
1049
1050   if ( myDragStarted ) {
1051     if ( myDragged ) // if the drag of some points has happened, restore the drag selection
1052       setSelectedPonts( myDragPoints );
1053     setDragStarted( false );
1054   }
1055   else // check whether the segment is clicked an a new point should be added to the segment
1056     insertPointToSelectedSegment( theEvent->pos().x(), theEvent->pos().y() );
1057
1058   // updates the input panel table to show the selected point coordinates
1059   updateLocalPointView();
1060 }
1061
1062 /**
1063  * Manage mouse move events in Modification mode
1064  * \param theWindow an owner of the signal
1065  * \param theEvent a mouse event
1066  */
1067 void CurveCreator_Widget::onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent )
1068 {
1069   if ( getActionMode() != ModificationMode || !myDragStarted )
1070     return;
1071
1072   QPoint aPos = theEvent->pos();
1073   if ( (aPos - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
1074     return;
1075
1076   moveSelectedPoints( aPos.x(), aPos.y() );
1077   myDragStartPosition = aPos;
1078 }
1079
1080 /**
1081  * Set zero viewer by the last view closed in
1082  * \param theManager a viewer manager
1083  */
1084 void CurveCreator_Widget::onLastViewClosed( SUIT_ViewManager* theManager )
1085 {
1086   myOCCViewer = 0;
1087 }
1088
1089 void CurveCreator_Widget::onMousePress( QMouseEvent* theEvent )
1090 {
1091   onMousePress( 0, theEvent );
1092 }
1093
1094 void CurveCreator_Widget::onMouseRelease( QMouseEvent* theEvent )
1095 {
1096   onMouseRelease( 0, theEvent );
1097 }
1098
1099 void CurveCreator_Widget::onMouseMove( QMouseEvent* theEvent )
1100 {
1101   onMouseMove( 0, theEvent );
1102 }
1103
1104 void CurveCreator_Widget::onCellChanged( int theRow, int theColumn )
1105 {
1106   int aCurrSect = getSectionId( theRow );
1107   int aPntIndex = getPointId( theRow );
1108
1109   if ( aPntIndex < 0 )
1110     return;
1111
1112   SectionToPointList aSelPoints;
1113   startCurveModification( aSelPoints );
1114
1115   double aX  = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
1116   double anY = myLocalPointView->item( theRow, 3 )->data( Qt::UserRole ).toDouble();
1117   std::deque<float> aChangedPos;
1118   aChangedPos.push_back( aX );
1119   aChangedPos.push_back( anY );
1120   myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
1121
1122   finishCurveModification( aSelPoints );
1123 }
1124
1125 /**
1126  * Removes a selected section from the curve. Updates undo/redo status
1127  */
1128 void CurveCreator_Widget::removeSection()
1129 {
1130   QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
1131   int aCurrSect=-1;
1132   int aRemoveCnt = 0;
1133 //  myCurve->startOperation();
1134   for( int i = 0 ; i < aSelPoints.size() ; i++ ){
1135     if( aCurrSect != aSelPoints[i].first ){
1136       aRemoveCnt = 0;
1137       aCurrSect = aSelPoints[i].first;
1138     }
1139     int aPntIndx = aSelPoints[i].second - aRemoveCnt;
1140     myCurve->removePoint( aCurrSect, aPntIndx );
1141     mySectionView->pointsRemoved( aCurrSect, aPntIndx );
1142     aRemoveCnt++;
1143   }
1144   QList<int> aSections = mySectionView->getSelectedSections();
1145   for( int i = 0 ; i < aSections.size() ; i++ ){
1146     int aSectNum = aSections[i] - (i);
1147     myCurve->removeSection( aSectNum );
1148     mySectionView->sectionsRemoved( aSectNum );
1149   }
1150 //  myCurve->finishOperation();
1151   mySectionView->clearSelection();
1152   updateUndoRedo();
1153 }
1154
1155 /**
1156  * Removes a selected points from the curve. Updates undo/redo status
1157  */
1158 void CurveCreator_Widget::removePoint()
1159 {
1160   SectionToPointList aPoints;
1161   getSelectedPonts( aPoints );
1162   if ( aPoints.size() == 0 )
1163     return;
1164
1165   SectionToPointList aSelPoints;
1166   startCurveModification( aSelPoints, false );
1167
1168   myCurve->removeSeveralPoints( aPoints );
1169   finishCurveModification( SectionToPointList() );
1170 }
1171
1172 void CurveCreator_Widget::insertPointToSelectedSegment( const int theX,
1173                                                         const int theY )
1174 {
1175   Handle(AIS_InteractiveContext) aContext = getAISContext();
1176   if ( !aContext )
1177     return;
1178   gp_Pnt aPoint;
1179   gp_Pnt aPoint1, aPoint2;
1180   bool isFoundPoint = false;
1181
1182   for ( aContext->InitSelected(); aContext->MoreSelected() && !isFoundPoint;
1183         aContext->NextSelected() ) {
1184     TopoDS_Shape aTShape = aContext->SelectedShape();
1185     if ( !aTShape.IsNull() && aTShape.ShapeType() == TopAbs_VERTEX )
1186       continue;
1187     else {
1188       Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
1189       if ( anOwner.IsNull() )
1190         continue;
1191       const TopLoc_Location& aLocation = anOwner->Location();
1192       Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
1193       isFoundPoint = pointOnObject( anAIS, theX, theY, aPoint, aPoint1, aPoint2 );
1194     }
1195   }
1196   if ( !isFoundPoint )
1197     return;
1198
1199   // insert the point to the model curve
1200   SectionToPointList aSelPoints;
1201   startCurveModification( aSelPoints );
1202
1203   CurveCreator::Coordinates aCoords;
1204   aCoords.push_back( aPoint.X() );
1205   aCoords.push_back( aPoint.Y() );
1206
1207   SectionToPointList aPoints1, aPoints2;
1208   findSectionsToPoints( aPoint1.X(), aPoint1.Y(), aPoints1 );
1209   findSectionsToPoints( aPoint2.X(), aPoint2.Y(), aPoints2 );
1210   SectionToPointList::const_iterator anIt = aPoints1.begin(), aLast = aPoints1.end();
1211   int aSectionId = -1;
1212   // there can be a case when a new point is added into two sections
1213   int aPoint1Id = -1, aPoint2Id = -1;
1214   for ( ; anIt != aLast && aSectionId < 0; anIt++ ) {
1215     int aSectionCur = anIt->first;
1216     SectionToPointList::const_iterator anIt2 = aPoints2.begin(), aLast2 = aPoints2.end();
1217     for ( ; anIt2 != aLast2 && aSectionId < 0; anIt2++ ) {
1218       if ( anIt2->first == aSectionCur ) {
1219         aSectionId = aSectionCur;
1220         aPoint1Id = anIt->second;
1221         aPoint2Id = anIt2->second;
1222       }
1223     }
1224   }
1225
1226   int anInsertPos = -1;
1227   int aLastPoint = myCurve->getNbPoints( aSectionId )-1; 
1228   if ( ( aPoint1Id == aLastPoint && aPoint2Id == 0 ) ||
1229        ( aPoint2Id == aLastPoint && aPoint1Id == 0 ) )
1230     anInsertPos = -1; // if the section happens between first and last points
1231   else
1232     anInsertPos = aPoint1Id < aPoint2Id ? aPoint1Id + 1 : aPoint2Id + 1;
1233
1234   myCurve->addPoints( aCoords, aSectionId, anInsertPos );
1235   mySectionView->pointsAdded( aSectionId, myCurve->getNbPoints( aSectionId ) );
1236
1237   finishCurveModification( aSelPoints );
1238
1239   setSelectedPonts();
1240 }
1241
1242 void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
1243                                               const int theYPosition )
1244 {
1245   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1246   if ( !aViewPort )
1247     return;
1248
1249   SectionToPointList aPoints;
1250   startCurveModification( aPoints, false );
1251
1252   gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(),
1253                                                               myDragStartPosition.y(),
1254                                                               aViewPort->getView() );
1255   gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( theXPosition, theYPosition,
1256                                                              aViewPort->getView() );
1257   double aXDelta = aStartPnt.X() - anEndPnt.X();
1258   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
1259
1260   CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
1261   std::deque<float> aChangedPos;
1262   SectionToPointList::const_iterator anIt = myDragPoints.begin(), aLast = myDragPoints.end();
1263   for ( ; anIt != aLast; anIt++ ) {
1264     int aSectionId = anIt->first;
1265     int aPointId = anIt->second;
1266     aChangedPos = myCurve->getPoint( aSectionId, aPointId );
1267     if ( aChangedPos.size() < 2 )
1268       continue;
1269     aChangedPos[0] = aChangedPos[0] - aXDelta;
1270     aChangedPos[1] = aChangedPos[1] - anYDelta;
1271     
1272     aCoordList.push_back(
1273       std::make_pair(std::make_pair( aSectionId, aPointId ), 
1274                      aChangedPos ));
1275   }
1276   myCurve->setSeveralPoints( aCoordList );
1277
1278   myDragged = true;
1279   finishCurveModification( myDragPoints );
1280 }
1281
1282 void CurveCreator_Widget::updateLocalPointView()
1283 {
1284   Handle(AIS_InteractiveContext) aContext = getAISContext();
1285   if ( !aContext )
1286     return;
1287
1288   bool isBlocked = myLocalPointView->blockSignals(true);
1289   gp_Pnt aPnt;
1290   myLocalPointView->setRowCount( 0 );
1291   for ( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) {
1292     TopoDS_Vertex aVertex;
1293     TopoDS_Shape aShape = aContext->SelectedShape();
1294     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
1295       aVertex = TopoDS::Vertex( aContext->SelectedShape() );
1296     else {
1297       Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
1298       if ( !anOwner.IsNull() ) {
1299         Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
1300         if ( !anAIS.IsNull() ) {
1301           Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast( anAIS);
1302           if ( !aPoint.IsNull() )
1303             aVertex = TopoDS::Vertex( aPoint->Vertex() );
1304         }
1305         if ( aVertex.IsNull() ) {
1306           // the following happens if there are no points in the current curve, there is only a shape
1307           /*Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
1308           if ( aBrepOwner.IsNull() )
1309             continue;
1310           if ( aBrepOwner->HasShape() ) {
1311             const TopoDS_Shape& aShape = aBrepOwner->Shape();
1312             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
1313             {
1314               aVertex = TopoDS::Vertex( aShape );
1315             }
1316           }*/
1317         }
1318       }
1319       if ( aVertex.IsNull() )
1320         continue;
1321       aPnt = BRep_Tool::Pnt( aVertex );
1322       addLocalPointToTable( aPnt.X(), aPnt.Y() );
1323     }
1324   }
1325   myLocalPointView->blockSignals(isBlocked);
1326 }
1327
1328 /**
1329  * 
1330  */
1331 void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable )
1332 {
1333   Handle(AIS_InteractiveContext) ic = getAISContext();
1334   if ( !ic )
1335     return;
1336
1337   if ( theOpen ) {
1338     // Open local context if there is no one
1339     if ( !ic->HasOpenedContext() ) {
1340       ic->ClearCurrents( false );
1341       ic->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ );
1342     }
1343     AIS_ListOfInteractive aList;
1344     ic->DisplayedObjects( aList );
1345     int aLSize = 0;
1346     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
1347       aLSize++;
1348
1349     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
1350     {
1351       Handle(AIS_InteractiveObject) anAIS = it.Value();
1352       if ( !anAIS.IsNull() )
1353       {
1354         if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
1355         {
1356           ic->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ );
1357           ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_WIRE ) );
1358         }
1359         else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
1360         {
1361           ic->Load( anAIS, -1/*selection mode*/, false/*allow decomposition*/ );
1362           ic->Activate( anAIS, TopAbs_VERTEX );
1363         }
1364       }
1365       continue;
1366     }
1367   }
1368   else {
1369     if ( ic->HasOpenedContext() )
1370       ic->CloseAllContexts();
1371     if ( isUpdateTable )
1372       updateLocalPointView();
1373   }
1374 }
1375
1376 void CurveCreator_Widget::addLocalPointToTable( const double theX, const double theY )
1377 {
1378   SectionToPointList aPoints;
1379   findSectionsToPoints( theX, theY, aPoints );
1380
1381   SectionToPointList aSkipList;
1382   // table could not contain two equal value rows
1383   int aRowId = myLocalPointView->rowCount();
1384   double aCurrentX, aCurrentY;
1385   int aSectionId, aPointId;
1386   SectionToPoint aPoint;
1387   for ( int i = 0; i < aRowId; i++ ) {
1388     aCurrentX = myLocalPointView->item( i, 2 )->data( Qt::UserRole ).toDouble();
1389     aCurrentY = myLocalPointView->item( i, 3 )->data( Qt::UserRole ).toDouble();
1390     if ( fabs( aCurrentX - theX ) < LOCAL_SELECTION_TOLERANCE &&
1391          fabs( aCurrentY - theY ) < LOCAL_SELECTION_TOLERANCE ) {
1392            aPoint = std::make_pair<int, int>( getSectionId( i ), getPointId( i ) );
1393       if ( !contains( aSkipList, aPoint ) )
1394         aSkipList.push_back( aPoint );
1395     }
1396   }
1397   if ( aSkipList.size() == aPoints.size() )
1398     return;
1399
1400   QTableWidgetItem* anItem;
1401   SectionToPointList::const_iterator anIt = aPoints.begin(), aLast = aPoints.end();
1402   for ( ; anIt != aLast; anIt++ ) {
1403     aPoint = *anIt;
1404     if ( contains( aSkipList, aPoint ) )
1405       continue;
1406
1407     myLocalPointView->setRowCount( aRowId+1 );
1408     aSectionId = aPoint.first;
1409     aPointId = aPoint.second;
1410
1411     anItem = new QTableWidgetItem( myCurve->getSectionName( aSectionId ).c_str() );
1412     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
1413     anItem->setData( Qt::UserRole, aSectionId );
1414     myLocalPointView->setItem( aRowId, 0, anItem );
1415
1416     anItem = new QTableWidgetItem( QString::number( aPointId + 1 ) );
1417     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
1418     anItem->setData( Qt::UserRole, aPointId );
1419     myLocalPointView->setItem( aRowId, 1, anItem );
1420
1421     anItem = new QTableWidgetItem( QString::number( theX ) );
1422     anItem->setData( Qt::UserRole, theX );
1423     myLocalPointView->setItem( aRowId, 2, anItem );
1424
1425     anItem = new QTableWidgetItem( QString::number( theY ) );
1426     anItem->setData( Qt::UserRole, theY );
1427     myLocalPointView->setItem( aRowId, 3, anItem );
1428   }
1429 }
1430
1431 /**
1432  * Set drag operation started. Save the position and a list of dragged points
1433  * \param theState the drag operation state: started/finished
1434  * \param thePoint the start drag position
1435  */
1436 void CurveCreator_Widget::setDragStarted( const bool theState, const QPoint& thePoint )
1437 {
1438   if ( theState ) {
1439     getSelectedPonts( myDragPoints );
1440     myDragStarted = myDragPoints.size();
1441     myDragStartPosition = thePoint;
1442     if ( myDragStarted ) {
1443       // change a viewer interaction style in order to avoid a select rectangle build
1444       myDragInteractionStyle = changeInteractionStyle( SUIT_ViewModel::KEY_FREE );
1445     }
1446   }
1447   else {
1448     if ( myDragStarted )
1449       changeInteractionStyle( myDragInteractionStyle );
1450     myDragStarted = false;
1451     myDragPoints.clear();
1452   }
1453   myDragged = false;
1454 }
1455
1456 void CurveCreator_Widget::getSelectedPonts( CurveCreator_Widget::SectionToPointList& thePoints )
1457 {
1458   thePoints.clear();
1459   for ( int i = 0, aNb = myLocalPointView->rowCount(); i < aNb; i++ )
1460     thePoints.push_back( std::make_pair( getSectionId( i ), getPointId( i ) ) );
1461 }
1462
1463 void CurveCreator_Widget::setSelectedPonts( const CurveCreator_Widget::SectionToPointList& thePoints )
1464 {
1465   Handle(AIS_InteractiveContext) ic = getAISContext();
1466   if ( !ic || !ic->HasOpenedContext() )
1467     return;
1468
1469   AIS_ListOfInteractive aListToSelect;
1470   AIS_ListOfInteractive aDisplayedList;
1471   ic->DisplayedObjects( aDisplayedList );
1472
1473   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
1474   SectionToPoint aSToPoint;
1475   for( ; anIt != aLast; anIt++ ) {
1476     aSToPoint = *anIt;
1477
1478     for ( AIS_ListIteratorOfListOfInteractive it( aDisplayedList ); it.More(); it.Next() )
1479     {
1480       Handle(AIS_InteractiveObject) anAIS = it.Value();
1481       if ( anAIS.IsNull() )
1482         continue;
1483       Handle(AIS_Point) anAISPoint = Handle(AIS_Point)::DownCast( anAIS );
1484       if ( anAISPoint.IsNull() )
1485         continue;
1486
1487       TopoDS_Vertex aVertex = TopoDS::Vertex( anAISPoint->Vertex() );
1488
1489       if ( aVertex.IsNull() )
1490         continue;
1491
1492       gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
1493
1494       SectionToPointList aPoints;
1495       findSectionsToPoints( aPnt.X(), aPnt.Y(), aPoints );
1496
1497       SectionToPointList::const_iterator anIt = aPoints.begin(), aLast = aPoints.end();
1498       SectionToPoint aPoint;
1499       for ( ; anIt != aLast; anIt++ ) {
1500         aPoint = *anIt;
1501         if ( aPoint.first == aSToPoint.first && aPoint.second == aSToPoint.second )
1502           aListToSelect.Append( anAIS );
1503       }
1504     }
1505   }
1506
1507   ic->ClearSelected( Standard_False );
1508   setObjectsSelected( aListToSelect );
1509   updateLocalPointView();
1510 }
1511
1512 /**
1513  * Get viewer information before perform the curve modification.
1514  * Take a list of selected cuve points an close local context.
1515  * The context should be closed because the curve presentation is
1516  * redisplayed and if it is not closed, when we close the local context
1517  * later, the presentation shown in the local context is disappeared.
1518  * \param thePoints an output list of curve selected points
1519  * \param theFillPoints a flag whether the selection list should be filled
1520  */
1521 void CurveCreator_Widget::startCurveModification(
1522                            CurveCreator_Widget::SectionToPointList& thePoints,
1523                            const bool theFillPoints )
1524 {
1525   if ( theFillPoints ) {
1526     thePoints.clear();
1527     getSelectedPonts( thePoints );
1528   }
1529   setLocalPointContext( false );
1530 }
1531
1532 /**
1533  * Restore the viewer state after the curve modification is done.
1534  * Open local context and select given points inside it.
1535  * \param thePoints a list of curve selected points
1536  */
1537 void CurveCreator_Widget::finishCurveModification(
1538                            const CurveCreator_Widget::SectionToPointList& thePoints )
1539 {
1540   if ( getActionMode() == ModificationMode )
1541     setLocalPointContext( true );
1542   setSelectedPonts( thePoints );
1543   updateUndoRedo();
1544 }
1545
1546 /**
1547  * Returns a point index in the model curve by the point coordinates in the viewer
1548  * \param theX the X coordinate of the point
1549  * \param theY the Y coordinate of the point
1550  */
1551 int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
1552 {
1553   int aPntIndex = -1;
1554
1555   CurveCreator::Coordinates aCoords;
1556   for ( int i = 0, aNb = myCurve->getNbPoints( theSectionId ); i < aNb && aPntIndex < 0; i++ ) {
1557     aCoords = myCurve->getPoint( theSectionId, i );
1558     if ( aCoords.size() < 2 )
1559       continue;
1560     if ( fabs( aCoords[0] - theX ) < LOCAL_SELECTION_TOLERANCE &&
1561          fabs( aCoords[1] - theY ) < LOCAL_SELECTION_TOLERANCE )
1562       aPntIndex = i;
1563   }
1564
1565   return aPntIndex;
1566 }
1567
1568 void CurveCreator_Widget::findSectionsToPoints( const double theX, const double theY,
1569                                  CurveCreator_Widget::SectionToPointList& thePoints )
1570 {
1571   thePoints.clear();
1572
1573   int aPointId = -1;
1574   for ( int i = 0, aNb = myCurve->getNbSections(); i < aNb; i++ ) {
1575     aPointId = findLocalPointIndex( i, theX, theY );
1576     if ( aPointId < 0 )
1577       continue;
1578     SectionToPoint aPoint = std::make_pair( i, aPointId );
1579     if ( !contains( thePoints, aPoint ) )
1580       thePoints.push_back( aPoint );
1581   }
1582 }
1583
1584 void CurveCreator_Widget::convert( const SectionToPointList& thePoints,
1585                                    QMap<int, QList<int> >& theConvPoints )
1586 {
1587   theConvPoints.clear();
1588
1589   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
1590   QList<int> aPoints;
1591   int aSectionId, aPointId;
1592   for ( ; anIt != aLast; anIt++ ) {
1593     aSectionId = anIt->first;
1594     aPointId = anIt->second;
1595     aPoints.clear();
1596     if ( theConvPoints.contains( aSectionId ) )
1597       aPoints = theConvPoints[aSectionId];
1598     if ( aPoints.contains( aPointId ) )
1599       continue;
1600     aPoints.append( aPointId );
1601     theConvPoints[aSectionId] = aPoints;
1602   }
1603 }
1604
1605 /**
1606  * Checks whether the point belongs to the OCC object
1607  * \param theObject a line or shape with a bspline inside
1608  * \param theX the X coordinate in the view.
1609  * \param theY the Y coordinate in the view.
1610  * \param thePoint the output point to be append to the model curve
1611  * \param thePoint1 the output point to bound the line where a new point should be inserted
1612  * \param thePoint2 the output point to bound the line where a new point should be inserted
1613  */
1614 bool CurveCreator_Widget::pointOnObject( Handle(AIS_InteractiveObject) theObject,
1615                                          const int theX, const int theY,
1616                                          gp_Pnt& thePoint,
1617                                          gp_Pnt& thePoint1, gp_Pnt& thePoint2 )
1618 {
1619   bool isFound = false;
1620
1621   Handle(AIS_InteractiveContext) aContext = getAISContext();
1622   if ( theObject.IsNull() || !aContext )
1623     return isFound;
1624
1625   gp_Pnt aPoint;
1626   Standard_Real aParameter;
1627   gp_Pnt aPnt1, aPnt2;
1628   Handle(AIS_Line) aLine = Handle(AIS_Line)::DownCast( theObject );
1629   if ( !aLine.IsNull() ) {
1630     const Handle(Geom_Line) aGLine = aLine->Line();
1631     isFound = hasProjectPointOnCurve( theX, theY, aGLine, aParameter );
1632     if ( isFound ) {
1633       aPoint = aGLine->Value( aParameter );
1634
1635       Handle(Geom_Point) aPStart;
1636       Handle(Geom_Point) aPEnd;
1637       aLine->Points( aPStart, aPEnd );
1638       aPnt1 = aPStart->Pnt();
1639       aPnt2 = aPEnd->Pnt();
1640
1641       // in case of Geom line a projection is performed to the infinite line,
1642       // so it is necessary to bound it by the line size
1643       Bnd_Box aLineBox;
1644       aLineBox.Set( aPnt1, gp_Vec( aPnt1, aPnt2 ) );
1645       isFound = !aLineBox.IsOut( aPoint );
1646     }
1647   }
1648   else {
1649     Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject );
1650     if ( !aShape.IsNull() ) {
1651       const TopoDS_Wire& aWire = TopoDS::Wire( aShape->Shape() );
1652       if ( !aWire.IsNull() ) {
1653         TopExp_Explorer anExp( aWire, TopAbs_EDGE );
1654         for ( ; anExp.More(); anExp.Next())
1655         {
1656           const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
1657           if ( !anEdge.IsNull() ) {
1658             Standard_Real aFirst, aLast;
1659             Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst, aLast );
1660
1661             if ( aCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) {
1662               Handle(Geom_BSplineCurve) aBSplineCurve = Handle(Geom_BSplineCurve)::DownCast( aCurve );
1663               if ( !aBSplineCurve.IsNull() ) {
1664                 isFound = hasProjectPointOnCurve( theX, theY, aCurve, aParameter );
1665                 if ( isFound ) {
1666                   aPoint = aBSplineCurve->Value( aParameter );
1667                   Standard_Integer anI1, anI2;
1668                   aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 );
1669
1670                   aPnt1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) );
1671                   aPnt2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) );
1672                 }
1673               }
1674             }
1675           }
1676         }
1677       }
1678     }
1679   }
1680   if ( isFound ) {
1681     thePoint = aPoint;
1682     thePoint1 = aPnt1;
1683     thePoint2 = aPnt2;
1684   }
1685   return isFound;
1686 }
1687
1688 /**
1689  * Returns whether the clicked point belong to the curve or has a very near projection
1690  * \param theX the X coordinate of a point clicked in the OCC viewer
1691  * \param theY the Y coordinate of a point clicked in the OCC viewer
1692  * \param theCurve a geometry curve
1693  * \param theOutPoint a found projected point on the curve
1694  */
1695 bool CurveCreator_Widget::hasProjectPointOnCurve( const int theX, const int theY,
1696                                                   const Handle(Geom_Curve)& theCurve,
1697                                                   Standard_Real& theParameter )
1698 {
1699   bool isFound = false;
1700   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1701   if ( !aViewPort )
1702     return isFound;
1703
1704   Handle(V3d_View) aView = aViewPort->getView();
1705   gp_Pnt aPoint = CurveCreator_Utils::ConvertClickToPoint( theX, theY, aView );
1706
1707   GeomAPI_ProjectPointOnCurve aProj( aPoint, theCurve );
1708   Standard_Integer aNbPoint = aProj.NbPoints();
1709   if (aNbPoint > 0) {
1710     for (Standard_Integer j = 1; j <= aNbPoint && !isFound; j++) {
1711       gp_Pnt aNewPoint = aProj.Point( j );
1712       theParameter = aProj.Parameter( j );
1713
1714       int aX, anY;
1715       CurveCreator_Utils::ConvertPointToClick( aNewPoint, aView, aX, anY );
1716
1717       int aXDelta = abs( aX - theX );
1718       int anYDelta = abs( anY - theY );
1719       isFound = aXDelta < SCENE_PIXEL_TOLERANCE && anYDelta < SCENE_PIXEL_TOLERANCE;
1720     }
1721   }
1722   return isFound;
1723 }
1724
1725 /**
1726  * Returns a section index from the table
1727  * \param theRowId a table row
1728  */
1729 int CurveCreator_Widget::getSectionId( const int theRowId ) const
1730 {
1731   return myLocalPointView->item( theRowId, 0 )->data( Qt::UserRole ).toInt();
1732 }
1733
1734 /**
1735  * Returns a point index from the table
1736  * \param theRowId a table row
1737  */
1738 int CurveCreator_Widget::getPointId( const int theRowId ) const
1739 {
1740   return myLocalPointView->item( theRowId, 1 )->data( Qt::UserRole ).toInt();
1741 }
1742
1743 /**
1744  * Returns whethe the container has the value
1745  * \param theList a container of values
1746  * \param theValue a value
1747  */
1748 bool CurveCreator_Widget::contains( const CurveCreator_Widget::SectionToPointList& theList,
1749                                     const CurveCreator_Widget::SectionToPoint& theValue ) const
1750 {
1751   bool isFound = false;
1752
1753   SectionToPointList::const_iterator anIt = theList.begin(), aLast = theList.end();
1754   for ( ; anIt != aLast && !isFound; anIt++ )
1755     isFound = anIt->first == theValue.first && anIt->second == theValue.second;
1756
1757   return isFound;
1758 }