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