Salome HOME
+//#define MESSAGE(m) {cout<<m<<endl;}
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_EditMeshDlg.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 #include "SMESHGUI_EditMeshDlg.h"
23
24 #include "SMESHGUI.h"
25 #include "SMESHGUI_Utils.h"
26 #include "SMESHGUI_VTKUtils.h"
27 #include "SMESHGUI_IdValidator.h"
28 #include "SMESHGUI_SpinBox.h"
29
30 #include "SMESH_Actor.h"
31 #include "SMESH_TypeFilter.hxx"
32 #include "SMESH_LogicalFilter.hxx"
33 #include "SMESHGUI_MeshUtils.h"
34 #include "SMDS_Mesh.hxx"
35
36 #include "GEOMBase.h"
37
38 #include "SUIT_ResourceMgr.h"
39 #include "SUIT_Session.h"
40 #include "SUIT_MessageBox.h"
41
42 #include "LightApp_Application.h"
43
44 #include "SVTK_ViewModel.h"
45 #include "SVTK_ViewWindow.h"
46 #include "SVTK_Selector.h"
47 #include "SVTK_Selection.h"
48 #include "SALOME_ListIO.hxx"
49
50 #include "utilities.h"
51
52 // OCCT Includes
53 #include <gp_XYZ.hxx>
54 #include <TColStd_MapOfInteger.hxx>
55 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
56
57 //IDL Headers
58 #include CORBA_SERVER_HEADER(SMESH_Group)
59
60 // VTK Includes
61 #include <vtkUnstructuredGrid.h>
62 #include <vtkRenderer.h>
63 #include <vtkActor2D.h>
64 #include <vtkPoints.h>
65 #include <vtkDataSetMapper.h>
66 #include <vtkMaskPoints.h>
67 #include <vtkSelectVisiblePoints.h>
68 #include <vtkLabeledDataMapper.h>
69 #include <vtkTextProperty.h>
70 #include <vtkIntArray.h>
71 #include <vtkPolyData.h>
72 #include <vtkProperty2D.h>
73 #include <vtkPointData.h>
74
75 // QT Includes
76 #include <qapplication.h>
77 #include <qbuttongroup.h>
78 #include <qgroupbox.h>
79 #include <qlabel.h>
80 #include <qlineedit.h>
81 #include <qlistbox.h>
82 #include <qlistview.h>
83 #include <qpushbutton.h>
84 #include <qradiobutton.h>
85 #include <qcheckbox.h>
86 #include <qlayout.h>
87 #include <qpixmap.h>
88 #include <qheader.h>
89
90 using namespace std;
91
92 namespace SMESH {
93   class TIdPreview { // to display in the viewer IDs of the selected elements
94     SVTK_ViewWindow* myViewWindow;
95
96     vtkUnstructuredGrid* myIdGrid;
97     SALOME_Actor* myIdActor;
98
99     vtkUnstructuredGrid* myPointsNumDataSet;
100     vtkMaskPoints* myPtsMaskPoints;
101     vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
102     vtkLabeledDataMapper* myPtsLabeledDataMapper;
103     vtkTextProperty* aPtsTextProp;
104     bool myIsPointsLabeled;
105     vtkActor2D* myPointLabels;
106
107     vector<int> myIDs;
108
109   public:
110     TIdPreview(SVTK_ViewWindow* theViewWindow):
111       myViewWindow(theViewWindow)
112     {
113       myIdGrid = vtkUnstructuredGrid::New();
114
115       // Create and display actor
116       vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
117       aMapper->SetInput( myIdGrid );
118
119       myIdActor = SALOME_Actor::New();
120       myIdActor->SetInfinitive(true);
121       myIdActor->VisibilityOff();
122       myIdActor->PickableOff();
123
124       myIdActor->SetMapper( aMapper );
125       aMapper->Delete();
126
127       myViewWindow->AddActor(myIdActor);
128
129       //Definition of points numbering pipeline
130       myPointsNumDataSet = vtkUnstructuredGrid::New();
131
132       myPtsMaskPoints = vtkMaskPoints::New();
133       myPtsMaskPoints->SetInput(myPointsNumDataSet);
134       myPtsMaskPoints->SetOnRatio(1);
135
136       myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
137       myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
138       myPtsSelectVisiblePoints->SelectInvisibleOff();
139       myPtsSelectVisiblePoints->SetTolerance(0.1);
140     
141       myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
142       myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
143       myPtsLabeledDataMapper->SetLabelFormat("%g");
144       myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
145     
146       vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
147       aPtsTextProp->SetFontFamilyToTimes();
148       static int aPointsFontSize = 12;
149       aPtsTextProp->SetFontSize(aPointsFontSize);
150       aPtsTextProp->SetBold(1);
151       aPtsTextProp->SetItalic(0);
152       aPtsTextProp->SetShadow(0);
153       myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
154       aPtsTextProp->Delete();
155   
156       myIsPointsLabeled = false;
157
158       myPointLabels = vtkActor2D::New();
159       myPointLabels->SetMapper(myPtsLabeledDataMapper);
160       myPointLabels->GetProperty()->SetColor(1,1,1);
161       myPointLabels->SetVisibility(myIsPointsLabeled);
162
163       AddToRender(myViewWindow->getRenderer());
164     }
165
166     void SetPointsData ( SMDS_Mesh* theMesh, 
167                          TColStd_MapOfInteger & theNodesIdMap )
168     {
169       vtkPoints* aPoints = vtkPoints::New();
170       aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
171       myIDs.clear();
172       
173       TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
174       for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
175         const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
176         aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
177         myIDs.push_back(idIter.Key());
178       }
179
180       myIdGrid->SetPoints(aPoints);
181
182       aPoints->Delete();
183
184       myIdActor->GetMapper()->Update();
185     }
186
187     void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, 
188                        list<gp_XYZ> & aGrCentersXYZ )
189     {
190       vtkPoints* aPoints = vtkPoints::New();
191       aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
192       myIDs.clear();
193       
194       TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
195       for( ; idIter.More(); idIter.Next() ) {
196         myIDs.push_back(idIter.Key());
197       }
198
199       gp_XYZ aXYZ;
200       list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
201       for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
202         aXYZ = *coordIt;
203         aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
204       }
205       myIdGrid->SetPoints(aPoints);
206       aPoints->Delete();
207       
208       myIdActor->GetMapper()->Update();
209     }
210
211     void AddToRender(vtkRenderer* theRenderer)
212     {
213       myIdActor->AddToRender(theRenderer);
214
215       myPtsSelectVisiblePoints->SetRenderer(theRenderer);
216       theRenderer->AddActor2D(myPointLabels);
217     }
218
219     void RemoveFromRender(vtkRenderer* theRenderer)
220     {
221       myIdActor->RemoveFromRender(theRenderer);
222
223       myPtsSelectVisiblePoints->SetRenderer(theRenderer);
224       theRenderer->RemoveActor(myPointLabels);
225     }
226
227     void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
228     {
229       myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
230       
231       if ( myIsPointsLabeled ) {
232         myPointsNumDataSet->ShallowCopy(myIdGrid);
233         vtkDataSet *aDataSet = myPointsNumDataSet;
234         int aNbElem = myIDs.size();
235         vtkIntArray *anArray = vtkIntArray::New();
236         anArray->SetNumberOfValues( aNbElem );
237         for ( int i = 0; i < aNbElem; i++ )
238           anArray->SetValue( i, myIDs[i] );
239         aDataSet->GetPointData()->SetScalars( anArray );
240         anArray->Delete();
241         myPtsMaskPoints->SetInput( aDataSet );
242         myPointLabels->SetVisibility( theIsActorVisible );
243       }
244       else {
245         myPointLabels->SetVisibility( false );
246       }
247     }
248     
249     ~TIdPreview()
250     {
251       RemoveFromRender(myViewWindow->getRenderer());
252
253       myIdGrid->Delete();
254
255       myViewWindow->RemoveActor(myIdActor);
256       myIdActor->Delete();
257
258       //Deleting of points numbering pipeline
259       //---------------------------------------
260       myPointsNumDataSet->Delete();
261       
262       //myPtsLabeledDataMapper->RemoveAllInputs();        //vtk 5.0 porting
263       myPtsLabeledDataMapper->Delete();
264
265       //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
266       myPtsSelectVisiblePoints->Delete();
267
268       //myPtsMaskPoints->UnRegisterAllOutputs();          //vtk 5.0 porting
269       myPtsMaskPoints->Delete();
270
271       myPointLabels->Delete();
272
273 //       myTimeStamp->Delete();
274     }
275   };
276 }
277
278 static const char * IconFirst[] = {
279 "18 10 2 1",
280 "       g None",
281 ".      g #000000",
282 "         .     .  ",
283 "  ..    ..    ..  ",
284 "  ..   ...   ...  ",
285 "  ..  ....  ....  ",
286 "  .. ..... .....  ",
287 "  .. ..... .....  ",
288 "  ..  ....  ....  ",
289 "  ..   ...   ...  ",
290 "  ..    ..    ..  ",
291 "         .     .  "};
292
293 //=================================================================================
294 // class    : SMESHGUI_EditMeshDlg()
295 // purpose  :
296 //=================================================================================
297 SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, 
298                                             int theAction)
299   : QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_EditMeshDlg", false, WStyle_Customize |
300             WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
301     mySMESHGUI(theModule),
302     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
303     myAction(theAction)
304 {
305   setCaption(tr("SMESH_MERGE_NODES"));
306
307   myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
308
309   SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
310   QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
311   QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
312   QPixmap IconSelect     (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
313   QPixmap IconAdd        (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
314   QPixmap IconRemove     (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
315
316   setSizeGripEnabled(TRUE);
317   DlgLayout = new QGridLayout (this);
318   DlgLayout->setSpacing(6);
319   DlgLayout->setMargin(11);
320
321   /***************************************************************/
322   GroupConstructors = new QButtonGroup (this, "GroupConstructors");
323   GroupConstructors->setTitle(tr("SMESH_MERGE_NODES"));
324   GroupConstructors->setExclusive(TRUE);
325   GroupConstructors->setColumnLayout(0, Qt::Vertical);
326   GroupConstructors->layout()->setSpacing(0);
327   GroupConstructors->layout()->setMargin(0);
328   GroupConstructorsLayout = new QGridLayout(GroupConstructors->layout());
329   GroupConstructorsLayout->setAlignment(Qt::AlignTop);
330   GroupConstructorsLayout->setSpacing(6);
331   GroupConstructorsLayout->setMargin(11);
332   RadioButton = new QRadioButton(GroupConstructors, "RadioButton");
333   RadioButton->setPixmap(IconMergeNodes);
334   if (myAction == 1) RadioButton->setPixmap(IconMergeElems);
335   RadioButton->setChecked(TRUE);
336   GroupConstructorsLayout->addWidget(RadioButton, 0, 0);
337   DlgLayout->addWidget(GroupConstructors, 0, 0);
338
339   /***************************************************************/
340   GroupButtons = new QGroupBox (this, "GroupButtons");
341   GroupButtons->setTitle(tr("" ));
342   GroupButtons->setColumnLayout(0, Qt::Vertical);
343   GroupButtons->layout()->setSpacing(0);
344   GroupButtons->layout()->setMargin(0);
345   GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
346   GroupButtonsLayout->setAlignment(Qt::AlignTop);
347   GroupButtonsLayout->setSpacing(6);
348   GroupButtonsLayout->setMargin(11);
349   buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
350   buttonHelp->setText(tr("SMESH_BUT_HELP" ));
351   buttonHelp->setAutoDefault(TRUE);
352   GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
353   buttonCancel = new QPushButton(GroupButtons, "buttonCancel");
354   buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
355   buttonCancel->setAutoDefault(TRUE);
356   GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
357   buttonApply = new QPushButton(GroupButtons, "buttonApply");
358   buttonApply->setText(tr("SMESH_BUT_APPLY" ));
359   buttonApply->setAutoDefault(TRUE);
360   GroupButtonsLayout->addWidget(buttonApply, 0, 1);
361   QSpacerItem* spacer3 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
362   GroupButtonsLayout->addItem(spacer3, 0, 2);
363   buttonOk = new QPushButton(GroupButtons, "buttonOk");
364   buttonOk->setText(tr("SMESH_BUT_APPLY_AND_CLOSE" ));
365   buttonOk->setAutoDefault(TRUE);
366   buttonOk->setDefault(TRUE);
367   GroupButtonsLayout->addWidget(buttonOk, 0, 0);
368   DlgLayout->addWidget(GroupButtons, 4, 0);
369
370   /***************************************************************/
371
372   // Controls for mesh defining
373   GroupMesh = new QGroupBox(this, "GroupMesh");
374   GroupMesh->setTitle(tr("SMESH_SELECT_WHOLE_MESH"));
375   GroupMesh->setColumnLayout(0, Qt::Vertical);
376   GroupMesh->layout()->setSpacing(0);
377   GroupMesh->layout()->setMargin(0);
378   GroupMeshLayout = new QGridLayout(GroupMesh->layout());
379   GroupMeshLayout->setAlignment(Qt::AlignTop);
380   GroupMeshLayout->setSpacing(6);
381   GroupMeshLayout->setMargin(11);
382
383   TextLabelName = new QLabel(GroupMesh, "TextLabelName");
384   TextLabelName->setText(tr("SMESH_NAME"));
385   GroupMeshLayout->addWidget(TextLabelName, 0, 0);
386
387   SelectMeshButton = new QPushButton(GroupMesh, "SelectMeshButton");
388   SelectMeshButton->setPixmap(IconSelect);
389   GroupMeshLayout->addWidget(SelectMeshButton, 0, 1);
390
391   LineEditMesh = new QLineEdit(GroupMesh, "LineEditMesh");
392   LineEditMesh->setReadOnly(true);
393   GroupMeshLayout->addWidget(LineEditMesh, 0, 2);
394
395   DlgLayout->addWidget(GroupMesh, 1, 0);
396
397   /***************************************************************/
398
399   // Controls for coincident elements detecting
400   GroupCoincident = new QGroupBox(this, "GroupCoincident");
401   GroupCoincident->setTitle(tr("COINCIDENT_NODES"));
402   GroupCoincident->setColumnLayout(0, Qt::Vertical);
403   GroupCoincident->layout()->setSpacing(0);
404   GroupCoincident->layout()->setMargin(0);
405   GroupCoincidentLayout = new QGridLayout(GroupCoincident->layout());
406   GroupCoincidentLayout->setAlignment(Qt::AlignTop);
407   GroupCoincidentLayout->setSpacing(6);
408   GroupCoincidentLayout->setMargin(11);
409   
410   if (myAction == 0) { // case merge nodes
411     TextLabelTolerance = new QLabel(GroupCoincident, "TextLabelTolerance");
412     TextLabelTolerance->setText(tr("SMESH_TOLERANCE"));
413     TextLabelTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
414     GroupCoincidentLayout->addWidget(TextLabelTolerance, 0, 0);
415
416     SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident, "SpinBoxTolerance");
417     GroupCoincidentLayout->addWidget(SpinBoxTolerance, 0, 1);
418   }
419
420   DetectButton = new QPushButton(GroupCoincident, "DetectButton");
421   DetectButton->setText(tr("DETECT"));
422   DetectButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
423   GroupCoincidentLayout->addWidget(DetectButton, 0, 2);
424
425   ListCoincident = new QListBox(GroupCoincident, "ListCoincident");
426   ListCoincident->setSelectionMode(QListBox::Extended);
427   if (myAction == 0) // case merge nodes
428     GroupCoincidentLayout->addMultiCellWidget(ListCoincident, 1, 3, 0, 1);
429   else // case merge elements
430     GroupCoincidentLayout->addMultiCellWidget(ListCoincident, 0, 3, 0, 1);
431
432   QSpacerItem* spacer1 = new QSpacerItem(20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding);
433   GroupCoincidentLayout->addItem(spacer1, 1, 2);
434
435   AddGroupButton = new QPushButton(GroupCoincident, "AddGroupButton");
436   AddGroupButton->setText(tr("SMESH_BUT_ADD"));
437   GroupCoincidentLayout->addWidget(AddGroupButton, 2, 2);
438
439   RemoveGroupButton = new QPushButton(GroupCoincident, "RemoveGroupButton");
440   RemoveGroupButton->setText(tr("SMESH_BUT_REMOVE"));
441   GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
442
443   SelectAllCB = new QCheckBox(GroupCoincident, "SelectAllCB");
444   SelectAllCB->setText(tr("SELECT_ALL"));
445   GroupCoincidentLayout->addWidget(SelectAllCB, 4, 0);
446
447   DlgLayout->addWidget(GroupCoincident, 2, 0);
448
449   /***************************************************************/
450
451   // Controls for editing the selected group
452   GroupEdit = new QGroupBox(this, "GroupEdit");
453   GroupEdit->setTitle(tr("EDIT_SELECTED_GROUP"));
454   GroupEdit->setColumnLayout(0, Qt::Vertical);
455   GroupEdit->layout()->setSpacing(0);
456   GroupEdit->layout()->setMargin(0);
457   GroupEditLayout = new QGridLayout(GroupEdit->layout());
458   GroupEditLayout->setAlignment(Qt::AlignTop);
459   GroupEditLayout->setSpacing(6);
460   GroupEditLayout->setMargin(11);
461
462   ListEdit = new QListBox(GroupEdit, "ListEdit");
463   ListEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
464   ListEdit->setRowMode(QListBox::FixedNumber);
465   ListEdit->setMinimumHeight(ListEdit->sizeHint().height());
466   ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
467   ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
468   ListEdit->setSelectionMode(QListBox::Extended);
469   GroupEditLayout->addMultiCellWidget(ListEdit, 0, 1, 0, 0);
470
471   AddElemButton = new QPushButton(GroupEdit, "AddElemButton");
472   AddElemButton->setPixmap(IconAdd);
473   GroupEditLayout->addWidget(AddElemButton, 0, 1);
474
475   RemoveElemButton = new QPushButton(GroupEdit, "RemoveElemButton");
476   RemoveElemButton->setPixmap(IconRemove);
477   GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
478
479   SetFirstButton = new QPushButton(GroupEdit, "SetFirstButton");
480   SetFirstButton->setIconSet(QPixmap(IconFirst));
481   SetFirstButton->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
482   GroupEditLayout->addMultiCellWidget(SetFirstButton, 1, 1, 1, 2);
483
484   DlgLayout->addWidget(GroupEdit, 3, 0);
485
486   Init(); // Initialisations
487 }
488
489 //=================================================================================
490 // function : ~SMESHGUI_EditMeshDlg()
491 // purpose  : Destroys the object and frees any allocated resources
492 //=================================================================================
493 SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
494 {
495   // no need to delete child widgets, Qt does it all for us
496   delete myIdPreview;
497 }
498
499 //=================================================================================
500 // function : Init()
501 // purpose  :
502 //=================================================================================
503 void SMESHGUI_EditMeshDlg::Init()
504 {
505   if (myAction == 0) {
506     SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.1, 3);
507     SpinBoxTolerance->SetValue(1e-05);
508   }
509
510   RadioButton->setChecked(TRUE);
511
512   myEditCurrentArgument = (QWidget*)LineEditMesh; 
513
514   myActor = 0;
515   mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
516
517   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
518
519   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
520   myIsBusy = false;
521   
522   // Costruction of the logical filter
523   SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
524   SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
525   
526   QPtrList<SUIT_SelectionFilter> aListOfFilters;
527   if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
528   if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
529
530   myMeshOrSubMeshOrGroupFilter =
531     new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
532   
533   /* signals and slots connections */
534   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
535   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
536   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
537   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
538
539   connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
540   connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
541   connect(ListCoincident, SIGNAL (selectionChanged()), this, SLOT(onSelectGroup()));
542   connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
543   connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
544   connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
545   connect(ListEdit, SIGNAL (selectionChanged()), this, SLOT(onSelectElementFromGroup()));
546   connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
547   connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
548   connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
549
550   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
551   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
552   /* to close dialog if study change */
553   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
554
555   this->show(); /* displays Dialog */
556   
557   SetFirstButton->setEnabled(false);
558   buttonOk->setEnabled(false);
559   buttonApply->setEnabled(false);
560
561   // Init Mesh field from selection
562   SelectionIntoArgument();
563
564   // dialog customization
565   if (myAction == 1) {
566     setCaption(tr("SMESH_MERGE_ELEMENTS"));
567     GroupConstructors->setTitle(tr("SMESH_MERGE_ELEMENTS"));
568     GroupCoincident->setTitle(tr("COINCIDENT_ELEMENTS"));
569   }
570     
571   myHelpFileName = "merging_elements_page.html";
572 }
573
574 //=================================================================================
575 // function : FindGravityCenter()
576 // purpose  :
577 //=================================================================================
578 void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
579                                              list< gp_XYZ > & theGrCentersXYZ)
580 {
581   if (!myActor)
582     return;
583
584   SMDS_Mesh* aMesh = 0;
585   aMesh = myActor->GetObject()->GetMesh();
586   if (!aMesh)
587     return;
588
589   int nbNodes;
590
591   TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
592   for( ; idIter.More(); idIter.Next() ) {
593     const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
594     if ( !anElem )
595       continue;
596
597     gp_XYZ anXYZ(0., 0., 0.);
598     SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
599     for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
600       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
601       anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
602     }
603     anXYZ.Divide( nbNodes );
604     
605     theGrCentersXYZ.push_back( anXYZ );
606   }
607 }
608
609 //=================================================================================
610 // function : ClickOnApply()
611 // purpose  :
612 //=================================================================================
613 bool SMESHGUI_EditMeshDlg::ClickOnApply()
614 {
615   if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
616     return false;
617
618   try {
619     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
620
621     QApplication::setOverrideCursor(Qt::waitCursor);
622
623     SMESH::long_array_var anIds = new SMESH::long_array;
624     SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
625
626     aGroupsOfElements->length(ListCoincident->count());
627     QListBoxItem* item = ListCoincident->firstItem();
628
629     int anArrayNum = 0;
630     while (item) {
631       QStringList aListIds = QStringList("");
632       aListIds = QStringList::split(" ", item->text(), false);
633
634       anIds->length(aListIds.count());
635       for (int i = 0; i < aListIds.count(); i++)
636         anIds[i] = aListIds[i].toInt();
637
638       aGroupsOfElements[anArrayNum++] = anIds.inout();
639       item = item->next();
640     }
641
642     if( myAction == 0 )
643       aMeshEditor->MergeNodes (aGroupsOfElements.inout());
644     else
645       aMeshEditor->MergeElements (aGroupsOfElements.inout());
646
647     QApplication::restoreOverrideCursor();
648   } catch(...) {
649   }
650   
651   SMESH::UpdateView();
652
653   onDetect();
654   return true;
655 }
656
657 //=================================================================================
658 // function : ClickOnOk()
659 // purpose  :
660 //=================================================================================
661 void SMESHGUI_EditMeshDlg::ClickOnOk()
662 {
663   if (ClickOnApply())
664     ClickOnCancel();
665 }
666
667 //=================================================================================
668 // function : ClickOnCancel()
669 // purpose  :
670 //=================================================================================
671 void SMESHGUI_EditMeshDlg::ClickOnCancel()
672 {
673   myIdPreview->SetPointsLabeled(false);
674   mySelectionMgr->clearFilters();
675   //mySelectionMgr->clearSelected();
676   SMESH::SetPointRepresentation(false);
677   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
678     aViewWindow->SetSelectionMode(ActorSelection);
679   disconnect(mySelectionMgr, 0, this, 0);
680   mySMESHGUI->ResetState();
681   reject();
682 }
683
684 //=================================================================================
685 // function : ClickOnHelp()
686 // purpose  :
687 //=================================================================================
688 void SMESHGUI_EditMeshDlg::ClickOnHelp()
689 {
690   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
691   if (app) 
692     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
693   else {
694                 QString platform;
695 #ifdef WIN32
696                 platform = "winapplication";
697 #else
698                 platform = "application";
699 #endif
700     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
701                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
702                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
703                            QObject::tr("BUT_OK"));
704   }
705 }
706
707 //=================================================================================
708 // function : onEditGroup()
709 // purpose  :
710 //=================================================================================
711 void SMESHGUI_EditMeshDlg::onEditGroup()
712 {
713   int nbSel = 0;
714   for (int i = 0; i < ListCoincident->count(); i++) {
715     if (ListCoincident->isSelected(i))
716       nbSel++;
717     if (nbSel > 1) {
718       ListEdit->clear();
719       return;
720     }
721   }
722   if (nbSel == 0) {
723     ListEdit->clear();
724     return;
725   }
726
727   QString aNewIds = "";
728
729   QListBoxItem* anItem;
730   for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next())
731     aNewIds+=QString(" %1").arg(anItem->text());
732
733   ListCoincident->changeItem(aNewIds, ListCoincident->currentItem());
734   ListCoincident->setSelected(ListCoincident->currentItem(), true);
735   
736 }
737
738 //=================================================================================
739 // function : updateControls()
740 // purpose  :
741 //=================================================================================
742 void SMESHGUI_EditMeshDlg::updateControls()
743 {
744   if (ListEdit->count() == 0)
745     SetFirstButton->setEnabled(false);
746   bool enable = !(myMesh->_is_nil()) && ListCoincident->count();
747   buttonOk->setEnabled(enable);
748   buttonApply->setEnabled(enable);
749 }
750
751 //=================================================================================
752 // function : onDetect()
753 // purpose  :
754 //=================================================================================
755 void SMESHGUI_EditMeshDlg::onDetect()
756 {
757   if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
758     return;
759
760   try {
761     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
762
763     QApplication::setOverrideCursor(Qt::waitCursor);
764     ListCoincident->clear();
765     ListEdit->clear();
766
767     SMESH::array_of_long_array_var aGroupsArray;
768
769     switch (myAction) {
770     case 0 :
771       if(!mySubMeshOrGroup->_is_nil())
772         aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray);
773       else
774         aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray);
775       break;
776     case 1 :
777       if(!mySubMeshOrGroup->_is_nil())
778         aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray);
779       else
780         aMeshEditor->FindEqualElements(myMesh, aGroupsArray);
781       break;
782     }
783     
784     QListBoxItem* anItem = 0;
785     for (int i = 0; i < aGroupsArray->length(); i++) {
786       SMESH::long_array& aGroup = aGroupsArray[i];
787
788       QString anIDs;
789       for (int j = 0; j < aGroup.length(); j++)
790         anIDs+=QString(" %1").arg(aGroup[j]);
791
792       anItem = new QListBoxText(anIDs);
793       ListCoincident->insertItem(anItem);
794     }
795     QApplication::restoreOverrideCursor();
796   } catch(...) {
797   }
798
799   ListCoincident->selectAll(true);
800   updateControls();
801 }
802
803 //=================================================================================
804 // function : onSelectGroup()
805 // purpose  :
806 //=================================================================================
807 void SMESHGUI_EditMeshDlg::onSelectGroup()
808 {
809   if (myIsBusy || !myActor)
810     return;
811   myEditCurrentArgument = (QWidget*)ListCoincident;
812
813   ListEdit->clear();
814   
815   TColStd_MapOfInteger anIndices;
816   QListBoxItem* anItem;
817   int NbOfSelected = 0;
818   for (anItem = ListCoincident->firstItem(); anItem != 0; anItem = anItem->next()) {
819     if (anItem->isSelected()) {
820       QStringList aListIds = QStringList("");
821       aListIds = QStringList::split(" ", anItem->text(), false);
822       for (int i = 0; i < aListIds.count(); i++)
823         anIndices.Add(aListIds[i].toInt());
824       NbOfSelected++;
825       ListEdit->clear();
826       if (NbOfSelected == 1) {
827         ListEdit->insertStringList(aListIds);
828         ListEdit->selectAll(true);
829       }
830     }
831   }
832   mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
833   SALOME_ListIO aList;
834   aList.Append(myActor->getIO());
835   mySelectionMgr->setSelectedObjects(aList,false);
836   
837   if (myAction == 0) {
838     myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
839     myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
840   }
841   else {
842     list< gp_XYZ > aGrCentersXYZ;
843     FindGravityCenter(anIndices, aGrCentersXYZ);
844     myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
845     myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
846   }
847
848   updateControls();
849 }
850
851 //=================================================================================
852 // function : onSelectAll()
853 // purpose  :
854 //=================================================================================
855 void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled)
856 {
857   ListCoincident->selectAll(isToggled);
858 }
859
860 //=================================================================================
861 // function : onSelectElementFromGroup()
862 // purpose  :
863 //=================================================================================
864 void SMESHGUI_EditMeshDlg::onSelectElementFromGroup()
865 {
866   if (myIsBusy || !myActor)
867     return;
868
869   int nbSel = 0;
870   TColStd_MapOfInteger anIndices;
871   QListBoxItem* anItem;
872   for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next()) {
873     if (anItem->isSelected()) {
874       int anId = anItem->text().toInt();
875       anIndices.Add(anId);
876       nbSel++;
877       if (nbSel == 1)
878         SetFirstButton->setEnabled(true);
879     }
880   }
881   if (nbSel == 0 || nbSel > 1)
882     SetFirstButton->setEnabled(false);
883
884   mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
885   SALOME_ListIO aList;
886   aList.Append(myActor->getIO());
887   mySelectionMgr->setSelectedObjects(aList);
888
889   if (myAction == 0) {
890     myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
891     myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
892   }
893   else {
894     list< gp_XYZ > aGrCentersXYZ;
895     FindGravityCenter(anIndices, aGrCentersXYZ);
896     myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
897     myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
898   }
899 }
900
901 //=================================================================================
902 // function : onAddGroup()
903 // purpose  :
904 //=================================================================================
905 void SMESHGUI_EditMeshDlg::onAddGroup()
906 {
907   if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
908     return;
909
910   QString anIDs = "";
911   SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
912   
913   ListCoincident->clearSelection();
914   QListBoxItem* anItem = new QListBoxText(anIDs);
915   ListCoincident->insertItem(anItem);
916   int nbGroups = ListCoincident->count();
917   if (nbGroups) {
918     ListCoincident->setCurrentItem(nbGroups-1);
919     ListCoincident->setSelected(nbGroups-1, true);
920   }
921   else {
922     ListCoincident->setCurrentItem(0);
923     ListCoincident->setSelected(0, true);
924   }
925
926   updateControls();
927 }
928
929 //=================================================================================
930 // function : onRemoveGroup()
931 // purpose  :
932 //=================================================================================
933 void SMESHGUI_EditMeshDlg::onRemoveGroup()
934 {
935   if (myEditCurrentArgument != (QWidget*)ListCoincident)
936     return;
937   myIsBusy = true;
938
939   for (int i = ListCoincident->count(); i > 0; i--)
940     if (ListCoincident->isSelected(i-1))
941       ListCoincident->removeItem(i-1);
942
943   ListEdit->clear();
944   updateControls();
945
946   myIsBusy = false;
947 }
948
949 //=================================================================================
950 // function : onAddElement()
951 // purpose  :
952 //=================================================================================
953 void SMESHGUI_EditMeshDlg::onAddElement()
954 {
955   if (!myActor)
956     return;
957   myIsBusy = true;
958
959   QString aListStr = "";
960   int aNbNnodes = 0;
961
962   aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
963   if (aNbNnodes < 1)
964     return;
965
966   QStringList aNodes = QStringList::split(" ", aListStr);
967   QListBoxItem* anItem = 0;
968
969   for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
970     anItem = ListEdit->findItem(*it, Qt::ExactMatch);
971     if (!anItem) {
972       anItem = new QListBoxText(*it);
973       ListEdit->insertItem(anItem);
974     }
975     ListEdit->setSelected(anItem, true);
976   }
977
978   myIsBusy = false;
979   onEditGroup();
980 }
981
982 //=================================================================================
983 // function : onRemoveElement()
984 // purpose  :
985 //=================================================================================
986 void SMESHGUI_EditMeshDlg::onRemoveElement()
987 {
988   if (myEditCurrentArgument != (QWidget*)ListCoincident)
989     return;
990   myIsBusy = true;
991
992   for (int i = ListEdit->count(); i > 0; i--)
993     if (ListEdit->isSelected(i-1))
994       ListEdit->removeItem(i-1);
995
996   myIsBusy = false;
997   onEditGroup();
998 }
999
1000 //=================================================================================
1001 // function : onSetFirst()
1002 // purpose  :
1003 //=================================================================================
1004 void SMESHGUI_EditMeshDlg::onSetFirst()
1005 {
1006   if (myEditCurrentArgument != (QWidget*)ListCoincident)
1007     return;
1008   myIsBusy = true;
1009   
1010   QListBoxItem* anItem;
1011   for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next()) {
1012     if (anItem->isSelected()) {
1013       ListEdit->takeItem(anItem);
1014       ListEdit->insertItem(anItem, 0);
1015     }
1016   }
1017
1018   myIsBusy = false;
1019   onEditGroup();
1020 }
1021
1022 //=================================================================================
1023 // function : SetEditCurrentArgument()
1024 // purpose  :
1025 //=================================================================================
1026 void SMESHGUI_EditMeshDlg::SetEditCurrentArgument()
1027 {
1028   QPushButton* send = (QPushButton*)sender();
1029
1030   disconnect(mySelectionMgr, 0, this, 0);
1031   mySelectionMgr->clearSelected();
1032   mySelectionMgr->clearFilters();
1033
1034   if (send == SelectMeshButton) {
1035     myEditCurrentArgument = (QWidget*)LineEditMesh;
1036     SMESH::SetPointRepresentation(false);
1037     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1038       aViewWindow->SetSelectionMode(ActorSelection);
1039     mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
1040   }
1041
1042   myEditCurrentArgument->setFocus();
1043   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1044   SelectionIntoArgument();
1045 }
1046
1047 //=================================================================================
1048 // function : SelectionIntoArgument()
1049 // purpose  : Called when selection as changed or other case
1050 //=================================================================================
1051 void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
1052 {
1053   if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
1054     QString aString = "";
1055     LineEditMesh->setText(aString);
1056     
1057     ListCoincident->clear();
1058     ListEdit->clear();
1059     myActor = 0;
1060     
1061     int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
1062     if (nbSel != 1)
1063       return;
1064
1065     SALOME_ListIO aList;
1066     mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
1067     
1068     Handle(SALOME_InteractiveObject) IO = aList.First();
1069     myMesh = SMESH::GetMeshByIO(IO);
1070     
1071     if (myMesh->_is_nil())
1072       return;
1073     
1074     myActor = SMESH::FindActorByEntry(IO->getEntry());
1075     if (!myActor)
1076       myActor = SMESH::FindActorByObject(myMesh);
1077     if(!myActor)
1078       return;
1079     
1080     mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
1081     
1082     if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
1083          !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
1084         !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
1085       mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
1086      
1087     LineEditMesh->setText(aString);
1088
1089     if (myAction == 0) {
1090       SMESH::SetPointRepresentation(true);
1091       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1092         aViewWindow->SetSelectionMode(NodeSelection);
1093     }
1094     else
1095       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1096         aViewWindow->SetSelectionMode(CellSelection);
1097   }
1098 }
1099
1100 //=================================================================================
1101 // function : DeactivateActiveDialog()
1102 // purpose  :
1103 //=================================================================================
1104 void SMESHGUI_EditMeshDlg::DeactivateActiveDialog()
1105 {
1106   if (GroupConstructors->isEnabled()) {
1107     GroupConstructors->setEnabled(false);
1108     GroupMesh->setEnabled(false);
1109     GroupCoincident->setEnabled(false);
1110     GroupEdit->setEnabled(false);
1111     GroupButtons->setEnabled(false);
1112     mySMESHGUI->ResetState();
1113     mySMESHGUI->SetActiveDialogBox(0);
1114   }
1115
1116   mySelectionMgr->clearSelected();
1117   disconnect(mySelectionMgr, 0, this, 0);
1118 }
1119
1120 //=================================================================================
1121 // function : ActivateThisDialog()
1122 // purpose  :
1123 //=================================================================================
1124 void SMESHGUI_EditMeshDlg::ActivateThisDialog()
1125 {
1126   /* Emit a signal to deactivate the active dialog */
1127   mySMESHGUI->EmitSignalDeactivateDialog();
1128   GroupConstructors->setEnabled(true);
1129   GroupMesh->setEnabled(true);
1130   GroupCoincident->setEnabled(true);
1131   GroupEdit->setEnabled(true);
1132   GroupButtons->setEnabled(true);
1133
1134   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1135   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
1136   SelectionIntoArgument();
1137 }
1138
1139 //=================================================================================
1140 // function : enterEvent()
1141 // purpose  :
1142 //=================================================================================
1143 void SMESHGUI_EditMeshDlg::enterEvent(QEvent*)
1144 {
1145   if (!GroupConstructors->isEnabled())
1146     ActivateThisDialog();
1147 }
1148
1149 //=================================================================================
1150 // function : closeEvent()
1151 // purpose  :
1152 //=================================================================================
1153 void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*)
1154 {
1155   /* same than click on cancel button */
1156   this->ClickOnCancel();
1157 }
1158
1159 //=======================================================================
1160 //function : hideEvent
1161 //purpose  : caused by ESC key
1162 //=======================================================================
1163 void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *)
1164 {
1165   if (!isMinimized())
1166     ClickOnCancel();
1167 }
1168
1169 //=================================================================================
1170 // function : keyPressEvent()
1171 // purpose  :
1172 //=================================================================================
1173 void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e)
1174 {
1175   QDialog::keyPressEvent( e );
1176   if ( e->isAccepted() )
1177     return;
1178
1179   if ( e->key() == Key_F1 )
1180     {
1181       e->accept();
1182       ClickOnHelp();
1183     }
1184 }