Salome HOME
5aea503571e5054bbcef4836ba7e09f518eae8d1
[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
28 #include <GEOMUtils.hxx>
29
30 #include <SUIT_Session.h>
31 #include <SUIT_Desktop.h>
32 #include <SUIT_ResourceMgr.h>
33 #include <SUIT_ViewManager.h>
34
35 #include <OCCViewer_ViewWindow.h>
36 #include <OCCViewer_ViewManager.h>
37 #include <OCCViewer_ViewPort3d.h>
38
39 #include <BRep_Tool.hxx>
40 #include <TopoDS.hxx>
41
42 #include <AIS_ListOfInteractive.hxx>
43 #include <AIS_ListIteratorOfListOfInteractive.hxx>
44 #include <AIS_Shape.hxx>
45 #include <AIS_Point.hxx>
46 #include <SelectMgr_EntityOwner.hxx>
47 //#include <StdSelect_BRepOwner.hxx>
48
49 #include <QHBoxLayout>
50 #include <QVBoxLayout>
51 #include <QLabel>
52 #include <QLineEdit>
53 #include <QGroupBox>
54 #include <QToolButton>
55 #include <QToolBar>
56 #include <QAction>
57 #include <QMenu>
58 #include <QMouseEvent>
59 #include <QApplication>
60 #include <QTableWidget>
61
62 #define LOCAL_SELECTION_TOLERANCE 0.0001
63
64 CurveCreator_Widget::CurveCreator_Widget(QWidget* parent,
65                                          CurveCreator_ICurve *theCurve,
66                                          Qt::WindowFlags fl) :
67     QWidget(parent), myNewSectionEditor(NULL), myCurve(theCurve), mySection(0)
68 {
69     myNewSectionEditor = new CurveCreator_NewSectionDlg( this );
70     myNewSectionEditor->hide();
71     connect( myNewSectionEditor, SIGNAL(addSection()), this, SLOT(onAddNewSection()) );
72     connect( myNewSectionEditor, SIGNAL(modifySection()), this, SLOT(onModifySection()) );
73     connect( myNewSectionEditor, SIGNAL(cancelSection()), this, SLOT(onCancelSection()) );
74
75     QGroupBox* aSectionGroup = new QGroupBox(tr("Sections"),this);
76
77     mySectionView = new CurveCreator_TreeView(myCurve, aSectionGroup);
78     connect( mySectionView, SIGNAL(selectionChanged()), this, SLOT( onSelectionChanged() ) );
79     connect( mySectionView, SIGNAL(sectionEntered(int)), this, SLOT(onEditSection(int)) );
80     connect( mySectionView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onContextMenu(QPoint)) );
81
82     myLocalPointView = new QTableWidget();
83     myLocalPointView->setVisible( false );
84     myLocalPointView->setColumnCount( 3 );
85     QStringList aLabels;
86     //aLabels << tr( "IDENTIFIER_LABEL" ) << tr( "X_POSITION_LBL" ) << tr( "Y_POSITION_LBL" );
87     aLabels << tr( "id" ) << tr( "X" ) << tr( "Y" );
88     myLocalPointView->setHorizontalHeaderLabels( aLabels );
89     connect( myLocalPointView, SIGNAL( cellChanged( int, int ) ),
90              this, SLOT( onLocalPointChanged( int, int ) ) );
91
92     QToolBar* aTB = new QToolBar(tr("TOOL_BAR_TLT"), aSectionGroup);
93 //    QToolButton* anUndoBtn = new QToolButton(aTB);
94
95     SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
96     QPixmap anUndoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_UNDO")));
97     QPixmap aRedoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_REDO")));
98     QPixmap aNewSectionPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_SECTION")));
99     QPixmap aNewPointPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_POINT")));
100     QPixmap anEditPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
101     QPixmap aDetectPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
102     QPixmap aPolylinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
103     QPixmap aSplinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
104     QPixmap aRemovePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_DELETE")));
105     QPixmap aJoinPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_JOIN")));
106     QPixmap aStepUpPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_UP")));
107     QPixmap aStepDownPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_DOWN")));
108
109     QAction* anAct = createAction( UNDO_ID, tr("UNDO"), anUndoPixmap, tr("UNDO_TLT"), 
110                                    QKeySequence(Qt::ControlModifier|Qt::Key_Z) );
111     connect(anAct, SIGNAL(triggered()), this, SLOT(onUndo()) );
112     aTB->addAction(anAct);
113
114     anAct = createAction( REDO_ID, tr("REDO"), aRedoPixmap, tr("REDO_TLT"), 
115                           QKeySequence(Qt::ControlModifier|Qt::Key_Y) );
116     connect(anAct, SIGNAL(triggered()), this, SLOT(onRedo()) );
117     aTB->addAction(anAct);
118
119     aTB->addSeparator();
120
121     anAct = createAction( NEW_SECTION_ID, tr("NEW_SECTION"), aNewSectionPixmap, tr("NEW_SECTION_TLT"), 
122                           QKeySequence(Qt::ControlModifier|Qt::Key_N) );
123     connect(anAct, SIGNAL(triggered()), this, SLOT(onNewSection()) );
124     aTB->addAction(anAct);
125     aTB->addSeparator();
126
127     anAct = createAction( ADDITION_MODE_ID, tr("ADDITION_MODE"), aNewPointPixmap, tr("ADDITION_MODE_TLT"), 
128                           QKeySequence() );
129     anAct->setCheckable(true);
130     connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onAdditionMode(bool)) );
131     connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
132     aTB->addAction(anAct);
133     
134     anAct = createAction( MODIFICATION_MODE_ID, tr("MODIFICATION_MODE"), anEditPointsPixmap, tr("MODIFICATION_MODE_TLT"), 
135                           QKeySequence() );
136     anAct->setCheckable(true);
137     connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onModificationMode(bool)) );
138     connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
139     aTB->addAction(anAct);
140
141     anAct = createAction( DETECTION_MODE_ID, tr("DETECTION_MODE"), aDetectPointsPixmap, tr("DETECTION_MODE_TLT"), 
142                           QKeySequence() );
143     anAct->setCheckable(true);
144     connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onDetectionMode(bool)) );
145     connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
146     aTB->addAction(anAct);
147
148     anAct = createAction( CLOSE_SECTIONS_ID, tr("CLOSE_SECTIONS"), QPixmap(), tr("CLOSE_SECTIONS_TLT"), 
149                           QKeySequence(Qt::ControlModifier|Qt::Key_W) );
150     connect(anAct, SIGNAL(triggered()), this, SLOT(onCloseSections()) );
151
152     anAct = createAction( UNCLOSE_SECTIONS_ID, tr("UNCLOSE_SECTIONS"), QPixmap(), 
153                           tr("UNCLOSE_SECTIONS_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_S) );
154     connect(anAct, SIGNAL(triggered()), this, SLOT(onUncloseSections()) );
155
156     anAct = createAction( SET_SECTIONS_POLYLINE_ID, tr("SET_SECTIONS_POLYLINE"), 
157                           aPolylinePixmap, tr("SET_POLYLINE_TLT"), 
158                           QKeySequence(Qt::ControlModifier|Qt::Key_E) );
159     connect(anAct, SIGNAL(triggered()), this, SLOT(onSetPolyline()) );
160
161     anAct = createAction( SET_SECTIONS_SPLINE_ID, tr("SET_SECTIONS_SPLINE"), aSplinePixmap, 
162                           tr("SET_SPLINE_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_R) );
163     connect(anAct, SIGNAL(triggered()), this, SLOT(onSetSpline()) );
164
165     anAct = createAction( REMOVE_ID, tr("REMOVE"), aRemovePixmap, tr("REMOVE_TLT"), 
166                           QKeySequence(Qt::ControlModifier|Qt::Key_Delete ) );
167     connect(anAct, SIGNAL(triggered()), this, SLOT(onRemove()) );
168     aTB->addAction(anAct);
169     aTB->addSeparator();
170
171     anAct = createAction( JOIN_ID, tr("JOIN"), aJoinPixmap, tr("JOIN_TLT"), 
172                           QKeySequence(Qt::ControlModifier|Qt::Key_Plus ) );
173     connect( anAct, SIGNAL(triggered()), this, SLOT(onJoin()) );
174     aTB->addAction(anAct);
175     aTB->addSeparator();
176
177     anAct = createAction( CLEAR_ALL_ID, tr("CLEAR_ALL"), QPixmap(), tr("CLEAR_ALL_TLT"), 
178                           QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Delete ) );
179     connect( anAct, SIGNAL(triggered()), this, SLOT( onClearAll()) );
180
181     anAct = createAction( JOIN_ALL_ID, tr("JOIN_ALL"), QPixmap(), tr("JOIN_ALL_TLT"), 
182                           QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Plus ) );
183     connect( anAct, SIGNAL(triggered()), this, SLOT(onJoinAll()) );
184
185     QVBoxLayout* aSectLayout = new QVBoxLayout();
186     aSectLayout->setMargin( 5 );
187     aSectLayout->setSpacing( 5 );
188     aSectLayout->addWidget(aTB);
189     aSectLayout->addWidget(mySectionView);
190     aSectLayout->addWidget( myLocalPointView );
191     aSectionGroup->setLayout(aSectLayout);
192     QVBoxLayout* aLay = new QVBoxLayout();
193     aLay->setMargin( 0 );
194     aLay->setSpacing( 5 );
195 //    aLay->addLayout(aNameLayout);
196     aLay->addWidget(aSectionGroup);
197     setLayout(aLay);
198     onSelectionChanged();
199
200     /*OCCViewer_Viewer* anOCCViewer = getOCCViewer();
201     if (anOCCViewer) {
202       OCCViewer_ViewWindow* aWnd = dynamic_cast<OCCViewer_ViewWindow*>(anOCCViewer->getViewManager()->getActiveView());
203       if ( aWnd )
204         aWnd->installEventFilter( this );
205     }*/
206 }
207
208 //=======================================================================
209 // function: getUniqSectionName
210 // purpose: return unique section name
211 //=======================================================================
212 OCCViewer_Viewer* CurveCreator_Widget::getOCCViewer()
213 {
214   OCCViewer_Viewer* anOCCViewer = 0;
215
216   OCCViewer_ViewWindow* aViewWindow = 0;
217   SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
218   if ( activeStudy )
219     aViewWindow = dynamic_cast<OCCViewer_ViewWindow*>(SUIT_Session::session()->activeApplication()->desktop()->activeWindow());
220   if ( aViewWindow == 0 )
221     return anOCCViewer;
222   OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>(aViewWindow->getViewManager());
223   if ( aViewManager == 0 )
224     return anOCCViewer;
225
226   anOCCViewer = aViewManager->getOCCViewer();
227   return anOCCViewer;
228 }
229
230 /*!
231   \brief Customize event handling
232   \param watched event receiver object
233   \param e event
234   \return \c true if the event processing should be stopped
235 */
236 /*bool CurveCreator_Widget::eventFilter( QObject* theWatched, QEvent* theEvent )
237 {
238   OCCViewer_Viewer* anOCCViewer = getOCCViewer();
239   Handle(AIS_InteractiveContext) aContext = anOCCViewer->getAISContext();
240   bool isLocalContext = aContext->HasOpenedContext();
241   if ( !isLocalContext )
242     return QWidget::eventFilter( theWatched, theEvent );
243
244   bool isProcessed = true;
245
246   return isProcessed;
247 }*/
248
249 //=======================================================================
250 // function: getUniqSectionName
251 // purpose: return unique section name
252 //=======================================================================
253 std::string CurveCreator_Widget::getUniqSectionName( CurveCreator_ICurve* theCurve ) const
254 {
255   for( int i = 0 ; i < 1000000 ; i++ ){
256       char aBuffer[255];
257       sprintf( aBuffer, "Section_%d", i+1 );
258       std::string aName(aBuffer);
259       int j;
260       for( j = 0 ; j < theCurve->getNbSections() ; j++ ){
261         if( theCurve->getSectionName(j) == aName )
262             break;
263       }
264       if( j == theCurve->getNbSections() )
265           return aName;
266   }
267   return "";
268 }
269
270 void CurveCreator_Widget::setCurve( CurveCreator_ICurve* theCurve )
271 {
272   myCurve = theCurve;
273   mySectionView->setCurve(myCurve);
274   onSelectionChanged();
275   updateUndoRedo();
276 }
277
278 void CurveCreator_Widget::onSelectionChanged()
279 {
280   QList<ActionId> anEnabledAct;
281   if( myCurve ){
282     anEnabledAct << NEW_SECTION_ID;
283     QList<int> aSelSections = mySectionView->getSelectedSections();
284     QList< QPair< int, int > > aSelPoints = mySectionView->getSelectedPoints();
285     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
286     switch( aSelType ){
287     case CurveCreator_TreeView::ST_NOSEL:{
288       break;
289     }
290     case CurveCreator_TreeView::ST_SECTIONS:{
291       /*if( aSelSections[0] > 0 ){
292         anEnabledAct << UP_ID;
293       }*/
294       if( aSelSections.size() == 1 ){
295         anEnabledAct << ADDITION_MODE_ID << MODIFICATION_MODE_ID << DETECTION_MODE_ID;
296       }
297       if (myActionMap[ADDITION_MODE_ID]->isChecked()) {
298         mySection = -1;
299         myPointNum = -1;
300         QList<int> aSelSection = mySectionView->getSelectedSections();
301         if( aSelSection.size() > 0 ){
302           mySection = aSelSection[0];
303           myPointNum = myCurve->getNbPoints(mySection);
304         }
305       } else if (myActionMap[MODIFICATION_MODE_ID]->isChecked()) {
306         anEnabledAct << REMOVE_ID;
307         anEnabledAct << CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID << SET_SECTIONS_SPLINE_ID;
308         int aSectCnt = myCurve->getNbSections();
309         if( aSectCnt > 0 )
310           anEnabledAct << CLEAR_ALL_ID;
311         if( aSectCnt > 1 )
312           anEnabledAct << JOIN_ALL_ID;
313         if( aSelSections.size() > 1 ){
314           anEnabledAct << JOIN_ID;
315         }
316       } else if (myActionMap[DETECTION_MODE_ID]->isChecked()) {
317       } else { //no active mode
318       }
319       /*if( aSelSections[ aSelSections.size() - 1 ] < ( myCurve->getNbSections() - 1 ) ){
320         anEnabledAct << DOWN_ID;
321       }*/
322       break;
323     }
324     /*case CurveCreator_TreeView::ST_POINTS_ONE_SECTION:{
325       if( aSelPoints[0].second > 0 ){
326         anEnabledAct << UP_ID;
327       }
328       int aLastIndex = aSelPoints.size()-1;
329       int aSect = aSelPoints[0].first;
330       if( aSelPoints[aLastIndex].second < (myCurve->getNbPoints(aSect) - 1)){
331         anEnabledAct << DOWN_ID;
332       }
333       if( aSelPoints.size() == 1){
334         anEnabledAct << INSERT_POINT_BEFORE_ID << INSERT_POINT_AFTER_ID;
335       }
336       break;
337     }*/
338
339     }
340     
341     /*int aSelObjsCnt = aSelPoints.size() + aSelSections.size();
342     if( aSelObjsCnt > 0 ){
343       anEnabledAct << REMOVE_ID;
344     }
345     if( (myCurve->getNbSections() + myCurve->getNbPoints()) > 0 ){
346       anEnabledAct << REMOVE_ALL_ID;
347     }*/
348     if( myCurve->getNbSections() > 1 ){
349       anEnabledAct << JOIN_ALL_ID;
350     }
351   }
352   QList<ActionId> anIds = myActionMap.keys();
353   for( int i = 0 ; i < anIds.size() ; i++ ){
354     if( myActionMap.contains(anIds[i]) ){
355       if( anEnabledAct.contains(anIds[i]) ){
356         myActionMap[anIds[i]]->setEnabled(true);
357       }
358       else{
359         myActionMap[anIds[i]]->setEnabled(false);
360       }
361     }
362   }
363   emit selectionChanged();
364 }
365
366 void CurveCreator_Widget::onAdditionMode(bool checked)
367 {
368   if( !myCurve )
369     return;
370   OCCViewer_Viewer* anOCCViewer = getOCCViewer();
371   Handle(AIS_InteractiveContext) aContext = anOCCViewer->getAISContext();
372   OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
373                                                     (anOCCViewer->getViewManager());
374 //  if ( aViewManager->getType() == OCCViewer_Viewer::Type() ) {
375   if( anOCCViewer ) {
376     if (checked) {
377 /*      myGuiState = aViewWindow->saveState();
378       anOCCViewer->enableMultiselection(false);
379       anOCCViewer->enableSelection(false);*/
380       connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
381              this, SLOT( onGetCoordsByClick( SUIT_ViewWindow*, QMouseEvent* ) ) );
382     } else {
383       disconnect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
384              this, SLOT( onGetCoordsByClick( SUIT_ViewWindow*, QMouseEvent* ) ) );
385 /*      anOCCViewer->enableMultiselection(true);
386       anOCCViewer->enableSelection(true);
387       aViewWindow->restoreState( myGuiState );*/
388       return;
389     }
390   }
391
392   mySection= -1;
393   myPointNum = -1;
394   QList<int> aSelSection = mySectionView->getSelectedSections();
395   if( aSelSection.size() > 0 ){
396     mySection = aSelSection[0];
397   }
398   else{
399     QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
400     if( aSelPoints.size() > 0 ){
401       mySection = aSelPoints[0].first;
402       myPointNum = aSelPoints[0].second + 1;
403     }
404   }
405 //  emit subOperationStarted( myNewPointEditor );
406 }
407
408 void CurveCreator_Widget::onModificationMode(bool checked)
409 {
410   myLocalPointView->setVisible( checked );
411   OCCViewer_Viewer* anOCCViewer = getOCCViewer();
412   OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
413                                                     (anOCCViewer->getViewManager());
414 /*
415   SUIT_ViewWindow* aViewWindow = 0;
416   SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
417   if ( activeStudy )
418     aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
419   if ( aViewWindow == 0 )
420     return;
421   SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();*/
422   if ( aViewManager->getType() == OCCViewer_Viewer::Type() ) {
423     if (checked) {
424       connect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
425              this, SLOT( onPointSelect( SUIT_ViewWindow*, QMouseEvent* ) ) );
426       connect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
427              this, SLOT( onPointDrag( SUIT_ViewWindow*, QMouseEvent* ) ) );
428     }
429     else {
430       disconnect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
431              this, SLOT( onPointSelect( SUIT_ViewWindow*, QMouseEvent* ) ) );
432       disconnect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
433              this, SLOT( onPointDrag( SUIT_ViewWindow*, QMouseEvent* ) ) );
434       return;
435     }
436   }
437   //NDS OCCViewer_ViewWindow* anOCCWnd = dynamic_cast<OCCViewer_ViewWindow*>(aViewWindow);
438   //anOCCWnd->activateStartPointSelection();
439     // activate selection ------>
440   //OCCViewer_Viewer* anOCCViewer = dynamic_cast<OCCViewer_Viewer*>(aViewManager->getViewModel());
441
442   setLocalPointContext( true );
443 }
444
445 void CurveCreator_Widget::onDetectionMode(bool checked)
446 {
447 }
448
449 void CurveCreator_Widget::onModeChanged(bool checked)
450 {
451   setLocalPointContext( false );
452   if (checked) {
453     QAction* anAction = (QAction*)sender();
454     switch(myActionMap.key(anAction)) {
455       case ADDITION_MODE_ID:
456         if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
457           myActionMap[MODIFICATION_MODE_ID]->trigger();
458         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
459           myActionMap[DETECTION_MODE_ID]->trigger();
460         break;
461       case MODIFICATION_MODE_ID:
462         if (myActionMap[ADDITION_MODE_ID]->isChecked())
463           myActionMap[ADDITION_MODE_ID]->trigger();
464         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
465           myActionMap[DETECTION_MODE_ID]->trigger();
466         break;
467       case DETECTION_MODE_ID:
468         if (myActionMap[ADDITION_MODE_ID]->isChecked())
469           myActionMap[ADDITION_MODE_ID]->trigger();
470         else if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
471           myActionMap[MODIFICATION_MODE_ID]->trigger();
472         break;
473     }
474   }
475   onSelectionChanged();
476 }
477
478 void CurveCreator_Widget::onAddNewPoint(const CurveCreator::Coordinates& theCoords)
479 {
480   if( !myCurve )
481     return;
482   myCurve->addPoints(theCoords, mySection, myPointNum );
483   mySectionView->pointsAdded( mySection, myPointNum );
484   myPointNum++;
485   onSelectionChanged();
486   updateUndoRedo();
487 }
488
489 void CurveCreator_Widget::onNewSection()
490 {
491   if( !myCurve )
492     return;
493   myNewSectionEditor->clear();
494   myNewSectionEditor->setEditMode(false);
495   QString aSectName = QString( getUniqSectionName(myCurve).c_str() );
496   myNewSectionEditor->setSectionParameters(aSectName, true, CurveCreator::Polyline );
497   emit subOperationStarted( myNewSectionEditor );
498 }
499
500 void CurveCreator_Widget::onAddNewSection()
501 {
502   if( !myCurve )
503     return;
504   myCurve->addSection( myNewSectionEditor->getName().toStdString(), myNewSectionEditor->getSectionType(),
505                       myNewSectionEditor->isClosed() );
506   mySectionView->sectionAdded( -1 ); // add a new section to the end of list
507   QString aNewName = QString(getUniqSectionName(myCurve).c_str());
508   myNewSectionEditor->setSectionName(aNewName);
509   onSelectionChanged();
510   updateUndoRedo();
511   onCancelSection();
512 }
513
514 void CurveCreator_Widget::onCancelSection()
515 {
516   emit subOperationFinished( myNewSectionEditor );
517 }
518
519 QAction* CurveCreator_Widget::createAction( ActionId theId, const QString& theName, const QPixmap& theImage,
520                                             const QString& theToolTip, const QKeySequence& theShortcut )
521 {
522   QAction* anAct = new QAction(theName,this);
523   if( !theImage.isNull() ){
524     anAct->setIcon(theImage);
525   }
526   anAct->setShortcut(theShortcut);
527   anAct->setToolTip(theToolTip);
528   myActionMap[theId] = anAct;
529   return anAct;
530 }
531
532 QAction* CurveCreator_Widget::getAction(ActionId theId)
533 {
534   if( myActionMap.contains(theId) )
535     return myActionMap[theId];
536   return NULL;
537 }
538
539 void CurveCreator_Widget::onEditSection( int theSection )
540 {
541   if( !myCurve )
542     return;
543   mySection = theSection;
544   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
545   bool isClosed = myCurve->isClosed(theSection);
546   CurveCreator::SectionType aType = myCurve->getSectionType(theSection);
547   myNewSectionEditor->setEditMode(true);
548   myNewSectionEditor->setSectionParameters( aSectName, isClosed, aType );
549
550   emit subOperationStarted( myNewSectionEditor );
551 }
552
553 void CurveCreator_Widget::onModifySection()
554 {
555   if( !myCurve )
556     return;
557   QString aName = myNewSectionEditor->getName();
558   bool isClosed = myNewSectionEditor->isClosed();
559   CurveCreator::SectionType aSectType = myNewSectionEditor->getSectionType();
560 //  myCurve->startOperation();
561   myCurve->setClosed( isClosed, mySection );
562   myCurve->setSectionName( mySection , aName.toStdString() );
563   myCurve->setSectionType( mySection, aSectType );
564 //  myCurve->finishOperation();
565   mySectionView->sectionChanged(mySection);
566   updateUndoRedo();
567   onCancelSection();
568 }
569
570 /*void CurveCreator_Widget::onEditPoint( int theSection, int thePoint )
571 {
572   if( !myNewPointEditor || !myEdit )
573     return;
574   mySection = theSection;
575   myPointNum = thePoint;
576   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
577   myNewPointEditor->setEditMode(true);
578   myNewPointEditor->setSectionName(aSectName);
579   myNewPointEditor->setDimension( myCurve->getDimension() );
580   CurveCreator::Coordinates aCoords = myCurve->getCoordinates(theSection,thePoint);
581   myNewPointEditor->setCoordinates(aCoords);
582   emit subOperationStarted( myNewPointEditor );
583 }
584
585 void CurveCreator_Widget::onModifyPoint()
586 {
587   if( !myEdit )
588     return;
589   CurveCreator::Coordinates aCoords = myNewPointEditor->getCoordinates();
590   myEdit->setCoordinates( aCoords, mySection, myPointNum );
591   mySectionView->pointDataChanged( mySection, myPointNum );
592   updateUndoRedo();
593   onCancelPoint();
594 }*/
595
596 void CurveCreator_Widget::onJoin()
597 {
598   if( !myCurve )
599     return;
600   QList<int> aSections = mySectionView->getSelectedSections();
601   if( aSections.size() == 0 ){
602     return;
603   }
604   int aMainSect = aSections[0];
605   int aMainSectSize = myCurve->getNbPoints(aMainSect);
606 //  myCurve->startOperation();
607   for( int i = 1 ; i < aSections.size() ; i++ ){
608     int aSectNum = aSections[i] - (i-1);
609     myCurve->join( aMainSect, aSectNum );
610     mySectionView->sectionsRemoved( aSectNum );
611   }
612 //  myCurve->finishOperation();
613   int aNewSectSize = myCurve->getNbPoints(aMainSect);
614   if( aNewSectSize != aMainSectSize )
615     mySectionView->pointsAdded( aMainSect, aMainSectSize, aNewSectSize-aMainSectSize );
616   updateUndoRedo();
617 }
618
619 void CurveCreator_Widget::onRemove()
620 {
621   if( !myCurve )
622     return;
623   QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
624   int aCurrSect=-1;
625   int aRemoveCnt = 0;
626 //  myCurve->startOperation();
627   for( int i = 0 ; i < aSelPoints.size() ; i++ ){
628     if( aCurrSect != aSelPoints[i].first ){
629       aRemoveCnt = 0;
630       aCurrSect = aSelPoints[i].first;
631     }
632     int aPntIndx = aSelPoints[i].second - aRemoveCnt;
633     myCurve->removePoint( aCurrSect, aPntIndx );
634     mySectionView->pointsRemoved( aCurrSect, aPntIndx );
635     aRemoveCnt++;
636   }
637   QList<int> aSections = mySectionView->getSelectedSections();
638   for( int i = 0 ; i < aSections.size() ; i++ ){
639     int aSectNum = aSections[i] - (i);
640     myCurve->removeSection( aSectNum );
641     mySectionView->sectionsRemoved( aSectNum );
642   }
643 //  myCurve->finishOperation();
644   mySectionView->clearSelection();
645   updateUndoRedo();
646 }
647
648 void CurveCreator_Widget::onClearAll()
649 {
650   if( !myCurve )
651     return;
652   myCurve->clear();
653   mySectionView->reset();
654   onSelectionChanged();
655   updateUndoRedo();
656 }
657
658 void CurveCreator_Widget::onJoinAll()
659 {
660   if( !myCurve )
661     return;
662   myCurve->join();
663   mySectionView->reset();
664   onSelectionChanged();
665   updateUndoRedo();
666 }
667
668 void CurveCreator_Widget::onUndoSettings()
669 {
670
671 }
672
673 void CurveCreator_Widget::onSetSpline()
674 {
675   if( !myCurve )
676     return;
677   QList<int> aSelSections = mySectionView->getSelectedSections();
678 //  myCurve->startOperation();
679   for( int i = 0 ; i < aSelSections.size() ; i++ ){
680     myCurve->setSectionType(aSelSections[i], CurveCreator::Spline );
681     mySectionView->sectionChanged(aSelSections[i]);
682   }
683 //  myCurve->finishOperation();
684   updateUndoRedo();
685 }
686
687 void CurveCreator_Widget::onSetPolyline()
688 {
689   if( !myCurve )
690     return;
691 //  myCurve->startOperation();
692   QList<int> aSelSections = mySectionView->getSelectedSections();
693   for( int i = 0 ; i < aSelSections.size() ; i++ ){
694     myCurve->setSectionType( aSelSections[i], CurveCreator::Polyline );
695     mySectionView->sectionChanged( aSelSections[i] );
696   }
697 //  myCurve->finishOperation();
698   updateUndoRedo();
699 }
700
701 void CurveCreator_Widget::onCloseSections()
702 {
703   if( !myCurve )
704     return;
705 //  myCurve->startOperation();
706   QList<int> aSelSections = mySectionView->getSelectedSections();
707   for( int i = 0 ; i < aSelSections.size() ; i++ ){
708     myCurve->setClosed(true, aSelSections[i]);
709     mySectionView->sectionChanged(aSelSections[i]);
710   }
711 //  myCurve->finishOperation();
712   updateUndoRedo();
713 }
714
715 void CurveCreator_Widget::onUncloseSections()
716 {
717   if( !myCurve )
718     return;
719 //  myCurve->startOperation();
720   QList<int> aSelSections = mySectionView->getSelectedSections();
721   for( int i = 0 ; i < aSelSections.size() ; i++ ){
722     myCurve->setClosed(false, aSelSections[i]);
723     mySectionView->sectionChanged(aSelSections[i]);
724   }
725 //  myCurve->finishOperation();
726   updateUndoRedo();
727 }
728
729 void CurveCreator_Widget::onUndo()
730 {
731     if( !myCurve )
732       return;
733     myCurve->undo();
734     mySectionView->reset();
735     updateUndoRedo();
736 }
737
738 void CurveCreator_Widget::onRedo()
739 {
740     if( !myCurve )
741       return;
742     myCurve->redo();
743     mySectionView->reset();
744     updateUndoRedo();
745 }
746
747 void CurveCreator_Widget::updateUndoRedo()
748 {
749     QAction* anAct = myActionMap[UNDO_ID];
750     if( anAct != 0 ){
751         if( myCurve->getNbUndo() != 0 ){
752             anAct->setEnabled(true);
753         }
754         else{
755             anAct->setDisabled(true);
756         }
757     }
758     anAct = myActionMap[REDO_ID];
759     if( anAct != 0 ){
760         if( myCurve->getNbRedo() != 0 ){
761             anAct->setEnabled(true);
762         }
763         else{
764             anAct->setDisabled(true);
765         }
766     }
767 }
768
769 void CurveCreator_Widget::onContextMenu( QPoint thePoint )
770 {
771   QList<ActionId> aContextActions;
772   aContextActions << CLEAR_ALL_ID << JOIN_ALL_ID << SEPARATOR_ID <<
773                      CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID <<
774                      SET_SECTIONS_SPLINE_ID;
775   QPoint aGlPoint = mySectionView->mapToGlobal(thePoint);
776   bool isVis = false;
777   QList<ActionId> aResAct;
778   for( int i = 0 ; i < aContextActions.size() ; i++ ){
779     if( aContextActions[i] != SEPARATOR_ID ){
780       if( myActionMap.contains(aContextActions[i]) ){
781         QAction* anAct = myActionMap[aContextActions[i]];
782         if( anAct->isEnabled() ){
783           aResAct << aContextActions[i];
784           isVis = true;
785         }
786       }
787     }
788     else{
789       aResAct << SEPARATOR_ID;
790     }
791   }
792   if( !isVis )
793     return;
794
795   QMenu* aMenu = new QMenu(this);
796   for( int i = 0 ; i < aResAct.size() ; i++ ){
797     if( aResAct[i] == SEPARATOR_ID ){
798       aMenu->addSeparator();
799     }
800     else{
801       QAction* anAct = myActionMap[aResAct[i]];
802       aMenu->insertAction(NULL, anAct);
803     }
804   }
805   aMenu->exec(aGlPoint);
806 }
807
808 QList<int> CurveCreator_Widget::getSelectedSections()
809 {
810   return mySectionView->getSelectedSections();
811 }
812
813 QList< QPair< int, int > > CurveCreator_Widget::getSelectedPoints()
814 {
815   return mySectionView->getSelectedPoints();
816 }
817
818 //=================================================================================
819 // function : GeometryGUI::onGetCoordsByClick()
820 // purpose  : Manage mouse press events in Additon mode
821 //=================================================================================
822 void CurveCreator_Widget::onGetCoordsByClick( SUIT_ViewWindow* theViewWindow, QMouseEvent* pe )
823 {
824   if (pe->button() != Qt::LeftButton)
825     return;
826
827   if ( theViewWindow->getViewManager()->getType() == OCCViewer_Viewer::Type() &&
828        pe->modifiers() != Qt::ControlModifier ) {
829     OCCViewer_Viewer* anOCCViewer =
830       ( (OCCViewer_ViewManager*)( theViewWindow->getViewManager() ) )->getOCCViewer();
831     Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
832
833     gp_Pnt aPnt;    
834
835     ic->InitSelected();
836     if ( pe->modifiers() == Qt::ShiftModifier )
837       ic->ShiftSelect();  // Append selection
838     else
839       ic->Select();       // New selection
840
841     /*TopoDS_Shape aShape;
842
843     ic->InitSelected();
844     if ( ic->MoreSelected() )
845       aShape = ic->SelectedShape();
846
847     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
848       aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
849     else*/
850     {
851       OCCViewer_ViewPort3d* vp =  ((OCCViewer_ViewWindow*)theViewWindow)->getViewPort();
852       aPnt = GEOMUtils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
853     }
854     // set the coordinates into dialog
855     CurveCreator::Coordinates aCoords;
856     aCoords.push_back( aPnt.X() );
857     aCoords.push_back( aPnt.Y() );
858     if ( myCurve->getDimension() == 3 ) {
859       aCoords.push_back( aPnt.Z() );
860     }
861     onAddNewPoint(aCoords);
862 //    myNewPointEditor->setCoordinates( aCoords );
863   }
864 }
865
866 //=================================================================================
867 // function : HYDROGUI_PolylineOp::onPointSelect()
868 // purpose  : Manage mouse press events in Modification mode
869 //=================================================================================
870 void CurveCreator_Widget::onPointSelect( SUIT_ViewWindow* theViewWindow, QMouseEvent* pe )
871 {
872   //store initial cursor position for Drag&Drop
873   if (pe->button() == Qt::LeftButton)
874     myDragStartPosition = pe->pos();
875   
876   //gp_Pnt aPnt;
877   OCCViewer_Viewer* anOCCViewer = 
878       ( (OCCViewer_ViewManager*)( theViewWindow->getViewManager() ) )->getOCCViewer();
879   Handle(AIS_InteractiveContext) aContext = anOCCViewer->getAISContext();
880   
881   //ic->InitSelected();
882   //if ( pe->modifiers() == Qt::ShiftModifier )
883   //  ic->ShiftSelect();  // Append selection
884   //else
885   //  ic->Select();       // New selection
886   
887   /*ic->InitSelected();
888   if ( ic->MoreSelected() ) {
889     TopoDS_Shape aShape = ic->SelectedShape();
890     Standard_Boolean hasdet = ic->HasDetectedShape();
891     Standard_Boolean hassel = ic->HasSelectedShape();
892     Standard_Integer nbcur = ic->NbCurrents();
893     Standard_Integer nbsel = ic->NbSelected();
894     if(!aShape.IsNull())
895       if ( aShape.ShapeType() == TopAbs_VERTEX )
896         aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
897   }
898   
899   Qt::KeyboardModifiers modifiers = pe->modifiers();
900 //  aSketcherDlg->OnPointSelected( modifiers, aPnt );  // "feed" the point to point construction dialog*/
901
902   updateLocalPointView();
903 }
904
905 //=================================================================================
906 // function : GeometryGUI::onPointDrag()
907 // purpose  : Manage mouse move events in Modification mode
908 //=================================================================================
909 void CurveCreator_Widget::onPointDrag( SUIT_ViewWindow* theViewWindow, QMouseEvent* pe )
910 {
911   if ( !(pe->buttons() & Qt::LeftButton) )
912     return;
913   if ( (pe->pos() - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
914     return;
915 /*  
916   QDrag *drag = new QDrag(this);
917   QMimeData *mimeData = new QMimeData;
918   
919   mimeData->setData(mimeType, data);
920   drag->setMimeData(mimeData);
921   
922   Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
923   */
924 }
925
926 void CurveCreator_Widget::onLocalPointChanged( int theRow, int theColumn )
927 {
928   setLocalPointContext( false );
929
930   QList<int> aSelSections = mySectionView->getSelectedSections();
931
932   int aPntIndex = -1;
933   int aCurrSect=-1;
934   std::deque<float> aChangedPos;
935   float aPrevX, aPrevY, aX, anY;
936   for( int i = 0 ; i < aSelSections.size() ; i++ ){
937     aCurrSect = aSelSections[i];
938
939     aPrevX = myLocalPointView->item( theRow, 1 )->data( Qt::UserRole ).toDouble();
940     aPrevY = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
941
942     aPntIndex = findLocalPointIndex( aCurrSect, aPrevX, aPrevY );
943     if ( aPntIndex < 0 )
944       continue;
945
946     aX  = myLocalPointView->item( theRow, 1 )->text().toDouble();
947     anY = myLocalPointView->item( theRow, 2 )->text().toDouble();
948     aChangedPos.clear();
949     aChangedPos.push_back( aX );
950     aChangedPos.push_back( anY );
951     myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
952   }
953   updateLocalPointView();
954
955   setLocalPointContext( true );
956 }
957
958 int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
959 {
960   int aPntIndex = -1;
961
962   CurveCreator::Coordinates aCoords;
963   for ( int i = 0, aNb = myCurve->getNbPoints( theSectionId ); i < aNb && aPntIndex < 0; i++ ) {
964     aCoords = myCurve->getPoint( theSectionId, i );
965     if ( aCoords.size() < 2 )
966       continue;
967     if ( fabs( aCoords[0] - theX ) < LOCAL_SELECTION_TOLERANCE &&
968          fabs( aCoords[1] - theY ) < LOCAL_SELECTION_TOLERANCE )
969       aPntIndex = i;
970   }
971
972   return aPntIndex;
973 }
974
975 void CurveCreator_Widget::updateLocalPointView()
976 {
977   OCCViewer_Viewer* anOCCViewer = getOCCViewer();
978   if ( !anOCCViewer )
979     return;
980   Handle(AIS_InteractiveContext) aContext = anOCCViewer->getAISContext();
981
982   bool isBlocked = myLocalPointView->blockSignals(true);
983   gp_Pnt aPnt;
984   myLocalPointView->setRowCount( 0 );
985   for ( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() ) {
986     TopoDS_Vertex aVertex;
987     TopoDS_Shape aShape = aContext->SelectedShape();
988     if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
989       aVertex = TopoDS::Vertex( aContext->SelectedShape() );
990     else {
991       Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
992       if ( !anOwner.IsNull() ) {
993         Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
994         if ( !anAIS.IsNull() ) {
995           Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast( anAIS);
996           if ( !aPoint.IsNull() )
997             aVertex = TopoDS::Vertex( aPoint->Vertex() );
998         }
999         if ( aVertex.IsNull() ) {
1000           // the following happens if there are no points in the current curve, there is only a shape
1001           /*Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
1002           if ( aBrepOwner.IsNull() )
1003             continue;
1004           if ( aBrepOwner->HasShape() ) {
1005             const TopoDS_Shape& aShape = aBrepOwner->Shape();
1006             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
1007             {
1008               aVertex = TopoDS::Vertex( aShape );
1009             }
1010           }*/
1011         }
1012       }
1013       if ( aVertex.IsNull() )
1014         continue;
1015       aPnt = BRep_Tool::Pnt( aVertex );
1016       addLocalPointToTable( aPnt.X(), aPnt.Y() );
1017     }
1018   }
1019   myLocalPointView->blockSignals(isBlocked);
1020 }
1021
1022 void CurveCreator_Widget::setLocalPointContext( const bool theOpen )
1023 {
1024   OCCViewer_Viewer* anOCCViewer = getOCCViewer();
1025   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
1026
1027   if ( theOpen ) {
1028     // Open local context if there is no one
1029     bool allObjects = true;
1030     if ( !ic->HasOpenedContext() ) {
1031       ic->ClearCurrents( false );
1032       ic->OpenLocalContext( allObjects, true, true );
1033     }
1034     AIS_ListOfInteractive aList;
1035     ic->DisplayedObjects( aList );
1036     int aLSize = 0;
1037     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
1038       aLSize++;
1039
1040     int theMode = TopAbs_VERTEX;
1041     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
1042     {
1043       Handle(AIS_InteractiveObject) anAIS = it.Value();
1044       if ( !anAIS.IsNull() )
1045       {
1046         if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
1047         {
1048           ic->Load( anAIS, -1, false );
1049           ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)theMode ) );
1050         }
1051         else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
1052         {
1053           ic->Load( anAIS, -1, false );
1054           ic->Activate( anAIS, theMode );
1055         }
1056       }
1057       continue;
1058     }
1059   }
1060   else {
1061     ic->CloseAllContexts();
1062   }
1063 }
1064
1065 void CurveCreator_Widget::addLocalPointToTable( const double theX, const double theY )
1066 {
1067   int aRowId = myLocalPointView->rowCount();
1068   double aCurrentX, aCurrentY;
1069   for ( int i = 0; i < aRowId; i++ ) {
1070     aCurrentX = myLocalPointView->item( i, 1 )->data( Qt::UserRole ).toDouble();
1071     aCurrentY = myLocalPointView->item( i, 2 )->data( Qt::UserRole ).toDouble();
1072     if ( fabs( aCurrentX - theX ) < LOCAL_SELECTION_TOLERANCE &&
1073          fabs( aCurrentY - theY ) < LOCAL_SELECTION_TOLERANCE )
1074       return;
1075   }
1076   QTableWidgetItem* anItem;
1077
1078   myLocalPointView->setRowCount( aRowId+1 );
1079   myLocalPointView->setItem( aRowId, 0, new QTableWidgetItem( QString::number( aRowId + 1 ) ) );
1080
1081   anItem = new QTableWidgetItem( QString::number( theX ) );
1082   anItem->setData( Qt::UserRole, theX );
1083   myLocalPointView->setItem( aRowId, 1, anItem );
1084
1085   anItem = new QTableWidgetItem( QString::number( theY ) );
1086   anItem->setData( Qt::UserRole, theY );
1087   myLocalPointView->setItem( aRowId, 2, anItem );
1088 }