Salome HOME
Merge from OCC_development_generic_2006
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_DistrTable.cxx
1 //  SMESH StdMeshersGUI
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   : StdMeshersGUI_DistrTable.cxx
25 //  Module : SMESH
26 //  $Header$
27
28 #include "StdMeshersGUI_DistrTable.h"
29 #include <QtxDblValidator.h>
30
31 #include <qlayout.h>
32 #include <qpushbutton.h>
33 #include <qlineedit.h>
34
35 //=================================================================================
36 // class    : StdMeshersGUI_DistrTable
37 // purpose  :
38 //=================================================================================
39 StdMeshersGUI_DistrTable::StdMeshersGUI_DistrTable( const int rows, QWidget* parent, const char* name )
40 : QTable( rows, 2, parent, name )
41 {
42   horizontalHeader()->setLabel( 0, "t" );
43   horizontalHeader()->setLabel( 1, "f(t)" );
44   myArgV = new QtxDblValidator( 0.0, 1.0, 3, this );
45   myFuncV = new QtxDblValidator( 0.0, 1E20, 3, this );
46 }
47
48 StdMeshersGUI_DistrTable::~StdMeshersGUI_DistrTable()
49 {
50 }
51
52 QSize StdMeshersGUI_DistrTable::sizeHint() const
53 {
54   if( cachedSizeHint().isValid() )
55     return cachedSizeHint();
56
57   constPolish();
58
59   QSize sh = QScrollView::sizeHint();
60   if( sh.width()<400 )
61     sh.setWidth( 400 );
62   if( sh.height()<200 )
63     sh.setHeight( 200 );
64
65   setCachedSizeHint( sh );
66   return sh;
67 }
68
69 void StdMeshersGUI_DistrTable::stopEditing( const bool accept )
70 {
71   endEdit( currEditRow(), currEditCol(), accept, false );
72 }
73
74 QWidget* StdMeshersGUI_DistrTable::beginEdit( int row, int col, bool replace )
75 {
76   QWidget* w = QTable::beginEdit( row, col, replace );
77   if( w && w->inherits( "QLineEdit" ) )
78     ( ( QLineEdit* )w )->selectAll();
79   return w;
80 }
81
82 void StdMeshersGUI_DistrTable::edit( const int r, const int c )
83 {
84   if( isEditing() )
85     endEdit( currEditRow(), currEditCol(), true, false );
86   clearSelection();
87   setCurrentCell( r, c );
88   if( beginEdit( r, c, false ) )
89     setEditMode( Editing, r, c );
90   QTableSelection sel;
91   sel.init( r, c );
92   sel.expandTo( r, c );
93   addSelection( sel );
94 }
95
96 bool StdMeshersGUI_DistrTable::eventFilter( QObject* o, QEvent* e )
97 {
98   if( e && e->type()==QEvent::KeyPress )
99   {
100     QKeyEvent* ke = ( QKeyEvent* )e;
101     int k = ke->key();
102     if( k==Qt::Key_Tab || k==Qt::Key_BackTab || k==Qt::Key_Return || k==Qt::Key_Up || k==Qt::Key_Down )
103     {
104       keyPressEvent( ke );
105       return true;
106     }
107   }
108   return QTable::eventFilter( o, e );
109 }
110
111 void StdMeshersGUI_DistrTable::keyPressEvent( QKeyEvent* e )
112 {
113   if( e )
114   {
115     int r = currentRow(), c = currentColumn(), nr, nc;
116     bool shift = e->state() & Qt::ShiftButton, cr = false;
117     switch( e->key() )
118     {
119     case Qt::Key_Tab:
120       nc = c+1;
121       nr = r;
122       break;
123
124     case Qt::Key_BackTab:
125       nc = c-1;
126       nr = r;
127       break;
128
129     case Qt::Key_Return:
130       nc = 0;
131       nr = shift ? r-1 : r+1;
132       cr = true;
133       break;
134
135     case Qt::Key_Up:
136       nc = c;
137       nr = r-1;
138       break;
139
140     case Qt::Key_Down:
141       nc = c;
142       nr = r+1;
143       break;
144
145     default:
146       QTable::keyPressEvent( e );
147       return;
148     }
149
150     if( nc<0 )
151     {
152       nc=1; nr--;
153     }
154     if( nc>1 )
155     {
156       nc=0; nr++;
157     }
158
159     if( nr>=numRows() && cr )
160     {
161       if( isEditing() )
162         endEdit( currEditRow(), currEditCol(), true, false );
163       onEdit( INSERT_ROW, nr );
164     }
165
166     else if( nr<0 || nr>=numRows() )
167     {
168       nr = r; nc = c;   
169     }
170     edit( nr, nc );
171     e->accept();
172   }
173 }
174
175 QWidget* StdMeshersGUI_DistrTable::createEditor( int r, int c, bool init ) const
176 {
177   QWidget* w = QTable::createEditor( r, c, init );
178   if( w )
179   {
180     //w->installEventFilter( this );
181     if( w->inherits( "QLineEdit" ) )
182     {
183       QLineEdit* le = ( QLineEdit* )w;
184       le->setValidator( c==0 ? myArgV : myFuncV );
185     }
186   }
187   
188   return w;
189 }
190
191 void StdMeshersGUI_DistrTable::onEdit( TableButton b, int cur )
192 {
193   switch( b )
194   {     
195   case INSERT_ROW:
196     setNumRows( numRows()+1 );
197     for( int i=numRows()-1; i>=cur; i-- )
198       for( int j=0; j<numCols(); j++ )
199         if( i>cur )
200           setText( i, j, text( i-1, j ) );
201         else
202           setText( i, j, "0" );
203     emit( valueChanged( cur, 0 ) );
204     break;
205       
206   case REMOVE_ROW:
207     if( numRows()>1 )
208     {
209       for( int i=cur; i<numRows(); i++ )
210         for( int j=0; j<numCols(); j++ )
211           setText( i, j, text( i+1, j ) );
212       setNumRows( numRows()-1 );
213     }
214     emit( valueChanged( cur, 0 ) );
215     break;
216   }
217 }
218
219 void StdMeshersGUI_DistrTable::sortData( SMESH::double_array& arr )
220 {
221   QValueList< QPair<double,double> > aData;
222   if( arr.length()%2==1 )
223     arr.length( arr.length()-1 );
224
225   int aLen = arr.length();
226   for( int i=0; i<aLen/2; i++ )
227     aData.append( QPair<double,double>( arr[2*i], arr[2*i+1] ) );
228
229   qHeapSort( aData );
230
231   QValueList< QPair<double,double> >::const_iterator anIt = aData.begin(), aLast = aData.end();
232   QValueList<double> unique_values;
233   double prev; int i=0;
234   if( (*anIt).first>0.0 )
235   {
236     unique_values.append( 0.0 );
237     unique_values.append( (*anIt).second );
238     i++; prev = 0.0;
239   }
240   for( ; anIt!=aLast; anIt++ )
241   {
242     if( i==0 || (*anIt).first>prev )
243     {
244       unique_values.append( (*anIt).first );
245       unique_values.append( (*anIt).second );
246       i++;
247     }
248     prev = (*anIt).first;
249   }
250   if( prev<1.0 )
251   {
252     unique_values.append( 1.0 );
253     anIt--;
254     unique_values.append( (*anIt).second );
255   }
256
257   arr.length( unique_values.count() );
258   QValueList<double>::const_iterator anIt1 = unique_values.begin(), aLast1 = unique_values.end();
259   for( int j=0; anIt1!=aLast1; anIt1++, j++ )
260     arr[j] = *anIt1;
261 }
262
263 void StdMeshersGUI_DistrTable::data( SMESH::double_array& v )
264 {
265   stopEditing( true );
266   v.length( 2*numRows() );
267   for( int i=0; i<numRows(); i++ )
268     for( int j=0; j<numCols(); j++ )
269       v[numCols()*i+j] = text( i, j ).toDouble();
270   sortData( v );
271 }
272
273 void StdMeshersGUI_DistrTable::setData( const SMESH::double_array& d )
274 {
275   stopEditing( false );
276   setNumRows( d.length()/2 );
277   QString val;
278   for( int i=0; i<d.length(); i++ )
279   {
280     QtxDblValidator* v = i%2==0 ? myArgV : myFuncV;
281     val = QString::number( d[i] );
282     v->fixup( val );
283     setText( i/2, i%2, val );
284   }
285 }
286
287 QtxDblValidator* StdMeshersGUI_DistrTable::argValidator() const
288 {
289   return myArgV;
290 }
291
292 QtxDblValidator* StdMeshersGUI_DistrTable::funcValidator() const
293 {
294   return myFuncV;
295 }
296
297 //=================================================================================
298 // class    : StdMeshersGUI_DistrTableFrame
299 // purpose  :
300 //=================================================================================
301 StdMeshersGUI_DistrTableFrame::StdMeshersGUI_DistrTableFrame( QWidget* parent )
302 : QFrame( parent )
303 {
304   QVBoxLayout* main = new QVBoxLayout( this, 0, 0 );
305
306   myTable = new StdMeshersGUI_DistrTable( 1, this );
307   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
308   connect( this, SIGNAL( toEdit( TableButton, int ) ), myTable, SLOT( onEdit( TableButton, int ) ) );
309   
310   QFrame* aButFrame = new QFrame( this );
311   QHBoxLayout* butLay = new QHBoxLayout( aButFrame, 5, 5 );
312
313   myInsertRow = new QPushButton( tr( "SMESH_INSERT_ROW" ), aButFrame );
314   myRemoveRow = new QPushButton( tr( "SMESH_REMOVE_ROW" ), aButFrame );
315
316   butLay->addWidget( myInsertRow, 0 );
317   butLay->addWidget( myRemoveRow, 0 );
318   butLay->addStretch( 1 );
319
320   main->addWidget( myTable, 1 );
321   main->addWidget( aButFrame, 0 );
322
323   connect( myInsertRow, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
324   connect( myRemoveRow, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
325 }
326
327 StdMeshersGUI_DistrTableFrame::~StdMeshersGUI_DistrTableFrame()
328 {
329 }
330
331 StdMeshersGUI_DistrTable* StdMeshersGUI_DistrTableFrame::table() const
332 {
333   return myTable;
334 }
335
336 void StdMeshersGUI_DistrTableFrame::setShown( const TableButton b, const bool sh )
337 {
338   if( button( b ) )
339     button( b )->setShown( sh );
340 }
341
342 bool StdMeshersGUI_DistrTableFrame::isShown( const TableButton b ) const
343 {
344   bool res = false;
345   if( button( b ) )
346     res = button( b )->isShown();
347   return res;
348 }
349
350 QButton* StdMeshersGUI_DistrTableFrame::button( const TableButton b ) const
351 {
352   QButton* res = 0;
353   switch( b )
354   {
355     case INSERT_ROW:
356       res = myInsertRow;
357       break;
358
359     case REMOVE_ROW:
360       res = myRemoveRow;
361       break;
362   }
363   return res;
364 }
365
366 void StdMeshersGUI_DistrTableFrame::onButtonClicked()
367 {
368   if( sender()==button( INSERT_ROW ) )
369     emit toEdit( INSERT_ROW, table()->currentRow() );
370     
371   else if( sender()==button( REMOVE_ROW ) )
372     emit toEdit( REMOVE_ROW, table()->currentRow() );
373 }
374