Salome HOME
1f67962f862d1c0ea25a5c9474fbd7c379ff81b1
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Add0DElemsOnAllNodesDlg.cxx
1 // Copyright (C) 2007-2012  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
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File      : SMESHGUI_Add0DElemsOnAllNodesDlg.cxx
25 // Created   : Fri Oct 19 15:51:24 2012
26 // Author    : Edward AGAPOV (eap)
27
28 #include "SMESHGUI_Add0DElemsOnAllNodesDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_FilterDlg.h"
32 #include "SMESHGUI_MeshUtils.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESH_LogicalFilter.hxx"
36 #include "SMESH_TypeFilter.hxx"
37
38 #include <LightApp_SelectionMgr.h>
39 #include <SALOME_ListIO.hxx>
40 #include <SUIT_MessageBox.h>
41 #include <SVTK_Selector.h>
42 #include <SalomeApp_Tools.h>
43
44 // Qt includes
45 #include <QButtonGroup>
46 #include <QCheckBox>
47 #include <QComboBox>
48 #include <QFrame>
49 #include <QGridLayout>
50 #include <QGroupBox>
51 #include <QHBoxLayout>
52 #include <QLabel>
53 #include <QLineEdit>
54 #include <QPushButton>
55 #include <QRadioButton>
56
57 #include <SALOMEconfig.h>
58 #include CORBA_SERVER_HEADER(SMESH_Mesh)
59 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
60
61 #define SPACING 6
62 #define MARGIN  11
63
64 enum { SEL_OBJECT, SEL_ELEMENTS, SEL_NODES };
65
66 //================================================================================
67 /*!
68  * \brief Dialog Constructor
69  */
70 //================================================================================
71
72 SMESHGUI_Add0DElemsOnAllNodesDlg::SMESHGUI_Add0DElemsOnAllNodesDlg()
73   : SMESHGUI_Dialog( 0, false, true ),
74     myIDValidator( this )
75 {
76   setWindowTitle( tr( "CAPTION" ) );
77
78   // Seletction type radio buttons
79
80   QGroupBox* selTypeGrBox = new QGroupBox( mainFrame() );
81   //
82   QRadioButton*    objBtn = new QRadioButton( tr( "SMESH_SUBMESH_GROUP"),selTypeGrBox );
83   QRadioButton*   elemBtn = new QRadioButton( tr( "SMESH_ELEMENTS" ),selTypeGrBox );
84   QRadioButton*   nodeBtn = new QRadioButton( tr( "SMESH_NODES" ),selTypeGrBox );
85   //
86   QHBoxLayout* selTypeLay = new QHBoxLayout( selTypeGrBox );
87   selTypeLay->setMargin(MARGIN);
88   selTypeLay->setSpacing(SPACING);
89   selTypeLay->addWidget( objBtn  );
90   selTypeLay->addWidget( elemBtn );
91   selTypeLay->addWidget( nodeBtn );
92   objBtn->setChecked(true);
93   //
94   mySelTypeBtnGrp         = new QButtonGroup( mainFrame() );
95   mySelTypeBtnGrp->addButton( objBtn , SEL_OBJECT );
96   mySelTypeBtnGrp->addButton( elemBtn, SEL_ELEMENTS );
97   mySelTypeBtnGrp->addButton( nodeBtn, SEL_NODES );
98
99   // Label, Select Btn, LineEdit, Filter Btn
100
101   // myLabel = new QLabel(tr("SMESH_NAME"), mainFrame() );
102   // QPushButton* selBtn = new QPushButton( mainFrame() );
103   // QPixmap imageSelect( resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")) );
104   // selBtn->setIcon(image2);
105   // myLineEdit = new QLineEdit( mainFrame() );
106
107   setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
108   createObject( tr( "SMESH_NAME" ), mainFrame(), 0 );
109
110   myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), mainFrame() );
111
112   // List of groups
113
114   myGroupBox = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), mainFrame() );
115   myGroupBox->setCheckable( true );
116
117   myGroupLabel = new QLabel( tr( "SMESH_GROUP" ), myGroupBox );
118   myGroupListCmBox = new QComboBox( myGroupBox );
119   myGroupListCmBox->setEditable( true );
120   myGroupListCmBox->setInsertPolicy( QComboBox::NoInsert );
121
122   QHBoxLayout* groupsLayout = new QHBoxLayout( myGroupBox );
123   groupsLayout->setSpacing(SPACING);
124   groupsLayout->setMargin(MARGIN);
125   groupsLayout->addWidget( myGroupLabel );
126   groupsLayout->addWidget( myGroupListCmBox, 1 );
127
128   // Main layout
129
130   QGridLayout* aLay = new QGridLayout( mainFrame() );
131   aLay->setMargin(MARGIN);
132   aLay->setSpacing(SPACING);
133   //
134   aLay->addWidget( selTypeGrBox,          0, 0, 1, 5  );
135   //
136   aLay->addWidget( objectWg( 0, Label  ), 1, 0 );
137   aLay->addWidget( objectWg( 0, Btn    ), 1, 1 );
138   aLay->addWidget( objectWg( 0, Control), 1, 2, 1, 2 );
139   aLay->addWidget( myFilterBtn,           1, 4 );
140   //
141   aLay->addWidget( myGroupBox,            2, 0, 1, 5 );
142
143   // Signals
144
145   connect( myGroupBox,      SIGNAL( toggled( bool )),     SLOT( onGroupChecked() ));
146   connect( mySelTypeBtnGrp, SIGNAL( buttonClicked(int) ), SLOT( onSelTypeChange(int)));
147
148   onSelTypeChange( SEL_OBJECT );
149 }
150
151 //================================================================================
152 /*!
153  * \brief SLOT to enable/disable groups
154  */
155 //================================================================================
156
157 void SMESHGUI_Add0DElemsOnAllNodesDlg::onGroupChecked( bool on )
158 {
159   myGroupLabel->setEnabled( on );
160   myGroupListCmBox->setEnabled( on );
161 }
162
163 //================================================================================
164 /*!
165  * \brief SLOT to enable/disable groups
166  */
167 //================================================================================
168
169 void SMESHGUI_Add0DElemsOnAllNodesDlg::onSelTypeChange( int selType )
170 {
171   setNameIndication( 0, selType == SEL_OBJECT ? OneName : ListOfNames );
172   setReadOnly      ( 0, selType == SEL_OBJECT );
173
174   QLabel* label = qobject_cast< QLabel* >( objectWg(0, Label ));
175   switch( selType ) {
176   case SEL_OBJECT:   label->setText( tr("SMESH_NAME")); break;
177   case SEL_ELEMENTS: label->setText( tr("ELEMENT_IDS")); break;
178   case SEL_NODES:    label->setText( tr("NODE_IDS")); break;
179   default:;
180   }
181   QLineEdit* lineEdit = qobject_cast< QLineEdit* >( objectWg(0, Control ));
182   lineEdit->setText("");
183   lineEdit->setValidator( selType == SEL_OBJECT ? 0 : & myIDValidator );
184
185   myFilterBtn->setEnabled( selType != SEL_OBJECT );
186
187   emit selTypeChanged( selType );
188 }
189
190 //================================================================================
191 /*!
192  * \brief Return type of selected object: [SEL_OBJECT, SEL_ELEMENTS, SEL_NODES]
193  */
194 //================================================================================
195
196 int SMESHGUI_Add0DElemsOnAllNodesDlg::getSelectionType() const
197 {
198   return mySelTypeBtnGrp->checkedId();
199 }
200
201 //================================================================================
202 /*!
203  * \brief Checks consistency of data
204  */
205 //================================================================================
206
207 bool SMESHGUI_Add0DElemsOnAllNodesDlg::isValid()
208 {
209   if( myGroupBox->isChecked() && myGroupListCmBox->currentText().isEmpty() ) {
210     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
211     return false;
212   }
213   return true;
214 }
215
216 //================================================================================
217 /*!
218  * \brief Operation Constructor
219  */
220 //================================================================================
221
222 SMESHGUI_Add0DElemsOnAllNodesOp::SMESHGUI_Add0DElemsOnAllNodesOp()
223   :SMESHGUI_SelectionOp(),
224    myDlg( new SMESHGUI_Add0DElemsOnAllNodesDlg ),
225    myFilterDlg( 0 )
226 {
227   myHelpFileName = "adding_nodes_and_elements_page#adding_0delems_anchor.html";
228
229   connect( myDlg,              SIGNAL( selTypeChanged(int) ), SLOT( onSelTypeChange(int)));
230   connect( myDlg->myFilterBtn, SIGNAL( clicked()),            SLOT( onSetFilter() ));
231 }
232
233 //================================================================================
234 /*!
235  * \brief Destructor
236  */
237 //================================================================================
238
239 SMESHGUI_Add0DElemsOnAllNodesOp::~SMESHGUI_Add0DElemsOnAllNodesOp()
240 {
241   if ( myFilterDlg ) {
242     myFilterDlg->setParent( 0 );
243     delete myFilterDlg;
244     myFilterDlg = 0;
245   }
246 }
247
248 //================================================================================
249 /*!
250  * \brief Start
251  */
252 //================================================================================
253
254 void SMESHGUI_Add0DElemsOnAllNodesOp::startOperation()
255 {
256   SMESHGUI_SelectionOp::startOperation();
257
258   myDlg->myGroupBox->setChecked( false );
259   myDlg->activateObject( 0 );
260   myDlg->show();
261
262   selectionDone();
263 }
264
265 //================================================================================
266 /*!
267  * \brief Treat changed selection
268  */
269 //================================================================================
270
271 void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
272 {
273   if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dgl active
274   if (!myDlg->myGroupBox->isEnabled())         return; // inactive
275
276   myIO.Nullify();
277   myDlg->setObjectText( 0, "");
278
279   SALOME_ListIO aList;
280   selectionMgr()->selectedObjects( aList );
281   if ( aList.Extent() == 1 )
282     myIO = aList.First();
283   else
284     return;
285
286   QString ids;
287   switch ( myDlg->getSelectionType() ) {
288   case SEL_OBJECT:
289     SMESHGUI_SelectionOp::selectionDone();
290     break;
291   case SEL_ELEMENTS:
292     SMESH::GetNameOfSelectedElements( selector(), myIO, ids );
293     myDlg->setObjectText( 0, ids );
294     break;
295   case SEL_NODES:
296     SMESH::GetNameOfSelectedNodes( selector(), myIO, ids );
297     myDlg->setObjectText( 0, ids );
298     break;
299   default:;
300   }
301
302   // fill the list of existing groups
303   myDlg->myGroupListCmBox->clear();
304   myDlg->myGroupListCmBox->addItem( QString() );
305   if ( !myIO.IsNull() && myIO->hasEntry()) {
306     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
307     _PTR(SObject) meshSO = aStudy->FindObjectID( myIO->getEntry() );
308     _PTR(SObject) group0DRoot;
309     if ( meshSO->FindSubObject( SMESH::Tag_0DElementsGroups, group0DRoot ))
310     {
311       _PTR(ChildIterator) group0DIter = aStudy->NewChildIterator( group0DRoot );
312       for ( ; group0DIter->More(); group0DIter->Next() )
313       {
314         _PTR(SObject) groupSO = group0DIter->Value();
315         std::string groupName = groupSO->GetName();
316         if ( !groupName.empty() )
317           myDlg->myGroupListCmBox->addItem( groupName.c_str() );
318       }
319     }
320   }
321 }
322
323 //================================================================================
324 /*!
325  * \brief Return a filter of objects
326  */
327 //================================================================================
328
329 SUIT_SelectionFilter* SMESHGUI_Add0DElemsOnAllNodesOp::createFilter( const int ) const
330 {
331   if ( myDlg->getSelectionType() == SEL_OBJECT )
332   {
333     // Create a filter of objects: any IDSource except the group of 0D elements
334
335     QList<SUIT_SelectionFilter*> filters;
336     filters.push_back( new SMESH_TypeFilter( SMESH::GROUP_0D ));
337     SMESH_LogicalFilter* not0DGroup = new SMESH_LogicalFilter( filters,
338                                                                SMESH_LogicalFilter::LO_NOT,
339                                                                /*takeOwnership=*/true);
340     filters[0] = not0DGroup;
341     filters.push_back( new SMESH_TypeFilter( SMESH::IDSOURCE ));
342     return new SMESH_LogicalFilter( filters,
343                                     SMESH_LogicalFilter::LO_AND,
344                                     /*takeOwnership=*/true);
345   }
346   return 0;
347 }
348
349 //================================================================================
350 /*!
351  * \brief Makes its main job
352  */
353 //================================================================================
354
355 bool SMESHGUI_Add0DElemsOnAllNodesOp::onApply()
356 {
357   if ( !myDlg->isValid() )
358     return false;
359
360   // get a mesh
361   SMESH::SMESH_IDSource_var meshObject;
362   SMESH::SMESH_Mesh_var     mesh;
363   if ( !myIO.IsNull() )
364   {
365     CORBA::Object_var obj = SMESH::IObjectToObject( myIO );
366     meshObject = SMESH::SMESH_IDSource::_narrow( obj );
367     if ( !meshObject->_is_nil() )
368       mesh = meshObject->GetMesh();
369   }
370   if ( mesh->_is_nil() )
371   {
372     SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_BAD_SELECTION" ) );
373     return false;
374   }
375
376   try {
377     SMESH::SMESH_MeshEditor_var editor = mesh->GetMeshEditor();
378
379     // make SMESH_IDSource holding IDs of selected elements
380     if ( myDlg->getSelectionType() != SEL_OBJECT )
381     {
382       QString elemIDs = myDlg->objectText( 0 );
383       QStringList idList = elemIDs.split( " ", QString::SkipEmptyParts );
384       if ( idList.count() == 0 )
385       {
386         SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_BAD_SELECTION" ) );
387         return false;
388       }
389       SMESH::long_array_var idArray = new SMESH::long_array;
390       idArray->length( idList.count() );
391       QStringList::iterator idIt = idList.begin();
392       for ( int i = 0; idIt != idList.end(); ++idIt, ++i )
393         idArray[i] = idIt->toLong();
394       SMESH::ElementType elemType =
395         myDlg->getSelectionType() == SEL_NODES ? SMESH::NODE : SMESH::ALL;
396       meshObject = editor->MakeIDSource( idArray, elemType );
397     }
398
399     // Create 0D elements
400
401     int prevNb0D = mesh->Nb0DElements();
402
403     QString groupName = myDlg->myGroupListCmBox->currentText();
404     SMESH::SMESH_IDSource_var newObj =
405       editor->Create0DElementsOnAllNodes( meshObject, groupName.toLatin1().data() );
406
407     int newNb0D = mesh->Nb0DElements() - prevNb0D;
408     SUIT_MessageBox::information( myDlg, tr( "SMESH_INFORMATION" ),
409                                   tr( "NB_NEW_0D" ).arg( newNb0D ),
410                                   SUIT_MessageBox::Ok, SUIT_MessageBox::Ok);
411   }
412   catch ( const SALOME::SALOME_Exception& S_ex ) {
413     SalomeApp_Tools::QtCatchCorbaException( S_ex );
414     return false;
415   }
416   catch (...) {
417     return false;
418   }
419
420   // clear selection
421
422   if ( myDlg->getSelectionType() == SEL_OBJECT )
423   {
424     selectionMgr()->setSelectedObjects( SALOME_ListIO(), /*append=*/false );
425   }
426   else
427   {
428     selector()->ClearIndex();
429   }
430   selectionDone();
431
432   SMESH::UpdateView();
433   SMESHGUI::Modified();
434
435   if ( myDlg->myGroupBox->isChecked() )
436     SMESHGUI::GetSMESHGUI()->updateObjBrowser();
437
438   return true;
439 }
440
441 //================================================================================
442 /*!
443  * \brief Sets selection mode
444  */
445 //================================================================================
446
447 void SMESHGUI_Add0DElemsOnAllNodesOp::onSelTypeChange(int selType)
448 {
449   switch ( selType ) {
450   case SEL_OBJECT:   setSelectionMode( ActorSelection ); break;
451   case SEL_ELEMENTS: setSelectionMode( CellSelection );  break;
452   case SEL_NODES:    setSelectionMode( NodeSelection );  break;
453   }
454
455   if ( selType != SEL_OBJECT )
456     connect( myDlg, SIGNAL( objectChanged( int, const QStringList& )),
457              this,  SLOT  ( onTextChanged( int, const QStringList& )));
458   else
459     disconnect( myDlg, SIGNAL( objectChanged( int, const QStringList& )),
460                 this,  SLOT  ( onTextChanged( int, const QStringList& )));
461
462   selectionDone();
463 }
464
465 //================================================================================
466 /*!
467  * \brief Install 
468  * 
469  * 
470  */
471 //================================================================================
472
473 void SMESHGUI_Add0DElemsOnAllNodesOp::onSetFilter()
474 {
475   SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
476   if ( mesh->_is_nil()) {
477     SUIT_MessageBox::critical( myDlg, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
478     return;
479   }
480   QList<int> types;
481   if ( myDlg->getSelectionType() == SEL_NODES ) {
482     types.push_back( SMESH::NODE );
483   }
484   else if ( myDlg->getSelectionType() == SEL_ELEMENTS ) {
485     types.push_back( SMESH::EDGE );
486     types.push_back( SMESH::FACE );
487     types.push_back( SMESH::VOLUME );
488   }
489   else
490     return;
491   if ( !myFilterDlg )
492     myFilterDlg = new SMESHGUI_FilterDlg( getSMESHGUI(), SMESH::ALL );
493
494   myFilterDlg->Init( types );
495   myFilterDlg->SetSelection();
496   myFilterDlg->SetMesh( mesh );
497   myFilterDlg->SetSourceWg( myDlg->objectWg( 0, LightApp_Dialog::Control ));
498
499   myFilterDlg->show();
500 }