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