Salome HOME
5c62beb671f9dc2310c08fe19de1fefb0f579e11
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MergeDlg.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_MergeDlg.cxx
25 // Author : Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_MergeDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_MeshUtils.h"
34 #include "SMESHGUI_SpinBox.h"
35
36 #include <SMESH_Actor.h>
37 #include <SMESH_TypeFilter.hxx>
38 #include <SMESH_LogicalFilter.hxx>
39 #include <SMDS_Mesh.hxx>
40
41 // SALOME GUI includes
42 #include <SUIT_Desktop.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_OverrideCursor.h>
47
48 #include <LightApp_Application.h>
49 #include <LightApp_SelectionMgr.h>
50
51 #include <SVTK_ViewModel.h>
52 #include <SVTK_ViewWindow.h>
53 #include <SALOME_ListIO.hxx>
54
55 // OCCT includes
56 #include <TColStd_MapOfInteger.hxx>
57 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
58
59 // IDL includes
60 #include <SALOMEconfig.h>
61 #include CORBA_SERVER_HEADER(SMESH_Group)
62 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
63
64 // VTK includes
65 #include <vtkUnstructuredGrid.h>
66 #include <vtkRenderer.h>
67 #include <vtkActor2D.h>
68 #include <vtkPoints.h>
69 #include <vtkDataSetMapper.h>
70 #include <vtkMaskPoints.h>
71 #include <vtkSelectVisiblePoints.h>
72 #include <vtkLabeledDataMapper.h>
73 #include <vtkTextProperty.h>
74 #include <vtkIntArray.h>
75 #include <vtkProperty2D.h>
76 #include <vtkPointData.h>
77
78 // Qt includes
79 #include <QApplication>
80 #include <QGroupBox>
81 #include <QLabel>
82 #include <QLineEdit>
83 #include <QListWidget>
84 #include <QPushButton>
85 #include <QRadioButton>
86 #include <QCheckBox>
87 #include <QHBoxLayout>
88 #include <QVBoxLayout>
89 #include <QGridLayout>
90 #include <QKeyEvent>
91 #include <QButtonGroup>
92
93 #define SPACING 6
94 #define MARGIN  11
95
96 namespace
97 {
98   enum ActionType { MERGE_NODES, MERGE_ELEMENTS };
99 }
100 namespace SMESH
101 {
102   class TIdPreview
103   { // to display in the viewer IDs of the selected elements
104     SVTK_ViewWindow* myViewWindow;
105
106     vtkUnstructuredGrid* myIdGrid;
107     SALOME_Actor* myIdActor;
108
109     vtkUnstructuredGrid* myPointsNumDataSet;
110     vtkMaskPoints* myPtsMaskPoints;
111     vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
112     vtkLabeledDataMapper* myPtsLabeledDataMapper;
113     vtkTextProperty* aPtsTextProp;
114     bool myIsPointsLabeled;
115     vtkActor2D* myPointLabels;
116
117     std::vector<int> myIDs;
118
119   public:
120     TIdPreview(SVTK_ViewWindow* theViewWindow):
121       myViewWindow(theViewWindow)
122     {
123       myIdGrid = vtkUnstructuredGrid::New();
124
125       // Create and display actor
126       vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
127       aMapper->SetInputData( myIdGrid );
128
129       myIdActor = SALOME_Actor::New();
130       myIdActor->SetInfinitive(true);
131       myIdActor->VisibilityOff();
132       myIdActor->PickableOff();
133
134       myIdActor->SetMapper( aMapper );
135       aMapper->Delete();
136
137       myViewWindow->AddActor(myIdActor);
138
139       //Definition of points numbering pipeline
140       myPointsNumDataSet = vtkUnstructuredGrid::New();
141
142       myPtsMaskPoints = vtkMaskPoints::New();
143       myPtsMaskPoints->SetInputData(myPointsNumDataSet);
144       myPtsMaskPoints->SetOnRatio(1);
145
146       myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
147       myPtsSelectVisiblePoints->SetInputConnection(myPtsMaskPoints->GetOutputPort());
148       myPtsSelectVisiblePoints->SelectInvisibleOff();
149       myPtsSelectVisiblePoints->SetTolerance(0.1);
150     
151       myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
152       myPtsLabeledDataMapper->SetInputConnection(myPtsSelectVisiblePoints->GetOutputPort());
153       myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
154     
155       vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
156       aPtsTextProp->SetFontFamilyToTimes();
157       static int aPointsFontSize = 12;
158       aPtsTextProp->SetFontSize(aPointsFontSize);
159       aPtsTextProp->SetBold(1);
160       aPtsTextProp->SetItalic(0);
161       aPtsTextProp->SetShadow(0);
162       myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
163       aPtsTextProp->Delete();
164   
165       myIsPointsLabeled = false;
166
167       myPointLabels = vtkActor2D::New();
168       myPointLabels->SetMapper(myPtsLabeledDataMapper);
169       myPointLabels->GetProperty()->SetColor(1,1,1);
170       myPointLabels->SetVisibility(myIsPointsLabeled);
171
172       AddToRender(myViewWindow->getRenderer());
173     }
174
175     void SetPointsData ( SMDS_Mesh* theMesh, 
176                          TColStd_MapOfInteger & theNodesIdMap )
177     {
178       vtkPoints* aPoints = vtkPoints::New();
179       aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
180       myIDs.clear();
181       
182       TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
183       for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
184         const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
185         aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
186         myIDs.push_back(idIter.Key());
187       }
188
189       myIdGrid->SetPoints(aPoints);
190
191       aPoints->Delete();
192
193       myIdActor->GetMapper()->Update();
194     }
195
196     void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, 
197                        std::list<gp_XYZ> & aGrCentersXYZ )
198     {
199       vtkPoints* aPoints = vtkPoints::New();
200       aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
201       myIDs.clear();
202       
203       TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
204       for( ; idIter.More(); idIter.Next() ) {
205         myIDs.push_back(idIter.Key());
206       }
207
208       gp_XYZ aXYZ;
209       std::list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
210       for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
211         aXYZ = *coordIt;
212         aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
213       }
214       myIdGrid->SetPoints(aPoints);
215       aPoints->Delete();
216       
217       myIdActor->GetMapper()->Update();
218     }
219
220     void AddToRender(vtkRenderer* theRenderer)
221     {
222       myIdActor->AddToRender(theRenderer);
223
224       myPtsSelectVisiblePoints->SetRenderer(theRenderer);
225       theRenderer->AddActor2D(myPointLabels);
226     }
227
228     void RemoveFromRender(vtkRenderer* theRenderer)
229     {
230       myIdActor->RemoveFromRender(theRenderer);
231
232       myPtsSelectVisiblePoints->SetRenderer(theRenderer);
233       theRenderer->RemoveActor(myPointLabels);
234     }
235
236     void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
237     {
238       myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
239       
240       if ( myIsPointsLabeled ) {
241         myPointsNumDataSet->ShallowCopy(myIdGrid);
242         vtkDataSet *aDataSet = myPointsNumDataSet;
243         int aNbElem = myIDs.size();
244         vtkIntArray *anArray = vtkIntArray::New();
245         anArray->SetNumberOfValues( aNbElem );
246         for ( int i = 0; i < aNbElem; i++ )
247           anArray->SetValue( i, myIDs[i] );
248         aDataSet->GetPointData()->SetScalars( anArray );
249         anArray->Delete();
250         myPtsMaskPoints->SetInputData( aDataSet );
251         myPointLabels->SetVisibility( theIsActorVisible );
252       }
253       else {
254         myPointLabels->SetVisibility( false );
255       }
256     }
257     
258     ~TIdPreview()
259     {
260       RemoveFromRender(myViewWindow->getRenderer());
261
262       myIdGrid->Delete();
263
264       myViewWindow->RemoveActor(myIdActor);
265       myIdActor->Delete();
266
267       //Deleting of points numbering pipeline
268       //---------------------------------------
269       myPointsNumDataSet->Delete();
270       
271       //myPtsLabeledDataMapper->RemoveAllInputs();        //vtk 5.0 porting
272       myPtsLabeledDataMapper->Delete();
273
274       //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
275       myPtsSelectVisiblePoints->Delete();
276
277       //myPtsMaskPoints->UnRegisterAllOutputs();          //vtk 5.0 porting
278       myPtsMaskPoints->Delete();
279
280       myPointLabels->Delete();
281
282 //       myTimeStamp->Delete();
283     }
284   };
285 }
286
287 static const char * IconFirst[] = {
288 "18 10 2 1",
289 "       g None",
290 ".      g #000000",
291 "         .     .  ",
292 "  ..    ..    ..  ",
293 "  ..   ...   ...  ",
294 "  ..  ....  ....  ",
295 "  .. ..... .....  ",
296 "  .. ..... .....  ",
297 "  ..  ....  ....  ",
298 "  ..   ...   ...  ",
299 "  ..    ..    ..  ",
300 "         .     .  "};
301
302 //=================================================================================
303 // class    : SMESHGUI_MergeDlg()
304 // purpose  :
305 //=================================================================================
306 SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
307   : QDialog(SMESH::GetDesktop(theModule)),
308     mySMESHGUI(theModule),
309     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
310     myAction(theAction)
311 {
312   setModal(false);
313   setAttribute(Qt::WA_DeleteOnClose, true);
314   setWindowTitle(myAction == MERGE_ELEMENTS ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
315
316   myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
317
318   SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
319   QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
320   QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
321   QPixmap IconSelect     (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
322   QPixmap IconAdd        (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
323   QPixmap IconRemove     (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
324
325   setSizeGripEnabled(true);
326
327   QVBoxLayout* DlgLayout = new QVBoxLayout(this);
328   DlgLayout->setSpacing(SPACING);
329   DlgLayout->setMargin(MARGIN);
330
331   /***************************************************************/
332   GroupConstructors = new QGroupBox(myAction == MERGE_ELEMENTS ? 
333                                     tr("SMESH_MERGE_ELEMENTS") : 
334                                     tr("SMESH_MERGE_NODES"), 
335                                     this);
336
337   QButtonGroup* ButtonGroup = new QButtonGroup(this);
338   QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
339   GroupConstructorsLayout->setSpacing(SPACING);
340   GroupConstructorsLayout->setMargin(MARGIN);
341
342   RadioButton = new QRadioButton(GroupConstructors);
343   RadioButton->setIcon(myAction == MERGE_ELEMENTS ? IconMergeElems : IconMergeNodes);
344   RadioButton->setChecked(true);
345   GroupConstructorsLayout->addWidget(RadioButton);
346   ButtonGroup->addButton(RadioButton, 0);
347
348   /***************************************************************/
349   // Controls for mesh defining
350   GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this);
351   QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
352   GroupMeshLayout->setSpacing(SPACING);
353   GroupMeshLayout->setMargin(MARGIN);
354
355   TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh);
356   SelectMeshButton = new QPushButton(GroupMesh);
357   SelectMeshButton->setIcon(IconSelect);
358   LineEditMesh = new QLineEdit(GroupMesh);
359   LineEditMesh->setReadOnly(true);
360
361   GroupMeshLayout->addWidget(TextLabelName);
362   GroupMeshLayout->addWidget(SelectMeshButton);
363   GroupMeshLayout->addWidget(LineEditMesh);
364
365   /***************************************************************/
366   // Controls for switch dialog behaviour
367
368   TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this );
369   GroupType = new QButtonGroup( this );
370   QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( TypeBox );
371   aTypeBoxLayout->setMargin( MARGIN );
372   aTypeBoxLayout->setSpacing( SPACING );
373
374   QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), TypeBox );
375   QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL" ),   TypeBox );
376   GroupType->addButton( rb1, 0 );
377   GroupType->addButton( rb2, 1 );
378   aTypeBoxLayout->addWidget( rb1 );
379   aTypeBoxLayout->addWidget( rb2 );
380
381   myTypeId = 0;
382
383   /***************************************************************/
384   // Controls for coincident elements detecting
385   GroupCoincident = new QGroupBox(myAction == MERGE_ELEMENTS ? 
386                                   tr("COINCIDENT_ELEMENTS") : 
387                                   tr("COINCIDENT_NODES"), 
388                                   this);
389
390   QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident);
391   aCoincidentLayout->setSpacing(SPACING);
392   aCoincidentLayout->setMargin(MARGIN);
393
394   if (myAction == MERGE_NODES) // case merge nodes
395   {
396     QWidget* foo = new QWidget(GroupCoincident);
397     TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), foo);
398     SpinBoxTolerance = new SMESHGUI_SpinBox(foo);
399     SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
400
401     SeparateCornersAndMedium = new QCheckBox(tr("SEPARATE_CORNERS_AND_MEDIUM"), foo);
402     SeparateCornersAndMedium->setEnabled( false );
403
404     GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), foo);
405     GroupExclude->setCheckable( true );
406     GroupExclude->setChecked( false );
407     ListExclude = new QListWidget( GroupExclude );
408     QVBoxLayout* GroupExcludeLayout = new QVBoxLayout(GroupExclude);
409     GroupExcludeLayout->setSpacing(SPACING);
410     GroupExcludeLayout->setMargin(MARGIN);
411     GroupExcludeLayout->addWidget(ListExclude);
412
413     QGridLayout* fooLayout = new QGridLayout( foo );
414     fooLayout->setSpacing(SPACING);
415     fooLayout->setMargin(0);
416     fooLayout->addWidget(TextLabelTolerance,       0, 0 );
417     fooLayout->addWidget(SpinBoxTolerance,         0, 1 );
418     fooLayout->addWidget(SeparateCornersAndMedium, 1, 0 );
419     fooLayout->addWidget(GroupExclude,             2, 0, 1, 2 );
420     aCoincidentLayout->addWidget(foo);
421   }
422   else {
423     TextLabelTolerance = 0;
424     SpinBoxTolerance = 0;
425     GroupExclude = 0;
426     ListExclude = 0;
427   }
428
429   GroupCoincidentWidget = new QWidget(GroupCoincident);
430   QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget);
431   GroupCoincidentLayout->setSpacing(SPACING);
432   GroupCoincidentLayout->setMargin(0);
433
434   ListCoincident = new QListWidget(GroupCoincidentWidget);
435   ListCoincident->setSelectionMode(QListWidget::ExtendedSelection);
436
437   DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincidentWidget);
438   AddGroupButton    = new QPushButton(tr("SMESH_BUT_ADD"),    GroupCoincidentWidget);
439   RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincidentWidget);
440
441   SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincidentWidget);
442   ShowIDs = new QCheckBox(myAction == MERGE_ELEMENTS ? tr("SHOW_ELEMS_IDS") : tr("SHOW_NODES_IDS"), GroupCoincidentWidget);
443
444   GroupCoincidentLayout->addWidget(ListCoincident,    0,   0, 4, 2);
445   GroupCoincidentLayout->addWidget(DetectButton,      0,   2);
446   GroupCoincidentLayout->addWidget(AddGroupButton,    2, 2);
447   GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
448   GroupCoincidentLayout->addWidget(SelectAllCB,       4, 0);
449   GroupCoincidentLayout->addWidget(ShowIDs,           4, 1);
450   GroupCoincidentLayout->setRowMinimumHeight(1, 10);
451   GroupCoincidentLayout->setRowStretch(1, 5);
452
453   aCoincidentLayout->addWidget(GroupCoincidentWidget);
454
455   /***************************************************************/
456   // Controls for editing the selected group
457   GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this);
458   QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
459   GroupEditLayout->setSpacing(SPACING);
460   GroupEditLayout->setMargin(MARGIN);
461
462   ListEdit = new QListWidget(GroupEdit);
463   //ListEdit->setRowMode(QListBox::FixedNumber);
464   //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
465   //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
466   ListEdit->setFlow( QListView::LeftToRight );
467   ListEdit->setSelectionMode(QListWidget::ExtendedSelection);
468
469   AddElemButton = new QPushButton(GroupEdit);
470   AddElemButton->setIcon(IconAdd);
471   RemoveElemButton = new QPushButton(GroupEdit);
472   RemoveElemButton->setIcon(IconRemove);
473   SetFirstButton = new QPushButton(GroupEdit);
474   SetFirstButton->setIcon(QPixmap(IconFirst));
475
476   GroupEditLayout->addWidget(ListEdit,         0, 0, 2, 1);
477   GroupEditLayout->addWidget(AddElemButton,    0, 1);
478   GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
479   GroupEditLayout->addWidget(SetFirstButton,   1, 1, 1, 2);
480
481   /***************************************************************/
482   GroupButtons = new QGroupBox(this);
483   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
484   GroupButtonsLayout->setSpacing(SPACING);
485   GroupButtonsLayout->setMargin(MARGIN);
486
487   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
488   buttonOk->setAutoDefault(true);
489   buttonOk->setDefault(true);
490   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
491   buttonApply->setAutoDefault(true);
492   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
493   buttonCancel->setAutoDefault(true);
494   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
495   buttonHelp->setAutoDefault(true);
496
497   GroupButtonsLayout->addWidget(buttonOk);
498   GroupButtonsLayout->addSpacing(10);
499   GroupButtonsLayout->addWidget(buttonApply);
500   GroupButtonsLayout->addSpacing(10);
501   GroupButtonsLayout->addStretch();
502   GroupButtonsLayout->addWidget(buttonCancel);
503   GroupButtonsLayout->addWidget(buttonHelp);
504
505   /***************************************************************/
506   DlgLayout->addWidget(GroupConstructors);
507   DlgLayout->addWidget(GroupMesh);
508   DlgLayout->addWidget(TypeBox);
509   DlgLayout->addWidget(GroupCoincident);
510   DlgLayout->addWidget(GroupEdit);
511   DlgLayout->addWidget(GroupButtons);
512
513   GroupCoincidentWidget->setVisible( myAction != MERGE_NODES );
514   GroupCoincident      ->setVisible( myAction == MERGE_NODES );
515   //if GroupExclude->setVisible( myAction == MERGE_NODES );
516   GroupEdit->hide();
517
518   this->resize(10,10);
519
520   ShowIDs->setChecked( true );
521
522   Init(); // Initialisations
523 }
524
525 //=================================================================================
526 // function : ~SMESHGUI_MergeDlg()
527 // purpose  : Destroys the object and frees any allocated resources
528 //=================================================================================
529 SMESHGUI_MergeDlg::~SMESHGUI_MergeDlg()
530 {
531   delete myIdPreview;
532 }
533
534 //=================================================================================
535 // function : Init()
536 // purpose  :
537 //=================================================================================
538 void SMESHGUI_MergeDlg::Init()
539 {
540   if ( myAction == MERGE_NODES ) {
541     SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
542     SpinBoxTolerance->SetValue(1e-05);
543   }
544
545   RadioButton->setChecked(true);
546
547   GroupType->button(0)->setChecked(true);
548
549   myEditCurrentArgument = (QWidget*)LineEditMesh; 
550
551   myActor = 0;
552   mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
553
554   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
555
556   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
557   myIsBusy = false;
558   
559   /* signals and slots connections */
560   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
561   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
562   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
563   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
564
565   connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
566   connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
567   connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
568   connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
569   connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
570   connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
571   connect(ShowIDs, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup()));
572   connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup()));
573   connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
574   connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
575   connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
576   connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
577
578   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
579   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
580   /* to close dialog if study change */
581   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(reject()));
582   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this,  SLOT(onOpenView()));
583   connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
584   // Init Mesh field from selection
585   SelectionIntoArgument();
586
587   // Update Buttons
588   updateControls();
589   
590   if ( myAction == MERGE_NODES )
591     myHelpFileName = "merging_nodes_page.html";
592   else
593     myHelpFileName = "merging_elements_page.html";
594 }
595
596 //=================================================================================
597 // function : FindGravityCenter()
598 // purpose  :
599 //=================================================================================
600 void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
601                                           std::list< gp_XYZ > & theGrCentersXYZ)
602 {
603   if (!myActor)
604     return;
605
606   SMDS_Mesh* aMesh = 0;
607   aMesh = myActor->GetObject()->GetMesh();
608   if (!aMesh)
609     return;
610
611   int nbNodes;
612
613   TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
614   for( ; idIter.More(); idIter.Next() ) {
615     const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
616     if ( !anElem )
617       continue;
618
619     gp_XYZ anXYZ(0., 0., 0.);
620     SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
621     for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
622       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
623       anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
624     }
625     anXYZ.Divide( nbNodes );
626     
627     theGrCentersXYZ.push_back( anXYZ );
628   }
629 }
630
631 //=================================================================================
632 // function : ClickOnApply()
633 // purpose  :
634 //=================================================================================
635 bool SMESHGUI_MergeDlg::ClickOnApply()
636 {
637   if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
638     return false;
639
640   try {
641     if (myTypeId == 0)
642       onDetect();
643
644     SUIT_OverrideCursor aWaitCursor;
645     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
646
647     SMESH::long_array_var anIds = new SMESH::long_array;
648     SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
649
650     if ( ListCoincident->count() == 0) {
651       if ( myAction == MERGE_NODES )
652         SUIT_MessageBox::warning(this,
653                                  tr("SMESH_WARNING"),
654                                  tr("SMESH_NO_NODES_DETECTED"));
655       else
656         SUIT_MessageBox::warning(this,
657                                  tr("SMESH_WARNING"),
658                                  tr("SMESH_NO_ELEMENTS_DETECTED"));
659       return false;
660     }
661
662     aGroupsOfElements->length(ListCoincident->count());
663
664     int anArrayNum = 0;
665     for (int i = 0; i < ListCoincident->count(); i++) {
666       QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts);
667
668       anIds->length(aListIds.count());
669       for (int i = 0; i < aListIds.count(); i++)
670         anIds[i] = aListIds[i].toInt();
671
672       aGroupsOfElements[anArrayNum++] = anIds.inout();
673     }
674
675     if( myAction == MERGE_NODES )
676       aMeshEditor->MergeNodes (aGroupsOfElements.inout());
677     else
678       aMeshEditor->MergeElements (aGroupsOfElements.inout());
679
680     if ( myTypeId == 0 ) {
681       if (myAction == MERGE_NODES )
682         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
683                                      tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data()));
684       else
685         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
686                                      tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data()));
687     }
688       
689
690   } catch(...) {
691   }
692   
693   ListCoincident->clear();
694   
695   myEditCurrentArgument = (QWidget*)LineEditMesh;
696
697   SMESH::UpdateView();
698   SMESHGUI::Modified();
699   
700   return true;
701 }
702
703 //=================================================================================
704 // function : ClickOnOk()
705 // purpose  :
706 //=================================================================================
707 void SMESHGUI_MergeDlg::ClickOnOk()
708 {
709   if (ClickOnApply())
710     reject();
711 }
712
713 //=================================================================================
714 // function : reject()
715 // purpose  :
716 //=================================================================================
717 void SMESHGUI_MergeDlg::reject()
718 {
719   myIdPreview->SetPointsLabeled(false);
720   SMESH::SetPointRepresentation(false);
721   disconnect(mySelectionMgr, 0, this, 0);
722   disconnect(mySMESHGUI, 0, this, 0);
723   mySMESHGUI->ResetState();
724
725   mySelectionMgr->clearFilters();
726   //mySelectionMgr->clearSelected();
727
728   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
729     aViewWindow->SetSelectionMode(ActorSelection);
730
731   QDialog::reject();
732 }
733
734 //=================================================================================
735 // function : onOpenView()
736 // purpose  :
737 //=================================================================================
738 void SMESHGUI_MergeDlg::onOpenView()
739 {
740   if ( mySelector ) {
741     SMESH::SetPointRepresentation(false);
742   }
743   else {
744     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
745     ActivateThisDialog();
746   }
747 }
748
749 //=================================================================================
750 // function : onCloseView()
751 // purpose  :
752 //=================================================================================
753 void SMESHGUI_MergeDlg::onCloseView()
754 {
755   DeactivateActiveDialog();
756   mySelector = 0;
757 }
758
759 //=================================================================================
760 // function : ClickOnHelp()
761 // purpose  :
762 //=================================================================================
763 void SMESHGUI_MergeDlg::ClickOnHelp()
764 {
765   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
766   if (app) 
767     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
768   else {
769     QString platform;
770 #ifdef WIN32
771     platform = "winapplication";
772 #else
773     platform = "application";
774 #endif
775     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
776                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
777                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
778                                                                  platform)).
779                              arg(myHelpFileName));
780   }
781 }
782
783 //=================================================================================
784 // function : onEditGroup()
785 // purpose  :
786 //=================================================================================
787 void SMESHGUI_MergeDlg::onEditGroup()
788 {
789   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
790   if ( selItems.count() != 1 ) {
791     ListEdit->clear();
792     return;
793   }
794
795   QStringList aNewIds;
796
797   for (int i = 0; i < ListEdit->count(); i++ )
798     aNewIds.append(ListEdit->item(i)->text());
799
800   ListCoincident->clearSelection();
801   selItems.first()->setText(aNewIds.join(" "));
802   selItems.first()->setSelected(true);
803 }
804
805 //=================================================================================
806 // function : updateControls()
807 // purpose  :
808 //=================================================================================
809 void SMESHGUI_MergeDlg::updateControls()
810 {
811   if (ListEdit->count() == 0)
812     SetFirstButton->setEnabled(false);
813   bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0));
814   buttonOk->setEnabled(enable);
815   buttonApply->setEnabled(enable);
816   DetectButton->setEnabled( !myMesh->_is_nil() );
817
818   if ( myAction == MERGE_NODES )
819   {
820     bool has2ndOrder = (( !myMesh->_is_nil() ) &&
821                         ( myMesh->NbEdgesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ||
822                           myMesh->NbFacesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ||
823                           myMesh->NbVolumesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ));
824
825     SeparateCornersAndMedium->setEnabled( has2ndOrder );
826   }
827 }
828
829 //=================================================================================
830 // function : onDetect()
831 // purpose  :
832 //=================================================================================
833 void SMESHGUI_MergeDlg::onDetect()
834 {
835   if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
836     return;
837
838   try {
839     SUIT_OverrideCursor aWaitCursor;
840     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
841
842     ListCoincident->clear();
843     ListEdit->clear();
844
845     SMESH::array_of_long_array_var aGroupsArray;
846     SMESH::ListOfIDSources_var aExcludeGroups = new SMESH::ListOfIDSources;
847
848     SMESH::SMESH_IDSource_var src;
849     if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh );
850     else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup );
851
852     switch (myAction) {
853     case MERGE_NODES :
854       for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) {
855         if ( ListExclude->item( i )->checkState() == Qt::Checked ) {
856           aExcludeGroups->length( aExcludeGroups->length()+1 );
857           aExcludeGroups[ aExcludeGroups->length()-1 ] = SMESH::SMESH_IDSource::_duplicate( myGroups[i] );
858         }
859       }
860       aMeshEditor->FindCoincidentNodesOnPartBut(src.in(),
861                                                 SpinBoxTolerance->GetValue(), 
862                                                 aGroupsArray.out(),
863                                                 aExcludeGroups.in(),
864                                                 SeparateCornersAndMedium->isEnabled() &&
865                                                 SeparateCornersAndMedium->isChecked());
866       break;
867     case MERGE_ELEMENTS :
868       aMeshEditor->FindEqualElements(src.in(), aGroupsArray.out());
869       break;
870     }
871     
872     for (int i = 0; i < aGroupsArray->length(); i++) {
873       SMESH::long_array& aGroup = aGroupsArray[i];
874
875       QStringList anIDs;
876       for (int j = 0; j < aGroup.length(); j++)
877         anIDs.append(QString::number(aGroup[j]));
878
879       ListCoincident->addItem(anIDs.join(" "));
880     }
881    } catch(...) {
882   }
883
884   ListCoincident->selectAll();
885   updateControls();
886   SMESH::UpdateView();
887 }
888
889 //=================================================================================
890 // function : onSelectGroup()
891 // purpose  :
892 //=================================================================================
893 void SMESHGUI_MergeDlg::onSelectGroup()
894 {
895   if (myIsBusy || !myActor)
896     return;
897
898   if( ListCoincident->count() != ListCoincident->selectedItems().count() )
899     SelectAllCB->setChecked( false );
900
901   myEditCurrentArgument = (QWidget*)ListCoincident;
902
903   myIsBusy = true;
904   ListEdit->clear();
905   
906   TColStd_MapOfInteger anIndices;
907   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
908   QListWidgetItem* anItem;
909   QStringList aListIds;
910
911   ListEdit->clear();
912
913   foreach(anItem, selItems) {
914     aListIds = anItem->text().split(" ", QString::SkipEmptyParts);
915     for (int i = 0; i < aListIds.count(); i++)
916       anIndices.Add(aListIds[i].toInt());
917   }
918   
919   if (selItems.count() == 1) {
920     ListEdit->addItems(aListIds);
921     ListEdit->selectAll();
922   }
923
924   mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
925   SALOME_ListIO aList;
926   aList.Append(myActor->getIO());
927   mySelectionMgr->setSelectedObjects(aList,false);
928   
929   if (ShowIDs->isChecked()) 
930     if ( myAction == MERGE_NODES ) {
931       myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
932       myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
933     }
934     else {
935       std::list< gp_XYZ > aGrCentersXYZ;
936       FindGravityCenter(anIndices, aGrCentersXYZ);
937       myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
938       myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
939     }
940   else
941     myIdPreview->SetPointsLabeled(false);
942
943   updateControls();
944   myIsBusy = false;
945 }
946
947 //=================================================================================
948 // function : onSelectAll()
949 // purpose  :
950 //=================================================================================
951 void SMESHGUI_MergeDlg::onSelectAll (bool isToggled)
952 {
953   if ( isToggled )
954     ListCoincident->selectAll();
955   else
956     ListCoincident->clearSelection();
957 }
958
959 //=================================================================================
960 // function : onSelectElementFromGroup()
961 // purpose  :
962 //=================================================================================
963 void SMESHGUI_MergeDlg::onSelectElementFromGroup()
964 {
965   if (myIsBusy || !myActor)
966     return;
967
968   TColStd_MapOfInteger anIndices;
969   QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
970   QListWidgetItem* anItem;
971
972   foreach(anItem, selItems)
973     anIndices.Add(anItem->text().toInt());
974
975   SetFirstButton->setEnabled(selItems.count() == 1);
976
977   mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
978   SALOME_ListIO aList;
979   aList.Append(myActor->getIO());
980   mySelectionMgr->setSelectedObjects(aList);
981   
982   if (ShowIDs->isChecked())
983     if (myAction == MERGE_NODES) {
984       myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
985       myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
986     }
987     else {
988       std::list< gp_XYZ > aGrCentersXYZ;
989       FindGravityCenter(anIndices, aGrCentersXYZ);
990       myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
991       myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
992     }
993   else 
994     myIdPreview->SetPointsLabeled(false);
995 }
996
997 //=================================================================================
998 // function : onAddGroup()
999 // purpose  :
1000 //=================================================================================
1001 void SMESHGUI_MergeDlg::onAddGroup()
1002 {
1003   if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
1004     return;
1005
1006   QString anIDs = "";
1007   int aNbElements = 0;
1008   aNbElements = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
1009
1010   if (aNbElements < 1)
1011     return;
1012   
1013   ListCoincident->clearSelection();
1014   ListCoincident->addItem(anIDs);
1015   int nbGroups = ListCoincident->count();
1016   if (nbGroups) {
1017     ListCoincident->setCurrentRow(nbGroups-1);
1018     ListCoincident->item(nbGroups-1)->setSelected(true);
1019   }
1020   else {
1021     // VSR ? this code seems to be never executed!!!
1022     ListCoincident->setCurrentRow(0);
1023     //ListCoincident->setSelected(0, true); // VSR: no items - no selection
1024   }
1025
1026   updateControls();
1027 }
1028
1029 //=================================================================================
1030 // function : onRemoveGroup()
1031 // purpose  :
1032 //=================================================================================
1033 void SMESHGUI_MergeDlg::onRemoveGroup()
1034 {
1035   if (myEditCurrentArgument != (QWidget*)ListCoincident)
1036     return;
1037   myIsBusy = true;
1038
1039   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
1040   QListWidgetItem* anItem;
1041
1042   foreach(anItem, selItems)
1043     delete anItem;
1044
1045   ListEdit->clear();
1046   myIdPreview->SetPointsLabeled(false);
1047   updateControls();
1048   SMESH::UpdateView();
1049   myIsBusy = false;
1050
1051   if( ListCoincident->count() == 0 ) {
1052     myEditCurrentArgument = (QWidget*)LineEditMesh;
1053     SelectAllCB->setChecked( false );
1054   }
1055 }
1056
1057 //=================================================================================
1058 // function : onAddElement()
1059 // purpose  :
1060 //=================================================================================
1061 void SMESHGUI_MergeDlg::onAddElement()
1062 {
1063   if (!myActor)
1064     return;
1065   myIsBusy = true;
1066
1067   QString aListStr = "";
1068   int aNbNnodes = 0;
1069
1070   aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
1071   if (aNbNnodes < 1)
1072     return;
1073
1074   QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts);
1075
1076   for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
1077     QList<QListWidgetItem*> found = ListEdit->findItems(*it, Qt::MatchExactly);
1078     if ( found.count() == 0 ) {
1079       QListWidgetItem* anItem = new QListWidgetItem(*it);
1080       ListEdit->addItem(anItem);
1081       anItem->setSelected(true);
1082     }
1083     else {
1084       QListWidgetItem* anItem;
1085       foreach(anItem, found) anItem->setSelected(true);
1086     }
1087   }
1088
1089   myIsBusy = false;
1090   onEditGroup();
1091 }
1092
1093 //=================================================================================
1094 // function : onRemoveElement()
1095 // purpose  :
1096 //=================================================================================
1097 void SMESHGUI_MergeDlg::onRemoveElement()
1098 {
1099   if (myEditCurrentArgument != (QWidget*)ListCoincident)
1100     return;
1101   myIsBusy = true;
1102
1103   QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
1104   QListWidgetItem* anItem;
1105
1106   foreach(anItem, selItems)
1107     delete anItem;
1108   
1109   myIsBusy = false;
1110   onEditGroup();
1111
1112   if( ListCoincident->count() == 0 ) {
1113     myEditCurrentArgument = (QWidget*)LineEditMesh;
1114     SelectAllCB->setChecked( false );
1115   }
1116 }
1117
1118 //=================================================================================
1119 // function : onSetFirst()
1120 // purpose  :
1121 //=================================================================================
1122 void SMESHGUI_MergeDlg::onSetFirst()
1123 {
1124   if (myEditCurrentArgument != (QWidget*)ListCoincident)
1125     return;
1126   myIsBusy = true;
1127   
1128   QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
1129   QListWidgetItem* anItem;
1130   
1131   foreach(anItem, selItems) {
1132     ListEdit->takeItem(ListEdit->row(anItem));
1133     ListEdit->insertItem(0, anItem);
1134   }
1135
1136   myIsBusy = false;
1137   onEditGroup();
1138 }
1139
1140 //=================================================================================
1141 // function : SetEditCurrentArgument()
1142 // purpose  :
1143 //=================================================================================
1144 void SMESHGUI_MergeDlg::SetEditCurrentArgument()
1145 {
1146   QPushButton* send = (QPushButton*)sender();
1147
1148   disconnect(mySelectionMgr, 0, this, 0);
1149   mySelectionMgr->clearSelected();
1150   mySelectionMgr->clearFilters();
1151
1152   if (send == SelectMeshButton) {
1153     myEditCurrentArgument = (QWidget*)LineEditMesh;
1154     SMESH::SetPointRepresentation(false);
1155     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1156       aViewWindow->SetSelectionMode(ActorSelection);
1157     if (myTypeId == 1)
1158       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
1159   }
1160
1161   myEditCurrentArgument->setFocus();
1162   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1163   SelectionIntoArgument();
1164 }
1165
1166 //=================================================================================
1167 // function : SelectionIntoArgument()
1168 // purpose  : Called when selection as changed or other case
1169 //=================================================================================
1170 void SMESHGUI_MergeDlg::SelectionIntoArgument()
1171 {
1172   if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
1173     QString aString = "";
1174     LineEditMesh->setText(aString);
1175
1176     ListCoincident->clear();
1177     ListEdit->clear();
1178     myActor = 0;
1179     myMesh = SMESH::SMESH_Mesh::_nil();
1180     QString aCurrentEntry = myEntry;
1181
1182     int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
1183     if (nbSel != 1) {
1184       myIdPreview->SetPointsLabeled(false);
1185       SMESH::SetPointRepresentation(false);
1186       mySelectionMgr->clearFilters();
1187       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1188         aViewWindow->SetSelectionMode(ActorSelection);
1189       return;
1190     }
1191
1192     SALOME_ListIO aList;
1193     mySelectionMgr->selectedObjects(aList);
1194
1195     Handle(SALOME_InteractiveObject) IO = aList.First();
1196     myEntry = IO->getEntry();
1197     myMesh = SMESH::GetMeshByIO(IO);
1198
1199     if (myMesh->_is_nil())
1200       return;
1201
1202     LineEditMesh->setText(aString);
1203
1204     myActor = SMESH::FindActorByEntry(IO->getEntry());
1205     if (!myActor)
1206       myActor = SMESH::FindActorByObject(myMesh);
1207
1208     if ( myActor && myTypeId == 1 && mySelector->IsSelectionEnabled() ) {
1209       mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
1210       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
1211
1212       if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
1213            !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
1214           !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
1215         mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
1216
1217       if (myAction == MERGE_NODES) {
1218         SMESH::SetPointRepresentation(true);
1219         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1220           aViewWindow->SetSelectionMode(NodeSelection);
1221       }
1222       else
1223         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1224           aViewWindow->SetSelectionMode(CellSelection);
1225     }
1226
1227     // process groups
1228     if ( myAction == MERGE_NODES && !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
1229       myGroups.clear();
1230       ListExclude->clear();
1231       SMESH::ListOfGroups_var aListOfGroups = myMesh->GetGroups();
1232       for( int i = 0, n = aListOfGroups->length(); i < n; i++ ) {
1233         SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
1234         if ( !aGroup->_is_nil() ) { // && aGroup->GetType() == SMESH::NODE
1235           QString aGroupName( aGroup->GetName() );
1236           if ( !aGroupName.isEmpty() ) {
1237             myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
1238             QListWidgetItem* item = new QListWidgetItem( aGroupName );
1239             item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
1240             item->setCheckState( Qt::Unchecked );
1241             ListExclude->addItem( item );
1242           }
1243         }
1244       }
1245     }
1246
1247     updateControls();
1248   }
1249 }
1250
1251 //=================================================================================
1252 // function : DeactivateActiveDialog()
1253 // purpose  :
1254 //=================================================================================
1255 void SMESHGUI_MergeDlg::DeactivateActiveDialog()
1256 {
1257   if (GroupConstructors->isEnabled()) {
1258     GroupConstructors->setEnabled(false);
1259     TypeBox->setEnabled(false);
1260     GroupMesh->setEnabled(false);
1261     GroupCoincident->setEnabled(false);
1262     GroupEdit->setEnabled(false);
1263     GroupButtons->setEnabled(false);
1264     mySMESHGUI->ResetState();
1265     mySMESHGUI->SetActiveDialogBox(0);
1266   }
1267
1268   mySelectionMgr->clearSelected();
1269   disconnect(mySelectionMgr, 0, this, 0);
1270 }
1271
1272 //=================================================================================
1273 // function : ActivateThisDialog()
1274 // purpose  :
1275 //=================================================================================
1276 void SMESHGUI_MergeDlg::ActivateThisDialog()
1277 {
1278   /* Emit a signal to deactivate the active dialog */
1279   mySMESHGUI->EmitSignalDeactivateDialog();
1280   GroupConstructors->setEnabled(true);
1281   TypeBox->setEnabled(true);
1282   GroupMesh->setEnabled(true);
1283   GroupCoincident->setEnabled(true);
1284   GroupEdit->setEnabled(true);
1285   GroupButtons->setEnabled(true);
1286
1287   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1288   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
1289   SelectionIntoArgument();
1290 }
1291
1292 //=================================================================================
1293 // function : enterEvent()
1294 // purpose  :
1295 //=================================================================================
1296 void SMESHGUI_MergeDlg::enterEvent (QEvent*)
1297 {
1298   if ( !GroupConstructors->isEnabled() ) {
1299     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1300     if ( aViewWindow && !mySelector) {
1301       mySelector = aViewWindow->GetSelector();
1302     }
1303     ActivateThisDialog();
1304   }
1305 }
1306
1307 //=================================================================================
1308 // function : keyPressEvent()
1309 // purpose  :
1310 //=================================================================================
1311 void SMESHGUI_MergeDlg::keyPressEvent( QKeyEvent* e)
1312 {
1313   QDialog::keyPressEvent( e );
1314   if ( e->isAccepted() )
1315     return;
1316
1317   if ( e->key() == Qt::Key_F1 ) {
1318     e->accept();
1319     ClickOnHelp();
1320   }
1321 }
1322
1323 //=================================================================================
1324 // function : onTypeChanged()
1325 // purpose  : the type radio button management
1326 //=================================================================================
1327 void SMESHGUI_MergeDlg::onTypeChanged (int id)
1328 {
1329   if (myTypeId == id)
1330     return;
1331
1332   myTypeId = id;
1333   switch (id)
1334   {
1335   case 0: // automatic
1336     myIdPreview->SetPointsLabeled(false);
1337     SMESH::SetPointRepresentation(false);
1338     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1339       aViewWindow->SetSelectionMode(ActorSelection);
1340     mySelectionMgr->clearFilters();
1341     if (myAction == MERGE_NODES)
1342       GroupCoincidentWidget->hide();
1343     else
1344       GroupCoincident->hide();
1345     GroupEdit->hide();
1346     break;
1347
1348   case 1: // manual
1349     SMESH::UpdateView();
1350
1351     // Costruction of the logical filter
1352     SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (SMESH::MESHorSUBMESH);
1353     SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (SMESH::GROUP);
1354     
1355     QList<SUIT_SelectionFilter*> aListOfFilters;
1356     if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
1357     if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
1358     
1359     myMeshOrSubMeshOrGroupFilter =
1360       new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
1361
1362     if (myAction == MERGE_NODES) {
1363       GroupCoincidentWidget->show();
1364       SMESH::SetPointRepresentation(true);
1365       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1366         if( mySelector->IsSelectionEnabled() )
1367           aViewWindow->SetSelectionMode(NodeSelection);
1368     }
1369     else {
1370       GroupCoincident->show();
1371       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1372         if( mySelector->IsSelectionEnabled() )
1373           aViewWindow->SetSelectionMode(CellSelection);
1374     }
1375     GroupEdit->show();
1376     break;
1377   }
1378   updateControls();
1379
1380   qApp->processEvents();
1381   updateGeometry();
1382   resize(10,10);
1383
1384   SelectionIntoArgument();
1385 }