Salome HOME
PAL8238 - Hypothesis for non-regular 1D meshing
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_aParameter.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESHGUI_aParameter.cxx
25 //  Module : SMESH
26 //  $Header$
27
28 #include "SMESHGUI_aParameter.h"
29
30 #include <qspinbox.h>
31 #include <qvalidator.h>
32 #include <qlineedit.h>
33 #include <qtextedit.h>
34 #include <qcombobox.h>
35 #include <qcheckbox.h>
36 #include <qtable.h>
37 #include <qvalidator.h>
38 #include <qpushbutton.h>
39 #include <qlayout.h>
40
41 #include <QtxDblSpinBox.h>
42
43 SMESHGUI_aParameter::SMESHGUI_aParameter( const QString& label, const bool preview )
44 : _needPreview( preview ),
45   _label(label)
46 {
47 }
48
49 SMESHGUI_aParameter::~SMESHGUI_aParameter()
50 {
51 }
52
53 bool SMESHGUI_aParameter::needPreview() const
54 {
55   return _needPreview;
56 }
57
58 QString& SMESHGUI_aParameter::Label()
59 {
60   return _label;
61 }
62
63 QString SMESHGUI_aParameter::sigValueChanged() const
64 {
65   return QString::null;
66 }
67
68 //=================================================================================
69 // class    : SMESHGUI_intParameter
70 // purpose  :
71 //=================================================================================
72 SMESHGUI_intParameter::SMESHGUI_intParameter (const int      theInitValue,
73                                               const QString& theLabel,
74                                               const int      theBottom,
75                                               const int      theTop,
76                                               const bool     preview  )
77      :SMESHGUI_aParameter(theLabel, preview),
78        _top(theTop), _bottom(theBottom), _initValue(theInitValue),
79        _newValue( theInitValue )
80 {
81 }
82 SMESHGUI_aParameter::Type SMESHGUI_intParameter::GetType() const
83 {
84   return SMESHGUI_aParameter::INT;
85 }
86 bool SMESHGUI_intParameter::GetNewInt (int & theValue) const
87 {
88   theValue = _newValue;
89   return _newValue != _initValue;
90 }
91 bool SMESHGUI_intParameter::GetNewDouble (double & Value) const
92 {
93   return false;
94 }
95 bool SMESHGUI_intParameter::GetNewText (QString & Value) const
96 {
97   return false;
98 }
99
100 QWidget* SMESHGUI_intParameter::CreateWidget( QWidget* parent ) const
101 {
102   return new QSpinBox( parent );
103 }
104   
105 void SMESHGUI_intParameter::InitializeWidget (QWidget* theQWidget) const
106 {
107   QSpinBox * aSpin = dynamic_cast< QSpinBox *>(theQWidget);
108   if (aSpin) {
109     aSpin->setMinValue(_bottom);
110     aSpin->setMaxValue(_top);
111     aSpin->setValue(_initValue);
112   }
113 }
114 void SMESHGUI_intParameter::TakeValue (QWidget* theQWidget)
115 {
116   QSpinBox * aSpin = dynamic_cast< QSpinBox *>(theQWidget);
117   if (aSpin)
118     _newValue = aSpin->value();
119 }
120
121 QString SMESHGUI_intParameter::sigValueChanged() const
122 {
123   return SIGNAL( valueChanged( int ) );
124 }
125
126 //=================================================================================
127 // class    : SMESHGUI_doubleParameter
128 // purpose  :
129 //=================================================================================
130 SMESHGUI_doubleParameter::SMESHGUI_doubleParameter (const double   theInitValue,
131                                                     const QString& theLabel,
132                                                     const double   theBottom,
133                                                     const double   theTop,
134                                                     const double   theStep,
135                                                     const int      theDecimals,
136                                                     const bool     preview )
137      :SMESHGUI_aParameter(theLabel, preview),
138        _top(theTop), _bottom(theBottom), _step(theStep),
139        _initValue(theInitValue), _decimals(theDecimals)
140 {
141 }
142 SMESHGUI_aParameter::Type SMESHGUI_doubleParameter::GetType() const
143 {
144   return SMESHGUI_aParameter::DOUBLE;
145 }
146 bool SMESHGUI_doubleParameter::GetNewInt (int & theValue) const
147 {
148   return false;
149 }
150 bool SMESHGUI_doubleParameter::GetNewDouble (double & Value) const
151 {
152   Value = _newValue;
153   return _newValue != _initValue;
154 }
155 bool SMESHGUI_doubleParameter::GetNewText (QString & Value) const
156 {
157   return false;
158 }
159
160 QWidget* SMESHGUI_doubleParameter::CreateWidget( QWidget* parent ) const
161 {
162   return new QtxDblSpinBox( parent );
163 }
164
165 void SMESHGUI_doubleParameter::InitializeWidget (QWidget* theQWidget) const
166 {
167   QtxDblSpinBox* aSpin = dynamic_cast<QtxDblSpinBox*>(theQWidget);
168   if (aSpin) {
169     aSpin->setPrecision(_decimals);
170 #ifdef NEW_GUI
171     aSpin->setDblPrecision(_bottom);
172 #endif
173     aSpin->setRange(_bottom, _top);
174     aSpin->setValue(_initValue);
175     aSpin->setLineStep(_step);
176   }
177 }
178 void SMESHGUI_doubleParameter::TakeValue (QWidget* theQWidget)
179 {
180   QtxDblSpinBox* aSpin = dynamic_cast<QtxDblSpinBox*>(theQWidget);
181   if (aSpin)
182     _newValue = aSpin->value();
183 }
184
185 QString SMESHGUI_doubleParameter::sigValueChanged() const
186 {
187   return SIGNAL( valueChanged( double ) );
188 }
189
190 //=================================================================================
191 // class    : SMESHGUI_strParameter
192 // purpose  :
193 //=================================================================================
194 SMESHGUI_strParameter::SMESHGUI_strParameter (const QString& theInitValue,
195                                               const QString& theLabel,
196                                               const bool preview )
197      :SMESHGUI_aParameter(theLabel, preview),
198       _initValue(theInitValue)
199 {
200 }
201 SMESHGUI_aParameter::Type SMESHGUI_strParameter::GetType() const
202 {
203   return SMESHGUI_aParameter::STRING;
204 }
205
206 bool SMESHGUI_strParameter::GetNewInt (int & theValue) const
207 {
208   return false;
209 }
210 bool SMESHGUI_strParameter::GetNewDouble (double & Value) const
211 {
212   return false;
213 }
214 bool SMESHGUI_strParameter::GetNewText (QString & theValue) const
215 {
216   theValue = _newValue;
217   return _newValue != _initValue;
218 }
219
220 QWidget* SMESHGUI_strParameter::CreateWidget( QWidget* parent ) const
221 {
222   return new QLineEdit( parent );
223 }
224
225 void SMESHGUI_strParameter::InitializeWidget (QWidget* theQWidget) const
226 {
227   QLineEdit* anEdit = dynamic_cast< QLineEdit* >(theQWidget);
228   if (anEdit) {
229     anEdit->setText(_initValue);
230   }
231 }
232 void SMESHGUI_strParameter::TakeValue (QWidget* theQWidget)
233 {
234   QLineEdit* anEdit = dynamic_cast< QLineEdit* >(theQWidget);
235   if (anEdit)
236     _newValue = anEdit->text();
237 }
238
239 QString SMESHGUI_strParameter::sigValueChanged() const
240 {
241   return SIGNAL( textChanged( const QString& ) );
242 }
243
244
245
246 //=================================================================================
247 // class    : SMESHGUI_dependParameter
248 // purpose  :
249 //=================================================================================
250 SMESHGUI_dependParameter::SMESHGUI_dependParameter( const QString& label, const bool     preview )
251 : SMESHGUI_aParameter( label, preview )
252 {
253 }
254
255 const SMESHGUI_dependParameter::ShownMap& SMESHGUI_dependParameter::shownMap() const
256 {
257   return myShownMap;
258 }
259
260 SMESHGUI_dependParameter::ShownMap& SMESHGUI_dependParameter::shownMap()
261 {
262   return myShownMap;
263 }
264
265
266   
267
268
269 //=================================================================================
270 // class    : SMESHGUI_enumParameter
271 // purpose  :
272 //=================================================================================
273 SMESHGUI_enumParameter::SMESHGUI_enumParameter( const QStringList& values,
274                                                 const int initValue,
275                                                 const QString& label,
276                                                 const bool     preview )
277 : SMESHGUI_dependParameter( label, preview ),
278   myInitValue( initValue ),
279   myValue( initValue ),
280   myValues( values )
281 {
282 }
283
284 SMESHGUI_enumParameter::~SMESHGUI_enumParameter()
285 {
286 }
287
288 SMESHGUI_aParameter::Type SMESHGUI_enumParameter::GetType() const
289 {
290   return SMESHGUI_aParameter::ENUM;
291 }
292
293 bool SMESHGUI_enumParameter::GetNewInt( int& v ) const
294 {
295   v = myValue;
296   return myValue!=myInitValue;
297 }
298
299 bool SMESHGUI_enumParameter::GetNewDouble( double& ) const
300 {
301   return false;
302 }
303
304 bool SMESHGUI_enumParameter::GetNewText( QString& v ) const
305 {
306   bool res = myValue>=0 && myValue<Count();
307
308   if( res )
309     v = myValues[ myValue ];
310
311   return res && v!=myInitValue;
312 }
313
314 QWidget* SMESHGUI_enumParameter::CreateWidget( QWidget* parent ) const
315 {
316   return new QComboBox( parent );
317 }
318
319 void SMESHGUI_enumParameter::InitializeWidget( QWidget* w ) const
320 {
321   if( w && w->inherits( "QComboBox" ) )
322   {
323     QComboBox* c = ( QComboBox* ) w;
324     c->clear();
325     c->insertStringList( myValues );
326     c->setCurrentItem( myInitValue );
327   }
328 }
329
330 void SMESHGUI_enumParameter::TakeValue( QWidget* w )
331 {
332   if( w && w->inherits( "QComboBox" ) )
333   {
334     QComboBox* c = ( QComboBox* ) w;
335     myValue = c->currentItem();
336   }
337 }
338
339 int SMESHGUI_enumParameter::Count() const
340 {
341   return myValues.count();
342 }
343
344 QString SMESHGUI_enumParameter::sigValueChanged() const
345 {
346   return SIGNAL( activated( int ) );
347 }
348
349
350 //=================================================================================
351 // class    : SMESHGUI_boolParameter
352 // purpose  :
353 //=================================================================================
354 SMESHGUI_boolParameter::SMESHGUI_boolParameter( const bool initValue,
355                                                 const QString& label,
356                                                 const bool     preview )
357 : SMESHGUI_dependParameter( label, preview ),
358   myInitValue( initValue ),
359   myValue( myInitValue )
360 {
361 }
362
363 SMESHGUI_boolParameter::~SMESHGUI_boolParameter()
364 {
365 }
366
367 SMESHGUI_aParameter::Type SMESHGUI_boolParameter::GetType() const
368 {
369   return BOOL;
370 }
371
372 bool SMESHGUI_boolParameter::GetNewInt( int& v ) const
373 {
374   if( myValue )
375     v = 1;
376   else
377     v = 0;
378   return v!=myInitValue;
379 }
380
381 bool SMESHGUI_boolParameter::GetNewDouble( double& ) const
382 {
383   return false;
384 }
385
386 bool SMESHGUI_boolParameter::GetNewText( QString& ) const
387 {
388   return false;
389 }
390
391 QWidget* SMESHGUI_boolParameter::CreateWidget( QWidget* parent ) const
392 {
393   return new QCheckBox( parent );
394 }
395
396 void SMESHGUI_boolParameter::InitializeWidget( QWidget* w ) const
397 {
398   if( w && w->inherits( "QCheckBox" ) )
399   {
400     QCheckBox* box = ( QCheckBox* )w;
401     box->setChecked( myInitValue );
402   }
403 }
404
405 void SMESHGUI_boolParameter::TakeValue( QWidget* w )
406 {
407   if( w && w->inherits( "QCheckBox" ) )
408   {
409     QCheckBox* box = ( QCheckBox* )w;
410     myValue = box->isChecked();
411   }  
412 }
413
414 QString SMESHGUI_boolParameter::sigValueChanged() const
415 {
416   return SIGNAL( stateChanged( int ) );
417 }
418
419
420
421
422 //=================================================================================
423 // class    : SMESHGUI_doubleItem
424 // purpose  : Custom table item which contains double and has double validator
425 //=================================================================================
426 class SMESHGUI_doubleItem: public QTableItem
427 {
428 public:
429   SMESHGUI_doubleItem( QTable*, EditType, const double );
430   virtual ~SMESHGUI_doubleItem();
431
432   void setValidator( const double, const double, const int );
433   void validator( double&, double&, int& );
434   virtual QWidget* createEditor() const;
435
436 private:
437   QDoubleValidator*  myValidator;
438 };
439
440 SMESHGUI_doubleItem::SMESHGUI_doubleItem( QTable* t, EditType e, const double num )
441 : QTableItem( t, e, QString( "%1" ).arg( num ) ),
442   myValidator( new QDoubleValidator( 0.0, 1.0, 3, t ) )
443 {
444 }
445
446 SMESHGUI_doubleItem::~SMESHGUI_doubleItem()
447 {
448 }
449
450 void SMESHGUI_doubleItem::setValidator( const double bot, const double top, const int dec )
451 {
452   myValidator->setBottom( bot );
453   myValidator->setTop( top );
454   myValidator->setDecimals( dec );
455 }
456
457 void SMESHGUI_doubleItem::validator( double& bot, double& top, int& dec )
458 {
459   bot = myValidator->bottom();
460   top = myValidator->top();
461   dec = myValidator->decimals();
462 }
463
464 QWidget* SMESHGUI_doubleItem::createEditor() const
465 {
466   QWidget* res = QTableItem::createEditor();
467   if( res && res->inherits( "QLineEdit" ) )
468   {
469     QLineEdit* l = ( QLineEdit* )res;
470     l->setValidator( myValidator );
471   }
472   return res;
473 }
474
475
476 //=================================================================================
477 // class    : SMESHGUI_Table
478 // purpose  :
479 //=================================================================================
480 SMESHGUI_Table::SMESHGUI_Table( const SMESHGUI_tableParameter* tab, int numRows, int numCols,
481                                 QWidget* parent, const char* name )
482 : QTable( numRows, numCols, parent, name ),
483   myParam( ( SMESHGUI_tableParameter* )tab )
484 {
485 }
486
487 SMESHGUI_Table::~SMESHGUI_Table()
488 {
489 }
490
491 QSize SMESHGUI_Table::sizeHint() const
492 {
493   if( cachedSizeHint().isValid() )
494     return cachedSizeHint();
495
496   constPolish();
497
498   QSize sh = QScrollView::sizeHint();
499   if( sh.width()<400 )
500     sh.setWidth( 400 );
501   if( sh.height()<200 )
502     sh.setHeight( 200 );
503
504   setCachedSizeHint( sh );
505   return sh;
506 }
507
508 void SMESHGUI_Table::stopEditing()
509 {
510   endEdit( currEditRow(), currEditCol(), false, false );
511 }
512
513 void SMESHGUI_Table::validator( const int row, const int col, double& minV, double& maxV, int& dec )
514 {
515   SMESHGUI_doubleItem* it = dynamic_cast<SMESHGUI_doubleItem*>( item( row, col ) );
516   if( it )
517     it->validator( minV, maxV, dec );
518 }
519
520 void SMESHGUI_Table::setValidator( const double minV, const double maxV, const int dec,
521                                    const int rmin, const int rmax,
522                                    const int cmin, const int cmax )
523 {
524   int r1 = rmin>=0 ? rmin : 0,
525       r2 = rmax>=0 ? rmax : numRows(),
526       c1 = cmin>=0 ? cmin : 0,
527       c2 = cmax>=0 ? cmax : numCols();
528
529   for( int i=r1; i<=r2; i++ )
530     for( int j=c1; j<=c2; j++ )
531     {
532       SMESHGUI_doubleItem* it = dynamic_cast<SMESHGUI_doubleItem*>( item( i, j ) );
533       if( it )
534         it->setValidator( minV, maxV, dec );
535     }
536 }
537
538 bool SMESHGUI_Table::eventFilter( QObject* o, QEvent* e )
539 {
540   if( o && e && e->type()==QEvent::KeyPress )
541   {
542     QKeyEvent* ke = ( QKeyEvent* )e;
543     if( ke->key()==Qt::Key_Tab || ke->key()==Qt::Key_Backtab || ke->key()==Qt::Key_Return )
544     {
545       keyPressEvent( ke );
546       return true;
547     }
548   }
549
550   return QTable::eventFilter( o, e );
551 }
552
553 void SMESHGUI_Table::keyPressEvent( QKeyEvent* e )
554 {
555   if( e )
556   {
557     bool shift = ( e->state() & Qt::ShiftButton );
558     int col = currentColumn(), row = currentRow();
559     if( e->key()==Qt::Key_Tab || e->key()==Qt::Key_Backtab )
560     {
561       if( e->key()==Qt::Key_Tab )
562         col++;
563       else 
564         col--;
565       if( col<0 )
566       {
567         col = numCols()-1;
568         row--;
569         if( row<0 )
570         {
571           col = 0;
572           row = 0;
573         }
574       }
575       if( col>=numCols() )
576       {
577         col = 0;
578         row++;
579         if( row>=numRows() )
580           row = numRows()-1;
581       }
582       e->accept();
583     }
584     else if( e->key()==Qt::Key_Return )
585     {
586       col = 0;
587       if( shift )
588         row--;
589       else
590         row++;
591       if( row<0 )
592         row = 0;
593       else if( row>=numRows() )
594       {
595         //add row
596         myParam->onEdit( this, SMESHGUI_TableFrame::ADD_ROW, 1 );
597       }
598       e->accept();
599     }
600     if( e->isAccepted() )
601     {
602       clearSelection();
603       setCurrentCell( row, col );
604     }
605     else
606       QTable::keyPressEvent( e );
607   }
608 }
609
610 QWidget* SMESHGUI_Table::createEditor( int r, int c, bool init ) const
611 {
612   QWidget* w = QTable::createEditor( r, c, init );
613   if( w )
614     w->installEventFilter( this );
615   return w;
616 }
617
618
619
620 //=================================================================================
621 // class    : SMESHGUI_TableFrame
622 // purpose  :
623 //=================================================================================
624 SMESHGUI_TableFrame::SMESHGUI_TableFrame( const SMESHGUI_tableParameter* param, QWidget* parent )
625 : QFrame( parent )
626 {
627   QVBoxLayout* main = new QVBoxLayout( this, 0, 0 );
628
629   myTable = new SMESHGUI_Table( param, 1, 1, this );
630   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
631   
632   QFrame* aButFrame = new QFrame( this );
633   QHBoxLayout* butLay = new QHBoxLayout( aButFrame, 5, 5 );
634
635   myAddColumn = new QPushButton( "Add column", aButFrame );
636
637   myRemoveColumn = new QPushButton( "Remove column", aButFrame );
638
639   myAddRow = new QPushButton( "Add row", aButFrame );
640
641   myRemoveRow = new QPushButton( "Remove row", aButFrame );
642
643   butLay->addWidget( myAddColumn, 0 );
644   butLay->addWidget( myRemoveColumn, 0 );
645   butLay->addWidget( myAddRow, 0 );
646   butLay->addWidget( myRemoveRow, 0 );
647   butLay->addStretch( 1 );
648
649   main->addWidget( myTable, 1 );
650   main->addWidget( aButFrame, 0 );
651
652   connect( myAddColumn,    SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
653   connect( myRemoveColumn, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
654   connect( myAddRow,       SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
655   connect( myRemoveRow,    SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
656 }
657
658 SMESHGUI_TableFrame::~SMESHGUI_TableFrame()
659 {
660 }
661
662 SMESHGUI_Table* SMESHGUI_TableFrame::table() const
663 {
664   return myTable;
665 }
666
667 void SMESHGUI_TableFrame::setShown( const Button b, const bool sh )
668 {
669   if( button( b ) )
670     button( b )->setShown( sh );
671 }
672
673 bool SMESHGUI_TableFrame::isShown( const Button b ) const
674 {
675   bool res = false;
676   if( button( b ) )
677     res = button( b )->isShown();
678   return res;
679 }
680
681 QButton* SMESHGUI_TableFrame::button( const Button b ) const
682 {
683   QButton* res = 0;
684   switch( b )
685   {
686     case ADD_COLUMN:
687       res = myAddColumn;
688       break;
689
690     case REMOVE_COLUMN:
691       res = myRemoveColumn;
692       break;
693
694     case ADD_ROW:
695       res = myAddRow;
696       break;
697
698     case REMOVE_ROW:
699       res = myRemoveRow;
700       break;
701   }
702   return res;
703 }
704
705 void SMESHGUI_TableFrame::onButtonClicked()
706 {
707   if( sender()==button( ADD_COLUMN ) )
708     emit toEdit( ADD_COLUMN, table()->currentColumn() );
709     
710   else if( sender()==button( REMOVE_COLUMN ) )
711     emit toEdit( REMOVE_COLUMN, table()->currentColumn() );
712     
713   else if( sender()==button( ADD_ROW ) )
714     emit toEdit( ADD_ROW, table()->currentRow() );
715     
716   else if( sender()==button( REMOVE_ROW ) )
717     emit toEdit( REMOVE_ROW, table()->currentRow() );
718 }
719
720
721 //=================================================================================
722 // class    : SMESHGUI_tableParameter
723 // purpose  :
724 //=================================================================================
725 SMESHGUI_tableParameter::SMESHGUI_tableParameter( const double init,
726                                                   const QString& label,
727                                                   const bool preview )
728 : SMESHGUI_aParameter( label, preview ),
729   myInitValue( init ),
730   myColsInt( 1 ),
731   myRowsInt( 1 ),
732   myEditCols( false ),
733   myEditRows( false )
734 {
735 }
736
737 SMESHGUI_tableParameter::~SMESHGUI_tableParameter()
738 {
739 }
740
741 bool operator<( const QPair<double,double>& p1, const QPair<double,double>& p2 )
742 {
743   return p1.first < p2.first;
744 }
745
746 void SMESHGUI_tableParameter::sortData( SMESH::double_array& arr )
747 {
748   QValueList< QPair<double,double> > aData;
749   if( arr.length()%2==1 )
750     arr.length( arr.length()-1 );
751
752   int aLen = arr.length();
753   for( int i=0; i<aLen/2; i++ )
754     aData.append( QPair<double,double>( arr[2*i], arr[2*i+1] ) );
755
756   qHeapSort( aData );
757
758   QValueList< QPair<double,double> >::const_iterator anIt = aData.begin(), aLast = aData.end();
759   QValueList<double> unique_values;
760   double prev; int i=0;
761   if( (*anIt).first>0.0 )
762   {
763     unique_values.append( 0.0 );
764     unique_values.append( 0.0 );
765     i++; prev = 0.0;
766   }
767   for( ; anIt!=aLast; anIt++ )
768   {
769     if( i==0 || (*anIt).first>prev )
770     {
771       unique_values.append( (*anIt).first );
772       unique_values.append( (*anIt).second );
773       i++;
774     }
775     prev = (*anIt).first;
776   }
777   if( prev<1.0 )
778   {
779     unique_values.append( 1.0 );
780     unique_values.append( 0.0 );
781   }
782
783   arr.length( unique_values.count() );
784   QValueList<double>::const_iterator anIt1 = unique_values.begin(), aLast1 = unique_values.end();
785   for( int j=0; anIt1!=aLast1; anIt1++, j++ )
786     arr[j] = *anIt1;
787 }
788
789 SMESHGUI_aParameter::Type SMESHGUI_tableParameter::GetType() const
790 {
791   return TABLE;
792 }
793
794 bool SMESHGUI_tableParameter::GetNewInt( int& ) const
795 {
796   return false;
797 }
798
799 bool SMESHGUI_tableParameter::GetNewDouble( double& ) const
800 {
801   return false;
802 }
803
804 bool SMESHGUI_tableParameter::GetNewText( QString& ) const
805 {
806   return false;
807 }
808
809 QWidget* SMESHGUI_tableParameter::CreateWidget( QWidget* par ) const
810 {
811   SMESHGUI_TableFrame* t = new SMESHGUI_TableFrame( this, par );
812   connect( t,    SIGNAL( toEdit( SMESHGUI_TableFrame::Button, int ) ),
813            this, SLOT  ( onEdit( SMESHGUI_TableFrame::Button, int ) ) );
814   
815   update( t );
816   return t;
817 }
818
819 void SMESHGUI_tableParameter::setItems( QWidget* w,
820                                         int old_row, int new_row,
821                                         int old_col, int new_col ) const
822 {
823   if( w && w->inherits( "SMESHGUI_TableFrame" ) )
824   {
825     QTable* tab = ( ( SMESHGUI_TableFrame* )w )->table();
826     
827     if( old_row<0 )
828       old_row = 0;
829     if( new_row<0 )
830       new_row = tab->numRows();
831     if( old_col<0 )
832       old_col = 0;
833     if( new_col<0 )
834       new_col = tab->numCols();
835     
836     for( int i=old_row, m=new_row; i<m; i++ )
837       for( int j=0, n=new_col; j<n; j++ )
838         tab->setItem( i, j, new SMESHGUI_doubleItem( tab, QTableItem::WhenCurrent, myInitValue ) );
839     
840     for( int i=0, m=new_row; i<m; i++ )
841       for( int j=old_col, n=new_col; j<n; j++ )
842         tab->setItem( i, j, new SMESHGUI_doubleItem( tab, QTableItem::WhenCurrent, myInitValue ) );
843
844     for( int j=old_col; j<new_col; j++ )
845       tab->setColumnWidth( j, 50 );
846   }
847 }
848
849 void SMESHGUI_tableParameter::InitializeWidget( QWidget* w ) const
850 {
851   setItems( w );
852
853   if( w && w->inherits( "SMESHGUI_TableFrame" ) )
854   {
855     SMESHGUI_Table* tab = ( ( SMESHGUI_TableFrame* )w )->table();
856     tab->stopEditing();
857
858     int col = tab->numCols(),
859         row = tab->numRows();
860     
861     for( int i=0, m=row; i<m; i++ )
862       for( int j=0, n=col; j<n; j++ )
863         if( row*j+i<myData.length() )
864           tab->item( i, j )->setText( QString( "%1" ).arg( myData[col*i+j] ) );
865   }
866 }
867
868 void SMESHGUI_tableParameter::TakeValue( QWidget* w )
869 {
870   if( w && w->inherits( "SMESHGUI_TableFrame" ) )
871   {
872     QTable* tab = ( ( SMESHGUI_TableFrame* )w )->table();
873
874     int col = tab->numCols(),
875         row = tab->numRows();
876
877     myData.length( col*row );
878     for( int i=0; i<row; i++ )
879       for( int j=0; j<col; j++ )
880         myData[ col*i+j ] = tab->text( i, j ).toDouble();
881   }
882 }
883
884 void SMESHGUI_tableParameter::data( SMESH::double_array& v ) const
885 {
886   v = myData;
887   sortData( v );
888 }
889
890 void SMESHGUI_tableParameter::setData( const SMESH::double_array& d )
891 {
892   myData = d;
893   sortData( myData );
894 }
895
896 void SMESHGUI_tableParameter::update( QWidget* w ) const
897 {
898   if( w && w->inherits( "SMESHGUI_TableFrame" ) )
899   {
900     SMESHGUI_TableFrame* tabfr = ( SMESHGUI_TableFrame* ) w;
901     SMESHGUI_Table* tab = tabfr->table();
902
903     int old_col = tab->numCols(),
904         old_row = tab->numRows();
905         
906     int col = myColsInt, row = myRowsInt;
907     if( myCols.get() )
908       myCols->GetNewInt( col );
909         
910     if( myRows.get() )
911       myRows->GetNewInt( row );
912
913     if( col<=0 )
914       col = 1;
915     if( row<=0 )
916       row = 1;
917
918     if( col!=tab->numCols() )
919       tab->setNumCols( col );
920
921     if( row!=tab->numRows() )
922       tab->setNumRows( row );
923
924     tabfr->setShown( SMESHGUI_TableFrame::ADD_COLUMN, myEditCols );
925     tabfr->setShown( SMESHGUI_TableFrame::REMOVE_COLUMN, myEditCols );
926     tabfr->setShown( SMESHGUI_TableFrame::ADD_ROW, myEditRows );
927     tabfr->setShown( SMESHGUI_TableFrame::REMOVE_ROW, myEditRows );
928
929     setItems( w, old_row, row, old_col, col );
930
931     QMap< int, QString >::const_iterator aNIt = myColNames.begin(),
932                                          aNLast = myColNames.end();
933     for( ; aNIt!=aNLast; aNIt++ )
934       tab->horizontalHeader()->setLabel( aNIt.key(), aNIt.data() );
935     
936     ValidatorsMap::const_iterator anIt = myValidators.begin(),
937                                   aLast = myValidators.end();
938     for( ; anIt!=aLast; anIt++ )
939     {
940       int row = anIt.key(), dec;
941       double minV, maxV;
942       validator( row, minV, maxV, dec );
943       tab->setValidator( minV, maxV, dec, -1, -1, col, col );
944     }
945
946     QSize s = tab->sizeHint();
947     tab->resize( s.width(), s.height() );
948   }
949 }
950
951 void SMESHGUI_tableParameter::setColCount( const int c, QWidget* w )
952 {
953   myColsInt = c;
954   update( w );
955 }
956
957 void SMESHGUI_tableParameter::setRowCount( const int c, QWidget* w )
958 {
959   myRowsInt = c;
960   update( w );
961 }
962
963 void SMESHGUI_tableParameter::setColCount( const SMESHGUI_aParameterPtr p, QWidget* w )
964 {
965   if( p.get() )
966   {
967     myCols = p;
968     update( w );
969   }
970 }
971
972 void SMESHGUI_tableParameter::setRowCount( const SMESHGUI_aParameterPtr p, QWidget* w )
973 {
974   if( p.get() )
975   {
976     myRows = p;
977     update( w );
978   }
979 }
980
981 QString SMESHGUI_tableParameter::sigValueChanged() const
982 {
983   return SIGNAL( valueChanged( int, int ) );
984 }
985
986 void SMESHGUI_tableParameter::setValidator( const int ind, const double minV, const double maxV, const int dec )
987 {
988   ValidatorInfo inf;
989   inf.myMin = minV;
990   inf.myMax = maxV;
991   inf.myDecimals = dec;
992   myValidators[ ind ] = inf;
993 }
994
995 void SMESHGUI_tableParameter::validator( const int ind, double& minV, double& maxV, int& dec ) const
996 {
997   if( myValidators.contains( ind ) )
998   {
999     const ValidatorInfo& inf = myValidators[ ind ];
1000     minV = inf.myMin;
1001     maxV = inf.myMax;
1002     dec = inf.myDecimals;
1003   }
1004 }
1005
1006 void SMESHGUI_tableParameter::setEditCols( const bool ed )
1007 {
1008   myEditCols = ed;
1009 }
1010
1011 void SMESHGUI_tableParameter::setEditRows( const bool ed )
1012 {
1013   myEditRows = ed;
1014 }
1015
1016 void SMESHGUI_tableParameter::setColName( const int ind, const QString& name )
1017 {
1018   myColNames.insert( ind, name );
1019 }
1020
1021 QString SMESHGUI_tableParameter::colName( const int ind ) const
1022 {
1023   if( myColNames.contains( ind ) )
1024     return myColNames[ ind ];
1025   else
1026     return QString::null;
1027 }
1028
1029 void SMESHGUI_tableParameter::onEdit( SMESHGUI_TableFrame::Button b, int n )
1030 {
1031   if( sender() && sender()->inherits( "SMESHGUI_TableFrame" ) )
1032   {
1033     SMESHGUI_TableFrame* fr = ( SMESHGUI_TableFrame* )sender();
1034     SMESHGUI_Table* tab = fr->table();
1035     onEdit( tab, b, n );
1036   }
1037 }
1038
1039 void SMESHGUI_tableParameter::onEdit( SMESHGUI_Table* tab, SMESHGUI_TableFrame::Button b, int n )
1040 {
1041   if( !tab )
1042     return;
1043
1044   SMESHGUI_TableFrame* fr = dynamic_cast<SMESHGUI_TableFrame*>( tab->parent() );
1045
1046   switch( b )
1047   {
1048   case SMESHGUI_TableFrame::ADD_COLUMN:
1049     {
1050       if( !myEditCols || myCols.get() )
1051         return;
1052
1053       myColsInt++; update( fr );
1054       if( n>=0 )
1055         for( int i=0; i<myRowsInt; i++ )
1056           for( int j=myColsInt-1; j>=n; j-- )
1057             if( j==n )
1058               tab->setText( i, j, QString( "%1" ).arg( myInitValue ) );
1059             else
1060               tab->setText( i, j, tab->text( i, j-1 ) );
1061       break;
1062     }
1063     
1064   case SMESHGUI_TableFrame::REMOVE_COLUMN:
1065     {
1066       if( !myEditCols || myCols.get() || myColsInt<=1 )
1067         return;
1068
1069       if( n>=0 )
1070         for( int i=0; i<myRowsInt; i++ )
1071           for( int j=n; j<myColsInt-1; j++ )
1072             tab->setText( i, j, tab->text( i, j+1 ) );
1073       myColsInt--; update( fr );
1074       
1075       break;
1076     }
1077       
1078   case SMESHGUI_TableFrame::ADD_ROW:
1079     {
1080       if( !myEditRows || myRows.get() )
1081         return;
1082
1083       myRowsInt++; update( fr );
1084       if( n>=0 )
1085         for( int i=myRowsInt-1; i>=n; i-- )
1086           for( int j=0; j<myColsInt; j++ )
1087             if( i==n )
1088               tab->setText( i, j, QString( "%1" ).arg( myInitValue ) );
1089             else
1090               tab->setText( i, j, tab->text( i-1, j ) );
1091       break;        
1092     }
1093       
1094   case SMESHGUI_TableFrame::REMOVE_ROW:
1095     {
1096       if( !myEditRows || myRows.get() || myRowsInt<=1 )
1097         return;
1098
1099       if( n>=0 )
1100         for( int i=n; i<myRowsInt-1; i++ )
1101           for( int j=0; j<myColsInt; j++ )
1102             tab->setText( i, j, tab->text( i+1, j ) );
1103       myRowsInt--; update( fr );
1104       
1105       break;
1106     }
1107   }
1108 }