Back to index

salome-smesh  6.5.0
StdMeshersGUI_FixedPointsParamWdg.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File   : StdMeshersGUI_FixedPointsParamWdg.cxx
00021 // Author : Open CASCADE S.A.S.
00022 // SMESH includes
00023 //
00024 #include "StdMeshersGUI_FixedPointsParamWdg.h"
00025 
00026 #include <SMESHGUI_SpinBox.h>
00027 
00028 #include <SalomeApp_IntSpinBox.h>
00029 
00030 // Qt includes
00031 #include <QPushButton>
00032 #include <QIntValidator>
00033 #include <QGridLayout>
00034 #include <QListWidget>
00035 #include <QListWidgetItem>
00036 #include <QItemDelegate>
00037 #include <QTreeWidget>
00038 #include <QTreeWidgetItem>
00039 #include <QCheckBox>
00040 #include <QLineEdit>
00041 #include <QItemDelegate>
00042 #include <QKeyEvent>
00043 
00044 #define SPACING 6
00045 #define MARGIN 0
00046 #define SAME_TEXT "-/-"
00047 
00048 #define TOLERANCE 1e-7
00049 #define EQUAL_DBL(a,b) (fabs(a-b)<TOLERANCE)
00050 #define LT_DBL(a,b) ((a<b)&&!EQUAL_DBL(a,b))
00051 #define GT_DBL(a,b) ((a>b)&&!EQUAL_DBL(a,b))
00052 
00053 /*
00054  * class : Tree Widget Item Delegate
00055  * purpose  : Custom item delegate
00056  */
00057 
00058 class StdMeshersGUI_FixedPointsParamWdg::LineDelegate : public QItemDelegate
00059 {
00060 public:
00061   LineDelegate( QTreeWidget* );
00062   ~LineDelegate() {}
00063 
00064   QWidget*     createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
00065   void         setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
00066 
00067 private:
00068   QTreeWidget* myTreeWidget;
00069 };
00070 
00071 StdMeshersGUI_FixedPointsParamWdg::LineDelegate::LineDelegate( QTreeWidget* parent )
00072   : QItemDelegate( parent ),
00073     myTreeWidget( parent )
00074 {
00075 }
00076 
00077 QWidget* StdMeshersGUI_FixedPointsParamWdg::LineDelegate::createEditor( QWidget* parent,
00078                                                                         const QStyleOptionViewItem& option,
00079                                                                         const QModelIndex& index ) const
00080 {
00081   QWidget* w = 0;
00082   if ( (index.column() == 1 ) ) {
00083     SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( parent );
00084     sb->setAcceptNames( false ); // No Notebook variables allowed
00085     sb->setFrame( false );
00086     sb->setRange( 1, 999);
00087     w = sb;
00088   }
00089 
00090   return w;
00091 }
00092 
00093 void StdMeshersGUI_FixedPointsParamWdg::LineDelegate::setModelData( QWidget* editor, 
00094                                                                     QAbstractItemModel* model, 
00095                                                                     const QModelIndex& index ) const
00096 {
00097   model->setData( index, qobject_cast<SalomeApp_IntSpinBox*>( editor )->value(), Qt::EditRole );
00098   model->setData( index, qobject_cast<SalomeApp_IntSpinBox*>( editor )->value(), Qt::UserRole );
00099 }
00100 
00101 //================================================================================
00105 //================================================================================
00106 
00107 StdMeshersGUI_FixedPointsParamWdg
00108 ::StdMeshersGUI_FixedPointsParamWdg( QWidget * parent ): 
00109   QWidget( parent )
00110 {
00111   QGridLayout* edgesLayout = new QGridLayout( this );
00112   edgesLayout->setMargin( MARGIN );
00113   edgesLayout->setSpacing( SPACING );
00114   
00115   myListWidget   = new QListWidget( this );
00116   myTreeWidget   = new QTreeWidget( this );
00117   mySpinBox      = new SMESHGUI_SpinBox( this );
00118   myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
00119   myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
00120   mySameValues   = new QCheckBox( tr("SMESH_SAME_NB_SEGMENTS"), this);
00121 
00122   myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
00123 
00124   myTreeWidget->setColumnCount(2);
00125   myTreeWidget->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << tr( "SMESH_NB_SEGMENTS" ) );
00126   myTreeWidget->setColumnWidth( 1, 40 );
00127   myTreeWidget->setColumnWidth( 2, 30 );
00128   myTreeWidget->setItemDelegate( new LineDelegate( myTreeWidget ) );
00129 
00130   edgesLayout->addWidget(myListWidget,   0, 0, 4, 1);
00131   edgesLayout->addWidget(mySpinBox,      0, 1);
00132   edgesLayout->addWidget(myAddButton,    1, 1);
00133   edgesLayout->addWidget(myRemoveButton, 2, 1);
00134   edgesLayout->addWidget(myTreeWidget,   0, 2, 4, 1);
00135   edgesLayout->addWidget(mySameValues,   4, 0, 1, 3);
00136   edgesLayout->setRowStretch( 3, 5 );
00137   edgesLayout->setColumnStretch(0, 1);
00138   edgesLayout->setColumnStretch(1, 0);
00139   edgesLayout->setColumnStretch(2, 2);
00140 
00141   myListWidget->setMinimumWidth( 80 );
00142   myTreeWidget->setMinimumWidth( 200 );
00143 
00144   mySpinBox->setAcceptNames( false ); // No Notebook variables allowed
00145   mySpinBox->RangeStepAndValidator( 0., 1., .1, "parametric_precision" );
00146   myListWidget->setMinimumWidth( 70 );
00147 
00148   connect( myAddButton,    SIGNAL( clicked() ),              SLOT( onAdd() ) );
00149   connect( myRemoveButton, SIGNAL( clicked() ),              SLOT( onRemove() ) );
00150   connect( mySameValues,   SIGNAL( stateChanged( int ) ),    SLOT( onCheckBoxChanged() ) );
00151   connect( mySpinBox,      SIGNAL( valueChanged( double ) ), SLOT( updateState() ) );
00152   connect( myListWidget,   SIGNAL( itemSelectionChanged() ), SLOT( updateState() ) );
00153   myListWidget->installEventFilter( this );
00154 
00155   clear();
00156 }
00157 
00158 //================================================================================
00162 //================================================================================
00163 
00164 StdMeshersGUI_FixedPointsParamWdg::~StdMeshersGUI_FixedPointsParamWdg()
00165 {
00166 }
00167 
00168 //================================================================================
00172 //================================================================================
00173 bool StdMeshersGUI_FixedPointsParamWdg::eventFilter( QObject* o, QEvent* e )
00174 {
00175   if ( o == myListWidget && e->type() == QEvent::KeyPress ) {
00176     QKeyEvent* ke = (QKeyEvent*)e;
00177     if ( ke->key() == Qt::Key_Delete )
00178       removePoints();
00179   }
00180   return QWidget::eventFilter( o, e );
00181 }
00182 
00183 //================================================================================
00187 //================================================================================
00188 void StdMeshersGUI_FixedPointsParamWdg::clear()
00189 {
00190   myTreeWidget->clear();
00191   myListWidget->clear();
00192   myTreeWidget->addTopLevelItem( newTreeItem( 0, 1 ) );
00193   mySpinBox->setValue( 0. );
00194   onCheckBoxChanged();
00195   updateState();
00196 }
00197 
00198 //=================================================================================
00199 // function : onAdd()
00200 // purpose  : Called when Add Button Clicked
00201 //=================================================================================
00202 void StdMeshersGUI_FixedPointsParamWdg::onAdd()
00203 {
00204   addPoint( mySpinBox->value() );
00205 }
00206          
00207 //=================================================================================
00208 // function : onRemove()
00209 // purpose  : Called when Remove Button Clicked
00210 //=================================================================================
00211 void StdMeshersGUI_FixedPointsParamWdg::onRemove()
00212 {
00213   removePoints();
00214 }
00215 
00216 //=================================================================================
00217 // function : newTreeItem()
00218 // purpose  : Called to create TreeItem
00219 //=================================================================================
00220 
00221 QTreeWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newTreeItem( double v1, double v2 )
00222 {
00223   QTreeWidgetItem* anItem = new QTreeWidgetItem();
00224   anItem->setText( 0, treeItemText( v1, v2 ) );
00225   anItem->setText( 1, QString::number( 1 ) );
00226   anItem->setData( 1, Qt::UserRole, 1 );
00227   return anItem;
00228 }
00229 
00230 //=================================================================================
00231 // function : newListItem()
00232 // purpose  : Called to create ListItem
00233 //=================================================================================
00234 
00235 QListWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newListItem( double v )
00236 {
00237   QListWidgetItem* anItem = new QListWidgetItem( QString::number( v ) );
00238   anItem->setData( Qt::UserRole, v );
00239   return anItem;
00240 }
00241 
00242 //=================================================================================
00243 // function : itemText()
00244 // purpose  : Called to convert Values to Text
00245 //=================================================================================
00246 
00247 QString StdMeshersGUI_FixedPointsParamWdg::treeItemText( double v1, double v2 )
00248 {
00249   return QString( "%1 - %2" ).arg( v1 ).arg( v2 );
00250 }
00251 
00252 //=================================================================================
00253 // function : addPoint()
00254 // purpose  : Called to Add new Point
00255 //=================================================================================
00256 void StdMeshersGUI_FixedPointsParamWdg::addPoint( double v)
00257 {
00258   if ( GT_DBL(v, 0.0) && LT_DBL(v, 1.0)) {
00259     bool toInsert = true;
00260     int idx = myTreeWidget->topLevelItemCount()-1;
00261     for ( int i = 0 ; i < myListWidget->count(); i++ ) {
00262       double lv = point( i );
00263       if ( EQUAL_DBL(lv, v) ) { toInsert = false; break; }
00264       else if ( GT_DBL(lv, v) ) {
00265         idx = i; break;
00266       }
00267     }
00268     if ( toInsert ) {
00269       double v1 = idx == 0 ? 0 : point( idx-1 );
00270       double v2 = idx == myTreeWidget->topLevelItemCount()-1 ? 1 : point( idx );
00271       myTreeWidget->insertTopLevelItem( idx, newTreeItem( v1, v ) );
00272       myTreeWidget->topLevelItem( idx+1 )->setText( 0, treeItemText( v, v2 ) );
00273       myListWidget->insertItem( idx, newListItem( v ) );
00274       onCheckBoxChanged();
00275     }
00276   }
00277   updateState();
00278 }
00279 
00280 //=================================================================================
00281 // function : removePoints()
00282 // purpose  : Called to remove selected points
00283 //=================================================================================
00284 void StdMeshersGUI_FixedPointsParamWdg::removePoints()
00285 {
00286   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
00287   QListWidgetItem* item;
00288   foreach ( item, selItems ) {
00289     int idx = myListWidget->row( item );
00290     delete myTreeWidget->topLevelItem( idx );
00291     delete item;
00292     myTreeWidget->topLevelItem( idx )->setText( 0, treeItemText( idx == 0 ? 0 : point( idx-1 ),
00293                                                                  idx > myListWidget->count()-1 ? 1 : point( idx ) ) );
00294   }
00295   onCheckBoxChanged();
00296   updateState();
00297 }
00298 
00299 double StdMeshersGUI_FixedPointsParamWdg::point( int idx ) const
00300 {
00301   return idx >= 0 && idx < myListWidget->count() ? myListWidget->item( idx )->data( Qt::UserRole ).toDouble() : 0.;
00302 }
00303 
00304 void StdMeshersGUI_FixedPointsParamWdg::setNbSegments( int idx, int val )
00305 {
00306   if ( idx >= 0 && idx < myTreeWidget->topLevelItemCount() ) {
00307     myTreeWidget->topLevelItem( idx )->setData( 1, Qt::UserRole, val );
00308     myTreeWidget->topLevelItem( idx )->setText( 1, idx > 0 && mySameValues->isChecked() ? QString( SAME_TEXT ) : QString::number( val ) );
00309   }
00310 }
00311 
00312 int StdMeshersGUI_FixedPointsParamWdg::nbSegments( int idx ) const
00313 {
00314   return idx >= 0 && idx < myTreeWidget->topLevelItemCount() ? myTreeWidget->topLevelItem( idx )->data( 1, Qt::UserRole ).toInt() : 1;
00315 }
00316 
00317 //=================================================================================
00318 // function : onCheckBoxChanged()
00319 // purpose  : Called when Check Box Clicked
00320 //=================================================================================
00321 void StdMeshersGUI_FixedPointsParamWdg::onCheckBoxChanged()
00322 {
00323   for ( int i = 0; i < myTreeWidget->topLevelItemCount(); i++ ) {
00324     QTreeWidgetItem* anItem = myTreeWidget->topLevelItem(i);
00325     setNbSegments( i, nbSegments( i ) );
00326     anItem->setFlags( mySameValues->isChecked() && i > 0 ? anItem->flags() & ~Qt::ItemIsEditable : anItem->flags() | Qt::ItemIsEditable );
00327   }
00328 }
00329 
00330 //=================================================================================
00331 // function : updateState()
00332 // purpose  : Update widgets state
00333 //=================================================================================
00334 void StdMeshersGUI_FixedPointsParamWdg::updateState()
00335 {
00336   double v = mySpinBox->value();
00337   myAddButton->setEnabled( GT_DBL(v, 0.0) && LT_DBL(v, 1.0) );
00338   myRemoveButton->setEnabled( myListWidget->selectedItems().count() > 0 );
00339 }
00340 
00341 //=================================================================================
00342 // function : GetListOfPoints
00343 // purpose  : Called to get the list of Edges IDs
00344 //=================================================================================
00345 SMESH::double_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfPoints()
00346 {
00347   SMESH::double_array_var anArray = new SMESH::double_array;
00348   int size = myListWidget->count();
00349   anArray->length( size );
00350   for (int i = 0; i < size; i++) {
00351     anArray[i] = point(i);
00352   }
00353   return anArray;
00354 }
00355 
00356 //=================================================================================
00357 // function : SetListOfPoints
00358 // purpose  : Called to set the list of Points
00359 //=================================================================================
00360 void StdMeshersGUI_FixedPointsParamWdg::SetListOfPoints( SMESH::double_array_var thePoints)
00361 {
00362   clear();
00363   for ( int i = 0; i < thePoints->length(); i++ ) {
00364     addPoint( thePoints[ i ] );
00365   }
00366 }
00367 
00368 //=================================================================================
00369 // function : GetListOfSegments
00370 // purpose  : Called to get the list Number of Segments
00371 //=================================================================================
00372 SMESH::long_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfSegments()
00373 {
00374   SMESH::long_array_var anArray = new SMESH::long_array;
00375   int size = mySameValues->isChecked() ? 1 : myTreeWidget->topLevelItemCount();
00376   anArray->length( size );
00377   for (int i = 0; i < size; i++) {
00378     anArray[i] = nbSegments( i );
00379   }
00380   return anArray;
00381 }
00382 
00383 //=================================================================================
00384 // function : SetListOfPoints
00385 // purpose  : Called to set the list of Points
00386 //=================================================================================
00387 void StdMeshersGUI_FixedPointsParamWdg::SetListOfSegments( SMESH::long_array_var theSegments)
00388 {
00389   if ( myListWidget->count() > 0 && theSegments->length() == 1)
00390     mySameValues->setChecked(true);
00391   for ( int i = 0; i < theSegments->length(); i++ ) {
00392     setNbSegments( i, theSegments[i] );
00393   }
00394 }