1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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)
28 #include "SMESHGUI_Add0DElemsOnAllNodesDlg.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"
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 #include <smIdType.hxx>
46 #include <QButtonGroup>
50 #include <QGridLayout>
52 #include <QHBoxLayout>
55 #include <QPushButton>
56 #include <QRadioButton>
58 #include <SALOMEconfig.h>
59 #include CORBA_SERVER_HEADER(SMESH_Mesh)
60 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
66 enum { SEL_OBJECT, SEL_ELEMENTS, SEL_NODES };
68 //================================================================================
70 * \brief Dialog Constructor
72 //================================================================================
74 SMESHGUI_Add0DElemsOnAllNodesDlg::SMESHGUI_Add0DElemsOnAllNodesDlg()
75 : SMESHGUI_Dialog( 0, false, true ),
78 setWindowTitle( tr( "CAPTION" ) );
80 // Seletction type radio buttons
82 QGroupBox* selTypeGrBox = new QGroupBox( mainFrame() );
84 QRadioButton* objBtn = new QRadioButton( tr( "SMESH_SUBMESH_GROUP"),selTypeGrBox );
85 QRadioButton* elemBtn = new QRadioButton( tr( "SMESH_ELEMENTS" ),selTypeGrBox );
86 QRadioButton* nodeBtn = new QRadioButton( tr( "SMESH_NODES" ),selTypeGrBox );
88 QHBoxLayout* selTypeLay = new QHBoxLayout( selTypeGrBox );
89 selTypeLay->setMargin(MARGIN);
90 selTypeLay->setSpacing(SPACING);
91 selTypeLay->addWidget( objBtn );
92 selTypeLay->addWidget( elemBtn );
93 selTypeLay->addWidget( nodeBtn );
94 objBtn->setChecked(true);
96 mySelTypeBtnGrp = new QButtonGroup( mainFrame() );
97 mySelTypeBtnGrp->addButton( objBtn , SEL_OBJECT );
98 mySelTypeBtnGrp->addButton( elemBtn, SEL_ELEMENTS );
99 mySelTypeBtnGrp->addButton( nodeBtn, SEL_NODES );
101 // Label, Select Btn, LineEdit, Filter Btn
103 setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
104 createObject( tr( "SMESH_NAME" ), mainFrame(), 0 );
106 myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), mainFrame() );
108 myDuplicateElemsChkBox = new QCheckBox( tr( "SMESH_DUPLICATE_0D" ), mainFrame() );
112 myGroupBox = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), mainFrame() );
113 myGroupBox->setCheckable( true );
115 myGroupLabel = new QLabel( tr( "SMESH_GROUP" ), myGroupBox );
116 myGroupListCmBox = new QComboBox( myGroupBox );
117 myGroupListCmBox->setEditable( true );
118 myGroupListCmBox->setInsertPolicy( QComboBox::NoInsert );
120 QHBoxLayout* groupsLayout = new QHBoxLayout( myGroupBox );
121 groupsLayout->setSpacing(SPACING);
122 groupsLayout->setMargin(MARGIN);
123 groupsLayout->addWidget( myGroupLabel );
124 groupsLayout->addWidget( myGroupListCmBox, 1 );
128 QGridLayout* aLay = new QGridLayout( mainFrame() );
129 aLay->setMargin(MARGIN);
130 aLay->setSpacing(SPACING);
132 aLay->addWidget( selTypeGrBox, 0, 0, 1, 5 );
134 aLay->addWidget( objectWg( 0, Label ), 1, 0 );
135 aLay->addWidget( objectWg( 0, Btn ), 1, 1 );
136 aLay->addWidget( objectWg( 0, Control), 1, 2, 1, 2 );
137 aLay->addWidget( myFilterBtn, 1, 4 );
138 aLay->addWidget( myDuplicateElemsChkBox,2, 0 );
140 aLay->addWidget( myGroupBox, 3, 0, 1, 5 );
144 connect( myGroupBox, SIGNAL( toggled( bool )), SLOT( onGroupChecked() ));
145 connect( mySelTypeBtnGrp, SIGNAL( buttonClicked(int) ), SLOT( onSelTypeChange(int)));
147 onSelTypeChange( SEL_OBJECT );
150 //================================================================================
152 * \brief SLOT to enable/disable groups
154 //================================================================================
156 void SMESHGUI_Add0DElemsOnAllNodesDlg::onGroupChecked( bool on )
158 myGroupLabel->setEnabled( on );
159 myGroupListCmBox->setEnabled( on );
162 //================================================================================
164 * \brief SLOT to enable/disable groups
166 //================================================================================
168 void SMESHGUI_Add0DElemsOnAllNodesDlg::onSelTypeChange( int selType )
170 setNameIndication( 0, selType == SEL_OBJECT ? OneName : ListOfNames );
171 setReadOnly ( 0, selType == SEL_OBJECT );
173 QLabel* label = qobject_cast< QLabel* >( objectWg(0, Label ));
175 case SEL_OBJECT: label->setText( tr("SMESH_NAME")); break;
176 case SEL_ELEMENTS: label->setText( tr("ELEMENT_IDS")); break;
177 case SEL_NODES: label->setText( tr("NODE_IDS")); break;
180 QLineEdit* lineEdit = qobject_cast< QLineEdit* >( objectWg(0, Control ));
181 lineEdit->setText("");
182 lineEdit->setValidator( selType == SEL_OBJECT ? 0 : & myIDValidator );
184 myFilterBtn->setEnabled( selType != SEL_OBJECT );
186 emit selTypeChanged( selType );
189 //================================================================================
191 * \brief Return type of selected object: [SEL_OBJECT, SEL_ELEMENTS, SEL_NODES]
193 //================================================================================
195 int SMESHGUI_Add0DElemsOnAllNodesDlg::getSelectionType() const
197 return mySelTypeBtnGrp->checkedId();
200 //================================================================================
202 * \brief Checks consistency of data
204 //================================================================================
206 bool SMESHGUI_Add0DElemsOnAllNodesDlg::isValid()
208 if( myGroupBox->isChecked() && myGroupListCmBox->currentText().isEmpty() ) {
209 SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
215 //================================================================================
217 * \brief Operation Constructor
219 //================================================================================
221 SMESHGUI_Add0DElemsOnAllNodesOp::SMESHGUI_Add0DElemsOnAllNodesOp()
222 :SMESHGUI_SelectionOp(),
223 myDlg( new SMESHGUI_Add0DElemsOnAllNodesDlg ),
226 myHelpFileName = "adding_nodes_and_elements.html#adding-0delems-on-all-nodes-anchor";
228 connect( myDlg, SIGNAL( selTypeChanged(int) ), SLOT( onSelTypeChange(int)));
229 connect( myDlg->myFilterBtn, SIGNAL( clicked()), SLOT( onSetFilter() ));
230 connect( myDlg->myGroupBox, SIGNAL( clicked(bool)), SLOT( updateButtons() ));
233 //================================================================================
237 //================================================================================
239 SMESHGUI_Add0DElemsOnAllNodesOp::~SMESHGUI_Add0DElemsOnAllNodesOp()
242 myFilterDlg->setParent( 0 );
248 //================================================================================
252 //================================================================================
254 void SMESHGUI_Add0DElemsOnAllNodesOp::startOperation()
256 SMESHGUI_SelectionOp::startOperation();
258 myDlg->myGroupBox->setChecked( false );
259 myDlg->activateObject( 0 );
265 //================================================================================
267 * \brief Treat changed selection
269 //================================================================================
271 void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
273 if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dgl active
274 if (!myDlg->myGroupBox->isEnabled()) return; // inactive
280 selectionMgr()->selectedObjects( aList );
281 if ( aList.Extent() == 1 ) {
282 myIO = aList.First();
285 myDlg->setObjectText( 0, ""); // it clears the selection
289 switch ( myDlg->getSelectionType() ) {
291 SMESHGUI_SelectionOp::selectionDone();
294 SMESH::GetNameOfSelectedElements( selector(), myIO, ids );
295 myDlg->setObjectText( 0, ids );
298 SMESH::GetNameOfSelectedNodes( selector(), myIO, ids );
299 myDlg->setObjectText( 0, ids );
304 // fill the list of existing groups
305 myDlg->myGroupListCmBox->clear();
306 myDlg->myGroupListCmBox->addItem( QString() );
307 if ( !myIO.IsNull() && myIO->hasEntry())
309 SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
310 _PTR(SObject) meshSO = SMESH::ObjectToSObject( mesh );
311 _PTR(SObject) group0DRoot;
312 if ( meshSO && meshSO->FindSubObject( SMESH::Tag_0DElementsGroups, group0DRoot ))
314 _PTR(ChildIterator) group0DIter = SMESH::getStudy()->NewChildIterator( group0DRoot );
315 for ( ; group0DIter->More(); group0DIter->Next() )
317 _PTR(SObject) groupSO = group0DIter->Value();
318 std::string groupName = groupSO->GetName();
319 if ( !groupName.empty() )
320 myDlg->myGroupListCmBox->addItem( groupName.c_str() );
328 //=======================================================================
329 //function : updateButtons
330 //purpose : enable [Apply]
331 //=======================================================================
333 void SMESHGUI_Add0DElemsOnAllNodesOp::updateButtons()
337 if (( !myIO.IsNull() && myIO->hasEntry() && !myDlg->objectText( 0 ).isEmpty() ) &&
338 ( !myDlg->myGroupBox->isChecked() || !myDlg->myGroupListCmBox->currentText().isEmpty() ))
340 SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
341 if ( !mesh->_is_nil() )
343 if ( myDlg->getSelectionType() == SEL_OBJECT )
347 QString ids = myDlg->objectText( 0 );
348 QStringList idList = ids.split( " ", QString::SkipEmptyParts );
349 const bool isElem = ( myDlg->getSelectionType() == SEL_ELEMENTS );
350 QStringList::iterator idIt = idList.begin();
351 for ( ; idIt != idList.end() && !ok; ++idIt )
352 ok = ( mesh->GetElementType( idIt->toLong(), isElem ) != SMESH::ALL );
357 myDlg->button( QtxDialog::Apply )->setEnabled( ok );
358 myDlg->button( QtxDialog::OK )->setEnabled( ok );
361 //================================================================================
363 * \brief Return a filter of objects
365 //================================================================================
367 SUIT_SelectionFilter* SMESHGUI_Add0DElemsOnAllNodesOp::createFilter( const int ) const
369 if ( myDlg->getSelectionType() == SEL_OBJECT )
371 // Create a filter of objects: any IDSource except the group of 0D elements
373 QList<SUIT_SelectionFilter*> filters;
374 filters.push_back( new SMESH_TypeFilter( SMESH::GROUP_0D ));
375 SMESH_LogicalFilter* not0DGroup = new SMESH_LogicalFilter( filters,
376 SMESH_LogicalFilter::LO_NOT,
377 /*takeOwnership=*/true);
378 filters[0] = not0DGroup;
379 filters.push_back( new SMESH_TypeFilter( SMESH::IDSOURCE ));
380 return new SMESH_LogicalFilter( filters,
381 SMESH_LogicalFilter::LO_AND,
382 /*takeOwnership=*/true);
387 //================================================================================
389 * \brief Makes its main job
391 //================================================================================
393 bool SMESHGUI_Add0DElemsOnAllNodesOp::onApply()
395 if ( !myDlg->isValid() )
399 SMESH::IDSource_wrap meshObject;
400 SMESH::SMESH_Mesh_var mesh;
401 if ( !myIO.IsNull() )
403 CORBA::Object_var obj = SMESH::IObjectToObject( myIO );
404 meshObject = SMESH::SMESH_IDSource::_narrow( obj );
405 if ( !meshObject->_is_nil() )
407 mesh = meshObject->GetMesh();
408 meshObject->Register();
411 if ( mesh->_is_nil() )
413 SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_BAD_SELECTION" ) );
418 SMESH::SMESH_MeshEditor_var editor = mesh->GetMeshEditor();
420 // make SMESH_IDSource holding IDs of selected elements
421 if ( myDlg->getSelectionType() != SEL_OBJECT )
423 QString elemIDs = myDlg->objectText( 0 );
424 QStringList idList = elemIDs.split( " ", QString::SkipEmptyParts );
425 if ( idList.count() == 0 )
427 SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_BAD_SELECTION" ) );
430 SMESH::smIdType_array_var idArray = new SMESH::smIdType_array;
431 idArray->length( idList.count() );
432 QStringList::iterator idIt = idList.begin();
433 for ( int i = 0; idIt != idList.end(); ++idIt, ++i )
434 idArray[i] = idIt->toLong();
435 SMESH::ElementType elemType =
436 myDlg->getSelectionType() == SEL_NODES ? SMESH::NODE : SMESH::ALL;
437 meshObject = editor->MakeIDSource( idArray, elemType );
440 // Create 0D elements
442 smIdType prevNb0D = mesh->Nb0DElements();
444 QString groupName = myDlg->myGroupListCmBox->currentText();
445 SMESH::SMESH_IDSource_var newObj =
446 editor->Create0DElementsOnAllNodes( meshObject, groupName.toUtf8().data(),
447 myDlg->myDuplicateElemsChkBox->isChecked() );
449 smIdType newNb0D = mesh->Nb0DElements() - prevNb0D;
450 SUIT_MessageBox::information( myDlg, tr( "SMESH_INFORMATION" ),
451 tr( "NB_NEW_0D" ).arg( newNb0D ),
452 SUIT_MessageBox::Ok, SUIT_MessageBox::Ok);
454 catch ( const SALOME::SALOME_Exception& S_ex ) {
455 SalomeApp_Tools::QtCatchCorbaException( S_ex );
464 if ( myDlg->getSelectionType() == SEL_OBJECT )
467 selectionMgr()->setSelectedObjects( aList, /*append=*/false );
471 selector()->ClearIndex();
476 SMESHGUI::Modified();
478 if ( myDlg->myGroupBox->isChecked() )
479 SMESHGUI::GetSMESHGUI()->updateObjBrowser();
484 //================================================================================
486 * \brief Sets selection mode
488 //================================================================================
490 void SMESHGUI_Add0DElemsOnAllNodesOp::onSelTypeChange(int selType)
493 case SEL_OBJECT: setSelectionMode( ActorSelection ); break;
494 case SEL_ELEMENTS: setSelectionMode( CellSelection ); break;
495 case SEL_NODES: setSelectionMode( NodeSelection ); break;
498 if ( selType != SEL_OBJECT )
499 connect( myDlg, SIGNAL( objectChanged( int, const QStringList& )),
500 this, SLOT ( onTextChanged( int, const QStringList& )));
502 disconnect( myDlg, SIGNAL( objectChanged( int, const QStringList& )),
503 this, SLOT ( onTextChanged( int, const QStringList& )));
505 connect( myDlg->myGroupListCmBox, SIGNAL( editTextChanged(const QString & )),
506 this, SLOT( updateButtons() ));
511 //================================================================================
513 * \brief Install filters
515 //================================================================================
517 void SMESHGUI_Add0DElemsOnAllNodesOp::onSetFilter()
519 SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
520 if ( mesh->_is_nil()) {
521 SUIT_MessageBox::critical( myDlg, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
525 if ( myDlg->getSelectionType() == SEL_NODES ) {
526 types.push_back( SMESH::NODE );
528 else if ( myDlg->getSelectionType() == SEL_ELEMENTS ) {
529 types.push_back( SMESH::EDGE );
530 types.push_back( SMESH::FACE );
531 types.push_back( SMESH::VOLUME );
536 myFilterDlg = new SMESHGUI_FilterDlg( getSMESHGUI(), SMESH::ALL );
538 myFilterDlg->Init( types );
539 myFilterDlg->SetSelection();
540 myFilterDlg->SetMesh( mesh );
541 myFilterDlg->SetSourceWg( myDlg->objectWg( 0, LightApp_Dialog::Control ));
546 //=======================================================================
547 //function : onTextChanged
548 //purpose : SLOT called when the user types IDs
549 //=======================================================================
551 void SMESHGUI_Add0DElemsOnAllNodesOp::onTextChanged( int obj, const QStringList& text )
553 SMESHGUI_SelectionOp::onTextChanged( obj, text );