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