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