Salome HOME
Merge from V6_5_BR 05/06/2012
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddMeshElementDlg.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_AddMeshElementDlg.cxx
25 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
26 //  SMESH includes
27 //
28 #include "SMESHGUI_AddMeshElementDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_MeshUtils.h"
34 #include "SMESHGUI_GroupUtils.h"
35 #include "SMESHGUI_IdValidator.h"
36
37 #include <SMESH_Actor.h>
38 #include <SMESH_ActorUtils.h>
39 #include <SMESH_FaceOrientationFilter.h>
40 #include <SMDS_Mesh.hxx>
41
42 // SALOME GUI inclues
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_MessageBox.h>
47 #include <SUIT_ViewManager.h>
48 #include <LightApp_SelectionMgr.h>
49 #include <SALOME_ListIO.hxx>
50 #include <SalomeApp_Application.h>
51 #include <SVTK_ViewModel.h>
52 #include <SVTK_ViewWindow.h>
53
54 // IDL incldues
55 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
56
57 // OCCT includes
58 #include <TColStd_MapOfInteger.hxx>
59
60 // VTK includes
61 #include <vtkCell.h>
62 #include <vtkIdList.h>
63 #include <vtkUnstructuredGrid.h>
64 #include <vtkDataSetMapper.h>
65 #include <vtkPolyDataMapper.h>
66 #include <vtkProperty.h>
67
68 // Qt includes
69 #include <QComboBox>
70 #include <QGroupBox>
71 #include <QLabel>
72 #include <QLineEdit>
73 #include <QPushButton>
74 #include <QRadioButton>
75 #include <QHBoxLayout>
76 #include <QVBoxLayout>
77 #include <QGridLayout>
78 #include <QVariant>
79 #include <QCheckBox>
80 #include <QKeyEvent>
81 #include <QButtonGroup>
82
83 #define SPACING 6
84 #define MARGIN  11
85
86 namespace SMESH
87 {
88   class TElementSimulation
89   {
90     SalomeApp_Application* myApplication;
91     SUIT_ViewWindow* myViewWindow;
92     SVTK_ViewWindow* myVTKViewWindow;
93
94     SALOME_Actor* myPreviewActor;
95     vtkDataSetMapper* myMapper;
96     vtkUnstructuredGrid* myGrid;
97
98     SALOME_Actor* myFaceOrientation;
99     vtkPolyDataMapper* myFaceOrientationDataMapper;
100     SMESH_FaceOrientationFilter* myFaceOrientationFilter;
101
102   public:
103     TElementSimulation (SalomeApp_Application* theApplication)
104     {
105       myApplication = theApplication;
106       SUIT_ViewManager* mgr = theApplication->activeViewManager();
107       if (!mgr) return;
108       myViewWindow = mgr->getActiveView();
109       myVTKViewWindow = GetVtkViewWindow(myViewWindow);
110
111       myGrid = vtkUnstructuredGrid::New();
112
113       // Create and display actor
114       myMapper = vtkDataSetMapper::New();
115       myMapper->SetInput(myGrid);
116
117       myPreviewActor = SALOME_Actor::New();
118       myPreviewActor->PickableOff();
119       myPreviewActor->VisibilityOff();
120       myPreviewActor->SetMapper(myMapper);
121
122       vtkFloatingPointType anRGB[3];
123       vtkProperty* aProp = vtkProperty::New();
124       GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
125       aProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
126       myPreviewActor->SetProperty( aProp );
127       aProp->Delete();
128
129       vtkProperty* aBackProp = vtkProperty::New();
130       GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
131       aBackProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
132       myPreviewActor->SetBackfaceProperty( aBackProp );
133       aBackProp->Delete();
134
135       myVTKViewWindow->AddActor(myPreviewActor);
136
137       // Orientation of faces
138       myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
139       myFaceOrientationFilter->SetInput(myGrid);
140
141       myFaceOrientationDataMapper = vtkPolyDataMapper::New();
142       myFaceOrientationDataMapper->SetInput(myFaceOrientationFilter->GetOutput());
143
144       myFaceOrientation = SALOME_Actor::New();
145       myFaceOrientation->PickableOff();
146       myFaceOrientation->VisibilityOff();
147       myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
148
149       vtkProperty* anOrientationProp = vtkProperty::New();
150       GetColor( "SMESH", "orientation_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) );
151       anOrientationProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
152       myFaceOrientation->SetProperty( anOrientationProp );
153       anOrientationProp->Delete();
154
155       myVTKViewWindow->AddActor(myFaceOrientation);
156     }
157
158     typedef std::vector<vtkIdType> TVTKIds;
159     void SetPosition (SMESH_Actor* theActor,
160                       vtkIdType    theType,
161                       TVTKIds&     theIds)
162     {
163       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
164       myGrid->SetPoints(aGrid->GetPoints());
165       myGrid->Reset();
166
167       const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( theType ));
168       SMDS_MeshCell::applyInterlace( interlace, theIds );
169
170       vtkIdList *anIds = vtkIdList::New();
171       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
172         anIds->InsertId(i,theIds[i]);
173
174       myGrid->InsertNextCell(theType,anIds);
175       anIds->Delete();
176
177       myGrid->Modified();
178
179       SetVisibility(true, theActor->GetFacesOriented());
180     }
181
182
183     void SetVisibility (bool theVisibility, bool theShowOrientation = false)
184     {
185       myPreviewActor->SetVisibility(theVisibility);
186       myFaceOrientation->SetVisibility(theShowOrientation);
187       RepaintCurrentView();
188     }
189
190
191     ~TElementSimulation()
192     {
193       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
194         myVTKViewWindow->RemoveActor(myPreviewActor);
195         myVTKViewWindow->RemoveActor(myFaceOrientation);
196       }
197       myPreviewActor->Delete();
198       myFaceOrientation->Delete();
199
200       myMapper->RemoveAllInputs();
201       myMapper->Delete();
202
203       myFaceOrientationFilter->Delete();
204
205       myFaceOrientationDataMapper->RemoveAllInputs();
206       myFaceOrientationDataMapper->Delete();
207
208       myGrid->Delete();
209     }
210   };
211 }
212
213 //=================================================================================
214 // function : SMESHGUI_AddMeshElementDlg()
215 // purpose  : constructor
216 //=================================================================================
217 SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI*          theModule,
218                                                         SMDSAbs_EntityType ElementType)
219   : QDialog( SMESH::GetDesktop( theModule ) ),
220     mySMESHGUI( theModule ),
221     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
222     myBusy ( false )
223 {
224   setModal( false );
225   setAttribute( Qt::WA_DeleteOnClose, true );
226
227   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
228     (SUIT_Session::session()->activeApplication());
229   myIsPoly = false;
230   mySimulation = new SMESH::TElementSimulation (anApp);
231   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
232   myGeomType = ElementType;
233   myElementType = SMDSAbs_Volume;
234
235   // verify nb nodes and type
236   QString elemName;
237   switch ( myGeomType ) {
238   case SMDSEntity_0D:
239     myNbNodes = 1;
240     myElementType = SMDSAbs_0DElement;
241     elemName = "ELEM0D";
242     myHelpFileName = "adding_nodes_and_elements_page.html#adding_0delems_anchor";
243     break;
244   case SMDSEntity_Edge:
245     myNbNodes = 2;
246     myElementType = SMDSAbs_Edge;
247     elemName = "EDGE";
248     myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor";
249     break;
250   case SMDSEntity_Triangle:
251     myNbNodes = 3;
252     elemName = "TRIANGLE";
253     myElementType = SMDSAbs_Face;
254     myHelpFileName = "adding_nodes_and_elements_page.html#adding_triangles_anchor";
255     break;
256   case SMDSEntity_Quadrangle:
257     myNbNodes = 4;
258     myElementType = SMDSAbs_Face;
259     elemName = "QUADRANGLE";
260     myHelpFileName = "adding_nodes_and_elements_page.html#adding_quadrangles_anchor";
261     break;
262   case SMDSEntity_Polygon:
263     myNbNodes = 0;
264     myElementType = SMDSAbs_Face;
265     elemName = "POLYGON";
266     myIsPoly = true;
267     myHelpFileName = "adding_nodes_and_elements_page.html#adding_polygons_anchor";
268     break;
269   case SMDSEntity_Tetra:
270     myNbNodes = 4;
271     elemName = "TETRAS";
272     myHelpFileName = "adding_nodes_and_elements_page.html#adding_tetrahedrons_anchor";
273     break;
274   case SMDSEntity_Pyramid:
275     myNbNodes = 5;
276     elemName = "PYRAMID";
277     myHelpFileName = "adding_nodes_and_elements_page.html#adding_pyramids_anchor";
278     break;
279   case SMDSEntity_Hexa:
280     myNbNodes = 8;
281     elemName = "HEXAS";
282     myHelpFileName = "adding_nodes_and_elements_page.html#adding_hexahedrons_anchor";
283     break;
284   case SMDSEntity_Penta:
285     myNbNodes = 6;
286     elemName = "PENTA";
287     myHelpFileName = "adding_nodes_and_elements_page.html#adding_pentahedrons_anchor";
288     break;
289   case SMDSEntity_Hexagonal_Prism:
290     myNbNodes = 12;
291     elemName = "OCTA";
292     myHelpFileName = "adding_nodes_and_elements_page.html#adding_octahedrons_anchor";
293     break;
294   default:
295     myNbNodes = 2;
296     elemName = "EDGE";
297     myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor";
298   }
299
300   QString iconName      = tr(QString("ICON_DLG_%1").arg(elemName).toLatin1().data());
301   QString buttonGrTitle = tr(QString("SMESH_%1").arg(elemName).toLatin1().data());
302   QString caption       = tr(QString("SMESH_ADD_%1_TITLE").arg(elemName).toLatin1().data());
303   QString grBoxTitle    = tr(QString("SMESH_ADD_%1").arg(elemName).toLatin1().data());
304
305   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
306   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
307
308   setWindowTitle(caption);
309   setSizeGripEnabled(true);
310
311   QVBoxLayout* aTopLayout = new QVBoxLayout(this);
312   aTopLayout->setSpacing(SPACING);
313   aTopLayout->setMargin(MARGIN);
314
315   /***************************************************************/
316   GroupConstructors = new QGroupBox(buttonGrTitle, this);
317   QButtonGroup* ButtonGroup = new QButtonGroup(this);
318   QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
319   GroupConstructorsLayout->setSpacing(SPACING);
320   GroupConstructorsLayout->setMargin(MARGIN);
321
322   Constructor1 = new QRadioButton(GroupConstructors);
323   Constructor1->setIcon(image0);
324   Constructor1->setChecked(true);
325
326   GroupConstructorsLayout->addWidget(Constructor1);
327   ButtonGroup->addButton( Constructor1, 0 );
328
329   /***************************************************************/
330   GroupC1 = new QGroupBox(grBoxTitle, this);
331   QGridLayout* GroupC1Layout = new QGridLayout(GroupC1);
332   GroupC1Layout->setSpacing(SPACING);
333   GroupC1Layout->setMargin(MARGIN);
334
335   TextLabelC1A1 = new QLabel(tr("SMESH_ID_NODES"), GroupC1);
336   SelectButtonC1A1 = new QPushButton(GroupC1);
337   SelectButtonC1A1->setIcon(image1);
338   LineEditC1A1 = new QLineEdit(GroupC1);
339   LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this, myIsPoly ? 1000 : myNbNodes));
340
341   Reverse = (myElementType == SMDSAbs_Face || myElementType == SMDSAbs_Volume ) ? new QCheckBox(tr("SMESH_REVERSE"), GroupC1) : 0;
342
343   GroupC1Layout->addWidget(TextLabelC1A1,    0, 0);
344   GroupC1Layout->addWidget(SelectButtonC1A1, 0, 1);
345   GroupC1Layout->addWidget(LineEditC1A1,     0, 2);
346   if ( Reverse ) GroupC1Layout->addWidget(Reverse, 1, 0, 1, 3);
347
348   /***************************************************************/
349   GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
350   GroupGroups->setCheckable( true );
351   QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
352   GroupGroupsLayout->setSpacing(SPACING);
353   GroupGroupsLayout->setMargin(MARGIN);
354
355   TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
356   ComboBox_GroupName = new QComboBox( GroupGroups );
357   ComboBox_GroupName->setEditable( true );
358   ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
359
360   GroupGroupsLayout->addWidget( TextLabel_GroupName );
361   GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
362
363   /***************************************************************/
364   GroupButtons = new QGroupBox(this);
365   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
366   GroupButtonsLayout->setSpacing(SPACING);
367   GroupButtonsLayout->setMargin(MARGIN);
368
369   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
370   buttonOk->setAutoDefault(true);
371   buttonOk->setDefault(true);
372   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
373   buttonApply->setAutoDefault(true);
374   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
375   buttonCancel->setAutoDefault(true);
376   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
377   buttonHelp->setAutoDefault(true);
378
379   GroupButtonsLayout->addWidget(buttonOk);
380   GroupButtonsLayout->addSpacing(10);
381   GroupButtonsLayout->addWidget(buttonApply);
382   GroupButtonsLayout->addSpacing(10);
383   GroupButtonsLayout->addStretch();
384   GroupButtonsLayout->addWidget(buttonCancel);
385   GroupButtonsLayout->addWidget(buttonHelp);
386
387   /***************************************************************/
388   aTopLayout->addWidget(GroupConstructors);
389   aTopLayout->addWidget(GroupC1);
390   aTopLayout->addWidget(GroupGroups);
391   aTopLayout->addWidget(GroupButtons);
392
393   Init(); /* Initialisations */
394 }
395
396 //=================================================================================
397 // function : ~SMESHGUI_AddMeshElementDlg()
398 // purpose  : Destroys the object and frees any allocated resources
399 //=================================================================================
400 SMESHGUI_AddMeshElementDlg::~SMESHGUI_AddMeshElementDlg()
401 {
402   delete mySimulation;
403 }
404
405 //=================================================================================
406 // function : Init()
407 // purpose  :
408 //=================================================================================
409 void SMESHGUI_AddMeshElementDlg::Init()
410 {
411   GroupC1->show();
412   Constructor1->setChecked(true);
413   myEditCurrentArgument = LineEditC1A1;
414   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
415
416   /* reset "Add to group" control */
417   GroupGroups->setChecked( false );
418   GroupGroups->setVisible( myElementType != SMDSAbs_0DElement );
419
420   myNbOkNodes = 0;
421   myActor = 0;
422
423   /* signals and slots connections */
424   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
425   connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel()));
426   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
427   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
428
429   connect(SelectButtonC1A1, SIGNAL(clicked()), SLOT(SetEditCurrentArgument()));
430   connect(LineEditC1A1, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
431   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
432   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
433   /* to close dialog if study frame change */
434   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
435   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));    
436
437   if (Reverse)
438     connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int)));
439
440   // set selection mode
441   SMESH::SetPointRepresentation(true);
442
443   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
444     aViewWindow->SetSelectionMode( NodeSelection );
445
446   myBusy = false;
447
448   SelectionIntoArgument();
449 }
450
451 //=================================================================================
452 // function : ClickOnApply()
453 // purpose  :
454 //=================================================================================
455 void SMESHGUI_AddMeshElementDlg::ClickOnApply()
456 {
457   if( !isValid() )
458     return;
459
460   if (myNbOkNodes && !mySMESHGUI->isActiveStudyLocked()) {
461     myBusy = true;
462     SMESH::long_array_var anArrayOfIndices = new SMESH::long_array;
463     anArrayOfIndices->length(myNbNodes);
464     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
465     const std::vector<int>& revIndex = SMDS_MeshCell::reverseSmdsOrder( myGeomType );
466     if ( Reverse && Reverse->isChecked() && !revIndex.empty() )
467       for (int i = 0; i < aListId.count(); i++)
468         anArrayOfIndices[i] = aListId[ revIndex[i] ].toInt();
469     else if ( Reverse && Reverse->isChecked() && revIndex.empty() ) // polygon
470       for (int i = 0; i < aListId.count(); i++)
471         anArrayOfIndices[i] = aListId[ aListId.count()-1 - i ].toInt();
472     else
473       for (int i = 0; i < aListId.count(); i++)
474         anArrayOfIndices[i] = aListId[ i ].toInt();
475
476     bool addToGroup = GroupGroups->isChecked();
477     QString aGroupName;
478
479     SMESH::SMESH_GroupBase_var aGroup;
480     int idx = 0;
481     if( addToGroup ) {
482       aGroupName = ComboBox_GroupName->currentText();
483       for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
484         QString aName = ComboBox_GroupName->itemText( i );
485         if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
486           idx = i;
487       }
488       if ( idx > 0 && idx < myGroups.count() ) {
489         SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
490         if ( !aGeomGroup->_is_nil() ) {
491           int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
492                                                tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
493                                                tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
494           if ( res == 1 ) return;
495         }
496         aGroup = myGroups[idx-1];
497       }
498     }
499
500     long anElemId = -1;
501     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
502     switch (myElementType) {
503     case SMDSAbs_0DElement:
504       anElemId = aMeshEditor->Add0DElement(anArrayOfIndices[0]); break;
505     case SMDSAbs_Edge:
506       anElemId = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
507     case SMDSAbs_Face:
508       if ( myIsPoly )
509         anElemId = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
510       else
511         anElemId = aMeshEditor->AddFace(anArrayOfIndices.inout());
512       break;
513     default:
514       anElemId = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
515     }
516
517     if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
518       SMESH::SMESH_Group_var aGroupUsed;
519       if ( aGroup->_is_nil() ) {
520         // create new group 
521         aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName );
522         if ( !aGroupUsed->_is_nil() ) {
523           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
524           ComboBox_GroupName->addItem( aGroupName );
525         }
526       }
527       else {
528         SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
529         if ( !aGeomGroup->_is_nil() ) {
530           aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
531           if ( !aGroupUsed->_is_nil() && idx > 0 ) {
532             myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
533             SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
534           }
535         }
536         else
537           aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
538       }
539
540       if ( !aGroupUsed->_is_nil() ) {
541         SMESH::long_array_var anIdList = new SMESH::long_array;
542         anIdList->length( 1 );
543         anIdList[0] = anElemId;
544         aGroupUsed->Add( anIdList.inout() );
545       }
546     }
547
548     SALOME_ListIO aList; aList.Append( myActor->getIO() );
549     mySelector->ClearIndex();
550     mySelectionMgr->setSelectedObjects( aList, false );
551
552     SMESH::UpdateView();
553     mySimulation->SetVisibility(false);
554
555     buttonOk->setEnabled(false);
556     buttonApply->setEnabled(false);
557
558     myEditCurrentArgument->setText("");
559
560     myBusy = false;
561
562     SMESHGUI::Modified();
563   }
564 }
565
566 //=================================================================================
567 // function : ClickOnOk()
568 // purpose  :
569 //=================================================================================
570 void SMESHGUI_AddMeshElementDlg::ClickOnOk()
571 {
572   ClickOnApply();
573   ClickOnCancel();
574 }
575
576 //=================================================================================
577 // function : ClickOnCancel()
578 // purpose  :
579 //=================================================================================
580 void SMESHGUI_AddMeshElementDlg::ClickOnCancel()
581 {
582   //mySelectionMgr->clearSelected();
583   mySimulation->SetVisibility(false);
584   SMESH::SetPointRepresentation(false);
585   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
586     aViewWindow->SetSelectionMode( ActorSelection );
587   disconnect(mySelectionMgr, 0, this, 0);
588   mySMESHGUI->ResetState();
589   reject();
590 }
591
592 //=================================================================================
593 // function : ClickOnHelp()
594 // purpose  :
595 //=================================================================================
596 void SMESHGUI_AddMeshElementDlg::ClickOnHelp()
597 {
598   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
599   if (app)
600     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""),
601                              myHelpFileName);
602   else {
603     QString platform;
604 #ifdef WIN32
605     platform = "winapplication";
606 #else
607     platform = "application";
608 #endif
609     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
610                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
611                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
612                                                                  platform)).
613                              arg(myHelpFileName));
614   }
615 }
616
617 //=================================================================================
618 // function : onTextChange()
619 // purpose  :
620 //=================================================================================
621 void SMESHGUI_AddMeshElementDlg::onTextChange (const QString& theNewText)
622 {
623   if (myBusy) return;
624   myBusy = true;
625
626   myNbOkNodes = 0;
627
628   buttonOk->setEnabled(false);
629   buttonApply->setEnabled(false);
630
631   mySimulation->SetVisibility(false);
632
633   // hilight entered nodes
634   SMDS_Mesh* aMesh = 0;
635   if (myActor)
636     aMesh = myActor->GetObject()->GetMesh();
637
638   if (aMesh) {
639     TColStd_MapOfInteger newIndices;
640
641     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
642     bool allOk = true;
643     for (int i = 0; i < aListId.count(); i++) {
644       if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
645         {
646           newIndices.Add( n->GetID() );
647           myNbOkNodes++;
648         }
649       else
650         allOk = false;  
651     }
652
653     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
654     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
655       aViewWindow->highlight( myActor->getIO(), true, true );
656
657     myNbOkNodes = ( allOk && myNbNodes == aListId.count() );
658
659     if (myIsPoly)
660       {
661         if ( !allOk || myElementType != SMDSAbs_Face || aListId.count() < 3 )
662           myNbOkNodes = 0;
663         else
664           myNbOkNodes = aListId.count();
665       }
666   }
667
668   if(myNbOkNodes) {
669     buttonOk->setEnabled(true);
670     buttonApply->setEnabled(true);
671     displaySimulation();
672   }
673
674   myBusy = false;
675 }
676
677 //=================================================================================
678 // function : SelectionIntoArgument()
679 // purpose  : Called when selection has changed
680 //=================================================================================
681 void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument()
682 {
683   if (myBusy) return;
684
685   // clear
686   myNbOkNodes = 0;
687   myActor = 0;
688
689   myBusy = true;
690   myEditCurrentArgument->setText("");
691   myBusy = false;
692
693   if (!GroupButtons->isEnabled()) // inactive
694     return;
695
696   buttonOk->setEnabled(false);
697   buttonApply->setEnabled(false);
698
699   mySimulation->SetVisibility(false);
700   //  SMESH::SetPointRepresentation(true);
701
702   QString aCurrentEntry = myEntry;
703
704   // get selected mesh
705   SALOME_ListIO aList;
706   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
707
708   if (aList.Extent() != 1)
709     return;
710
711   Handle(SALOME_InteractiveObject) anIO = aList.First();
712   myEntry = anIO->getEntry();
713   myMesh = SMESH::GetMeshByIO(anIO);
714   if (myMesh->_is_nil())
715     return;
716
717   // process groups
718   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
719     myGroups.clear();
720     ComboBox_GroupName->clear();
721     ComboBox_GroupName->addItem( QString() );
722     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
723     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
724       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
725       if ( !aGroup->_is_nil() && aGroup->GetType() == (SMESH::ElementType)myElementType ) {
726         QString aGroupName( aGroup->GetName() );
727         if ( !aGroupName.isEmpty() ) {
728           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
729           ComboBox_GroupName->addItem( aGroupName );
730         }
731       }
732     }
733   }
734
735   myActor = SMESH::FindActorByEntry(anIO->getEntry());
736   if (!myActor)
737     return;
738
739   // get selected nodes
740   QString aString = "";
741   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
742   myBusy = true;
743   myEditCurrentArgument->setText(aString);
744   myBusy = false;
745   if (myIsPoly && myElementType == SMDSAbs_Face && nbNodes >= 3 ) {
746     myNbNodes = nbNodes;
747   } else if (myNbNodes != nbNodes) {
748     return;
749   }
750
751   // OK
752   myNbOkNodes = nbNodes;
753
754   buttonOk->setEnabled(true);
755   buttonApply->setEnabled(true);
756
757   displaySimulation();
758 }
759
760 //=================================================================================
761 // function : displaySimulation()
762 // purpose  :
763 //=================================================================================
764 void SMESHGUI_AddMeshElementDlg::displaySimulation()
765 {
766   if (myNbOkNodes && GroupButtons->isEnabled()) {
767     SMESH::TElementSimulation::TVTKIds anIds;
768     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
769     for (int i = 0; i < aListId.count(); i++)
770       anIds.push_back(myActor->GetObject()->GetNodeVTKId(aListId[ i ].toInt()));
771
772     if (Reverse && Reverse->isChecked())
773     {
774       const std::vector<int>& i = SMDS_MeshCell::reverseSmdsOrder( myGeomType );
775       if ( i.empty() ) // polygon
776         std::reverse( anIds.begin(), anIds.end() );
777       else
778         SMDS_MeshCell::applyInterlace( i, anIds );
779     }
780
781     vtkIdType aType = SMDS_MeshCell::toVtkType( myGeomType );
782     mySimulation->SetPosition(myActor,aType,anIds);
783     SMESH::UpdateView();
784   }
785 }
786
787 //=================================================================================
788 // function : SetEditCurrentArgument()
789 // purpose  :
790 //=================================================================================
791 void SMESHGUI_AddMeshElementDlg::SetEditCurrentArgument()
792 {
793   QPushButton* send = (QPushButton*)sender();
794   if (send == SelectButtonC1A1) {
795     LineEditC1A1->setFocus();
796     myEditCurrentArgument = LineEditC1A1;
797   }
798   SelectionIntoArgument();
799 }
800
801 //=================================================================================
802 // function : DeactivateActiveDialog()
803 // purpose  :
804 //=================================================================================
805 void SMESHGUI_AddMeshElementDlg::DeactivateActiveDialog()
806 {
807   if (GroupConstructors->isEnabled()) {
808     GroupConstructors->setEnabled(false);
809     GroupC1->setEnabled(false);
810     GroupButtons->setEnabled(false);
811     mySimulation->SetVisibility(false);
812     mySMESHGUI->ResetState();
813     mySMESHGUI->SetActiveDialogBox(0);
814   }
815 }
816
817 //=================================================================================
818 // function : ActivateThisDialog()
819 // purpose  :
820 //=================================================================================
821 void SMESHGUI_AddMeshElementDlg::ActivateThisDialog()
822 {
823   /* Emit a signal to deactivate the active dialog */
824   mySMESHGUI->EmitSignalDeactivateDialog();
825
826   GroupConstructors->setEnabled(true);
827   GroupC1->setEnabled(true);
828   GroupButtons->setEnabled(true);
829
830   SMESH::SetPointRepresentation(true);
831
832   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
833     aViewWindow->SetSelectionMode( NodeSelection );
834   SelectionIntoArgument();
835 }
836
837 //=================================================================================
838 // function : enterEvent()
839 // purpose  :
840 //=================================================================================
841 void SMESHGUI_AddMeshElementDlg::enterEvent (QEvent*)
842 {
843   if (GroupConstructors->isEnabled())
844     return;
845   ActivateThisDialog();
846 }
847
848 //=================================================================================
849 // function : closeEvent()
850 // purpose  :
851 //=================================================================================
852 void SMESHGUI_AddMeshElementDlg::closeEvent (QCloseEvent*)
853 {
854   /* same than click on cancel button */
855   ClickOnCancel();
856 }
857
858 //=================================================================================
859 // function : hideEvent()
860 // purpose  : caused by ESC key
861 //=================================================================================
862 void SMESHGUI_AddMeshElementDlg::hideEvent (QHideEvent*)
863 {
864   if (!isMinimized())
865     ClickOnCancel();
866 }
867
868 //=================================================================================
869 // function : CheckBox()
870 // purpose  :
871 //=================================================================================
872 void SMESHGUI_AddMeshElementDlg::CheckBox (int state)
873 {
874   if (!myNbOkNodes)
875     return;
876
877   if (state >= 0) {
878     mySimulation->SetVisibility(false);
879     displaySimulation();
880   }
881 }
882
883 //=================================================================================
884 // function : keyPressEvent()
885 // purpose  :
886 //=================================================================================
887 void SMESHGUI_AddMeshElementDlg::keyPressEvent( QKeyEvent* e )
888 {
889   QDialog::keyPressEvent( e );
890   if ( e->isAccepted() )
891     return;
892
893   if ( e->key() == Qt::Key_F1 ) {
894     e->accept();
895     ClickOnHelp();
896   }
897 }
898
899 //=================================================================================
900 // function : isValid
901 // purpose  :
902 //=================================================================================
903 bool SMESHGUI_AddMeshElementDlg::isValid()
904 {
905   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
906     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
907     return false;
908   }
909   return true;
910 }