Salome HOME
OCC functionality moving out from the widget
[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_UtilsICurve.hxx"
29 #include "CurveCreator_TableView.h"
30
31 #include <SUIT_Session.h>
32 #include <SUIT_Desktop.h>
33 #include <SUIT_ResourceMgr.h>
34 #include <SUIT_ViewManager.h>
35
36 #include <OCCViewer_ViewWindow.h>
37 #include <OCCViewer_ViewManager.h>
38 #include <OCCViewer_ViewPort3d.h>
39 #include "OCCViewer_Utilities.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
77 CurveCreator_Widget::CurveCreator_Widget(QWidget* parent,
78                                          CurveCreator_ICurve *theCurve,
79                                          Qt::WindowFlags fl)
80 : QWidget(parent), myNewSectionEditor(NULL), myCurve(theCurve), mySection(0),
81   myDragStarted( false ), myDragInteractionStyle( SUIT_ViewModel::STANDARD ),
82   myOCCViewer( 0 )
83 {
84   myNewSectionEditor = new CurveCreator_NewSectionDlg( this );
85   myNewSectionEditor->hide();
86   connect( myNewSectionEditor, SIGNAL(addSection()), this, SLOT(onAddNewSection()) );
87   connect( myNewSectionEditor, SIGNAL(modifySection()), this, SLOT(onModifySection()) );
88   connect( myNewSectionEditor, SIGNAL(cancelSection()), this, SLOT(onCancelSection()) );
89
90   QGroupBox* aSectionGroup = new QGroupBox(tr("Sections"),this);
91
92   mySectionView = new CurveCreator_TreeView(myCurve, aSectionGroup);
93   connect( mySectionView, SIGNAL(selectionChanged()), this, SLOT( onSelectionChanged() ) );
94   connect( mySectionView, SIGNAL(sectionEntered(int)), this, SLOT(onEditSection(int)) );
95   connect( mySectionView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onContextMenu(QPoint)) );
96
97   myLocalPointView = new CurveCreator_TableView( myCurve, this );
98   connect( myLocalPointView, SIGNAL( cellChanged( int, int ) ),
99            this, SLOT( onCellChanged( int, int ) ) );
100
101   QToolBar* aTB = new QToolBar(tr("TOOL_BAR_TLT"), aSectionGroup);
102 //    QToolButton* anUndoBtn = new QToolButton(aTB);
103
104   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
105   QPixmap anUndoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_UNDO")));
106   QPixmap aRedoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_REDO")));
107   QPixmap aNewSectionPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_SECTION")));
108   QPixmap aNewPointPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_POINT")));
109   QPixmap anEditPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
110   QPixmap aDetectPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
111   QPixmap aPolylinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
112   QPixmap aSplinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
113   QPixmap aRemovePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_DELETE")));
114   QPixmap aJoinPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_JOIN")));
115   QPixmap aStepUpPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_UP")));
116   QPixmap aStepDownPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_DOWN")));
117
118   QAction* anAct = createAction( UNDO_ID, tr("UNDO"), anUndoPixmap, tr("UNDO_TLT"), 
119                                  QKeySequence(Qt::ControlModifier|Qt::Key_Z) );
120   connect(anAct, SIGNAL(triggered()), this, SLOT(onUndo()) );
121   aTB->addAction(anAct);
122
123   anAct = createAction( REDO_ID, tr("REDO"), aRedoPixmap, tr("REDO_TLT"), 
124                         QKeySequence(Qt::ControlModifier|Qt::Key_Y) );
125   connect(anAct, SIGNAL(triggered()), this, SLOT(onRedo()) );
126   aTB->addAction(anAct);
127
128   aTB->addSeparator();
129
130   anAct = createAction( NEW_SECTION_ID, tr("NEW_SECTION"), aNewSectionPixmap, tr("NEW_SECTION_TLT"), 
131                         QKeySequence(Qt::ControlModifier|Qt::Key_N) );
132   connect(anAct, SIGNAL(triggered()), this, SLOT(onNewSection()) );
133   aTB->addAction(anAct);
134   aTB->addSeparator();
135
136   anAct = createAction( ADDITION_MODE_ID, tr("ADDITION_MODE"), aNewPointPixmap, tr("ADDITION_MODE_TLT"), 
137                         QKeySequence() );
138   anAct->setCheckable(true);
139   connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onAdditionMode(bool)) );
140   connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
141   aTB->addAction(anAct);
142   
143   anAct = createAction( MODIFICATION_MODE_ID, tr("MODIFICATION_MODE"), anEditPointsPixmap, tr("MODIFICATION_MODE_TLT"), 
144                         QKeySequence() );
145   anAct->setCheckable(true);
146   connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onModificationMode(bool)) );
147   connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
148   aTB->addAction(anAct);
149
150   anAct = createAction( DETECTION_MODE_ID, tr("DETECTION_MODE"), aDetectPointsPixmap, tr("DETECTION_MODE_TLT"), 
151                         QKeySequence() );
152   anAct->setCheckable(true);
153   connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onDetectionMode(bool)) );
154   connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
155   aTB->addAction(anAct);
156
157   anAct = createAction( CLOSE_SECTIONS_ID, tr("CLOSE_SECTIONS"), QPixmap(), tr("CLOSE_SECTIONS_TLT"), 
158                         QKeySequence(Qt::ControlModifier|Qt::Key_W) );
159   connect(anAct, SIGNAL(triggered()), this, SLOT(onCloseSections()) );
160
161   anAct = createAction( UNCLOSE_SECTIONS_ID, tr("UNCLOSE_SECTIONS"), QPixmap(), 
162                         tr("UNCLOSE_SECTIONS_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_S) );
163   connect(anAct, SIGNAL(triggered()), this, SLOT(onUncloseSections()) );
164
165   anAct = createAction( SET_SECTIONS_POLYLINE_ID, tr("SET_SECTIONS_POLYLINE"), 
166                         aPolylinePixmap, tr("SET_POLYLINE_TLT"), 
167                         QKeySequence(Qt::ControlModifier|Qt::Key_E) );
168   connect(anAct, SIGNAL(triggered()), this, SLOT(onSetPolyline()) );
169
170   anAct = createAction( SET_SECTIONS_SPLINE_ID, tr("SET_SECTIONS_SPLINE"), aSplinePixmap, 
171                         tr("SET_SPLINE_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_R) );
172   connect(anAct, SIGNAL(triggered()), this, SLOT(onSetSpline()) );
173
174   anAct = createAction( REMOVE_ID, tr("REMOVE"), aRemovePixmap, tr("REMOVE_TLT"), 
175                         QKeySequence(Qt::ControlModifier|Qt::Key_Delete ) );
176   connect(anAct, SIGNAL(triggered()), this, SLOT(onRemove()) );
177   aTB->addAction(anAct);
178   // TODO join
179   //aTB->addSeparator();
180
181   //anAct = createAction( JOIN_ID, tr("JOIN"), aJoinPixmap, tr("JOIN_TLT"), 
182   //                      QKeySequence(Qt::ControlModifier|Qt::Key_Plus ) );
183   //connect( anAct, SIGNAL(triggered()), this, SLOT(onJoin()) );
184   //aTB->addAction(anAct);
185
186   anAct = createAction( CLEAR_ALL_ID, tr("CLEAR_ALL"), QPixmap(), tr("CLEAR_ALL_TLT"), 
187                         QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Delete ) );
188   connect( anAct, SIGNAL(triggered()), this, SLOT( onClearAll()) );
189
190   // TODO join
191   //anAct = createAction( JOIN_ALL_ID, tr("JOIN_ALL"), QPixmap(), tr("JOIN_ALL_TLT"), 
192   //                      QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Plus ) );
193   //connect( anAct, SIGNAL(triggered()), this, SLOT(onJoinAll()) );
194
195   QVBoxLayout* aSectLayout = new QVBoxLayout();
196   aSectLayout->setMargin( 5 );
197   aSectLayout->setSpacing( 5 );
198   aSectLayout->addWidget(aTB);
199   aSectLayout->addWidget(mySectionView);
200   aSectLayout->addWidget( myLocalPointView );
201   aSectionGroup->setLayout(aSectLayout);
202   QVBoxLayout* aLay = new QVBoxLayout();
203   aLay->setMargin( 0 );
204   aLay->setSpacing( 5 );
205 //    aLay->addLayout(aNameLayout);
206   aLay->addWidget(aSectionGroup);
207   setLayout(aLay);
208
209   updateActionsStates();
210   updateUndoRedo();
211 }
212
213 /**
214  * Set an OCC viewer
215  */
216 void CurveCreator_Widget::setOCCViewer( OCCViewer_Viewer* theViewer )
217 {
218   if ( myOCCViewer == theViewer )
219     return;
220
221   if ( myOCCViewer ) {
222     OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
223                                                     ( myOCCViewer->getViewManager() );
224     disconnect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
225            this, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ) );
226     disconnect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
227            this, SLOT( onMouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ) );
228     disconnect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
229            this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
230     disconnect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
231            this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
232     // restore normal mode in the viewer
233     OCCViewer_Utilities::setViewer2DMode( myOCCViewer, OCCViewer_ViewWindow::No2dMode );
234     // all local contexts should be closed if the viewer is not more used
235     setLocalPointContext( false, true );
236   }
237
238   myOCCViewer = theViewer;
239   if ( myOCCViewer ) {
240     OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
241                                                     ( myOCCViewer->getViewManager() );
242     connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
243            this, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ) );
244     connect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
245            this, SLOT( onMouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ) );
246     connect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
247            this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
248     connect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
249            this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
250     OCCViewer_Utilities::setViewer2DMode( myOCCViewer, OCCViewer_ViewWindow::XYPlane );
251   }
252 }
253
254 /**
255  * Returns current OCC viewer
256  */
257 OCCViewer_Viewer* CurveCreator_Widget::getOCCViewer()
258 {
259   return myOCCViewer;
260 }
261
262 /**
263  * Returns OCC viewer context
264  */
265 Handle(AIS_InteractiveContext) CurveCreator_Widget::getAISContext()
266 {
267   Handle(AIS_InteractiveContext) aContext;
268   OCCViewer_Viewer* aViewer = getOCCViewer();
269   if ( aViewer )
270     aContext = aViewer->getAISContext();
271
272   return aContext;
273 }
274
275 /**
276  * Returns OCC viewer view port
277  */
278 OCCViewer_ViewPort3d* CurveCreator_Widget::getViewPort()
279 {
280   OCCViewer_ViewPort3d* aViewPort = 0;
281   OCCViewer_Viewer* aViewer = getOCCViewer();
282   if ( aViewer )
283     aViewPort = ((OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView())->getViewPort();
284     
285   return aViewPort;
286 }
287
288 /**
289  * Set interaction style in the OCC viewer
290  * \param theStyle a new style
291  * \return the previous style
292  */
293 int CurveCreator_Widget::changeInteractionStyle( int theStyle )
294 {
295   OCCViewer_Viewer* aViewer = getOCCViewer();
296   if ( !aViewer )
297     return -1;
298
299   int aPrevStyle = aViewer->interactionStyle();
300   aViewer->setInteractionStyle( theStyle );
301
302   return aPrevStyle;
303 }
304
305 /**
306  * Set interaction style in the OCC viewer
307  * \param theStyle a new style
308  * \return the previous style
309  */
310 void CurveCreator_Widget::setObjectsSelected(const AIS_ListOfInteractive& theList)
311 {
312   OCCViewer_Viewer* aViewer = getOCCViewer();
313   if ( aViewer )
314     aViewer->setObjectsSelected(theList);
315 }
316
317 //=======================================================================
318 // function: reset
319 // purpose: reset the widget viewer, close local context, clear selection
320 //=======================================================================
321 void CurveCreator_Widget::reset()
322 {
323 }
324
325 void CurveCreator_Widget::setCurve( CurveCreator_ICurve* theCurve )
326 {
327   myCurve = theCurve;
328   mySectionView->setCurve( myCurve );
329   myLocalPointView->setCurve( myCurve );
330   updateActionsStates();
331   updateUndoRedo();
332 }
333
334 void CurveCreator_Widget::onSelectionChanged()
335 {
336   updateActionsStates();
337   updateUndoRedo();
338   emit selectionChanged();
339 }
340
341 void CurveCreator_Widget::updateActionsStates()
342 {
343   QList<ActionId> anEnabledAct;
344   if( myCurve ){
345     anEnabledAct << NEW_SECTION_ID << MODIFICATION_MODE_ID;
346     if ( removeEnabled() )
347       anEnabledAct << REMOVE_ID;
348     QList<int> aSelSections = mySectionView->getSelectedSections();
349     QList< QPair< int, int > > aSelPoints = mySectionView->getSelectedPoints();
350     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
351     switch( aSelType ){
352     case CurveCreator_TreeView::ST_NOSEL:{
353       break;
354     }
355     case CurveCreator_TreeView::ST_SECTIONS:{
356       /*if( aSelSections[0] > 0 ){
357         anEnabledAct << UP_ID;
358       }*/
359       if( aSelSections.size() == 1 ){
360         anEnabledAct << ADDITION_MODE_ID << DETECTION_MODE_ID;
361       }
362       switch ( getActionMode() ) {
363         case AdditionMode: {
364           mySection = -1;
365           myPointNum = -1;
366           QList<int> aSelSection = mySectionView->getSelectedSections();
367           if( aSelSection.size() > 0 ){
368             mySection = aSelSection[0];
369             myPointNum = myCurve->getNbPoints(mySection);
370           }
371         }
372         break;
373         case ModificationMode: {
374          anEnabledAct << CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID << SET_SECTIONS_SPLINE_ID;
375           int aSectCnt = myCurve->getNbSections();
376           if( aSectCnt > 0 )
377             anEnabledAct << CLEAR_ALL_ID;
378           // TODO
379           //if( aSectCnt > 1 )
380           //  anEnabledAct << JOIN_ALL_ID;
381           //if( aSelSections.size() > 1 ){
382           //  anEnabledAct << JOIN_ID;
383           //}
384         }
385         break;
386         case DetectionMode: {
387         }
388         break;
389         case NoneMode:
390         default:
391         break;
392       }
393       /*if( aSelSections[ aSelSections.size() - 1 ] < ( myCurve->getNbSections() - 1 ) ){
394         anEnabledAct << DOWN_ID;
395       }*/
396       break;
397     }
398     /*case CurveCreator_TreeView::ST_POINTS_ONE_SECTION:{
399       if( aSelPoints[0].second > 0 ){
400         anEnabledAct << UP_ID;
401       }
402       int aLastIndex = aSelPoints.size()-1;
403       int aSect = aSelPoints[0].first;
404       if( aSelPoints[aLastIndex].second < (myCurve->getNbPoints(aSect) - 1)){
405         anEnabledAct << DOWN_ID;
406       }
407       if( aSelPoints.size() == 1){
408         anEnabledAct << INSERT_POINT_BEFORE_ID << INSERT_POINT_AFTER_ID;
409       }
410       break;
411     }*/
412
413     }
414     
415     /*int aSelObjsCnt = aSelPoints.size() + aSelSections.size();
416     if( aSelObjsCnt > 0 ){
417       anEnabledAct << REMOVE_ID;
418     }
419     if( (myCurve->getNbSections() + myCurve->getNbPoints()) > 0 ){
420       anEnabledAct << REMOVE_ALL_ID;
421     }*/
422     // TODO
423     //if( myCurve->getNbSections() > 1 ){
424     //  anEnabledAct << JOIN_ALL_ID;
425     //}
426   }
427   QList<ActionId> anIds = myActionMap.keys();
428   for( int i = 0 ; i < anIds.size() ; i++ ){
429     if( myActionMap.contains(anIds[i]) ){
430       if( anEnabledAct.contains(anIds[i]) ){
431         myActionMap[anIds[i]]->setEnabled(true);
432       }
433       else{
434         myActionMap[anIds[i]]->setEnabled(false);
435       }
436     }
437   }
438 }
439
440 void CurveCreator_Widget::onAdditionMode(bool checked)
441 {
442   if (!checked)
443     return;
444
445   Handle(AIS_InteractiveContext) aContext = getAISContext();
446   if( !myCurve || aContext.IsNull() )
447     return;
448
449   mySection= -1;
450   myPointNum = -1;
451   QList<int> aSelSection = mySectionView->getSelectedSections();
452   if( aSelSection.size() > 0 ){
453     mySection = aSelSection[0];
454   }
455   else{
456     QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
457     if( aSelPoints.size() > 0 ){
458       mySection = aSelPoints[0].first;
459       myPointNum = aSelPoints[0].second + 1;
460     }
461   }
462 //  emit subOperationStarted( myNewPointEditor );
463 }
464
465 void CurveCreator_Widget::onModificationMode(bool checked)
466 {
467   myLocalPointView->setVisible( checked );
468 }
469
470 void CurveCreator_Widget::onDetectionMode(bool checked)
471 {
472 }
473
474 void CurveCreator_Widget::onModeChanged(bool checked)
475 {
476   ActionMode aMode = NoneMode;
477   if (checked) {
478     QAction* anAction = (QAction*)sender();
479     switch(myActionMap.key(anAction)) {
480       case ADDITION_MODE_ID:
481         aMode = AdditionMode;
482         if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
483           myActionMap[MODIFICATION_MODE_ID]->trigger();
484         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
485           myActionMap[DETECTION_MODE_ID]->trigger();
486         break;
487       case MODIFICATION_MODE_ID:
488         aMode = ModificationMode;
489         if (myActionMap[ADDITION_MODE_ID]->isChecked())
490           myActionMap[ADDITION_MODE_ID]->trigger();
491         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
492           myActionMap[DETECTION_MODE_ID]->trigger();
493         break;
494       case DETECTION_MODE_ID:
495         aMode = DetectionMode;
496         if (myActionMap[ADDITION_MODE_ID]->isChecked())
497           myActionMap[ADDITION_MODE_ID]->trigger();
498         else if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
499           myActionMap[MODIFICATION_MODE_ID]->trigger();
500         break;
501     }
502   }
503   updateActionsStates();
504   updateUndoRedo();
505   setLocalPointContext( aMode == ModificationMode, true );
506 }
507
508 void CurveCreator_Widget::onAddNewPoint(const CurveCreator::Coordinates& theCoords)
509 {
510   if( !myCurve )
511     return;
512   //myCurve->addPoints(theCoords, mySection, myPointNum );
513   //mySectionView->pointsAdded( mySection, myPointNum );
514   //myPointNum++;
515   QList<int> aSections = mySectionView->getSelectedSections();
516   if( aSections.size() == 0 ){
517     return;
518   }
519   int aSection = aSections[0];
520   myCurve->addPoints(theCoords, aSection); // add to the end of section
521   mySectionView->pointsAdded( aSection, myCurve->getNbPoints( aSection ) );
522   updateActionsStates();
523   updateUndoRedo();
524 }
525
526 void CurveCreator_Widget::onNewSection()
527 {
528   if( !myCurve )
529     return;
530   myNewSectionEditor->clear();
531   myNewSectionEditor->setEditMode(false);
532   QString aSectName = QString( CurveCreator_UtilsICurve::getUniqSectionName( myCurve ).c_str() );
533   myNewSectionEditor->setSectionParameters(aSectName, true, CurveCreator::Polyline );
534   emit subOperationStarted( myNewSectionEditor );
535 }
536
537 void CurveCreator_Widget::onAddNewSection()
538 {
539   if( !myCurve )
540     return;
541   myCurve->addSection( myNewSectionEditor->getName().toStdString(),
542                        myNewSectionEditor->getSectionType(),
543                        myNewSectionEditor->isClosed() );
544   mySectionView->sectionAdded( -1 ); // add a new section to the end of list
545   QString aNewName = QString( CurveCreator_UtilsICurve::getUniqSectionName( myCurve ).c_str() );
546   myNewSectionEditor->setSectionName(aNewName);
547   updateActionsStates();
548   updateUndoRedo();
549   onCancelSection();
550 }
551
552 void CurveCreator_Widget::onCancelSection()
553 {
554   emit subOperationFinished( myNewSectionEditor );
555 }
556
557 QAction* CurveCreator_Widget::createAction( ActionId theId, const QString& theName, const QPixmap& theImage,
558                                             const QString& theToolTip, const QKeySequence& theShortcut )
559 {
560   QAction* anAct = new QAction(theName,this);
561   if( !theImage.isNull() ){
562     anAct->setIcon(theImage);
563   }
564   anAct->setShortcut(theShortcut);
565   anAct->setToolTip(theToolTip);
566   myActionMap[theId] = anAct;
567   return anAct;
568 }
569
570 QAction* CurveCreator_Widget::getAction(ActionId theId)
571 {
572   if( myActionMap.contains(theId) )
573     return myActionMap[theId];
574   return NULL;
575 }
576
577 CurveCreator_Widget::ActionMode CurveCreator_Widget::getActionMode() const
578 {
579   ActionMode aMode = NoneMode;
580
581   if ( myActionMap[ADDITION_MODE_ID]->isChecked() )
582     aMode = AdditionMode;
583   else if ( myActionMap[MODIFICATION_MODE_ID]->isChecked() )
584     aMode = ModificationMode;
585   else if ( myActionMap[DETECTION_MODE_ID]->isChecked() )
586     aMode = DetectionMode;
587
588   return aMode;
589 }
590
591 void CurveCreator_Widget::onEditSection( int theSection )
592 {
593   if( !myCurve )
594     return;
595   mySection = theSection;
596   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
597   bool isClosed = myCurve->isClosed(theSection);
598   CurveCreator::SectionType aType = myCurve->getSectionType(theSection);
599   myNewSectionEditor->setEditMode(true);
600   myNewSectionEditor->setSectionParameters( aSectName, isClosed, aType );
601
602   emit subOperationStarted( myNewSectionEditor );
603 }
604
605 void CurveCreator_Widget::onModifySection()
606 {
607   if( !myCurve )
608     return;
609   QString aName = myNewSectionEditor->getName();
610   bool isClosed = myNewSectionEditor->isClosed();
611   CurveCreator::SectionType aSectType = myNewSectionEditor->getSectionType();
612 //  myCurve->startOperation();
613   if( myCurve->getSectionName(mySection) != aName.toStdString() )
614     myCurve->setSectionName( mySection , aName.toStdString() );
615
616   if( myCurve->getSectionType(mySection) != aSectType )
617     myCurve->setSectionType( mySection, aSectType );
618
619   if( myCurve->isClosed(mySection) != isClosed )
620     myCurve->setClosed( mySection, isClosed );
621 //  myCurve->finishOperation();
622   mySectionView->sectionChanged(mySection);
623   updateUndoRedo();
624   onCancelSection();
625 }
626
627 /*void CurveCreator_Widget::onEditPoint( int theSection, int thePoint )
628 {
629   if( !myNewPointEditor || !myEdit )
630     return;
631   mySection = theSection;
632   myPointNum = thePoint;
633   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
634   myNewPointEditor->setEditMode(true);
635   myNewPointEditor->setSectionName(aSectName);
636   myNewPointEditor->setDimension( myCurve->getDimension() );
637   CurveCreator::Coordinates aCoords = myCurve->getCoordinates(theSection,thePoint);
638   myNewPointEditor->setCoordinates(aCoords);
639   emit subOperationStarted( myNewPointEditor );
640 }
641
642 void CurveCreator_Widget::onModifyPoint()
643 {
644   if( !myEdit )
645     return;
646   CurveCreator::Coordinates aCoords = myNewPointEditor->getCoordinates();
647   myEdit->setCoordinates( aCoords, mySection, myPointNum );
648   mySectionView->pointDataChanged( mySection, myPointNum );
649   updateUndoRedo();
650   onCancelPoint();
651 }*/
652
653 void CurveCreator_Widget::onJoin()
654 {
655   if( !myCurve )
656     return;
657   QList<int> aSections = mySectionView->getSelectedSections();
658   if( aSections.size() == 0 ){
659     return;
660   }
661   int aMainSect = aSections[0];
662   int aMainSectSize = myCurve->getNbPoints(aMainSect);
663 //  myCurve->startOperation();
664   for( int i = 1 ; i < aSections.size() ; i++ ){
665     int aSectNum = aSections[i] - (i-1);
666     myCurve->join( aMainSect, aSectNum );
667     mySectionView->sectionsRemoved( aSectNum );
668   }
669 //  myCurve->finishOperation();
670   int aNewSectSize = myCurve->getNbPoints(aMainSect);
671   if( aNewSectSize != aMainSectSize )
672     mySectionView->pointsAdded( aMainSect, aMainSectSize, aNewSectSize-aMainSectSize );
673   updateUndoRedo();
674 }
675
676 void CurveCreator_Widget::onRemove()
677 {
678   if( !myCurve )
679     return;
680
681   switch( getActionMode() ) {
682     case NoneMode:
683       removeSection();
684     break;
685     case ModificationMode:
686       removePoint();
687     break;
688     default:
689       break;
690   }
691 }
692
693 void CurveCreator_Widget::onClearAll()
694 {
695   if( !myCurve )
696     return;
697   myCurve->clear();
698   mySectionView->reset();
699   updateActionsStates();
700   updateUndoRedo();
701 }
702
703 void CurveCreator_Widget::onJoinAll()
704 {
705   if( !myCurve )
706     return;
707   myCurve->join();
708   mySectionView->reset();
709   updateActionsStates();
710   updateUndoRedo();
711 }
712
713 void CurveCreator_Widget::onUndoSettings()
714 {
715
716 }
717
718 void CurveCreator_Widget::onSetSpline()
719 {
720   if( !myCurve )
721     return;
722   QList<int> aSelSections = mySectionView->getSelectedSections();
723 //  myCurve->startOperation();
724   for( int i = 0 ; i < aSelSections.size() ; i++ ){
725     myCurve->setSectionType(aSelSections[i], CurveCreator::Spline );
726     mySectionView->sectionChanged(aSelSections[i]);
727   }
728 //  myCurve->finishOperation();
729   updateUndoRedo();
730 }
731
732 void CurveCreator_Widget::onSetPolyline()
733 {
734   if( !myCurve )
735     return;
736 //  myCurve->startOperation();
737   QList<int> aSelSections = mySectionView->getSelectedSections();
738   for( int i = 0 ; i < aSelSections.size() ; i++ ){
739     myCurve->setSectionType( aSelSections[i], CurveCreator::Polyline );
740     mySectionView->sectionChanged( aSelSections[i] );
741   }
742 //  myCurve->finishOperation();
743   updateUndoRedo();
744 }
745
746 void CurveCreator_Widget::onCloseSections()
747 {
748   if( !myCurve )
749     return;
750 //  myCurve->startOperation();
751   QList<int> aSelSections = mySectionView->getSelectedSections();
752   for( int i = 0 ; i < aSelSections.size() ; i++ ){
753     myCurve->setClosed(aSelSections[i], true);
754     mySectionView->sectionChanged(aSelSections[i]);
755   }
756 //  myCurve->finishOperation();
757   updateUndoRedo();
758 }
759
760 void CurveCreator_Widget::onUncloseSections()
761 {
762   if( !myCurve )
763     return;
764 //  myCurve->startOperation();
765   QList<int> aSelSections = mySectionView->getSelectedSections();
766   for( int i = 0 ; i < aSelSections.size() ; i++ ){
767     myCurve->setClosed(aSelSections[i], false);
768     mySectionView->sectionChanged(aSelSections[i]);
769   }
770 //  myCurve->finishOperation();
771   updateUndoRedo();
772 }
773
774 void CurveCreator_Widget::onUndo()
775 {
776     if( !myCurve )
777       return;
778
779     CurveCreator_ICurve::SectionToPointList aPoints;
780     startCurveModification( aPoints, false );
781     myCurve->undo();
782     finishCurveModification();
783     mySectionView->reset();
784 }
785
786 void CurveCreator_Widget::onRedo()
787 {
788     if( !myCurve )
789       return;
790     CurveCreator_ICurve::SectionToPointList aPoints;
791     startCurveModification( aPoints, false );
792     myCurve->redo();
793     finishCurveModification();
794     mySectionView->reset();
795 }
796
797 void CurveCreator_Widget::updateUndoRedo()
798 {
799   if( !myCurve )
800     return;
801   QAction* anAct = myActionMap[UNDO_ID];
802   if( anAct != 0 ){
803     if( myCurve->getNbUndo() != 0 ){
804       anAct->setEnabled(true);
805     }
806     else{
807       anAct->setDisabled(true);
808     }
809   }
810   anAct = myActionMap[REDO_ID];
811   if( anAct != 0 ){
812     if( myCurve->getNbRedo() != 0 ){
813       anAct->setEnabled(true);
814     }
815     else{
816       anAct->setDisabled(true);
817     }
818   }
819 }
820
821 void CurveCreator_Widget::onContextMenu( QPoint thePoint )
822 {
823   QList<ActionId> aContextActions;
824   aContextActions << CLEAR_ALL_ID << JOIN_ALL_ID << SEPARATOR_ID <<
825                      CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID <<
826                      SET_SECTIONS_SPLINE_ID;
827   QPoint aGlPoint = mySectionView->mapToGlobal(thePoint);
828   bool isVis = false;
829   QList<ActionId> aResAct;
830   for( int i = 0 ; i < aContextActions.size() ; i++ ){
831     if( aContextActions[i] != SEPARATOR_ID ){
832       if( myActionMap.contains(aContextActions[i]) ){
833         QAction* anAct = myActionMap[aContextActions[i]];
834         if( anAct->isEnabled() ){
835           aResAct << aContextActions[i];
836           isVis = true;
837         }
838       }
839     }
840     else{
841       aResAct << SEPARATOR_ID;
842     }
843   }
844   if( !isVis )
845     return;
846
847   QMenu* aMenu = new QMenu(this);
848   for( int i = 0 ; i < aResAct.size() ; i++ ){
849     if( aResAct[i] == SEPARATOR_ID ){
850       aMenu->addSeparator();
851     }
852     else{
853       QAction* anAct = myActionMap[aResAct[i]];
854       aMenu->insertAction(NULL, anAct);
855     }
856   }
857   aMenu->exec(aGlPoint);
858 }
859
860 QList<int> CurveCreator_Widget::getSelectedSections()
861 {
862   return mySectionView->getSelectedSections();
863 }
864
865 QList< QPair< int, int > > CurveCreator_Widget::getSelectedPoints()
866 {
867   return mySectionView->getSelectedPoints();
868 }
869
870 /**
871  * According to the widget state, performs the remove action
872  */
873 void CurveCreator_Widget::removeSelected()
874 {
875   onRemove();
876 }
877
878 /**
879  * Checks whether there are some selection to be removed
880  */
881 bool CurveCreator_Widget::removeEnabled()
882 {
883   bool isEnabled = getActionMode() == ModificationMode;
884   if ( !isEnabled ) {
885     QList<int> aSelSections = mySectionView->getSelectedSections();
886     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
887     isEnabled = aSelType == CurveCreator_TreeView::ST_SECTIONS &&
888                 aSelSections.size() == 1;
889   }
890   return isEnabled;
891 }
892
893
894 //=================================================================================
895 // function : GeometryGUI::onGetCoordsByClick()
896 // purpose  : Manage mouse press events in Additon mode
897 //=================================================================================
898 void CurveCreator_Widget::onGetCoordsByClick( QMouseEvent* pe )
899 {
900   if (pe->button() != Qt::LeftButton)
901     return;
902
903   if ( pe->modifiers() != Qt::ControlModifier ) {
904     Handle(AIS_InteractiveContext) ic = getAISContext();
905     if ( ic.IsNull() )
906       return;
907
908     gp_Pnt aPnt;    
909
910     ic->InitSelected();
911     if ( pe->modifiers() == Qt::ShiftModifier )
912       ic->ShiftSelect();  // Append selection
913     else
914       ic->Select();       // New selection
915
916     /*TopoDS_Shape aShape;
917
918     ic->InitSelected();
919     if ( ic->MoreSelected() )
920       aShape = ic->SelectedShape();
921
922     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
923       aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
924     else*/
925     {
926       OCCViewer_ViewPort3d* vp = getViewPort();
927       aPnt = CurveCreator_Utils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
928     }
929     // set the coordinates into dialog
930     CurveCreator::Coordinates aCoords;
931     aCoords.push_back( aPnt.X() );
932     aCoords.push_back( aPnt.Y() );
933     if ( myCurve->getDimension() == 3 ) {
934       aCoords.push_back( aPnt.Z() );
935     }
936     onAddNewPoint(aCoords);
937 //    myNewPointEditor->setCoordinates( aCoords );
938   }
939 }
940
941 /**
942  * Manage mouse press events
943  * \param theWindow an owner of the signal
944  * \param theEvent a mouse event
945  */
946 void CurveCreator_Widget::onMousePress( SUIT_ViewWindow*, QMouseEvent* theEvent )
947 {
948   if ( theEvent->button() != Qt::LeftButton )
949     return;
950
951   switch( getActionMode() ) {
952     case ModificationMode: {
953       //store initial cursor position for Drag&Drop
954       setDragStarted( true, theEvent->pos() );
955       break;
956     }
957     case AdditionMode: {
958       onGetCoordsByClick( theEvent );
959       break;
960     }
961     default:
962       break;
963   }
964 }
965
966 /**
967  * Manage mouse release events in Modification mode
968  * \param theWindow an owner of the signal
969  * \param theEvent a mouse event
970  */
971 void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow*, QMouseEvent* theEvent )
972 {
973   if ( getActionMode() != ModificationMode )
974     return;
975
976   if ( myDragStarted ) {
977     bool isDragged = myDragged;
978     CurveCreator_ICurve::SectionToPointList aDraggedPoints;
979     if ( myDragged )
980       aDraggedPoints = myDragPoints;
981
982     setDragStarted( false );
983     // if the drag of some points has happened, restore the drag selection
984     if ( aDraggedPoints.size() > 0 )
985       setSelectedPonts( aDraggedPoints );
986   }
987   else // check whether the segment is clicked an a new point should be added to the segment
988     insertPointToSelectedSegment( theEvent->pos().x(), theEvent->pos().y() );
989
990   // updates the input panel table to show the selected point coordinates
991   updateLocalPointView();
992 }
993
994 /**
995  * Manage mouse move events in Modification mode
996  * \param theWindow an owner of the signal
997  * \param theEvent a mouse event
998  */
999 void CurveCreator_Widget::onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent )
1000 {
1001   if ( getActionMode() != ModificationMode || !myDragStarted )
1002     return;
1003
1004   QPoint aPos = theEvent->pos();
1005   if ( (aPos - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
1006     return;
1007
1008   moveSelectedPoints( aPos.x(), aPos.y() );
1009   myDragStartPosition = aPos;
1010 }
1011
1012 /**
1013  * Set zero viewer by the last view closed in
1014  * \param theManager a viewer manager
1015  */
1016 void CurveCreator_Widget::onLastViewClosed( SUIT_ViewManager* theManager )
1017 {
1018   myOCCViewer = 0;
1019 }
1020
1021 void CurveCreator_Widget::onMousePress( QMouseEvent* theEvent )
1022 {
1023   onMousePress( 0, theEvent );
1024 }
1025
1026 void CurveCreator_Widget::onMouseRelease( QMouseEvent* theEvent )
1027 {
1028   onMouseRelease( 0, theEvent );
1029 }
1030
1031 void CurveCreator_Widget::onMouseMove( QMouseEvent* theEvent )
1032 {
1033   onMouseMove( 0, theEvent );
1034 }
1035
1036 void CurveCreator_Widget::onCellChanged( int theRow, int theColumn )
1037 {
1038   int aCurrSect = myLocalPointView->getSectionId( theRow );
1039   int aPntIndex = myLocalPointView->getPointId( theRow );
1040
1041   if ( aPntIndex < 0 )
1042     return;
1043
1044   CurveCreator_ICurve::SectionToPointList aSelPoints;
1045   startCurveModification( aSelPoints );
1046
1047   double aX  = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
1048   double anY = myLocalPointView->item( theRow, 3 )->data( Qt::UserRole ).toDouble();
1049   std::deque<float> aChangedPos;
1050   aChangedPos.push_back( aX );
1051   aChangedPos.push_back( anY );
1052   myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
1053
1054   finishCurveModification( aSelPoints );
1055 }
1056
1057 /**
1058  * Removes a selected section from the curve. Updates undo/redo status
1059  */
1060 void CurveCreator_Widget::removeSection()
1061 {
1062   QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
1063   int aCurrSect=-1;
1064   int aRemoveCnt = 0;
1065 //  myCurve->startOperation();
1066   for( int i = 0 ; i < aSelPoints.size() ; i++ ){
1067     if( aCurrSect != aSelPoints[i].first ){
1068       aRemoveCnt = 0;
1069       aCurrSect = aSelPoints[i].first;
1070     }
1071     int aPntIndx = aSelPoints[i].second - aRemoveCnt;
1072     myCurve->removePoint( aCurrSect, aPntIndx );
1073     mySectionView->pointsRemoved( aCurrSect, aPntIndx );
1074     aRemoveCnt++;
1075   }
1076   QList<int> aSections = mySectionView->getSelectedSections();
1077   for( int i = 0 ; i < aSections.size() ; i++ ){
1078     int aSectNum = aSections[i] - (i);
1079     myCurve->removeSection( aSectNum );
1080     mySectionView->sectionsRemoved( aSectNum );
1081   }
1082 //  myCurve->finishOperation();
1083   mySectionView->clearSelection();
1084   updateUndoRedo();
1085 }
1086
1087 /**
1088  * Removes a selected points from the curve. Updates undo/redo status
1089  */
1090 void CurveCreator_Widget::removePoint()
1091 {
1092   CurveCreator_ICurve::SectionToPointList aPoints;
1093   getSelectedPonts( aPoints );
1094   if ( aPoints.size() == 0 )
1095     return;
1096
1097   CurveCreator_ICurve::SectionToPointList aSelPoints;
1098   startCurveModification( aSelPoints, false );
1099
1100   myCurve->removeSeveralPoints( aPoints );
1101   finishCurveModification( CurveCreator_ICurve::SectionToPointList() );
1102 }
1103
1104 void CurveCreator_Widget::insertPointToSelectedSegment( const int theX,
1105                                                         const int theY )
1106 {
1107   Handle(AIS_InteractiveContext) aContext = getAISContext();
1108
1109   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1110   Handle(V3d_View) aView;
1111   if ( aViewPort )
1112     aView = aViewPort->getView();
1113
1114   if ( aContext.IsNull() || aView.IsNull() )
1115     return;
1116   gp_Pnt aPoint;
1117   gp_Pnt aPoint1, aPoint2;
1118   bool isFoundPoint = CurveCreator_Utils::getNeighbourPoints( aContext, aView, theX, theY,
1119                                                               aPoint, aPoint1, aPoint2 );
1120   if ( !isFoundPoint )
1121     return;
1122
1123   // insert the point to the model curve
1124   CurveCreator_ICurve::SectionToPointList aSelPoints;
1125   startCurveModification( aSelPoints );
1126
1127   CurveCreator::Coordinates aCoords;
1128   aCoords.push_back( aPoint.X() );
1129   aCoords.push_back( aPoint.Y() );
1130
1131   CurveCreator_ICurve::SectionToPointList aPoints1, aPoints2;
1132   findSectionsToPoints( aPoint1.X(), aPoint1.Y(), aPoints1 );
1133   findSectionsToPoints( aPoint2.X(), aPoint2.Y(), aPoints2 );
1134   CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aPoints1.begin(),
1135                                                           aLast = aPoints1.end();
1136   int aSectionId = -1;
1137   // there can be a case when a new point is added into two sections
1138   int aPoint1Id = -1, aPoint2Id = -1;
1139   for ( ; anIt != aLast && aSectionId < 0; anIt++ ) {
1140     int aSectionCur = anIt->first;
1141     CurveCreator_ICurve::SectionToPointList::const_iterator anIt2 = aPoints2.begin(),
1142                                                             aLast2 = aPoints2.end();
1143     for ( ; anIt2 != aLast2 && aSectionId < 0; anIt2++ ) {
1144       if ( anIt2->first == aSectionCur ) {
1145         aSectionId = aSectionCur;
1146         aPoint1Id = anIt->second;
1147         aPoint2Id = anIt2->second;
1148       }
1149     }
1150   }
1151
1152   int anInsertPos = -1;
1153   int aLastPoint = myCurve->getNbPoints( aSectionId )-1; 
1154   if ( ( aPoint1Id == aLastPoint && aPoint2Id == 0 ) ||
1155        ( aPoint2Id == aLastPoint && aPoint1Id == 0 ) )
1156     anInsertPos = -1; // if the section happens between first and last points
1157   else
1158     anInsertPos = aPoint1Id < aPoint2Id ? aPoint1Id + 1 : aPoint2Id + 1;
1159
1160   myCurve->addPoints( aCoords, aSectionId, anInsertPos );
1161   mySectionView->pointsAdded( aSectionId, myCurve->getNbPoints( aSectionId ) );
1162
1163   finishCurveModification( aSelPoints );
1164
1165   setSelectedPonts();
1166 }
1167
1168 void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
1169                                               const int theYPosition )
1170 {
1171   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1172   if ( !aViewPort )
1173     return;
1174
1175   CurveCreator_ICurve::SectionToPointList aPoints;
1176   startCurveModification( aPoints, false );
1177
1178   gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(),
1179                                                               myDragStartPosition.y(),
1180                                                               aViewPort->getView() );
1181   gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( theXPosition, theYPosition,
1182                                                              aViewPort->getView() );
1183   double aXDelta = aStartPnt.X() - anEndPnt.X();
1184   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
1185
1186   CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
1187   std::deque<float> aChangedPos;
1188   CurveCreator_ICurve::SectionToPointList::const_iterator anIt = myDragPoints.begin(),
1189                                                           aLast = myDragPoints.end();
1190   for ( ; anIt != aLast; anIt++ ) {
1191     int aSectionId = anIt->first;
1192     int aPointId = anIt->second;
1193     aChangedPos = myCurve->getPoint( aSectionId, aPointId );
1194     if ( aChangedPos.size() < 2 )
1195       continue;
1196     aChangedPos[0] = aChangedPos[0] - aXDelta;
1197     aChangedPos[1] = aChangedPos[1] - anYDelta;
1198     
1199     aCoordList.push_back(
1200       std::make_pair(std::make_pair( aSectionId, aPointId ), 
1201                      aChangedPos ));
1202   }
1203   myCurve->setSeveralPoints( aCoordList );
1204
1205   myDragged = true;
1206   finishCurveModification( myDragPoints );
1207 }
1208
1209 void CurveCreator_Widget::updateLocalPointView()
1210 {
1211   if ( myDragStarted )
1212     return;
1213   Handle(AIS_InteractiveContext) aContext = getAISContext();
1214   if ( aContext.IsNull() )
1215     return;
1216
1217   std::list<float> aSelectedList = CurveCreator_Utils::getSelectedPoints( aContext );
1218
1219   std::list<float>::const_iterator anIt = aSelectedList.begin(), aLast = aSelectedList.end();
1220
1221   bool isBlocked = myLocalPointView->blockSignals(true);
1222   myLocalPointView->setRowCount( 0 );
1223   for ( ; anIt != aLast; anIt++ )
1224   {
1225     float aX = *anIt;
1226     anIt++;
1227     float anY = *anIt;
1228     anIt++;
1229     float aZ = *anIt;
1230     myLocalPointView->addLocalPointToTable( aX, anY );
1231   }
1232   myLocalPointView->blockSignals(isBlocked);
1233 }
1234
1235 /**
1236  * 
1237  */
1238 void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable )
1239 {
1240   CurveCreator_Utils::setLocalPointContext( getAISContext(), theOpen );
1241   if ( !theOpen && isUpdateTable )
1242     updateLocalPointView();
1243 }
1244
1245 /**
1246  * Set drag operation started. Save the position and a list of dragged points
1247  * \param theState the drag operation state: started/finished
1248  * \param thePoint the start drag position
1249  */
1250 void CurveCreator_Widget::setDragStarted( const bool theState, const QPoint& thePoint )
1251 {
1252   if ( theState ) {
1253     getSelectedPonts( myDragPoints );
1254     myDragStarted = myDragPoints.size();
1255     myDragStartPosition = thePoint;
1256     if ( myDragStarted ) {
1257       // change a viewer interaction style in order to avoid a select rectangle build
1258       myDragInteractionStyle = changeInteractionStyle( SUIT_ViewModel::KEY_FREE );
1259     }
1260   }
1261   else {
1262     if ( myDragStarted )
1263       changeInteractionStyle( myDragInteractionStyle );
1264     myDragStarted = false;
1265     myDragPoints.clear();
1266   }
1267   myDragged = false;
1268 }
1269
1270 void CurveCreator_Widget::getSelectedPonts( CurveCreator_ICurve::SectionToPointList& thePoints )
1271 {
1272   thePoints.clear();
1273   for ( int i = 0, aNb = myLocalPointView->rowCount(); i < aNb; i++ )
1274     thePoints.push_back( std::make_pair( myLocalPointView->getSectionId( i ),
1275                                          myLocalPointView->getPointId( i ) ) );
1276 }
1277
1278
1279 bool CurveCreator_Widget::isIntersectVertexToPoint( const TopoDS_Vertex& theVertex,
1280                                const CurveCreator_ICurve::SectionToPoint& theSToPoint )
1281 {
1282   bool isIntersect = false;
1283   if ( theVertex.IsNull() )
1284     return isIntersect;
1285
1286   gp_Pnt aSPoint;
1287   CurveCreator_UtilsICurve::getPoint( myCurve, theSToPoint.first, theSToPoint.second,
1288                                       aSPoint );
1289   gp_Pnt aVertexPoint = BRep_Tool::Pnt( theVertex );
1290   isIntersect = fabs( aVertexPoint.X() - aSPoint.X() ) < LOCAL_SELECTION_TOLERANCE &&
1291                 fabs( aVertexPoint.Y() - aSPoint.Y() ) < LOCAL_SELECTION_TOLERANCE;
1292
1293   return isIntersect;
1294 }
1295
1296
1297 void CurveCreator_Widget::setSelectedPonts( const CurveCreator_ICurve::SectionToPointList& thePoints )
1298 {
1299   if ( myDragStarted )
1300     return;
1301   Handle(AIS_InteractiveContext) ic = getAISContext();
1302   if ( ic.IsNull() || !ic->HasOpenedContext() )
1303     return;
1304
1305   AIS_ListOfInteractive aListToSelect;
1306
1307   AIS_ListOfInteractive aDisplayedList;
1308   ic->DisplayedObjects( aDisplayedList );
1309   ic->ClearSelected( Standard_False );
1310
1311   CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(),
1312                                                           aLast = thePoints.end();
1313   CurveCreator_ICurve::SectionToPoint aSToPoint;
1314   bool isSelectedVertex = false;
1315   for( ; anIt != aLast; anIt++ ) {
1316     aSToPoint = *anIt;
1317     for ( AIS_ListIteratorOfListOfInteractive it( aDisplayedList ); it.More(); it.Next() )
1318     {
1319       Handle(AIS_InteractiveObject) anAIS = it.Value();
1320       if ( anAIS.IsNull() )
1321         continue;
1322       Handle(AIS_Point) anAISPoint = Handle(AIS_Point)::DownCast( anAIS );
1323       if ( !anAISPoint.IsNull() ) {
1324         TopoDS_Vertex aVertex = TopoDS::Vertex( anAISPoint->Vertex() );
1325         if ( isIntersectVertexToPoint( aVertex, aSToPoint ) )
1326           aListToSelect.Append( anAIS );
1327       }
1328       else {
1329         Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast( anAIS );
1330         if ( anAISShape.IsNull() )
1331           continue;
1332         const TopoDS_Shape& aShape = anAISShape->Shape();
1333         TopExp_Explorer aExpV( aShape, TopAbs_VERTEX);
1334         for ( ; aExpV.More(); aExpV.Next() )
1335         {
1336           const TopoDS_Vertex& aVertex = TopoDS::Vertex( aExpV.Current() );
1337           if ( isIntersectVertexToPoint( aVertex, aSToPoint ) ) {
1338             ic->AddOrRemoveSelected( aVertex, Standard_False );
1339             isSelectedVertex = true;
1340           }
1341         }
1342       }
1343     }
1344   }
1345   ic->UpdateCurrentViewer();
1346   if ( !isSelectedVertex )
1347     setObjectsSelected( aListToSelect );
1348   updateLocalPointView();
1349 }
1350
1351 /**
1352  * Get viewer information before perform the curve modification.
1353  * Take a list of selected cuve points an close local context.
1354  * The context should be closed because the curve presentation is
1355  * redisplayed and if it is not closed, when we close the local context
1356  * later, the presentation shown in the local context is disappeared.
1357  * \param thePoints an output list of curve selected points
1358  * \param theFillPoints a flag whether the selection list should be filled
1359  */
1360 void CurveCreator_Widget::startCurveModification(
1361                            CurveCreator_ICurve::SectionToPointList& thePoints,
1362                            const bool theFillPoints )
1363 {
1364   if ( theFillPoints ) {
1365     thePoints.clear();
1366     getSelectedPonts( thePoints );
1367   }
1368   setLocalPointContext( false );
1369 }
1370
1371 /**
1372  * Restore the viewer state after the curve modification is done.
1373  * Open local context and select given points inside it.
1374  * \param thePoints a list of curve selected points
1375  */
1376 void CurveCreator_Widget::finishCurveModification(
1377                            const CurveCreator_ICurve::SectionToPointList& thePoints )
1378 {
1379   if ( getActionMode() == ModificationMode )
1380     setLocalPointContext( true );
1381   setSelectedPonts( thePoints );
1382   updateUndoRedo();
1383 }
1384
1385 /**
1386  * Returns a point index in the model curve by the point coordinates in the viewer
1387  * \param theX the X coordinate of the point
1388  * \param theY the Y coordinate of the point
1389  */
1390 int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
1391 {
1392   return CurveCreator_UtilsICurve::findLocalPointIndex( myCurve, theSectionId, theX, theY );
1393 }
1394
1395 void CurveCreator_Widget::findSectionsToPoints( const double theX, const double theY,
1396                                  CurveCreator_ICurve::SectionToPointList& thePoints )
1397 {
1398   return CurveCreator_UtilsICurve::findSectionsToPoints( myCurve, theX, theY, thePoints );
1399 }
1400
1401 void CurveCreator_Widget::convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
1402                                    QMap<int, QList<int> >& theConvPoints )
1403 {
1404   return CurveCreator_UtilsICurve::convert( thePoints, theConvPoints );
1405 }
1406
1407 /**
1408  * Returns whethe the container has the value
1409  * \param theList a container of values
1410  * \param theValue a value
1411  */
1412 bool CurveCreator_Widget::contains( const CurveCreator_ICurve::SectionToPointList& theList,
1413                                     const CurveCreator_ICurve::SectionToPoint& theValue ) const
1414 {
1415   return CurveCreator_UtilsICurve::contains( theList, theValue );
1416 }