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