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