Salome HOME
To avoid memory leaks
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_FixedPointsParamWdg.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 // File   : StdMeshersGUI_FixedPointsParamWdg.cxx
23 // Author : Open CASCADE S.A.S.
24 // SMESH includes
25 //
26 #include "StdMeshersGUI_FixedPointsParamWdg.h"
27
28 // Qt includes
29 #include <QPushButton>
30 #include <QIntValidator>
31 #include <QGridLayout>
32 #include <QListWidget>
33 #include <QListWidgetItem>
34 #include <QItemDelegate>
35 #include <QTreeWidget>
36 #include <QTreeWidgetItem>
37 #include <QCheckBox>
38 #include <QLineEdit>
39 #include <QDoubleSpinBox>
40 #include <QItemDelegate>
41 #include <QKeyEvent>
42
43 #define SPACING 6
44 #define MARGIN 0
45 #define SAME_TEXT "-/-"
46
47 /*
48  * function : Tree Widget Item Delegate
49  * purpose  : Custom item delegate
50  */
51
52 class StdMeshersGUI_FixedPointsParamWdg::LineDelegate : public QItemDelegate
53 {
54 public:
55   LineDelegate( QTreeWidget* );
56   ~LineDelegate() {}
57
58   QWidget*     createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
59   void         setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
60
61 private:
62   QTreeWidget* myTreeWidget;
63 };
64
65 StdMeshersGUI_FixedPointsParamWdg::LineDelegate::LineDelegate( QTreeWidget* parent )
66   : QItemDelegate( parent ),
67     myTreeWidget( parent )
68 {
69 }
70
71 QWidget* StdMeshersGUI_FixedPointsParamWdg::LineDelegate::createEditor( QWidget* parent,
72                                                                         const QStyleOptionViewItem& option,
73                                                                         const QModelIndex& index ) const
74 {
75   QWidget* w = 0;
76   if ( (index.column() == 1 ) ) {
77     QSpinBox* sb = new QSpinBox( parent );
78     sb->setFrame( false );
79     sb->setRange( 1, 999);
80     w = sb;
81   }
82
83   return w;
84 }
85
86 void StdMeshersGUI_FixedPointsParamWdg::LineDelegate::setModelData( QWidget* editor, 
87                                                                     QAbstractItemModel* model, 
88                                                                     const QModelIndex& index ) const
89 {
90   model->setData( index, qobject_cast<QSpinBox*>( editor )->value(), Qt::EditRole );
91   model->setData( index, qobject_cast<QSpinBox*>( editor )->value(), Qt::UserRole );
92 }
93
94 //================================================================================
95 /*!
96  *  Constructor
97  */
98 //================================================================================
99
100 StdMeshersGUI_FixedPointsParamWdg
101 ::StdMeshersGUI_FixedPointsParamWdg( QWidget * parent ): 
102   QWidget( parent )
103 {
104   QGridLayout* edgesLayout = new QGridLayout( this );
105   edgesLayout->setMargin( MARGIN );
106   edgesLayout->setSpacing( SPACING );
107   
108   myListWidget   = new QListWidget( this );
109   myTreeWidget   = new QTreeWidget( this );
110   mySpinBox      = new QDoubleSpinBox( this );
111   myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
112   myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
113   mySameValues   = new QCheckBox( tr("SMESH_SAME_NB_SEGMENTS"), this);
114
115   myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
116
117   myTreeWidget->setColumnCount(2);
118   myTreeWidget->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << tr( "SMESH_NB_SEGMENTS" ) );
119   myTreeWidget->setColumnWidth( 1, 40 );
120   myTreeWidget->setColumnWidth( 2, 30 );
121   myTreeWidget->setItemDelegate( new LineDelegate( myTreeWidget ) );
122
123   edgesLayout->addWidget(myListWidget,   0, 0, 4, 1);
124   edgesLayout->addWidget(mySpinBox,      0, 1);
125   edgesLayout->addWidget(myAddButton,    1, 1);
126   edgesLayout->addWidget(myRemoveButton, 2, 1);
127   edgesLayout->addWidget(myTreeWidget,   0, 2, 4, 1);
128   edgesLayout->addWidget(mySameValues,   4, 0, 1, 3);
129   edgesLayout->setRowStretch( 3, 5 );
130   edgesLayout->setColumnStretch(0, 1);
131   edgesLayout->setColumnStretch(1, 0);
132   edgesLayout->setColumnStretch(2, 2);
133
134   myListWidget->setMinimumWidth( 80 );
135   myTreeWidget->setMinimumWidth( 200 );
136
137   mySpinBox->setRange( 0, 1 );
138   mySpinBox->setSingleStep( 0.1 );
139
140   connect( myAddButton,    SIGNAL(clicked()), SLOT(onAdd()));
141   connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove()));
142   connect( mySameValues,   SIGNAL(stateChanged(int)), SLOT(onCheckBoxChanged()));
143   myListWidget->installEventFilter( this );
144
145   clear();
146 }
147
148 //================================================================================
149 /*!
150  *  Destructor
151  */
152 //================================================================================
153
154 StdMeshersGUI_FixedPointsParamWdg::~StdMeshersGUI_FixedPointsParamWdg()
155 {
156 }
157
158 //================================================================================
159 /*!
160  *  Event filter
161  */
162 //================================================================================
163 bool StdMeshersGUI_FixedPointsParamWdg::eventFilter( QObject* o, QEvent* e )
164 {
165   if ( o == myListWidget && e->type() == QEvent::KeyPress ) {
166     QKeyEvent* ke = (QKeyEvent*)e;
167     if ( ke->key() == Qt::Key_Delete )
168       removePoints();
169   }
170   return QWidget::eventFilter( o, e );
171 }
172
173 //================================================================================
174 /*!
175  *  Clear widget
176  */
177 //================================================================================
178 void StdMeshersGUI_FixedPointsParamWdg::clear()
179 {
180   myTreeWidget->clear();
181   myListWidget->clear();
182   myTreeWidget->addTopLevelItem( newTreeItem( 0, 1 ) );
183   mySpinBox->setValue( 0. );
184   onCheckBoxChanged();
185 }
186
187 //=================================================================================
188 // function : onAdd()
189 // purpose  : Called when Add Button Clicked
190 //=================================================================================
191 void StdMeshersGUI_FixedPointsParamWdg::onAdd()
192 {
193   addPoint( mySpinBox->value() );
194 }
195          
196 //=================================================================================
197 // function : onRemove()
198 // purpose  : Called when Remove Button Clicked
199 //=================================================================================
200 void StdMeshersGUI_FixedPointsParamWdg::onRemove()
201 {
202   removePoints();
203 }
204
205 //=================================================================================
206 // function : newTreeItem()
207 // purpose  : Called to create TreeItem
208 //=================================================================================
209
210 QTreeWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newTreeItem( double v1, double v2 )
211 {
212   QTreeWidgetItem* anItem = new QTreeWidgetItem();
213   anItem->setText( 0, treeItemText( v1, v2 ) );
214   anItem->setText( 1, QString::number( 1 ) );
215   anItem->setData( 1, Qt::UserRole, 1 );
216   return anItem;
217 }
218
219 //=================================================================================
220 // function : newListItem()
221 // purpose  : Called to create ListItem
222 //=================================================================================
223
224 QListWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newListItem( double v )
225 {
226   QListWidgetItem* anItem = new QListWidgetItem( QString::number( v ) );
227   anItem->setData( Qt::UserRole, v );
228   return anItem;
229 }
230
231 //=================================================================================
232 // function : itemText()
233 // purpose  : Called to convert Values to Text
234 //=================================================================================
235
236 QString StdMeshersGUI_FixedPointsParamWdg::treeItemText( double v1, double v2 )
237 {
238   return QString( "%1 - %2" ).arg( v1 ).arg( v2 );
239 }
240
241 //=================================================================================
242 // function : addPoint()
243 // purpose  : Called to Add new Point
244 //=================================================================================
245 void StdMeshersGUI_FixedPointsParamWdg::addPoint( double v)
246 {
247   if ( v > 0 && v < 1) {
248     bool toInsert = true;
249     int idx = myTreeWidget->topLevelItemCount()-1;
250     for ( int i = 0 ; i < myListWidget->count(); i++ ) {
251       double lv = point( i );
252       if ( lv == v ) { toInsert = false; break; }
253       else if ( lv > v ) {
254         idx = i; break;
255       }
256     }
257     if ( toInsert ) {
258       double v1 = idx == 0 ? 0 : point( idx-1 );
259       double v2 = idx == myTreeWidget->topLevelItemCount()-1 ? 1 : point( idx );
260       myTreeWidget->insertTopLevelItem( idx, newTreeItem( v1, v ) );
261       myTreeWidget->topLevelItem( idx+1 )->setText( 0, treeItemText( v, v2 ) );
262       myListWidget->insertItem( idx, newListItem( v ) );
263       onCheckBoxChanged();
264     }
265   }
266 }
267
268 //=================================================================================
269 // function : removePoints()
270 // purpose  : Called to remove selected points
271 //=================================================================================
272 void StdMeshersGUI_FixedPointsParamWdg::removePoints()
273 {
274   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
275   QListWidgetItem* item;
276   foreach ( item, selItems ) {
277     int idx = myListWidget->row( item );
278     delete myTreeWidget->topLevelItem( idx );
279     delete item;
280     myTreeWidget->topLevelItem( idx )->setText( 0, treeItemText( idx == 0 ? 0 : point( idx-1 ),
281                                                                  idx > myListWidget->count()-1 ? 1 : point( idx ) ) );
282   }
283   onCheckBoxChanged();
284 }
285
286 double StdMeshersGUI_FixedPointsParamWdg::point( int idx ) const
287 {
288   return idx >= 0 && idx < myListWidget->count() ? myListWidget->item( idx )->data( Qt::UserRole ).toDouble() : 0.;
289 }
290
291 void StdMeshersGUI_FixedPointsParamWdg::setNbSegments( int idx, int val )
292 {
293   if ( idx >= 0 && idx < myTreeWidget->topLevelItemCount() ) {
294     myTreeWidget->topLevelItem( idx )->setData( 1, Qt::UserRole, val );
295     myTreeWidget->topLevelItem( idx )->setText( 1, idx > 0 && mySameValues->isChecked() ? QString( SAME_TEXT ) : QString::number( val ) );
296   }
297 }
298
299 int StdMeshersGUI_FixedPointsParamWdg::nbSegments( int idx ) const
300 {
301   return idx >= 0 && idx < myTreeWidget->topLevelItemCount() ? myTreeWidget->topLevelItem( idx )->data( 1, Qt::UserRole ).toInt() : 1;
302 }
303
304 //=================================================================================
305 // function : onCheckBoxChanged()
306 // purpose  : Called when Check Box Clicked
307 //=================================================================================
308 void StdMeshersGUI_FixedPointsParamWdg::onCheckBoxChanged()
309 {
310   for ( int i = 0; i < myTreeWidget->topLevelItemCount(); i++ ) {
311     QTreeWidgetItem* anItem = myTreeWidget->topLevelItem(i);
312     setNbSegments( i, nbSegments( i ) );
313     anItem->setFlags( mySameValues->isChecked() && i > 0 ? anItem->flags() & ~Qt::ItemIsEditable : anItem->flags() | Qt::ItemIsEditable );
314   }
315 }
316
317 //=================================================================================
318 // function : GetListOfPoints
319 // purpose  : Called to get the list of Edges IDs
320 //=================================================================================
321 SMESH::double_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfPoints()
322 {
323   SMESH::double_array_var anArray = new SMESH::double_array;
324   int size = myListWidget->count();
325   anArray->length( size );
326   for (int i = 0; i < size; i++) {
327     anArray[i] = point(i);
328     //    printf ("Point %f \n", anArray[i]);
329   }
330   return anArray;
331 }
332
333 //=================================================================================
334 // function : SetListOfPoints
335 // purpose  : Called to set the list of Points
336 //=================================================================================
337 void StdMeshersGUI_FixedPointsParamWdg::SetListOfPoints( SMESH::double_array_var thePoints)
338 {
339   clear();
340   for ( int i = 0; i < thePoints->length(); i++ ) {
341     addPoint( thePoints[ i ] );
342     //    printf ("Add Point %f \n", thePoints[ i ]);
343   }
344 }
345
346 //=================================================================================
347 // function : GetListOfSegments
348 // purpose  : Called to get the list Number of Segments
349 //=================================================================================
350 SMESH::long_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfSegments()
351 {
352   SMESH::long_array_var anArray = new SMESH::long_array;
353   int size = mySameValues->isChecked() ? 1 : myTreeWidget->topLevelItemCount();
354   anArray->length( size );
355   for (int i = 0; i < size; i++) {
356     anArray[i] = nbSegments( i );
357     //    printf ("Segments %d \n", anArray[i] );
358   }
359   return anArray;
360 }
361
362 //=================================================================================
363 // function : SetListOfPoints
364 // purpose  : Called to set the list of Points
365 //=================================================================================
366 void StdMeshersGUI_FixedPointsParamWdg::SetListOfSegments( SMESH::long_array_var theSegments)
367 {
368   if ( myListWidget->count() > 0 && theSegments->length() == 1)
369     mySameValues->setChecked(true);
370   for ( int i = 0; i < theSegments->length(); i++ ) {
371     setNbSegments( i, theSegments[i] );
372     //    printf ("\nadd Segment = %d\n", theSegments[i]);
373   }
374 }