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