smesh/src/StdMeshersGUI/StdMeshersGUI_DistrTable.cxx

611 lines
15 KiB
C++
Raw Normal View History

2015-02-13 13:38:35 +05:00
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
2012-08-09 16:03:55 +06:00
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
2012-08-09 16:03:55 +06:00
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
2014-02-20 18:25:37 +06:00
// version 2.1 of the License, or (at your option) any later version.
//
2012-08-09 16:03:55 +06:00
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
2012-08-09 16:03:55 +06:00
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
2012-08-09 16:03:55 +06:00
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
2012-08-09 16:03:55 +06:00
2009-02-17 10:27:49 +05:00
// File : StdMeshersGUI_DistrTable.cxx
// Author : Open CASCADE S.A.S.
// SMESH includes
//
#include "StdMeshersGUI_DistrTable.h"
2012-08-09 16:03:55 +06:00
#include <SMESHGUI_SpinBox.h>
2009-02-17 10:27:49 +05:00
// Qt incldues
#include <QItemDelegate>
#include <QTableWidget>
2012-08-09 16:03:55 +06:00
#include <QHeaderView>
2009-02-17 10:27:49 +05:00
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#define SPACING 6
/*!
\brief Sort list of points by ascending order.
\internal
*/
static void sortData( QList<double>& d )
{
typedef QPair<double, double> Pair;
QList<Pair> pairs;
for ( int i = 0; i < d.count() / 2; i++ )
pairs.append( Pair( d[i*2], d[i*2+1] ) );
qSort( pairs );
d.clear();
Pair p;
double prevX = 0.0, prevY = 0.0;
d.append( prevX );
d.append( pairs.count() > 0 ? pairs[0].second : prevY );
foreach( p, pairs ) {
if ( p.first > prevX ) {
d.append( p.first );
d.append( p.second );
prevY = p.second;
}
prevX = p.first;
}
if ( prevX < 1.0 ) {
d.append( 1.0 );
d.append( prevY );
}
}
/*!
\class StdMeshersGUI_DistrTableFrame::SpinBoxDelegate
\brief Custom item delegate (uses double spin box to edit table item)
\internal
*/
2009-02-17 10:27:49 +05:00
class StdMeshersGUI_DistrTableFrame::SpinBoxDelegate : public QItemDelegate
{
public:
SpinBoxDelegate( StdMeshersGUI_DistrTableFrame::Table* );
~SpinBoxDelegate();
QWidget* createEditor( QWidget*,
2012-08-09 16:03:55 +06:00
const QStyleOptionViewItem&,
const QModelIndex& ) const;
2009-02-17 10:27:49 +05:00
void setEditorData( QWidget*, const QModelIndex&) const;
void setModelData( QWidget*, QAbstractItemModel*,
2012-08-09 16:03:55 +06:00
const QModelIndex& ) const;
2009-02-17 10:27:49 +05:00
void updateEditorGeometry( QWidget*,
2012-08-09 16:03:55 +06:00
const QStyleOptionViewItem&,
const QModelIndex& ) const;
2009-02-17 10:27:49 +05:00
private:
StdMeshersGUI_DistrTableFrame::Table* myTable;
};
/*!
\class StdMeshersGUI_DistrTableFrame::Table
\brief Table function widget
\internal
*/
class StdMeshersGUI_DistrTableFrame::Table : public QTableWidget
{
private:
struct EditorData
{
int r, c;
2012-08-09 16:03:55 +06:00
SMESHGUI_SpinBox* sb;
2009-02-17 10:27:49 +05:00
EditorData() { reset(); }
void reset() { r = -1; c = -1; sb = 0; }
};
public:
Table( QWidget*, int = 2 );
~Table();
QList<double> data();
void setData( const QList<double>& );
double value( int, int ) const;
void setValue( int, int, double );
double argMinimum( int ) const;
double argMaximum( int ) const;
double argStep( int ) const;
double funcMinimum( int ) const;
double funcMaximum( int ) const;
double funcStep( int ) const;
void setFuncMinValue( double );
QSize sizeHint() const;
void addRow();
void deleteRow();
2012-08-09 16:03:55 +06:00
void setEditor( int, int, SMESHGUI_SpinBox* );
2009-02-17 10:27:49 +05:00
protected:
void closeEditor( QWidget*, QAbstractItemDelegate::EndEditHint );
private:
void setUpRows( bool = false );
QSize cachedSizeHint() const;
void setCachedSizeHint( const QSize& ) const;
QList<int> selectedRows();
private:
double myFuncMin;
QSize myCachedSizeHint;
EditorData myEditorData;
};
// ---
// StdMeshersGUI_DistrTableFrame::SpinBoxDelegate implementation
// ---
StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
SpinBoxDelegate( StdMeshersGUI_DistrTableFrame::Table* parent )
: QItemDelegate( parent ), myTable( parent )
{
}
2009-02-17 10:27:49 +05:00
StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
~SpinBoxDelegate()
{
}
2009-02-17 10:27:49 +05:00
QWidget*
StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
createEditor( QWidget* parent,
2012-08-09 16:03:55 +06:00
const QStyleOptionViewItem& /*option*/,
const QModelIndex& index ) const
{
2012-08-09 16:03:55 +06:00
SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
sb->setAcceptNames(false); // No Notebook variables allowed
double aMin = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ?
myTable->argMinimum( index.row() ) :
myTable->funcMinimum( index.row() );
double aMax = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ?
myTable->argMaximum( index.row() ) :
myTable->funcMaximum( index.row() );
double aStep = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ?
myTable->argStep( index.row() ) :
myTable->funcStep( index.row() );
sb->RangeStepAndValidator( aMin, aMax, aStep, "parametric_precision" );
2009-02-17 10:27:49 +05:00
sb->setFrame(false);
2012-08-09 16:03:55 +06:00
myTable->setEditor( index.row(), index.column(), sb );
2009-02-17 10:27:49 +05:00
return sb;
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
setEditorData( QWidget* editor, const QModelIndex& index ) const
{
QString value = index.model()->data(index, Qt::DisplayRole).toString();
2012-08-09 16:03:55 +06:00
SMESHGUI_SpinBox* sb = static_cast<SMESHGUI_SpinBox*>(editor);
2009-02-17 10:27:49 +05:00
bool bOk = false;
double v = value.toDouble( &bOk );
if ( !bOk ) v = sb->minimum();
2009-02-17 10:27:49 +05:00
sb->setValue( v );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
setModelData( QWidget* editor, QAbstractItemModel* model,
2012-08-09 16:03:55 +06:00
const QModelIndex& index ) const
{
2012-08-09 16:03:55 +06:00
SMESHGUI_SpinBox* sb = static_cast<SMESHGUI_SpinBox*>(editor);
2009-02-17 10:27:49 +05:00
model->setData( index, QString::number( sb->value() ), Qt::DisplayRole );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
updateEditorGeometry( QWidget* editor,
2012-08-09 16:03:55 +06:00
const QStyleOptionViewItem& option,
const QModelIndex& /*index*/ ) const
{
2009-02-17 10:27:49 +05:00
editor->setGeometry( option.rect );
}
2009-02-17 10:27:49 +05:00
// ---
// StdMeshersGUI_DistrTableFrame::Table implementation
// ---
StdMeshersGUI_DistrTableFrame::Table::
Table( QWidget* parent, int rows )
: QTableWidget( parent ), myFuncMin( 0.0 )
{
2009-02-17 10:27:49 +05:00
setItemDelegate( new StdMeshersGUI_DistrTableFrame::SpinBoxDelegate( this ) );
setColumnCount( 2 );
QStringList labs;
labs << "t" << "f(t)";
setHorizontalHeaderLabels( labs );
2012-08-09 16:03:55 +06:00
this->horizontalHeader()->setStretchLastSection(true);
this->horizontalHeader()->setDefaultSectionSize(60);
2009-02-17 10:27:49 +05:00
while( rows-- )
addRow();
setUpRows( true );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
2012-08-09 16:03:55 +06:00
setEditor( int r, int c, SMESHGUI_SpinBox* sb )
{
2009-02-17 10:27:49 +05:00
myEditorData.r = r;
myEditorData.c = c;
myEditorData.sb = sb;
}
2009-02-17 10:27:49 +05:00
StdMeshersGUI_DistrTableFrame::Table::
~Table()
{
}
2009-02-17 10:27:49 +05:00
QList<double>
StdMeshersGUI_DistrTableFrame::Table::
data()
{
closePersistentEditor( currentItem() );
2009-02-17 10:27:49 +05:00
QList<double> d;
for ( int r = 0; r < rowCount(); r++ ) {
d.append( value( r, ArgColumn ) );
d.append( value( r, FuncColumn ) );
}
2009-02-17 10:27:49 +05:00
return d;
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
setData( const QList<double>& d )
{
2009-02-17 10:27:49 +05:00
closePersistentEditor( currentItem() );
setRowCount( d.count() / 2 );
for ( int r = 0; r < rowCount(); r++ ) {
setValue( r, ArgColumn, d[r*2] );
setValue( r, FuncColumn, d[r*2+1] );
}
2009-02-17 10:27:49 +05:00
}
double
StdMeshersGUI_DistrTableFrame::Table::
value( int r, int c ) const
{
if ( r < 0 || r > rowCount() || c < 0 || c > columnCount() || !item( r, c ) )
return 0.0;
return item( r, c )->text().toDouble();
}
void
StdMeshersGUI_DistrTableFrame::Table::
setValue( int r, int c, double v )
{
if ( r < 0 || r > rowCount() || c < 0 || c > columnCount() )
return;
if ( c == FuncColumn && v < funcMinimum( r ) )
v = funcMinimum( r ); // correct func value according to the valid min value
if ( c == FuncColumn && v > funcMaximum( r ) )
v = funcMaximum( r ); // correct func value according to the valid max value
else if ( r == ArgColumn && v < argMinimum( r ) )
v = argMinimum( r ); // correct arg value according to the valid min value
else if ( r == ArgColumn && v > argMaximum( r ) )
v = argMaximum( r ); // correct arg value according to the valid max value
if ( !item( r, c ) )
setItem( r, c, new QTableWidgetItem );
item( r, c )->setText( QString::number( v ) );
}
double
StdMeshersGUI_DistrTableFrame::Table::
argMinimum( int r ) const
{
// for the first row the minimum value is always 0.0
// for the other rows the minumum value is the above row's value
double val = 0.0;
if ( r > 0 && r < rowCount() )
val = value( r-1, ArgColumn );
return val;
}
double
StdMeshersGUI_DistrTableFrame::Table::
argMaximum( int r ) const
{
// for the last row the maximum value is always 1.0
// for the other rows the maxumum value is the below row's value
double val = 1.0;
if ( r >= 0 && r < rowCount()-1 ) {
val = value( r+1, ArgColumn );
}
2009-02-17 10:27:49 +05:00
return val;
}
2009-02-17 10:27:49 +05:00
double
StdMeshersGUI_DistrTableFrame::Table::
argStep( int /*r*/ ) const
{
2009-02-17 10:27:49 +05:00
// correct this to provide more smart behaviour if needed
return 0.1;
}
2009-02-17 10:27:49 +05:00
double
StdMeshersGUI_DistrTableFrame::Table::
funcMinimum( int /*r*/ ) const
{
// correct this to provide more smart behaviour if needed
return myFuncMin;
}
double
StdMeshersGUI_DistrTableFrame::Table::
funcMaximum( int /*r*/ ) const
{
// correct this to provide more smart behaviour if needed
return 1e20;
}
2009-02-17 10:27:49 +05:00
double
StdMeshersGUI_DistrTableFrame::Table::
funcStep( int /*r*/ ) const
{
// correct this to provide more smart behaviour if needed
return 1.0;
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
setFuncMinValue( double val )
{
myFuncMin = val;
QTableWidgetItem* i = currentItem();
if ( i &&
i->row() == myEditorData.r &&
i->column() == myEditorData.c &&
i->column() == FuncColumn &&
myEditorData.sb ) {
myEditorData.sb->setMinimum( myFuncMin );
}
2009-02-17 10:27:49 +05:00
else {
closePersistentEditor( currentItem() );
}
2009-02-17 10:27:49 +05:00
for ( int r = 0; r < rowCount(); r++ ) {
double v = item( r, FuncColumn )->text().toDouble();
if ( v < myFuncMin )
item( r, FuncColumn )->setText( QString::number( myFuncMin ) );
}
2009-02-17 10:27:49 +05:00
}
2009-02-17 10:27:49 +05:00
QSize
StdMeshersGUI_DistrTableFrame::Table::
sizeHint() const
{
if( cachedSizeHint().isValid() )
return cachedSizeHint();
2012-08-09 16:03:55 +06:00
return QTableWidget::sizeHint();
// QSize sh = QTableWidget::sizeHint();
// if( sh.width() < 400 )
// sh.setWidth( 400 );
// if( sh.height() < 200 )
// sh.setHeight( 200 );
//
// setCachedSizeHint( sh );
// return sh;
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
addRow()
{
2009-02-17 10:27:49 +05:00
int r = currentRow() >= 0 ? currentRow() : ( rowCount() > 0 ? rowCount() - 1 : 0 );
insertRow( r );
double argMin = argMinimum( r );
double funcMin = funcMinimum( r );
setItem( r, ArgColumn, new QTableWidgetItem( QString::number( argMin ) ) );
setItem( r, FuncColumn, new QTableWidgetItem( QString::number( funcMin ) ) );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
deleteRow()
{
2009-02-17 10:27:49 +05:00
QList<int> selRows = selectedRows();
for ( int r = selRows.count()-1; r >= 0; r-- )
removeRow( selRows.at(r) );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
closeEditor( QWidget* editor, QAbstractItemDelegate::EndEditHint hint )
{
2009-02-17 10:27:49 +05:00
myEditorData.reset();
QTableWidget::closeEditor( editor, hint );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
setUpRows( bool autoset )
{
2009-02-17 10:27:49 +05:00
if ( rowCount() < 1 )
return;
if ( autoset ) {
double s = argMaximum( rowCount()-1 ) / rowCount();
for ( int r = 0; r < rowCount()-1; r++ )
setValue( r, ArgColumn, r * s );
setValue( rowCount()-1, ArgColumn, argMaximum( rowCount()-1 ) );
}
else {
// TODO
}
}
2009-02-17 10:27:49 +05:00
QSize
StdMeshersGUI_DistrTableFrame::Table::
cachedSizeHint() const
{
2009-02-17 10:27:49 +05:00
return myCachedSizeHint;
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::Table::
setCachedSizeHint( const QSize& s ) const
{
Table* that = const_cast<Table*>( this );
that->myCachedSizeHint = s;
}
2009-02-17 10:27:49 +05:00
QList<int>
StdMeshersGUI_DistrTableFrame::Table::
selectedRows()
{
QList<int> l;
QList<QTableWidgetItem*> selItems = selectedItems();
QTableWidgetItem* i;
foreach( i, selItems )
if ( !l.contains( i->row() ) ) l.append( i->row() );
qSort( l );
return l;
}
2009-02-17 10:27:49 +05:00
/*!
\class StdMeshersGUI_DistrTableFrame
\brief Distribution table widget
*/
2009-02-17 10:27:49 +05:00
StdMeshersGUI_DistrTableFrame::
StdMeshersGUI_DistrTableFrame( QWidget* parent )
: QWidget( parent )
{
2012-08-09 16:03:55 +06:00
QGridLayout* main = new QGridLayout( this );
2009-02-17 10:27:49 +05:00
main->setMargin( 0 );
main->setSpacing( 0 );
2009-02-17 10:27:49 +05:00
// ---
myTable = new Table( this );
connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
2012-08-09 16:03:55 +06:00
myButtons[ InsertRowBtn ] = new QPushButton( tr( "SMESH_INSERT_ROW" ), this );
myButtons[ RemoveRowBtn ] = new QPushButton( tr( "SMESH_REMOVE_ROW" ), this );
2009-02-17 10:27:49 +05:00
// ---
2012-08-09 16:03:55 +06:00
main->addWidget( myTable , 0, 0, 1, 3);
main->addWidget( myButtons[ InsertRowBtn ] , 1, 0);
main->addWidget( myButtons[ RemoveRowBtn ] , 1, 1);
main->setColumnStretch(2, 1);
main->setSpacing( SPACING );
2009-02-17 10:27:49 +05:00
// ---
connect( myButtons[ InsertRowBtn ], SIGNAL( clicked() ), this, SLOT( onInsert() ) );
connect( myButtons[ RemoveRowBtn ], SIGNAL( clicked() ), this, SLOT( onRemove() ) );
connect( myTable, SIGNAL( currentCellChanged( int, int, int, int ) ),
2012-08-09 16:03:55 +06:00
this, SIGNAL( currentChanged( int, int ) ) );
2009-02-17 10:27:49 +05:00
connect( myTable, SIGNAL( cellChanged( int, int ) ),
2012-08-09 16:03:55 +06:00
this, SIGNAL( valueChanged( int, int ) ) );
}
2009-02-17 10:27:49 +05:00
StdMeshersGUI_DistrTableFrame::
~StdMeshersGUI_DistrTableFrame()
{
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::
showButton( const TableButton b, const bool on )
{
2009-02-17 10:27:49 +05:00
if ( button( b ) ) button( b )->setVisible( on );
}
2009-02-17 10:27:49 +05:00
bool
StdMeshersGUI_DistrTableFrame::
isButtonShown( const TableButton b ) const
{
2009-02-17 10:27:49 +05:00
return button( b ) ? button( b )->isVisible() : false;
}
void
StdMeshersGUI_DistrTableFrame::
data( DataArray& array ) const
{
QList<double> d = myTable->data();
sortData( d );
array.length( d.count() );
for ( int i = 0; i < d.count(); i++ )
array[i] = d[i];
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::
setData( const DataArray& array )
{
2009-02-17 10:27:49 +05:00
QList<double> d;
for ( CORBA::ULong i = 0; i < array.length(); i++ )
2009-02-17 10:27:49 +05:00
d.append( array[i] );
sortData( d );
myTable->setData( d );
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::
setFuncMinValue( double v )
{
2009-02-17 10:27:49 +05:00
myTable->setFuncMinValue( v );
}
2009-02-17 10:27:49 +05:00
QPushButton*
StdMeshersGUI_DistrTableFrame::
button( const TableButton b ) const
{
return myButtons.contains( b ) ? myButtons[ b ] : 0;
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::
onInsert()
{
2009-02-17 10:27:49 +05:00
myTable->addRow();
}
2009-02-17 10:27:49 +05:00
void
StdMeshersGUI_DistrTableFrame::
onRemove()
{
myTable->deleteRow();
}