Salome HOME
Fix for IPAL19590: Qt4 porting: Segmentation violation at Modification - add Quadrati...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddQuadraticElementDlg.cxx
1 // SMESH SMESHGUI : GUI for SMESH component
2 //
3 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 //
6 // This library is free software; you can redistribute it and/or 
7 // modify it under the terms of the GNU Lesser General Public 
8 // License as published by the Free Software Foundation; either 
9 // version 2.1 of the License. 
10 //
11 // This library is distributed in the hope that it will be useful, 
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 // Lesser General Public License for more details. 
15 //
16 // You should have received a copy of the GNU Lesser General Public 
17 // License along with this library; if not, write to the Free Software 
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File   : SMESHGUI_AddMeshElementDlg.cxx
23 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
24 //
25
26 // SMESH includes
27 #include "SMESHGUI_AddQuadraticElementDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32 #include "SMESHGUI_MeshUtils.h"
33 #include "SMESHGUI_IdValidator.h"
34
35 #include <SMESH_Actor.h>
36 #include <SMESH_ActorUtils.h>
37 #include <SMDS_Mesh.hxx>
38
39 // SALOME GUI includes
40 #include <SUIT_Desktop.h>
41 #include <SUIT_Session.h>
42 #include <SUIT_MessageBox.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_ViewManager.h>
45
46 #include <LightApp_SelectionMgr.h>
47
48 #include <SVTK_ViewModel.h>
49 #include <SVTK_ViewWindow.h>
50
51 #include <SALOME_ListIO.hxx>
52
53 #include <SalomeApp_Application.h>
54
55 // IDL includes
56 #include <SALOMEconfig.h>
57 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
58
59 // OCCT includes
60 #include <TColStd_MapOfInteger.hxx>
61
62 // VTK includes
63 #include <vtkIdList.h>
64 #include <vtkUnstructuredGrid.h>
65 #include <vtkDataSetMapper.h>
66 #include <vtkProperty.h>
67 #include <vtkCellType.h>
68
69 // Qt includes
70 #include <QGroupBox>
71 #include <QLabel>
72 #include <QLineEdit>
73 #include <QPushButton>
74 #include <QRadioButton>
75 #include <QVBoxLayout>
76 #include <QHBoxLayout>
77 #include <QGridLayout>
78 #include <QCheckBox>
79 #include <QTableWidget>
80 #include <QKeyEvent>
81 #include <QButtonGroup>
82
83 // STL includes
84 #include <vector>
85
86 #define SPACING 6
87 #define MARGIN  11
88
89 namespace SMESH
90 {
91   void ReverseConnectivity( std::vector<int> & ids, int type )
92   {
93     // for reverse connectivity of other types keeping the first id, see
94     // void SMESH_VisualObjDef::buildElemPrs() in SMESH_Object.cxx:900
95     const int* conn = 0;
96    
97     switch ( type ) {
98     case QUAD_TETRAHEDRON: {
99       static int aConn[] = {0,2,1,3,6,5,4,7,9,8};
100       conn = aConn;
101       break;
102     }
103     case QUAD_PYRAMID: {
104       static int aConn[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
105       conn = aConn;
106       break;
107     }
108     case QUAD_PENTAHEDRON: {
109       static int aConn[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
110       conn = aConn;
111       break;
112     }
113     case QUAD_HEXAHEDRON: {
114       static int aConn[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
115       conn = aConn;
116       break;
117     }
118     case QUAD_EDGE: {
119       static int aConn[] = {1,0,2};
120       conn = aConn;
121       break;
122     }
123     case QUAD_TRIANGLE: {
124       static int aConn[] = {0,2,1,5,4,3};
125       conn = aConn;
126       break;
127     }
128     case QUAD_QUADRANGLE: {
129       static int aConn[] = {0,3,2,1,7,6,5,4};
130       conn = aConn;
131       break;
132     }
133     default:;
134     }
135     if ( !conn ) {
136       reverse( ids.begin(), ids.end() );
137     }
138     else {
139       std::vector<int> aRevIds( ids.size() );
140       for ( int i = 0; i < ids.size(); i++)
141         aRevIds[ i ] = ids[ conn[ i ]];
142       ids = aRevIds;
143     }
144   }
145
146   class TElementSimulation {
147     SalomeApp_Application* myApplication;
148     SUIT_ViewWindow* myViewWindow;
149     SVTK_ViewWindow* myVTKViewWindow;
150
151     SALOME_Actor* myPreviewActor;
152     vtkDataSetMapper* myMapper;
153     vtkUnstructuredGrid* myGrid;
154     //vtkProperty* myBackProp, *myProp;
155
156     vtkFloatingPointType myRGB[3], myBackRGB[3];
157
158   public:
159     TElementSimulation (SalomeApp_Application* theApplication)
160     {
161       myApplication = theApplication;
162       SUIT_ViewManager* mgr = theApplication->activeViewManager();
163       if (!mgr) return;
164       myViewWindow = mgr->getActiveView();
165       myVTKViewWindow = GetVtkViewWindow(myViewWindow);
166
167       myGrid = vtkUnstructuredGrid::New();
168
169       // Create and display actor
170       myMapper = vtkDataSetMapper::New();
171       myMapper->SetInput(myGrid);
172
173       myPreviewActor = SALOME_Actor::New();
174       myPreviewActor->PickableOff();
175       myPreviewActor->VisibilityOff();
176       myPreviewActor->SetMapper(myMapper);
177
178       vtkProperty* myProp = vtkProperty::New();
179       GetColor( "SMESH", "fill_color", myRGB[0], myRGB[1], myRGB[2], QColor( 0, 170, 255 ) );
180       myProp->SetColor( myRGB[0], myRGB[1], myRGB[2] );
181       myPreviewActor->SetProperty( myProp );
182       myProp->Delete();
183
184       vtkProperty* myBackProp = vtkProperty::New();
185       GetColor( "SMESH", "backface_color", myBackRGB[0], myBackRGB[1], myBackRGB[2], QColor( 0, 0, 255 ) );
186       myBackProp->SetColor( myBackRGB[0], myBackRGB[1], myBackRGB[2] );
187       myPreviewActor->SetBackfaceProperty( myBackProp );
188       myBackProp->Delete();
189
190       myVTKViewWindow->AddActor(myPreviewActor);
191     }
192
193     typedef std::vector<vtkIdType> TVTKIds;
194     void SetPosition (SMESH_Actor* theActor,
195                       const int    theType,
196                       TVTKIds&     theIds,
197                       const int    theMode,
198                       const bool   theReverse)
199     {
200       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
201       myGrid->SetPoints(aGrid->GetPoints());
202
203       //add points
204
205       vtkIdType aType = 0;
206
207       switch (theType) {
208       case QUAD_EDGE:
209         aType = VTK_QUADRATIC_EDGE;
210         break;
211       case QUAD_TRIANGLE:
212         aType = VTK_QUADRATIC_TRIANGLE; 
213         break;
214       case QUAD_QUADRANGLE:
215         aType = VTK_QUADRATIC_QUAD; 
216         break;
217       case QUAD_TETRAHEDRON:
218         aType = VTK_QUADRATIC_TETRA; 
219         break;
220       case QUAD_PYRAMID:
221         //aType = VTK_QUADRATIC_PYRAMID; // NOT SUPPORTED IN VTK4.2
222         aType = VTK_CONVEX_POINT_SET;
223         break;
224       case QUAD_PENTAHEDRON:
225         //aType = VTK_QUADRATIC_WEDGE; // NOT SUPPORTED IN VTK4.2
226         aType = VTK_CONVEX_POINT_SET;
227         break; 
228       case QUAD_HEXAHEDRON:
229         aType = VTK_QUADRATIC_HEXAHEDRON;
230         break;
231       }
232
233       // take care of orientation
234       if ( aType == VTK_CONVEX_POINT_SET ) {
235         if ( theReverse && theMode == VTK_SURFACE ) {
236           //myPreviewActor->GetProperty()->SetColor( myBackRGB[0], myBackRGB[1], myBackRGB[2] );
237         }
238       }
239       else {
240         // VTK cell connectivity opposites the MED one for volumic elements
241         if ( theIds.size() > 8 ? !theReverse : theReverse ) {
242           ReverseConnectivity( theIds, theType );
243         }
244       }
245             
246       myGrid->Reset();
247       vtkIdList *anIds = vtkIdList::New();
248       
249       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
250         anIds->InsertId(i,theIds[i]);
251         //std::cout << i<< ": " << theIds[i] << std::endl;
252       }
253       
254       myGrid->InsertNextCell(aType,anIds);
255       anIds->Delete();
256       
257       myGrid->Modified();
258
259       myPreviewActor->GetMapper()->Update();
260       myPreviewActor->SetRepresentation( theMode );
261       SetVisibility(true);
262
263       // restore normal orientation
264       if ( aType == VTK_CONVEX_POINT_SET ) {
265         if ( theReverse  && theMode == VTK_SURFACE ) {
266           //myPreviewActor->GetProperty()->SetColor( myRGB[0], myRGB[1], myRGB[2] );
267         }
268       }
269     }
270
271
272     void SetVisibility (bool theVisibility)
273     {
274       myPreviewActor->SetVisibility(theVisibility);
275       RepaintCurrentView();
276     }
277
278
279     ~TElementSimulation()
280     {
281       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
282         myVTKViewWindow->RemoveActor(myPreviewActor);
283       }
284       myPreviewActor->Delete();
285
286       myMapper->RemoveAllInputs();
287       myMapper->Delete();
288
289       myGrid->Delete();
290
291 //       myProp->Delete();
292 //       myBackProp->Delete();
293     }
294   };
295 }
296
297
298 // Define the sequences of ids
299 static int FirstEdgeIds[] = {0};
300 static int LastEdgeIds[] =  {1};
301
302 static int FirstTriangleIds[] = {0,1,2};
303 static int LastTriangleIds[] =  {1,2,0};
304
305 static int FirstQuadrangleIds[] = {0,1,2,3};
306 static int LastQuadrangleIds[] =  {1,2,3,0};
307
308 static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
309 static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
310
311 static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
312 static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
313
314 static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
315 static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
316
317 static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
318 static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
319
320
321
322 class SMESHGUI_IdEditItem: public QTableWidgetItem
323 {
324 public:
325     SMESHGUI_IdEditItem(const QString& text ):
326       QTableWidgetItem(text, QTableWidgetItem::UserType+100) {};
327   ~SMESHGUI_IdEditItem() {};
328
329   QWidget* createEditor() const;
330 };
331
332 QWidget* SMESHGUI_IdEditItem::createEditor() const
333 {
334   QLineEdit *aLineEdit = new QLineEdit(text(), tableWidget());
335   aLineEdit->setValidator( new SMESHGUI_IdValidator(tableWidget(), 1) );
336   return aLineEdit;
337 }
338
339 //=================================================================================
340 // function : SMESHGUI_AddQuadraticElementDlg()
341 // purpose  : constructor
342 //=================================================================================
343 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
344                                                                   const int theType )
345   : QDialog( SMESH::GetDesktop( theModule ) ),
346     mySMESHGUI( theModule ),
347     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
348     myType( theType )
349 {
350   setModal( false );
351   setAttribute( Qt::WA_DeleteOnClose, true );
352
353   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
354     (SUIT_Session::session()->activeApplication());
355   
356   mySimulation = new SMESH::TElementSimulation (anApp);
357   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
358
359   QString anElementName;
360
361   switch ( myType ) {
362   case QUAD_EDGE:
363     anElementName = QString("QUADRATIC_EDGE");
364     break;
365   case QUAD_TRIANGLE:
366     anElementName = QString("QUADRATIC_TRIANGLE");
367     break; 
368   case QUAD_QUADRANGLE:
369     anElementName = QString("QUADRATIC_QUADRANGLE");
370     break;
371   case QUAD_TETRAHEDRON:
372     anElementName = QString("QUADRATIC_TETRAHEDRON");
373     break;
374   case QUAD_PYRAMID:
375     anElementName = QString("QUADRATIC_PYRAMID");
376     break;
377   case QUAD_PENTAHEDRON:
378     anElementName = QString("QUADRATIC_PENTAHEDRON");
379     break;
380   case QUAD_HEXAHEDRON:
381     anElementName = QString("QUADRATIC_HEXAHEDRON");
382     break;
383   default:
384     myType = QUAD_EDGE;
385     anElementName = QString("QUADRATIC_EDGE");
386   }
387
388   QString iconName           = tr(QString("ICON_DLG_%1").arg(anElementName).toLatin1().data());
389   QString caption            = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
390   QString argumentsGrTitle   = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
391   QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
392   
393   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
394   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
395
396   setWindowTitle(caption);
397   
398   setSizeGripEnabled(true);
399
400   QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
401   aDialogLayout->setSpacing(SPACING);
402   aDialogLayout->setMargin(MARGIN);
403
404   /***************************************************************/
405   GroupConstructors = new QGroupBox(constructorGrTitle, this);
406   QButtonGroup* ButtonGroup = new QButtonGroup(this);
407   QHBoxLayout* aGroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
408   aGroupConstructorsLayout->setSpacing(SPACING);
409   aGroupConstructorsLayout->setMargin(MARGIN);
410
411   myRadioButton1 = new QRadioButton(GroupConstructors);
412   myRadioButton1->setIcon(image0);
413   aGroupConstructorsLayout->addWidget(myRadioButton1);
414   ButtonGroup->addButton(myRadioButton1, 0);
415
416   /***************************************************************/
417   GroupArguments = new QGroupBox(argumentsGrTitle, this);
418   QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments);
419   aGroupArgumentsLayout->setSpacing(SPACING);
420   aGroupArgumentsLayout->setMargin(MARGIN);
421
422   QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
423   mySelectButton = new QPushButton(GroupArguments);
424   mySelectButton->setIcon(image1);
425   myCornerNodes = new QLineEdit(GroupArguments);
426
427   myTable = new QTableWidget(GroupArguments);
428
429   myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
430
431   aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0);
432   aGroupArgumentsLayout->addWidget(mySelectButton,    0, 1);
433   aGroupArgumentsLayout->addWidget(myCornerNodes,     0, 2);
434   aGroupArgumentsLayout->addWidget(myTable,           1, 0, 1, 3); 
435   aGroupArgumentsLayout->addWidget(myReverseCB,       2, 0, 1, 3);
436   
437   /***************************************************************/
438   GroupButtons = new QGroupBox(this);
439   QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
440   aGroupButtonsLayout->setSpacing(SPACING);
441   aGroupButtonsLayout->setMargin(MARGIN);
442
443   buttonOk = new QPushButton(tr("SMESH_BUT_OK"), GroupButtons);
444   buttonOk->setAutoDefault(true);
445   buttonOk->setDefault(true);
446   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
447   buttonApply->setAutoDefault(true);
448   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
449   buttonCancel->setAutoDefault(true);
450   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
451   buttonHelp->setAutoDefault(true);
452
453   aGroupButtonsLayout->addWidget(buttonOk);
454   aGroupButtonsLayout->addSpacing(10);
455   aGroupButtonsLayout->addWidget(buttonApply);
456   aGroupButtonsLayout->addSpacing(10);
457   aGroupButtonsLayout->addStretch();
458   aGroupButtonsLayout->addWidget(buttonCancel);
459   aGroupButtonsLayout->addWidget(buttonHelp);
460
461   /***************************************************************/
462   aDialogLayout->addWidget(GroupConstructors);
463   aDialogLayout->addWidget(GroupArguments);
464   aDialogLayout->addWidget(GroupButtons);
465
466   Init(); /* Initialisations */
467 }
468
469 //=================================================================================
470 // function : ~SMESHGUI_AddQuadraticElementDlg()
471 // purpose  : Destroys the object and frees any allocated resources
472 //=================================================================================
473 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
474 {
475   delete mySimulation;
476 }
477
478 //=================================================================================
479 // function : Init()
480 // purpose  :
481 //=================================================================================
482 void SMESHGUI_AddQuadraticElementDlg::Init()
483 {
484   myRadioButton1->setChecked(true);
485   myIsEditCorners = true;
486   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
487   
488   myActor = 0;
489
490   int aNumRows;
491
492   switch (myType) {
493   case QUAD_EDGE:
494     aNumRows = 1;
495     myNbCorners = 2;
496     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges
497     break;
498   case QUAD_TRIANGLE:
499     aNumRows = 3;
500     myNbCorners = 3;
501     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
502     break;
503   case QUAD_QUADRANGLE:
504     aNumRows = 4;
505     myNbCorners = 4;
506     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
507     break;
508   case QUAD_TETRAHEDRON:
509     aNumRows = 6;
510     myNbCorners = 4;
511     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons
512     break;
513   case QUAD_PYRAMID:
514     aNumRows = 8;
515     myNbCorners = 5;
516     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids
517     break;
518   case QUAD_PENTAHEDRON:
519     aNumRows = 9;
520     myNbCorners = 6;
521     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
522     break; 
523   case QUAD_HEXAHEDRON:
524     aNumRows = 12;
525     myNbCorners = 8;
526     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
527     break;
528   }
529     
530   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
531
532   /* initialize table */
533   myTable->setColumnCount(3);
534   myTable->setRowCount(aNumRows);
535
536   QStringList aColLabels;
537   aColLabels.append(tr("SMESH_FIRST"));
538   aColLabels.append(tr("SMESH_MIDDLE"));
539   aColLabels.append(tr("SMESH_LAST"));
540   myTable->setHorizontalHeaderLabels(aColLabels);
541   
542   for ( int col = 0; col < myTable->columnCount(); col++ )
543     myTable->setColumnWidth(col, 80);
544
545   //myTable->setColumnReadOnly(0, true); // VSR: TODO
546   //myTable->setColumnReadOnly(2, true); // VSR: TODO
547
548   myTable->setEnabled( false );
549   
550   for ( int row = 0; row < myTable->rowCount(); row++ )
551   {
552     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
553
554     SMESHGUI_IdEditItem* anEditItem = new SMESHGUI_IdEditItem( "" );
555     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
556     myTable->setItem(row, 1, anEditItem);
557
558     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
559   }
560   
561   /* signals and slots connections */
562   connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners()));
563   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
564   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
565   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
566   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
567   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
568
569   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
570   connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel()));
571   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
572   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
573
574   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
575   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
576
577   // set selection mode
578   SMESH::SetPointRepresentation(true);
579
580   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
581     aViewWindow->SetSelectionMode( NodeSelection );
582
583   myBusy = false;
584
585   SetEditCorners();
586 }
587
588 //=================================================================================
589 // function : ClickOnApply()
590 // purpose  :
591 //=================================================================================
592 void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
593 {
594   if (IsValid() && !mySMESHGUI->isActiveStudyLocked()) {
595     myBusy = true;
596     
597     std::vector<int> anIds;
598
599     switch (myType) {
600     case QUAD_EDGE:
601       anIds.push_back(myTable->item(0, 0)->text().toInt());
602       anIds.push_back(myTable->item(0, 2)->text().toInt());
603       anIds.push_back(myTable->item(0, 1)->text().toInt());
604       break;
605     case QUAD_TRIANGLE:
606     case QUAD_QUADRANGLE:
607     case QUAD_TETRAHEDRON:
608     case QUAD_PYRAMID:
609     case QUAD_PENTAHEDRON:
610     case QUAD_HEXAHEDRON:
611       for ( int row = 0; row < myNbCorners; row++ )
612         anIds.push_back(myTable->item(row, 0)->text().toInt());
613       for ( int row = 0; row < myTable->rowCount(); row++ )
614         anIds.push_back(myTable->item(row, 1)->text().toInt());
615       break;
616     }
617     if ( myReverseCB->isChecked())
618       SMESH::ReverseConnectivity( anIds, myType );
619     
620     int aNumberOfIds =  anIds.size();
621     SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
622     anArrayOfIdeces->length( aNumberOfIds );
623     
624     for (int i = 0; i < aNumberOfIds; i++)
625       anArrayOfIdeces[i] = anIds[ i ];
626
627     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
628     switch (myType) {
629     case QUAD_EDGE:
630       aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
631     case QUAD_TRIANGLE:
632     case QUAD_QUADRANGLE:
633       aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
634     case QUAD_TETRAHEDRON:
635     case QUAD_PYRAMID:
636     case QUAD_PENTAHEDRON: 
637     case QUAD_HEXAHEDRON:
638       aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
639     }
640     
641     SALOME_ListIO aList; aList.Append( myActor->getIO() );
642     mySelector->ClearIndex();
643     mySelectionMgr->setSelectedObjects( aList, false );
644
645     SMESH::UpdateView();
646     mySimulation->SetVisibility(false);
647     
648     buttonOk->setEnabled(false);
649     buttonApply->setEnabled(false);
650
651     UpdateTable();
652     SetEditCorners();
653
654     myBusy = false;
655   }
656 }
657
658 //=================================================================================
659 // function : ClickOnOk()
660 // purpose  :
661 //=================================================================================
662 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
663 {
664   ClickOnApply();
665   ClickOnCancel();
666 }
667
668 //=================================================================================
669 // function : ClickOnCancel()
670 // purpose  :
671 //=================================================================================
672 void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel()
673 {
674   mySelectionMgr->clearSelected();
675   mySimulation->SetVisibility(false);
676   SMESH::SetPointRepresentation(false);
677   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
678     aViewWindow->SetSelectionMode( ActorSelection );
679   disconnect(mySelectionMgr, 0, this, 0);
680   mySMESHGUI->ResetState();
681   reject();
682 }
683
684 //=================================================================================
685 // function : ClickOnHelp()
686 // purpose  :
687 //=================================================================================
688 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
689 {
690   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
691   if (app) 
692     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
693   else {
694     QString platform;
695 #ifdef WIN32
696     platform = "winapplication";
697 #else
698     platform = "application";
699 #endif
700     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
701                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
702                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
703                                                                  platform)).
704                              arg(myHelpFileName));
705   }
706 }
707
708 //=================================================================================
709 // function : onTextChange()
710 // purpose  :
711 //=================================================================================
712 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
713 {
714   if (myBusy) return;
715   myBusy = true;
716   
717   buttonOk->setEnabled(false);
718   buttonApply->setEnabled(false);
719
720   mySimulation->SetVisibility(false);
721
722   // hilight entered nodes
723   SMDS_Mesh* aMesh = 0;
724   if (myActor)
725     aMesh = myActor->GetObject()->GetMesh();
726
727   if (aMesh) {
728     TColStd_MapOfInteger newIndices;
729     
730     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
731     bool allOk = true;
732     for (int i = 0; i < aListId.count(); i++) {
733       if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
734         newIndices.Add( n->GetID() );
735       else
736         {
737           allOk = false;
738           break;
739         }
740     }
741     
742     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
743     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
744       aViewWindow->highlight( myActor->getIO(), true, true );
745     
746     if ( sender() == myCornerNodes )
747       UpdateTable( allOk );
748   }
749   
750   if( IsValid() ) {
751     buttonOk->setEnabled(true);
752     buttonApply->setEnabled(true);
753   }
754
755   if ( sender() == myTable )
756     displaySimulation();
757   
758   myBusy = false;
759 }
760
761 //=================================================================================
762 // function : SelectionIntoArgument()
763 // purpose  : Called when selection has changed
764 //=================================================================================
765 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
766 {
767   if (myBusy) return;
768   
769   if ( myIsEditCorners )
770     {
771       // clear
772       myActor = 0;
773       
774       myBusy = true;
775       myCornerNodes->setText("");
776       myBusy = false;
777       
778       if (!GroupButtons->isEnabled()) // inactive
779         return;
780       
781       buttonOk->setEnabled(false);
782       buttonApply->setEnabled(false);
783       
784       mySimulation->SetVisibility(false);
785       
786       // get selected mesh
787       SALOME_ListIO aList;
788       mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
789       
790       if (aList.Extent() != 1)
791         {
792           UpdateTable();
793           return;
794         }
795       
796       Handle(SALOME_InteractiveObject) anIO = aList.First();
797       myMesh = SMESH::GetMeshByIO(anIO);
798       if (myMesh->_is_nil())
799         return;
800       
801       myActor = SMESH::FindActorByEntry(anIO->getEntry());
802   
803     }
804   
805   if (!myActor)
806     return;
807   
808   // get selected nodes
809   QString aString = "";
810   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
811   
812   if ( myIsEditCorners )
813     {
814       myBusy = true;
815       myCornerNodes->setText(aString);
816       myBusy = false;
817       
818       UpdateTable();
819     }
820   else if ( myTable->isEnabled() && nbNodes == 1 )
821     {
822       myBusy = true;
823       int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
824       if ( theCol == 1 )
825         myTable->item(theRow, 1)->setText(aString);
826       myBusy = false;
827     }
828   
829   if ( IsValid() )
830     {
831       buttonOk->setEnabled( true );
832       buttonApply->setEnabled( true );
833     }
834
835   displaySimulation();
836 }
837
838 //=================================================================================
839 // function : displaySimulation()
840 // purpose  :
841 //=================================================================================
842 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
843 {
844   if (!myIsEditCorners) {
845     SMESH::TElementSimulation::TVTKIds anIds;
846     
847     // Collect ids from the dialog
848     int anID;
849     bool ok;
850     int aDisplayMode = VTK_SURFACE;
851
852     if ( myType == QUAD_EDGE )
853       {
854         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
855         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
856         anID = myTable->item(0, 1)->text().toInt(&ok);
857         if (!ok) anID = myTable->item(0, 0)->text().toInt();
858         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
859         aDisplayMode = VTK_WIREFRAME;
860       }
861     else
862       {
863         for ( int row = 0; row < myNbCorners; row++ )
864           anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
865         
866         for ( int row = 0; row < myTable->rowCount(); row++ )
867           {
868             anID = myTable->item(row, 1)->text().toInt(&ok);
869             if (!ok) {
870               anID = myTable->item(row, 0)->text().toInt();
871               aDisplayMode = VTK_WIREFRAME;
872             }
873             anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
874           }
875       }
876     
877     mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked());
878     SMESH::UpdateView();
879   }
880 }
881
882 //=================================================================================
883 // function : SetEditCorners()
884 // purpose  :
885 //=================================================================================
886 void SMESHGUI_AddQuadraticElementDlg::SetEditCorners()
887 {
888   myCornerNodes->setFocus();
889   myIsEditCorners = true;
890   
891   SelectionIntoArgument();
892 }
893
894 //=================================================================================
895 // function : DeactivateActiveDialog()
896 // purpose  :
897 //=================================================================================
898 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
899 {
900   if (GroupConstructors->isEnabled()) {
901     GroupConstructors->setEnabled(false);
902     GroupArguments->setEnabled(false);
903     GroupButtons->setEnabled(false);
904     mySimulation->SetVisibility(false);
905     mySMESHGUI->ResetState();
906     mySMESHGUI->SetActiveDialogBox(0);
907   }
908 }
909
910 //=================================================================================
911 // function : ActivateThisDialog()
912 // purpose  :
913 //=================================================================================
914 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
915 {
916   /* Emit a signal to deactivate the active dialog */
917   mySMESHGUI->EmitSignalDeactivateDialog();
918
919   GroupConstructors->setEnabled(true);
920   GroupArguments->setEnabled(true);
921   GroupButtons->setEnabled(true);
922
923   SMESH::SetPointRepresentation(true);
924
925   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
926     aViewWindow->SetSelectionMode( NodeSelection );
927   SelectionIntoArgument();
928 }
929
930 //=================================================================================
931 // function : enterEvent()
932 // purpose  :
933 //=================================================================================
934 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
935 {
936   if (GroupConstructors->isEnabled())
937     return;
938   ActivateThisDialog();
939 }
940
941 //=================================================================================
942 // function : closeEvent()
943 // purpose  :
944 //=================================================================================
945 void SMESHGUI_AddQuadraticElementDlg::closeEvent (QCloseEvent*)
946 {
947   /* same than click on cancel button */
948   ClickOnCancel();
949 }
950
951 //=================================================================================
952 // function : hideEvent()
953 // purpose  : caused by ESC key
954 //=================================================================================
955 void SMESHGUI_AddQuadraticElementDlg::hideEvent (QHideEvent*)
956 {
957   if (!isMinimized())
958     ClickOnCancel();
959 }
960
961 //=================================================================================
962 // function : onReverse()
963 // purpose  :
964 //=================================================================================
965 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
966 {
967   if (!IsValid())
968     return;
969
970   if (state >= 0) {
971     mySimulation->SetVisibility(false);
972     displaySimulation();
973   }
974 }
975
976
977 //=================================================================================
978 // function : IsValid()
979 // purpose  :
980 //=================================================================================
981 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
982 {
983   SMDS_Mesh* aMesh = 0;
984   if (myActor)
985     aMesh = myActor->GetObject()->GetMesh();
986   if (!aMesh)
987     return false;
988
989   bool ok;
990   
991   for ( int row = 0; row < myTable->rowCount(); row++ )
992     {
993       int anID =  myTable->item(row, 1)->text().toInt(&ok);
994       if ( !ok )
995         return false;
996       
997       const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
998       if ( !aNode )
999         return false;
1000     }
1001   
1002   return true;
1003 }
1004
1005 //=================================================================================
1006 // function : UpdateTable()
1007 // purpose  :
1008 //=================================================================================
1009 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1010 {
1011   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1012   
1013   if ( aListCorners.count() == myNbCorners && theConersValidity )
1014     {
1015       myTable->setEnabled( true );
1016       
1017       // clear the Middle column 
1018       for ( int row = 0; row < myTable->rowCount(); row++ )
1019         myTable->item( row, 1 )->setText("");
1020       
1021       int* aFirstColIds;
1022       int* aLastColIds;
1023
1024       switch (myType) {
1025       case QUAD_EDGE:
1026         aFirstColIds = FirstEdgeIds;
1027         aLastColIds  = LastEdgeIds;
1028         break;
1029       case QUAD_TRIANGLE:
1030         aFirstColIds = FirstTriangleIds;
1031         aLastColIds  = LastTriangleIds;
1032         break;
1033       case QUAD_QUADRANGLE:
1034         aFirstColIds = FirstQuadrangleIds;
1035         aLastColIds  = LastQuadrangleIds;
1036         break;
1037       case QUAD_TETRAHEDRON:
1038         aFirstColIds = FirstTetrahedronIds;
1039         aLastColIds  = LastTetrahedronIds;
1040         break;
1041       case QUAD_PYRAMID:
1042         aFirstColIds = FirstPyramidIds;
1043         aLastColIds  = LastPyramidIds;
1044         break;
1045       case QUAD_PENTAHEDRON:
1046         aFirstColIds = FirstPentahedronIds;
1047         aLastColIds  = LastPentahedronIds;
1048         break; 
1049       case QUAD_HEXAHEDRON:
1050         aFirstColIds = FirstHexahedronIds;
1051         aLastColIds  = LastHexahedronIds;
1052         break;
1053       }
1054       
1055       // fill the First and the Last columns
1056       for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1057         myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1058       
1059       for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1060         myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1061     }
1062   else
1063     {
1064       // clear table
1065       for ( int row = 0; row < myTable->rowCount(); row++ )
1066         for ( int col = 0; col < myTable->columnCount(); col++ )
1067           if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1068       
1069       myTable->setEnabled( false );
1070     }
1071 }
1072
1073
1074 //=================================================================================
1075 // function : onTableActivate()
1076 // purpose  :
1077 //=================================================================================
1078 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1079 {
1080   if ( theCol == 1 )
1081     myIsEditCorners = false;
1082   
1083   displaySimulation();
1084 }
1085
1086
1087 //=================================================================================
1088 // function : onCellTextChange()
1089 // purpose  :
1090 //=================================================================================
1091 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1092 {
1093   onTextChange( myTable->item(theRow, theCol)->text() );
1094 }
1095
1096 //=================================================================================
1097 // function : keyPressEvent()
1098 // purpose  :
1099 //=================================================================================
1100 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1101 {
1102   QDialog::keyPressEvent( e );
1103   if ( e->isAccepted() )
1104     return;
1105
1106   if ( e->key() == Qt::Key_F1 ) {
1107     e->accept();
1108     ClickOnHelp();
1109   }
1110 }