Salome HOME
Profile object creation.
[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: reset
388 // purpose: reset the widget viewer, close local context, clear selection
389 //=======================================================================
390 void CurveCreator_Widget::reset()
391 {
392 }
393
394 //=======================================================================
395 // function: getUniqSectionName
396 // purpose: return unique section name
397 //=======================================================================
398 std::string CurveCreator_Widget::getUniqSectionName( CurveCreator_ICurve* theCurve ) const
399 {
400   for( int i = 0 ; i < 1000000 ; i++ ){
401       char aBuffer[255];
402       sprintf( aBuffer, "Section_%d", i+1 );
403       std::string aName(aBuffer);
404       int j;
405       for( j = 0 ; j < theCurve->getNbSections() ; j++ ){
406         if( theCurve->getSectionName(j) == aName )
407             break;
408       }
409       if( j == theCurve->getNbSections() )
410           return aName;
411   }
412   return "";
413 }
414
415 void CurveCreator_Widget::setCurve( CurveCreator_ICurve* theCurve )
416 {
417   myCurve = theCurve;
418   mySectionView->setCurve(myCurve);
419   onSelectionChanged();
420   updateUndoRedo();
421 }
422
423 void CurveCreator_Widget::onSelectionChanged()
424 {
425   QList<ActionId> anEnabledAct;
426   if( myCurve ){
427     anEnabledAct << NEW_SECTION_ID << MODIFICATION_MODE_ID;
428     if ( removeEnabled() )
429       anEnabledAct << REMOVE_ID;
430     QList<int> aSelSections = mySectionView->getSelectedSections();
431     QList< QPair< int, int > > aSelPoints = mySectionView->getSelectedPoints();
432     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
433     switch( aSelType ){
434     case CurveCreator_TreeView::ST_NOSEL:{
435       break;
436     }
437     case CurveCreator_TreeView::ST_SECTIONS:{
438       /*if( aSelSections[0] > 0 ){
439         anEnabledAct << UP_ID;
440       }*/
441       if( aSelSections.size() == 1 ){
442         anEnabledAct << ADDITION_MODE_ID << DETECTION_MODE_ID;
443       }
444       switch ( getActionMode() ) {
445         case AdditionMode: {
446           mySection = -1;
447           myPointNum = -1;
448           QList<int> aSelSection = mySectionView->getSelectedSections();
449           if( aSelSection.size() > 0 ){
450             mySection = aSelSection[0];
451             myPointNum = myCurve->getNbPoints(mySection);
452           }
453         }
454         break;
455         case ModificationMode: {
456          anEnabledAct << CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID << SET_SECTIONS_SPLINE_ID;
457           int aSectCnt = myCurve->getNbSections();
458           if( aSectCnt > 0 )
459             anEnabledAct << CLEAR_ALL_ID;
460           // TODO
461           //if( aSectCnt > 1 )
462           //  anEnabledAct << JOIN_ALL_ID;
463           //if( aSelSections.size() > 1 ){
464           //  anEnabledAct << JOIN_ID;
465           //}
466         }
467         break;
468         case DetectionMode: {
469         }
470         break;
471         case NoneMode:
472         default:
473         break;
474       }
475       /*if( aSelSections[ aSelSections.size() - 1 ] < ( myCurve->getNbSections() - 1 ) ){
476         anEnabledAct << DOWN_ID;
477       }*/
478       break;
479     }
480     /*case CurveCreator_TreeView::ST_POINTS_ONE_SECTION:{
481       if( aSelPoints[0].second > 0 ){
482         anEnabledAct << UP_ID;
483       }
484       int aLastIndex = aSelPoints.size()-1;
485       int aSect = aSelPoints[0].first;
486       if( aSelPoints[aLastIndex].second < (myCurve->getNbPoints(aSect) - 1)){
487         anEnabledAct << DOWN_ID;
488       }
489       if( aSelPoints.size() == 1){
490         anEnabledAct << INSERT_POINT_BEFORE_ID << INSERT_POINT_AFTER_ID;
491       }
492       break;
493     }*/
494
495     }
496     
497     /*int aSelObjsCnt = aSelPoints.size() + aSelSections.size();
498     if( aSelObjsCnt > 0 ){
499       anEnabledAct << REMOVE_ID;
500     }
501     if( (myCurve->getNbSections() + myCurve->getNbPoints()) > 0 ){
502       anEnabledAct << REMOVE_ALL_ID;
503     }*/
504     // TODO
505     //if( myCurve->getNbSections() > 1 ){
506     //  anEnabledAct << JOIN_ALL_ID;
507     //}
508   }
509   QList<ActionId> anIds = myActionMap.keys();
510   for( int i = 0 ; i < anIds.size() ; i++ ){
511     if( myActionMap.contains(anIds[i]) ){
512       if( anEnabledAct.contains(anIds[i]) ){
513         myActionMap[anIds[i]]->setEnabled(true);
514       }
515       else{
516         myActionMap[anIds[i]]->setEnabled(false);
517       }
518     }
519   }
520   updateUndoRedo();
521   emit selectionChanged();
522 }
523
524 void CurveCreator_Widget::onAdditionMode(bool checked)
525 {
526   if (!checked)
527     return;
528
529   Handle(AIS_InteractiveContext) aContext = getAISContext();
530   if( !myCurve || !aContext )
531     return;
532
533   mySection= -1;
534   myPointNum = -1;
535   QList<int> aSelSection = mySectionView->getSelectedSections();
536   if( aSelSection.size() > 0 ){
537     mySection = aSelSection[0];
538   }
539   else{
540     QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
541     if( aSelPoints.size() > 0 ){
542       mySection = aSelPoints[0].first;
543       myPointNum = aSelPoints[0].second + 1;
544     }
545   }
546 //  emit subOperationStarted( myNewPointEditor );
547 }
548
549 void CurveCreator_Widget::onModificationMode(bool checked)
550 {
551   myLocalPointView->setVisible( checked );
552 }
553
554 void CurveCreator_Widget::onDetectionMode(bool checked)
555 {
556 }
557
558 void CurveCreator_Widget::onModeChanged(bool checked)
559 {
560   ActionMode aMode = NoneMode;
561   if (checked) {
562     QAction* anAction = (QAction*)sender();
563     switch(myActionMap.key(anAction)) {
564       case ADDITION_MODE_ID:
565         aMode = AdditionMode;
566         if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
567           myActionMap[MODIFICATION_MODE_ID]->trigger();
568         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
569           myActionMap[DETECTION_MODE_ID]->trigger();
570         break;
571       case MODIFICATION_MODE_ID:
572         aMode = ModificationMode;
573         if (myActionMap[ADDITION_MODE_ID]->isChecked())
574           myActionMap[ADDITION_MODE_ID]->trigger();
575         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
576           myActionMap[DETECTION_MODE_ID]->trigger();
577         break;
578       case DETECTION_MODE_ID:
579         aMode = DetectionMode;
580         if (myActionMap[ADDITION_MODE_ID]->isChecked())
581           myActionMap[ADDITION_MODE_ID]->trigger();
582         else if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
583           myActionMap[MODIFICATION_MODE_ID]->trigger();
584         break;
585     }
586   }
587   onSelectionChanged();
588   setLocalPointContext( aMode == ModificationMode, true );
589 }
590
591 void CurveCreator_Widget::onAddNewPoint(const CurveCreator::Coordinates& theCoords)
592 {
593   if( !myCurve )
594     return;
595   //myCurve->addPoints(theCoords, mySection, myPointNum );
596   //mySectionView->pointsAdded( mySection, myPointNum );
597   //myPointNum++;
598   QList<int> aSections = mySectionView->getSelectedSections();
599   if( aSections.size() == 0 ){
600     return;
601   }
602   int aSection = aSections[0];
603   myCurve->addPoints(theCoords, aSection); // add to the end of section
604   mySectionView->pointsAdded( aSection, myCurve->getNbPoints( aSection ) );
605   onSelectionChanged();
606   updateUndoRedo();
607 }
608
609 void CurveCreator_Widget::onNewSection()
610 {
611   if( !myCurve )
612     return;
613   myNewSectionEditor->clear();
614   myNewSectionEditor->setEditMode(false);
615   QString aSectName = QString( getUniqSectionName(myCurve).c_str() );
616   myNewSectionEditor->setSectionParameters(aSectName, true, CurveCreator::Polyline );
617   emit subOperationStarted( myNewSectionEditor );
618 }
619
620 void CurveCreator_Widget::onAddNewSection()
621 {
622   if( !myCurve )
623     return;
624   myCurve->addSection( myNewSectionEditor->getName().toStdString(), myNewSectionEditor->getSectionType(),
625                       myNewSectionEditor->isClosed() );
626   mySectionView->sectionAdded( -1 ); // add a new section to the end of list
627   QString aNewName = QString(getUniqSectionName(myCurve).c_str());
628   myNewSectionEditor->setSectionName(aNewName);
629   onSelectionChanged();
630   updateUndoRedo();
631   onCancelSection();
632 }
633
634 void CurveCreator_Widget::onCancelSection()
635 {
636   emit subOperationFinished( myNewSectionEditor );
637 }
638
639 QAction* CurveCreator_Widget::createAction( ActionId theId, const QString& theName, const QPixmap& theImage,
640                                             const QString& theToolTip, const QKeySequence& theShortcut )
641 {
642   QAction* anAct = new QAction(theName,this);
643   if( !theImage.isNull() ){
644     anAct->setIcon(theImage);
645   }
646   anAct->setShortcut(theShortcut);
647   anAct->setToolTip(theToolTip);
648   myActionMap[theId] = anAct;
649   return anAct;
650 }
651
652 QAction* CurveCreator_Widget::getAction(ActionId theId)
653 {
654   if( myActionMap.contains(theId) )
655     return myActionMap[theId];
656   return NULL;
657 }
658
659 CurveCreator_Widget::ActionMode CurveCreator_Widget::getActionMode() const
660 {
661   ActionMode aMode = NoneMode;
662
663   if ( myActionMap[ADDITION_MODE_ID]->isChecked() )
664     aMode = AdditionMode;
665   else if ( myActionMap[MODIFICATION_MODE_ID]->isChecked() )
666     aMode = ModificationMode;
667   else if ( myActionMap[DETECTION_MODE_ID]->isChecked() )
668     aMode = DetectionMode;
669
670   return aMode;
671 }
672
673 void CurveCreator_Widget::onEditSection( int theSection )
674 {
675   if( !myCurve )
676     return;
677   mySection = theSection;
678   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
679   bool isClosed = myCurve->isClosed(theSection);
680   CurveCreator::SectionType aType = myCurve->getSectionType(theSection);
681   myNewSectionEditor->setEditMode(true);
682   myNewSectionEditor->setSectionParameters( aSectName, isClosed, aType );
683
684   emit subOperationStarted( myNewSectionEditor );
685 }
686
687 void CurveCreator_Widget::onModifySection()
688 {
689   if( !myCurve )
690     return;
691   QString aName = myNewSectionEditor->getName();
692   bool isClosed = myNewSectionEditor->isClosed();
693   CurveCreator::SectionType aSectType = myNewSectionEditor->getSectionType();
694 //  myCurve->startOperation();
695   if( myCurve->getSectionName(mySection) != aName.toStdString() )
696     myCurve->setSectionName( mySection , aName.toStdString() );
697
698   if( myCurve->getSectionType(mySection) != aSectType )
699     myCurve->setSectionType( mySection, aSectType );
700
701   if( myCurve->isClosed(mySection) != isClosed )
702     myCurve->setClosed( mySection, isClosed );
703 //  myCurve->finishOperation();
704   mySectionView->sectionChanged(mySection);
705   updateUndoRedo();
706   onCancelSection();
707 }
708
709 /*void CurveCreator_Widget::onEditPoint( int theSection, int thePoint )
710 {
711   if( !myNewPointEditor || !myEdit )
712     return;
713   mySection = theSection;
714   myPointNum = thePoint;
715   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
716   myNewPointEditor->setEditMode(true);
717   myNewPointEditor->setSectionName(aSectName);
718   myNewPointEditor->setDimension( myCurve->getDimension() );
719   CurveCreator::Coordinates aCoords = myCurve->getCoordinates(theSection,thePoint);
720   myNewPointEditor->setCoordinates(aCoords);
721   emit subOperationStarted( myNewPointEditor );
722 }
723
724 void CurveCreator_Widget::onModifyPoint()
725 {
726   if( !myEdit )
727     return;
728   CurveCreator::Coordinates aCoords = myNewPointEditor->getCoordinates();
729   myEdit->setCoordinates( aCoords, mySection, myPointNum );
730   mySectionView->pointDataChanged( mySection, myPointNum );
731   updateUndoRedo();
732   onCancelPoint();
733 }*/
734
735 void CurveCreator_Widget::onJoin()
736 {
737   if( !myCurve )
738     return;
739   QList<int> aSections = mySectionView->getSelectedSections();
740   if( aSections.size() == 0 ){
741     return;
742   }
743   int aMainSect = aSections[0];
744   int aMainSectSize = myCurve->getNbPoints(aMainSect);
745 //  myCurve->startOperation();
746   for( int i = 1 ; i < aSections.size() ; i++ ){
747     int aSectNum = aSections[i] - (i-1);
748     myCurve->join( aMainSect, aSectNum );
749     mySectionView->sectionsRemoved( aSectNum );
750   }
751 //  myCurve->finishOperation();
752   int aNewSectSize = myCurve->getNbPoints(aMainSect);
753   if( aNewSectSize != aMainSectSize )
754     mySectionView->pointsAdded( aMainSect, aMainSectSize, aNewSectSize-aMainSectSize );
755   updateUndoRedo();
756 }
757
758 void CurveCreator_Widget::onRemove()
759 {
760   if( !myCurve )
761     return;
762
763   switch( getActionMode() ) {
764     case NoneMode:
765       removeSection();
766     break;
767     case ModificationMode:
768       removePoint();
769     break;
770     default:
771       break;
772   }
773 }
774
775 void CurveCreator_Widget::onClearAll()
776 {
777   if( !myCurve )
778     return;
779   myCurve->clear();
780   mySectionView->reset();
781   onSelectionChanged();
782   updateUndoRedo();
783 }
784
785 void CurveCreator_Widget::onJoinAll()
786 {
787   if( !myCurve )
788     return;
789   myCurve->join();
790   mySectionView->reset();
791   onSelectionChanged();
792   updateUndoRedo();
793 }
794
795 void CurveCreator_Widget::onUndoSettings()
796 {
797
798 }
799
800 void CurveCreator_Widget::onSetSpline()
801 {
802   if( !myCurve )
803     return;
804   QList<int> aSelSections = mySectionView->getSelectedSections();
805 //  myCurve->startOperation();
806   for( int i = 0 ; i < aSelSections.size() ; i++ ){
807     myCurve->setSectionType(aSelSections[i], CurveCreator::Spline );
808     mySectionView->sectionChanged(aSelSections[i]);
809   }
810 //  myCurve->finishOperation();
811   updateUndoRedo();
812 }
813
814 void CurveCreator_Widget::onSetPolyline()
815 {
816   if( !myCurve )
817     return;
818 //  myCurve->startOperation();
819   QList<int> aSelSections = mySectionView->getSelectedSections();
820   for( int i = 0 ; i < aSelSections.size() ; i++ ){
821     myCurve->setSectionType( aSelSections[i], CurveCreator::Polyline );
822     mySectionView->sectionChanged( aSelSections[i] );
823   }
824 //  myCurve->finishOperation();
825   updateUndoRedo();
826 }
827
828 void CurveCreator_Widget::onCloseSections()
829 {
830   if( !myCurve )
831     return;
832 //  myCurve->startOperation();
833   QList<int> aSelSections = mySectionView->getSelectedSections();
834   for( int i = 0 ; i < aSelSections.size() ; i++ ){
835     myCurve->setClosed(aSelSections[i], true);
836     mySectionView->sectionChanged(aSelSections[i]);
837   }
838 //  myCurve->finishOperation();
839   updateUndoRedo();
840 }
841
842 void CurveCreator_Widget::onUncloseSections()
843 {
844   if( !myCurve )
845     return;
846 //  myCurve->startOperation();
847   QList<int> aSelSections = mySectionView->getSelectedSections();
848   for( int i = 0 ; i < aSelSections.size() ; i++ ){
849     myCurve->setClosed(aSelSections[i], false);
850     mySectionView->sectionChanged(aSelSections[i]);
851   }
852 //  myCurve->finishOperation();
853   updateUndoRedo();
854 }
855
856 void CurveCreator_Widget::onUndo()
857 {
858     if( !myCurve )
859       return;
860
861     CurveCreator_Widget::SectionToPointList aPoints;
862     startCurveModification( aPoints, false );
863     myCurve->undo();
864     finishCurveModification();
865     mySectionView->reset();
866 }
867
868 void CurveCreator_Widget::onRedo()
869 {
870     if( !myCurve )
871       return;
872     CurveCreator_Widget::SectionToPointList aPoints;
873     startCurveModification( aPoints, false );
874     myCurve->redo();
875     finishCurveModification();
876     mySectionView->reset();
877 }
878
879 void CurveCreator_Widget::updateUndoRedo()
880 {
881   if( !myCurve )
882     return;
883   QAction* anAct = myActionMap[UNDO_ID];
884   if( anAct != 0 ){
885     if( myCurve->getNbUndo() != 0 ){
886       anAct->setEnabled(true);
887     }
888     else{
889       anAct->setDisabled(true);
890     }
891   }
892   anAct = myActionMap[REDO_ID];
893   if( anAct != 0 ){
894     if( myCurve->getNbRedo() != 0 ){
895       anAct->setEnabled(true);
896     }
897     else{
898       anAct->setDisabled(true);
899     }
900   }
901 }
902
903 void CurveCreator_Widget::onContextMenu( QPoint thePoint )
904 {
905   QList<ActionId> aContextActions;
906   aContextActions << CLEAR_ALL_ID << JOIN_ALL_ID << SEPARATOR_ID <<
907                      CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID <<
908                      SET_SECTIONS_SPLINE_ID;
909   QPoint aGlPoint = mySectionView->mapToGlobal(thePoint);
910   bool isVis = false;
911   QList<ActionId> aResAct;
912   for( int i = 0 ; i < aContextActions.size() ; i++ ){
913     if( aContextActions[i] != SEPARATOR_ID ){
914       if( myActionMap.contains(aContextActions[i]) ){
915         QAction* anAct = myActionMap[aContextActions[i]];
916         if( anAct->isEnabled() ){
917           aResAct << aContextActions[i];
918           isVis = true;
919         }
920       }
921     }
922     else{
923       aResAct << SEPARATOR_ID;
924     }
925   }
926   if( !isVis )
927     return;
928
929   QMenu* aMenu = new QMenu(this);
930   for( int i = 0 ; i < aResAct.size() ; i++ ){
931     if( aResAct[i] == SEPARATOR_ID ){
932       aMenu->addSeparator();
933     }
934     else{
935       QAction* anAct = myActionMap[aResAct[i]];
936       aMenu->insertAction(NULL, anAct);
937     }
938   }
939   aMenu->exec(aGlPoint);
940 }
941
942 QList<int> CurveCreator_Widget::getSelectedSections()
943 {
944   return mySectionView->getSelectedSections();
945 }
946
947 QList< QPair< int, int > > CurveCreator_Widget::getSelectedPoints()
948 {
949   return mySectionView->getSelectedPoints();
950 }
951
952 /**
953  * According to the widget state, performs the remove action
954  */
955 void CurveCreator_Widget::removeSelected()
956 {
957   onRemove();
958 }
959
960 /**
961  * Checks whether there are some selection to be removed
962  */
963 bool CurveCreator_Widget::removeEnabled()
964 {
965   bool isEnabled = getActionMode() == ModificationMode;
966   if ( !isEnabled ) {
967     QList<int> aSelSections = mySectionView->getSelectedSections();
968     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
969     isEnabled = aSelType == CurveCreator_TreeView::ST_SECTIONS &&
970                 aSelSections.size() == 1;
971   }
972   return isEnabled;
973 }
974
975
976 //=================================================================================
977 // function : GeometryGUI::onGetCoordsByClick()
978 // purpose  : Manage mouse press events in Additon mode
979 //=================================================================================
980 void CurveCreator_Widget::onGetCoordsByClick( QMouseEvent* pe )
981 {
982   if (pe->button() != Qt::LeftButton)
983     return;
984
985   if ( pe->modifiers() != Qt::ControlModifier ) {
986     Handle(AIS_InteractiveContext) ic = getAISContext();
987     if ( !ic )
988       return;
989
990     gp_Pnt aPnt;    
991
992     ic->InitSelected();
993     if ( pe->modifiers() == Qt::ShiftModifier )
994       ic->ShiftSelect();  // Append selection
995     else
996       ic->Select();       // New selection
997
998     /*TopoDS_Shape aShape;
999
1000     ic->InitSelected();
1001     if ( ic->MoreSelected() )
1002       aShape = ic->SelectedShape();
1003
1004     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
1005       aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
1006     else*/
1007     {
1008       OCCViewer_ViewPort3d* vp = getViewPort();
1009       aPnt = CurveCreator_Utils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
1010     }
1011     // set the coordinates into dialog
1012     CurveCreator::Coordinates aCoords;
1013     aCoords.push_back( aPnt.X() );
1014     aCoords.push_back( aPnt.Y() );
1015     if ( myCurve->getDimension() == 3 ) {
1016       aCoords.push_back( aPnt.Z() );
1017     }
1018     onAddNewPoint(aCoords);
1019 //    myNewPointEditor->setCoordinates( aCoords );
1020   }
1021 }
1022
1023 /**
1024  * Manage mouse press events
1025  * \param theWindow an owner of the signal
1026  * \param theEvent a mouse event
1027  */
1028 void CurveCreator_Widget::onMousePress( SUIT_ViewWindow*, QMouseEvent* theEvent )
1029 {
1030   if ( theEvent->button() != Qt::LeftButton )
1031     return;
1032
1033   switch( getActionMode() ) {
1034     case ModificationMode: {
1035       //store initial cursor position for Drag&Drop
1036       setDragStarted( true, theEvent->pos() );
1037       break;
1038     }
1039     case AdditionMode: {
1040       onGetCoordsByClick( theEvent );
1041       break;
1042     }
1043     default:
1044       break;
1045   }
1046 }
1047
1048 /**
1049  * Manage mouse release events in Modification mode
1050  * \param theWindow an owner of the signal
1051  * \param theEvent a mouse event
1052  */
1053 void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow*, QMouseEvent* theEvent )
1054 {
1055   if ( getActionMode() != ModificationMode )
1056     return;
1057
1058   if ( myDragStarted ) {
1059     if ( myDragged ) // if the drag of some points has happened, restore the drag selection
1060       setSelectedPonts( myDragPoints );
1061     setDragStarted( false );
1062   }
1063   else // check whether the segment is clicked an a new point should be added to the segment
1064     insertPointToSelectedSegment( theEvent->pos().x(), theEvent->pos().y() );
1065
1066   // updates the input panel table to show the selected point coordinates
1067   updateLocalPointView();
1068 }
1069
1070 /**
1071  * Manage mouse move events in Modification mode
1072  * \param theWindow an owner of the signal
1073  * \param theEvent a mouse event
1074  */
1075 void CurveCreator_Widget::onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent )
1076 {
1077   if ( getActionMode() != ModificationMode || !myDragStarted )
1078     return;
1079
1080   QPoint aPos = theEvent->pos();
1081   if ( (aPos - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
1082     return;
1083
1084   moveSelectedPoints( aPos.x(), aPos.y() );
1085   myDragStartPosition = aPos;
1086 }
1087
1088 /**
1089  * Set zero viewer by the last view closed in
1090  * \param theManager a viewer manager
1091  */
1092 void CurveCreator_Widget::onLastViewClosed( SUIT_ViewManager* theManager )
1093 {
1094   myOCCViewer = 0;
1095 }
1096
1097 void CurveCreator_Widget::onMousePress( QMouseEvent* theEvent )
1098 {
1099   onMousePress( 0, theEvent );
1100 }
1101
1102 void CurveCreator_Widget::onMouseRelease( QMouseEvent* theEvent )
1103 {
1104   onMouseRelease( 0, theEvent );
1105 }
1106
1107 void CurveCreator_Widget::onMouseMove( QMouseEvent* theEvent )
1108 {
1109   onMouseMove( 0, theEvent );
1110 }
1111
1112 void CurveCreator_Widget::onCellChanged( int theRow, int theColumn )
1113 {
1114   int aCurrSect = getSectionId( theRow );
1115   int aPntIndex = getPointId( theRow );
1116
1117   if ( aPntIndex < 0 )
1118     return;
1119
1120   SectionToPointList aSelPoints;
1121   startCurveModification( aSelPoints );
1122
1123   double aX  = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
1124   double anY = myLocalPointView->item( theRow, 3 )->data( Qt::UserRole ).toDouble();
1125   std::deque<float> aChangedPos;
1126   aChangedPos.push_back( aX );
1127   aChangedPos.push_back( anY );
1128   myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
1129
1130   finishCurveModification( aSelPoints );
1131 }
1132
1133 /**
1134  * Removes a selected section from the curve. Updates undo/redo status
1135  */
1136 void CurveCreator_Widget::removeSection()
1137 {
1138   QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
1139   int aCurrSect=-1;
1140   int aRemoveCnt = 0;
1141 //  myCurve->startOperation();
1142   for( int i = 0 ; i < aSelPoints.size() ; i++ ){
1143     if( aCurrSect != aSelPoints[i].first ){
1144       aRemoveCnt = 0;
1145       aCurrSect = aSelPoints[i].first;
1146     }
1147     int aPntIndx = aSelPoints[i].second - aRemoveCnt;
1148     myCurve->removePoint( aCurrSect, aPntIndx );
1149     mySectionView->pointsRemoved( aCurrSect, aPntIndx );
1150     aRemoveCnt++;
1151   }
1152   QList<int> aSections = mySectionView->getSelectedSections();
1153   for( int i = 0 ; i < aSections.size() ; i++ ){
1154     int aSectNum = aSections[i] - (i);
1155     myCurve->removeSection( aSectNum );
1156     mySectionView->sectionsRemoved( aSectNum );
1157   }
1158 //  myCurve->finishOperation();
1159   mySectionView->clearSelection();
1160   updateUndoRedo();
1161 }
1162
1163 /**
1164  * Removes a selected points from the curve. Updates undo/redo status
1165  */
1166 void CurveCreator_Widget::removePoint()
1167 {
1168   SectionToPointList aPoints;
1169   getSelectedPonts( aPoints );
1170   if ( aPoints.size() == 0 )
1171     return;
1172
1173   SectionToPointList aSelPoints;
1174   startCurveModification( aSelPoints, false );
1175
1176   myCurve->removeSeveralPoints( aPoints );
1177   finishCurveModification( SectionToPointList() );
1178 }
1179
1180 void CurveCreator_Widget::insertPointToSelectedSegment( const int theX,
1181                                                         const int theY )
1182 {
1183   Handle(AIS_InteractiveContext) aContext = getAISContext();
1184   if ( !aContext )
1185     return;
1186   gp_Pnt aPoint;
1187   gp_Pnt aPoint1, aPoint2;
1188   bool isFoundPoint = false;
1189
1190   for ( aContext->InitSelected(); aContext->MoreSelected() && !isFoundPoint;
1191         aContext->NextSelected() ) {
1192     TopoDS_Shape aTShape = aContext->SelectedShape();
1193     if ( !aTShape.IsNull() && aTShape.ShapeType() == TopAbs_VERTEX )
1194       continue;
1195     else {
1196       Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
1197       if ( anOwner.IsNull() )
1198         continue;
1199       const TopLoc_Location& aLocation = anOwner->Location();
1200       Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
1201       isFoundPoint = pointOnObject( anAIS, theX, theY, aPoint, aPoint1, aPoint2 );
1202     }
1203   }
1204   if ( !isFoundPoint )
1205     return;
1206
1207   // insert the point to the model curve
1208   SectionToPointList aSelPoints;
1209   startCurveModification( aSelPoints );
1210
1211   CurveCreator::Coordinates aCoords;
1212   aCoords.push_back( aPoint.X() );
1213   aCoords.push_back( aPoint.Y() );
1214
1215   SectionToPointList aPoints1, aPoints2;
1216   findSectionsToPoints( aPoint1.X(), aPoint1.Y(), aPoints1 );
1217   findSectionsToPoints( aPoint2.X(), aPoint2.Y(), aPoints2 );
1218   SectionToPointList::const_iterator anIt = aPoints1.begin(), aLast = aPoints1.end();
1219   int aSectionId = -1;
1220   // there can be a case when a new point is added into two sections
1221   int aPoint1Id = -1, aPoint2Id = -1;
1222   for ( ; anIt != aLast && aSectionId < 0; anIt++ ) {
1223     int aSectionCur = anIt->first;
1224     SectionToPointList::const_iterator anIt2 = aPoints2.begin(), aLast2 = aPoints2.end();
1225     for ( ; anIt2 != aLast2 && aSectionId < 0; anIt2++ ) {
1226       if ( anIt2->first == aSectionCur ) {
1227         aSectionId = aSectionCur;
1228         aPoint1Id = anIt->second;
1229         aPoint2Id = anIt2->second;
1230       }
1231     }
1232   }
1233
1234   int anInsertPos = -1;
1235   int aLastPoint = myCurve->getNbPoints( aSectionId )-1; 
1236   if ( ( aPoint1Id == aLastPoint && aPoint2Id == 0 ) ||
1237        ( aPoint2Id == aLastPoint && aPoint1Id == 0 ) )
1238     anInsertPos = -1; // if the section happens between first and last points
1239   else
1240     anInsertPos = aPoint1Id < aPoint2Id ? aPoint1Id + 1 : aPoint2Id + 1;
1241
1242   myCurve->addPoints( aCoords, aSectionId, anInsertPos );
1243   mySectionView->pointsAdded( aSectionId, myCurve->getNbPoints( aSectionId ) );
1244
1245   finishCurveModification( aSelPoints );
1246
1247   setSelectedPonts();
1248 }
1249
1250 void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
1251                                               const int theYPosition )
1252 {
1253   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1254   if ( !aViewPort )
1255     return;
1256
1257   SectionToPointList aPoints;
1258   startCurveModification( aPoints, false );
1259
1260   gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(),
1261                                                               myDragStartPosition.y(),
1262                                                               aViewPort->getView() );
1263   gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( theXPosition, theYPosition,
1264                                                              aViewPort->getView() );
1265   double aXDelta = aStartPnt.X() - anEndPnt.X();
1266   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
1267
1268   CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
1269   std::deque<float> aChangedPos;
1270   SectionToPointList::const_iterator anIt = myDragPoints.begin(), aLast = myDragPoints.end();
1271   for ( ; anIt != aLast; anIt++ ) {
1272     int aSectionId = anIt->first;
1273     int aPointId = anIt->second;
1274     aChangedPos = myCurve->getPoint( aSectionId, aPointId );
1275     if ( aChangedPos.size() < 2 )
1276       continue;
1277     aChangedPos[0] = aChangedPos[0] - aXDelta;
1278     aChangedPos[1] = aChangedPos[1] - anYDelta;
1279     
1280     aCoordList.push_back(
1281       std::make_pair(std::make_pair( aSectionId, aPointId ), 
1282                      aChangedPos ));
1283   }
1284   myCurve->setSeveralPoints( aCoordList );
1285
1286   myDragged = true;
1287   finishCurveModification( myDragPoints );
1288 }
1289
1290 void CurveCreator_Widget::updateLocalPointView()
1291 {
1292   Handle(AIS_InteractiveContext) aContext = getAISContext();
1293   if ( !aContext )
1294     return;
1295
1296   bool isBlocked = myLocalPointView->blockSignals(true);
1297   gp_Pnt aPnt;
1298   myLocalPointView->setRowCount( 0 );
1299   for ( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) {
1300     TopoDS_Vertex aVertex;
1301     TopoDS_Shape aShape = aContext->SelectedShape();
1302     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
1303       aVertex = TopoDS::Vertex( aContext->SelectedShape() );
1304     else {
1305       Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
1306       if ( !anOwner.IsNull() ) {
1307         Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
1308         if ( !anAIS.IsNull() ) {
1309           Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast( anAIS);
1310           if ( !aPoint.IsNull() )
1311             aVertex = TopoDS::Vertex( aPoint->Vertex() );
1312         }
1313         if ( aVertex.IsNull() ) {
1314           // the following happens if there are no points in the current curve, there is only a shape
1315           /*Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
1316           if ( aBrepOwner.IsNull() )
1317             continue;
1318           if ( aBrepOwner->HasShape() ) {
1319             const TopoDS_Shape& aShape = aBrepOwner->Shape();
1320             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
1321             {
1322               aVertex = TopoDS::Vertex( aShape );
1323             }
1324           }*/
1325         }
1326       }
1327       if ( aVertex.IsNull() )
1328         continue;
1329       aPnt = BRep_Tool::Pnt( aVertex );
1330       addLocalPointToTable( aPnt.X(), aPnt.Y() );
1331     }
1332   }
1333   myLocalPointView->blockSignals(isBlocked);
1334 }
1335
1336 /**
1337  * 
1338  */
1339 void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable )
1340 {
1341   Handle(AIS_InteractiveContext) ic = getAISContext();
1342   if ( !ic )
1343     return;
1344
1345   if ( theOpen ) {
1346     // Open local context if there is no one
1347     if ( !ic->HasOpenedContext() ) {
1348       ic->ClearCurrents( false );
1349       ic->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ );
1350     }
1351     AIS_ListOfInteractive aList;
1352     ic->DisplayedObjects( aList );
1353     int aLSize = 0;
1354     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
1355       aLSize++;
1356
1357     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
1358     {
1359       Handle(AIS_InteractiveObject) anAIS = it.Value();
1360       if ( !anAIS.IsNull() )
1361       {
1362         if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
1363         {
1364           ic->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ );
1365           ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_WIRE ) );
1366         }
1367         else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
1368         {
1369           ic->Load( anAIS, -1/*selection mode*/, false/*allow decomposition*/ );
1370           ic->Activate( anAIS, TopAbs_VERTEX );
1371         }
1372       }
1373       continue;
1374     }
1375   }
1376   else {
1377     if ( ic->HasOpenedContext() )
1378       ic->CloseAllContexts();
1379     if ( isUpdateTable )
1380       updateLocalPointView();
1381   }
1382 }
1383
1384 void CurveCreator_Widget::addLocalPointToTable( const double theX, const double theY )
1385 {
1386   SectionToPointList aPoints;
1387   findSectionsToPoints( theX, theY, aPoints );
1388
1389   SectionToPointList aSkipList;
1390   // table could not contain two equal value rows
1391   int aRowId = myLocalPointView->rowCount();
1392   double aCurrentX, aCurrentY;
1393   int aSectionId, aPointId;
1394   SectionToPoint aPoint;
1395   for ( int i = 0; i < aRowId; i++ ) {
1396     aCurrentX = myLocalPointView->item( i, 2 )->data( Qt::UserRole ).toDouble();
1397     aCurrentY = myLocalPointView->item( i, 3 )->data( Qt::UserRole ).toDouble();
1398     if ( fabs( aCurrentX - theX ) < LOCAL_SELECTION_TOLERANCE &&
1399          fabs( aCurrentY - theY ) < LOCAL_SELECTION_TOLERANCE ) {
1400            aPoint = std::make_pair<int, int>( getSectionId( i ), getPointId( i ) );
1401       if ( !contains( aSkipList, aPoint ) )
1402         aSkipList.push_back( aPoint );
1403     }
1404   }
1405   if ( aSkipList.size() == aPoints.size() )
1406     return;
1407
1408   QTableWidgetItem* anItem;
1409   SectionToPointList::const_iterator anIt = aPoints.begin(), aLast = aPoints.end();
1410   for ( ; anIt != aLast; anIt++ ) {
1411     aPoint = *anIt;
1412     if ( contains( aSkipList, aPoint ) )
1413       continue;
1414
1415     myLocalPointView->setRowCount( aRowId+1 );
1416     aSectionId = aPoint.first;
1417     aPointId = aPoint.second;
1418
1419     anItem = new QTableWidgetItem( myCurve->getSectionName( aSectionId ).c_str() );
1420     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
1421     anItem->setData( Qt::UserRole, aSectionId );
1422     myLocalPointView->setItem( aRowId, 0, anItem );
1423
1424     anItem = new QTableWidgetItem( QString::number( aPointId + 1 ) );
1425     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
1426     anItem->setData( Qt::UserRole, aPointId );
1427     myLocalPointView->setItem( aRowId, 1, anItem );
1428
1429     anItem = new QTableWidgetItem( QString::number( theX ) );
1430     anItem->setData( Qt::UserRole, theX );
1431     myLocalPointView->setItem( aRowId, 2, anItem );
1432
1433     anItem = new QTableWidgetItem( QString::number( theY ) );
1434     anItem->setData( Qt::UserRole, theY );
1435     myLocalPointView->setItem( aRowId, 3, anItem );
1436   }
1437 }
1438
1439 /**
1440  * Set drag operation started. Save the position and a list of dragged points
1441  * \param theState the drag operation state: started/finished
1442  * \param thePoint the start drag position
1443  */
1444 void CurveCreator_Widget::setDragStarted( const bool theState, const QPoint& thePoint )
1445 {
1446   if ( theState ) {
1447     getSelectedPonts( myDragPoints );
1448     myDragStarted = myDragPoints.size();
1449     myDragStartPosition = thePoint;
1450     if ( myDragStarted ) {
1451       // change a viewer interaction style in order to avoid a select rectangle build
1452       myDragInteractionStyle = changeInteractionStyle( SUIT_ViewModel::KEY_FREE );
1453     }
1454   }
1455   else {
1456     if ( myDragStarted )
1457       changeInteractionStyle( myDragInteractionStyle );
1458     myDragStarted = false;
1459     myDragPoints.clear();
1460   }
1461   myDragged = false;
1462 }
1463
1464 void CurveCreator_Widget::getSelectedPonts( CurveCreator_Widget::SectionToPointList& thePoints )
1465 {
1466   thePoints.clear();
1467   for ( int i = 0, aNb = myLocalPointView->rowCount(); i < aNb; i++ )
1468     thePoints.push_back( std::make_pair( getSectionId( i ), getPointId( i ) ) );
1469 }
1470
1471 void CurveCreator_Widget::setSelectedPonts( const CurveCreator_Widget::SectionToPointList& thePoints )
1472 {
1473   Handle(AIS_InteractiveContext) ic = getAISContext();
1474   if ( !ic || !ic->HasOpenedContext() )
1475     return;
1476
1477   AIS_ListOfInteractive aListToSelect;
1478   AIS_ListOfInteractive aDisplayedList;
1479   ic->DisplayedObjects( aDisplayedList );
1480
1481   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
1482   SectionToPoint aSToPoint;
1483   for( ; anIt != aLast; anIt++ ) {
1484     aSToPoint = *anIt;
1485
1486     for ( AIS_ListIteratorOfListOfInteractive it( aDisplayedList ); it.More(); it.Next() )
1487     {
1488       Handle(AIS_InteractiveObject) anAIS = it.Value();
1489       if ( anAIS.IsNull() )
1490         continue;
1491       Handle(AIS_Point) anAISPoint = Handle(AIS_Point)::DownCast( anAIS );
1492       if ( anAISPoint.IsNull() )
1493         continue;
1494
1495       TopoDS_Vertex aVertex = TopoDS::Vertex( anAISPoint->Vertex() );
1496
1497       if ( aVertex.IsNull() )
1498         continue;
1499
1500       gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
1501
1502       SectionToPointList aPoints;
1503       findSectionsToPoints( aPnt.X(), aPnt.Y(), aPoints );
1504
1505       SectionToPointList::const_iterator anIt = aPoints.begin(), aLast = aPoints.end();
1506       SectionToPoint aPoint;
1507       for ( ; anIt != aLast; anIt++ ) {
1508         aPoint = *anIt;
1509         if ( aPoint.first == aSToPoint.first && aPoint.second == aSToPoint.second )
1510           aListToSelect.Append( anAIS );
1511       }
1512     }
1513   }
1514
1515   ic->ClearSelected( Standard_False );
1516   setObjectsSelected( aListToSelect );
1517   updateLocalPointView();
1518 }
1519
1520 /**
1521  * Get viewer information before perform the curve modification.
1522  * Take a list of selected cuve points an close local context.
1523  * The context should be closed because the curve presentation is
1524  * redisplayed and if it is not closed, when we close the local context
1525  * later, the presentation shown in the local context is disappeared.
1526  * \param thePoints an output list of curve selected points
1527  * \param theFillPoints a flag whether the selection list should be filled
1528  */
1529 void CurveCreator_Widget::startCurveModification(
1530                            CurveCreator_Widget::SectionToPointList& thePoints,
1531                            const bool theFillPoints )
1532 {
1533   if ( theFillPoints ) {
1534     thePoints.clear();
1535     getSelectedPonts( thePoints );
1536   }
1537   setLocalPointContext( false );
1538 }
1539
1540 /**
1541  * Restore the viewer state after the curve modification is done.
1542  * Open local context and select given points inside it.
1543  * \param thePoints a list of curve selected points
1544  */
1545 void CurveCreator_Widget::finishCurveModification(
1546                            const CurveCreator_Widget::SectionToPointList& thePoints )
1547 {
1548   if ( getActionMode() == ModificationMode )
1549     setLocalPointContext( true );
1550   setSelectedPonts( thePoints );
1551   updateUndoRedo();
1552 }
1553
1554 /**
1555  * Returns a point index in the model curve by the point coordinates in the viewer
1556  * \param theX the X coordinate of the point
1557  * \param theY the Y coordinate of the point
1558  */
1559 int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
1560 {
1561   int aPntIndex = -1;
1562
1563   CurveCreator::Coordinates aCoords;
1564   for ( int i = 0, aNb = myCurve->getNbPoints( theSectionId ); i < aNb && aPntIndex < 0; i++ ) {
1565     aCoords = myCurve->getPoint( theSectionId, i );
1566     if ( aCoords.size() < 2 )
1567       continue;
1568     if ( fabs( aCoords[0] - theX ) < LOCAL_SELECTION_TOLERANCE &&
1569          fabs( aCoords[1] - theY ) < LOCAL_SELECTION_TOLERANCE )
1570       aPntIndex = i;
1571   }
1572
1573   return aPntIndex;
1574 }
1575
1576 void CurveCreator_Widget::findSectionsToPoints( const double theX, const double theY,
1577                                  CurveCreator_Widget::SectionToPointList& thePoints )
1578 {
1579   thePoints.clear();
1580
1581   int aPointId = -1;
1582   for ( int i = 0, aNb = myCurve->getNbSections(); i < aNb; i++ ) {
1583     aPointId = findLocalPointIndex( i, theX, theY );
1584     if ( aPointId < 0 )
1585       continue;
1586     SectionToPoint aPoint = std::make_pair( i, aPointId );
1587     if ( !contains( thePoints, aPoint ) )
1588       thePoints.push_back( aPoint );
1589   }
1590 }
1591
1592 void CurveCreator_Widget::convert( const SectionToPointList& thePoints,
1593                                    QMap<int, QList<int> >& theConvPoints )
1594 {
1595   theConvPoints.clear();
1596
1597   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
1598   QList<int> aPoints;
1599   int aSectionId, aPointId;
1600   for ( ; anIt != aLast; anIt++ ) {
1601     aSectionId = anIt->first;
1602     aPointId = anIt->second;
1603     aPoints.clear();
1604     if ( theConvPoints.contains( aSectionId ) )
1605       aPoints = theConvPoints[aSectionId];
1606     if ( aPoints.contains( aPointId ) )
1607       continue;
1608     aPoints.append( aPointId );
1609     theConvPoints[aSectionId] = aPoints;
1610   }
1611 }
1612
1613 /**
1614  * Checks whether the point belongs to the OCC object
1615  * \param theObject a line or shape with a bspline inside
1616  * \param theX the X coordinate in the view.
1617  * \param theY the Y coordinate in the view.
1618  * \param thePoint the output point to be append to the model curve
1619  * \param thePoint1 the output point to bound the line where a new point should be inserted
1620  * \param thePoint2 the output point to bound the line where a new point should be inserted
1621  */
1622 bool CurveCreator_Widget::pointOnObject( Handle(AIS_InteractiveObject) theObject,
1623                                          const int theX, const int theY,
1624                                          gp_Pnt& thePoint,
1625                                          gp_Pnt& thePoint1, gp_Pnt& thePoint2 )
1626 {
1627   bool isFound = false;
1628
1629   Handle(AIS_InteractiveContext) aContext = getAISContext();
1630   if ( theObject.IsNull() || !aContext )
1631     return isFound;
1632
1633   gp_Pnt aPoint;
1634   Standard_Real aParameter;
1635   gp_Pnt aPnt1, aPnt2;
1636   Handle(AIS_Line) aLine = Handle(AIS_Line)::DownCast( theObject );
1637   if ( !aLine.IsNull() ) {
1638     const Handle(Geom_Line) aGLine = aLine->Line();
1639     isFound = hasProjectPointOnCurve( theX, theY, aGLine, aParameter );
1640     if ( isFound ) {
1641       aPoint = aGLine->Value( aParameter );
1642
1643       Handle(Geom_Point) aPStart;
1644       Handle(Geom_Point) aPEnd;
1645       aLine->Points( aPStart, aPEnd );
1646       aPnt1 = aPStart->Pnt();
1647       aPnt2 = aPEnd->Pnt();
1648
1649       // in case of Geom line a projection is performed to the infinite line,
1650       // so it is necessary to bound it by the line size
1651       Bnd_Box aLineBox;
1652       aLineBox.Set( aPnt1, gp_Vec( aPnt1, aPnt2 ) );
1653       isFound = !aLineBox.IsOut( aPoint );
1654     }
1655   }
1656   else {
1657     Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject );
1658     if ( !aShape.IsNull() ) {
1659       const TopoDS_Wire& aWire = TopoDS::Wire( aShape->Shape() );
1660       if ( !aWire.IsNull() ) {
1661         TopExp_Explorer anExp( aWire, TopAbs_EDGE );
1662         for ( ; anExp.More(); anExp.Next())
1663         {
1664           const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
1665           if ( !anEdge.IsNull() ) {
1666             Standard_Real aFirst, aLast;
1667             Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst, aLast );
1668
1669             if ( aCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) {
1670               Handle(Geom_BSplineCurve) aBSplineCurve = Handle(Geom_BSplineCurve)::DownCast( aCurve );
1671               if ( !aBSplineCurve.IsNull() ) {
1672                 isFound = hasProjectPointOnCurve( theX, theY, aCurve, aParameter );
1673                 if ( isFound ) {
1674                   aPoint = aBSplineCurve->Value( aParameter );
1675                   Standard_Integer anI1, anI2;
1676                   aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 );
1677
1678                   aPnt1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) );
1679                   aPnt2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) );
1680                 }
1681               }
1682             }
1683           }
1684         }
1685       }
1686     }
1687   }
1688   if ( isFound ) {
1689     thePoint = aPoint;
1690     thePoint1 = aPnt1;
1691     thePoint2 = aPnt2;
1692   }
1693   return isFound;
1694 }
1695
1696 /**
1697  * Returns whether the clicked point belong to the curve or has a very near projection
1698  * \param theX the X coordinate of a point clicked in the OCC viewer
1699  * \param theY the Y coordinate of a point clicked in the OCC viewer
1700  * \param theCurve a geometry curve
1701  * \param theOutPoint a found projected point on the curve
1702  */
1703 bool CurveCreator_Widget::hasProjectPointOnCurve( const int theX, const int theY,
1704                                                   const Handle(Geom_Curve)& theCurve,
1705                                                   Standard_Real& theParameter )
1706 {
1707   bool isFound = false;
1708   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1709   if ( !aViewPort )
1710     return isFound;
1711
1712   Handle(V3d_View) aView = aViewPort->getView();
1713   gp_Pnt aPoint = CurveCreator_Utils::ConvertClickToPoint( theX, theY, aView );
1714
1715   GeomAPI_ProjectPointOnCurve aProj( aPoint, theCurve );
1716   Standard_Integer aNbPoint = aProj.NbPoints();
1717   if (aNbPoint > 0) {
1718     for (Standard_Integer j = 1; j <= aNbPoint && !isFound; j++) {
1719       gp_Pnt aNewPoint = aProj.Point( j );
1720       theParameter = aProj.Parameter( j );
1721
1722       int aX, anY;
1723       CurveCreator_Utils::ConvertPointToClick( aNewPoint, aView, aX, anY );
1724
1725       int aXDelta = abs( aX - theX );
1726       int anYDelta = abs( anY - theY );
1727       isFound = aXDelta < SCENE_PIXEL_TOLERANCE && anYDelta < SCENE_PIXEL_TOLERANCE;
1728     }
1729   }
1730   return isFound;
1731 }
1732
1733 /**
1734  * Returns a section index from the table
1735  * \param theRowId a table row
1736  */
1737 int CurveCreator_Widget::getSectionId( const int theRowId ) const
1738 {
1739   return myLocalPointView->item( theRowId, 0 )->data( Qt::UserRole ).toInt();
1740 }
1741
1742 /**
1743  * Returns a point index from the table
1744  * \param theRowId a table row
1745  */
1746 int CurveCreator_Widget::getPointId( const int theRowId ) const
1747 {
1748   return myLocalPointView->item( theRowId, 1 )->data( Qt::UserRole ).toInt();
1749 }
1750
1751 /**
1752  * Returns whethe the container has the value
1753  * \param theList a container of values
1754  * \param theValue a value
1755  */
1756 bool CurveCreator_Widget::contains( const CurveCreator_Widget::SectionToPointList& theList,
1757                                     const CurveCreator_Widget::SectionToPoint& theValue ) const
1758 {
1759   bool isFound = false;
1760
1761   SectionToPointList::const_iterator anIt = theList.begin(), aLast = theList.end();
1762   for ( ; anIt != aLast && !isFound; anIt++ )
1763     isFound = anIt->first == theValue.first && anIt->second == theValue.second;
1764
1765   return isFound;
1766 }