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