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