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