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