Salome HOME
bos #20256: [CEA 18523] Porting SMESH to int 64 bits
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_OffsetDlg.cxx
1 // Copyright (C) 2007-2021  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->isStudyLocked())
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::smIdType_array_var anElementsId = new SMESH::smIdType_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 copyElements = ( actionButton == COPY_ELEMS_BUTTON );
355     bool   makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
356     SMESH::ListOfGroups_var groups;
357     SMESH::SMESH_Mesh_var mesh;
358     QStringList anEntryList;
359     try
360     {
361       switch ( actionButton ) {
362
363       case MOVE_ELEMS_BUTTON:
364         makeGroups = true;
365         if ( CheckBoxMesh->isChecked() )
366           for ( int i = 0; i < myObjects.count(); i++ ) {
367             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
368             myMeshes[i]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
369             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups,
370                                         copyElements, "", groups.out() );
371           }
372         else {
373           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
374           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE);
375           myMeshes[0]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
376           mesh = aMeshEditor->Offset( src, offsetValue, makeGroups,
377                                       copyElements, "", groups.out() );
378         }
379         break;
380
381       case COPY_ELEMS_BUTTON:
382         if ( CheckBoxMesh->isChecked() )
383           for ( int i = 0; i < myObjects.count(); i++ ) {
384             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
385             myMeshes[i]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
386             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups,
387                                         copyElements, "", groups.out() );
388           }
389         else {
390           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
391           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE );
392           myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
393           mesh = aMeshEditor->Offset( src, offsetValue, makeGroups,
394                                       copyElements, "", groups.out() );
395         }
396         break;
397
398       case MAKE_MESH_BUTTON: {
399         SMESH::SMESH_Mesh_var mesh;
400         if ( CheckBoxMesh->isChecked() ) {
401           for ( int i = 0; i < myObjects.count(); i++ ) {
402             QString aName =
403               SMESH::UniqueMeshName( LineEditNewMesh->text().replace( "*", myObjectsNames[i] ));
404             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditor();
405             myMeshes[i]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
406             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, makeGroups, copyElements,
407                                         aName.toLatin1().data(), groups.out() );
408             if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ))
409               anEntryList.append( aSObject->GetID().c_str() );
410           }
411         }
412         else {
413           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
414           myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
415           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE );
416           mesh = aMeshEditor->Offset( src, offsetValue, makeGroups, copyElements,
417                                       LineEditNewMesh->text().toLatin1().data(), groups.out() );
418           if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
419             anEntryList.append( aSObject->GetID().c_str() );
420         }
421         break;
422       }
423       }
424     }
425     catch ( const SALOME::SALOME_Exception& S_ex ) {
426       SalomeApp_Tools::QtCatchCorbaException( S_ex );
427     }
428     catch (...) {
429     }
430
431     for ( int i = 0; i < myObjects.count(); i++ ) {
432       SMESH_Actor* actor = SMESH::FindActorByObject( myObjects[i] );
433       if ( actor ) SMESH::Update( actor->getIO(), true );
434     }
435
436     if ( makeGroups || actionButton == MAKE_MESH_BUTTON )
437     {
438       mySMESHGUI->updateObjBrowser(true); // new groups may appear
439       if( LightApp_Application* anApp =
440           dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
441         anApp->browseObjects( anEntryList, isApplyAndClose() );
442     }
443     if ( !isApplyAndClose() )
444     {
445       Init(false);
446       SelectionIntoArgument();
447     }
448     SMESHGUI::Modified();
449   }
450
451   return true;
452 }
453
454 //=================================================================================
455 // function : ClickOnOk()
456 // purpose  :
457 //=================================================================================
458 void SMESHGUI_OffsetDlg::ClickOnOk()
459 {
460   setIsApplyAndClose( true );
461   if( ClickOnApply() )
462     reject();
463 }
464
465 //=================================================================================
466 // function : reject()
467 // purpose  :
468 //=================================================================================
469 void SMESHGUI_OffsetDlg::reject()
470 {
471   disconnect(mySelectionMgr, 0, this, 0);
472   mySelectionMgr->clearFilters();
473   if (SMESH::GetCurrentVtkView()) {
474     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
475     SMESH::SetPointRepresentation(false);
476   }
477   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
478     aViewWindow->SetSelectionMode( ActorSelection );
479   mySMESHGUI->ResetState();
480   QDialog::reject();
481 }
482
483 //=================================================================================
484 // function : onOpenView()
485 // purpose  :
486 //=================================================================================
487 void SMESHGUI_OffsetDlg::onOpenView()
488 {
489   if ( mySelector ) {
490     SMESH::SetPointRepresentation(false);
491   }
492   else {
493     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
494     ActivateThisDialog();
495   }
496 }
497
498 //=================================================================================
499 // function : onCloseView()
500 // purpose  :
501 //=================================================================================
502 void SMESHGUI_OffsetDlg::onCloseView()
503 {
504   DeactivateActiveDialog();
505   mySelector = 0;
506 }
507
508 //=================================================================================
509 // function : ClickOnHelp()
510 // purpose  :
511 //=================================================================================
512 void SMESHGUI_OffsetDlg::ClickOnHelp()
513 {
514   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
515   if (app)
516     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
517   else {
518     QString platform;
519 #ifdef WIN32
520     platform = "winapplication";
521 #else
522     platform = "application";
523 #endif
524     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
525                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
526                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
527                                                                  platform)).
528                              arg(myHelpFileName));
529   }
530 }
531
532 //=======================================================================
533 // function : onTextChange()
534 // purpose  :
535 //=======================================================================
536
537 void SMESHGUI_OffsetDlg::onTextChange (const QString& theNewText)
538 {
539   if (myBusy) return;
540   BusyLocker lock( myBusy );
541
542   myNbOkElements = 0;
543
544   buttonOk->setEnabled(false);
545   buttonApply->setEnabled(false);
546
547   // highlight entered elements
548   SMDS_Mesh* aMesh = 0;
549   if (myActor)
550     aMesh = myActor->GetObject()->GetMesh();
551
552   if (aMesh) {
553     Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
554
555     SVTK_TVtkIDsMap newIndices;
556
557     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
558     for (int i = 0; i < aListId.count(); i++)
559     {
560       if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()))
561         newIndices.Add( e->GetID() );
562       myNbOkElements++;
563     }
564
565     mySelector->AddOrRemoveIndex( anIO, newIndices, false );
566     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
567       aViewWindow->highlight( anIO, true, true );
568
569     myElementsId = theNewText;
570   }
571
572   if (myNbOkElements) {
573     buttonOk->setEnabled(true);
574     buttonApply->setEnabled(true);
575   }
576 }
577
578 //=================================================================================
579 // function : SelectionIntoArgument()
580 // purpose  : Called when selection as changed or other case
581 //=================================================================================
582 void SMESHGUI_OffsetDlg::SelectionIntoArgument()
583 {
584   if (myBusy) return;
585   if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
586
587   BusyLocker lock( myBusy );
588
589   // clear
590   myActor = 0;
591   QString aString = "";
592   onDisplaySimulation(false);
593
594   LineEditElements->setText(aString);
595   myNbOkElements = 0;
596   buttonOk->setEnabled(false);
597   buttonApply->setEnabled(false);
598
599   if (!GroupButtons->isEnabled()) // inactive
600     return;
601
602   // get selected mesh
603   SALOME_ListIO aList;
604   mySelectionMgr->selectedObjects(aList);
605
606   int nbSel = aList.Extent();
607   if (nbSel < 1)
608     return;
609
610   myElementsId = "";
611   myObjects.clear();
612   myObjectsNames.clear();
613   myMeshes.clear();
614
615   for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
616   {
617     Handle(SALOME_InteractiveObject) IO = it.Value();
618     SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
619     if ( aMesh->_is_nil() || aMesh->NbFaces() == 0 )
620       return;
621
622     myActor = SMESH::FindActorByObject( aMesh );
623     if ( !myActor )
624       myActor = SMESH::FindActorByEntry( IO->getEntry() );
625
626     SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
627     if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
628     {
629       std::string name = obj->GetName();
630       if ( !name.empty() )
631       {
632         myObjects << idSrc;
633         myObjectsNames << name.c_str();
634         myMeshes << aMesh;
635       }
636     }
637   }
638
639   // MakeGroups is available if there are groups and "Copy"
640   int aNbGroups = 0;
641   for ( int i = 0; i < myMeshes.count(); i++ )
642     aNbGroups += myMeshes[i]->NbGroups();
643
644   if ( aNbGroups == 0 ) {
645     MakeGroupsCheck->setChecked(false);
646     MakeGroupsCheck->setEnabled(false);
647   }
648   else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) {
649     MakeGroupsCheck->setEnabled(true);
650   }
651
652   if (CheckBoxMesh->isChecked()) {
653     if (myMeshes.isEmpty())
654       return;
655     SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
656   }
657   else {
658     int aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString);
659     myElementsId = aString;
660     if (aNbUnits < 1)
661       return;
662   }
663
664   myNbOkElements = true;
665   
666   LineEditElements->setText(aString);
667   LineEditElements->repaint();
668   LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809
669   LineEditElements->setEnabled(true);
670   setNewMeshName();
671
672   buttonOk->setEnabled(true);
673   buttonApply->setEnabled(true);
674
675   onDisplaySimulation(true);
676 }
677
678 //=================================================================================
679 // function : DeactivateActiveDialog()
680 // purpose  :
681 //=================================================================================
682
683 void SMESHGUI_OffsetDlg::DeactivateActiveDialog()
684 {
685   if (ConstructorsBox->isEnabled())
686   {
687     ConstructorsBox->setEnabled(false);
688     GroupArguments->setEnabled(false);
689     GroupButtons->setEnabled(false);
690     mySMESHGUI->ResetState();
691     mySMESHGUI->SetActiveDialogBox(0);
692   }
693 }
694
695 //=================================================================================
696 // function : ActivateThisDialog()
697 // purpose  :
698 //=================================================================================
699
700 void SMESHGUI_OffsetDlg::ActivateThisDialog()
701 {
702   /* Emit a signal to deactivate the active dialog */
703   mySMESHGUI->EmitSignalDeactivateDialog();
704   ConstructorsBox->setEnabled(true);
705   GroupArguments->setEnabled(true);
706   GroupButtons->setEnabled(true);
707
708   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
709
710   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
711     aViewWindow->SetSelectionMode( CellSelection );
712
713   SelectionIntoArgument();
714 }
715
716 //=================================================================================
717 // function : enterEvent()
718 // purpose  :
719 //=================================================================================
720
721 void SMESHGUI_OffsetDlg::enterEvent (QEvent*)
722 {
723   if (!ConstructorsBox->isEnabled()) {
724     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
725     if ( aViewWindow && !mySelector) {
726       mySelector = aViewWindow->GetSelector();
727     }
728     ActivateThisDialog();
729   }
730 }
731
732 //=======================================================================
733 //function : onSelectMesh
734 //purpose  :
735 //=======================================================================
736
737 void SMESHGUI_OffsetDlg::onSelectMesh (bool toSelectMesh)
738 {
739   if (toSelectMesh)
740     TextLabelElements->setText(tr("SMESH_NAME"));
741   else
742     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
743   myFilterBtn->setEnabled(!toSelectMesh);
744
745   mySelectionMgr->clearFilters();
746   SMESH::SetPointRepresentation(false);
747
748   if (toSelectMesh)
749   {
750     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
751       aViewWindow->SetSelectionMode( ActorSelection );
752     mySelectionMgr->installFilter( myMeshOrSubMeshOrGroupFilter );
753     LineEditElements->setReadOnly( true );
754     LineEditElements->setValidator( 0 );
755   }
756   else
757   {
758     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
759       aViewWindow->SetSelectionMode( FaceSelection );
760     LineEditElements->setReadOnly( false );
761     LineEditElements->setValidator( myIdValidator );
762     onTextChange(LineEditElements->text());
763     hidePreview();
764   }
765
766   SelectionIntoArgument();
767 }
768
769 //=======================================================================
770 //function : onActionClicked
771 //purpose  : slot called when an action type changed
772 //=======================================================================
773
774 void SMESHGUI_OffsetDlg::onActionClicked(int button)
775 {
776   int aNbGroups = 0;
777   for ( int i = 0; i < myMeshes.count(); i++ )
778     aNbGroups += myMeshes[i]->NbGroups();
779
780   switch ( button ) {
781   case MOVE_ELEMS_BUTTON:
782     MakeGroupsCheck->setEnabled(false);
783     LineEditNewMesh->setEnabled(false);
784     break;
785   case COPY_ELEMS_BUTTON:
786     LineEditNewMesh->setEnabled(false);
787     MakeGroupsCheck->setText( tr("SMESH_MAKE_GROUPS"));
788     MakeGroupsCheck->setEnabled( myMeshes.isEmpty() || aNbGroups > 0 );
789     break;
790   case MAKE_MESH_BUTTON:
791     LineEditNewMesh->setEnabled(true);
792     MakeGroupsCheck->setText( tr("SMESH_COPY_GROUPS"));
793     MakeGroupsCheck->setEnabled( myMeshes.isEmpty() || aNbGroups > 0 );
794     break;
795   }
796   setNewMeshName();
797   //toDisplaySimulation();
798 }
799
800 //=======================================================================
801 //function : setNewMeshName
802 //purpose  : update contents of LineEditNewMesh
803 //=======================================================================
804
805 void SMESHGUI_OffsetDlg::setNewMeshName()
806 {
807   LineEditNewMesh->setText("");
808   if ( LineEditNewMesh->isEnabled() && !myMeshes.isEmpty() ) {
809     QString name;
810     if ( CheckBoxMesh->isChecked() ) {
811       name = myObjects.count() > 1 ? "*" : LineEditElements->text();
812     }
813     else {
814       _PTR(SObject) meshSO = SMESH::FindSObject( myMeshes[0] );
815       name = meshSO->GetName().c_str();
816     }
817     if ( !name.isEmpty() )
818       LineEditNewMesh->setText( SMESH::UniqueMeshName( name, "Offset"));
819   }
820 }
821
822 //=================================================================================
823 // function : keyPressEvent()
824 // purpose  :
825 //=================================================================================
826
827 void SMESHGUI_OffsetDlg::keyPressEvent( QKeyEvent* e )
828 {
829   QDialog::keyPressEvent( e );
830   if ( e->isAccepted() )
831     return;
832
833   if ( e->key() == Qt::Key_F1 ) {
834     e->accept();
835     ClickOnHelp();
836   }
837 }
838
839 //=================================================================================
840 // function : setFilters()
841 // purpose  : SLOT. Called when "Filter" button pressed.
842 //=================================================================================
843
844 void SMESHGUI_OffsetDlg::setFilters()
845 {
846   if ( myMeshes.isEmpty() ) {
847     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
848     return;
849   }
850   if ( !myFilterDlg ) {
851     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
852     connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
853   }
854
855   myFilterDlg->Init( SMESH::FACE );
856   myFilterDlg->SetSelection();
857   myFilterDlg->SetMesh( myMeshes[0] );
858   myFilterDlg->SetSourceWg( LineEditElements );
859
860   myFilterDlg->show();
861 }
862
863 //=======================================================================
864 // name    : onFilterAccepted()
865 // Purpose : SLOT. Called when Filter dlg closed with OK button.
866 //           Activate [Apply] if no Actor is available
867 //=======================================================================
868
869 void SMESHGUI_OffsetDlg::onFilterAccepted()
870 {
871   if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
872   {
873     myElementsId = LineEditElements->text();
874     QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
875     myNbOkElements = aListElementsId.count();
876     buttonOk->setEnabled   ( myNbOkElements );
877     buttonApply->setEnabled( myNbOkElements );
878   }
879 }
880
881 //=================================================================================
882 // function : isValid
883 // purpose  :
884 //=================================================================================
885
886 bool SMESHGUI_OffsetDlg::isValid()
887 {
888   return true;
889 }
890
891 //=================================================================================
892 // function : onDisplaySimulation
893 // purpose  : Show/Hide preview
894 //=================================================================================
895 void SMESHGUI_OffsetDlg::onDisplaySimulation( bool toDisplayPreview )
896 {
897   SUIT_OverrideCursor aWaitCursor;
898
899   if (myPreviewCheckBox->isChecked() && toDisplayPreview)
900   {
901     if ( myNbOkElements && isValid() )
902     {
903       double offsetValue = SpinBox->value();
904
905       SMESH::ListOfGroups_var groups;
906       SMESH::SMESH_Mesh_var mesh;
907
908       try
909       {
910         QList<SMESH::MeshPreviewStruct_var> aMeshPreviewStruct;
911
912         if ( CheckBoxMesh->isChecked())
913           for ( int i = 0; i < myObjects.count(); i++ )
914           {
915             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[i]->GetMeshEditPreviewer();
916             mesh = aMeshEditor->Offset( myObjects[i], offsetValue, false, false, "", groups.out() );
917             aMeshPreviewStruct << aMeshEditor->GetPreviewData();
918           }
919         else
920         {
921           SMESH::smIdType_array_var anElementsId = new SMESH::smIdType_array;
922           QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
923           anElementsId->length(aListElementsId.count());
924           for (int i = 0; i < aListElementsId.count(); i++)
925             anElementsId[i] = aListElementsId[i].toInt();
926
927           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditPreviewer();
928           SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::FACE);
929           mesh = aMeshEditor->Offset( src, offsetValue, false, false, "", groups.out() );
930           aMeshPreviewStruct << aMeshEditor->GetPreviewData();
931         }
932         setSimulationPreview(aMeshPreviewStruct);
933
934       } catch (...) {
935         hidePreview();
936       }
937     } else {
938       hidePreview();
939     }
940   } else {
941     hidePreview();
942   }
943 }