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