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