Salome HOME
49d24f18c1d39c0b59829496ce48b8ecedc68e44
[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   myAutomaticPresentation = (myGeomType == SMDSEntity_Quad_Quadrangle || myGeomType == SMDSEntity_BiQuad_Quadrangle ||
556                              myGeomType == SMDSEntity_Quad_Pyramid    || myGeomType == SMDSEntity_Quad_Penta        ||
557                              myGeomType == SMDSEntity_Quad_Hexa       || myGeomType == SMDSEntity_TriQuad_Hexa ) ? new QCheckBox(tr("SMESH_AUTOMATIC_PRESENTATION"), GroupArguments) : 0;
558   if ( myAutomaticPresentation ) {
559     myNextPresentationButton = new QPushButton(tr("SMESH_BUT_GET_NEXT_SHAPE"), GroupArguments);
560     myNextPresentationButton->setAutoDefault(false);
561   }
562
563   aGroupArgumentsLayout->addWidget(aCornerNodesLabel,     0, 0);
564   aGroupArgumentsLayout->addWidget(myCornerSelectButton,  0, 1);
565   aGroupArgumentsLayout->addWidget(myCornerNodes,         0, 2);
566   if ( myAutomaticPresentation ) {
567     myAutomaticPresentation->setChecked(true);
568     aGroupArgumentsLayout->addWidget(myAutomaticPresentation,  1, 0, 1, 2);
569     aGroupArgumentsLayout->addWidget(myNextPresentationButton, 1, 2, 1, 1);
570   }
571   aGroupArgumentsLayout->addWidget(myTable,               2, 0, 1, 3);
572   aGroupArgumentsLayout->addWidget(myMidFaceLabel,        3, 0);
573   aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 3, 1);
574   aGroupArgumentsLayout->addWidget(myMidFaceNodes,        3, 2);
575   aGroupArgumentsLayout->addWidget(myCenterLabel,         4, 0);
576   aGroupArgumentsLayout->addWidget(myCenterSelectButton,  4, 1);
577   aGroupArgumentsLayout->addWidget(myCenterNode,          4, 2);
578   aGroupArgumentsLayout->addWidget(myReverseCB,           5, 0, 1, 3);
579     /***************************************************************/
580   GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
581   GroupGroups->setCheckable( true );
582   QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
583   GroupGroupsLayout->setSpacing(SPACING);
584   GroupGroupsLayout->setMargin(MARGIN);
585
586   TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
587   ComboBox_GroupName = new QComboBox( GroupGroups );
588   ComboBox_GroupName->setEditable( true );
589   ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
590
591   GroupGroupsLayout->addWidget( TextLabel_GroupName );
592   GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
593
594   /***************************************************************/
595   GroupButtons = new QGroupBox(this);
596   QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
597   aGroupButtonsLayout->setSpacing(SPACING);
598   aGroupButtonsLayout->setMargin(MARGIN);
599
600   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
601   buttonOk->setAutoDefault(true);
602   buttonOk->setDefault(true);
603   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
604   buttonApply->setAutoDefault(true);
605   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
606   buttonCancel->setAutoDefault(true);
607   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
608   buttonHelp->setAutoDefault(true);
609
610   aGroupButtonsLayout->addWidget(buttonOk);
611   aGroupButtonsLayout->addSpacing(10);
612   aGroupButtonsLayout->addWidget(buttonApply);
613   aGroupButtonsLayout->addSpacing(10);
614   aGroupButtonsLayout->addStretch();
615   aGroupButtonsLayout->addWidget(buttonCancel);
616   aGroupButtonsLayout->addWidget(buttonHelp);
617
618   /***************************************************************/
619   aDialogLayout->addWidget(GroupConstructors);
620   aDialogLayout->addWidget(GroupArguments);
621   aDialogLayout->addWidget(GroupGroups);
622   aDialogLayout->addWidget(GroupButtons);
623
624   Init(); /* Initialisations */
625 }
626
627 //=================================================================================
628 // function : ~SMESHGUI_AddQuadraticElementDlg()
629 // purpose  : Destroys the object and frees any allocated resources
630 //=================================================================================
631
632 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
633 {
634   delete mySimulation;
635 }
636
637 //=================================================================================
638 // function : Init()
639 // purpose  :
640 //=================================================================================
641
642 void SMESHGUI_AddQuadraticElementDlg::Init()
643 {
644   myRadioButton1->setChecked(true);
645   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
646
647   /* reset "Add to group" control */
648   GroupGroups->setChecked( false );
649
650   myActor = 0;
651   myNbMidFaceNodes = 0;
652   myNbCenterNodes = 0;
653
654   int aNumRows;
655
656   switch (myGeomType) {
657   case SMDSEntity_Quad_Edge:
658     aNumRows = 1;
659     myNbCorners = 2;
660     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges
661     break;
662   case SMDSEntity_Quad_Triangle:
663     aNumRows = 3;
664     myNbCorners = 3;
665     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
666     break;
667   case SMDSEntity_BiQuad_Triangle:
668     aNumRows = 3;
669     myNbCorners = 3;
670     myNbCenterNodes = 1;
671     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
672     break;
673   case SMDSEntity_Quad_Quadrangle:
674     aNumRows = 4;
675     myNbCorners = 4;
676     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
677     break;
678   case SMDSEntity_BiQuad_Quadrangle:
679     aNumRows = 4;
680     myNbCorners = 4;
681     myNbCenterNodes = 1;
682     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
683     break;
684   case SMDSEntity_Quad_Tetra:
685     aNumRows = 6;
686     myNbCorners = 4;
687     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons
688     break;
689   case SMDSEntity_Quad_Pyramid:
690     aNumRows = 8;
691     myNbCorners = 5;
692     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids
693     break;
694   case SMDSEntity_Quad_Penta:
695     aNumRows = 9;
696     myNbCorners = 6;
697     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
698     break;
699   case SMDSEntity_Quad_Hexa:
700     aNumRows = 12;
701     myNbCorners = 8;
702     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
703     break;
704   case SMDSEntity_TriQuad_Hexa:
705     aNumRows = 12;
706     myNbCorners = 8;
707     myNbMidFaceNodes = 6;
708     myNbCenterNodes = 1;
709     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
710     break;
711   }
712
713   myMidFaceLabel       ->setVisible( myNbMidFaceNodes );
714   myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
715   myMidFaceNodes       ->setVisible( myNbMidFaceNodes );
716   myCenterLabel        ->setVisible( myNbCenterNodes );
717   myCenterSelectButton ->setVisible( myNbCenterNodes );
718   myCenterNode         ->setVisible( myNbCenterNodes );
719
720   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
721
722   /* initialize table */
723   myTable->setColumnCount(3);
724   myTable->setRowCount(aNumRows);
725
726   QStringList aColLabels;
727   aColLabels.append(tr("SMESH_FIRST"));
728   aColLabels.append(tr("SMESH_MIDDLE"));
729   aColLabels.append(tr("SMESH_LAST"));
730   myTable->setHorizontalHeaderLabels(aColLabels);
731
732   for ( int col = 0; col < myTable->columnCount(); col++ )
733     myTable->setColumnWidth(col, 80);
734
735   //myTable->setColumnReadOnly(0, true); // VSR: TODO
736   //myTable->setColumnReadOnly(2, true); // VSR: TODO
737
738   myTable->setEnabled( false );
739
740   for ( int row = 0; row < myTable->rowCount(); row++ )
741   {
742     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
743     myTable->item( row, 0 )->setFlags(0);
744
745     IdEditItem* anEditItem = new IdEditItem( "" );
746     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
747     myTable->setItem(row, 1, anEditItem);
748
749     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
750     myTable->item( row, 2 )->setFlags(0);
751   }
752
753   /* signals and slots connections */
754   connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
755   connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
756   connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
757   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
758   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
759   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
760   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
761   connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
762   connect(myCenterNode,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
763   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
764
765   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
766   connect(buttonCancel, SIGNAL(clicked()), SLOT(reject()));
767   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
768   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
769
770   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
771   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
772   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
773   if (myAutomaticPresentation) {
774     connect(myAutomaticPresentation, SIGNAL(stateChanged(int)), SLOT(SetCurrentSelection()));
775     connect(myNextPresentationButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
776   }
777   myCurrentLineEdit = myCornerNodes;
778
779   // set selection mode
780   SMESH::SetPointRepresentation(true);
781
782   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
783     aViewWindow->SetSelectionMode( NodeSelection );
784
785   SelectionIntoArgument();
786 }
787
788 //=================================================================================
789 // function : ClickOnApply()
790 // purpose  :
791 //=================================================================================
792
793 bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
794 {
795   if( !isValid() )
796     return false;
797
798   if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
799     return false;
800
801   BusyLocker lock( myBusy );
802
803   std::vector<vtkIdType> anIds;
804
805   switch (myGeomType) {
806   case SMDSEntity_Quad_Edge:
807     anIds.push_back(myTable->item(0, 0)->text().toInt());
808     anIds.push_back(myTable->item(0, 2)->text().toInt());
809     anIds.push_back(myTable->item(0, 1)->text().toInt());
810     break;
811   case SMDSEntity_Quad_Triangle:
812   case SMDSEntity_Quad_Quadrangle:
813   case SMDSEntity_BiQuad_Triangle:
814   case SMDSEntity_BiQuad_Quadrangle:
815   case SMDSEntity_Quad_Tetra:
816   case SMDSEntity_Quad_Pyramid:
817   case SMDSEntity_Quad_Penta:
818   case SMDSEntity_Quad_Hexa:
819   case SMDSEntity_TriQuad_Hexa:
820     for ( int row = 0; row < myNbCorners; row++ )
821       anIds.push_back(myTable->item(row, 0)->text().toInt());
822     for ( int row = 0; row < myTable->rowCount(); row++ )
823       anIds.push_back(myTable->item(row, 1)->text().toInt());
824     if ( myNbMidFaceNodes )
825     {
826       QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
827       for (int i = 0; i < aListId.count(); i++)
828         anIds.push_back( aListId[ i ].toInt() );
829     }
830     if ( myNbCenterNodes )
831     {
832       QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
833       anIds.push_back( aListId[ 0 ].toInt() );
834     }
835     break;
836   }
837   if ( myReverseCB->isChecked())
838     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
839
840   int aNumberOfIds =  anIds.size();
841   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
842   anArrayOfIdeces->length( aNumberOfIds );
843
844   for (int i = 0; i < aNumberOfIds; i++)
845     anArrayOfIdeces[i] = anIds[ i ];
846
847   bool addToGroup = GroupGroups->isChecked();
848   QString aGroupName;
849
850   SMESH::SMESH_GroupBase_var aGroup;
851   int idx = 0;
852   if( addToGroup ) {
853     aGroupName = ComboBox_GroupName->currentText();
854     for ( int i = 1; i <= ComboBox_GroupName->count(); i++ ) {
855       QString aName = ComboBox_GroupName->itemText( i );
856       if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
857         idx = i;
858     }
859     if ( idx > 0 && idx <= myGroups.count() ) {
860       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
861       if ( !aGeomGroup->_is_nil() ) {
862         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
863                                              tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
864                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
865         if ( res == 1 ) return false;
866       }
867       aGroup = myGroups[idx-1];
868     }
869   }
870
871   SMESH::ElementType anElementType;
872   long anElemId = -1;
873   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
874   switch (myGeomType) {
875   case SMDSEntity_Quad_Edge:
876     anElementType = SMESH::EDGE;
877     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
878   case SMDSEntity_Quad_Triangle:
879   case SMDSEntity_Quad_Quadrangle:
880   case SMDSEntity_BiQuad_Triangle:
881   case SMDSEntity_BiQuad_Quadrangle:
882     anElementType = SMESH::FACE;
883     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
884   case SMDSEntity_Quad_Tetra:
885   case SMDSEntity_Quad_Pyramid:
886   case SMDSEntity_Quad_Penta:
887   case SMDSEntity_Quad_Hexa:
888   case SMDSEntity_TriQuad_Hexa:
889     anElementType = SMESH::VOLUME;
890     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
891   default: break;
892   }
893
894   if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
895     SMESH::SMESH_Group_var aGroupUsed;
896     if ( aGroup->_is_nil() ) {
897       // create new group
898       aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
899       if ( !aGroupUsed->_is_nil() ) {
900         myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
901         ComboBox_GroupName->addItem( aGroupName );
902       }
903     }
904     else {
905       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
906       if ( !aGeomGroup->_is_nil() ) {
907         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
908         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
909           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
910           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
911         }
912       }
913       else
914         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
915     }
916
917     if ( !aGroupUsed->_is_nil() ) {
918       SMESH::long_array_var anIdList = new SMESH::long_array;
919       anIdList->length( 1 );
920       anIdList[0] = anElemId;
921       aGroupUsed->Add( anIdList.inout() );
922     }
923   }
924
925   SALOME_ListIO aList; aList.Append( myActor->getIO() );
926   mySelector->ClearIndex();
927   mySelectionMgr->setSelectedObjects( aList, false );
928
929   mySimulation->SetVisibility(false);
930   SMESH::UpdateView();
931
932   UpdateTable();
933   SetCurrentSelection();
934
935   updateButtons();
936
937   SMESHGUI::Modified();
938
939   return true;
940 }
941
942 //=================================================================================
943 // function : ClickOnOk()
944 // purpose  :
945 //=================================================================================
946
947 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
948 {
949   if ( ClickOnApply() )
950     reject();
951 }
952
953 //=================================================================================
954 // function : reject()
955 // purpose  :
956 //=================================================================================
957
958 void SMESHGUI_AddQuadraticElementDlg::reject()
959 {
960   mySelectionMgr->clearSelected();
961   mySimulation->SetVisibility(false);
962   SMESH::SetPointRepresentation(false);
963   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
964     aViewWindow->SetSelectionMode( ActorSelection );
965   disconnect(mySelectionMgr, 0, this, 0);
966   mySMESHGUI->ResetState();
967   QDialog::reject();
968 }
969
970 //=================================================================================
971 // function : ClickOnHelp()
972 // purpose  :
973 //=================================================================================
974
975 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
976 {
977   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
978   if (app)
979     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
980   else {
981     QString platform;
982 #ifdef WIN32
983     platform = "winapplication";
984 #else
985     platform = "application";
986 #endif
987     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
988                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
989                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
990                                                                  platform)).
991                              arg(myHelpFileName));
992   }
993 }
994
995 //=================================================================================
996 // function : onTextChange()
997 // purpose  :
998 //=================================================================================
999
1000 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
1001 {
1002   if (myBusy) return;
1003   BusyLocker lock( myBusy );
1004
1005   mySimulation->SetVisibility(false);
1006
1007   // hilight entered nodes
1008   SMDS_Mesh* aMesh = 0;
1009   if (myActor)
1010     aMesh = myActor->GetObject()->GetMesh();
1011
1012   QLineEdit* send = (QLineEdit*)sender();
1013   if (send == myCornerNodes ||
1014       send == myMidFaceNodes ||
1015       send == myCenterNode)
1016     myCurrentLineEdit = send;
1017
1018   if (aMesh) {
1019     TColStd_MapOfInteger newIndices;
1020
1021     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
1022     bool allOk = true;
1023     for (int i = 0; i < aListId.count(); i++) {
1024       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
1025       {
1026         newIndices.Add( n->GetID() );
1027       }
1028       else
1029       {
1030         allOk = false;
1031         break;
1032       }
1033     }
1034
1035     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
1036     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1037       aViewWindow->highlight( myActor->getIO(), true, true );
1038
1039     if ( myCurrentLineEdit == myCornerNodes )
1040       UpdateTable( allOk );
1041   }
1042   updateButtons();
1043   displaySimulation();
1044 }
1045
1046 //=================================================================================
1047 // function : SelectionIntoArgument()
1048 // purpose  : Called when selection has changed
1049 //=================================================================================
1050
1051 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
1052 {
1053   if (myBusy) return;
1054   BusyLocker lock( myBusy );
1055
1056   QString aCurrentEntry = myEntry;
1057   QString anOldEditArgument = "";
1058   // clear
1059   myActor = 0;
1060   if ( myCurrentLineEdit ) {
1061     anOldEditArgument = myCurrentLineEdit->text();
1062     myCurrentLineEdit->setText("");
1063   }
1064
1065   if (!GroupButtons->isEnabled()) // inactive
1066     return;
1067
1068   mySimulation->SetVisibility(false);
1069
1070   // get selected mesh
1071   SALOME_ListIO aList;
1072   mySelectionMgr->selectedObjects(aList);
1073
1074   if (aList.Extent() != 1)
1075   {
1076     UpdateTable();
1077     updateButtons();
1078     return;
1079   }
1080
1081   Handle(SALOME_InteractiveObject) anIO = aList.First();
1082   myEntry = anIO->getEntry();
1083   myMesh = SMESH::GetMeshByIO(anIO);
1084   if (myMesh->_is_nil()) {
1085     updateButtons();
1086     return;
1087   }
1088
1089   myActor = SMESH::FindActorByEntry(anIO->getEntry());
1090
1091   // process groups
1092   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
1093     SMESH::ElementType anElementType;
1094     switch ( myGeomType ) {
1095     case SMDSEntity_Quad_Edge:
1096       anElementType = SMESH::EDGE; break;
1097     case SMDSEntity_Quad_Triangle:
1098     case SMDSEntity_Quad_Quadrangle:
1099     case SMDSEntity_BiQuad_Triangle:
1100     case SMDSEntity_BiQuad_Quadrangle:
1101       anElementType = SMESH::FACE; break;
1102     case SMDSEntity_Quad_Tetra:
1103     case SMDSEntity_Quad_Pyramid:
1104     case SMDSEntity_Quad_Penta:
1105     case SMDSEntity_Quad_Hexa:
1106     case SMDSEntity_TriQuad_Hexa:
1107       anElementType = SMESH::VOLUME; break;
1108     }
1109     myGroups.clear();
1110     ComboBox_GroupName->clear();
1111     ComboBox_GroupName->addItem( QString() );
1112     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
1113     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
1114       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
1115       if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
1116         QString aGroupName( aGroup->GetName() );
1117         if ( !aGroupName.isEmpty() ) {
1118           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
1119           ComboBox_GroupName->addItem( aGroupName );
1120         }
1121       }
1122     }
1123   }
1124
1125   if (!myActor) {
1126     updateButtons();
1127     return;
1128   }
1129   if ( myAutomaticPresentation )
1130     myNextPresentationButton->setEnabled(false);
1131   // get selected nodes
1132   QString aString = "";
1133   int nbNodes = 0;
1134   while ( aString == "" || anOldEditArgument == aString ) {
1135     if ( myAutomaticPresentation && myAutomaticPresentation->isChecked() ) {
1136       nbNodes = SMESH::GetNameOfSelectedSortedNodes( myGeomType , mySelector, myActor, myShift, aString );
1137     }
1138     else
1139       nbNodes = SMESH::GetNameOfSelectedNodes( mySelector, myActor->getIO(), aString );
1140     if ( aString!= "" && myNbCorners == nbNodes && anOldEditArgument == aString && myAutomaticPresentation && myAutomaticPresentation->isChecked()) {
1141       myShift++;
1142       if ( myShift > nbNodes ) {
1143         myShift = 0;
1144         break;
1145       }
1146       continue;
1147     }
1148     if (myNbCorners != nbNodes && myNbCorners != 1) {
1149       myShift = 0;
1150       break;
1151     }
1152     if ( !myAutomaticPresentation || !myAutomaticPresentation->isChecked() )
1153       break;
1154   }
1155   if ( myCurrentLineEdit )
1156   {
1157     if ( myCurrentLineEdit != myCenterNode || nbNodes == 1)
1158       myCurrentLineEdit->setText(aString);
1159
1160     if ( myCurrentLineEdit == myCornerNodes ) {
1161       UpdateTable();
1162       if ( myAutomaticPresentation && myAutomaticPresentation->isChecked() && myNbCorners == nbNodes)
1163         myNextPresentationButton->setEnabled(true);
1164     }
1165   }
1166   else if ( myTable->isEnabled() && nbNodes == 1 )
1167   {
1168     int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1169     if ( theCol == 1 )
1170       myTable->item(theRow, 1)->setText(aString);
1171   }
1172   updateButtons();
1173   displaySimulation();
1174 }
1175
1176 //=================================================================================
1177 // function : displaySimulation()
1178 // purpose  :
1179 //=================================================================================
1180
1181 void SMESHGUI_AddQuadraticElementDlg::displaySimulation(int theRow, int theCol)
1182 {
1183   bool isValid = IsValid();
1184   if ( ( isValid || myTable->isEnabled() ) && myActor )
1185   {
1186     SMESH::TElementSimulationQuad::TVTKIds anIds;
1187
1188     // Collect ids from the dialog
1189     int anID;
1190     bool ok;
1191     int aDisplayMode = VTK_SURFACE;
1192     if ( myGeomType == SMDSEntity_Quad_Edge )
1193     {
1194       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1195       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1196       anID = myTable->item(0, 1)->text().toInt(&ok);
1197       if (!ok) anID = myTable->item(0, 0)->text().toInt();
1198       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1199       aDisplayMode = VTK_WIREFRAME;
1200     }
1201     else
1202     {
1203       for ( int row = 0; row < myNbCorners; row++ )
1204         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1205
1206       for ( int row = 0; row < myTable->rowCount(); row++ )
1207       {
1208         anID = myTable->item(row, 1)->text().toInt(&ok);
1209         if (!ok) {
1210           anID = myTable->item(row, 0)->text().toInt();
1211           aDisplayMode = VTK_WIREFRAME;
1212         }
1213         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1214       }
1215       if ( myNbMidFaceNodes && isValid)
1216       {
1217         QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1218         for (int i = 0; i < aListId.count(); i++)
1219           anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
1220       }
1221       if ( myNbCenterNodes && isValid)
1222       {
1223         QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
1224         anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
1225       }
1226     }
1227     if ( isValid )
1228       mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
1229     mySimulation->SetCornerNodes(myActor, anIds);
1230     if ( theCol == 1 ) {
1231       anIds.clear();
1232       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(theRow, 0)->text().toInt() ) );
1233       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(theRow, 2)->text().toInt() ) );
1234       bool ok;
1235       int anID;
1236       anID = myTable->item(theRow, 1)->text().toInt(&ok);
1237       if (ok)
1238         anIds.push_back(myActor->GetObject()->GetNodeVTKId(anID));
1239       mySimulation->SetSelectedNodes(myActor, anIds);
1240     }
1241     mySimulation->SetVisibility(isValid, true, true, myActor->GetFacesOriented());
1242   }
1243   else
1244   {
1245     mySimulation->SetVisibility(false);
1246   }
1247   SMESH::UpdateView();
1248 }
1249
1250 //=================================================================================
1251 // function : SetCurrentSelection()
1252 // purpose  :
1253 //=================================================================================
1254
1255 void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
1256 {
1257   QPushButton* send = (QPushButton*)sender();
1258   myCurrentLineEdit = 0;
1259
1260   if (send == myCornerSelectButton || (QCheckBox*)sender() == myAutomaticPresentation)
1261     myCurrentLineEdit = myCornerNodes;
1262   else if ( send == myMidFaceSelectButton )
1263     myCurrentLineEdit = myMidFaceNodes;
1264   else if ( send == myCenterSelectButton )
1265     myCurrentLineEdit = myCenterNode;
1266   else if (send == myNextPresentationButton ) {
1267     myShift++;
1268     myCurrentLineEdit = myCornerNodes;
1269   }
1270
1271   if ( myCurrentLineEdit )
1272   {
1273     myCurrentLineEdit->setFocus();
1274     SelectionIntoArgument();
1275   }
1276 }
1277
1278 //=================================================================================
1279 // function : DeactivateActiveDialog()
1280 // purpose  :
1281 //=================================================================================
1282
1283 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1284 {
1285   if (GroupConstructors->isEnabled()) {
1286     GroupConstructors->setEnabled(false);
1287     GroupArguments->setEnabled(false);
1288     GroupButtons->setEnabled(false);
1289     mySimulation->SetVisibility(false);
1290     mySMESHGUI->ResetState();
1291     mySMESHGUI->SetActiveDialogBox(0);
1292   }
1293 }
1294
1295 //=================================================================================
1296 // function : ActivateThisDialog()
1297 // purpose  :
1298 //=================================================================================
1299
1300 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1301 {
1302   /* Emit a signal to deactivate the active dialog */
1303   mySMESHGUI->EmitSignalDeactivateDialog();
1304
1305   GroupConstructors->setEnabled(true);
1306   GroupArguments->setEnabled(true);
1307   GroupButtons->setEnabled(true);
1308
1309   SMESH::SetPointRepresentation(true);
1310
1311   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1312     aViewWindow->SetSelectionMode( NodeSelection );
1313   SelectionIntoArgument();
1314 }
1315
1316 //=================================================================================
1317 // function : enterEvent()
1318 // purpose  :
1319 //=================================================================================
1320
1321 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1322 {
1323   if (GroupConstructors->isEnabled())
1324     return;
1325   ActivateThisDialog();
1326 }
1327
1328 //=================================================================================
1329 // function : onReverse()
1330 // purpose  :
1331 //=================================================================================
1332
1333 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
1334 {
1335   mySimulation->SetVisibility(false);
1336   displaySimulation();
1337   updateButtons();
1338 }
1339
1340 //=================================================================================
1341 // function : IsValid()
1342 // purpose  :
1343 //=================================================================================
1344
1345 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1346 {
1347   SMDS_Mesh* aMesh = 0;
1348   if (myActor)
1349     aMesh = myActor->GetObject()->GetMesh();
1350   if (!aMesh)
1351     return false;
1352
1353   bool ok;
1354   std::set< int > okIDs;
1355   for ( int row = 0; row < myTable->rowCount(); row++ )
1356   {
1357     int anID =  myTable->item(row, 1)->text().toInt(&ok);
1358     if ( !ok )
1359       return false;
1360
1361     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1362     if ( !aNode )
1363       return false;
1364     okIDs.insert( anID );
1365   }
1366
1367   QStringList aListId;
1368   if ( myNbMidFaceNodes )
1369     aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1370   if ( myNbCenterNodes )
1371     aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
1372
1373   for (int i = 0; i < aListId.count(); i++)
1374   {
1375     int anID = aListId[ i ].toInt(&ok);
1376     if ( !ok )
1377       return false;
1378
1379     if ( !aMesh->FindNode(anID) )
1380       return false;
1381     okIDs.insert( anID );
1382   }
1383
1384   return okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
1385 }
1386
1387 //=================================================================================
1388 // function : UpdateTable()
1389 // purpose  :
1390 //=================================================================================
1391
1392 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1393 {
1394   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1395
1396   if ( aListCorners.count() == myNbCorners && theConersValidity )
1397   {
1398     myTable->setEnabled( true );
1399
1400     // clear the Middle column
1401     for ( int row = 0; row < myTable->rowCount(); row++ )
1402       myTable->item( row, 1 )->setText("");
1403
1404     int* aFirstColIds;
1405     int* aLastColIds;
1406
1407     switch (myGeomType) {
1408     case SMDSEntity_Quad_Edge:
1409       aFirstColIds = FirstEdgeIds;
1410       aLastColIds  = LastEdgeIds;
1411       break;
1412     case SMDSEntity_Quad_Triangle:
1413     case SMDSEntity_BiQuad_Triangle:
1414       aFirstColIds = FirstTriangleIds;
1415       aLastColIds  = LastTriangleIds;
1416       break;
1417     case SMDSEntity_Quad_Quadrangle:
1418     case SMDSEntity_BiQuad_Quadrangle:
1419       aFirstColIds = FirstQuadrangleIds;
1420       aLastColIds  = LastQuadrangleIds;
1421       break;
1422     case SMDSEntity_Quad_Tetra:
1423       aFirstColIds = FirstTetrahedronIds;
1424       aLastColIds  = LastTetrahedronIds;
1425       break;
1426     case SMDSEntity_Quad_Pyramid:
1427       aFirstColIds = FirstPyramidIds;
1428       aLastColIds  = LastPyramidIds;
1429       break;
1430     case SMDSEntity_Quad_Penta:
1431       aFirstColIds = FirstPentahedronIds;
1432       aLastColIds  = LastPentahedronIds;
1433       break;
1434     case SMDSEntity_Quad_Hexa:
1435     case SMDSEntity_TriQuad_Hexa:
1436       aFirstColIds = FirstHexahedronIds;
1437       aLastColIds  = LastHexahedronIds;
1438       break;
1439     }
1440
1441     // fill the First and the Last columns
1442     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1443       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1444
1445     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1446       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1447   }
1448   else
1449   {
1450     // clear table
1451     for ( int row = 0; row < myTable->rowCount(); row++ )
1452       for ( int col = 0; col < myTable->columnCount(); col++ )
1453         if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1454
1455     myTable->setEnabled( false );
1456   }
1457 }
1458
1459 //=================================================================================
1460 // function : onTableActivate()
1461 // purpose  :
1462 //=================================================================================
1463
1464 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1465 {
1466   myCurrentLineEdit = 0;
1467   displaySimulation(theRow, theCol);
1468   updateButtons();
1469 }
1470
1471 //=================================================================================
1472 // function : onCellTextChange()
1473 // purpose  :
1474 //=================================================================================
1475
1476 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1477 {
1478   myCurrentLineEdit = 0;
1479   displaySimulation(theRow, theCol);
1480   updateButtons();
1481 }
1482
1483 //=================================================================================
1484 // function : keyPressEvent()
1485 // purpose  :
1486 //=================================================================================
1487
1488 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1489 {
1490   QDialog::keyPressEvent( e );
1491   if ( e->isAccepted() )
1492     return;
1493
1494   if ( e->key() == Qt::Key_F1 ) {
1495     e->accept();
1496     ClickOnHelp();
1497   }
1498 }
1499
1500 //=======================================================================
1501 //function : updateButtons
1502 //purpose  : 
1503 //=======================================================================
1504
1505 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1506 {
1507   bool valid = IsValid();
1508   buttonOk->setEnabled( valid );
1509   buttonApply->setEnabled( valid );
1510 }
1511
1512 //=================================================================================
1513 // function : isValid
1514 // purpose  :
1515 //=================================================================================
1516
1517 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1518 {
1519   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1520     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
1521     return false;
1522   }
1523   return true;
1524 }