Salome HOME
Merge remote branch 'origin/V8_5_asterstudy'
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_SmoothingDlg.cxx
1 // Copyright (C) 2007-2016  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_SmoothingDlg.cxx
25 // Author : Michael ZORIN, Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_SmoothingDlg.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 #include "SMESHGUI_IdValidator.h"
36 #include "SMESHGUI_FilterDlg.h"
37
38 #include <SMESH_Actor.h>
39 #include <SMESH_TypeFilter.hxx>
40 #include <SMESH_LogicalFilter.hxx>
41
42 #include <SMDS_Mesh.hxx>
43
44 // SALOME GUI includes
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_OverrideCursor.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_Session.h>
49 #include <SUIT_MessageBox.h>
50
51 #include <LightApp_Application.h>
52 #include <LightApp_SelectionMgr.h>
53
54 #include <SalomeApp_IntSpinBox.h>
55
56 #include <SVTK_ViewModel.h>
57 #include <SVTK_Selector.h>
58 #include <SVTK_ViewWindow.h>
59 #include <SVTK_Selection.h>
60 #include <SALOME_ListIO.hxx>
61
62 // OCCT includes
63 #include <TColStd_MapOfInteger.hxx>
64
65 // Qt includes
66 #include <QApplication>
67 #include <QGroupBox>
68 #include <QLabel>
69 #include <QLineEdit>
70 #include <QPushButton>
71 #include <QRadioButton>
72 #include <QComboBox>
73 #include <QCheckBox>
74 #include <QHBoxLayout>
75 #include <QVBoxLayout>
76 #include <QGridLayout>
77 #include <QKeyEvent>
78 #include <QButtonGroup>
79
80 // IDL includes
81 #include <SALOMEconfig.h>
82 #include CORBA_SERVER_HEADER(SMESH_Group)
83 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
84
85 #define SPACING 6
86 #define MARGIN  11
87
88 /*!
89   \class BusyLocker
90   \brief Simple 'busy state' flag locker.
91   \internal
92 */
93
94 class BusyLocker
95 {
96 public:
97   //! Constructor. Sets passed boolean flag to \c true.
98   BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
99   //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
100   ~BusyLocker() { myBusy = false; }
101 private:
102   bool& myBusy; //! External 'busy state' boolean flag
103 };
104
105
106 //=================================================================================
107 // function : SMESHGUI_SmoothingDlg()
108 // purpose  : constructor
109 //=================================================================================
110 SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
111   : QDialog( SMESH::GetDesktop( theModule ) ),
112     mySMESHGUI( theModule ),
113     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
114     mySelectedObject(SMESH::SMESH_IDSource::_nil()),
115     myFilterDlg(0)
116 {
117   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_SMOOTHING")));
118   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
119
120   setModal(false);
121   setAttribute(Qt::WA_DeleteOnClose, true);
122   setWindowTitle(tr("SMESH_SMOOTHING"));
123   setSizeGripEnabled(true);
124
125   /***************************************************************/
126   QVBoxLayout* SMESHGUI_SmoothingDlgLayout = new QVBoxLayout(this);
127   SMESHGUI_SmoothingDlgLayout->setSpacing(SPACING);
128   SMESHGUI_SmoothingDlgLayout->setMargin(MARGIN);
129
130   /***************************************************************/
131   GroupConstructors = new QGroupBox(tr("SMESH_SMOOTHING"), this);
132   QButtonGroup* ButtonGroup = new QButtonGroup(this);
133   QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
134   GroupConstructorsLayout->setSpacing(SPACING);
135   GroupConstructorsLayout->setMargin(MARGIN);
136
137   Constructor1 = new QRadioButton(GroupConstructors);
138   Constructor1->setIcon(image0);
139   Constructor1->setChecked(true);
140   GroupConstructorsLayout->addWidget(Constructor1);
141   ButtonGroup->addButton(Constructor1, 0);
142
143   /***************************************************************/
144   GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
145   QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
146   GroupArgumentsLayout->setSpacing(SPACING);
147   GroupArgumentsLayout->setMargin(MARGIN);
148
149   myIdValidator = new SMESHGUI_IdValidator(this);
150
151   // Controls for elements selection
152   TextLabelElements = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments);
153
154   SelectElementsButton = new QPushButton(GroupArguments);
155   SelectElementsButton->setIcon(image1);
156
157   LineEditElements = new QLineEdit(GroupArguments);
158   LineEditElements->setValidator(myIdValidator);
159   LineEditElements->setMaxLength(-1);
160   myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
161   connect(myElemFilterBtn,   SIGNAL(clicked()), this, SLOT(setElemFilters()));
162
163   // Control for the whole mesh selection
164   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
165
166   // Controls for nodes selection
167   TextLabelNodes = new QLabel(tr("FIXED_NODES_IDS"), GroupArguments);
168
169   SelectNodesButton  = new QPushButton(GroupArguments);
170   SelectNodesButton->setIcon(image1);
171
172   LineEditNodes  = new QLineEdit(GroupArguments);
173   LineEditNodes->setValidator(myIdValidator);
174   LineEditNodes->setMaxLength(-1);
175   QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
176   connect(filterNodeBtn,   SIGNAL(clicked()), this, SLOT(setNodeFilters()));
177
178   // Controls for method selection
179   TextLabelMethod = new QLabel(tr("METHOD"), GroupArguments);
180
181   ComboBoxMethod = new QComboBox(GroupArguments);
182
183   // Controls for iteration limit defining
184   TextLabelLimit = new QLabel(tr("ITERATION_LIMIT"), GroupArguments);
185
186   SpinBox_IterationLimit = new SalomeApp_IntSpinBox(GroupArguments);
187
188   // Controls for max. aspect ratio defining
189   TextLabelAspectRatio = new QLabel(tr("MAX_ASPECT_RATIO"), GroupArguments);
190
191   SpinBox_AspectRatio = new SMESHGUI_SpinBox(GroupArguments);
192
193   // Check box "Is Parametric"
194   CheckBoxParametric = new QCheckBox( tr("IS_PARAMETRIC"), GroupArguments );
195
196   GroupArgumentsLayout->addWidget(TextLabelElements,      0, 0);
197   GroupArgumentsLayout->addWidget(SelectElementsButton,   0, 1);
198   GroupArgumentsLayout->addWidget(LineEditElements,       0, 2);
199   GroupArgumentsLayout->addWidget(myElemFilterBtn,        0, 3);
200   GroupArgumentsLayout->addWidget(CheckBoxMesh,           1, 0, 1, 4);
201   GroupArgumentsLayout->addWidget(TextLabelNodes,         2, 0);
202   GroupArgumentsLayout->addWidget(SelectNodesButton,      2, 1);
203   GroupArgumentsLayout->addWidget(LineEditNodes,          2, 2);
204   GroupArgumentsLayout->addWidget(filterNodeBtn,          2, 3);
205   GroupArgumentsLayout->addWidget(TextLabelMethod,        3, 0);
206   GroupArgumentsLayout->addWidget(ComboBoxMethod,         3, 2, 1, 2);
207   GroupArgumentsLayout->addWidget(TextLabelLimit,         4, 0);
208   GroupArgumentsLayout->addWidget(SpinBox_IterationLimit, 4, 2, 1, 2);
209   GroupArgumentsLayout->addWidget(TextLabelAspectRatio,   5, 0);
210   GroupArgumentsLayout->addWidget(SpinBox_AspectRatio,    5, 2, 1, 2);
211   GroupArgumentsLayout->addWidget(CheckBoxParametric,     6, 0, 1, 4);
212
213   /***************************************************************/
214   GroupButtons = new QGroupBox(this);
215   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
216   GroupButtonsLayout->setSpacing(SPACING);
217   GroupButtonsLayout->setMargin(MARGIN);
218
219   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
220   buttonOk->setAutoDefault(true);
221   buttonOk->setDefault(true);
222   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
223   buttonApply->setAutoDefault(true);
224   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
225   buttonCancel->setAutoDefault(true);
226   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
227   buttonHelp->setAutoDefault(true);
228
229   GroupButtonsLayout->addWidget(buttonOk);
230   GroupButtonsLayout->addSpacing(10);
231   GroupButtonsLayout->addWidget(buttonApply);
232   GroupButtonsLayout->addSpacing(10);
233   GroupButtonsLayout->addStretch();
234   GroupButtonsLayout->addWidget(buttonCancel);
235   GroupButtonsLayout->addWidget(buttonHelp);
236
237   /***************************************************************/
238   SMESHGUI_SmoothingDlgLayout->addWidget(GroupConstructors);
239   SMESHGUI_SmoothingDlgLayout->addWidget(GroupArguments);
240   SMESHGUI_SmoothingDlgLayout->addWidget(GroupButtons);
241
242   /***************************************************************/
243   /* Initialisations */
244   ComboBoxMethod->addItem(tr("LAPLACIAN"));
245   ComboBoxMethod->addItem(tr("CENTROIDAL"));
246
247   ComboBoxMethod->setCurrentIndex(0);
248
249   CheckBoxParametric->setChecked( true );
250   
251   SpinBox_IterationLimit->setRange(1, 999999);
252   SpinBox_IterationLimit->setValue(20);
253   SpinBox_AspectRatio->RangeStepAndValidator(0.0, +999999.999, 0.1, "parametric_precision");
254   SpinBox_AspectRatio->SetValue(1.1);
255
256   GroupArguments->show();
257   myConstructorId = 0;
258   Constructor1->setChecked(true);
259   
260   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
261
262   mySMESHGUI->SetActiveDialogBox(this);
263
264   // Costruction of the logical filter for the elements: mesh/sub-mesh/group
265   QList<SUIT_SelectionFilter*> aListOfFilters;
266   aListOfFilters << new SMESH_TypeFilter(SMESH::MESHorSUBMESH) << new SMESH_TypeFilter(SMESH::GROUP);
267
268   myMeshOrSubMeshOrGroupFilter =
269     new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
270
271   myHelpFileName = "smoothing.html";
272
273   Init();
274
275   /***************************************************************/
276   // signals and slots connections
277   connect(buttonOk, SIGNAL(clicked()),     this, SLOT(ClickOnOk()));
278   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
279   connect(buttonApply, SIGNAL(clicked()),  this, SLOT(ClickOnApply()));
280   connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
281
282   connect(SelectElementsButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
283   connect(SelectNodesButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
284   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
285   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
286   /* to close dialog if study change */
287   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()),      this, SLOT(reject()));
288   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
289   connect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
290   connect(LineEditElements, SIGNAL(textChanged(const QString&)),
291            SLOT(onTextChange(const QString&)));
292   connect(LineEditNodes, SIGNAL(textChanged(const QString&)),
293            SLOT(onTextChange(const QString&)));
294   connect(CheckBoxMesh, SIGNAL(toggled(bool)),
295            SLOT(onSelectMesh(bool)));
296 }
297
298 //=================================================================================
299 // function : ~SMESHGUI_SmoothingDlg()
300 // purpose  : destructor
301 //=================================================================================
302 SMESHGUI_SmoothingDlg::~SMESHGUI_SmoothingDlg()
303 {
304   // no need to delete child widgets, Qt does it all for us
305   if ( myFilterDlg != 0 ) {
306     myFilterDlg->setParent( 0 );
307     delete myFilterDlg;
308   }
309 }
310
311 //=================================================================================
312 // function : Init()
313 // purpose  : initialization
314 //=================================================================================
315 void SMESHGUI_SmoothingDlg::Init()
316 {
317   myBusy = false;
318
319 //   ComboBoxMethod->setCurrentItem(0);
320
321 //   SpinBox_IterationLimit->setValue(20);
322 //   SpinBox_AspectRatio->SetValue(1.1);
323
324   myEditCurrentArgument = LineEditElements;
325   LineEditElements->setFocus();
326   LineEditElements->clear();
327   LineEditNodes->clear();
328   myNbOkElements = 0;
329   myNbOkNodes = 0;
330   myActor     = 0;
331   myIO.Nullify();
332   myMesh = SMESH::SMESH_Mesh::_nil();
333
334   CheckBoxMesh->setChecked(false);
335   onSelectMesh(false);
336 }
337
338 //=================================================================================
339 // function : ClickOnApply()
340 // purpose  : Called when user presses <Apply> button
341 //=================================================================================
342 bool SMESHGUI_SmoothingDlg::ClickOnApply()
343 {
344   if (SMESHGUI::isStudyLocked())
345     return false;
346
347   if (!isValid())
348     return false;
349
350   if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) {
351     QStringList aListElementsId = LineEditElements->text().split(" ", QString::SkipEmptyParts);
352     QStringList aListNodesId    = LineEditNodes->text().split(" ", QString::SkipEmptyParts);
353
354     SMESH::long_array_var anElementsId = new SMESH::long_array;
355     SMESH::long_array_var aNodesId = new SMESH::long_array;
356
357     anElementsId->length(aListElementsId.count());
358     for (int i = 0; i < aListElementsId.count(); i++)
359       anElementsId[i] = aListElementsId[i].toInt();
360
361     if ( myNbOkNodes && aListNodesId.count() > 0 ) {
362       aNodesId->length(aListNodesId.count());
363       for (int i = 0; i < aListNodesId.count(); i++)
364         aNodesId[i] = aListNodesId[i].toInt();
365     } else {
366       aNodesId->length(0);
367     }
368
369     long anIterationLimit = (long)SpinBox_IterationLimit->value();
370     double aMaxAspectRatio = SpinBox_AspectRatio->GetValue();
371
372     QStringList aParameters;
373     aParameters << SpinBox_IterationLimit->text();
374     aParameters << SpinBox_AspectRatio->text();
375
376     SMESH::SMESH_MeshEditor::Smooth_Method aMethod = SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH;
377     if (ComboBoxMethod->currentIndex() > 0)
378       aMethod =  SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH;
379
380     bool aResult = false;
381     try {
382       SUIT_OverrideCursor aWaitCursor;
383       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
384
385       myMesh->SetParameters( aParameters.join(":").toUtf8().constData() );
386
387       if ( CheckBoxParametric->isChecked() ) {
388         if(CheckBoxMesh->isChecked())
389           aResult = aMeshEditor->SmoothParametricObject(mySelectedObject, aNodesId.inout(),
390                                                         anIterationLimit, aMaxAspectRatio, aMethod);
391         else
392           aResult = aMeshEditor->SmoothParametric(anElementsId.inout(), aNodesId.inout(),
393                                                   anIterationLimit, aMaxAspectRatio, aMethod);
394       }
395       else {
396         if(CheckBoxMesh->isChecked())
397           aResult = aMeshEditor->SmoothObject(mySelectedObject, aNodesId.inout(),
398                                               anIterationLimit, aMaxAspectRatio, aMethod);
399         else
400           aResult = aMeshEditor->Smooth(anElementsId.inout(), aNodesId.inout(),
401                                         anIterationLimit, aMaxAspectRatio, aMethod);
402       }
403
404     } catch (...) {
405     }
406
407     if (aResult) {
408       SMESH::Update(myIO, SMESH::eDisplay);
409       SMESH::RepaintCurrentView();
410       SMESHGUI::Modified();
411       //Init();
412
413       //mySelectedObject = SMESH::SMESH_IDSource::_nil();
414     }
415   }
416
417   return true;
418 }
419
420 //=================================================================================
421 // function : ClickOnOk()
422 // purpose  : Called when user presses <OK> button
423 //=================================================================================
424 void SMESHGUI_SmoothingDlg::ClickOnOk()
425 {
426   if( ClickOnApply() )
427     reject();
428 }
429
430 //=================================================================================
431 // function : reject()
432 // purpose  : Called when dialog box is closed
433 //=================================================================================
434 void SMESHGUI_SmoothingDlg::reject()
435 {
436   disconnect(mySelectionMgr, 0, this, 0);
437   mySelectionMgr->clearFilters();
438   //mySelectionMgr->clearSelected();
439   if (SMESH::GetCurrentVtkView()) {
440     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
441     SMESH::SetPointRepresentation(false);
442     SMESH::SetPickable();
443   }
444   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
445     aViewWindow->SetSelectionMode(ActorSelection);
446   mySMESHGUI->ResetState();
447   QDialog::reject();
448 }
449
450 //=================================================================================
451 // function : onOpenView()
452 // purpose  :
453 //=================================================================================
454 void SMESHGUI_SmoothingDlg::onOpenView()
455 {
456   if ( mySelector ) {
457     SMESH::SetPointRepresentation(false);
458   }
459   else {
460     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
461     ActivateThisDialog();
462   }
463 }
464
465 //=================================================================================
466 // function : onCloseView()
467 // purpose  :
468 //=================================================================================
469 void SMESHGUI_SmoothingDlg::onCloseView()
470 {
471   DeactivateActiveDialog();
472   mySelector = 0;
473 }
474
475 //=================================================================================
476 // function : ClickOnHelp()
477 // purpose  :
478 //=================================================================================
479 void SMESHGUI_SmoothingDlg::ClickOnHelp()
480 {
481   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
482   if (app) 
483     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
484   else {
485     QString platform;
486 #ifdef WIN32
487     platform = "winapplication";
488 #else
489     platform = "application";
490 #endif
491     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
492                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
493                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
494                                                                  platform)).
495                              arg(myHelpFileName));
496   }
497 }
498
499 //=======================================================================
500 // function : onTextChange()
501 // purpose  :
502 //=======================================================================
503 void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText)
504 {
505   QLineEdit* send = (QLineEdit*)sender();
506
507   // return if busy
508   if (myBusy || myIO.IsNull()) return;
509
510   // set busy flag
511   BusyLocker lock( myBusy );
512
513   if (send == LineEditElements)
514     myNbOkElements = 0;
515   else if (send == LineEditNodes)
516     myNbOkNodes = 0;
517
518   buttonOk->setEnabled(false);
519   buttonApply->setEnabled(false);
520
521   // highlight entered elements/nodes
522   SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
523   QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
524
525   if (send == LineEditElements) {
526     TColStd_MapOfInteger newIndices;
527     for (int i = 0; i < aListId.count(); i++) {
528       int id = aListId[ i ].toInt();
529       if ( id > 0 ) {
530         bool validId = aMesh ? ( aMesh->FindElement( id ) != 0 ) : ( myMesh->GetElementType( id, true ) != SMESH::EDGE );
531         if ( validId ) 
532           newIndices.Add( id );
533       }
534       myNbOkElements = newIndices.Extent();
535       mySelector->AddOrRemoveIndex(myIO, newIndices, false);
536       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
537         aViewWindow->highlight( myIO, true, true );
538     }
539   }
540   else if (send == LineEditNodes) {
541     TColStd_MapOfInteger newIndices;
542     for (int i = 0; i < aListId.count(); i++) {
543       int id = aListId[ i ].toInt();
544       if ( id > 0 ) {
545         bool validId = aMesh ? ( aMesh->FindNode( id ) != 0 ) : ( myMesh->GetElementType( id, false ) != SMESH::EDGE );
546         if ( validId ) 
547           newIndices.Add( id );
548       }
549       myNbOkNodes = newIndices.Extent();
550       mySelector->AddOrRemoveIndex(myIO, newIndices, false);
551       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
552         aViewWindow->highlight( myIO, true, true );
553     }
554   }
555
556   if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) {
557     buttonOk->setEnabled(true);
558     buttonApply->setEnabled(true);
559   }
560 }
561
562 //=================================================================================
563 // function : SelectionIntoArgument()
564 // purpose  : Called when selection has changed or other cases
565 //=================================================================================
566 void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
567 {
568   if (myBusy) return;
569   if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
570
571   // clear
572   QString aString = "";
573
574   // set busy flag
575   BusyLocker lock( myBusy );
576
577   if (myEditCurrentArgument == LineEditElements ||
578       myEditCurrentArgument == LineEditNodes)
579   {
580     myEditCurrentArgument->setText(aString);
581     if (myEditCurrentArgument == LineEditElements) {
582       myNbOkElements = 0;
583       myActor = 0;
584       myIO.Nullify();
585     }
586     else {
587       myNbOkNodes = 0;
588     }
589     buttonOk->setEnabled(false);
590     buttonApply->setEnabled(false);
591   }
592
593   if (!GroupButtons->isEnabled()) // inactive
594     return;
595
596   // get selected mesh
597   SALOME_ListIO aList;
598   mySelectionMgr->selectedObjects(aList);
599   int nbSel = aList.Extent();
600   if (nbSel == 1)
601   {
602     Handle(SALOME_InteractiveObject) IO = aList.First();
603
604     if (myEditCurrentArgument == LineEditElements) {
605       myMesh = SMESH::GetMeshByIO(IO);
606       if (myMesh->_is_nil())
607         return;
608       myIO = IO;
609       myActor = SMESH::FindActorByObject(myMesh);
610
611       if (CheckBoxMesh->isChecked()) {
612         SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
613
614         SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( myIO );
615         if ( !CORBA::is_nil( obj ) )
616           mySelectedObject = obj;
617         else
618           return;
619         myNbOkElements = true;
620       } else {
621         // get indices of selected elements
622         TColStd_IndexedMapOfInteger aMapIndex;
623         mySelector->GetIndex(IO,aMapIndex);
624         myNbOkElements = aMapIndex.Extent();
625
626         if (myNbOkElements < 1)
627           return;
628
629         QStringList elements;
630         for ( int i = 0; i < myNbOkElements; ++i )
631           elements << QString::number( aMapIndex( i+1 ) );
632         aString = elements.join(" ");
633       }
634     } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myIO->isSame(IO) )
635     {
636       myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
637     }
638   }
639
640   myEditCurrentArgument->setText(aString);
641   myEditCurrentArgument->repaint();
642   myEditCurrentArgument->setEnabled(false); // to update lineedit IPAL 19809
643   myEditCurrentArgument->setEnabled(true);
644
645   if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) {
646     buttonOk->setEnabled(true);
647     buttonApply->setEnabled(true);
648   }
649 }
650
651 //=================================================================================
652 // function : SetEditCurrentArgument()
653 // purpose  :
654 //=================================================================================
655 void SMESHGUI_SmoothingDlg::SetEditCurrentArgument()
656 {
657   QPushButton* send = (QPushButton*)sender();
658
659   switch (myConstructorId) {
660   case 0: /* default constructor */
661     {
662       disconnect(mySelectionMgr, 0, this, 0);
663       mySelectionMgr->clearSelected();
664       mySelectionMgr->clearFilters();
665
666       if (send == SelectElementsButton) {
667         myEditCurrentArgument = LineEditElements;
668         SMESH::SetPointRepresentation(false);
669         if (CheckBoxMesh->isChecked()) {
670           //          mySelectionMgr->setSelectionModes(ActorSelection);
671           if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
672             aViewWindow->SetSelectionMode(ActorSelection);
673           mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
674         } else {
675           if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
676             aViewWindow->SetSelectionMode(FaceSelection);
677         }
678       } else if (send == SelectNodesButton) {
679         LineEditNodes->clear();
680         myEditCurrentArgument = LineEditNodes;
681         SMESH::SetPointRepresentation(true);
682         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
683           aViewWindow->SetSelectionMode(NodeSelection);
684         }
685       }
686
687       myEditCurrentArgument->setFocus();
688       connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
689       SelectionIntoArgument();
690       break;
691     }
692   }
693 }
694
695 //=================================================================================
696 // function : DeactivateActiveDialog()
697 // purpose  : Deactivates this dialog
698 //=================================================================================
699 void SMESHGUI_SmoothingDlg::DeactivateActiveDialog()
700 {
701   if (GroupConstructors->isEnabled()) {
702     GroupConstructors->setEnabled(false);
703     GroupArguments->setEnabled(false);
704     GroupButtons->setEnabled(false);
705     mySMESHGUI->ResetState();
706     mySMESHGUI->SetActiveDialogBox(0);
707   }
708 }
709
710 //=================================================================================
711 // function : ActivateThisDialog()
712 // purpose  : Activates this dialog
713 //=================================================================================
714 void SMESHGUI_SmoothingDlg::ActivateThisDialog()
715 {
716   // Emit a signal to deactivate the active dialog
717   mySMESHGUI->EmitSignalDeactivateDialog();
718   GroupConstructors->setEnabled(true);
719   GroupArguments->setEnabled(true);
720   GroupButtons->setEnabled(true);
721
722   mySMESHGUI->SetActiveDialogBox(this);
723   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
724     aViewWindow->SetSelectionMode(FaceSelection);
725   SelectionIntoArgument();
726 }
727
728 //=================================================================================
729 // function : enterEvent()
730 // purpose  : Mouse enter event
731 //=================================================================================
732 void SMESHGUI_SmoothingDlg::enterEvent (QEvent*)
733 {
734   if (!GroupConstructors->isEnabled()) {
735     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
736     if ( aViewWindow && !mySelector) {
737       mySelector = aViewWindow->GetSelector();
738     }
739     ActivateThisDialog();
740   }
741 }
742
743 //=======================================================================
744 // function : onSelectMesh()
745 // purpose  :
746 //=======================================================================
747 void SMESHGUI_SmoothingDlg::onSelectMesh (bool toSelectMesh)
748 {
749   if (toSelectMesh)
750     TextLabelElements->setText(tr("SMESH_NAME"));
751   else
752     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
753   myElemFilterBtn->setEnabled(!toSelectMesh);
754
755   if (myEditCurrentArgument != LineEditElements &&
756       myEditCurrentArgument != LineEditNodes) {
757     LineEditElements->clear();
758     LineEditNodes->clear();
759     return;
760   }
761
762   mySelectionMgr->clearFilters();
763   SMESH::SetPointRepresentation(false);
764
765   if (toSelectMesh) {
766     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
767       aViewWindow->SetSelectionMode(ActorSelection);
768     //    mySelectionMgr->setSelectionModes(ActorSelection);
769     mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
770     myEditCurrentArgument->setReadOnly(true);
771     myEditCurrentArgument->setValidator(0);
772   } else {
773     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
774       aViewWindow->SetSelectionMode(myEditCurrentArgument == LineEditElements ? FaceSelection 
775                                                                               : NodeSelection );
776     myEditCurrentArgument->setReadOnly(false);
777     LineEditElements->setValidator(myIdValidator);
778     onTextChange(myEditCurrentArgument->text());
779   }
780
781   SelectionIntoArgument();
782 }
783
784 //=================================================================================
785 // function : keyPressEvent()
786 // purpose  :
787 //=================================================================================
788 void SMESHGUI_SmoothingDlg::keyPressEvent( QKeyEvent* e )
789 {
790   QDialog::keyPressEvent( e );
791   if ( e->isAccepted() )
792     return;
793
794   if ( e->key() == Qt::Key_F1 ) {
795     e->accept();
796     ClickOnHelp();
797   }
798 }
799
800 //=================================================================================
801 // function : setFilters()
802 // purpose  : activate filter dialog
803 //=================================================================================
804 void SMESHGUI_SmoothingDlg::setFilters( const bool theIsElem )
805 {
806   if(myMesh->_is_nil()) {
807     SUIT_MessageBox::critical(this,
808                               tr("SMESH_ERROR"),
809                               tr("NO_MESH_SELECTED"));
810    return;
811   }
812   if ( !myFilterDlg )
813   {
814     QList<int> types;  
815     types.append( SMESH::NODE );
816     types.append( SMESH::ALL );
817     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
818   }
819   myFilterDlg->Init( theIsElem ? SMESH::ALL : SMESH::NODE );
820
821   myFilterDlg->SetSelection();
822   myFilterDlg->SetMesh( myMesh );
823   myFilterDlg->SetSourceWg( theIsElem ? LineEditElements : LineEditNodes );
824
825   myFilterDlg->show();
826 }
827
828 //=================================================================================
829 // function : setElemFilters()
830 // purpose  : SLOT. Called when element "Filter" button pressed.
831 //=================================================================================
832 void SMESHGUI_SmoothingDlg::setElemFilters()
833 {
834   setFilters( true );
835 }
836
837 //=================================================================================
838 // function : setNodeFilters()
839 // purpose  : SLOT. Called when node "Filter" button pressed.
840 //=================================================================================
841 void SMESHGUI_SmoothingDlg::setNodeFilters()
842 {
843   setFilters( false );
844 }
845
846 //=================================================================================
847 // function : isValid
848 // purpose  :
849 //=================================================================================
850 bool SMESHGUI_SmoothingDlg::isValid()
851 {
852   QString msg;
853   bool ok = true;
854   ok = SpinBox_IterationLimit->isValid( msg, true ) && ok;
855   ok = SpinBox_AspectRatio->isValid( msg, true ) && ok;
856
857   if( !ok ) {
858     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
859     if ( !msg.isEmpty() )
860       str += "\n" + msg;
861     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
862     return false;
863   }
864   return true;
865 }