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