Salome HOME
Fix for the bug #135: It is impossible to rename bathymetry: Rename operation is...
[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.IsNull() )
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.IsNull() )
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
1132   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1133   Handle(V3d_View) aView;
1134   if ( aViewPort )
1135     aView = aViewPort->getView();
1136
1137   if ( aContext.IsNull() || aView.IsNull() )
1138     return;
1139   gp_Pnt aPoint;
1140   gp_Pnt aPoint1, aPoint2;
1141   bool isFoundPoint = CurveCreator_Utils::getNeighbourPoints( aContext, aView, theX, theY,
1142                                                               aPoint, aPoint1, aPoint2 );
1143   if ( !isFoundPoint )
1144     return;
1145
1146   // insert the point to the model curve
1147   SectionToPointList aSelPoints;
1148   startCurveModification( aSelPoints );
1149
1150   CurveCreator::Coordinates aCoords;
1151   aCoords.push_back( aPoint.X() );
1152   aCoords.push_back( aPoint.Y() );
1153
1154   SectionToPointList aPoints1, aPoints2;
1155   findSectionsToPoints( aPoint1.X(), aPoint1.Y(), aPoints1 );
1156   findSectionsToPoints( aPoint2.X(), aPoint2.Y(), aPoints2 );
1157   SectionToPointList::const_iterator anIt = aPoints1.begin(), aLast = aPoints1.end();
1158   int aSectionId = -1;
1159   // there can be a case when a new point is added into two sections
1160   int aPoint1Id = -1, aPoint2Id = -1;
1161   for ( ; anIt != aLast && aSectionId < 0; anIt++ ) {
1162     int aSectionCur = anIt->first;
1163     SectionToPointList::const_iterator anIt2 = aPoints2.begin(), aLast2 = aPoints2.end();
1164     for ( ; anIt2 != aLast2 && aSectionId < 0; anIt2++ ) {
1165       if ( anIt2->first == aSectionCur ) {
1166         aSectionId = aSectionCur;
1167         aPoint1Id = anIt->second;
1168         aPoint2Id = anIt2->second;
1169       }
1170     }
1171   }
1172
1173   int anInsertPos = -1;
1174   int aLastPoint = myCurve->getNbPoints( aSectionId )-1; 
1175   if ( ( aPoint1Id == aLastPoint && aPoint2Id == 0 ) ||
1176        ( aPoint2Id == aLastPoint && aPoint1Id == 0 ) )
1177     anInsertPos = -1; // if the section happens between first and last points
1178   else
1179     anInsertPos = aPoint1Id < aPoint2Id ? aPoint1Id + 1 : aPoint2Id + 1;
1180
1181   myCurve->addPoints( aCoords, aSectionId, anInsertPos );
1182   mySectionView->pointsAdded( aSectionId, myCurve->getNbPoints( aSectionId ) );
1183
1184   finishCurveModification( aSelPoints );
1185
1186   setSelectedPonts();
1187 }
1188
1189 void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
1190                                               const int theYPosition )
1191 {
1192   OCCViewer_ViewPort3d* aViewPort = getViewPort();
1193   if ( !aViewPort )
1194     return;
1195
1196   SectionToPointList aPoints;
1197   startCurveModification( aPoints, false );
1198
1199   gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(),
1200                                                               myDragStartPosition.y(),
1201                                                               aViewPort->getView() );
1202   gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( theXPosition, theYPosition,
1203                                                              aViewPort->getView() );
1204   double aXDelta = aStartPnt.X() - anEndPnt.X();
1205   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
1206
1207   CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
1208   std::deque<float> aChangedPos;
1209   SectionToPointList::const_iterator anIt = myDragPoints.begin(), aLast = myDragPoints.end();
1210   for ( ; anIt != aLast; anIt++ ) {
1211     int aSectionId = anIt->first;
1212     int aPointId = anIt->second;
1213     aChangedPos = myCurve->getPoint( aSectionId, aPointId );
1214     if ( aChangedPos.size() < 2 )
1215       continue;
1216     aChangedPos[0] = aChangedPos[0] - aXDelta;
1217     aChangedPos[1] = aChangedPos[1] - anYDelta;
1218     
1219     aCoordList.push_back(
1220       std::make_pair(std::make_pair( aSectionId, aPointId ), 
1221                      aChangedPos ));
1222   }
1223   myCurve->setSeveralPoints( aCoordList );
1224
1225   myDragged = true;
1226   finishCurveModification( myDragPoints );
1227 }
1228
1229 void CurveCreator_Widget::updateLocalPointView()
1230 {
1231   if ( myDragStarted )
1232     return;
1233   Handle(AIS_InteractiveContext) aContext = getAISContext();
1234   if ( aContext.IsNull() )
1235     return;
1236
1237   std::list<float> aSelectedList = CurveCreator_Utils::getSelectedPoints( aContext );
1238
1239   std::list<float>::const_iterator anIt = aSelectedList.begin(), aLast = aSelectedList.end();
1240   float aX, anY, aZ;
1241
1242   bool isBlocked = myLocalPointView->blockSignals(true);
1243   myLocalPointView->setRowCount( 0 );
1244   for ( ; anIt != aLast; anIt++ )
1245   {
1246     aX = *anIt;
1247     anIt++;
1248     anY = *anIt;
1249     anIt++;
1250     aZ = *anIt;
1251     addLocalPointToTable( aX, anY );
1252   }
1253   myLocalPointView->blockSignals(isBlocked);
1254 }
1255
1256 /**
1257  * 
1258  */
1259 void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable )
1260 {
1261   CurveCreator_Utils::setLocalPointContext( getAISContext(), theOpen );
1262   if ( !theOpen && isUpdateTable )
1263     updateLocalPointView();
1264 }
1265
1266 void CurveCreator_Widget::addLocalPointToTable( const double theX, const double theY )
1267 {
1268   SectionToPointList aPoints;
1269   findSectionsToPoints( theX, theY, aPoints );
1270
1271   SectionToPointList aSkipList;
1272   // table could not contain two equal value rows
1273   int aRowId = myLocalPointView->rowCount();
1274   double aCurrentX, aCurrentY;
1275   int aSectionId, aPointId;
1276   SectionToPoint aPoint;
1277   for ( int i = 0; i < aRowId; i++ ) {
1278     aCurrentX = myLocalPointView->item( i, 2 )->data( Qt::UserRole ).toDouble();
1279     aCurrentY = myLocalPointView->item( i, 3 )->data( Qt::UserRole ).toDouble();
1280     if ( fabs( aCurrentX - theX ) < LOCAL_SELECTION_TOLERANCE &&
1281          fabs( aCurrentY - theY ) < LOCAL_SELECTION_TOLERANCE ) {
1282            aPoint = std::make_pair<int, int>( getSectionId( i ), getPointId( i ) );
1283       if ( !contains( aSkipList, aPoint ) )
1284         aSkipList.push_back( aPoint );
1285     }
1286   }
1287   if ( aSkipList.size() == aPoints.size() )
1288     return;
1289
1290   QTableWidgetItem* anItem;
1291   SectionToPointList::const_iterator anIt = aPoints.begin(), aLast = aPoints.end();
1292   for ( ; anIt != aLast; anIt++ ) {
1293     aPoint = *anIt;
1294     if ( contains( aSkipList, aPoint ) )
1295       continue;
1296
1297     myLocalPointView->setRowCount( aRowId+1 );
1298     aSectionId = aPoint.first;
1299     aPointId = aPoint.second;
1300
1301     anItem = new QTableWidgetItem( myCurve->getSectionName( aSectionId ).c_str() );
1302     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
1303     anItem->setData( Qt::UserRole, aSectionId );
1304     myLocalPointView->setItem( aRowId, 0, anItem );
1305
1306     anItem = new QTableWidgetItem( QString::number( aPointId + 1 ) );
1307     anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
1308     anItem->setData( Qt::UserRole, aPointId );
1309     myLocalPointView->setItem( aRowId, 1, anItem );
1310
1311     anItem = new QTableWidgetItem( QString::number( theX ) );
1312     anItem->setData( Qt::UserRole, theX );
1313     myLocalPointView->setItem( aRowId, 2, anItem );
1314
1315     anItem = new QTableWidgetItem( QString::number( theY ) );
1316     anItem->setData( Qt::UserRole, theY );
1317     myLocalPointView->setItem( aRowId, 3, anItem );
1318   }
1319 }
1320
1321 /**
1322  * Set drag operation started. Save the position and a list of dragged points
1323  * \param theState the drag operation state: started/finished
1324  * \param thePoint the start drag position
1325  */
1326 void CurveCreator_Widget::setDragStarted( const bool theState, const QPoint& thePoint )
1327 {
1328   if ( theState ) {
1329     getSelectedPonts( myDragPoints );
1330     myDragStarted = myDragPoints.size();
1331     myDragStartPosition = thePoint;
1332     if ( myDragStarted ) {
1333       // change a viewer interaction style in order to avoid a select rectangle build
1334       myDragInteractionStyle = changeInteractionStyle( SUIT_ViewModel::KEY_FREE );
1335     }
1336   }
1337   else {
1338     if ( myDragStarted )
1339       changeInteractionStyle( myDragInteractionStyle );
1340     myDragStarted = false;
1341     myDragPoints.clear();
1342   }
1343   myDragged = false;
1344 }
1345
1346 void CurveCreator_Widget::getSelectedPonts( CurveCreator_Widget::SectionToPointList& thePoints )
1347 {
1348   thePoints.clear();
1349   for ( int i = 0, aNb = myLocalPointView->rowCount(); i < aNb; i++ )
1350     thePoints.push_back( std::make_pair( getSectionId( i ), getPointId( i ) ) );
1351 }
1352
1353 void CurveCreator_Widget::setSelectedPonts( const CurveCreator_Widget::SectionToPointList& thePoints )
1354 {
1355   if ( myDragStarted )
1356     return;
1357   Handle(AIS_InteractiveContext) ic = getAISContext();
1358   if ( ic.IsNull() || !ic->HasOpenedContext() )
1359     return;
1360
1361   AIS_ListOfInteractive aListToSelect;
1362   AIS_ListOfInteractive aDisplayedList;
1363   ic->DisplayedObjects( aDisplayedList );
1364
1365   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
1366   SectionToPoint aSToPoint;
1367   for( ; anIt != aLast; anIt++ ) {
1368     aSToPoint = *anIt;
1369
1370     for ( AIS_ListIteratorOfListOfInteractive it( aDisplayedList ); it.More(); it.Next() )
1371     {
1372       Handle(AIS_InteractiveObject) anAIS = it.Value();
1373       if ( anAIS.IsNull() )
1374         continue;
1375       Handle(AIS_Point) anAISPoint = Handle(AIS_Point)::DownCast( anAIS );
1376       if ( anAISPoint.IsNull() )
1377         continue;
1378
1379       TopoDS_Vertex aVertex = TopoDS::Vertex( anAISPoint->Vertex() );
1380
1381       if ( aVertex.IsNull() )
1382         continue;
1383
1384       gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
1385
1386       SectionToPointList aPoints;
1387       findSectionsToPoints( aPnt.X(), aPnt.Y(), aPoints );
1388
1389       SectionToPointList::const_iterator anIt = aPoints.begin(), aLast = aPoints.end();
1390       SectionToPoint aPoint;
1391       for ( ; anIt != aLast; anIt++ ) {
1392         aPoint = *anIt;
1393         if ( aPoint.first == aSToPoint.first && aPoint.second == aSToPoint.second )
1394           aListToSelect.Append( anAIS );
1395       }
1396     }
1397   }
1398
1399   ic->ClearSelected( Standard_False );
1400   setObjectsSelected( aListToSelect );
1401   updateLocalPointView();
1402 }
1403
1404 /**
1405  * Get viewer information before perform the curve modification.
1406  * Take a list of selected cuve points an close local context.
1407  * The context should be closed because the curve presentation is
1408  * redisplayed and if it is not closed, when we close the local context
1409  * later, the presentation shown in the local context is disappeared.
1410  * \param thePoints an output list of curve selected points
1411  * \param theFillPoints a flag whether the selection list should be filled
1412  */
1413 void CurveCreator_Widget::startCurveModification(
1414                            CurveCreator_Widget::SectionToPointList& thePoints,
1415                            const bool theFillPoints )
1416 {
1417   if ( theFillPoints ) {
1418     thePoints.clear();
1419     getSelectedPonts( thePoints );
1420   }
1421   setLocalPointContext( false );
1422 }
1423
1424 /**
1425  * Restore the viewer state after the curve modification is done.
1426  * Open local context and select given points inside it.
1427  * \param thePoints a list of curve selected points
1428  */
1429 void CurveCreator_Widget::finishCurveModification(
1430                            const CurveCreator_Widget::SectionToPointList& thePoints )
1431 {
1432   if ( getActionMode() == ModificationMode )
1433     setLocalPointContext( true );
1434   setSelectedPonts( thePoints );
1435   updateUndoRedo();
1436 }
1437
1438 /**
1439  * Returns a point index in the model curve by the point coordinates in the viewer
1440  * \param theX the X coordinate of the point
1441  * \param theY the Y coordinate of the point
1442  */
1443 int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
1444 {
1445   int aPntIndex = -1;
1446
1447   CurveCreator::Coordinates aCoords;
1448   for ( int i = 0, aNb = myCurve->getNbPoints( theSectionId ); i < aNb && aPntIndex < 0; i++ ) {
1449     aCoords = myCurve->getPoint( theSectionId, i );
1450     if ( aCoords.size() < 2 )
1451       continue;
1452     if ( fabs( aCoords[0] - theX ) < LOCAL_SELECTION_TOLERANCE &&
1453          fabs( aCoords[1] - theY ) < LOCAL_SELECTION_TOLERANCE )
1454       aPntIndex = i;
1455   }
1456
1457   return aPntIndex;
1458 }
1459
1460 void CurveCreator_Widget::findSectionsToPoints( const double theX, const double theY,
1461                                  CurveCreator_Widget::SectionToPointList& thePoints )
1462 {
1463   thePoints.clear();
1464
1465   int aPointId = -1;
1466   for ( int i = 0, aNb = myCurve->getNbSections(); i < aNb; i++ ) {
1467     aPointId = findLocalPointIndex( i, theX, theY );
1468     if ( aPointId < 0 )
1469       continue;
1470     SectionToPoint aPoint = std::make_pair( i, aPointId );
1471     if ( !contains( thePoints, aPoint ) )
1472       thePoints.push_back( aPoint );
1473   }
1474 }
1475
1476 void CurveCreator_Widget::convert( const SectionToPointList& thePoints,
1477                                    QMap<int, QList<int> >& theConvPoints )
1478 {
1479   theConvPoints.clear();
1480
1481   SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
1482   QList<int> aPoints;
1483   int aSectionId, aPointId;
1484   for ( ; anIt != aLast; anIt++ ) {
1485     aSectionId = anIt->first;
1486     aPointId = anIt->second;
1487     aPoints.clear();
1488     if ( theConvPoints.contains( aSectionId ) )
1489       aPoints = theConvPoints[aSectionId];
1490     if ( aPoints.contains( aPointId ) )
1491       continue;
1492     aPoints.append( aPointId );
1493     theConvPoints[aSectionId] = aPoints;
1494   }
1495 }
1496
1497 /**
1498  * Returns a section index from the table
1499  * \param theRowId a table row
1500  */
1501 int CurveCreator_Widget::getSectionId( const int theRowId ) const
1502 {
1503   return myLocalPointView->item( theRowId, 0 )->data( Qt::UserRole ).toInt();
1504 }
1505
1506 /**
1507  * Returns a point index from the table
1508  * \param theRowId a table row
1509  */
1510 int CurveCreator_Widget::getPointId( const int theRowId ) const
1511 {
1512   return myLocalPointView->item( theRowId, 1 )->data( Qt::UserRole ).toInt();
1513 }
1514
1515 /**
1516  * Returns whethe the container has the value
1517  * \param theList a container of values
1518  * \param theValue a value
1519  */
1520 bool CurveCreator_Widget::contains( const CurveCreator_Widget::SectionToPointList& theList,
1521                                     const CurveCreator_Widget::SectionToPoint& theValue ) const
1522 {
1523   bool isFound = false;
1524
1525   SectionToPointList::const_iterator anIt = theList.begin(), aLast = theList.end();
1526   for ( ; anIt != aLast && !isFound; anIt++ )
1527     isFound = anIt->first == theValue.first && anIt->second == theValue.second;
1528
1529   return isFound;
1530 }