Salome HOME
52566]: TC7.5.0: Empty group of Balls at Diameter Equal to filter
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_QuadrangleParamWdg.cxx
1 // Copyright (C) 2007-2014  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 //  File   : StdMeshersGUI_QuadrangleParamWdg.cxx
20 //  Author : Open CASCADE S.A.S. (jfa)
21 //  SMESH includes
22
23 #include "StdMeshersGUI_QuadrangleParamWdg.h"
24
25 #include "SMESHGUI.h"
26 #include "SMESHGUI_SpinBox.h"
27 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
28
29 #include <GEOMBase.h>
30 #include <LightApp_SelectionMgr.h>
31 #include <SALOME_ListIO.hxx>
32 #include <SUIT_ResourceMgr.h>
33
34 // Qt includes
35 #include <QButtonGroup>
36 #include <QFrame>
37 #include <QGridLayout>
38 #include <QGroupBox>
39 #include <QLabel>
40 #include <QLineEdit>
41 #include <QListWidget>
42 #include <QListWidgetItem>
43 #include <QPushButton>
44 #include <QRadioButton>
45 #include <QTreeWidget>
46 #include <QVBoxLayout>
47
48 // IDL includes
49 #include <SALOMEconfig.h>
50 #include CORBA_CLIENT_HEADER(SMESH_BasicHypothesis)
51 #include CORBA_CLIENT_HEADER(GEOM_Gen)
52
53
54 #define SPACING 6
55 #define MARGIN 11
56
57 enum { TAB_TRANSITION, TAB_VERTEX, TAB_ENF_POINTS };
58
59 //================================================================================
60 // function : Constructor
61 // purpose  :
62 //================================================================================
63
64 StdMeshersGUI_QuadrangleParamCreator::StdMeshersGUI_QuadrangleParamCreator(const QString& aHypType)
65   : StdMeshersGUI_StdHypothesisCreator( aHypType )
66 {
67 }
68
69 //=======================================================================
70 //function : helpPage
71 //purpose  : 
72 //=======================================================================
73
74 QString  StdMeshersGUI_QuadrangleParamCreator::helpPage() const
75 {
76   return "a2d_meshing_hypo_page.html#hypo_quad_params_anchor";
77 }
78
79 //=======================================================================
80 //function : buildFrame
81 //purpose  :
82 //=======================================================================
83
84 QFrame*  StdMeshersGUI_QuadrangleParamCreator::buildFrame()
85 {
86   QFrame* fr = new QFrame();
87
88   QGridLayout* lay = new QGridLayout( fr );
89   lay->setMargin( MARGIN );
90   lay->setSpacing( SPACING );
91   int row = 0;
92
93   myName = 0;
94   if ( isCreation() )
95   {
96     myName = new QLineEdit( fr );
97     QLabel* nameLab = new QLabel( tr("SMESH_NAME"));
98     lay->addWidget( nameLab, row, 0 );
99     lay->addWidget( myName,  row, 1 );
100     ++row;
101   }
102
103   // Transition type
104
105   myTypeWdg = new StdMeshersGUI_QuadrangleParamWdg( fr );
106
107   // Vertexes
108
109   myVertexSelWdg = new StdMeshersGUI_SubShapeSelectorWdg( fr, TopAbs_VERTEX );
110   myVertexSelWdg->layout()->setMargin( MARGIN );
111
112   // Enforced Points
113
114   QWidget* pointsFrame = new QWidget( fr );
115   QVBoxLayout* pointsLay = new QVBoxLayout( pointsFrame );
116   pointsLay->setMargin(MARGIN);
117   pointsLay->setSpacing(SPACING);
118
119   // shapes
120   QGroupBox* shapesGroup = new QGroupBox( tr("SHAPES"), pointsFrame );
121   myShapesList = new QListWidget( shapesGroup );
122   myAddShapeBut = new QPushButton( tr("SMESH_BUT_ADD"), shapesGroup );
123   QPushButton* remShapeBut = new QPushButton( tr("SMESH_BUT_REMOVE"), shapesGroup );
124   //
125   QGridLayout* shapesLay = new QGridLayout( shapesGroup );
126   shapesLay->setMargin(MARGIN);
127   shapesLay->setSpacing(SPACING);
128   shapesLay->addWidget( myShapesList,  0, 0, 3, 2 );
129   shapesLay->addWidget( myAddShapeBut, 0, 2 );
130   shapesLay->addWidget( remShapeBut,   1, 2 );
131   shapesLay->setColumnStretch( 0, 1 );
132   shapesLay->setRowStretch   ( 2, 1 );
133
134   // coords
135   QGroupBox* coordsGroup = new QGroupBox( tr("POINTS"), pointsFrame );
136   myCoordsTreeWdg = new QTreeWidget( coordsGroup );
137   myCoordsTreeWdg->setColumnCount ( 3 );
138   myCoordsTreeWdg->setHeaderLabels( QStringList() << "X" << "Y" << "Z" );
139   myCoordsTreeWdg->setItemDelegate( new ItemDelegate( myCoordsTreeWdg ));
140   QPushButton* addCoordBut = new QPushButton( tr("SMESH_BUT_ADD"), coordsGroup );
141   QPushButton* remCoordBut = new QPushButton( tr("SMESH_BUT_REMOVE"), coordsGroup );
142   //
143   QGridLayout* coordsLay = new QGridLayout( coordsGroup );
144   coordsLay->setMargin(MARGIN);
145   coordsLay->setSpacing(SPACING);
146   coordsLay->addWidget( myCoordsTreeWdg, 0, 0, 3, 2 );
147   coordsLay->addWidget( addCoordBut,     0, 2 );
148   coordsLay->addWidget( remCoordBut,     1, 2 );
149   coordsLay->setColumnStretch( 0, 1 );
150   coordsLay->setRowStretch   ( 2, 1 );
151
152   pointsLay->addWidget( shapesGroup );
153   pointsLay->addWidget( coordsGroup );
154
155   // Tabs
156   myTabs = new QTabWidget( fr );
157   myTabs->addTab( myTypeWdg,      tr("TRANSITION"));
158   myTabs->addTab( myVertexSelWdg, tr("SMESH_BASE_VERTEX"));
159   myTabs->addTab( pointsFrame,    tr("ENF_NODES"));
160
161   lay->addWidget( myTabs, row, 0, 2, 3 );
162
163   // signals
164   connect( myTypeWdg,     SIGNAL( typeChanged(int)),   SLOT( onTypeChanged(int)));
165   connect( myAddShapeBut, SIGNAL( clicked()),          SLOT( onAddShape() ));
166   connect( remShapeBut,   SIGNAL( clicked()),          SLOT( onRemoveShape() ));
167   connect( addCoordBut,   SIGNAL( clicked()),          SLOT( onAddPoint() ));
168   connect( remCoordBut,   SIGNAL( clicked()),          SLOT( onRemovePoint() ));
169   connect( myTabs,        SIGNAL( currentChanged(int)),SLOT( onTabChanged(int)));
170
171   LightApp_SelectionMgr* selMgr = SMESHGUI::GetSMESHGUI()->selectionMgr();
172   connect( selMgr, SIGNAL(currentSelectionChanged()), SLOT( onSelectionChanged()));
173
174   return fr;
175 }
176
177 //=======================================================================
178 //function : retrieveParams
179 //purpose  :
180 //=======================================================================
181
182 void StdMeshersGUI_QuadrangleParamCreator::retrieveParams() const
183 {
184   StdMeshers::StdMeshers_QuadrangleParams_var h =
185     StdMeshers::StdMeshers_QuadrangleParams::_narrow( initParamsHypothesis() );
186
187   // name
188   if( myName )
189     myName->setText( hypName() );
190
191   // main shape
192   myVertexSelWdg->SetMaxSize(1);
193   QString anEntry    = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
194   QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
195   if ( anEntry.isEmpty() )
196     anEntry = h->GetObjectEntry();
197   myVertexSelWdg->SetGeomShapeEntry(anEntry);
198   myVertexSelWdg->SetMainShapeEntry(aMainEntry);
199
200   if ( !isCreation())
201   {
202     // type
203     myTypeWdg->SetType(int(h->GetQuadType()));
204
205     // vertex
206     int vertID = h->GetTriaVertex();
207     if (vertID > 0) {
208       SMESH::long_array_var aVec = new SMESH::long_array;
209       aVec->length(1);
210       aVec[0] = vertID;
211       myVertexSelWdg->SetListOfIDs(aVec);
212     }
213
214     // enforced nodes
215     GEOM::ListOfGO_var     shapes;
216     SMESH::nodes_array_var points;
217     h->GetEnforcedNodes( shapes, points );
218     for ( int i = 0; i < shapes->length(); ++i )
219     {
220       CORBA::String_var name  = shapes[i]->GetName();
221       CORBA::String_var entry = shapes[i]->GetStudyEntry();
222       QListWidgetItem* item = new QListWidgetItem( name.in() );
223       item->setData( Qt::UserRole, entry.in() );
224       myShapesList->addItem( item );
225     }
226     for ( int i = 0; i < points->length(); ++i )
227     {
228       QTreeWidgetItem* item = new QTreeWidgetItem
229         ( QStringList()
230           << QString::number( points[i].x )
231           << QString::number( points[i].y )
232           << QString::number( points[i].z ));
233       item->setFlags( item->flags() | Qt::ItemIsEditable );
234       myCoordsTreeWdg->addTopLevelItem( item );
235     }
236   }
237   ((StdMeshersGUI_QuadrangleParamCreator*) this)->onSelectionChanged();
238 }
239
240 //=======================================================================
241 //function : storeParams
242 //purpose  :
243 //=======================================================================
244
245 QString  StdMeshersGUI_QuadrangleParamCreator::storeParams() const
246 {
247   StdMeshers::StdMeshers_QuadrangleParams_var h =
248     StdMeshers::StdMeshers_QuadrangleParams::_narrow( hypothesis() );
249
250   // name
251   if( myName )
252     SMESH::SetName( SMESH::FindSObject( h ), myName->text().toLatin1().constData() );
253
254   // transition
255   h->SetQuadType( StdMeshers::QuadType( myTypeWdg->GetType()) );
256
257   // vertex
258   if ( myVertexSelWdg->GetListSize() > 0 )
259   {
260     h->SetTriaVertex( myVertexSelWdg->GetListOfIDs()[0] ); // getlist must be called once
261     h->SetObjectEntry( myVertexSelWdg->GetMainShapeEntry() );
262   }
263   else
264   {
265     h->SetTriaVertex( -1 );
266   }
267
268   // enfored nodes
269
270   GEOM::ListOfGO_var goList = new GEOM::ListOfGO;
271   int nbShapes = 0;
272   goList->length( myShapesList->count() );
273   for ( int i = 0; i < myShapesList->count(); ++i )
274   {
275     QListWidgetItem* item = myShapesList->item(i);
276     QString         entry = item->data( Qt::UserRole ).toString();
277     Handle(SALOME_InteractiveObject) io =
278       new SALOME_InteractiveObject( entry.toStdString().c_str(), "GEOM" );
279     GEOM::GEOM_Object_var go = GEOMBase::ConvertIOinGEOMObject( io );
280     if ( !go->_is_nil() )
281       goList[ nbShapes++ ] = go;
282   }
283   goList->length( nbShapes );
284   
285   SMESH::nodes_array_var points = new SMESH::nodes_array;
286   points->length( myCoordsTreeWdg->topLevelItemCount() );
287   for ( int i = 0; i < myCoordsTreeWdg->topLevelItemCount(); ++i )
288   {
289     QTreeWidgetItem* item = myCoordsTreeWdg->topLevelItem( i );
290     points[i].x = item->text(0).toInt();
291     points[i].y = item->text(1).toInt();
292     points[i].z = item->text(2).toInt();
293   }
294   h->SetEnforcedNodes( goList, points );
295
296   return "";
297 }
298
299 //=======================================================================
300 //function : onTypeChanged
301 //purpose  :
302 //=======================================================================
303
304 void StdMeshersGUI_QuadrangleParamCreator::onTypeChanged(int type)
305 {
306   myTabs->setTabEnabled( TAB_ENF_POINTS, ( type != StdMeshers::QUAD_REDUCED ));
307 }
308
309 //=======================================================================
310 //function : onAddShape
311 //purpose  : 
312 //=======================================================================
313
314 void StdMeshersGUI_QuadrangleParamCreator::onAddShape()
315 {
316   if ( !mySelectedShapeIO.IsNull() )
317   {
318     QListWidgetItem* item = new QListWidgetItem( mySelectedShapeIO->getName() );
319     item->setData( Qt::UserRole, mySelectedShapeIO->getEntry() );
320     myShapesList->addItem( item );
321     mySelectedShapeIO.Nullify();
322     myAddShapeBut->setEnabled( false );
323   }
324 }
325
326 //=======================================================================
327 //function : onRemoveShape
328 //purpose  : 
329 //=======================================================================
330
331 void StdMeshersGUI_QuadrangleParamCreator::onRemoveShape()
332 {
333   if ( QListWidgetItem * item = myShapesList->currentItem() )
334     delete item;
335   onSelectionChanged();
336 }
337
338 //=======================================================================
339 //function : onAddPoint
340 //purpose  : 
341 //=======================================================================
342
343 void StdMeshersGUI_QuadrangleParamCreator::onAddPoint()
344 {
345   QTreeWidgetItem* item = new QTreeWidgetItem( QStringList() << "0" << "0" << "0" );
346   item->setFlags( item->flags() | Qt::ItemIsEditable );
347   myCoordsTreeWdg->addTopLevelItem( item );
348 }
349
350 //=======================================================================
351 //function : onRemovePoint
352 //purpose  :
353 //=======================================================================
354
355 void StdMeshersGUI_QuadrangleParamCreator::onRemovePoint()
356 {
357   if ( myCoordsTreeWdg->topLevelItemCount() )
358     delete myCoordsTreeWdg->currentItem();
359 }
360
361 //=======================================================================
362 //function : onSelectionChanged
363 //purpose  : 
364 //=======================================================================
365
366 void StdMeshersGUI_QuadrangleParamCreator::onSelectionChanged()
367 {
368   mySelectedShapeIO.Nullify();
369
370   // find a sole selected geometry
371   LightApp_SelectionMgr* selMgr = SMESHGUI::GetSMESHGUI()->selectionMgr();
372   SALOME_ListIO          selList;
373   selMgr->selectedObjects( selList );
374   SALOME_ListIteratorOfListIO selIt( selList );
375   for ( ; selIt.More(); selIt.Next() )
376   {
377     GEOM::GEOM_Object_var go = GEOMBase::ConvertIOinGEOMObject( selIt.Value() );
378     if ( !go->_is_nil() )
379     {
380       if ( !mySelectedShapeIO.IsNull() )
381       {
382         mySelectedShapeIO.Nullify();
383         break;
384       }
385       mySelectedShapeIO = selIt.Value();
386       if ( !mySelectedShapeIO->getName() || !mySelectedShapeIO->getName()[0] )
387         mySelectedShapeIO.Nullify();
388     }
389   }
390   // check if a selected geometry is not already in myShapesList
391   if ( !mySelectedShapeIO.IsNull() )
392   {
393     for ( int i = 0; i < myShapesList->count(); ++i )
394       if ( myShapesList->item(i)->data( Qt::UserRole ) == mySelectedShapeIO->getEntry() )
395       {
396         mySelectedShapeIO.Nullify();
397         break;
398       }
399   }
400   myAddShapeBut->setEnabled( !mySelectedShapeIO.IsNull() );
401 }
402
403 //=======================================================================
404 //function : onTabChanged
405 //purpose  : 
406 //=======================================================================
407
408 void StdMeshersGUI_QuadrangleParamCreator::onTabChanged(int i)
409 {
410   myVertexSelWdg->showPreview( i == TAB_VERTEX );
411 }
412
413 //================================================================================
414 // function : Constructor
415 // purpose  :
416 //================================================================================
417
418 StdMeshersGUI_QuadrangleParamWdg::StdMeshersGUI_QuadrangleParamWdg (QWidget * parent)
419   : QWidget(parent), myType(0)
420 {
421   myType = new QButtonGroup (this);
422
423   QGridLayout* typeLay = new QGridLayout( this );
424
425   typeLay->setMargin(MARGIN);
426   typeLay->setSpacing(SPACING);
427
428   QString aTypeKey ("SMESH_QUAD_TYPE_%1");
429   QString aPictKey ("ICON_StdMeshers_Quadrangle_Params_%1");
430
431   int itype = 0;
432   for (; itype < int(StdMeshers::QUAD_NB_TYPES); itype++) {
433     QRadioButton* rbi = new QRadioButton (tr(aTypeKey.arg(itype).toLatin1()), this);
434     QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr(aPictKey.arg(itype).toLatin1())));
435     QLabel* pli = new QLabel (this);
436     pli->setPixmap(pmi);
437     typeLay->addWidget(rbi, itype, 0, 1, 1);
438     typeLay->addWidget(pli, itype, 1, 1, 1);
439     myType->addButton(rbi, itype);
440   }
441   myType->button(0)->setChecked(true);
442
443   setLayout(typeLay);
444   setMinimumWidth(300);
445
446   connect( myType, SIGNAL( buttonClicked(int)), this, SIGNAL( typeChanged(int)));
447 }
448
449 //================================================================================
450 // function : Destructor
451 // purpose  :
452 //================================================================================
453 StdMeshersGUI_QuadrangleParamWdg::~StdMeshersGUI_QuadrangleParamWdg()
454 {
455 }
456
457 //=================================================================================
458 // function : SetType
459 // purpose  :
460 //=================================================================================
461 void StdMeshersGUI_QuadrangleParamWdg::SetType (int theType)
462 {
463   myType->button(theType)->setChecked(true);
464 }
465
466 //=================================================================================
467 // function : GetType
468 // purpose  :
469 //=================================================================================
470 int StdMeshersGUI_QuadrangleParamWdg::GetType()
471 {
472   return myType->checkedId();
473 }
474
475 //================================================================================
476 /*!
477   \brief Constructor
478 */
479 StdMeshersGUI_QuadrangleParamCreator::
480 ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
481 {
482 }
483 //================================================================================
484 /*!
485   \brief Create item editor widget
486 */
487 QWidget* StdMeshersGUI_QuadrangleParamCreator::
488 ItemDelegate::createEditor( QWidget*                    parent,
489                             const QStyleOptionViewItem& option,
490                             const QModelIndex&          index ) const
491 {
492   SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
493   sb->RangeStepAndValidator( COORD_MIN, COORD_MAX, 10 );
494   return sb;
495 }