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