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