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