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