Salome HOME
Bug IPAL19470 - Qt4 porting. Orientation, Filter. Crash after selection Bad oriented...
[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     SMESHGUI_IdEditItem* anEditItem = new SMESHGUI_IdEditItem( "" );
553     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
554     myTable->setItem(row, 1, anEditItem);
555   }
556   
557   /* signals and slots connections */
558   connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners()));
559   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
560   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
561   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
562   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
563   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
564
565   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
566   connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel()));
567   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
568   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
569
570   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
571   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
572
573   // set selection mode
574   SMESH::SetPointRepresentation(true);
575
576   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
577     aViewWindow->SetSelectionMode( NodeSelection );
578
579   myBusy = false;
580
581   SetEditCorners();
582 }
583
584 //=================================================================================
585 // function : ClickOnApply()
586 // purpose  :
587 //=================================================================================
588 void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
589 {
590   if (IsValid() && !mySMESHGUI->isActiveStudyLocked()) {
591     myBusy = true;
592     
593     std::vector<int> anIds;
594
595     switch (myType) {
596     case QUAD_EDGE:
597       anIds.push_back(myTable->item(0, 0)->text().toInt());
598       anIds.push_back(myTable->item(0, 2)->text().toInt());
599       anIds.push_back(myTable->item(0, 1)->text().toInt());
600       break;
601     case QUAD_TRIANGLE:
602     case QUAD_QUADRANGLE:
603     case QUAD_TETRAHEDRON:
604     case QUAD_PYRAMID:
605     case QUAD_PENTAHEDRON:
606     case QUAD_HEXAHEDRON:
607       for ( int row = 0; row < myNbCorners; row++ )
608         anIds.push_back(myTable->item(row, 0)->text().toInt());
609       for ( int row = 0; row < myTable->rowCount(); row++ )
610         anIds.push_back(myTable->item(row, 1)->text().toInt());
611       break;
612     }
613     if ( myReverseCB->isChecked())
614       SMESH::ReverseConnectivity( anIds, myType );
615     
616     int aNumberOfIds =  anIds.size();
617     SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
618     anArrayOfIdeces->length( aNumberOfIds );
619     
620     for (int i = 0; i < aNumberOfIds; i++)
621       anArrayOfIdeces[i] = anIds[ i ];
622
623     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
624     switch (myType) {
625     case QUAD_EDGE:
626       aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
627     case QUAD_TRIANGLE:
628     case QUAD_QUADRANGLE:
629       aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
630     case QUAD_TETRAHEDRON:
631     case QUAD_PYRAMID:
632     case QUAD_PENTAHEDRON: 
633     case QUAD_HEXAHEDRON:
634       aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
635     }
636     
637     SALOME_ListIO aList; aList.Append( myActor->getIO() );
638     mySelector->ClearIndex();
639     mySelectionMgr->setSelectedObjects( aList, false );
640
641     SMESH::UpdateView();
642     mySimulation->SetVisibility(false);
643     
644     buttonOk->setEnabled(false);
645     buttonApply->setEnabled(false);
646
647     UpdateTable();
648     SetEditCorners();
649
650     myBusy = false;
651   }
652 }
653
654 //=================================================================================
655 // function : ClickOnOk()
656 // purpose  :
657 //=================================================================================
658 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
659 {
660   ClickOnApply();
661   ClickOnCancel();
662 }
663
664 //=================================================================================
665 // function : ClickOnCancel()
666 // purpose  :
667 //=================================================================================
668 void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel()
669 {
670   mySelectionMgr->clearSelected();
671   mySimulation->SetVisibility(false);
672   SMESH::SetPointRepresentation(false);
673   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
674     aViewWindow->SetSelectionMode( ActorSelection );
675   disconnect(mySelectionMgr, 0, this, 0);
676   mySMESHGUI->ResetState();
677   reject();
678 }
679
680 //=================================================================================
681 // function : ClickOnHelp()
682 // purpose  :
683 //=================================================================================
684 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
685 {
686   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
687   if (app) 
688     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
689   else {
690     QString platform;
691 #ifdef WIN32
692     platform = "winapplication";
693 #else
694     platform = "application";
695 #endif
696     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
697                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
698                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
699                                                                  platform)).
700                              arg(myHelpFileName));
701   }
702 }
703
704 //=================================================================================
705 // function : onTextChange()
706 // purpose  :
707 //=================================================================================
708 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
709 {
710   if (myBusy) return;
711   myBusy = true;
712   
713   buttonOk->setEnabled(false);
714   buttonApply->setEnabled(false);
715
716   mySimulation->SetVisibility(false);
717
718   // hilight entered nodes
719   SMDS_Mesh* aMesh = 0;
720   if (myActor)
721     aMesh = myActor->GetObject()->GetMesh();
722
723   if (aMesh) {
724     TColStd_MapOfInteger newIndices;
725     
726     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
727     bool allOk = true;
728     for (int i = 0; i < aListId.count(); i++) {
729       if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
730         newIndices.Add( n->GetID() );
731       else
732         {
733           allOk = false;
734           break;
735         }
736     }
737     
738     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
739     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
740       aViewWindow->highlight( myActor->getIO(), true, true );
741     
742     if ( sender() == myCornerNodes )
743       UpdateTable( allOk );
744   }
745   
746   if( IsValid() ) {
747     buttonOk->setEnabled(true);
748     buttonApply->setEnabled(true);
749   }
750
751   if ( sender() == myTable )
752     displaySimulation();
753   
754   myBusy = false;
755 }
756
757 //=================================================================================
758 // function : SelectionIntoArgument()
759 // purpose  : Called when selection has changed
760 //=================================================================================
761 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
762 {
763   if (myBusy) return;
764   
765   if ( myIsEditCorners )
766     {
767       // clear
768       myActor = 0;
769       
770       myBusy = true;
771       myCornerNodes->setText("");
772       myBusy = false;
773       
774       if (!GroupButtons->isEnabled()) // inactive
775         return;
776       
777       buttonOk->setEnabled(false);
778       buttonApply->setEnabled(false);
779       
780       mySimulation->SetVisibility(false);
781       
782       // get selected mesh
783       SALOME_ListIO aList;
784       mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
785       
786       if (aList.Extent() != 1)
787         {
788           UpdateTable();
789           return;
790         }
791       
792       Handle(SALOME_InteractiveObject) anIO = aList.First();
793       myMesh = SMESH::GetMeshByIO(anIO);
794       if (myMesh->_is_nil())
795         return;
796       
797       myActor = SMESH::FindActorByEntry(anIO->getEntry());
798   
799     }
800   
801   if (!myActor)
802     return;
803   
804   // get selected nodes
805   QString aString = "";
806   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
807   
808   if ( myIsEditCorners )
809     {
810       myBusy = true;
811       myCornerNodes->setText(aString);
812       myBusy = false;
813       
814       UpdateTable();
815     }
816   else if ( myTable->isEnabled() && nbNodes == 1 )
817     {
818       myBusy = true;
819       int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
820       if ( theCol == 1 )
821         myTable->item(theRow, 1)->setText(aString);
822       myBusy = false;
823     }
824   
825   if ( IsValid() )
826     {
827       buttonOk->setEnabled( true );
828       buttonApply->setEnabled( true );
829     }
830
831   displaySimulation();
832 }
833
834 //=================================================================================
835 // function : displaySimulation()
836 // purpose  :
837 //=================================================================================
838 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
839 {
840   if (!myIsEditCorners) {
841     SMESH::TElementSimulation::TVTKIds anIds;
842     
843     // Collect ids from the dialog
844     int anID;
845     bool ok;
846     int aDisplayMode = VTK_SURFACE;
847
848     if ( myType == QUAD_EDGE )
849       {
850         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
851         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
852         anID = myTable->item(0, 1)->text().toInt(&ok);
853         if (!ok) anID = myTable->item(0, 0)->text().toInt();
854         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
855         aDisplayMode = VTK_WIREFRAME;
856       }
857     else
858       {
859         for ( int row = 0; row < myNbCorners; row++ )
860           anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
861         
862         for ( int row = 0; row < myTable->rowCount(); row++ )
863           {
864             anID = myTable->item(row, 1)->text().toInt(&ok);
865             if (!ok) {
866               anID = myTable->item(row, 0)->text().toInt();
867               aDisplayMode = VTK_WIREFRAME;
868             }
869             anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
870           }
871       }
872     
873     mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked());
874     SMESH::UpdateView();
875   }
876 }
877
878 //=================================================================================
879 // function : SetEditCorners()
880 // purpose  :
881 //=================================================================================
882 void SMESHGUI_AddQuadraticElementDlg::SetEditCorners()
883 {
884   myCornerNodes->setFocus();
885   myIsEditCorners = true;
886   
887   SelectionIntoArgument();
888 }
889
890 //=================================================================================
891 // function : DeactivateActiveDialog()
892 // purpose  :
893 //=================================================================================
894 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
895 {
896   if (GroupConstructors->isEnabled()) {
897     GroupConstructors->setEnabled(false);
898     GroupArguments->setEnabled(false);
899     GroupButtons->setEnabled(false);
900     mySimulation->SetVisibility(false);
901     mySMESHGUI->ResetState();
902     mySMESHGUI->SetActiveDialogBox(0);
903   }
904 }
905
906 //=================================================================================
907 // function : ActivateThisDialog()
908 // purpose  :
909 //=================================================================================
910 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
911 {
912   /* Emit a signal to deactivate the active dialog */
913   mySMESHGUI->EmitSignalDeactivateDialog();
914
915   GroupConstructors->setEnabled(true);
916   GroupArguments->setEnabled(true);
917   GroupButtons->setEnabled(true);
918
919   SMESH::SetPointRepresentation(true);
920
921   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
922     aViewWindow->SetSelectionMode( NodeSelection );
923   SelectionIntoArgument();
924 }
925
926 //=================================================================================
927 // function : enterEvent()
928 // purpose  :
929 //=================================================================================
930 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
931 {
932   if (GroupConstructors->isEnabled())
933     return;
934   ActivateThisDialog();
935 }
936
937 //=================================================================================
938 // function : closeEvent()
939 // purpose  :
940 //=================================================================================
941 void SMESHGUI_AddQuadraticElementDlg::closeEvent (QCloseEvent*)
942 {
943   /* same than click on cancel button */
944   ClickOnCancel();
945 }
946
947 //=================================================================================
948 // function : hideEvent()
949 // purpose  : caused by ESC key
950 //=================================================================================
951 void SMESHGUI_AddQuadraticElementDlg::hideEvent (QHideEvent*)
952 {
953   if (!isMinimized())
954     ClickOnCancel();
955 }
956
957 //=================================================================================
958 // function : onReverse()
959 // purpose  :
960 //=================================================================================
961 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
962 {
963   if (!IsValid())
964     return;
965
966   if (state >= 0) {
967     mySimulation->SetVisibility(false);
968     displaySimulation();
969   }
970 }
971
972
973 //=================================================================================
974 // function : IsValid()
975 // purpose  :
976 //=================================================================================
977 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
978 {
979   SMDS_Mesh* aMesh = 0;
980   if (myActor)
981     aMesh = myActor->GetObject()->GetMesh();
982   if (!aMesh)
983     return false;
984
985   bool ok;
986   
987   for ( int row = 0; row < myTable->rowCount(); row++ )
988     {
989       int anID =  myTable->item(row, 1)->text().toInt(&ok);
990       if ( !ok )
991         return false;
992       
993       const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
994       if ( !aNode )
995         return false;
996     }
997   
998   return true;
999 }
1000
1001 //=================================================================================
1002 // function : UpdateTable()
1003 // purpose  :
1004 //=================================================================================
1005 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1006 {
1007   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1008   
1009   if ( aListCorners.count() == myNbCorners && theConersValidity )
1010     {
1011       myTable->setEnabled( true );
1012       
1013       // clear the Middle column 
1014       for ( int row = 0; row < myTable->rowCount(); row++ )
1015         myTable->item( row, 1 )->setText("");
1016       
1017       int* aFirstColIds;
1018       int* aLastColIds;
1019
1020       switch (myType) {
1021       case QUAD_EDGE:
1022         aFirstColIds = FirstEdgeIds;
1023         aLastColIds  = LastEdgeIds;
1024         break;
1025       case QUAD_TRIANGLE:
1026         aFirstColIds = FirstTriangleIds;
1027         aLastColIds  = LastTriangleIds;
1028         break;
1029       case QUAD_QUADRANGLE:
1030         aFirstColIds = FirstQuadrangleIds;
1031         aLastColIds  = LastQuadrangleIds;
1032         break;
1033       case QUAD_TETRAHEDRON:
1034         aFirstColIds = FirstTetrahedronIds;
1035         aLastColIds  = LastTetrahedronIds;
1036         break;
1037       case QUAD_PYRAMID:
1038         aFirstColIds = FirstPyramidIds;
1039         aLastColIds  = LastPyramidIds;
1040         break;
1041       case QUAD_PENTAHEDRON:
1042         aFirstColIds = FirstPentahedronIds;
1043         aLastColIds  = LastPentahedronIds;
1044         break; 
1045       case QUAD_HEXAHEDRON:
1046         aFirstColIds = FirstHexahedronIds;
1047         aLastColIds  = LastHexahedronIds;
1048         break;
1049       }
1050       
1051       // fill the First and the Last columns
1052       for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1053         myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1054       
1055       for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1056         myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1057     }
1058   else
1059     {
1060       // clear table
1061       for ( int row = 0; row < myTable->rowCount(); row++ )
1062         for ( int col = 0; col < myTable->columnCount(); col++ )
1063           if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1064       
1065       myTable->setEnabled( false );
1066     }
1067 }
1068
1069
1070 //=================================================================================
1071 // function : onTableActivate()
1072 // purpose  :
1073 //=================================================================================
1074 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1075 {
1076   if ( theCol == 1 )
1077     myIsEditCorners = false;
1078   
1079   displaySimulation();
1080 }
1081
1082
1083 //=================================================================================
1084 // function : onCellTextChange()
1085 // purpose  :
1086 //=================================================================================
1087 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1088 {
1089   onTextChange( myTable->item(theRow, theCol)->text() );
1090 }
1091
1092 //=================================================================================
1093 // function : keyPressEvent()
1094 // purpose  :
1095 //=================================================================================
1096 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1097 {
1098   QDialog::keyPressEvent( e );
1099   if ( e->isAccepted() )
1100     return;
1101
1102   if ( e->key() == Qt::Key_F1 ) {
1103     e->accept();
1104     ClickOnHelp();
1105   }
1106 }