Salome HOME
Merge from V5_1_4_BR 07/05/2010
[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
670   // set selection mode
671   SMESH::SetPointRepresentation(true);
672
673   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
674     aViewWindow->SetSelectionMode( NodeSelection );
675
676   SetEditCorners();
677 }
678
679 //=================================================================================
680 // function : ClickOnApply()
681 // purpose  :
682 //=================================================================================
683 void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
684 {
685   if( !isValid() )
686     return;
687
688   if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
689     return;
690
691   BusyLocker lock( myBusy );
692
693   std::vector<vtkIdType> anIds;
694
695   switch (myType) {
696   case QUAD_EDGE:
697     anIds.push_back(myTable->item(0, 0)->text().toInt());
698     anIds.push_back(myTable->item(0, 2)->text().toInt());
699     anIds.push_back(myTable->item(0, 1)->text().toInt());
700     break;
701   case QUAD_TRIANGLE:
702   case QUAD_QUADRANGLE:
703   case QUAD_TETRAHEDRON:
704   case QUAD_PYRAMID:
705   case QUAD_PENTAHEDRON:
706   case QUAD_HEXAHEDRON:
707     for ( int row = 0; row < myNbCorners; row++ )
708       anIds.push_back(myTable->item(row, 0)->text().toInt());
709     for ( int row = 0; row < myTable->rowCount(); row++ )
710       anIds.push_back(myTable->item(row, 1)->text().toInt());
711     break;
712   }
713   if ( myReverseCB->isChecked())
714     SMESH::ReverseConnectivity( anIds, myType );
715     
716   int aNumberOfIds =  anIds.size();
717   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
718   anArrayOfIdeces->length( aNumberOfIds );
719     
720   for (int i = 0; i < aNumberOfIds; i++)
721     anArrayOfIdeces[i] = anIds[ i ];
722
723   bool addToGroup = GroupGroups->isChecked();
724   QString aGroupName;
725   
726   SMESH::SMESH_GroupBase_var aGroup;
727   int idx = 0;
728   if( addToGroup ) {
729     aGroupName = ComboBox_GroupName->currentText();
730     for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
731       QString aName = ComboBox_GroupName->itemText( i );
732       if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
733         idx = i;
734     }
735     if ( idx > 0 ) {
736       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
737       if ( !aGeomGroup->_is_nil() ) {
738         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
739                                              tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
740                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
741         if ( res == 1 ) return;
742       }
743       aGroup = myGroups[idx-1];
744     }
745   }
746
747   SMESH::ElementType anElementType;
748   long anElemId = -1;
749   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
750   switch (myType) {
751   case QUAD_EDGE:
752     anElementType = SMESH::EDGE;
753     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
754   case QUAD_TRIANGLE:
755   case QUAD_QUADRANGLE:
756     anElementType = SMESH::FACE;
757     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
758   case QUAD_TETRAHEDRON:
759   case QUAD_PYRAMID:
760   case QUAD_PENTAHEDRON: 
761   case QUAD_HEXAHEDRON:
762     anElementType = SMESH::VOLUME;
763     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
764   default: break;
765   }
766     
767   if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
768     SMESH::SMESH_Group_var aGroupUsed;
769     if ( aGroup->_is_nil() ) {
770       // create new group 
771       aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
772       if ( !aGroupUsed->_is_nil() ) {
773         myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
774         ComboBox_GroupName->addItem( aGroupName );
775       }
776     }
777     else {
778       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
779       if ( !aGeomGroup->_is_nil() ) {
780         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
781         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
782           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
783           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
784         }
785       }
786       else
787         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
788     }
789     
790     if ( !aGroupUsed->_is_nil() ) {
791       SMESH::long_array_var anIdList = new SMESH::long_array;
792       anIdList->length( 1 );
793       anIdList[0] = anElemId;
794       aGroupUsed->Add( anIdList.inout() );
795     }
796   }
797
798   SALOME_ListIO aList; aList.Append( myActor->getIO() );
799   mySelector->ClearIndex();
800   mySelectionMgr->setSelectedObjects( aList, false );
801
802   mySimulation->SetVisibility(false);
803   SMESH::UpdateView();
804     
805   UpdateTable();
806   SetEditCorners();
807
808   updateButtons();
809 }
810
811 //=================================================================================
812 // function : ClickOnOk()
813 // purpose  :
814 //=================================================================================
815 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
816 {
817   ClickOnApply();
818   ClickOnCancel();
819 }
820
821 //=================================================================================
822 // function : ClickOnCancel()
823 // purpose  :
824 //=================================================================================
825 void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel()
826 {
827   mySelectionMgr->clearSelected();
828   mySimulation->SetVisibility(false);
829   SMESH::SetPointRepresentation(false);
830   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
831     aViewWindow->SetSelectionMode( ActorSelection );
832   disconnect(mySelectionMgr, 0, this, 0);
833   mySMESHGUI->ResetState();
834   reject();
835 }
836
837 //=================================================================================
838 // function : ClickOnHelp()
839 // purpose  :
840 //=================================================================================
841 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
842 {
843   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
844   if (app) 
845     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
846   else {
847     QString platform;
848 #ifdef WIN32
849     platform = "winapplication";
850 #else
851     platform = "application";
852 #endif
853     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
854                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
855                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
856                                                                  platform)).
857                              arg(myHelpFileName));
858   }
859 }
860
861 //=================================================================================
862 // function : onTextChange()
863 // purpose  :
864 //=================================================================================
865 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
866 {
867   if (myBusy) return;
868   BusyLocker lock( myBusy );
869   
870   mySimulation->SetVisibility(false);
871
872   // hilight entered nodes
873   SMDS_Mesh* aMesh = 0;
874   if (myActor)
875     aMesh = myActor->GetObject()->GetMesh();
876
877   if (aMesh) {
878     TColStd_MapOfInteger newIndices;
879     
880     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
881     bool allOk = true;
882     for (int i = 0; i < aListId.count(); i++) {
883       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
884       {
885         newIndices.Add( n->GetID() );
886       }
887       else
888       {
889         allOk = false;
890         break;
891       }
892     }
893     
894     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
895     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
896       aViewWindow->highlight( myActor->getIO(), true, true );
897     
898     if ( sender() == myCornerNodes )
899       UpdateTable( allOk );
900   }
901   
902   updateButtons();
903   displaySimulation();
904 }
905
906 //=================================================================================
907 // function : SelectionIntoArgument()
908 // purpose  : Called when selection has changed
909 //=================================================================================
910 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
911 {
912   if (myBusy) return;
913   BusyLocker lock( myBusy );
914   
915   QString aCurrentEntry = myEntry;
916
917   if ( myIsEditCorners )
918   {
919     // clear
920     myActor = 0;
921     
922     myCornerNodes->setText("");
923     
924     if (!GroupButtons->isEnabled()) // inactive
925       return;
926     
927     mySimulation->SetVisibility(false);
928       
929     // get selected mesh
930     SALOME_ListIO aList;
931     mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
932     
933     if (aList.Extent() != 1)
934     {
935       UpdateTable();
936       updateButtons();
937       return;
938     }
939       
940     Handle(SALOME_InteractiveObject) anIO = aList.First();
941     myEntry = anIO->getEntry();
942     myMesh = SMESH::GetMeshByIO(anIO);
943     if (myMesh->_is_nil()) {
944       updateButtons();
945       return;
946     }
947       
948     myActor = SMESH::FindActorByEntry(anIO->getEntry());
949   
950   }
951
952   // process groups
953   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
954     SMESH::ElementType anElementType;
955     switch ( myType ) {
956     case QUAD_EDGE:
957       anElementType = SMESH::EDGE; break;
958     case QUAD_TRIANGLE:
959     case QUAD_QUADRANGLE:
960       anElementType = SMESH::FACE; break;
961     case QUAD_TETRAHEDRON:
962     case QUAD_PYRAMID:
963     case QUAD_PENTAHEDRON: 
964     case QUAD_HEXAHEDRON:
965       anElementType = SMESH::VOLUME; break;
966     }
967     myGroups.clear();
968     ComboBox_GroupName->clear();
969     ComboBox_GroupName->addItem( QString() );
970     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
971     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
972       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
973       if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
974         QString aGroupName( aGroup->GetName() );
975         if ( !aGroupName.isEmpty() ) {
976           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
977           ComboBox_GroupName->addItem( aGroupName );
978         }
979       }
980     }
981   }
982   
983   if (!myActor) {
984     updateButtons();
985     return;
986   }
987   
988   // get selected nodes
989   QString aString = "";
990   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
991   
992   if ( myIsEditCorners )
993   {
994     myCornerNodes->setText(aString);
995     
996     UpdateTable();
997   }
998   else if ( myTable->isEnabled() && nbNodes == 1 )
999   {
1000     int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1001     if ( theCol == 1 )
1002       myTable->item(theRow, 1)->setText(aString);
1003   }
1004   
1005   updateButtons();
1006   displaySimulation();
1007 }
1008
1009 //=================================================================================
1010 // function : displaySimulation()
1011 // purpose  :
1012 //=================================================================================
1013 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
1014 {
1015   if ( IsValid() )
1016   {
1017     SMESH::TElementSimulation::TVTKIds anIds;
1018     
1019     // Collect ids from the dialog
1020     int anID;
1021     bool ok;
1022     int aDisplayMode = VTK_SURFACE;
1023     
1024     if ( myType == QUAD_EDGE )
1025     {
1026       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1027       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1028       anID = myTable->item(0, 1)->text().toInt(&ok);
1029       if (!ok) anID = myTable->item(0, 0)->text().toInt();
1030       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1031       aDisplayMode = VTK_WIREFRAME;
1032     }
1033     else
1034     {
1035       for ( int row = 0; row < myNbCorners; row++ )
1036         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1037       
1038       for ( int row = 0; row < myTable->rowCount(); row++ )
1039       {
1040         anID = myTable->item(row, 1)->text().toInt(&ok);
1041         if (!ok) {
1042           anID = myTable->item(row, 0)->text().toInt();
1043           aDisplayMode = VTK_WIREFRAME;
1044         }
1045         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1046       }
1047     }
1048     
1049     mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked());
1050   }
1051   else
1052   {
1053     mySimulation->SetVisibility(false);
1054   }
1055   SMESH::UpdateView();
1056 }
1057
1058 //=================================================================================
1059 // function : SetEditCorners()
1060 // purpose  :
1061 //=================================================================================
1062 void SMESHGUI_AddQuadraticElementDlg::SetEditCorners()
1063 {
1064   myCornerNodes->setFocus();
1065   myIsEditCorners = true;
1066   SelectionIntoArgument();
1067   updateButtons();
1068 }
1069
1070 //=================================================================================
1071 // function : DeactivateActiveDialog()
1072 // purpose  :
1073 //=================================================================================
1074 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1075 {
1076   if (GroupConstructors->isEnabled()) {
1077     GroupConstructors->setEnabled(false);
1078     GroupArguments->setEnabled(false);
1079     GroupButtons->setEnabled(false);
1080     mySimulation->SetVisibility(false);
1081     mySMESHGUI->ResetState();
1082     mySMESHGUI->SetActiveDialogBox(0);
1083   }
1084 }
1085
1086 //=================================================================================
1087 // function : ActivateThisDialog()
1088 // purpose  :
1089 //=================================================================================
1090 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1091 {
1092   /* Emit a signal to deactivate the active dialog */
1093   mySMESHGUI->EmitSignalDeactivateDialog();
1094
1095   GroupConstructors->setEnabled(true);
1096   GroupArguments->setEnabled(true);
1097   GroupButtons->setEnabled(true);
1098
1099   SMESH::SetPointRepresentation(true);
1100
1101   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1102     aViewWindow->SetSelectionMode( NodeSelection );
1103   SelectionIntoArgument();
1104 }
1105
1106 //=================================================================================
1107 // function : enterEvent()
1108 // purpose  :
1109 //=================================================================================
1110 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1111 {
1112   if (GroupConstructors->isEnabled())
1113     return;
1114   ActivateThisDialog();
1115 }
1116
1117 //=================================================================================
1118 // function : closeEvent()
1119 // purpose  :
1120 //=================================================================================
1121 void SMESHGUI_AddQuadraticElementDlg::closeEvent (QCloseEvent*)
1122 {
1123   /* same than click on cancel button */
1124   ClickOnCancel();
1125 }
1126
1127 //=================================================================================
1128 // function : hideEvent()
1129 // purpose  : caused by ESC key
1130 //=================================================================================
1131 void SMESHGUI_AddQuadraticElementDlg::hideEvent (QHideEvent*)
1132 {
1133   if (!isMinimized())
1134     ClickOnCancel();
1135 }
1136
1137 //=================================================================================
1138 // function : onReverse()
1139 // purpose  :
1140 //=================================================================================
1141 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
1142 {
1143   mySimulation->SetVisibility(false);
1144   displaySimulation();
1145   updateButtons();
1146 }
1147
1148
1149 //=================================================================================
1150 // function : IsValid()
1151 // purpose  :
1152 //=================================================================================
1153 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1154 {
1155   SMDS_Mesh* aMesh = 0;
1156   if (myActor)
1157     aMesh = myActor->GetObject()->GetMesh();
1158   if (!aMesh)
1159     return false;
1160
1161   bool ok;
1162   
1163   for ( int row = 0; row < myTable->rowCount(); row++ )
1164   {
1165     int anID =  myTable->item(row, 1)->text().toInt(&ok);
1166     if ( !ok )
1167       return false;
1168     
1169     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1170     if ( !aNode )
1171       return false;
1172   }
1173   
1174   return true;
1175 }
1176
1177 //=================================================================================
1178 // function : UpdateTable()
1179 // purpose  :
1180 //=================================================================================
1181 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1182 {
1183   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1184   
1185   if ( aListCorners.count() == myNbCorners && theConersValidity )
1186   {
1187     myTable->setEnabled( true );
1188     
1189     // clear the Middle column 
1190     for ( int row = 0; row < myTable->rowCount(); row++ )
1191       myTable->item( row, 1 )->setText("");
1192     
1193     int* aFirstColIds;
1194     int* aLastColIds;
1195     
1196     switch (myType) {
1197     case QUAD_EDGE:
1198       aFirstColIds = FirstEdgeIds;
1199       aLastColIds  = LastEdgeIds;
1200       break;
1201     case QUAD_TRIANGLE:
1202       aFirstColIds = FirstTriangleIds;
1203       aLastColIds  = LastTriangleIds;
1204       break;
1205     case QUAD_QUADRANGLE:
1206       aFirstColIds = FirstQuadrangleIds;
1207       aLastColIds  = LastQuadrangleIds;
1208       break;
1209     case QUAD_TETRAHEDRON:
1210       aFirstColIds = FirstTetrahedronIds;
1211       aLastColIds  = LastTetrahedronIds;
1212       break;
1213     case QUAD_PYRAMID:
1214       aFirstColIds = FirstPyramidIds;
1215       aLastColIds  = LastPyramidIds;
1216       break;
1217     case QUAD_PENTAHEDRON:
1218       aFirstColIds = FirstPentahedronIds;
1219       aLastColIds  = LastPentahedronIds;
1220       break; 
1221     case QUAD_HEXAHEDRON:
1222       aFirstColIds = FirstHexahedronIds;
1223       aLastColIds  = LastHexahedronIds;
1224       break;
1225     }
1226     
1227     // fill the First and the Last columns
1228     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1229       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1230     
1231     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1232       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1233   }
1234   else
1235   {
1236     // clear table
1237     for ( int row = 0; row < myTable->rowCount(); row++ )
1238       for ( int col = 0; col < myTable->columnCount(); col++ )
1239         if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1240     
1241     myTable->setEnabled( false );
1242   }
1243 }
1244
1245
1246 //=================================================================================
1247 // function : onTableActivate()
1248 // purpose  :
1249 //=================================================================================
1250 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1251 {
1252   myIsEditCorners = false;
1253   displaySimulation();
1254   updateButtons();
1255 }
1256
1257
1258 //=================================================================================
1259 // function : onCellTextChange()
1260 // purpose  :
1261 //=================================================================================
1262 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1263 {
1264   myIsEditCorners = false;
1265   displaySimulation();
1266   updateButtons();
1267 }
1268
1269 //=================================================================================
1270 // function : keyPressEvent()
1271 // purpose  :
1272 //=================================================================================
1273 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1274 {
1275   QDialog::keyPressEvent( e );
1276   if ( e->isAccepted() )
1277     return;
1278
1279   if ( e->key() == Qt::Key_F1 ) {
1280     e->accept();
1281     ClickOnHelp();
1282   }
1283 }
1284
1285 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1286 {
1287   bool valid = IsValid();
1288   buttonOk->setEnabled( valid );
1289   buttonApply->setEnabled( valid );
1290 }
1291
1292 //=================================================================================
1293 // function : isValid
1294 // purpose  :
1295 //=================================================================================
1296 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1297 {
1298   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1299     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
1300     return false;
1301   }
1302   return true;
1303 }