00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "StdMeshersGUI_DistrTable.h"
00028
00029 #include <SMESHGUI_SpinBox.h>
00030
00031
00032 #include <QItemDelegate>
00033 #include <QTableWidget>
00034 #include <QHeaderView>
00035 #include <QPushButton>
00036 #include <QVBoxLayout>
00037 #include <QHBoxLayout>
00038
00039 #define SPACING 6
00040
00045 static void sortData( QList<double>& d )
00046 {
00047 typedef QPair<double, double> Pair;
00048 QList<Pair> pairs;
00049 for ( int i = 0; i < d.count() / 2; i++ )
00050 pairs.append( Pair( d[i*2], d[i*2+1] ) );
00051
00052 qSort( pairs );
00053
00054 d.clear();
00055
00056 Pair p;
00057 double prevX = 0.0, prevY = 0.0;
00058
00059 d.append( prevX );
00060 d.append( pairs.count() > 0 ? pairs[0].second : prevY );
00061
00062 foreach( p, pairs ) {
00063 if ( p.first > prevX ) {
00064 d.append( p.first );
00065 d.append( p.second );
00066 prevY = p.second;
00067 }
00068 prevX = p.first;
00069 }
00070
00071 if ( prevX < 1.0 ) {
00072 d.append( 1.0 );
00073 d.append( prevY );
00074 }
00075 }
00076
00083 class StdMeshersGUI_DistrTableFrame::SpinBoxDelegate : public QItemDelegate
00084 {
00085 public:
00086 SpinBoxDelegate( StdMeshersGUI_DistrTableFrame::Table* );
00087 ~SpinBoxDelegate();
00088
00089 QWidget* createEditor( QWidget*,
00090 const QStyleOptionViewItem&,
00091 const QModelIndex& ) const;
00092 void setEditorData( QWidget*, const QModelIndex&) const;
00093 void setModelData( QWidget*, QAbstractItemModel*,
00094 const QModelIndex& ) const;
00095 void updateEditorGeometry( QWidget*,
00096 const QStyleOptionViewItem&,
00097 const QModelIndex& ) const;
00098
00099 private:
00100 StdMeshersGUI_DistrTableFrame::Table* myTable;
00101 };
00102
00109 class StdMeshersGUI_DistrTableFrame::Table : public QTableWidget
00110 {
00111 private:
00112 struct EditorData
00113 {
00114 int r, c;
00115 SMESHGUI_SpinBox* sb;
00116 EditorData() { reset(); }
00117 void reset() { r = -1; c = -1; sb = 0; }
00118 };
00119
00120 public:
00121 Table( QWidget*, int = 2 );
00122 ~Table();
00123
00124 QList<double> data();
00125 void setData( const QList<double>& );
00126
00127 double value( int, int ) const;
00128 void setValue( int, int, double );
00129
00130 double argMinimum( int ) const;
00131 double argMaximum( int ) const;
00132 double argStep( int ) const;
00133 double funcMinimum( int ) const;
00134 double funcMaximum( int ) const;
00135 double funcStep( int ) const;
00136
00137 void setFuncMinValue( double );
00138
00139 QSize sizeHint() const;
00140
00141 void addRow();
00142 void deleteRow();
00143
00144 void setEditor( int, int, SMESHGUI_SpinBox* );
00145
00146 protected:
00147 void closeEditor( QWidget*, QAbstractItemDelegate::EndEditHint );
00148
00149 private:
00150 void setUpRows( bool = false );
00151 QSize cachedSizeHint() const;
00152 void setCachedSizeHint( const QSize& ) const;
00153 QList<int> selectedRows();
00154
00155 private:
00156 double myFuncMin;
00157 QSize myCachedSizeHint;
00158 EditorData myEditorData;
00159 };
00160
00161
00162
00163
00164
00165 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
00166 SpinBoxDelegate( StdMeshersGUI_DistrTableFrame::Table* parent )
00167 : QItemDelegate( parent ), myTable( parent )
00168 {
00169 }
00170
00171 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
00172 ~SpinBoxDelegate()
00173 {
00174 }
00175
00176 QWidget*
00177 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
00178 createEditor( QWidget* parent,
00179 const QStyleOptionViewItem& ,
00180 const QModelIndex& index ) const
00181 {
00182 SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
00183
00184 sb->setAcceptNames(false);
00185 double aMin = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ?
00186 myTable->argMinimum( index.row() ) :
00187 myTable->funcMinimum( index.row() );
00188 double aMax = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ?
00189 myTable->argMaximum( index.row() ) :
00190 myTable->funcMaximum( index.row() );
00191 double aStep = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ?
00192 myTable->argStep( index.row() ) :
00193 myTable->funcStep( index.row() );
00194 sb->RangeStepAndValidator( aMin, aMax, aStep, "parametric_precision" );
00195 sb->setFrame(false);
00196
00197 myTable->setEditor( index.row(), index.column(), sb );
00198 return sb;
00199 }
00200
00201 void
00202 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
00203 setEditorData( QWidget* editor, const QModelIndex& index ) const
00204 {
00205 QString value = index.model()->data(index, Qt::DisplayRole).toString();
00206 SMESHGUI_SpinBox* sb = static_cast<SMESHGUI_SpinBox*>(editor);
00207
00208 bool bOk = false;
00209 double v = value.toDouble( &bOk );
00210 if ( !bOk ) v = sb->minimum();
00211
00212 sb->setValue( v );
00213 }
00214
00215 void
00216 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
00217 setModelData( QWidget* editor, QAbstractItemModel* model,
00218 const QModelIndex& index ) const
00219 {
00220 SMESHGUI_SpinBox* sb = static_cast<SMESHGUI_SpinBox*>(editor);
00221 model->setData( index, QString::number( sb->value() ), Qt::DisplayRole );
00222 }
00223
00224 void
00225 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
00226 updateEditorGeometry( QWidget* editor,
00227 const QStyleOptionViewItem& option,
00228 const QModelIndex& ) const
00229 {
00230 editor->setGeometry( option.rect );
00231 }
00232
00233
00234
00235
00236
00237 StdMeshersGUI_DistrTableFrame::Table::
00238 Table( QWidget* parent, int rows )
00239 : QTableWidget( parent ), myFuncMin( 0.0 )
00240 {
00241 setItemDelegate( new StdMeshersGUI_DistrTableFrame::SpinBoxDelegate( this ) );
00242
00243 setColumnCount( 2 );
00244
00245 QStringList labs;
00246 labs << "t" << "f(t)";
00247 setHorizontalHeaderLabels( labs );
00248 this->horizontalHeader()->setStretchLastSection(true);
00249 this->horizontalHeader()->setDefaultSectionSize(60);
00250
00251 while( rows-- )
00252 addRow();
00253
00254 setUpRows( true );
00255 }
00256
00257 void
00258 StdMeshersGUI_DistrTableFrame::Table::
00259 setEditor( int r, int c, SMESHGUI_SpinBox* sb )
00260 {
00261 myEditorData.r = r;
00262 myEditorData.c = c;
00263 myEditorData.sb = sb;
00264 }
00265
00266 StdMeshersGUI_DistrTableFrame::Table::
00267 ~Table()
00268 {
00269 }
00270
00271 QList<double>
00272 StdMeshersGUI_DistrTableFrame::Table::
00273 data()
00274 {
00275 closePersistentEditor( currentItem() );
00276
00277 QList<double> d;
00278 for ( int r = 0; r < rowCount(); r++ ) {
00279 d.append( value( r, ArgColumn ) );
00280 d.append( value( r, FuncColumn ) );
00281 }
00282 return d;
00283 }
00284
00285 void
00286 StdMeshersGUI_DistrTableFrame::Table::
00287 setData( const QList<double>& d )
00288 {
00289 closePersistentEditor( currentItem() );
00290
00291 setRowCount( d.count() / 2 );
00292 for ( int r = 0; r < rowCount(); r++ ) {
00293 setValue( r, ArgColumn, d[r*2] );
00294 setValue( r, FuncColumn, d[r*2+1] );
00295 }
00296 }
00297
00298 double
00299 StdMeshersGUI_DistrTableFrame::Table::
00300 value( int r, int c ) const
00301 {
00302 if ( r < 0 || r > rowCount() || c < 0 || c > columnCount() || !item( r, c ) )
00303 return 0.0;
00304
00305 return item( r, c )->text().toDouble();
00306 }
00307
00308 void
00309 StdMeshersGUI_DistrTableFrame::Table::
00310 setValue( int r, int c, double v )
00311 {
00312 if ( r < 0 || r > rowCount() || c < 0 || c > columnCount() )
00313 return;
00314
00315 if ( c == FuncColumn && v < funcMinimum( r ) )
00316 v = funcMinimum( r );
00317 if ( c == FuncColumn && v > funcMaximum( r ) )
00318 v = funcMaximum( r );
00319 else if ( r == ArgColumn && v < argMinimum( r ) )
00320 v = argMinimum( r );
00321 else if ( r == ArgColumn && v > argMaximum( r ) )
00322 v = argMaximum( r );
00323
00324 if ( !item( r, c ) )
00325 setItem( r, c, new QTableWidgetItem );
00326 item( r, c )->setText( QString::number( v ) );
00327 }
00328
00329 double
00330 StdMeshersGUI_DistrTableFrame::Table::
00331 argMinimum( int r ) const
00332 {
00333
00334
00335 double val = 0.0;
00336 if ( r > 0 && r < rowCount() )
00337 val = value( r-1, ArgColumn );
00338 return val;
00339 }
00340
00341 double
00342 StdMeshersGUI_DistrTableFrame::Table::
00343 argMaximum( int r ) const
00344 {
00345
00346
00347 double val = 1.0;
00348 if ( r >= 0 && r < rowCount()-1 ) {
00349 val = value( r+1, ArgColumn );
00350 }
00351 return val;
00352 }
00353
00354 double
00355 StdMeshersGUI_DistrTableFrame::Table::
00356 argStep( int ) const
00357 {
00358
00359 return 0.1;
00360 }
00361
00362 double
00363 StdMeshersGUI_DistrTableFrame::Table::
00364 funcMinimum( int ) const
00365 {
00366
00367 return myFuncMin;
00368 }
00369
00370 double
00371 StdMeshersGUI_DistrTableFrame::Table::
00372 funcMaximum( int ) const
00373 {
00374
00375 return 1e20;
00376 }
00377
00378 double
00379 StdMeshersGUI_DistrTableFrame::Table::
00380 funcStep( int ) const
00381 {
00382
00383 return 1.0;
00384 }
00385
00386 void
00387 StdMeshersGUI_DistrTableFrame::Table::
00388 setFuncMinValue( double val )
00389 {
00390 myFuncMin = val;
00391
00392 QTableWidgetItem* i = currentItem();
00393 if ( i &&
00394 i->row() == myEditorData.r &&
00395 i->column() == myEditorData.c &&
00396 i->column() == FuncColumn &&
00397 myEditorData.sb ) {
00398 myEditorData.sb->setMinimum( myFuncMin );
00399 }
00400 else {
00401 closePersistentEditor( currentItem() );
00402 }
00403
00404 for ( int r = 0; r < rowCount(); r++ ) {
00405 double v = item( r, FuncColumn )->text().toDouble();
00406 if ( v < myFuncMin )
00407 item( r, FuncColumn )->setText( QString::number( myFuncMin ) );
00408 }
00409 }
00410
00411 QSize
00412 StdMeshersGUI_DistrTableFrame::Table::
00413 sizeHint() const
00414 {
00415 if( cachedSizeHint().isValid() )
00416 return cachedSizeHint();
00417 return QTableWidget::sizeHint();
00418
00419
00420
00421
00422
00423
00424
00425
00426 }
00427
00428 void
00429 StdMeshersGUI_DistrTableFrame::Table::
00430 addRow()
00431 {
00432 int r = currentRow() >= 0 ? currentRow() : ( rowCount() > 0 ? rowCount() - 1 : 0 );
00433 insertRow( r );
00434
00435 double argMin = argMinimum( r );
00436 double funcMin = funcMinimum( r );
00437
00438 setItem( r, ArgColumn, new QTableWidgetItem( QString::number( argMin ) ) );
00439 setItem( r, FuncColumn, new QTableWidgetItem( QString::number( funcMin ) ) );
00440 }
00441
00442 void
00443 StdMeshersGUI_DistrTableFrame::Table::
00444 deleteRow()
00445 {
00446 QList<int> selRows = selectedRows();
00447 for ( int r = selRows.count()-1; r >= 0; r-- )
00448 removeRow( r );
00449 }
00450
00451 void
00452 StdMeshersGUI_DistrTableFrame::Table::
00453 closeEditor( QWidget* editor, QAbstractItemDelegate::EndEditHint hint )
00454 {
00455 myEditorData.reset();
00456 QTableWidget::closeEditor( editor, hint );
00457 }
00458
00459 void
00460 StdMeshersGUI_DistrTableFrame::Table::
00461 setUpRows( bool autoset )
00462 {
00463 if ( rowCount() < 1 )
00464 return;
00465 if ( autoset ) {
00466 double s = argMaximum( rowCount()-1 ) / rowCount();
00467 for ( int r = 0; r < rowCount()-1; r++ )
00468 setValue( r, ArgColumn, r * s );
00469 setValue( rowCount()-1, ArgColumn, argMaximum( rowCount()-1 ) );
00470 }
00471 else {
00472
00473 }
00474 }
00475
00476 QSize
00477 StdMeshersGUI_DistrTableFrame::Table::
00478 cachedSizeHint() const
00479 {
00480 return myCachedSizeHint;
00481 }
00482
00483 void
00484 StdMeshersGUI_DistrTableFrame::Table::
00485 setCachedSizeHint( const QSize& s ) const
00486 {
00487 Table* that = const_cast<Table*>( this );
00488 that->myCachedSizeHint = s;
00489 }
00490
00491 QList<int>
00492 StdMeshersGUI_DistrTableFrame::Table::
00493 selectedRows()
00494 {
00495 QList<int> l;
00496 QList<QTableWidgetItem*> selItems = selectedItems();
00497 QTableWidgetItem* i;
00498 foreach( i, selItems )
00499 if ( !l.contains( i->row() ) ) l.append( i->row() );
00500 qSort( l );
00501 return l;
00502 }
00503
00509 StdMeshersGUI_DistrTableFrame::
00510 StdMeshersGUI_DistrTableFrame( QWidget* parent )
00511 : QWidget( parent )
00512 {
00513 QGridLayout* main = new QGridLayout( this );
00514 main->setMargin( 0 );
00515 main->setSpacing( 0 );
00516
00517
00518 myTable = new Table( this );
00519 connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
00520
00521 myButtons[ InsertRowBtn ] = new QPushButton( tr( "SMESH_INSERT_ROW" ), this );
00522 myButtons[ RemoveRowBtn ] = new QPushButton( tr( "SMESH_REMOVE_ROW" ), this );
00523
00524
00525
00526 main->addWidget( myTable , 0, 0, 1, 3);
00527 main->addWidget( myButtons[ InsertRowBtn ] , 1, 0);
00528 main->addWidget( myButtons[ RemoveRowBtn ] , 1, 1);
00529 main->setColumnStretch(2, 1);
00530 main->setSpacing( SPACING );
00531
00532
00533 connect( myButtons[ InsertRowBtn ], SIGNAL( clicked() ), this, SLOT( onInsert() ) );
00534 connect( myButtons[ RemoveRowBtn ], SIGNAL( clicked() ), this, SLOT( onRemove() ) );
00535 connect( myTable, SIGNAL( currentCellChanged( int, int, int, int ) ),
00536 this, SIGNAL( currentChanged( int, int ) ) );
00537 connect( myTable, SIGNAL( cellChanged( int, int ) ),
00538 this, SIGNAL( valueChanged( int, int ) ) );
00539 }
00540
00541 StdMeshersGUI_DistrTableFrame::
00542 ~StdMeshersGUI_DistrTableFrame()
00543 {
00544 }
00545
00546 void
00547 StdMeshersGUI_DistrTableFrame::
00548 showButton( const TableButton b, const bool on )
00549 {
00550 if ( button( b ) ) button( b )->setVisible( on );
00551 }
00552
00553 bool
00554 StdMeshersGUI_DistrTableFrame::
00555 isButtonShown( const TableButton b ) const
00556 {
00557 return button( b ) ? button( b )->isVisible() : false;
00558 }
00559
00560 void
00561 StdMeshersGUI_DistrTableFrame::
00562 data( DataArray& array ) const
00563 {
00564 QList<double> d = myTable->data();
00565 sortData( d );
00566
00567 array.length( d.count() );
00568 for ( int i = 0; i < d.count(); i++ )
00569 array[i] = d[i];
00570 }
00571
00572 void
00573 StdMeshersGUI_DistrTableFrame::
00574 setData( const DataArray& array )
00575 {
00576 QList<double> d;
00577 for ( int i = 0; i < array.length(); i++ )
00578 d.append( array[i] );
00579
00580 sortData( d );
00581 myTable->setData( d );
00582 }
00583
00584 void
00585 StdMeshersGUI_DistrTableFrame::
00586 setFuncMinValue( double v )
00587 {
00588 myTable->setFuncMinValue( v );
00589 }
00590
00591 QPushButton*
00592 StdMeshersGUI_DistrTableFrame::
00593 button( const TableButton b ) const
00594 {
00595 return myButtons.contains( b ) ? myButtons[ b ] : 0;
00596 }
00597
00598 void
00599 StdMeshersGUI_DistrTableFrame::
00600 onInsert()
00601 {
00602 myTable->addRow();
00603 }
00604
00605 void
00606 StdMeshersGUI_DistrTableFrame::
00607 onRemove()
00608 {
00609 myTable->deleteRow();
00610 }