Salome HOME
Images neccessary for CurveEditor were added
[modules/geom.git] / src / CurveCreator / CurveCreator_EditPntsDlg.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:        CurveCreator_EditPntsDlg.cxx
24 // Created:     Fri Jul  05 16:29:53 2013
25 // Author:      Sergey KHROMOV
26 //
27
28
29 #include <CurveCreator_EditPntsDlg.h>
30 #include <CurveCreator_PointItem.h>
31 #include <QGroupBox>
32 #include <QVBoxLayout>
33 #include <QLabel>
34 #include <QPushButton>
35 #include <QSpinBox>
36 #include <QListWidget>
37
38
39 //=======================================================================
40 // function: Constructor
41 // purpose:
42 //=======================================================================
43 CurveCreator_EditPntsDlg::CurveCreator_EditPntsDlg
44           (QWidget* parent, const CurveCreator::Dimension theDimension)
45   : QDialog      (parent),
46     myDimension  (theDimension),
47     myPntsList   (NULL),
48     myXSpn       (NULL),
49     myYSpn       (NULL),
50     myZSpn       (NULL),
51     myAddBtn     (NULL),
52     myModifBtn   (NULL),
53     myRmBtn      (NULL),
54     myClearBtn   (NULL),
55     myPntUpBtn   (NULL),
56     myPntDownBtn (NULL),
57     myOkBtn      (NULL),
58     myCancelBtn  (NULL)
59 {
60   setWindowTitle(tr("CC_EDIT_POINTS_TITLE"));
61
62   // Set Add/modify point group
63   QGroupBox   *aModifPntGrp =
64                new QGroupBox(tr("CC_EDIT_POINTS_ADD_MODIFY"));
65   QGridLayout *aModifPntLO  = new QGridLayout(aModifPntGrp);
66   QLabel      *aXLbl        =
67                new QLabel(tr("CC_EDIT_POINTS_X"), aModifPntGrp);
68   QLabel      *aYLbl        =
69                new QLabel(tr("CC_EDIT_POINTS_Y"), aModifPntGrp);
70
71   aXLbl->setAlignment(Qt::AlignRight);
72   aYLbl->setAlignment(Qt::AlignRight);
73   myXSpn     = new QDoubleSpinBox(aModifPntGrp);
74   myYSpn     = new QDoubleSpinBox(aModifPntGrp);
75   myAddBtn   = new QPushButton(tr("CC_EDIT_POINTS_ADD"), aModifPntGrp);
76   myModifBtn = new QPushButton(tr("CC_EDIT_POINTS_MODIFY"), aModifPntGrp);
77   myRmBtn    = new QPushButton(tr("CC_EDIT_POINTS_REMOVE"), aModifPntGrp);
78   aModifPntLO->setMargin(9);
79   aModifPntLO->setSpacing(6);
80   aModifPntLO->addWidget(aXLbl,      0, 0);
81   aModifPntLO->addWidget(aYLbl,      1, 0);
82   aModifPntLO->addWidget(myXSpn,      0, 1);
83   aModifPntLO->addWidget(myYSpn,      1, 1);
84   aModifPntLO->addWidget(myAddBtn,   0, 2);
85   aModifPntLO->addWidget(myModifBtn, 1, 2);
86   aModifPntLO->addWidget(myRmBtn,    2, 2);
87
88   if (myDimension == CurveCreator::Dim3d) {
89     QLabel   *aZLbl = new QLabel(tr("CC_EDIT_POINTS_Z"), aModifPntGrp);
90
91     aZLbl->setAlignment(Qt::AlignRight);
92     myZSpn = new QDoubleSpinBox(aModifPntGrp);
93     aModifPntLO->addWidget(aZLbl, 2, 0);
94     aModifPntLO->addWidget(myZSpn, 2, 1);
95   }
96
97   // Set Buttons group
98   QGroupBox   *aPntsGrp     = new QGroupBox();
99   QGridLayout *aPntsLO      = new QGridLayout(aPntsGrp);
100
101   myClearBtn   = new QPushButton(tr("CC_EDIT_POINTS_CLEAR"), aModifPntGrp);
102   myPntUpBtn   = new QPushButton(tr("CC_EDIT_POINTS_UP"), aPntsGrp);
103   myPntDownBtn = new QPushButton(tr("CC_EDIT_POINTS_DOWN"), aPntsGrp);
104   myPntsList   = new QListWidget(aPntsGrp);
105   aPntsLO->setMargin(9);
106   aPntsLO->setSpacing(6);
107   aPntsLO->addWidget(myClearBtn,   0, 0);
108   aPntsLO->addWidget(myPntUpBtn,   2, 4);
109   aPntsLO->addWidget(myPntDownBtn, 3, 4);
110   aPntsLO->addWidget(myPntsList,   1, 0, 4, 4);
111
112   // Set OK/Cancel buttons group
113   QGroupBox *anOkCancelGrp  = new QGroupBox();
114   QGridLayout *anOkCancelLO = new QGridLayout(anOkCancelGrp);
115
116   myOkBtn     = new QPushButton(tr("GEOM_BUT_OK"), anOkCancelGrp);
117   myCancelBtn = new QPushButton(tr("GEOM_BUT_CANCEL"), anOkCancelGrp);
118   anOkCancelLO->setMargin(9);
119   anOkCancelLO->setSpacing(6);
120   anOkCancelLO->addWidget(myOkBtn,     0, 3);
121   anOkCancelLO->addWidget(myCancelBtn, 0, 4);
122
123   // Set main group
124   QGroupBox   *aMainGrp = new QGroupBox;
125   QVBoxLayout *aMainLO = new QVBoxLayout(aMainGrp);
126
127   aMainLO->addWidget(aModifPntGrp);
128   aMainLO->addWidget(aPntsGrp);
129   aMainLO->addWidget(anOkCancelGrp);
130
131   setLayout(aMainLO);
132
133   init();
134 }
135
136 //=======================================================================
137 // function: Destructor
138 // purpose:
139 //=======================================================================
140 CurveCreator_EditPntsDlg::~CurveCreator_EditPntsDlg()
141 {
142 }
143
144 //=======================================================================
145 // function: setPoints
146 // purpose:
147 //=======================================================================
148 void CurveCreator_EditPntsDlg::setPoints
149                     (const CurveCreator::Coordinates &thePoints)
150 {
151   myPoints = thePoints;
152   updateEditList();
153 }
154
155 //=======================================================================
156 // function: getPoints
157 // purpose:
158 //=======================================================================
159 const CurveCreator::Coordinates &CurveCreator_EditPntsDlg::getPoints() const
160 {
161   return myPoints;
162 }
163
164 //=======================================================================
165 // function: init
166 // purpose:
167 //=======================================================================
168 void CurveCreator_EditPntsDlg::init()
169 {
170   // Init spin boxes.
171   initSpinBox(myXSpn);
172   initSpinBox(myYSpn);
173
174   if (myDimension == CurveCreator::Dim3d) {
175     initSpinBox(myZSpn);
176   }
177
178   // Init buttons.
179   myModifBtn->setEnabled(false);
180   myRmBtn->setEnabled(false);
181   myClearBtn->setEnabled(false);
182   myPntUpBtn->setEnabled(false);
183   myPntDownBtn->setEnabled(false);
184   myOkBtn->setDefault(true);
185
186   connect(myAddBtn,     SIGNAL(clicked()), this, SLOT(appendPoint()));
187   connect(myModifBtn,   SIGNAL(clicked()), this, SLOT(modifyPoint()));
188   connect(myRmBtn,      SIGNAL(clicked()), this, SLOT(removePoint()));
189   connect(myClearBtn,   SIGNAL(clicked()), this, SLOT(clear()));
190   connect(myPntUpBtn,   SIGNAL(clicked()), this, SLOT(upPoint()));
191   connect(myPntDownBtn, SIGNAL(clicked()), this, SLOT(downPoint()));
192   connect(myOkBtn,      SIGNAL(clicked()), this, SLOT(accept()));
193   connect(myCancelBtn,  SIGNAL(clicked()), this, SLOT(reject()));
194
195   // Init list widget.
196   myPntsList->clear();
197   myPntsList->setSelectionMode(QAbstractItemView::ExtendedSelection);
198   myPntsList->setDragEnabled(true);
199   myPntsList->setDragDropMode(QAbstractItemView::InternalMove);
200   myPntsList->viewport()->setAcceptDrops(true);
201
202   connect(myPntsList, SIGNAL(itemSelectionChanged()),
203           this, SLOT(changeSelection()));
204   connect(this, SIGNAL(numberOfItemsChanged(int)),
205           this, SLOT(onNumberOfItemsChanged(int)));
206
207   // Set tab order.
208   setTabOrder();
209 }
210
211 //=======================================================================
212 // function: initSpinBox
213 // purpose:
214 //=======================================================================
215 void CurveCreator_EditPntsDlg::initSpinBox(QDoubleSpinBox *theSpinBox)
216 {
217   const double aCoordMin  = -1.e+15;
218   const double aCoordMax  = 1.e+15;
219   const double aStep      = 10;
220   const int    aPrecision = 6;
221
222   theSpinBox->setDecimals( qAbs( aPrecision ) );
223   theSpinBox->setRange(aCoordMin, aCoordMax);
224   theSpinBox->setSingleStep(aStep);
225   theSpinBox->setValue(0.0);
226 }
227
228 //=======================================================================
229 // function: updateEditList
230 // purpose:
231 //=======================================================================
232 void CurveCreator_EditPntsDlg::updateEditList()
233 {
234   myPntsList->clear();
235
236   const int aNbCoords = myPoints.size();
237
238   if (aNbCoords % myDimension == 0) {
239     int i = 0;
240
241     while (i < aNbCoords) {
242       const CurveCreator::TypeCoord aX = myPoints[i++];
243       const CurveCreator::TypeCoord aY = myPoints[i++];
244
245       if (myDimension == CurveCreator::Dim3d) {
246         const CurveCreator::TypeCoord aZ = myPoints[i++];
247
248         new CurveCreator_PointItem(aX, aY, aZ, myPntsList);
249       } else {
250         new CurveCreator_PointItem(aX, aY, myPntsList);
251       }
252     }
253   }
254
255   emit numberOfItemsChanged(myPntsList->count());
256 }
257
258 //=======================================================================
259 // function: movePoints
260 // purpose:
261 //=======================================================================
262 void CurveCreator_EditPntsDlg::movePoints(const int theShift)
263 {
264   // Sort list items in ascending or descending order depending on
265   // the sign of theShift.
266   QList<QListWidgetItem *> aListItems = myPntsList->selectedItems();
267
268   if (!aListItems.empty() && theShift != 0) {
269     QMap<int, QListWidgetItem *> aMapItems;
270
271     foreach(QListWidgetItem *anItem, aListItems) {
272       int aRow = myPntsList->row(anItem);
273
274       if (theShift > 0) {
275         aRow = -aRow;
276       }
277
278       aMapItems.insert(aRow, anItem);
279     }
280
281     // Compute new rows
282     QList<int> aListRows = aMapItems.keys();
283     QList<int> aListNewRows;
284     int i;
285     const int aSize = aListRows.size();
286
287
288     if (theShift < 0) {
289       // Check each row to be positive.
290       int aMinIndex = 0;
291
292       for (i = 0; i < aSize; i++) {
293         int aRow = aListRows[i] + theShift;
294
295         if (aRow < aMinIndex) {
296           aRow = aMinIndex++;
297         }
298
299         aListNewRows.append(aRow);
300       }
301     } else {
302       // Check each row to be not greater then a myPntsList's size.
303       int aMaxIndex = myPntsList->count() - 1;
304
305       for (i = 0; i < aSize; i++) {
306         int aRow = -aListRows[i] + theShift;
307
308         if (aRow > aMaxIndex) {
309           aRow = aMaxIndex--;
310         }
311
312         aListRows[i] = -aListRows[i];
313         aListNewRows.append(aRow);
314       }
315     }
316
317     // Move each item to another position.
318     for (i = 0; i < aSize; i++) {
319       if (aListRows[i] != aListNewRows[i]) {
320         QListWidgetItem *anItem = myPntsList->takeItem(aListRows[i]);
321
322         myPntsList->insertItem(aListNewRows[i], anItem);
323       }
324     }
325
326     // Select added items.
327     foreach (int anIndex, aListNewRows) {
328       myPntsList->item(anIndex)->setSelected(true);
329     }
330   }
331 }
332
333 //=======================================================================
334 // function: setTabOrder
335 // purpose:
336 //=======================================================================
337 void CurveCreator_EditPntsDlg::setTabOrder()
338 {
339   QWidget::setTabOrder(myXSpn, myYSpn);
340
341   if (myDimension == CurveCreator::Dim3d) {
342     QWidget::setTabOrder(myYSpn, myZSpn);
343     QWidget::setTabOrder(myZSpn, myAddBtn);
344   } else {
345     QWidget::setTabOrder(myYSpn, myAddBtn);
346   }
347
348   QWidget::setTabOrder(myAddBtn, myModifBtn);
349   QWidget::setTabOrder(myModifBtn, myRmBtn);
350   QWidget::setTabOrder(myRmBtn, myClearBtn);
351   QWidget::setTabOrder(myClearBtn, myPntsList);
352   QWidget::setTabOrder(myPntsList, myPntUpBtn);
353   QWidget::setTabOrder(myPntUpBtn, myPntDownBtn);
354   QWidget::setTabOrder(myPntDownBtn, myOkBtn);
355   QWidget::setTabOrder(myOkBtn, myCancelBtn);
356 }
357
358 //=======================================================================
359 // function: appendPoint
360 // purpose:
361 //=======================================================================
362 void CurveCreator_EditPntsDlg::appendPoint()
363 {
364   if (myDimension == CurveCreator::Dim3d) {
365     new CurveCreator_PointItem(myXSpn->value(), myYSpn->value(),
366                                myZSpn->value(), myPntsList);
367   } else {
368     new CurveCreator_PointItem(myXSpn->value(), myYSpn->value(), myPntsList);
369   }
370
371   emit numberOfItemsChanged(myPntsList->count());
372 }
373
374 //=======================================================================
375 // function: modifyPoint
376 // purpose:
377 //=======================================================================
378 void CurveCreator_EditPntsDlg::modifyPoint()
379 {
380   QList<QListWidgetItem *> aListItems = myPntsList->selectedItems();
381
382   if (aListItems.size() == 1) {
383     CurveCreator_PointItem *aPntItem =
384       (CurveCreator_PointItem *)aListItems.first();
385
386     if (myDimension == CurveCreator::Dim3d) {
387       aPntItem->setCoord(myXSpn->value(), myYSpn->value(), myZSpn->value());
388     } else {
389       aPntItem->setCoord(myXSpn->value(), myYSpn->value());
390     }
391   }
392 }
393
394 //=======================================================================
395 // function: removePoint
396 // purpose:
397 //=======================================================================
398 void CurveCreator_EditPntsDlg::removePoint()
399 {
400   QList<QListWidgetItem *> aListItems = myPntsList->selectedItems();
401   int aRow = -1;
402
403   foreach(QListWidgetItem *anItem, aListItems) {
404     if (aRow < 0) {
405       aRow = myPntsList->row(anItem);
406     }
407
408     delete anItem;
409   }
410
411   if (aRow >= 0) {
412     emit numberOfItemsChanged(myPntsList->count());
413   }
414
415   // Set the new selection.
416   if (aRow >= myPntsList->count()) {
417     aRow = myPntsList->count() - 1;
418   }
419
420   if (aRow >= 0) {
421     myPntsList->item(aRow)->setSelected(true);
422   }
423 }
424
425 //=======================================================================
426 // function: upPoint
427 // purpose:
428 //=======================================================================
429 void CurveCreator_EditPntsDlg::upPoint()
430 {
431   movePoints(-1);
432 }
433
434 //=======================================================================
435 // function: downPoint
436 // purpose:
437 //=======================================================================
438 void CurveCreator_EditPntsDlg::downPoint()
439 {
440   movePoints(1);
441 }
442
443 //=======================================================================
444 // function: changeSelection
445 // purpose:
446 //=======================================================================
447 void CurveCreator_EditPntsDlg::changeSelection()
448 {
449   // Update modify button and spin boxes.
450   QList<QListWidgetItem *> aListItems = myPntsList->selectedItems();
451   const int aNbItems = aListItems.size();
452
453   if (aNbItems == 1) {
454     const CurveCreator_PointItem *aPntItem =
455       (const CurveCreator_PointItem *)aListItems.first();
456
457     myModifBtn->setEnabled(true);
458     myXSpn->setValue(aPntItem->getX());
459     myYSpn->setValue(aPntItem->getY());
460
461     if (myDimension == CurveCreator::Dim3d) {
462       myZSpn->setValue(aPntItem->getZ());
463     }
464   } else if (myModifBtn->isEnabled()) {
465     myModifBtn->setEnabled(false);
466     myXSpn->setValue(0.0);
467     myYSpn->setValue(0.0);
468
469     if (myDimension == CurveCreator::Dim3d) {
470       myZSpn->setValue(0.0);
471     }
472   }
473
474   // Set enabled remove, up and down points.
475   bool isEnabled = (aNbItems > 0);
476
477   myRmBtn->setEnabled(isEnabled);
478   isEnabled &= (aNbItems < myPntsList->count());
479   myPntUpBtn->setEnabled(isEnabled);
480   myPntDownBtn->setEnabled(isEnabled);
481 }
482
483 //=======================================================================
484 // function: accept
485 // purpose:
486 //=======================================================================
487 void CurveCreator_EditPntsDlg::accept()
488 {
489   // Copy points
490   myPoints.clear();
491
492   const int aNbPoints = myPntsList->count();
493   int i;
494
495   for (i = 0; i < aNbPoints; i++) {
496     const CurveCreator_PointItem *aPntItem =
497       (const CurveCreator_PointItem *)myPntsList->item(i);
498
499     myPoints.push_back(aPntItem->getX());
500     myPoints.push_back(aPntItem->getY());
501
502     if (myDimension == CurveCreator::Dim3d) {
503       myPoints.push_back(aPntItem->getZ());
504     }
505   }
506
507   QDialog::accept();
508 }
509
510 //=======================================================================
511 // function: clear
512 // purpose:
513 //=======================================================================
514 void CurveCreator_EditPntsDlg::clear()
515 {
516   bool isEmpty = (myPntsList->count() == 0);
517
518   myPntsList->clear();
519
520   if (!isEmpty) {
521     emit onNumberOfItemsChanged(0);
522   }
523 }
524
525 //=======================================================================
526 // function: onNumberOfItemsChanged
527 // purpose:
528 //=======================================================================
529 void CurveCreator_EditPntsDlg::onNumberOfItemsChanged(int theNewValue)
530 {
531   myClearBtn->setEnabled(theNewValue > 0);
532
533   // Update Up and down buttons
534   QList<QListWidgetItem *> aListItems = myPntsList->selectedItems();
535   const int aNbItems = aListItems.size();
536   const bool isEnabled = (aNbItems > 0 && aNbItems < theNewValue);
537
538   myPntUpBtn->setEnabled(isEnabled);
539   myPntDownBtn->setEnabled(isEnabled);
540 }