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