Salome HOME
Fix of issue 0020614: EDF 1133 SMESH : Put new added elements and nodes to group
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddMeshElementDlg.cxx
1 //  Copyright (C) 2007-2008  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.
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 // SMESH SMESHGUI : GUI for SMESH component
23 // File   : SMESHGUI_AddMeshElementDlg.cxx
24 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
25
26 //  SMESH includes
27 #include "SMESHGUI_AddMeshElementDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32 #include "SMESHGUI_MeshUtils.h"
33 #include "SMESHGUI_GroupUtils.h"
34 #include "SMESHGUI_IdValidator.h"
35
36 #include <SMESH_Actor.h>
37 #include <SMESH_ActorUtils.h>
38 #include <SMESH_FaceOrientationFilter.h>
39 #include <SMDS_Mesh.hxx>
40
41 // SALOME GUI inclues
42 #include <SUIT_Desktop.h>
43 #include <SUIT_Session.h>
44 #include <SUIT_ResourceMgr.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ViewManager.h>
47 #include <LightApp_SelectionMgr.h>
48 #include <SALOME_ListIO.hxx>
49 #include <SalomeApp_Application.h>
50 #include <SVTK_ViewModel.h>
51 #include <SVTK_ViewWindow.h>
52
53 // IDL incldues
54 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
55
56 // OCCT includes
57 #include <TColStd_MapOfInteger.hxx>
58
59 // VTK includes
60 #include <vtkCell.h>
61 #include <vtkIdList.h>
62 #include <vtkUnstructuredGrid.h>
63 #include <vtkDataSetMapper.h>
64 #include <vtkPolyDataMapper.h>
65 #include <vtkProperty.h>
66
67 // Qt includes
68 #include <QComboBox>
69 #include <QGroupBox>
70 #include <QLabel>
71 #include <QLineEdit>
72 #include <QPushButton>
73 #include <QRadioButton>
74 #include <QHBoxLayout>
75 #include <QVBoxLayout>
76 #include <QGridLayout>
77 #include <QVariant>
78 #include <QCheckBox>
79 #include <QKeyEvent>
80 #include <QButtonGroup>
81
82 #define SPACING 6
83 #define MARGIN  11
84
85 namespace SMESH
86 {
87   class TElementSimulation
88   {
89     SalomeApp_Application* myApplication;
90     SUIT_ViewWindow* myViewWindow;
91     SVTK_ViewWindow* myVTKViewWindow;
92
93     SALOME_Actor* myPreviewActor;
94     vtkDataSetMapper* myMapper;
95     vtkUnstructuredGrid* myGrid;
96
97     SALOME_Actor* myFaceOrientation;
98     vtkPolyDataMapper* myFaceOrientationDataMapper;
99     SMESH_FaceOrientationFilter* myFaceOrientationFilter;
100
101   public:
102     TElementSimulation (SalomeApp_Application* theApplication)
103     {
104       myApplication = theApplication;
105       SUIT_ViewManager* mgr = theApplication->activeViewManager();
106       if (!mgr) return;
107       myViewWindow = mgr->getActiveView();
108       myVTKViewWindow = GetVtkViewWindow(myViewWindow);
109
110       myGrid = vtkUnstructuredGrid::New();
111
112       // Create and display actor
113       myMapper = vtkDataSetMapper::New();
114       myMapper->SetInput(myGrid);
115
116       myPreviewActor = SALOME_Actor::New();
117       myPreviewActor->PickableOff();
118       myPreviewActor->VisibilityOff();
119       myPreviewActor->SetMapper(myMapper);
120
121       vtkFloatingPointType anRGB[3];
122       vtkProperty* aProp = vtkProperty::New();
123       GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
124       aProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
125       myPreviewActor->SetProperty( aProp );
126       aProp->Delete();
127
128       vtkProperty* aBackProp = vtkProperty::New();
129       GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
130       aBackProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
131       myPreviewActor->SetBackfaceProperty( aBackProp );
132       aBackProp->Delete();
133
134       myVTKViewWindow->AddActor(myPreviewActor);
135
136       // Orientation of faces
137       myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
138       myFaceOrientationFilter->SetInput(myGrid);
139
140       myFaceOrientationDataMapper = vtkPolyDataMapper::New();
141       myFaceOrientationDataMapper->SetInput(myFaceOrientationFilter->GetOutput());
142
143       myFaceOrientation = SALOME_Actor::New();
144       myFaceOrientation->PickableOff();
145       myFaceOrientation->VisibilityOff();
146       myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
147
148       vtkProperty* anOrientationProp = vtkProperty::New();
149       GetColor( "SMESH", "orientation_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) );
150       anOrientationProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
151       myFaceOrientation->SetProperty( anOrientationProp );
152       anOrientationProp->Delete();
153
154       myVTKViewWindow->AddActor(myFaceOrientation);
155     }
156
157     typedef std::vector<vtkIdType> TVTKIds;
158     void SetPosition (SMESH_Actor* theActor,
159                       vtkIdType theType,
160                       const TVTKIds& theIds)
161     {
162       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
163       myGrid->SetPoints(aGrid->GetPoints());
164
165       const int* aConn = NULL;
166       switch (theType) {
167       case VTK_TETRA:
168         {
169           static int anIds[] = {0,2,1,3};
170           aConn = anIds;
171           break;
172         }
173       case VTK_PYRAMID:
174         {
175           static int anIds[] = {0,3,2,1,4};
176           aConn = anIds;
177           break;
178         }
179       case VTK_HEXAHEDRON:
180         {
181           static int anIds[] = {0,3,2,1,4,7,6,5};
182           aConn = anIds;
183           break;
184         }
185       }
186
187       myGrid->Reset();
188       vtkIdList *anIds = vtkIdList::New();
189
190       if(aConn)
191         for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
192           anIds->InsertId(i,theIds[aConn[i]]);
193       else
194         for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
195           anIds->InsertId(i,theIds[i]);
196
197       myGrid->InsertNextCell(theType,anIds);
198       anIds->Delete();
199
200       myGrid->Modified();
201
202       SetVisibility(true, theActor->GetFacesOriented());
203     }
204
205
206     void SetVisibility (bool theVisibility, bool theShowOrientation = false)
207     {
208       myPreviewActor->SetVisibility(theVisibility);
209       myFaceOrientation->SetVisibility(theShowOrientation);
210       RepaintCurrentView();
211     }
212
213
214     ~TElementSimulation()
215     {
216       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
217         myVTKViewWindow->RemoveActor(myPreviewActor);
218         myVTKViewWindow->RemoveActor(myFaceOrientation);
219       }
220       myPreviewActor->Delete();
221       myFaceOrientation->Delete();
222
223       myMapper->RemoveAllInputs();
224       myMapper->Delete();
225
226       myFaceOrientationFilter->Delete();
227
228       myFaceOrientationDataMapper->RemoveAllInputs();
229       myFaceOrientationDataMapper->Delete();
230
231       myGrid->Delete();
232     }
233   };
234 }
235
236 //=================================================================================
237 // function : SMESHGUI_AddMeshElementDlg()
238 // purpose  : constructor
239 //=================================================================================
240 SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
241                                                         SMDSAbs_ElementType ElementType,
242                                                         int nbNodes )
243   : QDialog( SMESH::GetDesktop( theModule ) ),
244     mySMESHGUI( theModule ),
245     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
246 {
247   setModal( false );
248   setAttribute( Qt::WA_DeleteOnClose, true );
249
250   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
251     (SUIT_Session::session()->activeApplication());
252   myIsPoly = false;
253   mySimulation = new SMESH::TElementSimulation (anApp);
254   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
255
256   // verify nb nodes and type
257   myNbNodes = nbNodes;
258   myElementType = ElementType;
259   switch (ElementType) {
260   case SMDSAbs_0DElement:
261     if (myNbNodes != 1)
262       myNbNodes = 1;
263     break;
264   case SMDSAbs_Face:
265     //     if (myNbNodes != 3 && myNbNodes != 4)
266     //       myNbNodes = 3;
267     //     break;
268   case SMDSAbs_Volume:
269     //     if (myNbNodes != 4 && myNbNodes != 8) //(nbNodes < 4 || nbNodes > 8 || nbNodes == 7)
270     //       myNbNodes = 4;
271     break;
272   default:
273     myElementType = SMDSAbs_Edge;
274     myNbNodes = 2;
275   }
276
277   QString elemName;
278   if (myNbNodes == 1) {
279     elemName = "ELEM0D";
280     myHelpFileName = "adding_nodes_and_elements_page.html#adding_0delems_anchor";
281   }
282   else if (myNbNodes == 2) {
283     elemName = "EDGE";
284     myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor";
285   }
286   else if (myNbNodes == 3) {
287     elemName = "TRIANGLE";
288     myHelpFileName = "adding_nodes_and_elements_page.html#adding_triangles_anchor";
289   }
290   else if (myNbNodes == 4) {
291     if (myElementType == SMDSAbs_Face) {
292       elemName = "QUADRANGLE";
293       myHelpFileName = "adding_nodes_and_elements_page.html#adding_quadrangles_anchor";
294     }
295     else {
296       elemName = "TETRAS";
297       myHelpFileName = "adding_nodes_and_elements_page.html#adding_tetrahedrons_anchor";
298     }
299   }
300   else if (myNbNodes == 8) {
301     elemName = "HEXAS";
302     myHelpFileName = "adding_nodes_and_elements_page.html#adding_hexahedrons_anchor";
303   }
304   else if (myElementType == SMDSAbs_Face) {
305     elemName = "POLYGON";
306     myIsPoly = true;
307     myHelpFileName = "adding_nodes_and_elements_page.html#adding_polygons_anchor";
308   }
309   else if (myElementType == SMDSAbs_Volume) {
310     myHelpFileName = "adding_nodes_and_elements_page.html#adding_polyhedrons_anchor";
311   }
312
313   QString iconName      = tr(QString("ICON_DLG_%1").arg(elemName).toLatin1().data());
314   QString buttonGrTitle = tr(QString("SMESH_%1").arg(elemName).toLatin1().data());
315   QString caption       = tr(QString("SMESH_ADD_%1_TITLE").arg(elemName).toLatin1().data());
316   QString grBoxTitle    = tr(QString("SMESH_ADD_%1").arg(elemName).toLatin1().data());
317
318   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
319   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
320
321   setWindowTitle(caption);
322   setSizeGripEnabled(true);
323
324   QVBoxLayout* aTopLayout = new QVBoxLayout(this);
325   aTopLayout->setSpacing(SPACING);
326   aTopLayout->setMargin(MARGIN);
327
328   /***************************************************************/
329   GroupConstructors = new QGroupBox(buttonGrTitle, this);
330   QButtonGroup* ButtonGroup = new QButtonGroup(this);
331   QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
332   GroupConstructorsLayout->setSpacing(SPACING);
333   GroupConstructorsLayout->setMargin(MARGIN);
334
335   Constructor1 = new QRadioButton(GroupConstructors);
336   Constructor1->setIcon(image0);
337   Constructor1->setChecked(true);
338
339   GroupConstructorsLayout->addWidget(Constructor1);
340   ButtonGroup->addButton( Constructor1, 0 );
341
342   /***************************************************************/
343   GroupC1 = new QGroupBox(grBoxTitle, this);
344   QGridLayout* GroupC1Layout = new QGridLayout(GroupC1);
345   GroupC1Layout->setSpacing(SPACING);
346   GroupC1Layout->setMargin(MARGIN);
347
348   TextLabelC1A1 = new QLabel(tr("SMESH_ID_NODES"), GroupC1);
349   SelectButtonC1A1 = new QPushButton(GroupC1);
350   SelectButtonC1A1->setIcon(image1);
351   LineEditC1A1 = new QLineEdit(GroupC1);
352   //  LineEditC1A1->setReadOnly(true);
353   if (!myIsPoly)
354     LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this, myNbNodes));
355
356   Reverse = myElementType == SMDSAbs_Face ? new QCheckBox(tr("SMESH_REVERSE"), GroupC1) : 0;
357
358   GroupC1Layout->addWidget(TextLabelC1A1,    0, 0);
359   GroupC1Layout->addWidget(SelectButtonC1A1, 0, 1);
360   GroupC1Layout->addWidget(LineEditC1A1,     0, 2);
361   if ( Reverse ) GroupC1Layout->addWidget(Reverse, 1, 0, 1, 3);
362
363   /***************************************************************/
364   GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
365   GroupGroups->setCheckable( true );
366   QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
367   GroupGroupsLayout->setSpacing(SPACING);
368   GroupGroupsLayout->setMargin(MARGIN);
369
370   TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
371   ComboBox_GroupName = new QComboBox( GroupGroups );
372   ComboBox_GroupName->setEditable( true );
373
374   GroupGroupsLayout->addWidget( TextLabel_GroupName );
375   GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
376
377   /***************************************************************/
378   GroupButtons = new QGroupBox(this);
379   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
380   GroupButtonsLayout->setSpacing(SPACING);
381   GroupButtonsLayout->setMargin(MARGIN);
382
383   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
384   buttonOk->setAutoDefault(true);
385   buttonOk->setDefault(true);
386   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
387   buttonApply->setAutoDefault(true);
388   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
389   buttonCancel->setAutoDefault(true);
390   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
391   buttonHelp->setAutoDefault(true);
392
393   GroupButtonsLayout->addWidget(buttonOk);
394   GroupButtonsLayout->addSpacing(10);
395   GroupButtonsLayout->addWidget(buttonApply);
396   GroupButtonsLayout->addSpacing(10);
397   GroupButtonsLayout->addStretch();
398   GroupButtonsLayout->addWidget(buttonCancel);
399   GroupButtonsLayout->addWidget(buttonHelp);
400
401   /***************************************************************/
402   aTopLayout->addWidget(GroupConstructors);
403   aTopLayout->addWidget(GroupC1);
404   aTopLayout->addWidget(GroupGroups);
405   aTopLayout->addWidget(GroupButtons);
406
407   Init(); /* Initialisations */
408 }
409
410 //=================================================================================
411 // function : ~SMESHGUI_AddMeshElementDlg()
412 // purpose  : Destroys the object and frees any allocated resources
413 //=================================================================================
414 SMESHGUI_AddMeshElementDlg::~SMESHGUI_AddMeshElementDlg()
415 {
416   delete mySimulation;
417 }
418
419 //=================================================================================
420 // function : Init()
421 // purpose  :
422 //=================================================================================
423 void SMESHGUI_AddMeshElementDlg::Init()
424 {
425   GroupC1->show();
426   Constructor1->setChecked(true);
427   myEditCurrentArgument = LineEditC1A1;
428   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
429
430   /* reset "Add to group" control */
431   GroupGroups->setChecked( false );
432
433   myNbOkNodes = 0;
434   myActor = 0;
435
436   /* signals and slots connections */
437   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
438   connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel()));
439   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
440   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
441
442   connect(SelectButtonC1A1, SIGNAL(clicked()), SLOT(SetEditCurrentArgument()));
443   connect(LineEditC1A1, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
444   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
445   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
446   /* to close dialog if study frame change */
447   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
448
449   if (Reverse)
450     connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int)));
451
452   // set selection mode
453   SMESH::SetPointRepresentation(true);
454
455   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
456     aViewWindow->SetSelectionMode( NodeSelection );
457
458   myBusy = false;
459
460   SelectionIntoArgument();
461 }
462
463 //=================================================================================
464 // function : ClickOnApply()
465 // purpose  :
466 //=================================================================================
467 void SMESHGUI_AddMeshElementDlg::ClickOnApply()
468 {
469   if( !isValid() )
470     return;
471
472   if (myNbOkNodes && !mySMESHGUI->isActiveStudyLocked()) {
473     myBusy = true;
474     SMESH::long_array_var anArrayOfIndices = new SMESH::long_array;
475     anArrayOfIndices->length(myNbNodes);
476     bool reverse = (Reverse && Reverse->isChecked());
477     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
478     for (int i = 0; i < aListId.count(); i++)
479       if (reverse)
480         anArrayOfIndices[i] = aListId[ myNbNodes - i - 1 ].toInt();
481       else
482         anArrayOfIndices[i] = aListId[ i ].toInt();
483
484     long anElemId = -1;
485     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
486     switch (myElementType) {
487     case SMDSAbs_0DElement:
488       anElemId = aMeshEditor->Add0DElement(anArrayOfIndices[0]); break;
489     case SMDSAbs_Edge:
490       anElemId = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
491     case SMDSAbs_Face: {
492       if(myIsPoly)
493         anElemId = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
494       else
495         anElemId = aMeshEditor->AddFace(anArrayOfIndices.inout());
496       break;
497     }
498     case SMDSAbs_Volume:
499       anElemId = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
500     default:;
501     }
502
503     if( anElemId != -1 && GroupGroups->isChecked() ) {
504       SMESH::SMESH_Group_var aGroup;
505       QString aGroupName = ComboBox_GroupName->currentText();
506       SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
507       for( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
508         SMESH::SMESH_GroupBase_var aGroupBase = aListOfGroups[i];
509         if( !aGroupBase->_is_nil() ) {
510           SMESH::SMESH_Group_var aRefGroup = SMESH::SMESH_Group::_narrow( aGroupBase );
511           if( !aRefGroup->_is_nil() ) {
512             QString aRefGroupName( aRefGroup->GetName() );
513             if( aRefGroupName == aGroupName ) {
514               aGroup = aRefGroup; // // add node to existing group
515               break;
516             }
517           }
518         }
519       }
520       if( aGroup->_is_nil() ) // create new group
521         aGroup = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName );
522
523       if( !aGroup->_is_nil() ) {
524         SMESH::long_array_var anIdList = new SMESH::long_array;
525         anIdList->length( 1 );
526         anIdList[0] = anElemId;
527         aGroup->Add( anIdList.inout() );
528       }
529     }
530
531     SALOME_ListIO aList; aList.Append( myActor->getIO() );
532     mySelector->ClearIndex();
533     mySelectionMgr->setSelectedObjects( aList, false );
534
535     SMESH::UpdateView();
536     mySimulation->SetVisibility(false);
537
538     buttonOk->setEnabled(false);
539     buttonApply->setEnabled(false);
540
541     myEditCurrentArgument->setText("");
542
543     myBusy = false;
544   }
545 }
546
547 //=================================================================================
548 // function : ClickOnOk()
549 // purpose  :
550 //=================================================================================
551 void SMESHGUI_AddMeshElementDlg::ClickOnOk()
552 {
553   ClickOnApply();
554   ClickOnCancel();
555 }
556
557 //=================================================================================
558 // function : ClickOnCancel()
559 // purpose  :
560 //=================================================================================
561 void SMESHGUI_AddMeshElementDlg::ClickOnCancel()
562 {
563   //mySelectionMgr->clearSelected();
564   mySimulation->SetVisibility(false);
565   SMESH::SetPointRepresentation(false);
566   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
567     aViewWindow->SetSelectionMode( ActorSelection );
568   disconnect(mySelectionMgr, 0, this, 0);
569   mySMESHGUI->ResetState();
570   reject();
571 }
572
573 //=================================================================================
574 // function : ClickOnHelp()
575 // purpose  :
576 //=================================================================================
577 void SMESHGUI_AddMeshElementDlg::ClickOnHelp()
578 {
579   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
580   if (app)
581     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""),
582                              myHelpFileName);
583   else {
584     QString platform;
585 #ifdef WIN32
586     platform = "winapplication";
587 #else
588     platform = "application";
589 #endif
590     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
591                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
592                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
593                                                                  platform)).
594                              arg(myHelpFileName));
595   }
596 }
597
598 //=================================================================================
599 // function : onTextChange()
600 // purpose  :
601 //=================================================================================
602 void SMESHGUI_AddMeshElementDlg::onTextChange (const QString& theNewText)
603 {
604   if (myBusy) return;
605   myBusy = true;
606
607   myNbOkNodes = 0;
608
609   buttonOk->setEnabled(false);
610   buttonApply->setEnabled(false);
611
612   mySimulation->SetVisibility(false);
613
614   // hilight entered nodes
615   SMDS_Mesh* aMesh = 0;
616   if (myActor)
617     aMesh = myActor->GetObject()->GetMesh();
618
619   if (aMesh) {
620     TColStd_MapOfInteger newIndices;
621
622     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
623     bool allOk = true;
624     for (int i = 0; i < aListId.count(); i++) {
625       if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
626         {
627           newIndices.Add( n->GetID() );
628           myNbOkNodes++;
629         }
630       else
631         allOk = false;  
632     }
633
634     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
635     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
636       aViewWindow->highlight( myActor->getIO(), true, true );
637
638     myNbOkNodes = ( allOk && myNbNodes == aListId.count() );
639
640     if (myIsPoly)
641       {
642         if ( !allOk || myElementType != SMDSAbs_Face || aListId.count() < 3 )
643           myNbOkNodes = 0;
644         else
645           myNbOkNodes = aListId.count();
646       }
647   }
648
649   if(myNbOkNodes) {
650     buttonOk->setEnabled(true);
651     buttonApply->setEnabled(true);
652     displaySimulation();
653   }
654
655   myBusy = false;
656 }
657
658 //=================================================================================
659 // function : SelectionIntoArgument()
660 // purpose  : Called when selection has changed
661 //=================================================================================
662 void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument()
663 {
664   if (myBusy) return;
665
666   // clear
667   myNbOkNodes = 0;
668   myActor = 0;
669
670   myBusy = true;
671   myEditCurrentArgument->setText("");
672   myBusy = false;
673
674   if (!GroupButtons->isEnabled()) // inactive
675     return;
676
677   buttonOk->setEnabled(false);
678   buttonApply->setEnabled(false);
679
680   mySimulation->SetVisibility(false);
681   //  SMESH::SetPointRepresentation(true);
682
683   QString aCurrentEntry = myEntry;
684
685   // get selected mesh
686   SALOME_ListIO aList;
687   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
688
689   if (aList.Extent() != 1)
690     return;
691
692   Handle(SALOME_InteractiveObject) anIO = aList.First();
693   myEntry = anIO->getEntry();
694   myMesh = SMESH::GetMeshByIO(anIO);
695   if (myMesh->_is_nil())
696     return;
697
698   // process groups
699   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
700     ComboBox_GroupName->clear();
701     ComboBox_GroupName->addItem( QString() );
702     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
703     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
704       SMESH::SMESH_GroupBase_var aGroupBase = aListOfGroups[i];
705       if ( !aGroupBase->_is_nil() && aGroupBase->GetType() == (SMESH::ElementType)myElementType ) {
706         SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupBase );
707         if ( !aGroup->_is_nil() ) {
708           QString aGroupName( aGroup->GetName() );
709           if ( !aGroupName.isEmpty() )
710             ComboBox_GroupName->addItem( aGroupName );
711         }
712       }
713     }
714   }
715
716   myActor = SMESH::FindActorByEntry(anIO->getEntry());
717   if (!myActor)
718     return;
719
720   // get selected nodes
721   QString aString = "";
722   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
723   myBusy = true;
724   myEditCurrentArgument->setText(aString);
725   myBusy = false;
726   if (myIsPoly && myElementType == SMDSAbs_Face && nbNodes >= 3 ) {
727     myNbNodes = nbNodes;
728   } else if (myNbNodes != nbNodes) {
729     return;
730   }
731
732   // OK
733   myNbOkNodes = nbNodes;
734
735   buttonOk->setEnabled(true);
736   buttonApply->setEnabled(true);
737
738   displaySimulation();
739 }
740
741 //=================================================================================
742 // function : displaySimulation()
743 // purpose  :
744 //=================================================================================
745 void SMESHGUI_AddMeshElementDlg::displaySimulation()
746 {
747   if (myNbOkNodes && GroupButtons->isEnabled()) {
748     SMESH::TElementSimulation::TVTKIds anIds;
749     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
750     for (int i = 0; i < aListId.count(); i++)
751       anIds.push_back(myActor->GetObject()->GetNodeVTKId(aListId[ i ].toInt()));
752
753     if (Reverse && Reverse->isChecked())
754       reverse(anIds.begin(),anIds.end());
755
756     vtkIdType aType = 0;
757     if (myIsPoly)
758       switch ( myElementType ) {
759       case SMDSAbs_Face  : aType = VTK_POLYGON; break;
760       default: return;
761       }
762     else {
763       switch (myNbNodes) {
764       case 2: aType = VTK_LINE; break;
765       case 3: aType = VTK_TRIANGLE; break;
766       case 4: aType = myElementType == SMDSAbs_Face ? VTK_QUAD : VTK_TETRA; break;
767       case 8: aType = VTK_HEXAHEDRON; break;
768       default: return;
769       }
770     }
771
772     mySimulation->SetPosition(myActor,aType,anIds);
773     SMESH::UpdateView();
774   }
775 }
776
777 //=================================================================================
778 // function : SetEditCurrentArgument()
779 // purpose  :
780 //=================================================================================
781 void SMESHGUI_AddMeshElementDlg::SetEditCurrentArgument()
782 {
783   QPushButton* send = (QPushButton*)sender();
784   if (send == SelectButtonC1A1) {
785     LineEditC1A1->setFocus();
786     myEditCurrentArgument = LineEditC1A1;
787   }
788   SelectionIntoArgument();
789 }
790
791 //=================================================================================
792 // function : DeactivateActiveDialog()
793 // purpose  :
794 //=================================================================================
795 void SMESHGUI_AddMeshElementDlg::DeactivateActiveDialog()
796 {
797   if (GroupConstructors->isEnabled()) {
798     GroupConstructors->setEnabled(false);
799     GroupC1->setEnabled(false);
800     GroupButtons->setEnabled(false);
801     mySimulation->SetVisibility(false);
802     mySMESHGUI->ResetState();
803     mySMESHGUI->SetActiveDialogBox(0);
804   }
805 }
806
807 //=================================================================================
808 // function : ActivateThisDialog()
809 // purpose  :
810 //=================================================================================
811 void SMESHGUI_AddMeshElementDlg::ActivateThisDialog()
812 {
813   /* Emit a signal to deactivate the active dialog */
814   mySMESHGUI->EmitSignalDeactivateDialog();
815
816   GroupConstructors->setEnabled(true);
817   GroupC1->setEnabled(true);
818   GroupButtons->setEnabled(true);
819
820   SMESH::SetPointRepresentation(true);
821
822   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
823     aViewWindow->SetSelectionMode( NodeSelection );
824   SelectionIntoArgument();
825 }
826
827 //=================================================================================
828 // function : enterEvent()
829 // purpose  :
830 //=================================================================================
831 void SMESHGUI_AddMeshElementDlg::enterEvent (QEvent*)
832 {
833   if (GroupConstructors->isEnabled())
834     return;
835   ActivateThisDialog();
836 }
837
838 //=================================================================================
839 // function : closeEvent()
840 // purpose  :
841 //=================================================================================
842 void SMESHGUI_AddMeshElementDlg::closeEvent (QCloseEvent*)
843 {
844   /* same than click on cancel button */
845   ClickOnCancel();
846 }
847
848 //=================================================================================
849 // function : hideEvent()
850 // purpose  : caused by ESC key
851 //=================================================================================
852 void SMESHGUI_AddMeshElementDlg::hideEvent (QHideEvent*)
853 {
854   if (!isMinimized())
855     ClickOnCancel();
856 }
857
858 //=================================================================================
859 // function : CheckBox()
860 // purpose  :
861 //=================================================================================
862 void SMESHGUI_AddMeshElementDlg::CheckBox (int state)
863 {
864   if (!myNbOkNodes)
865     return;
866
867   if (state >= 0) {
868     mySimulation->SetVisibility(false);
869     displaySimulation();
870   }
871 }
872
873 //=================================================================================
874 // function : keyPressEvent()
875 // purpose  :
876 //=================================================================================
877 void SMESHGUI_AddMeshElementDlg::keyPressEvent( QKeyEvent* e )
878 {
879   QDialog::keyPressEvent( e );
880   if ( e->isAccepted() )
881     return;
882
883   if ( e->key() == Qt::Key_F1 ) {
884     e->accept();
885     ClickOnHelp();
886   }
887 }
888
889 //=================================================================================
890 // function : isValid
891 // purpose  :
892 //=================================================================================
893 bool SMESHGUI_AddMeshElementDlg::isValid()
894 {
895   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
896     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
897     return false;
898   }
899   return true;
900 }