Salome HOME
Fixed Salome crashed after close application with opened "Add Quadratic element"
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddQuadraticElementDlg.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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_AddQuadraticElementDlg.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 includes
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_ViewManager.h>
48
49 #include <LightApp_SelectionMgr.h>
50
51 #include <SVTK_ViewModel.h>
52 #include <SVTK_ViewWindow.h>
53
54 #include <SALOME_ListIO.hxx>
55
56 #include <SalomeApp_Application.h>
57
58 #include <Qtx.h>
59
60 // IDL includes
61 #include <SALOMEconfig.h>
62 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
63
64 // OCCT includes
65 #include <TColStd_MapOfInteger.hxx>
66
67 // VTK includes
68 #include <vtkIdList.h>
69 #include <vtkUnstructuredGrid.h>
70 #include <vtkDataSetMapper.h>
71 #include <vtkPolyDataMapper.h>
72 #include <vtkProperty.h>
73 #include <vtkCellType.h>
74
75 // Qt includes
76 #include <QComboBox>
77 #include <QGroupBox>
78 #include <QLabel>
79 #include <QLineEdit>
80 #include <QPushButton>
81 #include <QRadioButton>
82 #include <QVBoxLayout>
83 #include <QHBoxLayout>
84 #include <QGridLayout>
85 #include <QCheckBox>
86 #include <QTableWidget>
87 #include <QKeyEvent>
88 #include <QButtonGroup>
89
90 // STL includes
91 #include <vector>
92
93 #define SPACING 6
94 #define MARGIN  11
95
96 namespace
97 {
98   void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
99                             bool toReverse, // inverse element
100                             bool toVtkOrder ) // smds connectivity to vtk one
101   {
102     if ( toReverse ) // first reverse smds order
103     {
104       const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type);
105       SMDS_MeshCell::applyInterlace( index, ids );
106     }
107     if ( toVtkOrder ) // from smds to vtk connectivity
108     {
109       const std::vector<int>& index = SMDS_MeshCell::toVtkOrder(type);
110       SMDS_MeshCell::applyInterlace( index, ids );
111     }
112   }
113 }
114 namespace SMESH
115 {
116   class TElementSimulationQuad {
117     SalomeApp_Application* myApplication;
118     SUIT_ViewWindow* myViewWindow;
119     SVTK_ViewWindow* myVTKViewWindow;
120
121     SALOME_Actor* myPreviewActor;
122     vtkDataSetMapper* myMapper;
123     vtkUnstructuredGrid* myGrid;
124     //vtkProperty* myBackProp, *myProp;
125
126     //double myRGB[3], myBackRGB[3];
127
128     SALOME_Actor* myFaceOrientation;
129     vtkPolyDataMapper* myFaceOrientationDataMapper;
130     SMESH_FaceOrientationFilter* myFaceOrientationFilter;
131
132   public:
133     TElementSimulationQuad (SalomeApp_Application* theApplication)
134     {
135       myApplication = theApplication;
136       SUIT_ViewManager* mgr = theApplication->activeViewManager();
137       if (!mgr) return;
138       myViewWindow = mgr->getActiveView();
139       myVTKViewWindow = GetVtkViewWindow(myViewWindow);
140
141       myGrid = vtkUnstructuredGrid::New();
142
143       // Create and display actor
144       myMapper = vtkDataSetMapper::New();
145       myMapper->SetInputData(myGrid);
146
147       myPreviewActor = SALOME_Actor::New();
148       myPreviewActor->PickableOff();
149       myPreviewActor->VisibilityOff();
150       myPreviewActor->SetMapper(myMapper);
151       
152       QColor ffc, bfc;
153       int delta;
154       vtkProperty* myProp = vtkProperty::New();
155       SMESH::GetColor( "SMESH", "preview_color", ffc, delta, "0, 255, 0|-100" ) ;
156    
157       myProp->SetColor( ffc.red() / 255. , ffc.green() / 255. , ffc.blue() / 255. );
158       myPreviewActor->SetProperty( myProp );
159       myProp->Delete();
160
161       vtkProperty* myBackProp = vtkProperty::New();
162       bfc = Qtx::mainColorToSecondary(ffc, delta);
163       myBackProp->SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. );
164       myPreviewActor->SetBackfaceProperty( myBackProp );
165       myBackProp->Delete();
166
167       myVTKViewWindow->AddActor(myPreviewActor);
168
169       // Orientation of faces
170       myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
171       myFaceOrientationFilter->SetInputData(myGrid);
172
173       myFaceOrientationDataMapper = vtkPolyDataMapper::New();
174       myFaceOrientationDataMapper->SetInputConnection(myFaceOrientationFilter->GetOutputPort());
175
176       myFaceOrientation = SALOME_Actor::New();
177       myFaceOrientation->PickableOff();
178       myFaceOrientation->VisibilityOff();
179       myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
180
181       vtkProperty* anOrientationProp = vtkProperty::New();
182       double aRGB[3];
183       GetColor( "SMESH", "orientation_color", aRGB[0], aRGB[1], aRGB[2], QColor( 255, 255, 255 ) );
184       anOrientationProp->SetColor( aRGB[0], aRGB[1], aRGB[2] );
185       myFaceOrientation->SetProperty( anOrientationProp );
186       anOrientationProp->Delete();
187
188       myVTKViewWindow->AddActor(myFaceOrientation);
189     }
190
191     typedef std::vector<vtkIdType> TVTKIds;
192     void SetPosition (SMESH_Actor*       theActor,
193                       SMDSAbs_EntityType theType,
194                       TVTKIds&           theIds,
195                       const int          theMode,
196                       const bool         theReverse)
197     {
198       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
199       myGrid->SetPoints(aGrid->GetPoints());
200
201       //add points
202
203       ReverseConnectivity( theIds, theType, theReverse, /*toVtkOrder=*/true);
204
205       myGrid->Reset();
206       vtkIdList *anIds = vtkIdList::New();
207
208       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
209         anIds->InsertId(i,theIds[i]);
210         //std::cout << i<< ": " << theIds[i] << std::endl;
211       }
212
213       vtkIdType aType = SMDS_MeshCell::toVtkType(theType);
214       myGrid->InsertNextCell(aType,anIds);
215       anIds->Delete();
216
217       myGrid->Modified();
218
219       myPreviewActor->GetMapper()->Update();
220       myPreviewActor->SetRepresentation( theMode );
221       SetVisibility(true, theActor->GetFacesOriented());
222     }
223
224
225     void SetVisibility (bool theVisibility, bool theShowOrientation = false)
226     {
227       myPreviewActor->SetVisibility(theVisibility);
228       myFaceOrientation->SetVisibility(theShowOrientation);
229       RepaintCurrentView();
230     }
231
232
233     ~TElementSimulationQuad()
234     {
235       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
236         myVTKViewWindow->RemoveActor(myPreviewActor);
237         myVTKViewWindow->RemoveActor(myFaceOrientation);
238       }
239       myPreviewActor->Delete();
240       myFaceOrientation->Delete();
241
242       myMapper->RemoveAllInputs();
243       myMapper->Delete();
244
245       myFaceOrientationFilter->Delete();
246
247       myFaceOrientationDataMapper->RemoveAllInputs();
248       myFaceOrientationDataMapper->Delete();
249
250       myGrid->Delete();
251
252 //       myProp->Delete();
253 //       myBackProp->Delete();
254     }
255   };
256 }
257
258
259 // Define the sequences of ids
260 static int FirstEdgeIds[] = {0};
261 static int LastEdgeIds[] =  {1};
262
263 static int FirstTriangleIds[] = {0,1,2};
264 static int LastTriangleIds[] =  {1,2,0};
265
266 static int FirstQuadrangleIds[] = {0,1,2,3};
267 static int LastQuadrangleIds[] =  {1,2,3,0};
268
269 static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
270 static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
271
272 static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
273 static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
274
275 static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
276 static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
277
278 static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
279 static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
280
281 /*!
282   \class BusyLocker
283   \brief Simple 'busy state' flag locker.
284   \internal
285 */
286 class BusyLocker
287 {
288 public:
289   //! Constructor. Sets passed boolean flag to \c true.
290   BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
291   //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
292   ~BusyLocker() { myBusy = false; }
293 private:
294   bool& myBusy; //! External 'busy state' boolean flag
295 };
296
297 /*!
298   \class IdEditItem
299   \brief Simple editable table item.
300   \internal
301 */
302 class IdEditItem: public QTableWidgetItem
303 {
304 public:
305   IdEditItem(const QString& text );
306   ~IdEditItem();
307
308   QWidget* createEditor() const;
309 };
310
311 IdEditItem::IdEditItem(const QString& text )
312   : QTableWidgetItem(text, QTableWidgetItem::UserType+100)
313 {
314 }
315
316 IdEditItem::~IdEditItem()
317 {
318 }
319
320 QWidget* IdEditItem::createEditor() const
321 {
322   QLineEdit *aLineEdit = new QLineEdit(text(), tableWidget());
323   aLineEdit->setValidator( new SMESHGUI_IdValidator(tableWidget(), 1) );
324   return aLineEdit;
325 }
326
327 //=================================================================================
328 // function : SMESHGUI_AddQuadraticElementDlg()
329 // purpose  : constructor
330 //=================================================================================
331
332 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
333                                                                   const SMDSAbs_EntityType theType )
334   : QDialog( SMESH::GetDesktop( theModule ) ),
335     mySMESHGUI( theModule ),
336     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
337     myGeomType( theType ),
338     //myType( theType ),
339     myBusy( false )
340 {
341   setModal( false );
342   setAttribute( Qt::WA_DeleteOnClose, true );
343
344   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
345     (SUIT_Session::session()->activeApplication());
346
347   mySimulation = new SMESH::TElementSimulationQuad (anApp);
348   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
349
350   QString anElementName;
351
352   switch ( myGeomType ) {
353   case SMDSEntity_Quad_Edge:
354     anElementName = QString("QUADRATIC_EDGE");
355     break;
356   case SMDSEntity_Quad_Triangle:
357     anElementName = QString("QUADRATIC_TRIANGLE");
358     break;
359   case SMDSEntity_Quad_Quadrangle:
360     anElementName = QString("QUADRATIC_QUADRANGLE");
361     break;
362   case SMDSEntity_BiQuad_Quadrangle:
363     anElementName = QString("BIQUADRATIC_QUADRANGLE");
364     break;
365   case SMDSEntity_BiQuad_Triangle:
366     anElementName = QString("BIQUADRATIC_TRIANGLE");
367     break;
368   case SMDSEntity_Quad_Tetra:
369     anElementName = QString("QUADRATIC_TETRAHEDRON");
370     break;
371   case SMDSEntity_Quad_Pyramid:
372     anElementName = QString("QUADRATIC_PYRAMID");
373     break;
374   case SMDSEntity_Quad_Penta:
375     anElementName = QString("QUADRATIC_PENTAHEDRON");
376     break;
377   case SMDSEntity_Quad_Hexa:
378     anElementName = QString("QUADRATIC_HEXAHEDRON");
379     break;
380   case SMDSEntity_TriQuad_Hexa:
381     anElementName = QString("TRIQUADRATIC_HEXAHEDRON");
382     break;
383   default:
384     myGeomType = SMDSEntity_Quad_Edge;
385     anElementName = QString("QUADRATIC_EDGE");
386   }
387
388   QString iconName           = tr(QString("ICON_DLG_%1").arg(anElementName).toLatin1().data());
389   QString caption            = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
390   QString argumentsGrTitle   = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
391   QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
392
393   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
394   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
395
396   setWindowTitle(caption);
397
398   setSizeGripEnabled(true);
399
400   QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
401   aDialogLayout->setSpacing(SPACING);
402   aDialogLayout->setMargin(MARGIN);
403
404   /***************************************************************/
405   GroupConstructors = new QGroupBox(constructorGrTitle, this);
406   QButtonGroup* ButtonGroup = new QButtonGroup(this);
407   QHBoxLayout* aGroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
408   aGroupConstructorsLayout->setSpacing(SPACING);
409   aGroupConstructorsLayout->setMargin(MARGIN);
410
411   myRadioButton1 = new QRadioButton(GroupConstructors);
412   myRadioButton1->setIcon(image0);
413   aGroupConstructorsLayout->addWidget(myRadioButton1);
414   ButtonGroup->addButton(myRadioButton1, 0);
415
416   /***************************************************************/
417   GroupArguments = new QGroupBox(argumentsGrTitle, this);
418   QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments);
419   aGroupArgumentsLayout->setSpacing(SPACING);
420   aGroupArgumentsLayout->setMargin(MARGIN);
421
422   // Corner nodes
423   QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
424   myCornerSelectButton = new QPushButton(GroupArguments);
425   myCornerSelectButton->setIcon(image1);
426   myCornerNodes = new QLineEdit(GroupArguments);
427
428   // Mid-edge nodes
429   myTable = new QTableWidget(GroupArguments);
430
431   // Mid-face nodes
432   myMidFaceLabel = new QLabel(tr("SMESH_MIDFACE_NODES"), GroupArguments);
433   myMidFaceSelectButton = new QPushButton(GroupArguments);
434   myMidFaceSelectButton->setIcon(image1);
435   myMidFaceNodes = new QLineEdit(GroupArguments);
436   myMidFaceNodes->setValidator(new SMESHGUI_IdValidator(this, 6));
437
438   // Central node
439   myCenterLabel = new QLabel(tr("SMESH_CENTER_NODE"), GroupArguments);
440   myCenterSelectButton = new QPushButton(GroupArguments);
441   myCenterSelectButton->setIcon(image1);
442   myCenterNode = new QLineEdit(GroupArguments);
443   myCenterNode->setValidator(new SMESHGUI_IdValidator(this, 1));
444
445   myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
446
447   aGroupArgumentsLayout->addWidget(aCornerNodesLabel,     0, 0);
448   aGroupArgumentsLayout->addWidget(myCornerSelectButton,  0, 1);
449   aGroupArgumentsLayout->addWidget(myCornerNodes,         0, 2);
450   aGroupArgumentsLayout->addWidget(myTable,               1, 0, 1, 3);
451   aGroupArgumentsLayout->addWidget(myMidFaceLabel,        2, 0);
452   aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 2, 1);
453   aGroupArgumentsLayout->addWidget(myMidFaceNodes,        2, 2);
454   aGroupArgumentsLayout->addWidget(myCenterLabel,         3, 0);
455   aGroupArgumentsLayout->addWidget(myCenterSelectButton,  3, 1);
456   aGroupArgumentsLayout->addWidget(myCenterNode,          3, 2);
457   aGroupArgumentsLayout->addWidget(myReverseCB,           4, 0, 1, 3);
458
459     /***************************************************************/
460   GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
461   GroupGroups->setCheckable( true );
462   QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
463   GroupGroupsLayout->setSpacing(SPACING);
464   GroupGroupsLayout->setMargin(MARGIN);
465
466   TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
467   ComboBox_GroupName = new QComboBox( GroupGroups );
468   ComboBox_GroupName->setEditable( true );
469   ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
470
471   GroupGroupsLayout->addWidget( TextLabel_GroupName );
472   GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
473
474   /***************************************************************/
475   GroupButtons = new QGroupBox(this);
476   QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
477   aGroupButtonsLayout->setSpacing(SPACING);
478   aGroupButtonsLayout->setMargin(MARGIN);
479
480   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
481   buttonOk->setAutoDefault(true);
482   buttonOk->setDefault(true);
483   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
484   buttonApply->setAutoDefault(true);
485   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
486   buttonCancel->setAutoDefault(true);
487   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
488   buttonHelp->setAutoDefault(true);
489
490   aGroupButtonsLayout->addWidget(buttonOk);
491   aGroupButtonsLayout->addSpacing(10);
492   aGroupButtonsLayout->addWidget(buttonApply);
493   aGroupButtonsLayout->addSpacing(10);
494   aGroupButtonsLayout->addStretch();
495   aGroupButtonsLayout->addWidget(buttonCancel);
496   aGroupButtonsLayout->addWidget(buttonHelp);
497
498   /***************************************************************/
499   aDialogLayout->addWidget(GroupConstructors);
500   aDialogLayout->addWidget(GroupArguments);
501   aDialogLayout->addWidget(GroupGroups);
502   aDialogLayout->addWidget(GroupButtons);
503
504   Init(); /* Initialisations */
505 }
506
507 //=================================================================================
508 // function : ~SMESHGUI_AddQuadraticElementDlg()
509 // purpose  : Destroys the object and frees any allocated resources
510 //=================================================================================
511
512 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
513 {
514   delete mySimulation;
515 }
516
517 //=================================================================================
518 // function : Init()
519 // purpose  :
520 //=================================================================================
521
522 void SMESHGUI_AddQuadraticElementDlg::Init()
523 {
524   myRadioButton1->setChecked(true);
525   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
526
527   /* reset "Add to group" control */
528   GroupGroups->setChecked( false );
529
530   myActor = 0;
531   myNbMidFaceNodes = 0;
532   myNbCenterNodes = 0;
533
534   int aNumRows;
535
536   switch (myGeomType) {
537   case SMDSEntity_Quad_Edge:
538     aNumRows = 1;
539     myNbCorners = 2;
540     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges
541     break;
542   case SMDSEntity_Quad_Triangle:
543     aNumRows = 3;
544     myNbCorners = 3;
545     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
546     break;
547   case SMDSEntity_BiQuad_Triangle:
548     aNumRows = 3;
549     myNbCorners = 3;
550     myNbCenterNodes = 1;
551     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
552     break;
553   case SMDSEntity_Quad_Quadrangle:
554     aNumRows = 4;
555     myNbCorners = 4;
556     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
557     break;
558   case SMDSEntity_BiQuad_Quadrangle:
559     aNumRows = 4;
560     myNbCorners = 4;
561     myNbCenterNodes = 1;
562     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
563     break;
564   case SMDSEntity_Quad_Tetra:
565     aNumRows = 6;
566     myNbCorners = 4;
567     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons
568     break;
569   case SMDSEntity_Quad_Pyramid:
570     aNumRows = 8;
571     myNbCorners = 5;
572     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids
573     break;
574   case SMDSEntity_Quad_Penta:
575     aNumRows = 9;
576     myNbCorners = 6;
577     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
578     break;
579   case SMDSEntity_Quad_Hexa:
580     aNumRows = 12;
581     myNbCorners = 8;
582     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
583     break;
584   case SMDSEntity_TriQuad_Hexa:
585     aNumRows = 12;
586     myNbCorners = 8;
587     myNbMidFaceNodes = 6;
588     myNbCenterNodes = 1;
589     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
590     break;
591   }
592
593   myMidFaceLabel       ->setVisible( myNbMidFaceNodes );
594   myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
595   myMidFaceNodes       ->setVisible( myNbMidFaceNodes );
596   myCenterLabel        ->setVisible( myNbCenterNodes );
597   myCenterSelectButton ->setVisible( myNbCenterNodes );
598   myCenterNode         ->setVisible( myNbCenterNodes );
599
600   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
601
602   /* initialize table */
603   myTable->setColumnCount(3);
604   myTable->setRowCount(aNumRows);
605
606   QStringList aColLabels;
607   aColLabels.append(tr("SMESH_FIRST"));
608   aColLabels.append(tr("SMESH_MIDDLE"));
609   aColLabels.append(tr("SMESH_LAST"));
610   myTable->setHorizontalHeaderLabels(aColLabels);
611
612   for ( int col = 0; col < myTable->columnCount(); col++ )
613     myTable->setColumnWidth(col, 80);
614
615   //myTable->setColumnReadOnly(0, true); // VSR: TODO
616   //myTable->setColumnReadOnly(2, true); // VSR: TODO
617
618   myTable->setEnabled( false );
619
620   for ( int row = 0; row < myTable->rowCount(); row++ )
621   {
622     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
623     myTable->item( row, 0 )->setFlags(0);
624
625     IdEditItem* anEditItem = new IdEditItem( "" );
626     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
627     myTable->setItem(row, 1, anEditItem);
628
629     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
630     myTable->item( row, 2 )->setFlags(0);
631   }
632
633   /* signals and slots connections */
634   connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
635   connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
636   connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
637   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
638   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
639   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
640   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
641   connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
642   connect(myCenterNode,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
643   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
644
645   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
646   connect(buttonCancel, SIGNAL(clicked()), SLOT(reject()));
647   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
648   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
649
650   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
651   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
652   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
653
654   myCurrentLineEdit = myCornerNodes;
655
656   // set selection mode
657   SMESH::SetPointRepresentation(true);
658
659   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
660     aViewWindow->SetSelectionMode( NodeSelection );
661
662   SelectionIntoArgument();
663 }
664
665 //=================================================================================
666 // function : ClickOnApply()
667 // purpose  :
668 //=================================================================================
669
670 bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
671 {
672   if( !isValid() )
673     return false;
674
675   if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
676     return false;
677
678   BusyLocker lock( myBusy );
679
680   std::vector<vtkIdType> anIds;
681
682   switch (myGeomType) {
683   case SMDSEntity_Quad_Edge:
684     anIds.push_back(myTable->item(0, 0)->text().toInt());
685     anIds.push_back(myTable->item(0, 2)->text().toInt());
686     anIds.push_back(myTable->item(0, 1)->text().toInt());
687     break;
688   case SMDSEntity_Quad_Triangle:
689   case SMDSEntity_Quad_Quadrangle:
690   case SMDSEntity_BiQuad_Triangle:
691   case SMDSEntity_BiQuad_Quadrangle:
692   case SMDSEntity_Quad_Tetra:
693   case SMDSEntity_Quad_Pyramid:
694   case SMDSEntity_Quad_Penta:
695   case SMDSEntity_Quad_Hexa:
696   case SMDSEntity_TriQuad_Hexa:
697     for ( int row = 0; row < myNbCorners; row++ )
698       anIds.push_back(myTable->item(row, 0)->text().toInt());
699     for ( int row = 0; row < myTable->rowCount(); row++ )
700       anIds.push_back(myTable->item(row, 1)->text().toInt());
701     if ( myNbMidFaceNodes )
702     {
703       QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
704       for (int i = 0; i < aListId.count(); i++)
705         anIds.push_back( aListId[ i ].toInt() );
706     }
707     if ( myNbCenterNodes )
708     {
709       QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
710       anIds.push_back( aListId[ 0 ].toInt() );
711     }
712     break;
713   }
714   if ( myReverseCB->isChecked())
715     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
716
717   int aNumberOfIds =  anIds.size();
718   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
719   anArrayOfIdeces->length( aNumberOfIds );
720
721   for (int i = 0; i < aNumberOfIds; i++)
722     anArrayOfIdeces[i] = anIds[ i ];
723
724   bool addToGroup = GroupGroups->isChecked();
725   QString aGroupName;
726
727   SMESH::SMESH_GroupBase_var aGroup;
728   int idx = 0;
729   if( addToGroup ) {
730     aGroupName = ComboBox_GroupName->currentText();
731     for ( int i = 1; i <= ComboBox_GroupName->count(); i++ ) {
732       QString aName = ComboBox_GroupName->itemText( i );
733       if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
734         idx = i;
735     }
736     if ( idx > 0 && idx <= myGroups.count() ) {
737       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
738       if ( !aGeomGroup->_is_nil() ) {
739         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
740                                              tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
741                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
742         if ( res == 1 ) return false;
743       }
744       aGroup = myGroups[idx-1];
745     }
746   }
747
748   SMESH::ElementType anElementType;
749   long anElemId = -1;
750   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
751   switch (myGeomType) {
752   case SMDSEntity_Quad_Edge:
753     anElementType = SMESH::EDGE;
754     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
755   case SMDSEntity_Quad_Triangle:
756   case SMDSEntity_Quad_Quadrangle:
757   case SMDSEntity_BiQuad_Triangle:
758   case SMDSEntity_BiQuad_Quadrangle:
759     anElementType = SMESH::FACE;
760     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
761   case SMDSEntity_Quad_Tetra:
762   case SMDSEntity_Quad_Pyramid:
763   case SMDSEntity_Quad_Penta:
764   case SMDSEntity_Quad_Hexa:
765   case SMDSEntity_TriQuad_Hexa:
766     anElementType = SMESH::VOLUME;
767     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
768   default: break;
769   }
770
771   if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
772     SMESH::SMESH_Group_var aGroupUsed;
773     if ( aGroup->_is_nil() ) {
774       // create new group
775       aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
776       if ( !aGroupUsed->_is_nil() ) {
777         myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
778         ComboBox_GroupName->addItem( aGroupName );
779       }
780     }
781     else {
782       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
783       if ( !aGeomGroup->_is_nil() ) {
784         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
785         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
786           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
787           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
788         }
789       }
790       else
791         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
792     }
793
794     if ( !aGroupUsed->_is_nil() ) {
795       SMESH::long_array_var anIdList = new SMESH::long_array;
796       anIdList->length( 1 );
797       anIdList[0] = anElemId;
798       aGroupUsed->Add( anIdList.inout() );
799     }
800   }
801
802   SALOME_ListIO aList; aList.Append( myActor->getIO() );
803   mySelector->ClearIndex();
804   mySelectionMgr->setSelectedObjects( aList, false );
805
806   mySimulation->SetVisibility(false);
807   SMESH::UpdateView();
808
809   UpdateTable();
810   SetCurrentSelection();
811
812   updateButtons();
813
814   SMESHGUI::Modified();
815
816   return true;
817 }
818
819 //=================================================================================
820 // function : ClickOnOk()
821 // purpose  :
822 //=================================================================================
823
824 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
825 {
826   if ( ClickOnApply() )
827     reject();
828 }
829
830 //=================================================================================
831 // function : reject()
832 // purpose  :
833 //=================================================================================
834
835 void SMESHGUI_AddQuadraticElementDlg::reject()
836 {
837   mySelectionMgr->clearSelected();
838   mySimulation->SetVisibility(false);
839   SMESH::SetPointRepresentation(false);
840   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
841     aViewWindow->SetSelectionMode( ActorSelection );
842   disconnect(mySelectionMgr, 0, this, 0);
843   mySMESHGUI->ResetState();
844   QDialog::reject();
845 }
846
847 //=================================================================================
848 // function : ClickOnHelp()
849 // purpose  :
850 //=================================================================================
851
852 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
853 {
854   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
855   if (app)
856     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
857   else {
858     QString platform;
859 #ifdef WIN32
860     platform = "winapplication";
861 #else
862     platform = "application";
863 #endif
864     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
865                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
866                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
867                                                                  platform)).
868                              arg(myHelpFileName));
869   }
870 }
871
872 //=================================================================================
873 // function : onTextChange()
874 // purpose  :
875 //=================================================================================
876
877 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
878 {
879   if (myBusy) return;
880   BusyLocker lock( myBusy );
881
882   mySimulation->SetVisibility(false);
883
884   // hilight entered nodes
885   SMDS_Mesh* aMesh = 0;
886   if (myActor)
887     aMesh = myActor->GetObject()->GetMesh();
888
889   QLineEdit* send = (QLineEdit*)sender();
890   if (send == myCornerNodes ||
891       send == myMidFaceNodes ||
892       send == myCenterNode)
893     myCurrentLineEdit = send;
894
895   if (aMesh) {
896     TColStd_MapOfInteger newIndices;
897
898     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
899     bool allOk = true;
900     for (int i = 0; i < aListId.count(); i++) {
901       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
902       {
903         newIndices.Add( n->GetID() );
904       }
905       else
906       {
907         allOk = false;
908         break;
909       }
910     }
911
912     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
913     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
914       aViewWindow->highlight( myActor->getIO(), true, true );
915
916     if ( myCurrentLineEdit == myCornerNodes )
917       UpdateTable( allOk );
918   }
919
920   updateButtons();
921   displaySimulation();
922 }
923
924 //=================================================================================
925 // function : SelectionIntoArgument()
926 // purpose  : Called when selection has changed
927 //=================================================================================
928
929 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
930 {
931   if (myBusy) return;
932   BusyLocker lock( myBusy );
933
934   QString aCurrentEntry = myEntry;
935
936   // clear
937   myActor = 0;
938   if ( myCurrentLineEdit )
939     myCurrentLineEdit->setText("");
940
941   if (!GroupButtons->isEnabled()) // inactive
942     return;
943
944   mySimulation->SetVisibility(false);
945
946   // get selected mesh
947   SALOME_ListIO aList;
948   mySelectionMgr->selectedObjects(aList);
949
950   if (aList.Extent() != 1)
951   {
952     UpdateTable();
953     updateButtons();
954     return;
955   }
956
957   Handle(SALOME_InteractiveObject) anIO = aList.First();
958   myEntry = anIO->getEntry();
959   myMesh = SMESH::GetMeshByIO(anIO);
960   if (myMesh->_is_nil()) {
961     updateButtons();
962     return;
963   }
964
965   myActor = SMESH::FindActorByEntry(anIO->getEntry());
966
967   // process groups
968   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
969     SMESH::ElementType anElementType;
970     switch ( myGeomType ) {
971     case SMDSEntity_Quad_Edge:
972       anElementType = SMESH::EDGE; break;
973     case SMDSEntity_Quad_Triangle:
974     case SMDSEntity_Quad_Quadrangle:
975     case SMDSEntity_BiQuad_Triangle:
976     case SMDSEntity_BiQuad_Quadrangle:
977       anElementType = SMESH::FACE; break;
978     case SMDSEntity_Quad_Tetra:
979     case SMDSEntity_Quad_Pyramid:
980     case SMDSEntity_Quad_Penta:
981     case SMDSEntity_Quad_Hexa:
982     case SMDSEntity_TriQuad_Hexa:
983       anElementType = SMESH::VOLUME; break;
984     }
985     myGroups.clear();
986     ComboBox_GroupName->clear();
987     ComboBox_GroupName->addItem( QString() );
988     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
989     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
990       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
991       if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
992         QString aGroupName( aGroup->GetName() );
993         if ( !aGroupName.isEmpty() ) {
994           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
995           ComboBox_GroupName->addItem( aGroupName );
996         }
997       }
998     }
999   }
1000
1001   if (!myActor) {
1002     updateButtons();
1003     return;
1004   }
1005
1006   // get selected nodes
1007   QString aString = "";
1008   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
1009
1010   if ( myCurrentLineEdit )
1011   {
1012     if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 )
1013       myCurrentLineEdit->setText(aString);
1014
1015     if ( myCurrentLineEdit == myCornerNodes )
1016       UpdateTable();
1017   }
1018   else if ( myTable->isEnabled() && nbNodes == 1 )
1019   {
1020     int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1021     if ( theCol == 1 )
1022       myTable->item(theRow, 1)->setText(aString);
1023   }
1024
1025   updateButtons();
1026   displaySimulation();
1027 }
1028
1029 //=================================================================================
1030 // function : displaySimulation()
1031 // purpose  :
1032 //=================================================================================
1033
1034 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
1035 {
1036   if ( IsValid() )
1037   {
1038     SMESH::TElementSimulationQuad::TVTKIds anIds;
1039
1040     // Collect ids from the dialog
1041     int anID;
1042     bool ok;
1043     int aDisplayMode = VTK_SURFACE;
1044
1045     if ( myGeomType == SMDSEntity_Quad_Edge )
1046     {
1047       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1048       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1049       anID = myTable->item(0, 1)->text().toInt(&ok);
1050       if (!ok) anID = myTable->item(0, 0)->text().toInt();
1051       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1052       aDisplayMode = VTK_WIREFRAME;
1053     }
1054     else
1055     {
1056       for ( int row = 0; row < myNbCorners; row++ )
1057         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1058
1059       for ( int row = 0; row < myTable->rowCount(); row++ )
1060       {
1061         anID = myTable->item(row, 1)->text().toInt(&ok);
1062         if (!ok) {
1063           anID = myTable->item(row, 0)->text().toInt();
1064           aDisplayMode = VTK_WIREFRAME;
1065         }
1066         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1067       }
1068       if ( myNbMidFaceNodes )
1069       {
1070         QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1071         for (int i = 0; i < aListId.count(); i++)
1072           anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
1073       }
1074       if ( myNbCenterNodes )
1075       {
1076         QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
1077         anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
1078       }
1079     }
1080
1081     mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
1082   }
1083   else
1084   {
1085     mySimulation->SetVisibility(false);
1086   }
1087   SMESH::UpdateView();
1088 }
1089
1090 //=================================================================================
1091 // function : SetCurrentSelection()
1092 // purpose  :
1093 //=================================================================================
1094
1095 void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
1096 {
1097   QPushButton* send = (QPushButton*)sender();
1098   myCurrentLineEdit = 0;
1099
1100   if (send == myCornerSelectButton)
1101     myCurrentLineEdit = myCornerNodes;
1102   else if ( send == myMidFaceSelectButton )
1103     myCurrentLineEdit = myMidFaceNodes;
1104   else if ( send == myCenterSelectButton )
1105     myCurrentLineEdit = myCenterNode;
1106
1107   if ( myCurrentLineEdit )
1108   {
1109     myCurrentLineEdit->setFocus();
1110     SelectionIntoArgument();
1111   }
1112 }
1113
1114 //=================================================================================
1115 // function : DeactivateActiveDialog()
1116 // purpose  :
1117 //=================================================================================
1118
1119 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1120 {
1121   if (GroupConstructors->isEnabled()) {
1122     GroupConstructors->setEnabled(false);
1123     GroupArguments->setEnabled(false);
1124     GroupButtons->setEnabled(false);
1125     mySimulation->SetVisibility(false);
1126     mySMESHGUI->ResetState();
1127     mySMESHGUI->SetActiveDialogBox(0);
1128   }
1129 }
1130
1131 //=================================================================================
1132 // function : ActivateThisDialog()
1133 // purpose  :
1134 //=================================================================================
1135
1136 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1137 {
1138   /* Emit a signal to deactivate the active dialog */
1139   mySMESHGUI->EmitSignalDeactivateDialog();
1140
1141   GroupConstructors->setEnabled(true);
1142   GroupArguments->setEnabled(true);
1143   GroupButtons->setEnabled(true);
1144
1145   SMESH::SetPointRepresentation(true);
1146
1147   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1148     aViewWindow->SetSelectionMode( NodeSelection );
1149   SelectionIntoArgument();
1150 }
1151
1152 //=================================================================================
1153 // function : enterEvent()
1154 // purpose  :
1155 //=================================================================================
1156
1157 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1158 {
1159   if (GroupConstructors->isEnabled())
1160     return;
1161   ActivateThisDialog();
1162 }
1163
1164 //=================================================================================
1165 // function : onReverse()
1166 // purpose  :
1167 //=================================================================================
1168
1169 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
1170 {
1171   mySimulation->SetVisibility(false);
1172   displaySimulation();
1173   updateButtons();
1174 }
1175
1176 //=================================================================================
1177 // function : IsValid()
1178 // purpose  :
1179 //=================================================================================
1180
1181 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1182 {
1183   SMDS_Mesh* aMesh = 0;
1184   if (myActor)
1185     aMesh = myActor->GetObject()->GetMesh();
1186   if (!aMesh)
1187     return false;
1188
1189   bool ok;
1190   std::set< int > okIDs;
1191   for ( int row = 0; row < myTable->rowCount(); row++ )
1192   {
1193     int anID =  myTable->item(row, 1)->text().toInt(&ok);
1194     if ( !ok )
1195       return false;
1196
1197     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1198     if ( !aNode )
1199       return false;
1200     okIDs.insert( anID );
1201   }
1202
1203   QStringList aListId;
1204   if ( myNbMidFaceNodes )
1205     aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1206   if ( myNbCenterNodes )
1207     aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
1208
1209   for (int i = 0; i < aListId.count(); i++)
1210   {
1211     int anID = aListId[ i ].toInt(&ok);
1212     if ( !ok )
1213       return false;
1214
1215     if ( !aMesh->FindNode(anID) )
1216       return false;
1217     okIDs.insert( anID );
1218   }
1219
1220   return okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
1221 }
1222
1223 //=================================================================================
1224 // function : UpdateTable()
1225 // purpose  :
1226 //=================================================================================
1227
1228 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1229 {
1230   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1231
1232   if ( aListCorners.count() == myNbCorners && theConersValidity )
1233   {
1234     myTable->setEnabled( true );
1235
1236     // clear the Middle column
1237     for ( int row = 0; row < myTable->rowCount(); row++ )
1238       myTable->item( row, 1 )->setText("");
1239
1240     int* aFirstColIds;
1241     int* aLastColIds;
1242
1243     switch (myGeomType) {
1244     case SMDSEntity_Quad_Edge:
1245       aFirstColIds = FirstEdgeIds;
1246       aLastColIds  = LastEdgeIds;
1247       break;
1248     case SMDSEntity_Quad_Triangle:
1249     case SMDSEntity_BiQuad_Triangle:
1250       aFirstColIds = FirstTriangleIds;
1251       aLastColIds  = LastTriangleIds;
1252       break;
1253     case SMDSEntity_Quad_Quadrangle:
1254     case SMDSEntity_BiQuad_Quadrangle:
1255       aFirstColIds = FirstQuadrangleIds;
1256       aLastColIds  = LastQuadrangleIds;
1257       break;
1258     case SMDSEntity_Quad_Tetra:
1259       aFirstColIds = FirstTetrahedronIds;
1260       aLastColIds  = LastTetrahedronIds;
1261       break;
1262     case SMDSEntity_Quad_Pyramid:
1263       aFirstColIds = FirstPyramidIds;
1264       aLastColIds  = LastPyramidIds;
1265       break;
1266     case SMDSEntity_Quad_Penta:
1267       aFirstColIds = FirstPentahedronIds;
1268       aLastColIds  = LastPentahedronIds;
1269       break;
1270     case SMDSEntity_Quad_Hexa:
1271     case SMDSEntity_TriQuad_Hexa:
1272       aFirstColIds = FirstHexahedronIds;
1273       aLastColIds  = LastHexahedronIds;
1274       break;
1275     }
1276
1277     // fill the First and the Last columns
1278     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1279       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1280
1281     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1282       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1283   }
1284   else
1285   {
1286     // clear table
1287     for ( int row = 0; row < myTable->rowCount(); row++ )
1288       for ( int col = 0; col < myTable->columnCount(); col++ )
1289         if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1290
1291     myTable->setEnabled( false );
1292   }
1293 }
1294
1295 //=================================================================================
1296 // function : onTableActivate()
1297 // purpose  :
1298 //=================================================================================
1299
1300 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1301 {
1302   myCurrentLineEdit = 0;
1303   displaySimulation();
1304   updateButtons();
1305 }
1306
1307 //=================================================================================
1308 // function : onCellTextChange()
1309 // purpose  :
1310 //=================================================================================
1311
1312 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1313 {
1314   myCurrentLineEdit = 0;
1315   displaySimulation();
1316   updateButtons();
1317 }
1318
1319 //=================================================================================
1320 // function : keyPressEvent()
1321 // purpose  :
1322 //=================================================================================
1323
1324 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1325 {
1326   QDialog::keyPressEvent( e );
1327   if ( e->isAccepted() )
1328     return;
1329
1330   if ( e->key() == Qt::Key_F1 ) {
1331     e->accept();
1332     ClickOnHelp();
1333   }
1334 }
1335
1336 //=======================================================================
1337 //function : updateButtons
1338 //purpose  : 
1339 //=======================================================================
1340
1341 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1342 {
1343   bool valid = IsValid();
1344   buttonOk->setEnabled( valid );
1345   buttonApply->setEnabled( valid );
1346 }
1347
1348 //=================================================================================
1349 // function : isValid
1350 // purpose  :
1351 //=================================================================================
1352
1353 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1354 {
1355   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1356     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
1357     return false;
1358   }
1359   return true;
1360 }