Salome HOME
db0b7f3ff3e5ed1bb9438639df808ba15a156f95
[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 <qlayout.h>
30 #include <qpushbutton.h>
31 #include <qvalidator.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 QDoubleValidator( 0.0, 1.0, 3, this );
44   myFuncV = new QDoubleValidator( 0.0, 1E10, 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 void StdMeshersGUI_DistrTable::edit( const int r, const int c )
74 {
75   if( isEditing() )
76     endEdit( currEditRow(), currEditCol(), true, false );
77   clearSelection();
78   setCurrentCell( r, c );
79   if( beginEdit( r, c, false ) )
80     setEditMode( Editing, r, c );
81   QTableSelection sel;
82   sel.init( r, c );
83   sel.expandTo( r, c );
84   addSelection( sel );
85 }
86
87 bool StdMeshersGUI_DistrTable::eventFilter( QObject* o, QEvent* e )
88 {
89   if( e && e->type()==QEvent::KeyPress )
90   {
91     QKeyEvent* ke = ( QKeyEvent* )e;
92     int k = ke->key();
93     if( k==Qt::Key_Tab || k==Qt::Key_BackTab || k==Qt::Key_Return || k==Qt::Key_Up || k==Qt::Key_Down )
94     {
95       keyPressEvent( ke );
96       return true;
97     }
98   }
99   return QTable::eventFilter( o, e );
100 }
101
102 void StdMeshersGUI_DistrTable::keyPressEvent( QKeyEvent* e )
103 {
104   if( e )
105   {
106     int r = currentRow(), c = currentColumn(), nr, nc;
107     bool shift = e->state() & Qt::ShiftButton, cr = false;
108     switch( e->key() )
109     {
110     case Qt::Key_Tab:
111       nc = c+1;
112       nr = r;
113       break;
114
115     case Qt::Key_BackTab:
116       nc = c-1;
117       nr = r;
118       break;
119
120     case Qt::Key_Return:
121       nc = 0;
122       nr = shift ? r-1 : r+1;
123       cr = true;
124       break;
125
126     case Qt::Key_Up:
127       nc = c;
128       nr = r-1;
129       break;
130
131     case Qt::Key_Down:
132       nc = c;
133       nr = r+1;
134       break;
135
136     default:
137       QTable::keyPressEvent( e );
138       return;
139     }
140
141     if( nc<0 )
142     {
143       nc=1; nr--;
144     }
145     if( nc>1 )
146     {
147       nc=0; nr++;
148     }
149
150     if( nr>=numRows() && cr )
151     {
152       if( isEditing() )
153         endEdit( currEditRow(), currEditCol(), true, false );
154       onEdit( INSERT_ROW, nr );
155     }
156
157     else if( nr<0 || nr>=numRows() )
158     {
159       nr = r; nc = c;   
160     }
161     edit( nr, nc );
162     e->accept();
163   }
164 }
165
166 QWidget* StdMeshersGUI_DistrTable::createEditor( int r, int c, bool init ) const
167 {
168   QWidget* w = QTable::createEditor( r, c, init );
169   if( w )
170   {
171     //w->installEventFilter( this );
172     if( w->inherits( "QLineEdit" ) )
173     {
174       QLineEdit* le = ( QLineEdit* )w;
175       le->setValidator( c==0 ? myArgV : myFuncV );
176     }
177   }
178   
179   return w;
180 }
181
182 void StdMeshersGUI_DistrTable::onEdit( TableButton b, int cur )
183 {
184   switch( b )
185   {     
186   case INSERT_ROW:
187     setNumRows( numRows()+1 );
188     for( int i=numRows()-1; i>=cur; i-- )
189       for( int j=0; j<numCols(); j++ )
190         if( i>cur )
191           setText( i, j, text( i-1, j ) );
192         else
193           setText( i, j, "0" );
194     emit( valueChanged( cur, 0 ) );
195     break;
196       
197   case REMOVE_ROW:
198     if( numRows()>1 )
199     {
200       for( int i=cur; i<numRows(); i++ )
201         for( int j=0; j<numCols(); j++ )
202           setText( i, j, text( i+1, j ) );
203       setNumRows( numRows()-1 );
204     }
205     emit( valueChanged( cur, 0 ) );
206     break;
207   }
208 }
209
210 void StdMeshersGUI_DistrTable::sortData( SMESH::double_array& arr )
211 {
212   QValueList< QPair<double,double> > aData;
213   if( arr.length()%2==1 )
214     arr.length( arr.length()-1 );
215
216   int aLen = arr.length();
217   for( int i=0; i<aLen/2; i++ )
218     aData.append( QPair<double,double>( arr[2*i], arr[2*i+1] ) );
219
220   qHeapSort( aData );
221
222   QValueList< QPair<double,double> >::const_iterator anIt = aData.begin(), aLast = aData.end();
223   QValueList<double> unique_values;
224   double prev; int i=0;
225   if( (*anIt).first>0.0 )
226   {
227     unique_values.append( 0.0 );
228     unique_values.append( (*anIt).second );
229     i++; prev = 0.0;
230   }
231   for( ; anIt!=aLast; anIt++ )
232   {
233     if( i==0 || (*anIt).first>prev )
234     {
235       unique_values.append( (*anIt).first );
236       unique_values.append( (*anIt).second );
237       i++;
238     }
239     prev = (*anIt).first;
240   }
241   if( prev<1.0 )
242   {
243     unique_values.append( 1.0 );
244     anIt--;
245     unique_values.append( (*anIt).second );
246   }
247
248   arr.length( unique_values.count() );
249   QValueList<double>::const_iterator anIt1 = unique_values.begin(), aLast1 = unique_values.end();
250   for( int j=0; anIt1!=aLast1; anIt1++, j++ )
251     arr[j] = *anIt1;
252 }
253
254 void StdMeshersGUI_DistrTable::data( SMESH::double_array& v )
255 {
256   stopEditing( true );
257   v.length( 2*numRows() );
258   for( int i=0; i<numRows(); i++ )
259     for( int j=0; j<numCols(); j++ )
260       v[numCols()*i+j] = text( i, j ).toDouble();
261   sortData( v );
262 }
263
264 void StdMeshersGUI_DistrTable::setData( const SMESH::double_array& d )
265 {
266   stopEditing( false );
267   setNumRows( d.length()/2 );
268   for( int i=0; i<d.length(); i++ )
269     setText( i/2, i%2, QString( "%1" ).arg( d[i] ) );
270 }
271
272 //=================================================================================
273 // class    : StdMeshersGUI_DistrTableFrame
274 // purpose  :
275 //=================================================================================
276 StdMeshersGUI_DistrTableFrame::StdMeshersGUI_DistrTableFrame( QWidget* parent )
277 : QFrame( parent )
278 {
279   QVBoxLayout* main = new QVBoxLayout( this, 0, 0 );
280
281   myTable = new StdMeshersGUI_DistrTable( 1, this );
282   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
283   connect( this, SIGNAL( toEdit( TableButton, int ) ), myTable, SLOT( onEdit( TableButton, int ) ) );
284   
285   QFrame* aButFrame = new QFrame( this );
286   QHBoxLayout* butLay = new QHBoxLayout( aButFrame, 5, 5 );
287
288   myInsertRow = new QPushButton( tr( "SMESH_INSERT_ROW" ), aButFrame );
289   myRemoveRow = new QPushButton( tr( "SMESH_REMOVE_ROW" ), aButFrame );
290
291   butLay->addWidget( myInsertRow, 0 );
292   butLay->addWidget( myRemoveRow, 0 );
293   butLay->addStretch( 1 );
294
295   main->addWidget( myTable, 1 );
296   main->addWidget( aButFrame, 0 );
297
298   connect( myInsertRow, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
299   connect( myRemoveRow, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
300 }
301
302 StdMeshersGUI_DistrTableFrame::~StdMeshersGUI_DistrTableFrame()
303 {
304 }
305
306 StdMeshersGUI_DistrTable* StdMeshersGUI_DistrTableFrame::table() const
307 {
308   return myTable;
309 }
310
311 void StdMeshersGUI_DistrTableFrame::setShown( const TableButton b, const bool sh )
312 {
313   if( button( b ) )
314     button( b )->setShown( sh );
315 }
316
317 bool StdMeshersGUI_DistrTableFrame::isShown( const TableButton b ) const
318 {
319   bool res = false;
320   if( button( b ) )
321     res = button( b )->isShown();
322   return res;
323 }
324
325 QButton* StdMeshersGUI_DistrTableFrame::button( const TableButton b ) const
326 {
327   QButton* res = 0;
328   switch( b )
329   {
330     case INSERT_ROW:
331       res = myInsertRow;
332       break;
333
334     case REMOVE_ROW:
335       res = myRemoveRow;
336       break;
337   }
338   return res;
339 }
340
341 void StdMeshersGUI_DistrTableFrame::onButtonClicked()
342 {
343   if( sender()==button( INSERT_ROW ) )
344     emit toEdit( INSERT_ROW, table()->currentRow() );
345     
346   else if( sender()==button( REMOVE_ROW ) )
347     emit toEdit( REMOVE_ROW, table()->currentRow() );
348 }