Salome HOME
Merge branch 'V8_4_BR'
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_OffsetDlg.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 //  File   : SMESHGUI_OffsetDlg.cxx
20
21 //  SMESH includes
22
23 #include "SMESHGUI_OffsetDlg.h"
24
25 #include "SMESHGUI.h"
26 #include "SMESHGUI_SpinBox.h"
27 #include "SMESHGUI_Utils.h"
28 #include "SMESHGUI_VTKUtils.h"
29 #include "SMESHGUI_MeshUtils.h"
30 #include "SMESHGUI_IdValidator.h"
31 #include "SMESHGUI_FilterDlg.h"
32 #include "SMESHGUI_MeshEditPreview.h"
33
34 #include <SMESH_Actor.h>
35 #include <SMESH_TypeFilter.hxx>
36 #include <SMESH_LogicalFilter.hxx>
37 #include <SMDS_Mesh.hxx>
38
39 // SALOME GUI includes
40 #include <LightApp_Application.h>
41 #include <LightApp_SelectionMgr.h>
42 #include <SALOME_ListIO.hxx>
43 #include <SUIT_Desktop.h>
44 #include <SUIT_MessageBox.h>
45 #include <SUIT_OverrideCursor.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_Session.h>
48 #include <SVTK_ViewModel.h>
49 #include <SVTK_ViewWindow.h>
50 #include <SalomeApp_Tools.h>
51
52 // SALOME KERNEL includes
53 #include <SALOMEDSClient.hxx>
54 #include <SALOMEDSClient_SObject.hxx>
55
56 // OCCT includes
57 #include <TColStd_MapOfInteger.hxx>
58
59 // Qt includes
60 #include <QApplication>
61 #include <QButtonGroup>
62 #include <QGroupBox>
63 #include <QLabel>
64 #include <QLineEdit>
65 #include <QPushButton>
66 #include <QRadioButton>
67 #include <QCheckBox>
68 #include <QHBoxLayout>
69 #include <QVBoxLayout>
70 #include <QGridLayout>
71 #include <QSpinBox>
72 #include <QKeyEvent>
73
74 // IDL includes
75 #include <SALOMEconfig.h>
76 #include CORBA_SERVER_HEADER(SMESH_Group)
77 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
78
79 enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action type
80
81 /*!
82   \class BusyLocker
83   \brief Simple 'busy state' flag locker.
84   \internal
85 */
86 class BusyLocker
87 {
88 public:
89   //! Constructor. Sets passed boolean flag to \c true.
90   BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
91   //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
92   ~BusyLocker() { myBusy = false; }
93 private:
94   bool& myBusy; //! External 'busy state' boolean flag
95 };
96
97 #define SPACING 6
98 #define MARGIN  11
99
100 //=================================================================================
101 // class    : SMESHGUI_OffsetDlg()
102 // purpose  :
103 //=================================================================================
104 SMESHGUI_OffsetDlg::SMESHGUI_OffsetDlg( SMESHGUI* theModule ) :
105   SMESHGUI_MultiPreviewDlg( theModule ),
106   mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
107   myFilterDlg(0)
108 {
109   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MESH_OFFSET")));
110   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
111
112   setModal(false);
113   setAttribute(Qt::WA_DeleteOnClose, true);
114   setWindowTitle(tr("SMESH_OFFSET_TITLE"));
115   setSizeGripEnabled(true);
116
117   QVBoxLayout* dlgLayout = new QVBoxLayout(this);
118   dlgLayout->setSpacing(SPACING);
119   dlgLayout->setMargin(MARGIN);
120
121   /***************************************************************/
122   ConstructorsBox = new QGroupBox(tr("SMESH_OFFSET"), this);
123   QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
124   ConstructorsBoxLayout->setSpacing(SPACING);
125   ConstructorsBoxLayout->setMargin(MARGIN);
126
127   QRadioButton* RadioButton1= new QRadioButton(ConstructorsBox);
128   RadioButton1->setIcon(image0);
129
130   ConstructorsBoxLayout->addWidget(RadioButton1);
131
132   /***************************************************************/
133   GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
134   QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
135   GroupArgumentsLayout->setSpacing(SPACING);
136   GroupArgumentsLayout->setMargin(MARGIN);
137
138   myIdValidator = new SMESHGUI_IdValidator(this);
139
140   // Controls for elements selection
141   TextLabelElements = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments);
142   // SelectElementsButton = new QPushButton(GroupArguments);
143   // SelectElementsButton->setIcon(image1);
144   LineEditElements = new QLineEdit(GroupArguments);
145   LineEditElements->setValidator(myIdValidator);
146   LineEditElements->setMaxLength(-1);
147   myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
148   connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
149
150   // Control for the whole mesh selection
151   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
152
153   // offset
154   QLabel* TextLabel1 = new QLabel(tr("OFFSET_VALUE"), GroupArguments);
155   SpinBox = new SMESHGUI_SpinBox(GroupArguments);
156
157
158   // switch of action type
159   ActionBox = new QGroupBox(GroupArguments);
160   ActionGroup = new QButtonGroup(GroupArguments);
161   QVBoxLayout* ActionBoxLayout = new QVBoxLayout(ActionBox);
162   ActionBoxLayout->addSpacing(SPACING);
163   ActionBoxLayout->setMargin(MARGIN);
164
165   QRadioButton* aMoveElements = new QRadioButton(tr("SMESH_MOVE_ELEMENTS"), ActionBox);
166   QRadioButton* aCopyElements = new QRadioButton(tr("SMESH_COPY_ELEMENTS"), ActionBox);
167   QRadioButton* aCreateMesh   = new QRadioButton(tr("SMESH_CREATE_MESH"),   ActionBox);
168
169   ActionBoxLayout->addWidget(aMoveElements);
170   ActionBoxLayout->addWidget(aCopyElements);
171   ActionBoxLayout->addWidget(aCreateMesh);
172   ActionGroup->addButton(aMoveElements, MOVE_ELEMS_BUTTON);
173   ActionGroup->addButton(aCopyElements, COPY_ELEMS_BUTTON);
174   ActionGroup->addButton(aCreateMesh,   MAKE_MESH_BUTTON);
175
176   // CheckBox for groups generation
177   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
178   MakeGroupsCheck->setChecked(false);
179
180   // Name of a mesh to create
181   LineEditNewMesh = new QLineEdit(GroupArguments);
182
183   //Preview check box
184   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
185
186   // layout
187   GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
188   //GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
189   GroupArgumentsLayout->addWidget(LineEditElements,     0, 2, 1, 5);
190   GroupArgumentsLayout->addWidget(myFilterBtn,          0, 7);
191   GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 8);
192   GroupArgumentsLayout->addWidget(TextLabel1,           2, 0);
193   GroupArgumentsLayout->addWidget(SpinBox,              2, 3);
194   GroupArgumentsLayout->addWidget(ActionBox,            3, 0, 3, 4);
195   GroupArgumentsLayout->addWidget(MakeGroupsCheck,      4, 5, 1, 4);
196   GroupArgumentsLayout->addWidget(LineEditNewMesh,      5, 5, 1, 4);
197   GroupArgumentsLayout->addWidget(myPreviewCheckBox,    6, 0);
198
199   /***************************************************************/
200   GroupButtons = new QGroupBox(this);
201   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
202   GroupButtonsLayout->setSpacing(SPACING);
203   GroupButtonsLayout->setMargin(MARGIN);
204
205   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
206   buttonOk->setAutoDefault(true);
207   buttonOk->setDefault(true);
208   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
209   buttonApply->setAutoDefault(true);
210   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
211   buttonCancel->setAutoDefault(true);
212   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
213   buttonHelp->setAutoDefault(true);
214
215   GroupButtonsLayout->addWidget(buttonOk);
216   GroupButtonsLayout->addSpacing(10);
217   GroupButtonsLayout->addWidget(buttonApply);
218   GroupButtonsLayout->addSpacing(10);
219   GroupButtonsLayout->addStretch();
220   GroupButtonsLayout->addWidget(buttonCancel);
221   GroupButtonsLayout->addWidget(buttonHelp);
222
223   /***************************************************************/
224   dlgLayout->addWidget(ConstructorsBox);
225   dlgLayout->addWidget(GroupArguments);
226   dlgLayout->addWidget(GroupButtons);
227
228   /* Initialisations */
229   SpinBox->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision");
230
231   RadioButton1->setChecked(true);
232
233   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
234
235   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
236
237   // Costruction of the logical filter
238   SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (SMESH::MESHorSUBMESH);
239   SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (SMESH::GROUP);
240
241   QList<SUIT_SelectionFilter*> aListOfFilters;
242   if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
243   if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
244
245   myMeshOrSubMeshOrGroupFilter =
246     new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR);
247
248   myHelpFileName = "Offset_page.html";
249
250   Init();
251
252   /* signals and slots connections */
253   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
254   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
255   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
256   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
257
258   //connect(SelectElementsButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
259
260   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
261   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),   this, SLOT(SelectionIntoArgument()));
262   /* to close dialog if study change */
263   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
264   connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
265   connect(mySMESHGUI, SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
266
267   connect(LineEditElements, SIGNAL(textChanged(const QString&)),    SLOT(onTextChange(const QString&)));
268   connect(CheckBoxMesh,     SIGNAL(toggled(bool)),                  SLOT(onSelectMesh(bool)));
269   connect(ActionGroup,      SIGNAL(buttonClicked(int)),             SLOT(onActionClicked(int)));
270
271   connect(SpinBox,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
272
273   //To Connect preview check box
274   connectPreviewControl();
275
276   SelectionIntoArgument();
277   onActionClicked(MOVE_ELEMS_BUTTON);
278 }
279
280 //=================================================================================
281 // function : ~SMESHGUI_OffsetDlg()
282 // purpose  : Destroys the object and frees any allocated resources
283 //=================================================================================
284 SMESHGUI_OffsetDlg::~SMESHGUI_OffsetDlg()
285 {
286   if ( myFilterDlg ) {
287     myFilterDlg->setParent( 0 );
288     delete myFilterDlg;
289     myFilterDlg = 0;
290   }
291 }
292
293 //=================================================================================
294 // function : Init()
295 // purpose  :
296 //=================================================================================
297 void SMESHGUI_OffsetDlg::Init (bool ResetControls)
298 {
299   myBusy = false;
300   myObjects.clear();
301   myObjectsNames.clear();
302   myMeshes.clear();
303
304   LineEditElements->clear();
305   myElementsId = "";
306   myNbOkElements = 0;
307
308   buttonOk->setEnabled(false);
309   buttonApply->setEnabled(false);
310
311   myActor = 0;
312
313   if (ResetControls)
314   {
315     SpinBox->SetValue(1.0);
316     myPreviewCheckBox->setChecked(false);
317     onDisplaySimulation(false);
318
319     ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true);
320     CheckBoxMesh->setChecked(true);
321     onSelectMesh(true);
322   }
323 }
324
325 //=================================================================================
326 // function : ClickOnApply()
327 // purpose  :
328 //=================================================================================
329 bool SMESHGUI_OffsetDlg::ClickOnApply()
330 {
331   if (mySMESHGUI->isActiveStudyLocked())
332     return false;
333
334   if( !isValid() )
335     return false;
336
337   SUIT_OverrideCursor aWaitCursor;
338
339   if (myNbOkElements)
340   {
341     QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
342
343     SMESH::long_array_var anElementsId = new SMESH::long_array;
344     anElementsId->length(aListElementsId.count());
345     for (int i = 0; i < aListElementsId.count(); i++)
346       anElementsId[i] = aListElementsId[i].toInt();
347
348     double offsetValue = SpinBox->value();
349
350     QStringList aParameters;
351     aParameters << SpinBox->text();
352
353     int actionButton = ActionGroup->checkedId();
354     bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
355     SMESH::ListOfGroups_var groups;
356     SMESH::SMESH_Mesh_var mesh;
357     QStringList anEntryList;
358     try
359     {
360       switch ( actionButton ) {
361
362       case MOVE_ELEMS_BUTTON:
363         if ( CheckBoxMesh->isChecked() )
364           for ( int i = 0; i < myObjects.count(); i++ ) {
365             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
366             myMeshes[i]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
367             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, true, "", groups.out() );
368           }
369         else {
370           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
371           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE);
372           myMeshes[0]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
373           mesh = aMeshEditor->Offset( src, offsetValue, true, "", groups.out() );
374         }
375         break;
376
377       case COPY_ELEMS_BUTTON:
378         if ( CheckBoxMesh->isChecked() )
379           for ( int i = 0; i < myObjects.count(); i++ ) {
380             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
381             myMeshes[i]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
382             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups, "", groups.out() );
383           }
384         else {
385           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
386           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE );
387           myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
388           mesh = aMeshEditor->Offset( src, offsetValue, makeGroups, "", groups.out() );
389         }
390         break;
391
392       case MAKE_MESH_BUTTON: {
393         SMESH::SMESH_Mesh_var mesh;
394         if ( CheckBoxMesh->isChecked() ) {
395           for ( int i = 0; i < myObjects.count(); i++ ) {
396             QString aName =
397               SMESH::UniqueMeshName( LineEditNewMesh->text().replace( "*", myObjectsNames[i] ));
398             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
399             myMeshes[i]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
400             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups,
401                                         aName.toLatin1().data(), groups.out() );
402             if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ))
403               anEntryList.append( aSObject->GetID().c_str() );
404           }
405         }
406         else {
407           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
408           myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
409           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE );
410           mesh = aMeshEditor->Offset( src, offsetValue, makeGroups,
411                                       LineEditNewMesh->text().toLatin1().data(), groups.out() );
412           if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
413             anEntryList.append( aSObject->GetID().c_str() );
414         }
415         break;
416       }
417       }
418     }
419     catch ( const SALOME::SALOME_Exception& S_ex ) {
420       SalomeApp_Tools::QtCatchCorbaException( S_ex );
421     }
422     catch (...) {
423     }
424
425     for ( int i = 0; i < myObjects.count(); i++ ) {
426       SMESH_Actor* actor = SMESH::FindActorByObject( myObjects[i] );
427       if ( actor ) SMESH::Update( actor->getIO(), true );
428     }
429
430     if ( makeGroups || actionButton == MAKE_MESH_BUTTON )
431     {
432       mySMESHGUI->updateObjBrowser(true); // new groups may appear
433       if( LightApp_Application* anApp =
434           dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
435         anApp->browseObjects( anEntryList, isApplyAndClose() );
436     }
437     if ( !isApplyAndClose() )
438     {
439       Init(false);
440       SelectionIntoArgument();
441     }
442     SMESHGUI::Modified();
443   }
444
445   return true;
446 }
447
448 //=================================================================================
449 // function : ClickOnOk()
450 // purpose  :
451 //=================================================================================
452 void SMESHGUI_OffsetDlg::ClickOnOk()
453 {
454   setIsApplyAndClose( true );
455   if( ClickOnApply() )
456     reject();
457 }
458
459 //=================================================================================
460 // function : reject()
461 // purpose  :
462 //=================================================================================
463 void SMESHGUI_OffsetDlg::reject()
464 {
465   disconnect(mySelectionMgr, 0, this, 0);
466   mySelectionMgr->clearFilters();
467   if (SMESH::GetCurrentVtkView()) {
468     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
469     SMESH::SetPointRepresentation(false);
470   }
471   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
472     aViewWindow->SetSelectionMode( ActorSelection );
473   mySMESHGUI->ResetState();
474   QDialog::reject();
475 }
476
477 //=================================================================================
478 // function : onOpenView()
479 // purpose  :
480 //=================================================================================
481 void SMESHGUI_OffsetDlg::onOpenView()
482 {
483   if ( mySelector ) {
484     SMESH::SetPointRepresentation(false);
485   }
486   else {
487     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
488     ActivateThisDialog();
489   }
490 }
491
492 //=================================================================================
493 // function : onCloseView()
494 // purpose  :
495 //=================================================================================
496 void SMESHGUI_OffsetDlg::onCloseView()
497 {
498   DeactivateActiveDialog();
499   mySelector = 0;
500 }
501
502 //=================================================================================
503 // function : ClickOnHelp()
504 // purpose  :
505 //=================================================================================
506 void SMESHGUI_OffsetDlg::ClickOnHelp()
507 {
508   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
509   if (app)
510     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
511   else {
512     QString platform;
513 #ifdef WIN32
514     platform = "winapplication";
515 #else
516     platform = "application";
517 #endif
518     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
519                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
520                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
521                                                                  platform)).
522                              arg(myHelpFileName));
523   }
524 }
525
526 //=======================================================================
527 // function : onTextChange()
528 // purpose  :
529 //=======================================================================
530
531 void SMESHGUI_OffsetDlg::onTextChange (const QString& theNewText)
532 {
533   if (myBusy) return;
534   BusyLocker lock( myBusy );
535
536   myNbOkElements = 0;
537
538   buttonOk->setEnabled(false);
539   buttonApply->setEnabled(false);
540
541   // highlight entered elements
542   SMDS_Mesh* aMesh = 0;
543   if (myActor)
544     aMesh = myActor->GetObject()->GetMesh();
545
546   if (aMesh) {
547     Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
548
549     TColStd_MapOfInteger newIndices;
550
551     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
552     for (int i = 0; i < aListId.count(); i++)
553     {
554       if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()))
555         newIndices.Add( e->GetID() );
556       myNbOkElements++;
557     }
558
559     mySelector->AddOrRemoveIndex( anIO, newIndices, false );
560     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
561       aViewWindow->highlight( anIO, true, true );
562
563     myElementsId = theNewText;
564   }
565
566   if (myNbOkElements) {
567     buttonOk->setEnabled(true);
568     buttonApply->setEnabled(true);
569   }
570 }
571
572 //=================================================================================
573 // function : SelectionIntoArgument()
574 // purpose  : Called when selection as changed or other case
575 //=================================================================================
576 void SMESHGUI_OffsetDlg::SelectionIntoArgument()
577 {
578   if (myBusy) return;
579   if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
580
581   BusyLocker lock( myBusy );
582
583   // clear
584   myActor = 0;
585   QString aString = "";
586   onDisplaySimulation(false);
587
588   LineEditElements->setText(aString);
589   myNbOkElements = 0;
590   buttonOk->setEnabled(false);
591   buttonApply->setEnabled(false);
592
593   if (!GroupButtons->isEnabled()) // inactive
594     return;
595
596   // get selected mesh
597   SALOME_ListIO aList;
598   mySelectionMgr->selectedObjects(aList);
599
600   int nbSel = aList.Extent();
601   if (nbSel < 1)
602     return;
603
604   myElementsId = "";
605   myObjects.clear();
606   myObjectsNames.clear();
607   myMeshes.clear();
608
609   for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
610   {
611     Handle(SALOME_InteractiveObject) IO = it.Value();
612     SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
613     if ( aMesh->_is_nil() || aMesh->NbFaces() == 0 )
614       return;
615
616     myActor = SMESH::FindActorByObject( aMesh );
617     if ( !myActor )
618       myActor = SMESH::FindActorByEntry( IO->getEntry() );
619
620     SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
621     if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
622     {
623       std::string name = obj->GetName();
624       if ( !name.empty() )
625       {
626         myObjects << idSrc;
627         myObjectsNames << name.c_str();
628         myMeshes << aMesh;
629       }
630     }
631   }
632
633   // MakeGroups is available if there are groups and "Copy"
634   int aNbGroups = 0;
635   for ( int i = 0; i < myMeshes.count(); i++ )
636     aNbGroups += myMeshes[i]->NbGroups();
637
638   if ( aNbGroups == 0 ) {
639     MakeGroupsCheck->setChecked(false);
640     MakeGroupsCheck->setEnabled(false);
641   }
642   else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) {
643     MakeGroupsCheck->setEnabled(true);
644   }
645
646   if (CheckBoxMesh->isChecked()) {
647     if (myMeshes.isEmpty())
648       return;
649     SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
650   }
651   else {
652     int aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString);
653     myElementsId = aString;
654     if (aNbUnits < 1)
655       return;
656   }
657
658   myNbOkElements = true;
659   
660   LineEditElements->setText(aString);
661   LineEditElements->repaint();
662   LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809
663   LineEditElements->setEnabled(true);
664   setNewMeshName();
665
666   buttonOk->setEnabled(true);
667   buttonApply->setEnabled(true);
668
669   onDisplaySimulation(true);
670 }
671
672 //=================================================================================
673 // function : DeactivateActiveDialog()
674 // purpose  :
675 //=================================================================================
676
677 void SMESHGUI_OffsetDlg::DeactivateActiveDialog()
678 {
679   if (ConstructorsBox->isEnabled())
680   {
681     ConstructorsBox->setEnabled(false);
682     GroupArguments->setEnabled(false);
683     GroupButtons->setEnabled(false);
684     mySMESHGUI->ResetState();
685     mySMESHGUI->SetActiveDialogBox(0);
686   }
687 }
688
689 //=================================================================================
690 // function : ActivateThisDialog()
691 // purpose  :
692 //=================================================================================
693
694 void SMESHGUI_OffsetDlg::ActivateThisDialog()
695 {
696   /* Emit a signal to deactivate the active dialog */
697   mySMESHGUI->EmitSignalDeactivateDialog();
698   ConstructorsBox->setEnabled(true);
699   GroupArguments->setEnabled(true);
700   GroupButtons->setEnabled(true);
701
702   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
703
704   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
705     aViewWindow->SetSelectionMode( CellSelection );
706
707   SelectionIntoArgument();
708 }
709
710 //=================================================================================
711 // function : enterEvent()
712 // purpose  :
713 //=================================================================================
714
715 void SMESHGUI_OffsetDlg::enterEvent (QEvent*)
716 {
717   if (!ConstructorsBox->isEnabled()) {
718     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
719     if ( aViewWindow && !mySelector) {
720       mySelector = aViewWindow->GetSelector();
721     }
722     ActivateThisDialog();
723   }
724 }
725
726 //=======================================================================
727 //function : onSelectMesh
728 //purpose  :
729 //=======================================================================
730
731 void SMESHGUI_OffsetDlg::onSelectMesh (bool toSelectMesh)
732 {
733   if (toSelectMesh)
734     TextLabelElements->setText(tr("SMESH_NAME"));
735   else
736     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
737   myFilterBtn->setEnabled(!toSelectMesh);
738
739   mySelectionMgr->clearFilters();
740   SMESH::SetPointRepresentation(false);
741
742   if (toSelectMesh)
743   {
744     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
745       aViewWindow->SetSelectionMode( ActorSelection );
746     mySelectionMgr->installFilter( myMeshOrSubMeshOrGroupFilter );
747     LineEditElements->setReadOnly( true );
748     LineEditElements->setValidator( 0 );
749   }
750   else
751   {
752     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
753       aViewWindow->SetSelectionMode( FaceSelection );
754     LineEditElements->setReadOnly( false );
755     LineEditElements->setValidator( myIdValidator );
756     onTextChange(LineEditElements->text());
757     hidePreview();
758   }
759
760   SelectionIntoArgument();
761 }
762
763 //=======================================================================
764 //function : onActionClicked
765 //purpose  : slot called when an action type changed
766 //=======================================================================
767
768 void SMESHGUI_OffsetDlg::onActionClicked(int button)
769 {
770   int aNbGroups = 0;
771   for ( int i = 0; i < myMeshes.count(); i++ )
772     aNbGroups += myMeshes[i]->NbGroups();
773
774   switch ( button ) {
775   case MOVE_ELEMS_BUTTON:
776     MakeGroupsCheck->setEnabled(false);
777     LineEditNewMesh->setEnabled(false);
778     break;
779   case COPY_ELEMS_BUTTON:
780     LineEditNewMesh->setEnabled(false);
781     MakeGroupsCheck->setText( tr("SMESH_MAKE_GROUPS"));
782     MakeGroupsCheck->setEnabled( myMeshes.isEmpty() || aNbGroups > 0 );
783     break;
784   case MAKE_MESH_BUTTON:
785     LineEditNewMesh->setEnabled(true);
786     MakeGroupsCheck->setText( tr("SMESH_COPY_GROUPS"));
787     MakeGroupsCheck->setEnabled( myMeshes.isEmpty() || aNbGroups > 0 );
788     break;
789   }
790   setNewMeshName();
791   //toDisplaySimulation();
792 }
793
794 //=======================================================================
795 //function : setNewMeshName
796 //purpose  : update contents of LineEditNewMesh
797 //=======================================================================
798
799 void SMESHGUI_OffsetDlg::setNewMeshName()
800 {
801   LineEditNewMesh->setText("");
802   if ( LineEditNewMesh->isEnabled() && !myMeshes.isEmpty() ) {
803     QString name;
804     if ( CheckBoxMesh->isChecked() ) {
805       name = myObjects.count() > 1 ? "*" : LineEditElements->text();
806     }
807     else {
808       _PTR(SObject) meshSO = SMESH::FindSObject( myMeshes[0] );
809       name = meshSO->GetName().c_str();
810     }
811     if ( !name.isEmpty() )
812       LineEditNewMesh->setText( SMESH::UniqueMeshName( name, "Offset"));
813   }
814 }
815
816 //=================================================================================
817 // function : keyPressEvent()
818 // purpose  :
819 //=================================================================================
820
821 void SMESHGUI_OffsetDlg::keyPressEvent( QKeyEvent* e )
822 {
823   QDialog::keyPressEvent( e );
824   if ( e->isAccepted() )
825     return;
826
827   if ( e->key() == Qt::Key_F1 ) {
828     e->accept();
829     ClickOnHelp();
830   }
831 }
832
833 //=================================================================================
834 // function : setFilters()
835 // purpose  : SLOT. Called when "Filter" button pressed.
836 //=================================================================================
837
838 void SMESHGUI_OffsetDlg::setFilters()
839 {
840   if ( myMeshes.isEmpty() ) {
841     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
842     return;
843   }
844   if ( !myFilterDlg ) {
845     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
846     connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
847   }
848
849   myFilterDlg->Init( SMESH::FACE );
850   myFilterDlg->SetSelection();
851   myFilterDlg->SetMesh( myMeshes[0] );
852   myFilterDlg->SetSourceWg( LineEditElements );
853
854   myFilterDlg->show();
855 }
856
857 //=======================================================================
858 // name    : onFilterAccepted()
859 // Purpose : SLOT. Called when Filter dlg closed with OK button.
860 //           Activate [Apply] if no Actor is available
861 //=======================================================================
862
863 void SMESHGUI_OffsetDlg::onFilterAccepted()
864 {
865   if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
866   {
867     myElementsId = LineEditElements->text();
868     QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
869     myNbOkElements = aListElementsId.count();
870     buttonOk->setEnabled   ( myNbOkElements );
871     buttonApply->setEnabled( myNbOkElements );
872   }
873 }
874
875 //=================================================================================
876 // function : isValid
877 // purpose  :
878 //=================================================================================
879
880 bool SMESHGUI_OffsetDlg::isValid()
881 {
882   return true;
883 }
884
885 //=================================================================================
886 // function : onDisplaySimulation
887 // purpose  : Show/Hide preview
888 //=================================================================================
889 void SMESHGUI_OffsetDlg::onDisplaySimulation( bool toDisplayPreview )
890 {
891   SUIT_OverrideCursor aWaitCursor;
892
893   if (myPreviewCheckBox->isChecked() && toDisplayPreview)
894   {
895     if ( myNbOkElements && isValid() )
896     {
897       double offsetValue = SpinBox->value();
898
899       SMESH::ListOfGroups_var groups;
900       SMESH::SMESH_Mesh_var mesh;
901
902       try
903       {
904         QList<SMESH::MeshPreviewStruct_var> aMeshPreviewStruct;
905
906         if ( CheckBoxMesh->isChecked())
907           for ( int i = 0; i < myObjects.count(); i++ )
908           {
909             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditPreviewer();
910             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, false, "", groups.out() );
911             aMeshPreviewStruct << aMeshEditor->GetPreviewData();
912           }
913         else
914         {
915           SMESH::long_array_var anElementsId = new SMESH::long_array;
916           QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
917           anElementsId->length(aListElementsId.count());
918           for (int i = 0; i < aListElementsId.count(); i++)
919             anElementsId[i] = aListElementsId[i].toInt();
920
921           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditPreviewer();
922           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE);
923           mesh = aMeshEditor->Offset( src, offsetValue, false, "", groups.out() );
924           aMeshPreviewStruct << aMeshEditor->GetPreviewData();
925         }
926         setSimulationPreview(aMeshPreviewStruct);
927
928       } catch (...) {
929         hidePreview();
930       }
931     } else {
932       hidePreview();
933     }
934   } else {
935     hidePreview();
936   }
937 }