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