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