Salome HOME
Hide "Closed" checkbox in new section widget for profiles dialog.
[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 );
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 );
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     if ( myDragged )
976       aDraggedPoints = myDragPoints;
977
978     setDragStarted( false );
979
980     if ( aDraggedPoints.size() > 0 ) {
981       if ( myCurve->canPointsBeSorted() ) {
982         // Apply points sorting
983         CurveCreator_ICurve::SectionToPointList aPoints;
984         startCurveModification( aPoints, false );
985
986         myCurve->setSkipSorting( false );
987
988         CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
989         CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aDraggedPoints.begin(),
990                                                                 aLast = aDraggedPoints.end();
991         for ( ; anIt != aLast; anIt++ ) {
992           int aSectionId = anIt->first;
993           int aPointId = anIt->second;
994           std::deque<float> aPos = myCurve->getPoint( aSectionId, aPointId );
995     
996           aCoordList.push_back(
997             std::make_pair( std::make_pair( aSectionId, aPointId ), aPos ) );
998         }
999
1000         myCurve->setSeveralPoints( aCoordList );
1001     
1002         finishCurveModification( aDraggedPoints );
1003       } else {
1004         // if the drag of some points has happened, restore the drag selection
1005         if ( aDraggedPoints.size() > 0 ) {
1006           START_MEASURE_TIME;
1007           setSelectedPoints( aDraggedPoints );
1008           END_MEASURE_TIME( "drop" );
1009         }
1010       }
1011     }
1012   }
1013   else // check whether the segment is clicked an a new point should be added to the segment
1014     insertPointToSelectedSegment( theEvent->pos().x(), theEvent->pos().y() );
1015
1016   // updates the input panel table to show the selected point coordinates
1017   updateLocalPointView();
1018 }
1019
1020 /**
1021  * Manage mouse move events in Modification mode
1022  * \param theWindow an owner of the signal
1023  * \param theEvent a mouse event
1024  */
1025 void CurveCreator_Widget::onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent )
1026 {
1027   if ( getActionMode() != ModificationMode || !myDragStarted )
1028     return;
1029
1030   QPoint aPos = theEvent->pos();
1031   if ( (aPos - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
1032     return;
1033
1034   START_MEASURE_TIME;
1035
1036   moveSelectedPoints( aPos.x(), aPos.y() );
1037   myDragStartPosition = aPos;
1038
1039   END_MEASURE_TIME( "drag" );
1040 }
1041
1042 /**
1043  * Set zero viewer by the last view closed in
1044  * \param theManager a viewer manager
1045  */
1046 void CurveCreator_Widget::onLastViewClosed( SUIT_ViewManager* theManager )
1047 {
1048   myOCCViewer = 0;
1049 }
1050
1051 void CurveCreator_Widget::onMousePress( QMouseEvent* theEvent )
1052 {
1053   onMousePress( 0, theEvent );
1054 }
1055
1056 void CurveCreator_Widget::onMouseRelease( QMouseEvent* theEvent )
1057 {
1058   onMouseRelease( 0, theEvent );
1059 }
1060
1061 void CurveCreator_Widget::onMouseMove( QMouseEvent* theEvent )
1062 {
1063   onMouseMove( 0, theEvent );
1064 }
1065
1066 void CurveCreator_Widget::onCellChanged( int theRow, int theColumn )
1067 {
1068   int aCurrSect = myLocalPointView->getSectionId( theRow );
1069   int aPntIndex = myLocalPointView->getPointId( theRow );
1070
1071   if ( aPntIndex < 0 )
1072     return;
1073
1074   CurveCreator_ICurve::SectionToPointList aSelPoints;
1075   startCurveModification( aSelPoints );
1076
1077   double aX  = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
1078   double anY = myLocalPointView->item( theRow, 3 )->data( Qt::UserRole ).toDouble();
1079   std::deque<float> aChangedPos;
1080   aChangedPos.push_back( aX );
1081   aChangedPos.push_back( anY );
1082   myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
1083
1084   finishCurveModification( aSelPoints );
1085 }
1086
1087 /**
1088  * Removes a selected section from the curve. Updates undo/redo status
1089  */
1090 void CurveCreator_Widget::removeSection()
1091 {
1092   stopActionMode();
1093
1094   QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
1095   int aCurrSect=-1;
1096   int aRemoveCnt = 0;
1097   for( int i = 0 ; i < aSelPoints.size() ; i++ ){
1098     if( aCurrSect != aSelPoints[i].first ){
1099       aRemoveCnt = 0;
1100       aCurrSect = aSelPoints[i].first;
1101     }
1102     int aPntIndx = aSelPoints[i].second - aRemoveCnt;
1103     myCurve->removePoint( aCurrSect, aPntIndx );
1104     mySectionView->pointsRemoved( aCurrSect, aPntIndx );
1105     aRemoveCnt++;
1106   }
1107   QList<int> aSections = mySectionView->getSelectedSections();
1108   for( int i = 0 ; i < aSections.size() ; i++ ){
1109     int aSectNum = aSections[i] - (i);
1110     myCurve->removeSection( aSectNum );
1111     mySectionView->sectionsRemoved( aSectNum );
1112   }
1113   mySectionView->clearSelection();
1114   updateUndoRedo();
1115 }
1116
1117 /**
1118  * Removes a selected points from the curve. Updates undo/redo status
1119  */
1120 void CurveCreator_Widget::removePoint()
1121 {
1122   CurveCreator_ICurve::SectionToPointList aPoints;
1123   getSelectedPoints( aPoints );
1124   if ( aPoints.size() == 0 )
1125     return;
1126
1127   CurveCreator_ICurve::SectionToPointList aSelPoints;
1128   startCurveModification( aSelPoints, false );
1129
1130   myCurve->removeSeveralPoints( aPoints );
1131   finishCurveModification( CurveCreator_ICurve::SectionToPointList() );
1132 }
1133
1134 void CurveCreator_Widget::addNewPoint(const CurveCreator::Coordinates& theCoords)
1135 {
1136   if( !myCurve )
1137     return;
1138   QList<int> aSections = mySectionView->getSelectedSections();
1139   if( aSections.size() == 0 ){
1140     return;
1141   }
1142   int aSection = aSections[0];
1143   myCurve->addPoints(theCoords, aSection); // add to the end of section
1144   mySectionView->pointsAdded( aSection, myCurve->getNbPoints( aSection ) );
1145   updateActionsStates();
1146   updateUndoRedo();
1147 }
1148
1149 void CurveCreator_Widget::insertPointToSelectedSegment( const int theX,
1150                                                         const int theY )
1151 {
1152   Handle(AIS_InteractiveContext) aContext = getAISContext();
1153
1154   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1155   Handle(V3d_View) aView;
1156   if ( aViewPort )
1157     aView = aViewPort->getView();
1158
1159   if ( aContext.IsNull() || aView.IsNull() )
1160     return;
1161   gp_Pnt aPoint;
1162   gp_Pnt aPoint1, aPoint2;
1163   Handle(AIS_InteractiveObject) anAISObject = myCurve->getAISObject();
1164   bool isFoundPoint = CurveCreator_Utils::pointOnObject( aView, anAISObject, theX, theY,
1165                                                          aPoint, aPoint1, aPoint2 );
1166   if ( !isFoundPoint )
1167     return;
1168
1169   // insert the point to the model curve
1170   CurveCreator_ICurve::SectionToPointList aSelPoints;
1171   startCurveModification( aSelPoints );
1172
1173   CurveCreator::Coordinates aCoords;
1174   aCoords.push_back( aPoint.X() );
1175   aCoords.push_back( aPoint.Y() );
1176
1177   CurveCreator_ICurve::SectionToPointList aPoints1, aPoints2;
1178   findSectionsToPoints( aPoint1.X(), aPoint1.Y(), aPoints1 );
1179   findSectionsToPoints( aPoint2.X(), aPoint2.Y(), aPoints2 );
1180   CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aPoints1.begin(),
1181                                                           aLast = aPoints1.end();
1182   int aSectionId = -1;
1183   // there can be a case when a new point is added into two sections
1184   int aPoint1Id = -1, aPoint2Id = -1;
1185   for ( ; anIt != aLast && aSectionId < 0; anIt++ ) {
1186     int aSectionCur = anIt->first;
1187     CurveCreator_ICurve::SectionToPointList::const_iterator anIt2 = aPoints2.begin(),
1188                                                             aLast2 = aPoints2.end();
1189     for ( ; anIt2 != aLast2 && aSectionId < 0; anIt2++ ) {
1190       if ( anIt2->first == aSectionCur ) {
1191         aSectionId = aSectionCur;
1192         aPoint1Id = anIt->second;
1193         aPoint2Id = anIt2->second;
1194       }
1195     }
1196   }
1197
1198   int anInsertPos = -1;
1199   int aLastPoint = myCurve->getNbPoints( aSectionId )-1; 
1200   if ( ( aPoint1Id == aLastPoint && aPoint2Id == 0 ) ||
1201        ( aPoint2Id == aLastPoint && aPoint1Id == 0 ) )
1202     anInsertPos = -1; // if the section happens between first and last points
1203   else
1204     anInsertPos = aPoint1Id < aPoint2Id ? aPoint1Id + 1 : aPoint2Id + 1;
1205
1206   myCurve->addPoints( aCoords, aSectionId, anInsertPos );
1207   mySectionView->pointsAdded( aSectionId, myCurve->getNbPoints( aSectionId ) );
1208
1209   finishCurveModification( aSelPoints );
1210
1211   setSelectedPoints();
1212 }
1213
1214 void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
1215                                               const int theYPosition )
1216 {
1217   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1218   if ( !aViewPort )
1219     return;
1220
1221   CurveCreator_ICurve::SectionToPointList aPoints;
1222   startCurveModification( aPoints, false );
1223
1224   gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(),
1225                                                               myDragStartPosition.y(),
1226                                                               aViewPort->getView() );
1227   gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( theXPosition, theYPosition,
1228                                                              aViewPort->getView() );
1229   double aXDelta = aStartPnt.X() - anEndPnt.X();
1230   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
1231
1232   CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
1233   std::deque<float> aChangedPos;
1234   CurveCreator_ICurve::SectionToPointList::const_iterator anIt = myDragPoints.begin(),
1235                                                           aLast = myDragPoints.end();
1236   for ( ; anIt != aLast; anIt++ ) {
1237     int aSectionId = anIt->first;
1238     int aPointId = anIt->second;
1239     aChangedPos = myCurve->getPoint( aSectionId, aPointId );
1240     if ( aChangedPos.size() < 2 )
1241       continue;
1242     aChangedPos[0] = aChangedPos[0] - aXDelta;
1243     aChangedPos[1] = aChangedPos[1] - anYDelta;
1244     
1245     aCoordList.push_back(
1246       std::make_pair(std::make_pair( aSectionId, aPointId ), 
1247                      aChangedPos ));
1248   }
1249   myCurve->setSeveralPoints( aCoordList );
1250
1251   myDragged = true;
1252   finishCurveModification( myDragPoints );
1253 }
1254
1255 void CurveCreator_Widget::updateLocalPointView()
1256 {
1257   if ( myDragStarted )
1258     return;
1259   Handle(AIS_InteractiveContext) aContext = getAISContext();
1260   if ( aContext.IsNull() )
1261     return;
1262
1263   CurveCreator_Utils::getSelectedPoints( aContext, myCurve, myLocalPoints );
1264   int aNbPoints = myLocalPoints.size();
1265
1266   bool isRowLimit = aNbPoints > myLocalPointRowLimit;
1267   myLocalPointView->setVisible( getActionMode() == ModificationMode && !isRowLimit );
1268
1269   if ( !isRowLimit ) {
1270     bool isBlocked = myLocalPointView->blockSignals(true);
1271     myLocalPointView->setRowCount( 0 );
1272     CurveCreator_ICurve::SectionToPointList::const_iterator anIt = myLocalPoints.begin(),
1273                                                             aLast = myLocalPoints.end();
1274     for ( ; anIt != aLast; anIt++ )
1275       myLocalPointView->addLocalPointToTable( *anIt );
1276
1277     myLocalPointView->blockSignals( isBlocked );
1278   }
1279 }
1280
1281 /**
1282  * 
1283  */
1284 void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable )
1285 {
1286   CurveCreator_Utils::setLocalPointContext( myCurve, getAISContext(), theOpen );
1287   if ( !theOpen && isUpdateTable )
1288     updateLocalPointView();
1289 }
1290
1291 /**
1292  * Set drag operation started. Save the position and a list of dragged points
1293  * \param theState the drag operation state: started/finished
1294  * \param thePoint the start drag position
1295  */
1296 void CurveCreator_Widget::setDragStarted( const bool theState, const QPoint& thePoint )
1297 {
1298   if ( theState ) {
1299     getSelectedPoints( myDragPoints );
1300
1301     myDragStarted = myDragPoints.size();
1302     myDragStartPosition = thePoint;
1303     if ( myDragStarted ) {
1304       // change a viewer interaction style in order to avoid a select rectangle build
1305       myDragInteractionStyle = changeInteractionStyle( SUIT_ViewModel::KEY_FREE );
1306       myCurve->setSkipSorting( true );
1307     }
1308   }
1309   else {
1310     if ( myDragStarted )
1311       changeInteractionStyle( myDragInteractionStyle );
1312     myDragStarted = false;
1313     myDragPoints.clear();
1314   }
1315   myDragged = false;
1316 }
1317
1318 void CurveCreator_Widget::getSelectedPoints( CurveCreator_ICurve::SectionToPointList& thePoints )
1319 {
1320   thePoints.clear();
1321   thePoints = myLocalPoints;
1322 }
1323
1324 void CurveCreator_Widget::setSelectedPoints( const CurveCreator_ICurve::SectionToPointList& thePoints )
1325 {
1326   if ( myDragStarted )
1327     return;
1328   Handle(AIS_InteractiveContext) aContext = getAISContext();
1329   if ( aContext.IsNull() || !aContext->HasOpenedContext() )
1330     return;
1331
1332   CurveCreator_Utils::setSelectedPoints( aContext, myCurve, thePoints );
1333
1334   updateLocalPointView();
1335 }
1336
1337 void CurveCreator_Widget::stopActionMode()
1338 {
1339   setActionMode( NoneMode );
1340 }
1341
1342 /**
1343  * Get viewer information before perform the curve modification.
1344  * Take a list of selected cuve points an close local context.
1345  * The context should be closed because the curve presentation is
1346  * redisplayed and if it is not closed, when we close the local context
1347  * later, the presentation shown in the local context is disappeared.
1348  * \param thePoints an output list of curve selected points
1349  * \param theFillPoints a flag whether the selection list should be filled
1350  */
1351 void CurveCreator_Widget::startCurveModification(
1352                            CurveCreator_ICurve::SectionToPointList& thePoints,
1353                            const bool theFillPoints )
1354 {
1355   if ( theFillPoints ) {
1356     thePoints.clear();
1357     getSelectedPoints( thePoints );
1358   }
1359   setLocalPointContext( false );
1360 }
1361
1362 /**
1363  * Restore the viewer state after the curve modification is done.
1364  * Open local context and select given points inside it.
1365  * \param thePoints a list of curve selected points
1366  */
1367 void CurveCreator_Widget::finishCurveModification(
1368                            const CurveCreator_ICurve::SectionToPointList& thePoints )
1369 {
1370   if ( getActionMode() == ModificationMode )
1371     setLocalPointContext( true );
1372   setSelectedPoints( thePoints );
1373   updateUndoRedo();
1374 }
1375
1376 /**
1377  * Returns a point index in the model curve by the point coordinates in the viewer
1378  * \param theX the X coordinate of the point
1379  * \param theY the Y coordinate of the point
1380  */
1381 int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
1382 {
1383   return CurveCreator_UtilsICurve::findLocalPointIndex( myCurve, theSectionId, theX, theY );
1384 }
1385
1386 void CurveCreator_Widget::findSectionsToPoints( const double theX, const double theY,
1387                                  CurveCreator_ICurve::SectionToPointList& thePoints )
1388 {
1389   return CurveCreator_UtilsICurve::findSectionsToPoints( myCurve, theX, theY, thePoints );
1390 }
1391
1392 void CurveCreator_Widget::convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
1393                                    QMap<int, QList<int> >& theConvPoints )
1394 {
1395   return CurveCreator_UtilsICurve::convert( thePoints, theConvPoints );
1396 }
1397
1398 /**
1399  * Returns whethe the container has the value
1400  * \param theList a container of values
1401  * \param theValue a value
1402  */
1403 bool CurveCreator_Widget::contains( const CurveCreator_ICurve::SectionToPointList& theList,
1404                                     const CurveCreator_ICurve::SectionToPoint& theValue ) const
1405 {
1406   return CurveCreator_UtilsICurve::contains( theList, theValue );
1407 }