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