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