Salome HOME
#24666 [CEA][Windows] BLSURPLUGIN compilation issue
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_FixedPointsParamWdg.cxx
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File   : StdMeshersGUI_FixedPointsParamWdg.cxx
21 // Author : Open CASCADE S.A.S.
22 // SMESH includes
23 //
24 #include "StdMeshersGUI_FixedPointsParamWdg.h"
25
26 #include <SMESHGUI_SpinBox.h>
27
28 #include <SalomeApp_IntSpinBox.h>
29
30 // Qt includes
31 #include <QPushButton>
32 #include <QIntValidator>
33 #include <QGridLayout>
34 #include <QListWidget>
35 #include <QListWidgetItem>
36 #include <QItemDelegate>
37 #include <QTreeWidget>
38 #include <QTreeWidgetItem>
39 #include <QCheckBox>
40 #include <QLineEdit>
41 #include <QItemDelegate>
42 #include <QKeyEvent>
43
44 #define SPACING 6
45 #define MARGIN 0
46 #define SAME_TEXT "-/-"
47
48 #define TOLERANCE 1e-7
49 #define EQUAL_DBL(a,b) (fabs(a-b)<TOLERANCE)
50 #define LT_DBL(a,b) ((a<b)&&!EQUAL_DBL(a,b))
51 #define GT_DBL(a,b) ((a>b)&&!EQUAL_DBL(a,b))
52
53 /*
54  * class : Tree Widget Item Delegate
55  * purpose  : Custom item delegate
56  */
57
58 class StdMeshersGUI_FixedPointsParamWdg::LineDelegate : public QItemDelegate
59 {
60 public:
61   LineDelegate( QTreeWidget* );
62   ~LineDelegate() {}
63
64   QWidget*     createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
65   void         setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
66
67 private:
68   QTreeWidget* myTreeWidget;
69 };
70
71 StdMeshersGUI_FixedPointsParamWdg::LineDelegate::LineDelegate( QTreeWidget* parent )
72   : QItemDelegate( parent ),
73     myTreeWidget( parent )
74 {
75 }
76
77 QWidget* StdMeshersGUI_FixedPointsParamWdg::LineDelegate::createEditor( QWidget* parent,
78                                                                         const QStyleOptionViewItem& /*option*/,
79                                                                         const QModelIndex& index ) const
80 {
81   QWidget* w = 0;
82   if ( (index.column() == 1 ) ) {
83     SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( parent );
84     sb->setAcceptNames( false ); // No Notebook variables allowed
85     sb->setFrame( false );
86     sb->setRange( 1, 999);
87     w = sb;
88   }
89
90   return w;
91 }
92
93 void StdMeshersGUI_FixedPointsParamWdg::LineDelegate::setModelData( QWidget* editor, 
94                                                                     QAbstractItemModel* model, 
95                                                                     const QModelIndex& index ) const
96 {
97   model->setData( index, qobject_cast<SalomeApp_IntSpinBox*>( editor )->value(), Qt::EditRole );
98   model->setData( index, qobject_cast<SalomeApp_IntSpinBox*>( editor )->value(), Qt::UserRole );
99 }
100
101 //================================================================================
102 /*!
103  *  Constructor
104  */
105 //================================================================================
106
107 StdMeshersGUI_FixedPointsParamWdg
108 ::StdMeshersGUI_FixedPointsParamWdg( QWidget * parent ): 
109   QWidget( parent )
110 {
111   QGridLayout* edgesLayout = new QGridLayout( this );
112   edgesLayout->setMargin( MARGIN );
113   edgesLayout->setSpacing( SPACING );
114   
115   myListWidget   = new QListWidget( this );
116   myTreeWidget   = new QTreeWidget( this );
117   mySpinBox      = new SMESHGUI_SpinBox( this );
118   myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
119   myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
120   mySameValues   = new QCheckBox( tr("SMESH_SAME_NB_SEGMENTS"), this);
121
122   myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
123
124   myTreeWidget->setColumnCount(2);
125   myTreeWidget->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << tr( "SMESH_NB_SEGMENTS" ) );
126   myTreeWidget->setColumnWidth( 1, 40 );
127   myTreeWidget->setColumnWidth( 2, 30 );
128   myTreeWidget->setItemDelegate( new LineDelegate( myTreeWidget ) );
129
130   edgesLayout->addWidget(myListWidget,   0, 0, 4, 1);
131   edgesLayout->addWidget(mySpinBox,      0, 1);
132   edgesLayout->addWidget(myAddButton,    1, 1);
133   edgesLayout->addWidget(myRemoveButton, 2, 1);
134   edgesLayout->addWidget(myTreeWidget,   0, 2, 4, 1);
135   edgesLayout->addWidget(mySameValues,   4, 0, 1, 3);
136   edgesLayout->setRowStretch( 3, 5 );
137   edgesLayout->setColumnStretch(0, 1);
138   edgesLayout->setColumnStretch(1, 0);
139   edgesLayout->setColumnStretch(2, 2);
140
141   myListWidget->setMinimumWidth( 80 );
142   myTreeWidget->setMinimumWidth( 200 );
143
144   mySpinBox->setAcceptNames( false ); // No Notebook variables allowed
145   mySpinBox->RangeStepAndValidator( 0., 1., .1, "parametric_precision" );
146   myListWidget->setMinimumWidth( 70 );
147
148   connect( myAddButton,    SIGNAL( clicked() ),              SLOT( onAdd() ) );
149   connect( myRemoveButton, SIGNAL( clicked() ),              SLOT( onRemove() ) );
150   connect( mySameValues,   SIGNAL( stateChanged( int ) ),    SLOT( onCheckBoxChanged() ) );
151   connect( mySpinBox,      SIGNAL( valueChanged( double ) ), SLOT( updateState() ) );
152   connect( myListWidget,   SIGNAL( itemSelectionChanged() ), SLOT( updateState() ) );
153   myListWidget->installEventFilter( this );
154
155   clear();
156 }
157
158 //================================================================================
159 /*!
160  *  Destructor
161  */
162 //================================================================================
163
164 StdMeshersGUI_FixedPointsParamWdg::~StdMeshersGUI_FixedPointsParamWdg()
165 {
166 }
167
168 //================================================================================
169 /*!
170  *  Event filter
171  */
172 //================================================================================
173 bool StdMeshersGUI_FixedPointsParamWdg::eventFilter( QObject* o, QEvent* e )
174 {
175   if ( o == myListWidget && e->type() == QEvent::KeyPress ) {
176     QKeyEvent* ke = (QKeyEvent*)e;
177     if ( ke->key() == Qt::Key_Delete )
178       removePoints();
179   }
180   return QWidget::eventFilter( o, e );
181 }
182
183 //================================================================================
184 /*!
185  *  Clear widget
186  */
187 //================================================================================
188 void StdMeshersGUI_FixedPointsParamWdg::clear()
189 {
190   myTreeWidget->clear();
191   myListWidget->clear();
192   myTreeWidget->addTopLevelItem( newTreeItem( 0, 1 ) );
193   mySpinBox->setValue( 0. );
194   onCheckBoxChanged();
195   updateState();
196 }
197
198 //=================================================================================
199 // function : onAdd()
200 // purpose  : Called when Add Button Clicked
201 //=================================================================================
202 void StdMeshersGUI_FixedPointsParamWdg::onAdd()
203 {
204   addPoint( mySpinBox->value() );
205 }
206          
207 //=================================================================================
208 // function : onRemove()
209 // purpose  : Called when Remove Button Clicked
210 //=================================================================================
211 void StdMeshersGUI_FixedPointsParamWdg::onRemove()
212 {
213   removePoints();
214 }
215
216 //=================================================================================
217 // function : newTreeItem()
218 // purpose  : Called to create TreeItem
219 //=================================================================================
220
221 QTreeWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newTreeItem( double v1, double v2 )
222 {
223   QTreeWidgetItem* anItem = new QTreeWidgetItem();
224   anItem->setText( 0, treeItemText( v1, v2 ) );
225   anItem->setText( 1, QString::number( 1 ) );
226   anItem->setData( 1, Qt::UserRole, 1 );
227   return anItem;
228 }
229
230 //=================================================================================
231 // function : newListItem()
232 // purpose  : Called to create ListItem
233 //=================================================================================
234
235 QListWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newListItem( double v )
236 {
237   QListWidgetItem* anItem = new QListWidgetItem( QString::number( v ) );
238   anItem->setData( Qt::UserRole, v );
239   return anItem;
240 }
241
242 //=================================================================================
243 // function : itemText()
244 // purpose  : Called to convert Values to Text
245 //=================================================================================
246
247 QString StdMeshersGUI_FixedPointsParamWdg::treeItemText( double v1, double v2 )
248 {
249   return QString( "%1 - %2" ).arg( v1 ).arg( v2 );
250 }
251
252 //=================================================================================
253 // function : addPoint()
254 // purpose  : Called to Add new Point
255 //=================================================================================
256 void StdMeshersGUI_FixedPointsParamWdg::addPoint( double v)
257 {
258   if ( GT_DBL(v, 0.0) && LT_DBL(v, 1.0)) {
259     bool toInsert = true;
260     int idx = myTreeWidget->topLevelItemCount()-1;
261     for ( int i = 0 ; i < myListWidget->count(); i++ ) {
262       double lv = point( i );
263       if ( EQUAL_DBL(lv, v) ) { toInsert = false; break; }
264       else if ( GT_DBL(lv, v) ) {
265         idx = i; break;
266       }
267     }
268     if ( toInsert ) {
269       double v1 = idx == 0 ? 0 : point( idx-1 );
270       double v2 = idx == myTreeWidget->topLevelItemCount()-1 ? 1 : point( idx );
271       myTreeWidget->insertTopLevelItem( idx, newTreeItem( v1, v ) );
272       myTreeWidget->topLevelItem( idx+1 )->setText( 0, treeItemText( v, v2 ) );
273       myListWidget->insertItem( idx, newListItem( v ) );
274       onCheckBoxChanged();
275     }
276   }
277   updateState();
278 }
279
280 //=================================================================================
281 // function : removePoints()
282 // purpose  : Called to remove selected points
283 //=================================================================================
284 void StdMeshersGUI_FixedPointsParamWdg::removePoints()
285 {
286   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
287   QListWidgetItem* item;
288   foreach ( item, selItems ) {
289     int idx = myListWidget->row( item );
290     delete myTreeWidget->topLevelItem( idx );
291     delete item;
292     myTreeWidget->topLevelItem( idx )->setText( 0, treeItemText( idx == 0 ? 0 : point( idx-1 ),
293                                                                  idx > myListWidget->count()-1 ? 1 : point( idx ) ) );
294   }
295   onCheckBoxChanged();
296   updateState();
297 }
298
299 double StdMeshersGUI_FixedPointsParamWdg::point( int idx ) const
300 {
301   return idx >= 0 && idx < myListWidget->count() ? myListWidget->item( idx )->data( Qt::UserRole ).toDouble() : 0.;
302 }
303
304 void StdMeshersGUI_FixedPointsParamWdg::setNbSegments( int idx, SMESH::smIdType val )
305 {
306   if ( idx >= 0 && idx < myTreeWidget->topLevelItemCount() )
307   {
308     myTreeWidget->topLevelItem( idx )->setData( 1, Qt::UserRole, qlonglong( val ));
309     myTreeWidget->topLevelItem( idx )->setText( 1, idx > 0 && mySameValues->isChecked() ? QString( SAME_TEXT ) : QString::number( val ) );
310   }
311 }
312
313 smIdType StdMeshersGUI_FixedPointsParamWdg::nbSegments( int idx ) const
314 {
315   return idx >= 0 && idx < myTreeWidget->topLevelItemCount() ? myTreeWidget->topLevelItem( idx )->data( 1, Qt::UserRole ).toLongLong() : 1;
316 }
317
318 //=================================================================================
319 // function : onCheckBoxChanged()
320 // purpose  : Called when Check Box Clicked
321 //=================================================================================
322 void StdMeshersGUI_FixedPointsParamWdg::onCheckBoxChanged()
323 {
324   for ( int i = 0; i < myTreeWidget->topLevelItemCount(); i++ ) {
325     QTreeWidgetItem* anItem = myTreeWidget->topLevelItem(i);
326     setNbSegments( i, nbSegments( i ) );
327     anItem->setFlags( mySameValues->isChecked() && i > 0 ? anItem->flags() & ~Qt::ItemIsEditable : anItem->flags() | Qt::ItemIsEditable );
328   }
329 }
330
331 //=================================================================================
332 // function : updateState()
333 // purpose  : Update widgets state
334 //=================================================================================
335 void StdMeshersGUI_FixedPointsParamWdg::updateState()
336 {
337   double v = mySpinBox->value();
338   myAddButton->setEnabled( GT_DBL(v, 0.0) && LT_DBL(v, 1.0) );
339   myRemoveButton->setEnabled( myListWidget->selectedItems().count() > 0 );
340 }
341
342 //=================================================================================
343 // function : GetListOfPoints
344 // purpose  : Called to get the list of Edges IDs
345 //=================================================================================
346 SMESH::double_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfPoints()
347 {
348   SMESH::double_array_var anArray = new SMESH::double_array;
349   int size = myListWidget->count();
350   anArray->length( size );
351   for (int i = 0; i < size; i++) {
352     anArray[i] = point(i);
353   }
354   return anArray;
355 }
356
357 //=================================================================================
358 // function : SetListOfPoints
359 // purpose  : Called to set the list of Points
360 //=================================================================================
361 void StdMeshersGUI_FixedPointsParamWdg::SetListOfPoints( SMESH::double_array_var thePoints)
362 {
363   clear();
364   for ( CORBA::ULong i = 0; i < thePoints->length(); i++ ) {
365     addPoint( thePoints[ i ] );
366   }
367 }
368
369 //=================================================================================
370 // function : GetListOfSegments
371 // purpose  : Called to get the list Number of Segments
372 //=================================================================================
373 SMESH::smIdType_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfSegments()
374 {
375   SMESH::smIdType_array_var anArray = new SMESH::smIdType_array;
376   int size = mySameValues->isChecked() ? 1 : myTreeWidget->topLevelItemCount();
377   anArray->length( size );
378   for (int i = 0; i < size; i++) {
379     anArray[i] = nbSegments( i );
380   }
381   return anArray;
382 }
383
384 //=================================================================================
385 // function : SetListOfPoints
386 // purpose  : Called to set the list of Points
387 //=================================================================================
388 void StdMeshersGUI_FixedPointsParamWdg::SetListOfSegments( SMESH::smIdType_array_var theSegments)
389 {
390   if ( myListWidget->count() > 0 && theSegments->length() == 1)
391     mySameValues->setChecked(true);
392   for ( CORBA::ULong i = 0; i < theSegments->length(); i++ ) {
393     setNbSegments( i, theSegments[i] );
394   }
395 }