Salome HOME
Merge branch 'V9_9_BR'
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupDlg.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SMESH SMESHGUI : GUI for SMESH component
24 //  File   : SMESHGUI_GroupDlg.cxx
25 //  Author : Natalia KOPNOVA, Open CASCADE S.A.S.
26 //  SMESH includes
27 //
28 #include "SMESHGUI_GroupDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_GroupUtils.h"
34 #include "SMESHGUI_FilterUtils.h"
35 #include "SMESHGUI_GEOMGenUtils.h"
36 #include "SMESHGUI_FilterDlg.h"
37 #include "SMESHGUI_ShapeByMeshDlg.h"
38
39 #include <SMESH_TypeFilter.hxx>
40 #include <SMESH_Actor.h>
41 //#include <SMESH_ActorUtils.h>
42 #include <SMESH_LogicalFilter.hxx>
43
44 // SALOME GEOM includes
45 #include <GEOMBase.h>
46 #include <GEOM_SelectionFilter.h>
47 #include <GEOM_wrap.hxx>
48
49 // SALOME GUI includes
50 #include <QtxColorButton.h>
51
52 #include <SUIT_Desktop.h>
53 #include <SUIT_ResourceMgr.h>
54 #include <SUIT_Session.h>
55 #include <SUIT_MessageBox.h>
56 #include <SUIT_OverrideCursor.h>
57
58 #include <SalomeApp_Tools.h>
59 #include <SalomeApp_Application.h>
60 #include <SalomeApp_Study.h>
61 #include <LightApp_SelectionMgr.h>
62
63 #include <SALOME_ListIO.hxx>
64
65 #include <SVTK_ViewWindow.h>
66
67 #include <VTKViewer_Algorithm.h>
68
69 // SALOME KERNEL includes
70 #include <SALOMEDSClient_Study.hxx>
71
72 // VTK Includes
73 #include <vtkRenderer.h>
74 #include <vtkActorCollection.h>
75
76 // OCCT includes
77 #include <TColStd_MapOfAsciiString.hxx>
78 #include <TColStd_MapOfInteger.hxx>
79
80 // Qt includes
81 #include <QButtonGroup>
82 #include <QGroupBox>
83 #include <QLabel>
84 #include <QLineEdit>
85 #include <QPushButton>
86 #include <QToolButton>
87 #include <QRadioButton>
88 #include <QCheckBox>
89 #include <QGridLayout>
90 #include <QHBoxLayout>
91 #include <QVBoxLayout>
92 #include <QListWidget>
93 #include <QStackedWidget>
94 #include <QKeyEvent>
95 #include <QMenu>
96
97 // STL includes
98 #include <vector>
99 #include <algorithm>
100 #include <set>
101
102 #define SPACING 6
103 #define MARGIN  11
104
105 enum grpSelectionMode {
106   grpNoSelection       = -1,
107   grpNodeSelection     = 0,
108   grp0DSelection       = 1,
109   grpBallSelection     = 2,
110   grpEdgeSelection     = 3,
111   grpFaceSelection     = 4,
112   grpVolumeSelection   = 5,
113   grpSubMeshSelection  = 6,
114   grpGroupSelection    = 7,
115   grpMeshSelection     = 8,
116   grpGeomSelection     = 9,
117   grpAllSelection      = 10,
118 };
119
120 //=================================================================================
121 // function : SMESHGUI_GroupDlg()
122 // purpose  :
123 //=================================================================================
124 SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
125                                       SMESH::SMESH_Mesh_ptr theMesh )
126   : QDialog( SMESH::GetDesktop( theModule ) ),
127     mySMESHGUI( theModule ),
128     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myStoredShownEntity(0),
129     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
130     myIsBusy( false ),
131     myNameChanged( false ),
132     myNbChangesOfContents(0),
133     myIsApplyAndClose( false )
134 {
135   initDialog( true );
136   if ( !theMesh->_is_nil() )
137     init( theMesh );
138   else
139   {
140     mySelectSubMesh->setEnabled( false );
141     mySelectGroup->setEnabled( false );
142     myGeomGroupBtn->setEnabled( false );
143     myGeomGroupLine->setEnabled( false );
144   }
145 }
146
147 //=================================================================================
148 // function : SMESHGUI_GroupDlg()
149 // purpose  :
150 //=================================================================================
151 SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
152                                       SMESH::SMESH_GroupBase_ptr theGroup,
153                                       const bool theIsConvert )
154   : QDialog( SMESH::GetDesktop( theModule ) ),
155     mySMESHGUI( theModule ),
156     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myStoredShownEntity(0),
157     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
158     myIsBusy( false ),
159     myNameChanged( false ),
160     myNbChangesOfContents(0) // just not to use uninitialized variable
161 {
162   initDialog( false );
163   if ( !theGroup->_is_nil() )
164     init( theGroup, theIsConvert );
165   else
166   {
167     mySelectSubMesh->setEnabled( false );
168     mySelectGroup->setEnabled( false );
169
170     myCurrentLineEdit = myMeshGroupLine;
171     setSelectionMode( grpGroupSelection );
172   }
173 }
174
175 //=================================================================================
176 // function : SMESHGUI_GroupDlg()
177 // purpose  :
178 //=================================================================================
179 void SMESHGUI_GroupDlg::initDialog( bool create)
180 {
181   setModal( false );
182   setAttribute( Qt::WA_DeleteOnClose, true );
183
184   myFilterDlg = 0;
185   myCreate = create;
186   myCurrentLineEdit = 0;
187
188   myShapeByMeshOp = 0;
189   myGeomPopup = 0;
190   myGeomObjects = new GEOM::ListOfGO();
191   myGeomObjects->length( 0 );
192
193   QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) );
194
195   setWindowTitle( create ? tr( "SMESH_CREATE_GROUP_TITLE" ) : tr( "SMESH_EDIT_GROUP_TITLE" ) );
196   myHelpFileName = create ? "creating_groups.html" : "editing_groups.html";
197
198   setSizeGripEnabled( true);
199
200   QGridLayout* aMainLayout = new QGridLayout( this );
201   aMainLayout->setMargin( MARGIN );
202   aMainLayout->setSpacing( SPACING );
203
204   /***************************************************************/
205   QLabel* meshGroupLab = new QLabel( create ? tr( "SMESH_MESH" ) : tr( "SMESH_GROUP" ), this );
206   myMeshGroupBtn = new QPushButton( this );
207   myMeshGroupBtn->setIcon( image0 );
208   myMeshGroupLine = new QLineEdit( this );
209   myMeshGroupLine->setReadOnly( true );
210
211   /***************************************************************/
212   QGroupBox* aTypeBox = new QGroupBox( tr( "SMESH_ELEMENTS_TYPE" ), this );
213   myTypeGroup = new QButtonGroup( this );
214   QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( aTypeBox );
215   aTypeBoxLayout->setMargin( MARGIN );
216   aTypeBoxLayout->setSpacing( SPACING );
217
218   QStringList types;
219   types.append( tr( "MESH_NODE" ) );
220   types.append( tr( "SMESH_ELEM0D" ) );
221   types.append( tr( "SMESH_BALL_ELEM" ) );
222   types.append( tr( "SMESH_EDGE" ) );
223   types.append( tr( "SMESH_FACE" ) );
224   types.append( tr( "SMESH_VOLUME" ) );
225   QRadioButton* rb;
226   for ( int i = 0; i < types.count(); i++ )
227   {
228     rb = new QRadioButton( types[i], aTypeBox );
229     myTypeGroup->addButton( rb, i );
230     aTypeBoxLayout->addWidget( rb );
231   }
232   aTypeBox->setEnabled( create );
233   myTypeId = -1;
234
235   /***************************************************************/
236   QLabel* aName = new QLabel( tr( "SMESH_NAME" ), this );
237   aName->setMinimumWidth( 50 );
238   myName = new QLineEdit( this );
239
240   /***************************************************************/
241   QGroupBox* aGrpTypeBox = new QGroupBox( tr( "SMESH_GROUP_TYPE" ), this );
242   myGrpTypeGroup = new QButtonGroup( this );
243   QHBoxLayout* aGrpTypeBoxLayout = new QHBoxLayout( aGrpTypeBox );
244   aGrpTypeBoxLayout->setMargin( MARGIN );
245   aGrpTypeBoxLayout->setSpacing( SPACING );
246
247   QRadioButton* rb1 = new QRadioButton( tr( "SMESH_GROUP_STANDALONE" ), aGrpTypeBox );
248   QRadioButton* rb2 = new QRadioButton( tr( "SMESH_GROUP_GEOMETRY" ),   aGrpTypeBox );
249   QRadioButton* rb3 = new QRadioButton( tr( "SMESH_GROUP_FILTER" ),     aGrpTypeBox );
250   myGrpTypeGroup->addButton( rb1, 0 );
251   myGrpTypeGroup->addButton( rb2, 1 );
252   myGrpTypeGroup->addButton( rb3, 2 );
253   aGrpTypeBoxLayout->addWidget( rb1 );
254   aGrpTypeBoxLayout->addWidget( rb2 );
255   aGrpTypeBoxLayout->addWidget( rb3 );
256   aGrpTypeBox->setEnabled( create );
257   myGrpTypeId = -1;
258
259   /***************************************************************/
260   myWGStack = new QStackedWidget( this );
261   QWidget* wg1 = new QWidget( myWGStack );
262   QWidget* wg2 = new QWidget( myWGStack );
263   QWidget* wg3 = new QWidget( myWGStack );
264
265   /***************************************************************/
266   QGroupBox* aContentBox         = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 );
267   QGridLayout* aContentBoxLayout = new QGridLayout( aContentBox );
268   aContentBoxLayout->setMargin( MARGIN );
269   aContentBoxLayout->setSpacing( SPACING );
270
271   mySelectAll       = new QCheckBox( tr( "SELECT_ALL" ), aContentBox );
272   myAllowElemsModif = new QCheckBox( tr( "ALLOW_ELEM_LIST_MODIF" ), aContentBox );
273
274   myElementsLab = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox );
275   myElements    = new QListWidget( aContentBox );
276   myElements->setSelectionMode( QListWidget::ExtendedSelection );
277
278   myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox );
279   myAddBtn    = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox );
280   myRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox );
281   mySortBtn   = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox );
282
283   aContentBoxLayout->addWidget( mySelectAll,       0, 0 );
284   aContentBoxLayout->addWidget( myAllowElemsModif, 1, 0 );
285   aContentBoxLayout->addWidget( myFilterBtn,       1, 1 );
286   aContentBoxLayout->addWidget( myElementsLab,     2, 0 );
287   aContentBoxLayout->addWidget( myElements,        3, 0, 6, 1 );
288   aContentBoxLayout->addWidget( myAddBtn,          3, 1 );
289   aContentBoxLayout->addWidget( myRemoveBtn,       4, 1 );
290   aContentBoxLayout->addWidget( mySortBtn,         8, 1 );
291
292   aContentBoxLayout->setColumnStretch( 0, 1 );
293   aContentBoxLayout->setRowStretch( 3, 1 );
294   aContentBoxLayout->setRowStretch( 6, 1 );
295
296   /***************************************************************/
297   mySelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 );
298   QGridLayout* mySelectBoxLayout = new QGridLayout( mySelectBox );
299   mySelectBoxLayout->setMargin( MARGIN );
300   mySelectBoxLayout->setSpacing( SPACING );
301
302   mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), mySelectBox );
303   mySubMeshBtn = new QPushButton( mySelectBox );
304   mySubMeshBtn->setIcon( image0 );
305   mySubMeshLine = new QLineEdit( mySelectBox );
306   mySubMeshLine->setReadOnly( true );
307   onSelectSubMesh( false );
308
309   mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), mySelectBox );
310   myGroupBtn = new QPushButton( mySelectBox );
311   myGroupBtn->setIcon( image0 );
312   myGroupLine = new QLineEdit( mySelectBox );
313   myGroupLine->setReadOnly( true );
314   onSelectGroup( false );
315
316   mySelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 );
317   mySelectBoxLayout->addWidget( mySubMeshBtn,    0, 1 );
318   mySelectBoxLayout->addWidget( mySubMeshLine,   0, 2 );
319   mySelectBoxLayout->addWidget( mySelectGroup,   1, 0 );
320   mySelectBoxLayout->addWidget( myGroupBtn,      1, 1 );
321   mySelectBoxLayout->addWidget( myGroupLine,     1, 2 );
322
323   /***************************************************************/
324   QVBoxLayout* wg1Layout = new QVBoxLayout( wg1 );
325   wg1Layout->setMargin( 0 );
326   wg1Layout->setSpacing( SPACING );
327   wg1Layout->addWidget( aContentBox );
328   wg1Layout->addWidget( mySelectBox );
329   wg1Layout->setStretchFactor( aContentBox, 10 );
330
331   /***************************************************************/
332   QLabel* geomObject = new QLabel( tr( "SMESH_OBJECT_GEOM" ), wg2 );
333   myGeomGroupBtn = new QToolButton( wg2 );
334   myGeomGroupBtn->setIcon( image0 );
335   myGeomGroupBtn->setCheckable( true );
336   myGeomGroupLine = new QLineEdit( wg2 );
337   myGeomGroupLine->setReadOnly( true ); //VSR ???
338   onSelectGeomGroup( false );
339
340   myGeomGroupBtn->setEnabled( create );
341   myGeomGroupLine->setEnabled( create );
342
343   /***************************************************************/
344   QGridLayout* wg2Layout = new QGridLayout( wg2 );
345   wg2Layout->setMargin( 0 );
346   wg2Layout->setSpacing( SPACING );
347   wg2Layout->addWidget( geomObject,     0, 0 );
348   wg2Layout->addWidget( myGeomGroupBtn, 0, 1 );
349   wg2Layout->addWidget( myGeomGroupLine,0, 2 );
350   wg2Layout->setRowStretch( 1, 5 );
351
352   /***************************************************************/
353   QPushButton * aFilter2 = new QPushButton( tr( "SMESH_BUT_FILTER" ), wg3 );
354   QGridLayout* wg3Layout = new QGridLayout( wg3 );
355   wg3Layout->setMargin( 0 );
356   wg3Layout->setSpacing( SPACING );
357   wg3Layout->addWidget( aFilter2, 0, 0 );
358   wg3Layout->setRowStretch( 1, 5 );
359
360   /***************************************************************/
361   myWGStack->insertWidget( 0, wg1 );
362   myWGStack->insertWidget( 1, wg2 );
363   myWGStack->insertWidget( 2, wg3 );
364
365   /***************************************************************/
366   QGroupBox* aColorBox = new QGroupBox(tr( "SMESH_SET_COLOR" ), this);
367   QHBoxLayout* aColorBoxLayout = new QHBoxLayout(aColorBox);
368   aColorBoxLayout->setMargin(MARGIN);
369   aColorBoxLayout->setSpacing(SPACING);
370
371   QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox );
372   myColorBtn = new QtxColorButton(aColorBox);
373   myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding, 
374                              myColorBtn->sizePolicy().verticalPolicy() );
375
376   aColorBoxLayout->addWidget(aColorLab);
377   aColorBoxLayout->addWidget(myColorBtn);
378
379   /***************************************************************/
380
381   QFrame* aButtons = new QFrame(this);
382   aButtons->setFrameStyle( QFrame::Box | QFrame::Sunken );
383   QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons);
384   aBtnLayout->setMargin(MARGIN);
385   aBtnLayout->setSpacing(SPACING);
386
387   myOKBtn = new QPushButton(tr( "SMESH_BUT_APPLY_AND_CLOSE" ), aButtons);
388   myOKBtn->setAutoDefault(true);
389   myOKBtn->setDefault(true);
390   myApplyBtn = new QPushButton(tr( "SMESH_BUT_APPLY" ), aButtons);
391   myApplyBtn->setAutoDefault(true);
392   myCloseBtn = new QPushButton(tr( "SMESH_BUT_CLOSE" ), aButtons);
393   myCloseBtn->setAutoDefault(true);
394   myHelpBtn = new QPushButton(tr( "SMESH_BUT_HELP" ), aButtons);
395   myHelpBtn->setAutoDefault(true);
396
397   aBtnLayout->addWidget(myOKBtn);
398   aBtnLayout->addSpacing(10);
399   aBtnLayout->addWidget(myApplyBtn);
400   aBtnLayout->addSpacing(10);
401   aBtnLayout->addStretch();
402   aBtnLayout->addWidget(myCloseBtn);
403   aBtnLayout->addWidget(myHelpBtn);
404
405   /***************************************************************/
406   aMainLayout->addWidget(meshGroupLab,    0, 0);
407   aMainLayout->addWidget(myMeshGroupBtn,  0, 1);
408   aMainLayout->addWidget(myMeshGroupLine, 0, 2);
409   aMainLayout->addWidget(aTypeBox,        1, 0, 1, 3);
410   aMainLayout->addWidget(aName,           2, 0);
411   aMainLayout->addWidget(myName,          2, 2);
412   aMainLayout->addWidget(aGrpTypeBox,     3, 0, 1, 3);
413   aMainLayout->addWidget(myWGStack,       4, 0, 1, 3);
414   aMainLayout->addWidget(aColorBox,       5, 0, 1, 3);
415   aMainLayout->addWidget(aButtons,        6, 0, 1, 3);
416
417   /* signals and slots connections */
418   connect(myMeshGroupBtn,  SIGNAL(clicked()),          this, SLOT(setCurrentSelection()));
419   connect(myGrpTypeGroup,  SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int)));
420   connect(myTypeGroup,     SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
421
422   connect(myName,          SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
423   connect(myElements,      SIGNAL(itemSelectionChanged()),      this, SLOT(onListSelectionChanged()));
424
425   connect(myFilterBtn,     SIGNAL(clicked()),     this, SLOT(setFilters()));
426   connect(aFilter2,        SIGNAL(clicked()),     this, SLOT(setFilters()));
427   connect(mySelectAll,     SIGNAL(toggled(bool)), this, SLOT(onSelectAll()));
428   connect(myAllowElemsModif,SIGNAL(toggled(bool)), this, SLOT(onSelectAll()));
429   connect(myAddBtn,        SIGNAL(clicked()),     this, SLOT(onAdd()));
430   connect(myRemoveBtn,     SIGNAL(clicked()),     this, SLOT(onRemove()));
431   connect(mySortBtn,       SIGNAL(clicked()),     this, SLOT(onSort()));
432
433   connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool)));
434   connect(mySelectGroup,   SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool)));
435   connect(mySubMeshBtn,    SIGNAL(clicked()),     this, SLOT(setCurrentSelection()));
436   connect(myGroupBtn,      SIGNAL(clicked()),     this, SLOT(setCurrentSelection()));
437   connect(myGeomGroupBtn,  SIGNAL(toggled(bool)), this, SLOT(onGeomSelectionButton(bool)));
438
439   connect(myColorBtn,      SIGNAL(changed( QColor )),  this, SLOT(onColorChanged( QColor )));
440
441   connect(myOKBtn,         SIGNAL(clicked()), this, SLOT(onOK()));
442   connect(myApplyBtn,      SIGNAL(clicked()), this, SLOT(onApply()));
443   connect(myCloseBtn,      SIGNAL(clicked()), this, SLOT(reject()));
444   connect(myHelpBtn,       SIGNAL(clicked()), this, SLOT(onHelp()));
445
446   /* Init selection */
447   mySMESHGUI->SetActiveDialogBox(this);
448
449   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
450   mySelectionMode = grpNoSelection;
451
452   myMeshFilter    = new SMESH_TypeFilter(SMESH::MESH);
453   mySubMeshFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
454                                             SMESH_LogicalFilter::LO_OR,
455                                             /*takeOwnership=*/true);
456   myGroupFilter   = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
457                                             SMESH_LogicalFilter::LO_OR,
458                                             /*takeOwnership=*/true);
459   myGeomFilter    = new GEOM_SelectionFilter( aStudy, true );
460
461   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
462   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(reject()));
463   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),  this, SLOT(onObjectSelectionChanged()));
464   connect(mySMESHGUI, SIGNAL(SignalVisibilityChanged()),      this, SLOT(onVisibilityChanged()));
465   connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()),   this, SLOT(onOpenView()));
466   connect(mySMESHGUI, SIGNAL(SignalCloseView()),              this, SLOT(onCloseView()));
467   rb1->setChecked(true); // VSR !!!
468   onGrpTypeChanged(0); // VSR!!!
469
470   if (myMesh->_is_nil() )
471     myTypeGroup->button(0)->setChecked(true);
472
473   onSelectAll(); //updateButtons();
474 }
475
476 //=================================================================================
477 // function : ~SMESHGUI_GroupDlg()
478 // purpose  : Destroys the object and frees any allocated resources
479 //=================================================================================
480 SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg()
481 {
482   // no need to delete child widgets, Qt does it all for us
483   if ( myFilterDlg != 0 ) {
484     myFilterDlg->setParent( 0 );
485     delete myFilterDlg;
486   }
487   if ( myMeshFilter )    delete myMeshFilter;
488   if ( mySubMeshFilter ) delete mySubMeshFilter;
489   if ( myGroupFilter )   delete myGroupFilter;
490   if ( myGeomFilter )    delete myGeomFilter;
491 }
492
493 //=================================================================================
494 // function : GetDefaultName()
495 // purpose  : Get the Group Name if Create new Group
496 //=================================================================================
497 QString SMESHGUI_GroupDlg::GetDefaultName(const QString& theOperation)
498 {
499   QString aName = "";
500
501   // collect all object names of SMESH component
502   _PTR(Study) aStudy = SMESH::getStudy();
503
504   std::set<std::string> aSet;
505   _PTR(SComponent) aMeshCompo (aStudy->FindComponent( "SMESH" ));
506   if (aMeshCompo) {
507     _PTR(ChildIterator) it (aStudy->NewChildIterator(aMeshCompo));
508     _PTR(SObject) obj;
509     for (it->InitEx(true); it->More(); it->Next()) {
510       obj = it->Value();
511       aSet.insert(obj->GetName());
512     }
513   }
514
515   // build a unique name
516   int aNumber = 0;
517   bool isUnique = false;
518   while (!isUnique) {
519     aName = theOperation + "_" + QString::number(++aNumber);
520     isUnique = (aSet.count(std::string(aName.toUtf8().constData())) == 0);
521   }
522
523   return aName;
524 }
525
526 //=======================================================================
527 //function : setDefaultName
528 //purpose  : 
529 //=======================================================================
530
531 void  SMESHGUI_GroupDlg::setDefaultName() const
532 {
533   QString aResName;
534   const QString aPrefix ="Group_";
535
536   if ( myMesh->_is_nil() )
537   {
538     aResName = aPrefix + "1";
539   }
540   else
541   {
542     SMESH::ListOfGroups_var allGroups = myMesh->GetGroups();
543     TColStd_MapOfAsciiString allNames( allGroups->length() );
544     for ( CORBA::ULong i = 0; i < allGroups->length(); ++i )
545     {
546       CORBA::String_var name = allGroups[i]->GetName();
547       allNames.Add( name.in() );
548     }
549     int i = 1;
550     while ( true )
551     {
552       aResName = aPrefix + QString::number( i++ );
553       if ( !allNames.Contains( aResName.toUtf8().constData() ))
554         break;
555     }
556   }
557   myName->setText(aResName);
558 }
559
560 //=================================================================================
561 // function : Init()
562 // purpose  :
563 //=================================================================================
564 void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
565 {
566   mySelectionMgr->installFilter(myMeshFilter);
567
568   /* init data from current selection */
569   restoreShowEntityMode();
570   myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
571   setShowEntityMode();
572   myGroup = SMESH::SMESH_Group::_nil();
573   myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
574   myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
575
576   // NPAL19389: create a group with a selection in another group
577   // set actor of myMesh, if it is visible, else try
578   // any visible actor of group or submesh of myMesh
579   SetAppropriateActor();
580
581   setDefaultGroupColor();
582   setDefaultName();
583
584
585   SALOME_ListIO aList;
586   mySelectionMgr->selectedObjects( aList );
587   if( !aList.IsEmpty() )
588   {
589     QString aName = aList.First()->getName();
590     myMeshGroupLine->setText(aName);//??????
591     myMeshGroupLine->home( false );
592   }
593
594   myCurrentLineEdit = 0;
595
596   myTypeGroup->button(0)->setChecked(true);
597   onTypeChanged(0);
598 }
599
600 //=================================================================================
601 // function : Init()
602 // purpose  :
603 //=================================================================================
604 void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
605                               const bool                 theIsConvert)
606 {
607   restoreShowEntityMode();
608   myMesh = theGroup->GetMesh();
609   setShowEntityMode();
610
611   myNameChanged = true;
612   myName->blockSignals(true);
613   myName->setText(SMESH::fromUtf8(theGroup->GetName()));
614   myName->blockSignals(false);
615   myName->home(false);
616
617   SALOMEDS::Color aColor = theGroup->GetColor();
618   setGroupColor( aColor );
619
620   myMeshGroupLine->setText(theGroup->GetName());
621
622   int aType = 0;
623   switch(theGroup->GetType()) {
624   case SMESH::NODE:   aType = grpNodeSelection;   break;
625   case SMESH::ELEM0D: aType = grp0DSelection;     break;
626   case SMESH::BALL:   aType = grpBallSelection;   break;
627   case SMESH::EDGE:   aType = grpEdgeSelection;   break;
628   case SMESH::FACE:   aType = grpFaceSelection;   break;
629   case SMESH::VOLUME: aType = grpVolumeSelection; break;
630   case SMESH::ALL:
631   case SMESH::NB_ELEMENT_TYPES: break;
632   }
633   myTypeGroup->button(aType)->setChecked(true);
634
635   myGroup         = SMESH::SMESH_Group::_narrow( theGroup );
636   myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
637   myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_narrow( theGroup );
638   myFilter        = SMESH::Filter::_nil();
639
640   if (myGroup->_is_nil() && myGroupOnGeom->_is_nil() && myGroupOnFilter->_is_nil() )
641     return;
642
643   // NPAL19389: create a group with a selection in another group
644   // set actor of myMesh, if it is visible, else set
645   // actor of theGroup, if it is visible, else try
646   // any visible actor of group or submesh of myMesh
647   // commented, because an attempt to set selection on not displayed cells leads to error
648   SetAppropriateActor();
649
650   /*  SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
651   if ( !anActor )
652     anActor = SMESH::FindActorByObject(theGroup);
653   SMESH::SetPickable(anActor);*/
654
655   int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : myGroupOnGeom->_is_nil() ? 2 : 1));
656   myGrpTypeGroup->button(grpType)->setChecked(true);
657   onGrpTypeChanged(grpType);
658
659   myTypeId = aType;
660   if ( grpType == 0 ) { // standalone group
661     myCurrentLineEdit = 0;
662     myElements->clear();
663     myAllowElemsModif->setChecked( true );
664
665     setSelectionMode(aType);
666
667     setShowEntityMode(); // depends on myTypeId
668
669     myIdList.clear();
670     if (!theGroup->IsEmpty()) {
671       SMESH::smIdType_array_var anElements = theGroup->GetListOfID();
672       int k = anElements->length();
673       for (int i = 0; i < k; i++) {
674         myIdList.append(anElements[i]);
675         myElements->addItem(QString::number(anElements[i]));
676       }
677       myElements->selectAll();
678     }
679   }
680   else if ( grpType == 1 ) // group on geom
681   {
682     QString aShapeName( "" );
683     _PTR(Study) aStudy = SMESH::getStudy();
684     GEOM::GEOM_Object_var aGroupShape = myGroupOnGeom->GetShape();
685     if (!aGroupShape->_is_nil())
686     {
687       _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry());
688       if ( aGroupShapeSO )
689         aShapeName = aGroupShapeSO->GetName().c_str();
690     }
691     myGeomGroupLine->setText( aShapeName );
692   }
693   else // group on filter
694   {
695     myFilter = myGroupOnFilter->GetFilter();
696     if ( !myFilter->_is_nil() ) {
697       SMESH::Predicate_var perdicate = myFilter->GetPredicate();
698       if ( perdicate->_is_nil() )
699         myFilter = SMESH::Filter::_nil();
700     }
701   }
702
703   if ( grpType != 0 )
704   {
705     myNameChanged = true;
706     myName->blockSignals(true);
707     myName->setText(theGroup->GetName());
708     myName->blockSignals(false);
709   }
710
711   onSelectAll(); //updateButtons();
712 }
713
714 //=================================================================================
715 // function : updateButtons()
716 // purpose  :
717 //=================================================================================
718 void SMESHGUI_GroupDlg::updateButtons()
719 {
720   bool enable = !myName->text().trimmed().isEmpty();
721   if ( enable )
722   {
723     if (myGrpTypeId == 0) { // standalone
724       if ( !mySelectAll->isChecked() )
725       {
726         if ( myAllowElemsModif->isChecked() )
727         {
728           enable = ( myElements->count() > 0 );
729         }
730         else if ((enable = !myFilter->_is_nil() ))
731         {
732           SMESH::array_of_ElementType_var types = myFilter->GetTypes();
733           enable = types->length();
734         }
735       }
736       enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
737     }
738     else if (myGrpTypeId == 1) // on geom
739     {
740       if (CORBA::is_nil(myGroupOnGeom)) // creation mode
741         enable = ( myGeomObjects->length() > 0 && !myMesh->_is_nil() );
742     }
743     else if (myGrpTypeId == 2) // on filter
744     {
745       if (( enable = !myFilter->_is_nil() ))
746         if (CORBA::is_nil(myGroupOnFilter) )  // creation mode
747           enable = !myMesh->_is_nil();
748     }
749   }
750
751   bool meshHasGeom = ( myMesh->_is_nil() || myMesh->HasShapeToMesh() );
752   if ( myGrpTypeId != 1 )
753   {
754     myGrpTypeGroup->button(1)->setEnabled( meshHasGeom );
755   }
756   else
757   {
758     myGeomGroupBtn->setEnabled( meshHasGeom );
759     myGeomGroupLine->setEnabled( meshHasGeom );
760   }
761
762   myOKBtn->setEnabled(enable);
763   myApplyBtn->setEnabled(enable);
764 }
765
766 //=================================================================================
767 // function : onNameChanged()
768 // purpose  :
769 //=================================================================================
770 void SMESHGUI_GroupDlg::onNameChanged (const QString& /*text*/)
771 {
772   myOldName = myName->text();
773   updateButtons();
774   myNameChanged = !myName->text().trimmed().isEmpty();
775 }
776
777 //=================================================================================
778 // function : onTypeChanged()
779 // purpose  : Group elements type radio button management
780 //=================================================================================
781 void SMESHGUI_GroupDlg::onTypeChanged (int id)
782 {
783   if (myTypeId != id) {
784     myElements->clear();
785     myTypeId = id;
786     if ( myGrpTypeId == 0 && myCurrentLineEdit == 0)
787       setSelectionMode(id);
788     else
789       setSelectionMode( mySelectionMode++ ); // update according to mySelectionMode
790
791     onObjectSelectionChanged();
792     setShowEntityMode();
793   }
794 }
795
796 //=================================================================================
797 // function : onGrpTypeChanged()
798 // purpose  : Group type radio button management
799 //=================================================================================
800 void SMESHGUI_GroupDlg::onGrpTypeChanged (int id)
801 {
802   if (myGrpTypeId != id) {
803     myGrpTypeId = id;
804     myWGStack->setCurrentIndex( id );
805     myName->blockSignals(true);
806     myName->setText(myOldName);
807     myName->blockSignals(false);
808     onSelectGeomGroup(id != 0);
809   }
810   updateButtons();
811 }
812
813 //=================================================================================
814 // function : onColorChanged()
815 // purpose  : Color button management
816 //=================================================================================
817 void SMESHGUI_GroupDlg::onColorChanged(QColor /*theColor*/)
818 {
819   updateButtons();
820 }
821
822 //=================================================================================
823 // function : setSelectionMode()
824 // purpose  : Radio button management
825 //=================================================================================
826 void SMESHGUI_GroupDlg::setSelectionMode (int theMode)
827 {
828   // PAL7314
829   if (myMesh->_is_nil())
830     return;
831   SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
832   bool isSelectAll = mySelectAll->isChecked() || !myAllowElemsModif->isChecked() || myGrpTypeId != 0;
833   if (mySelectionMode != theMode) {
834     // [PAL10408] mySelectionMgr->clearSelected();
835     mySelectionMgr->clearFilters();
836     SMESH::RemoveFilters();
837
838     if (myActorsList.count() > 0)
839       for (QListIterator<SMESH_Actor*> it( myActorsList ); it.hasNext(); )
840         it.next()->SetPointRepresentation(false);
841     else
842       SMESH::SetPointRepresentation(false);
843
844     switch (theMode) {
845     case grpNodeSelection:
846       if ( myGrpTypeId == 0 ) // standalone
847       {
848         if (myActorsList.count() > 0)
849           for (QListIterator<SMESH_Actor*> it( myActorsList ); it.hasNext(); )
850             it.next()->SetPointRepresentation(true);
851         else
852           SMESH::SetPointRepresentation(true);
853       }
854       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : NodeSelection);
855       break;
856     case grpEdgeSelection:
857       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : EdgeSelection);
858       break;
859     case grpBallSelection:
860       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : BallSelection);
861       break;
862     case grp0DSelection:
863       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : Elem0DSelection);
864       break;
865     case grpFaceSelection:
866       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : FaceSelection);
867       break;
868     case grpVolumeSelection:
869       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : VolumeSelection);
870       break;
871     case grpSubMeshSelection: {
872
873       SMESH_TypeFilter* f = 0;
874       switch (myTypeId) {
875       case grpNodeSelection:   f = new SMESH_TypeFilter(SMESH::SUBMESH); break;
876       case grpEdgeSelection:   f = new SMESH_TypeFilter(SMESH::SUBMESH_EDGE); break;
877       case grpFaceSelection:   f = new SMESH_TypeFilter(SMESH::SUBMESH_FACE); break;
878       case grpVolumeSelection: f = new SMESH_TypeFilter(SMESH::SUBMESH_SOLID); break;
879       default:                 f = new SMESH_TypeFilter(SMESH::SUBMESH);
880       }
881       QList<SUIT_SelectionFilter*> filtList;
882       filtList.append( f );
883       filtList.append( new SMESH_TypeFilter(SMESH::SUBMESH_COMPOUND));
884       mySubMeshFilter->setFilters( filtList );
885
886       mySelectionMgr->installFilter( mySubMeshFilter );
887
888       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
889       break;
890     }
891     case grpGroupSelection: {
892
893       SMESH_TypeFilter* f = 0;
894       switch (myTypeId) {
895       case grpNodeSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_NODE);   break;
896       case grp0DSelection:     f = new SMESH_TypeFilter(SMESH::GROUP_0D);     break;
897       case grpBallSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_BALL);   break;
898       case grpEdgeSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_EDGE);   break;
899       case grpFaceSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_FACE);   break;
900       case grpVolumeSelection: f = new SMESH_TypeFilter(SMESH::GROUP_VOLUME); break;
901       default:                 f = new SMESH_TypeFilter(SMESH::GROUP);
902       }
903       QList<SUIT_SelectionFilter*> filtList;
904       filtList.append( f );
905       myGroupFilter->setFilters( filtList );
906
907       mySelectionMgr->installFilter(myGroupFilter);
908       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
909       break;
910     }
911     case grpMeshSelection:
912       mySelectionMgr->installFilter(myMeshFilter);
913       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
914       break;
915     case grpGeomSelection:
916       mySelectionMgr->installFilter(myGeomFilter);
917       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
918       break;
919     default:
920       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
921       break;
922     }
923     if ( aViewWindow ) aViewWindow->Repaint();
924     mySelectionMode = theMode;
925   }
926 }
927
928 //=================================================================================
929 // function : onApply()
930 // purpose  :
931 //=================================================================================
932 bool SMESHGUI_GroupDlg::onApply()
933 {
934   if (SMESHGUI::isStudyLocked())
935     return false;
936
937   if (myName->text().trimmed().isEmpty())
938     return false;
939
940   SMESH::ElementType aType = SMESH::ALL;
941   switch (myTypeId) {
942   case grpNodeSelection:   aType = SMESH::NODE;   break;
943   case grp0DSelection:     aType = SMESH::ELEM0D; break;
944   case grpBallSelection:   aType = SMESH::BALL;   break;
945   case grpEdgeSelection:   aType = SMESH::EDGE;   break;
946   case grpFaceSelection:   aType = SMESH::FACE;   break;
947   case grpVolumeSelection: aType = SMESH::VOLUME; break;
948   }
949
950   bool anIsOk = false;
951   QStringList anEntryList;
952
953   SMESH::SMESH_GroupBase_var resultGroup;
954   bool isCreation = false, isConversion = false;
955     
956   SUIT_OverrideCursor wc;
957
958   if (myGrpTypeId == 0)  // standalone
959   {
960     if (!mySelectAll->isChecked() && !myElements->count() && myAllowElemsModif->isChecked())
961       return false;
962
963     mySelectionMgr->clearSelected();
964
965     if (myGroup->_is_nil()) { // creation or conversion
966       // check if group on geometry is not null
967       if (!myGroupOnGeom->_is_nil() || !myGroupOnFilter->_is_nil())
968       {
969         if (myMesh->_is_nil())
970           return false;
971         if ( myGroupOnGeom->_is_nil() )
972           myGroup = myMesh->ConvertToStandalone( myGroupOnFilter );
973         else
974           myGroup = myMesh->ConvertToStandalone( myGroupOnGeom );
975
976         myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_nil();
977         myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
978         isConversion    = true;
979       }
980     }
981
982     if (myGroup->_is_nil()) // creation
983     {
984       if (myMesh->_is_nil())
985         return false;
986
987       myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
988
989       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup );
990       isCreation = true;
991
992       if ( mySelectAll->isChecked() ) {
993         // select all
994         myGroup->AddFrom(myMesh.in());
995       }
996       else {
997         // select manually
998
999         if ( !myFilter->_is_nil() &&
1000              ( myNbChangesOfContents == 1 || !myAllowElemsModif->isChecked()))
1001         {
1002           myGroup->AddFrom( myFilter );
1003         }
1004         else
1005         {
1006           SMESH::smIdType_array_var anIdList = new SMESH::smIdType_array;
1007           int i, k = myElements->count();
1008           anIdList->length(k);
1009           for (i = 0; i < k; i++) {
1010             anIdList[i] = myElements->item(i)->text().toInt();
1011           }
1012           myGroup->Add(anIdList.inout());
1013         }
1014       }
1015     }
1016
1017     else // edition
1018     {
1019       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup );
1020       isCreation = false;
1021
1022       if ( mySelectAll->isChecked() ) {
1023         // select all
1024         myGroup->Clear();
1025         myGroup->AddFrom(myMesh.in());
1026       }
1027       else {
1028         QList<int> aAddList;
1029         
1030         int i, total = myElements->count();
1031         for (i = 0; i < total; i++) {
1032           int anId = myElements->item(i)->text().toInt();
1033           int idx = myIdList.indexOf(anId);
1034           if ( idx == -1 )
1035             aAddList.append(anId);
1036           else
1037             myIdList.removeAt(idx);
1038         }
1039         if (!aAddList.empty()) {
1040           SMESH::smIdType_array_var anIdList = new SMESH::smIdType_array;
1041           int added = aAddList.count();
1042           anIdList->length(added);
1043           for (i = 0; i < added; i++)
1044             anIdList[i] = aAddList[i];
1045           myGroup->Add(anIdList.inout());
1046         }
1047         if (!myIdList.empty()) {
1048           SMESH::smIdType_array_var anIdList = new SMESH::smIdType_array;
1049           int removed = myIdList.count();
1050           anIdList->length(removed);
1051           for (i = 0; i < removed; i++)
1052             anIdList[i] = myIdList[i];
1053           myGroup->Remove(anIdList.inout());
1054         }
1055         /* init for next operation */
1056         myIdList.clear();
1057         for (i = 0; i < total; i++) {
1058           myIdList.append(myElements->item(i)->text().toInt());
1059         }
1060       }
1061     }
1062
1063     anIsOk = true;
1064   }
1065   else if (myGrpTypeId == 1) // on geom object
1066   {
1067     if (CORBA::is_nil(myGroupOnGeom)) { // creation
1068       if (myMesh->_is_nil() || !myGeomObjects->length())
1069         return false;
1070
1071       _PTR(Study) aStudy = SMESH::getStudy();
1072
1073       if (myGeomObjects->length() == 1) {
1074         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
1075                                                     myName->text().toUtf8(),
1076                                                     myGeomObjects[0]);
1077       }
1078       else {
1079         SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
1080         if ( aSMESHGen->_is_nil() || myGeomObjects->length() == 0 )
1081           return false;
1082
1083         // create a geometry group
1084         GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen( myGeomObjects[0] );
1085         if (geomGen->_is_nil())
1086           return false;
1087
1088         GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations();
1089         if (op->_is_nil())
1090           return false;
1091
1092         // check and add all selected GEOM objects: they must be
1093         // a sub-shapes of the main GEOM and must be of one type
1094         TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
1095         for ( CORBA::ULong i =0; i < myGeomObjects->length(); i++)
1096         {
1097           TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
1098           if ( i == 0 )
1099             aGroupType = aSubShapeType;
1100           else if ( aSubShapeType != aGroupType ) {
1101             aGroupType = TopAbs_SHAPE;
1102             break;
1103           }
1104         }
1105
1106         GEOM::GEOM_Object_var  aMeshShape = myMesh->GetShapeToMesh();
1107         GEOM::GEOM_Object_wrap aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
1108         if ( aGroupVar->_is_nil() )
1109           return false;
1110         op->UnionList(aGroupVar, myGeomObjects);
1111
1112         if (op->IsDone()) {
1113           // publish the GEOM group in study
1114           QString aNewGeomGroupName ( "Auto_group_for_" );
1115           aNewGeomGroupName += myName->text();
1116           SALOMEDS::SObject_var aNewGroupSO =
1117             geomGen->AddInStudy(aGroupVar,
1118                                 aNewGeomGroupName.toUtf8(), aMeshShape);
1119         }
1120
1121         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
1122                                                     myName->text().toUtf8(),
1123                                                     aGroupVar);
1124       }
1125       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
1126       isCreation = true;
1127
1128     }
1129     else { // edition
1130
1131       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
1132       isCreation = false;
1133     }
1134     anIsOk = true;
1135   }
1136
1137   if (myGrpTypeId == 2) // group on filter
1138   {
1139     if ( myFilter->_is_nil() ) return false;
1140
1141     if (CORBA::is_nil(myGroupOnFilter)) // creation
1142     {
1143       if (myMesh->_is_nil())
1144         return false;
1145
1146       myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
1147                                                       myName->text().toUtf8(),
1148                                                       myFilter);
1149       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
1150       isCreation = true;
1151     }
1152     else
1153     {
1154       myGroupOnFilter->SetFilter( myFilter );
1155
1156       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
1157       isCreation = false;
1158     }
1159     anIsOk = true;
1160   }
1161
1162   if ( anIsOk )
1163   {
1164     SALOMEDS::Color aColor = getGroupColor();
1165     resultGroup->SetColor(aColor);
1166
1167     _PTR(SObject) aMeshGroupSO = SMESH::FindSObject( resultGroup );
1168     if( aMeshGroupSO )
1169       anEntryList.append( aMeshGroupSO->GetID().c_str() );
1170
1171     resultGroup->SetName(myName->text().trimmed().toUtf8());
1172
1173     if ( isCreation )
1174     {
1175       SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
1176
1177       /* init for the next operation */
1178       setDefaultName();
1179       myElements->clear();
1180       myGroup         = SMESH::SMESH_Group::_nil();
1181       myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_nil();
1182       myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
1183       myFilter        = SMESH::Filter::_nil();
1184
1185       setDefaultGroupColor(); // reset color for case if 'auto-color' feature is enabled.
1186     }
1187     else
1188     {
1189       if ( aMeshGroupSO )
1190       {
1191         if ( SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
1192         {
1193           Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
1194           if ( isConversion ) { // need to reset TVisualObj and actor
1195             SMESH::RemoveVisualObjectWithActors( anIO->getEntry(), true );
1196             SMESH::Update( anIO, true );
1197             myActorsList.clear();
1198             anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1199             if ( !anActor ) return false;
1200             myActorsList.append( anActor );
1201           }
1202           anActor->setName(myName->text().toUtf8());
1203           QColor c;
1204           int delta;
1205           switch ( myTypeId ) {
1206           case grpNodeSelection:   anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
1207           case grp0DSelection:     anActor->Set0DColor  ( aColor.R, aColor.G, aColor.B ); break;
1208           case grpBallSelection:   anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break;
1209           case grpEdgeSelection:   anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
1210           case grpVolumeSelection: 
1211             SMESH::GetColor("SMESH", "volume_color", c , delta, "255,0,170|-100");
1212             anActor->SetVolumeColor( aColor.R, aColor.G, aColor.B, delta ); break;          
1213             break;
1214           case grpFaceSelection:   
1215           default:
1216             SMESH::GetColor("SMESH", "fill_color", c , delta, "0,170,255|-100");
1217             anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); break;          
1218             break;
1219           }
1220           // update a visible group according to a changed contents
1221           if ( !isConversion && anActor->GetVisibility() )
1222           {
1223             SMESH::Update( anIO, true );
1224             SMESH::RepaintCurrentView();
1225           }
1226         }
1227       }
1228     }
1229     SMESHGUI::Modified();
1230     mySMESHGUI->updateObjBrowser(true);
1231     mySelectionMgr->clearSelected();
1232
1233     if( LightApp_Application* anApp =
1234         dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
1235       myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() );
1236   }
1237   return anIsOk;
1238 }
1239
1240 //=================================================================================
1241 // function : onOK()
1242 // purpose  :
1243 //=================================================================================
1244 void SMESHGUI_GroupDlg::onOK()
1245 {
1246   setIsApplyAndClose( true );
1247   if ( onApply() )
1248     reject();
1249   setIsApplyAndClose( false );
1250
1251   if ( myFilterDlg ) myFilterDlg->UnRegisterFilters();
1252 }
1253
1254 //=================================================================================
1255 // function : onListSelectionChanged()
1256 // purpose  : Called when selection in element list is changed
1257 //=================================================================================
1258 void SMESHGUI_GroupDlg::onListSelectionChanged()
1259 {
1260   //MESSAGE( "SMESHGUI_GroupDlg::onListSelectionChanged(); myActorsList.count() = " << myActorsList.count());
1261   if( myIsBusy || myActorsList.count() == 0 ) return;
1262   myIsBusy = true;
1263
1264   if (myCurrentLineEdit == 0) {
1265     mySelectionMgr->clearSelected();
1266     SVTK_TVtkIDsMap aIndexes;
1267     QList<QListWidgetItem*> selItems = myElements->selectedItems();
1268     QListWidgetItem* anItem;
1269     foreach(anItem, selItems) aIndexes.Add(anItem->text().toInt());
1270     mySelector->AddOrRemoveIndex(myActorsList.first()->getIO(), aIndexes, false);
1271     SALOME_ListIO aList;
1272     aList.Append(myActorsList.first()->getIO());
1273     mySelectionMgr->setSelectedObjects(aList,false);
1274   }
1275   myIsBusy = false;
1276 }
1277
1278 //=================================================================================
1279 // function : onObjectSelectionChanged()
1280 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
1281 //=================================================================================
1282 void SMESHGUI_GroupDlg::onObjectSelectionChanged()
1283 {
1284   if ( myIsBusy || !isEnabled()) return;
1285   if (myCurrentLineEdit == myGeomGroupLine && !myGeomGroupBtn->isChecked()) return;
1286
1287   myIsBusy = true;
1288
1289   SALOME_ListIO aList;
1290   mySelectionMgr->selectedObjects( aList );
1291
1292   int aNbSel = aList.Extent();
1293   myElements->clearSelection();
1294
1295   if (myCurrentLineEdit)
1296   {
1297     myCurrentLineEdit->setText( "" );
1298     QString aString = "";
1299
1300     if (myCurrentLineEdit == myMeshGroupLine)
1301     {
1302       mySelectSubMesh->setEnabled(false);
1303       mySelectGroup->setEnabled(false);
1304       myGroupLine->setText( "" );
1305       mySubMeshLine->setText( "" );
1306
1307       myGeomGroupBtn->setEnabled(false);
1308       myGeomGroupLine->setEnabled(false);
1309       myGeomGroupLine->setText( "" );
1310       myGeomObjects = new GEOM::ListOfGO();
1311       myGeomObjects->length(0);
1312
1313       if (myGeomGroupBtn->isChecked())
1314         myGeomGroupBtn->setChecked(false);
1315       if (!myCreate)
1316         myName->setText( "" );
1317
1318       myElements->clear();
1319
1320       if (aNbSel != 1 ) {
1321         myGroup = SMESH::SMESH_Group::_nil();
1322         myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
1323         restoreShowEntityMode();
1324         myMesh = SMESH::SMESH_Mesh::_nil();
1325         updateGeomPopup();
1326         updateButtons();
1327         myIsBusy = false;
1328         return;
1329       }
1330       Handle(SALOME_InteractiveObject) IO = aList.First();
1331
1332       if (myCreate) {
1333         restoreShowEntityMode();
1334         myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
1335         setShowEntityMode();
1336         updateGeomPopup();
1337         if (myMesh->_is_nil())
1338         {
1339           updateButtons();
1340           myIsBusy = false;
1341           return;
1342         }
1343
1344         if ( myFilterDlg && !myMesh->_is_nil()){
1345           myFilterDlg->SetMesh( myMesh );
1346         }
1347         myGroup = SMESH::SMESH_Group::_nil();
1348
1349         // NPAL19389: create a group with a selection in another group
1350         // set actor of myMesh, if it is visible, else try
1351         // any visible actor of group or submesh of myMesh
1352         SetAppropriateActor();
1353
1354         setDefaultGroupColor();
1355         if (myName->text().isEmpty())
1356           setDefaultName();
1357
1358         aString = aList.First()->getName();
1359         myMeshGroupLine->setText(aString);
1360         myMeshGroupLine->home( false );
1361
1362         mySelectSubMesh->setEnabled(true);
1363         mySelectGroup->setEnabled(true);
1364         myGeomGroupBtn->setEnabled(true);
1365         myGeomGroupLine->setEnabled(true);
1366         updateButtons();
1367       }
1368       else {
1369         SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
1370         if (aGroup->_is_nil())
1371         {
1372           myIsBusy = false;
1373           return;
1374         }
1375         myIsBusy = false;
1376
1377         myGroup = SMESH::SMESH_Group::_nil();
1378         myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
1379
1380         init(aGroup);
1381         myIsBusy = true;
1382         mySelectSubMesh->setEnabled(true);
1383         mySelectGroup->setEnabled(true);
1384       }
1385       myCurrentLineEdit = 0;
1386       myIsBusy = false;
1387       if (!myCreate)
1388         return;
1389
1390       if (myGrpTypeId == 0)
1391       {
1392         if (myTypeId == -1)
1393           onTypeChanged(0);
1394         else
1395         {
1396           myElements->clear();
1397           setSelectionMode(myTypeId);
1398         }
1399       }
1400
1401       myIsBusy = false;
1402       return;
1403
1404     }
1405     else if (myCurrentLineEdit == myGeomGroupLine)
1406     {
1407       myGeomObjects = new GEOM::ListOfGO();
1408       myGeomObjects->length( aNbSel );
1409
1410       if ( aNbSel == 0 || myMesh->_is_nil() )
1411       {
1412         updateButtons();
1413         myIsBusy = false;
1414         return;
1415       }
1416
1417       GEOM::GEOM_Object_var mainGeom = myMesh->GetShapeToMesh();
1418       int i = 0;
1419       for ( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
1420       {
1421         // Check if group constructed on the same shape as a mesh or on its child
1422         GEOM::GEOM_Object_var geomGroup = SMESH::GetGeom( anIt.Value() );
1423         if ( SMESH::ContainsSubShape( mainGeom, geomGroup ))
1424           myGeomObjects[ i++ ] = geomGroup;
1425       }
1426
1427       myGeomObjects->length(i);
1428       if ( i == 0 )
1429       {
1430         myIsBusy = false;
1431         return;
1432       }
1433
1434       aNbSel = i;
1435     }
1436
1437     if (aNbSel >= 1) {
1438       if (aNbSel > 1) {
1439         if (myCurrentLineEdit == mySubMeshLine)
1440           aString = tr( "SMESH_SUBMESH_SELECTED" ).arg(aNbSel);
1441         else if (myCurrentLineEdit == myGroupLine)
1442           aString = tr( "SMESH_GROUP_SELECTED" ).arg(aNbSel);
1443         else if (myCurrentLineEdit == myGeomGroupLine)
1444           aString = tr( "%1 Objects" ).arg(aNbSel);
1445       }
1446       else {
1447         aString = aList.First()->getName();
1448       }
1449     }
1450
1451     myCurrentLineEdit->setText(aString);
1452     myCurrentLineEdit->home(false);
1453     // 07.06.2008 skl for IPAL19574:
1454     // change name of group only if it is empty
1455     if( myName->text().trimmed().isEmpty() || !myNameChanged ) {
1456       myOldName = myName->text();
1457       myName->blockSignals(true);
1458       myName->setText(aString);
1459       myName->blockSignals(false);
1460     }
1461
1462     updateButtons();
1463   }
1464   else // !myCurrentLineEdit: local selection of nodes or elements
1465   {
1466     if (aNbSel == 1 && myActorsList.count() > 0 )
1467     {
1468       // NPAL19389: create a group with a selection in another group
1469       // Switch myActor to the newly selected one, if the last
1470       // is visible and belongs to group or submesh of myMesh
1471       /*      Handle(SALOME_InteractiveObject) curIO = myActor->getIO();
1472       Handle(SALOME_InteractiveObject) selIO = aList.First();
1473       if (curIO->hasEntry() && selIO->hasEntry()) {
1474         const char* selEntry = selIO->getEntry();
1475         if (strcmp(curIO->getEntry(), selEntry) != 0) {
1476           // different objects: selected and myActor
1477           SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
1478           if (aViewWindow && aViewWindow->isVisible(selIO)) {
1479             // newly selected actor is visible
1480
1481             // mesh entry
1482             _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
1483             if (aSObject) {
1484               CORBA::String_var meshEntry = aSObject->GetID().c_str();
1485               int len = strlen(meshEntry);
1486
1487               if (strncmp(selEntry, meshEntry, len) == 0) {
1488                 // selected object is myMesh or a part of it
1489                 SMESH_Actor* anActor = SMESH::FindActorByEntry(selEntry);
1490                 if (anActor) {
1491                   myActor = anActor;
1492                   SMESH::SetPickable(myActor);
1493                 }
1494               }
1495             }
1496           }
1497         }
1498       }*/
1499       // NPAL19389 END
1500
1501       QString aListStr = "";
1502       int aNbItems = 0;
1503       if (myTypeId == 0) {
1504         QListIterator<SMESH_Actor*> it( myActorsList );
1505         while ( it.hasNext() ) {
1506           QString tmpStr;
1507           aNbItems += SMESH::GetNameOfSelectedNodes(mySelector, it.next()->getIO(), tmpStr);
1508           aListStr += tmpStr;
1509         }
1510       } else {
1511         QListIterator<SMESH_Actor*> it( myActorsList );
1512         while ( it.hasNext() ) {
1513           QString tmpStr;
1514           aNbItems += SMESH::GetNameOfSelectedElements(mySelector, it.next()->getIO(), tmpStr);
1515           aListStr += tmpStr;
1516         }
1517       }
1518       if (aNbItems > 0) {
1519         QListWidgetItem* anItem;
1520         QList<QListWidgetItem*> listItemsToSel;
1521         QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts);
1522         for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
1523           QList<QListWidgetItem*> found = myElements->findItems(*it, Qt::MatchExactly);
1524           foreach(anItem, found)
1525             if (!anItem->isSelected())
1526               listItemsToSel.push_back(anItem);
1527         }
1528         bool blocked = myElements->signalsBlocked();
1529         myElements->blockSignals(true);
1530         foreach(anItem, listItemsToSel) anItem->setSelected(true);
1531         myElements->blockSignals(blocked);
1532         onListSelectionChanged();
1533         listItemsToSel.clear();
1534       }
1535     }
1536   }
1537   
1538   if (myActorsList.count() == 0) {
1539     if (!myGroup->_is_nil()) {
1540       SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup);
1541       if ( anActor )
1542         myActorsList.append( anActor  );
1543     }
1544     else if(!myGroupOnGeom->_is_nil()) {
1545       SMESH_Actor* anActor = SMESH::FindActorByObject(myGroupOnGeom);
1546       if ( anActor )
1547         myActorsList.append( anActor );
1548     }
1549     else {
1550       SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh );
1551       if ( anActor )
1552         myActorsList.append( anActor );
1553     }
1554   }
1555
1556   // somehow, if we display the mesh, while selecting from another actor,
1557   // the mesh becomes pickable, and there is no way to select any element
1558   if (myActorsList.count() > 0) {
1559     QListIterator<SMESH_Actor*> it( myActorsList );
1560     while ( it.hasNext() ) {
1561       SMESH_Actor* anActor = it.next();
1562       if ( IsActorVisible(anActor) )
1563         anActor->SetPickable(true);
1564     }
1565   }
1566
1567   myIsBusy = false;
1568 }
1569
1570 //=================================================================================
1571 // function : onSelectAll()
1572 // purpose  : Called when "Select all" is checked
1573 //=================================================================================
1574 void SMESHGUI_GroupDlg::onSelectAll()
1575 {
1576   bool noElemsModif = ( mySelectAll->isChecked() || !myAllowElemsModif->isChecked() );
1577
1578   myElementsLab->setEnabled( !noElemsModif );
1579   myElements->setEnabled   ( !noElemsModif );
1580   myFilterBtn->setEnabled  ( !noElemsModif );
1581   myAddBtn->setEnabled     ( !noElemsModif );
1582   myRemoveBtn->setEnabled  ( !noElemsModif );
1583   mySortBtn->setEnabled    ( !noElemsModif );
1584   mySelectBox->setEnabled  ( !noElemsModif );
1585   myAllowElemsModif->setEnabled( !mySelectAll->isChecked() );
1586   if ( noElemsModif ) mySMESHGUI->ResetState();
1587   else                mySMESHGUI->SetState(800);
1588
1589   int selMode     = mySelectionMode;
1590   mySelectionMode = grpNoSelection;
1591   setSelectionMode( selMode );
1592   updateButtons();
1593 }
1594
1595 //=================================================================================
1596 // function : onSelectSubMesh()
1597 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
1598 //=================================================================================
1599 void SMESHGUI_GroupDlg::onSelectSubMesh(bool on)
1600 {
1601   if (on) {
1602     if (mySelectGroup->isChecked()) {
1603       mySelectGroup->setChecked(false);
1604     }
1605     //VSR: else if (mySelectGeomGroup->isChecked()) {
1606     //VSR:   mySelectGeomGroup->setChecked(false);
1607     //VSR: }
1608     myCurrentLineEdit = mySubMeshLine;
1609     setSelectionMode(grpSubMeshSelection);
1610   }
1611   else {
1612     mySubMeshLine->setText( "" );
1613     myCurrentLineEdit = 0;
1614     if (myTypeId != -1)
1615       setSelectionMode(myTypeId);
1616   }
1617   mySubMeshBtn->setEnabled(on);
1618   mySubMeshLine->setEnabled(on);
1619 }
1620
1621
1622 //=================================================================================
1623 // function : (onSelectGroup)
1624 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
1625 //=================================================================================
1626 void SMESHGUI_GroupDlg::onSelectGroup(bool on)
1627 {
1628   if (on) {
1629     if (mySelectSubMesh->isChecked()) {
1630       mySelectSubMesh->setChecked(false);
1631     }
1632     myCurrentLineEdit = myGroupLine;
1633     setSelectionMode(grpGroupSelection);
1634   }
1635   else {
1636     myGroupLine->setText( "" );
1637     myCurrentLineEdit = 0;
1638     if (myTypeId != -1)
1639       setSelectionMode(myTypeId);
1640   }
1641   myGroupBtn->setEnabled(on);
1642   myGroupLine->setEnabled(on);
1643 }
1644
1645
1646 //=================================================================================
1647 // function : (onSelectGeomGroup)
1648 // purpose  : Called when group type changed. on == "on geometry" or "on filter"
1649 //=================================================================================
1650 void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
1651 {
1652   if (on) {
1653     if (mySelectSubMesh->isChecked()) {
1654       mySelectSubMesh->setChecked(false);
1655     }
1656     else if (mySelectGroup->isChecked()) {
1657       mySelectGroup->setChecked(false);
1658     }
1659     if ( myGrpTypeId == 1 ) { // on geometry
1660       myCurrentLineEdit = myGeomGroupLine;
1661       updateGeomPopup();
1662     }
1663     else { // on filter
1664       myCurrentLineEdit = 0;
1665     }
1666     setSelectionMode(grpAllSelection);
1667   }
1668   else {
1669     myGeomGroupBtn->setChecked(false);
1670     myGeomObjects->length(0);
1671     myGeomGroupLine->setText( "" );
1672     myCurrentLineEdit = 0;
1673     if (myTypeId != -1)
1674       setSelectionMode( myTypeId );
1675   }
1676 }
1677
1678 //=================================================================================
1679 // function : setCurrentSelection()
1680 // purpose  :
1681 //=================================================================================
1682 void SMESHGUI_GroupDlg::setCurrentSelection()
1683 {
1684   QPushButton* send = (QPushButton*)sender();
1685   myCurrentLineEdit = 0;
1686   if (send == myMeshGroupBtn) {
1687     disconnect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
1688     mySelectionMgr->clearSelected();
1689     if (myCreate)
1690       setSelectionMode(grpMeshSelection);
1691     else
1692       setSelectionMode(grpGroupSelection);
1693     connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
1694     myCurrentLineEdit = myMeshGroupLine;
1695     onObjectSelectionChanged();
1696   }
1697   else if (send == mySubMeshBtn) {
1698     myCurrentLineEdit = mySubMeshLine;
1699     onObjectSelectionChanged();
1700   }
1701   else if (send == myGroupBtn) {
1702     myCurrentLineEdit = myGroupLine;
1703     onObjectSelectionChanged();
1704   }
1705 }
1706
1707
1708 //=================================================================================
1709 // function : setFilters()
1710 // purpose  : SLOT. Called when "Filter" button pressed.
1711 //=================================================================================
1712 void SMESHGUI_GroupDlg::setFilters()
1713 {
1714   if(myMesh->_is_nil()) {
1715     SUIT_MessageBox::critical(this,
1716                               tr("SMESH_ERROR"),
1717                               tr("NO_MESH_SELECTED"));
1718    return;
1719   }
1720
1721   SMESH::ElementType aType = SMESH::ALL;
1722   switch ( myTypeId )
1723   {
1724     case grpNodeSelection:   aType = SMESH::NODE;   break;
1725     case grp0DSelection:     aType = SMESH::ELEM0D; break;
1726     case grpBallSelection:   aType = SMESH::BALL;   break;
1727     case grpEdgeSelection:   aType = SMESH::EDGE;   break;
1728     case grpFaceSelection:   aType = SMESH::FACE;   break;
1729     case grpVolumeSelection: aType = SMESH::VOLUME; break;
1730     default:                 return;
1731   }
1732
1733   if ( myFilterDlg == 0 )
1734   {
1735     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, aType );
1736     connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) );
1737   }
1738   else
1739     myFilterDlg->Init( aType );
1740
1741   if ( !myGroupOnFilter->_is_nil() )
1742   {
1743     myFilterDlg->SetFilter( myFilter, aType );
1744     myFilterDlg->Init( aType );
1745   }
1746
1747   bool isStandalone = ( sender() == myFilterBtn );
1748   myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone,
1749                            /*diffSources=*/isStandalone );
1750   myFilterDlg->SetMesh( myMesh );
1751   myFilterDlg->SetGroup( myGroupOnFilter );
1752   myFilterDlg->SetSelection();
1753   myFilterDlg->SetSourceWg( myElements, false );
1754
1755   myFilterDlg->show();
1756 }
1757
1758 //=================================================================================
1759 // function : onFilterAccepted()
1760 // purpose  : SLOT. Called when Filter dlg closed with OK button.
1761 //            Uncheck "Select submesh" and "Select group" checkboxes
1762 //=================================================================================
1763 void SMESHGUI_GroupDlg::onFilterAccepted()
1764 {
1765   if ( mySelectSubMesh->isChecked() || mySelectGroup->isChecked() )
1766   {
1767     mySelectionMode = myTypeId;
1768     mySelectSubMesh->setChecked( false );
1769     mySelectGroup->setChecked( false );
1770   }
1771   // get a filter from myFilterDlg
1772   myFilter = myFilterDlg->GetFilter();
1773   if ( !myFilter->_is_nil() ) {
1774     SMESH::Predicate_var perdicate = myFilter->GetPredicate();
1775     if ( perdicate->_is_nil() )
1776       myFilter = SMESH::Filter::_nil();
1777   }
1778   // set mesh to myFilter
1779   if ( !myFilter->_is_nil() ) {
1780     SMESH::SMESH_Mesh_var mesh = myMesh;
1781     if ( mesh->_is_nil() ) {
1782       if ( !myGroup->_is_nil() )
1783         mesh = myGroup->GetMesh();
1784       else if ( !myGroupOnGeom->_is_nil() )
1785         mesh = myGroupOnGeom->GetMesh();
1786       else if ( !myGroupOnFilter->_is_nil() )
1787         mesh = myGroupOnFilter->GetMesh();
1788     }
1789     myFilter->SetMesh( mesh );
1790
1791     // highlight ids if selection changed in the Viewer (IPAL52924)
1792     myCurrentLineEdit = 0;
1793     onObjectSelectionChanged();
1794   }
1795
1796   updateButtons();
1797 }
1798
1799 //=================================================================================
1800 // function : onAdd()
1801 // purpose  :
1802 //=================================================================================
1803 void SMESHGUI_GroupDlg::onAdd()
1804 {
1805   SALOME_ListIO aList;
1806   mySelectionMgr->selectedObjects( aList );
1807
1808   int aNbSel = aList.Extent();
1809
1810   if (aNbSel == 0 || myActorsList.count() == 0 || myMesh->_is_nil()) return;
1811
1812   SUIT_OverrideCursor wc;
1813
1814   myIsBusy = true;
1815   int sizeBefore = myElements->count();
1816
1817   SMESH::ElementType aType = SMESH::ALL;
1818   switch(myTypeId) {
1819   case grpNodeSelection:
1820     aType = SMESH::NODE;
1821     mySelector->SetSelectionMode(NodeSelection);
1822     break;
1823   case grpBallSelection:
1824     aType = SMESH::BALL;
1825     mySelector->SetSelectionMode(BallSelection);
1826     break;
1827   case grp0DSelection:
1828     aType = SMESH::ELEM0D;
1829     mySelector->SetSelectionMode(Elem0DSelection);
1830     break;
1831   case grpEdgeSelection:
1832     aType = SMESH::EDGE;
1833     mySelector->SetSelectionMode(EdgeSelection);
1834     break;
1835   case grpFaceSelection:
1836     aType = SMESH::FACE;
1837     mySelector->SetSelectionMode(FaceSelection);
1838     break;
1839   case grpVolumeSelection:
1840     aType = SMESH::VOLUME;
1841     mySelector->SetSelectionMode(VolumeSelection);
1842     break;
1843   default:
1844     mySelector->SetSelectionMode(ActorSelection);
1845   }
1846
1847   QListWidgetItem* anItem = 0;
1848   QList<QListWidgetItem*> listItemsToSel;
1849
1850   if ( myCurrentLineEdit == 0 )
1851   {
1852     //if (aNbSel != 1) { myIsBusy = false; return; }
1853     QString aListStr = "";
1854     int aNbItems = 0;
1855     if (myTypeId == 0) {
1856       QListIterator<SMESH_Actor*> it( myActorsList );
1857       while ( it.hasNext() ) {
1858         QString tmpStr;
1859         aNbItems += SMESH::GetNameOfSelectedNodes(mySelector, it.next()->getIO(), tmpStr);
1860         aListStr += tmpStr;
1861       }
1862     }
1863     else {
1864       QListIterator<SMESH_Actor*> it( myActorsList );
1865       while ( it.hasNext() ) {
1866         QString tmpStr;
1867         aNbItems += SMESH::GetNameOfSelectedElements(mySelector, it.next()->getIO(), tmpStr);
1868         aListStr += tmpStr;
1869       }
1870     }
1871     if (aNbItems > 0) {
1872       QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts);
1873       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
1874         QList<QListWidgetItem*> found = myElements->findItems(*it, Qt::MatchExactly);
1875         if (found.count() == 0) {
1876           anItem = new QListWidgetItem(*it);
1877           myElements->addItem(anItem);
1878           if (!anItem->isSelected())
1879             listItemsToSel.push_back(anItem);
1880         }
1881         else {
1882           foreach(anItem, found)
1883             if (!anItem->isSelected())
1884               listItemsToSel.push_back(anItem);
1885         }
1886       }
1887       bool blocked = myElements->signalsBlocked();
1888       myElements->blockSignals(true);
1889       foreach(anItem, listItemsToSel) anItem->setSelected(true);
1890       myElements->blockSignals(blocked);
1891       onListSelectionChanged();
1892       listItemsToSel.clear();
1893     }
1894   }
1895   else if ( myCurrentLineEdit == mySubMeshLine )
1896   {
1897     //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
1898
1899     SALOME_ListIO aList;
1900     mySelectionMgr->selectedObjects( aList );
1901
1902     SALOME_ListIteratorOfListIO anIt (aList);
1903     for ( ; anIt.More(); anIt.Next()) {
1904       SMESH::SMESH_subMesh_var aSubMesh =
1905         SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
1906       if (!aSubMesh->_is_nil()) {
1907         // check if mesh is the same
1908         if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
1909           try {
1910             SMESH::smIdType_array_var anElements = aSubMesh->GetElementsByType(aType);
1911             int k = anElements->length();
1912             for (int i = 0; i < k; i++) {
1913               QString aText = QString::number(anElements[i]);
1914               QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
1915               if (found.count() == 0) {
1916                 anItem = new QListWidgetItem(aText);
1917                 myElements->addItem(anItem);
1918                 if (!anItem->isSelected())
1919                   listItemsToSel.push_back(anItem);
1920               }
1921               else {
1922                 foreach(anItem, found)
1923                   if (!anItem->isSelected())
1924                     listItemsToSel.push_back(anItem);
1925               }
1926             }
1927             bool blocked = myElements->signalsBlocked();
1928             myElements->blockSignals(true);
1929             foreach(anItem, listItemsToSel) anItem->setSelected(true);
1930             myElements->blockSignals(blocked);
1931             onListSelectionChanged();
1932             listItemsToSel.clear();
1933           }
1934           catch (const SALOME::SALOME_Exception& ex) {
1935             SalomeApp_Tools::QtCatchCorbaException(ex);
1936           }
1937         }
1938       }
1939     }
1940     mySelectSubMesh->setChecked(false);
1941     myIsBusy = false;
1942     onListSelectionChanged();
1943
1944   }
1945   else if ( myCurrentLineEdit == myGroupLine )
1946   {
1947     //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
1948     SALOME_ListIO aList;
1949     mySelectionMgr->selectedObjects( aList );
1950
1951     SALOME_ListIteratorOfListIO anIt (aList);
1952     for ( ; anIt.More(); anIt.Next()) {
1953       SMESH::SMESH_GroupBase_var aGroup =
1954         SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIt.Value());
1955       if (!aGroup->_is_nil()) {
1956         // check if mesh is the same
1957         if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
1958           SMESH::smIdType_array_var anElements = aGroup->GetListOfID();
1959           int k = anElements->length();
1960           for (int i = 0; i < k; i++) {
1961             QString aText = QString::number(anElements[i]);
1962             QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
1963             if (found.count() == 0) {
1964               anItem = new QListWidgetItem(aText);
1965               myElements->addItem(anItem);
1966               if (!anItem->isSelected())
1967                 listItemsToSel.push_back(anItem);
1968             }
1969             else {
1970               foreach(anItem, found)
1971                 if (!anItem->isSelected())
1972                   listItemsToSel.push_back(anItem);
1973             }
1974           }
1975           bool blocked = myElements->signalsBlocked();
1976           myElements->blockSignals(true);
1977           foreach(anItem, listItemsToSel) anItem->setSelected(true);
1978           myElements->blockSignals(blocked);
1979           onListSelectionChanged();
1980           listItemsToSel.clear();
1981         }
1982       }
1983     }
1984     mySelectGroup->setChecked(false);
1985     myIsBusy = false;
1986     onListSelectionChanged();
1987
1988   }
1989   else if ( myCurrentLineEdit == myGeomGroupLine && myGeomObjects->length() == 1 )
1990   {
1991     GEOM::GEOM_IGroupOperations_wrap aGroupOp =
1992       SMESH::GetGEOMGen( myGeomObjects[0] )->GetIGroupOperations();
1993
1994     SMESH::ElementType aGroupType = SMESH::ALL;
1995     switch(aGroupOp->GetType(myGeomObjects[0])) {
1996     case TopAbs_VERTEX: aGroupType = SMESH::NODE; break;
1997     case TopAbs_EDGE:   aGroupType = SMESH::EDGE; break;
1998     case TopAbs_FACE:   aGroupType = SMESH::FACE; break;
1999     case TopAbs_SOLID:  aGroupType = SMESH::VOLUME; break;
2000     default: myIsBusy = false; return;
2001     }
2002
2003     if (aGroupType == aType) {
2004       _PTR(SObject) aGroupSO =
2005         //SMESH::getStudy()->FindObjectIOR(SMESH::getStudy()->ConvertObjectToIOR(myGeomGroup));
2006         SMESH::getStudy()->FindObjectID(myGeomObjects[0]->GetStudyEntry());
2007       // Construct filter
2008       SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
2009       SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
2010       SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();
2011       aBelongToGeom->SetGeom(myGeomObjects[0]);
2012       aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str());
2013       aBelongToGeom->SetElementType(aType);
2014       aFilter->SetPredicate(aBelongToGeom);
2015
2016       SMESH::smIdType_array_var anElements = aFilter->GetElementsId(myMesh);
2017
2018       int k = anElements->length();
2019       for (int i = 0; i < k; i++) {
2020         QString aText = QString::number(anElements[i]);
2021         QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
2022         if (found.count() == 0) {
2023           anItem = new QListWidgetItem(aText);
2024           myElements->addItem(anItem);
2025           if (!anItem->isSelected())
2026             listItemsToSel.push_back(anItem);
2027         }
2028         else {
2029           foreach(anItem, found)
2030             if (!anItem->isSelected())
2031               listItemsToSel.push_back(anItem);
2032         }
2033       }
2034       bool blocked = myElements->signalsBlocked();
2035       myElements->blockSignals(true);
2036       foreach(anItem, listItemsToSel) anItem->setSelected(true);
2037       myElements->blockSignals(blocked);
2038       onListSelectionChanged();
2039       listItemsToSel.clear();
2040     }
2041
2042     //VSR: mySelectGeomGroup->setChecked(false);
2043     myIsBusy = false;
2044     onListSelectionChanged();
2045   }
2046   myIsBusy = false;
2047   if ( sizeBefore < myElements->count() )
2048     ++myNbChangesOfContents;
2049   //  mySelectionMgr->clearSelected();
2050   updateButtons();
2051 }
2052
2053 //=================================================================================
2054 // function : onRemove()
2055 // purpose  :
2056 //=================================================================================
2057 void SMESHGUI_GroupDlg::onRemove()
2058 {
2059   myIsBusy = true;
2060   int sizeBefore = myElements->count();
2061
2062   if (myCurrentLineEdit == 0) {
2063     QList<QListWidgetItem*> selItems = myElements->selectedItems();
2064     QListWidgetItem* item;
2065     foreach(item, selItems) delete item;
2066   } else {
2067     SALOME_ListIO aList;
2068     mySelectionMgr->selectedObjects( aList );
2069
2070     int aNbSel = aList.Extent();
2071
2072     if (aNbSel == 0) { myIsBusy = false; return; }
2073
2074     SMESH::ElementType aType = SMESH::ALL;
2075     switch(myTypeId) {
2076     case grpNodeSelection:   aType = SMESH::NODE;   break;
2077     case grp0DSelection:     aType = SMESH::ELEM0D; break;
2078     case grpBallSelection:   aType = SMESH::BALL;   break;
2079     case grpEdgeSelection:   aType = SMESH::EDGE;   break;
2080     case grpFaceSelection:   aType = SMESH::FACE;   break;
2081     case grpVolumeSelection: aType = SMESH::VOLUME; break;
2082     }
2083
2084     if (myCurrentLineEdit == mySubMeshLine) {
2085       //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
2086       SALOME_ListIO aList;
2087       mySelectionMgr->selectedObjects( aList );
2088
2089       SALOME_ListIteratorOfListIO anIt (aList);
2090       for ( ; anIt.More(); anIt.Next()) {
2091         SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
2092         if (!aSubMesh->_is_nil()) {
2093           // check if mesh is the same
2094           if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
2095             if (aType == SMESH::NODE) {
2096               try {
2097                 SMESH::smIdType_array_var anElements = aSubMesh->GetNodesId();
2098                 int k = anElements->length();
2099                 for (int i = 0; i < k; i++) {
2100                   QList<QListWidgetItem*> found = 
2101                     myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
2102                   QListWidgetItem* anItem;
2103                   foreach(anItem, found) delete anItem;
2104                 }
2105               }
2106               catch (const SALOME::SALOME_Exception& ex) {
2107                 SalomeApp_Tools::QtCatchCorbaException(ex);
2108               }
2109             }
2110             else {
2111               try {
2112                 SMESH::smIdType_array_var anElements = aSubMesh->GetElementsId();
2113                 int k = anElements->length();
2114                 for (int i = 0; i < k; i++) {
2115                   QList<QListWidgetItem*> found = 
2116                     myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
2117                   QListWidgetItem* anItem;
2118                   foreach(anItem, found) delete anItem;
2119                 }
2120               }
2121               catch (const SALOME::SALOME_Exception& ex) {
2122                 SalomeApp_Tools::QtCatchCorbaException(ex);
2123               }
2124             }
2125           }
2126         }
2127       }
2128     }
2129     else if (myCurrentLineEdit == myGroupLine) {
2130       SALOME_ListIO aList;
2131       mySelectionMgr->selectedObjects( aList );
2132
2133       SALOME_ListIteratorOfListIO anIt (aList);
2134       for ( ; anIt.More(); anIt.Next()) {
2135         SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
2136         if (!aGroup->_is_nil()) {
2137           // check if mesh is the same
2138           if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
2139             SMESH::smIdType_array_var anElements = aGroup->GetListOfID();
2140             int k = anElements->length();
2141             for (int i = 0; i < k; i++) {
2142               QList<QListWidgetItem*> found = 
2143                 myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
2144               QListWidgetItem* anItem;
2145               foreach(anItem, found) delete anItem;
2146             }
2147           }
2148         }
2149       }
2150     }
2151   }
2152   myIsBusy = false;
2153   if ( sizeBefore > myElements->count() )
2154     myNbChangesOfContents += 2; // it's used to detect that "Add" was only once
2155   updateButtons();
2156 }
2157
2158 //=================================================================================
2159 // function : onSort()
2160 // purpose  :
2161 //=================================================================================
2162 void SMESHGUI_GroupDlg::onSort()
2163 {
2164   // PAL5412: sorts items in ascending by "string" value
2165   // myElements->sort(true);
2166   // myElements->update();
2167   vtkIdType i, k = myElements->count();
2168   if (k > 0) {
2169     myIsBusy = true;
2170     QList<vtkIdType> aSelected;
2171     std::vector<vtkIdType> anArray(k);
2172     //    QMemArray<int> anArray(k);
2173     // fill the array
2174     for (i = 0; i < k; i++) {
2175       vtkIdType id;
2176       if (sizeof(vtkIdType)==8)
2177         id = myElements->item(i)->text().toLongLong();
2178       else
2179         id = myElements->item(i)->text().toInt();
2180       anArray[i] = id;
2181       if (myElements->item(i)->isSelected())
2182         aSelected.append(id);
2183     }
2184     // sort & update list
2185     std::sort(anArray.begin(), anArray.end());
2186     //    anArray.sort();
2187     myElements->clear();
2188     QListWidgetItem* anItem;
2189     QList<QListWidgetItem*> listItemsToSel;
2190     for (i = 0; i < k; i++) {
2191       anItem = new QListWidgetItem(QString::number(anArray[i]));
2192       myElements->addItem(anItem);
2193       if (aSelected.contains(anArray[i]))
2194         listItemsToSel.push_back(anItem);
2195     }
2196     bool blocked = myElements->signalsBlocked();
2197     myElements->blockSignals(true);
2198     foreach(anItem, listItemsToSel) anItem->setSelected(true);
2199     myElements->blockSignals(blocked);
2200     listItemsToSel.clear();
2201     myIsBusy = false;
2202   }
2203 }
2204
2205 //=================================================================================
2206 // function : onVisibilityChanged()
2207 // purpose  :
2208 //=================================================================================
2209 void SMESHGUI_GroupDlg::onVisibilityChanged()
2210 {
2211   SetAppropriateActor();
2212 }
2213
2214 //=================================================================================
2215 // function : SMESHGUI_GroupDlg::reject
2216 // purpose  : SLOT called when "Close" button pressed. Close dialog
2217 //=================================================================================
2218 void SMESHGUI_GroupDlg::reject()
2219 {
2220   if (SMESH::GetCurrentVtkView()) {
2221     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
2222     SMESH::SetPointRepresentation(false);
2223     SMESH::SetPickable();
2224     restoreShowEntityMode();
2225   }
2226
2227   if( isApplyAndClose() && !myObjectToSelect.isEmpty() ) {
2228     SUIT_DataOwnerPtrList aList;
2229     aList.append( new LightApp_DataOwner( myObjectToSelect ) );
2230     mySelectionMgr->setSelected( aList );
2231   }
2232   else
2233     mySelectionMgr->clearSelected();
2234   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2235     aViewWindow->SetSelectionMode(ActorSelection);
2236   mySelectionMgr->clearFilters();
2237   mySMESHGUI->ResetState();
2238
2239   QDialog::reject();
2240
2241   if ( myFilterDlg ) myFilterDlg->UnRegisterFilters();
2242 }
2243
2244 //=================================================================================
2245 // function : onOpenView()
2246 // purpose  :
2247 //=================================================================================
2248 void SMESHGUI_GroupDlg::onOpenView()
2249 {
2250   if ( mySelector ) {
2251     SMESH::SetPointRepresentation(false);
2252   }
2253   else {
2254     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
2255     mySMESHGUI->EmitSignalDeactivateDialog();
2256     setEnabled(true);
2257   }
2258 }
2259
2260 //=================================================================================
2261 // function : onCloseView()
2262 // purpose  :
2263 //=================================================================================
2264 void SMESHGUI_GroupDlg::onCloseView()
2265 {
2266   onDeactivate();
2267   mySelector = 0;
2268 }
2269
2270 //=================================================================================
2271 // function : onHelp()
2272 // purpose  :
2273 //=================================================================================
2274 void SMESHGUI_GroupDlg::onHelp()
2275 {
2276   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
2277   if (app)
2278   {
2279     app->onHelpContextModule
2280       ( mySMESHGUI ? app->moduleName( mySMESHGUI->moduleName() ) : QString(""), myHelpFileName );
2281   }
2282   else
2283   {
2284 #ifdef WIN32
2285     QString platform = "winapplication";
2286 #else
2287     QString platform = "application";
2288 #endif
2289     SUIT_MessageBox::warning(this, tr( "WRN_WARNING" ),
2290                              tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
2291                              arg(app->resourceMgr()->stringValue( "ExternalBrowser", platform)).
2292                              arg(myHelpFileName));
2293   }
2294 }
2295
2296 //=================================================================================
2297 // function : SMESHGUI_GroupDlg::onDeactivate
2298 // purpose  : SLOT called when dialog must be deactivated
2299 //=================================================================================
2300 void SMESHGUI_GroupDlg::onDeactivate()
2301 {
2302   mySMESHGUI->ResetState();
2303   setEnabled(false);
2304 }
2305
2306 //=================================================================================
2307 // function : SMESHGUI_GroupDlg::enterEvent
2308 // purpose  : Event filter
2309 //=================================================================================
2310 void SMESHGUI_GroupDlg::enterEvent (QEvent*)
2311 {
2312   if (!isEnabled()) {
2313     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
2314     if ( aViewWindow && !mySelector) {
2315       mySelector = aViewWindow->GetSelector();
2316     }
2317     mySMESHGUI->EmitSignalDeactivateDialog();
2318     setEnabled(true);
2319     mySelectionMode = grpNoSelection;
2320     setSelectionMode(myTypeId);
2321     mySMESHGUI->SetActiveDialogBox(this);
2322     if ( mySelectBox->isEnabled() ) mySMESHGUI->SetState(800);
2323     else                            mySMESHGUI->ResetState();
2324   }
2325 }
2326
2327 //=================================================================================
2328 // function : keyPressEvent()
2329 // purpose  :
2330 //=================================================================================
2331 void SMESHGUI_GroupDlg::keyPressEvent( QKeyEvent* e )
2332 {
2333   QDialog::keyPressEvent( e );
2334   if ( e->isAccepted() )
2335     return;
2336
2337   if ( e->key() == Qt::Key_F1 )
2338   {
2339     e->accept();
2340     onHelp();
2341   }
2342 }
2343
2344 //================================================================================
2345 /*!
2346  * \brief Enable showing of the popup when Geometry selection btn is clicked
2347  * \param enable - true to enable
2348  */
2349 //================================================================================
2350
2351 enum { DIRECT_GEOM_INDEX = 0, GEOM_BY_MESH_INDEX };
2352
2353 void SMESHGUI_GroupDlg::updateGeomPopup()
2354 {
2355   bool enable = false;
2356
2357   if ( !myMesh->_is_nil() )
2358     enable = myMesh->NbEdges() > 0;
2359
2360   if ( myGeomGroupBtn )
2361   {
2362     disconnect( myGeomGroupBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
2363     if ( enable ) {
2364       if ( !myGeomPopup ) {
2365         myGeomPopup = new QMenu(this);
2366         myActions[myGeomPopup->addAction( tr( "DIRECT_GEOM_SELECTION" ) )] = DIRECT_GEOM_INDEX;
2367         myActions[myGeomPopup->addAction( tr( "GEOM_BY_MESH_ELEM_SELECTION" ) )] = GEOM_BY_MESH_INDEX;
2368         connect( myGeomPopup, SIGNAL( triggered( QAction* ) ), SLOT( onGeomPopup( QAction* ) ) );
2369       }
2370       connect( myGeomGroupBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
2371     }
2372   }
2373 }
2374
2375
2376 //=================================================================================
2377 // function : onGeomSelectionButton()
2378 // purpose  :
2379 //=================================================================================
2380 void SMESHGUI_GroupDlg::onGeomSelectionButton(bool isBtnOn)
2381 {
2382   if ( myGeomPopup && isBtnOn )
2383   {
2384     myCurrentLineEdit = myGeomGroupLine;
2385     QAction* a = myGeomPopup->exec( QCursor::pos() );
2386     if (!a || myActions[a] == DIRECT_GEOM_INDEX)
2387       setSelectionMode(grpGeomSelection);
2388   }
2389   else if (!isBtnOn)
2390   {
2391     myCurrentLineEdit = 0;
2392     setSelectionMode(grpAllSelection);
2393   }
2394 }
2395
2396 //=================================================================================
2397 // function : onGeomPopup()
2398 // purpose  :
2399 //=================================================================================
2400 void SMESHGUI_GroupDlg::onGeomPopup( QAction* a )
2401 {
2402   int index = myActions[a];
2403   if ( index == GEOM_BY_MESH_INDEX )
2404   {
2405     mySelectionMode = grpNoSelection;
2406     if ( !myShapeByMeshOp ) {
2407       myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true);
2408       connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)),
2409               SLOT(onPublishShapeByMeshDlg(SUIT_Operation*)));
2410       connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)),
2411               SLOT(onCloseShapeByMeshDlg(SUIT_Operation*)));
2412     }
2413     // set mesh object to SMESHGUI_ShapeByMeshOp and start it
2414     if ( !myMesh->_is_nil() ) {
2415       myIsBusy = true;
2416       hide(); // stop processing selection
2417       myIsBusy = false;
2418       myShapeByMeshOp->setModule( mySMESHGUI );
2419       myShapeByMeshOp->setStudy( 0 ); // it's really necessary
2420       myShapeByMeshOp->SetMesh( myMesh );
2421       myShapeByMeshOp->start();
2422     }
2423   }
2424 }
2425
2426 //================================================================================
2427 /*!
2428  * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg
2429  */
2430 //================================================================================
2431
2432 void SMESHGUI_GroupDlg::onPublishShapeByMeshDlg(SUIT_Operation* op)
2433 {
2434   if ( myShapeByMeshOp == op ) {
2435     mySMESHGUI->getApp()->updateObjectBrowser();
2436     show();
2437     // Select a found geometry object
2438     GEOM::GEOM_Object_var aGeomVar = myShapeByMeshOp->GetShape();
2439     if ( !aGeomVar->_is_nil() )
2440     {
2441       QString ID = aGeomVar->GetStudyEntry();
2442       if ( _PTR(SObject) aGeomSO = SMESH::getStudy()->FindObjectID( ID.toLatin1().data() )) {
2443         SALOME_ListIO anIOList;
2444         Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
2445           ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() );
2446         anIOList.Append( anIO );
2447         mySelectionMgr->setSelectedObjects( anIOList, false );
2448         onObjectSelectionChanged();
2449       }
2450     }
2451   }
2452 }
2453
2454 //================================================================================
2455 /*!
2456  * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg
2457  */
2458 //================================================================================
2459
2460 void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op)
2461 {
2462   if ( myShapeByMeshOp == op )
2463   {
2464     show();
2465     setSelectionMode(grpGeomSelection);
2466   }
2467 }
2468
2469 //=================================================================================
2470 // function : setGroupColor()
2471 // purpose  :
2472 //=================================================================================
2473 void SMESHGUI_GroupDlg::setGroupColor( const SALOMEDS::Color& theColor )
2474 {
2475   QColor aQColor( (int)( theColor.R * 255.0 ),
2476                   (int)( theColor.G * 255.0 ),
2477                   (int)( theColor.B * 255.0 ) );
2478   setGroupQColor( aQColor );
2479 }
2480
2481 //=================================================================================
2482 // function : getGroupColor()
2483 // purpose  :
2484 //=================================================================================
2485 SALOMEDS::Color SMESHGUI_GroupDlg::getGroupColor() const
2486 {
2487   QColor aQColor = getGroupQColor();
2488
2489   SALOMEDS::Color aColor;
2490   aColor.R = (float)aQColor.red() / 255.0;
2491   aColor.G = (float)aQColor.green() / 255.0;
2492   aColor.B = (float)aQColor.blue() / 255.0;
2493
2494   return aColor;
2495 }
2496
2497 //=================================================================================
2498 // function : setGroupQColor()
2499 // purpose  :
2500 //=================================================================================
2501 void SMESHGUI_GroupDlg::setGroupQColor( const QColor& theColor )
2502 {
2503   if( theColor.isValid() )
2504     myColorBtn->setColor( theColor );
2505 }
2506
2507 //=================================================================================
2508 // function : getGroupQColor()
2509 // purpose  :
2510 //=================================================================================
2511 QColor SMESHGUI_GroupDlg::getGroupQColor() const
2512 {
2513   return myColorBtn->color();
2514 }
2515
2516 //=================================================================================
2517 // function : setDefaultGroupColor()
2518 // purpose  :
2519 //=================================================================================
2520 void SMESHGUI_GroupDlg::setDefaultGroupColor()
2521 {
2522   if( myMesh->_is_nil() )
2523     return;
2524
2525   bool isAutoColor = myMesh->GetAutoColor();
2526
2527   QColor aQColor = myColorBtn->color();
2528   if( !isAutoColor )
2529   {
2530     if ( !aQColor.isValid() ) {
2531       int r = 0, g = 0, b = 0;
2532       SMESH::GetColor( "SMESH", "default_grp_color", r, g, b, QColor( 255, 170, 0 ) );
2533       aQColor.setRgb( r, g, b );
2534     }
2535   }
2536   else
2537   {
2538 #ifdef SIMPLE_AUTOCOLOR   // simplified algorithm for auto-colors
2539     SALOMEDS::Color aColor = SMESHGUI::getPredefinedUniqueColor();
2540 #else                     // old algorithm  for auto-colors
2541     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
2542
2543     QList<SALOMEDS::Color> aReservedColors;
2544     for( int i = 0, n = aListOfGroups.length(); i < n; i++ )
2545     {
2546       SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i];
2547       SALOMEDS::Color aReservedColor = aGroupObject->GetColor();
2548       aReservedColors.append( aReservedColor );
2549     }
2550
2551     SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
2552 #endif                    // SIMPLE_AUTOCOLOR
2553
2554     aQColor.setRgb( (int)( aColor.R * 255.0 ),
2555                     (int)( aColor.G * 255.0 ),
2556                     (int)( aColor.B * 255.0 ) );
2557
2558   }
2559
2560   setGroupQColor( aQColor );
2561 }
2562
2563 //=================================================================================
2564 // function : SetAppropriateActor()
2565 // purpose  : Find more appropriate of visible actors, set it to myActor, allow picking
2566 //            NPAL19389: create a group with a selection in another group.
2567 //            if mesh actor is not visible - find any first visible group or sub-mesh
2568 //=================================================================================
2569 bool SMESHGUI_GroupDlg::SetAppropriateActor()
2570 {
2571   bool isActor = false;
2572   myActorsList.clear();
2573
2574   if (myMesh->_is_nil()) return false;
2575
2576   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
2577
2578   if (myGrpTypeGroup->checkedId() > 0) {   // try current group on geometry actor
2579     SMESH_Actor* anActor = 0;
2580     if (!myGroupOnGeom->_is_nil())
2581       anActor = SMESH::FindActorByObject(myGroupOnGeom);
2582     if (!myGroupOnFilter->_is_nil())
2583       anActor = SMESH::FindActorByObject(myGroupOnFilter);
2584     if (anActor && anActor->hasIO())
2585     {
2586       isActor = true;
2587       if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
2588         isActor = false;
2589       else
2590         myActorsList.append(anActor);
2591     }
2592     return anActor;
2593   }
2594   else {
2595     // try mesh actor
2596     SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
2597     if (anActor && anActor->hasIO()) {
2598       isActor = true;
2599       if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
2600         isActor = false;
2601       else
2602         myActorsList.append(anActor);
2603     }
2604
2605     // try group actor
2606     SMESH_Actor* aGroupActor = 0;
2607     if (!isActor && !myGroup->_is_nil()) {
2608       aGroupActor = SMESH::FindActorByObject(myGroup);
2609       if (aGroupActor && aGroupActor->hasIO())
2610         myActorsList.append(aGroupActor);
2611     }
2612
2613     // try any visible actor of group or sub-mesh of current mesh
2614     if (aViewWindow) {
2615       // mesh entry
2616       _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
2617       if (aSObject) {
2618         CORBA::String_var meshEntry = aSObject->GetID().c_str();
2619         int len = strlen(meshEntry);
2620
2621         // iterate on all actors in current view window, search for
2622         // any visible actor, that belongs to group or submesh of current mesh
2623         VTK::ActorCollectionCopy aCopy(aViewWindow->getRenderer()->GetActors());
2624         vtkActorCollection *aCollection = aCopy.GetActors();
2625         int nbItems = aCollection->GetNumberOfItems();
2626         for (int i=0; i<nbItems && !isActor; i++)
2627         {
2628           SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(aCollection->GetItemAsObject(i));
2629           if (anActor && anActor->hasIO()) {
2630             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
2631             if (aViewWindow->isVisible(anIO)) {
2632               if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0 && !myActorsList.contains(anActor) )
2633                 myActorsList.append(anActor);
2634             }
2635           }
2636         }
2637       }
2638     }
2639
2640     // Show a standalone group if nothing else is visible (IPAL52227)
2641     if ( myActorsList.count() == 1 &&
2642          myActorsList[0] == aGroupActor &&
2643          aViewWindow && !aViewWindow->isVisible(aGroupActor->getIO()))
2644       SMESH::UpdateView( aViewWindow, SMESH::eDisplay, aGroupActor->getIO()->getEntry() );
2645   }
2646
2647
2648   if (myActorsList.count() > 0) {
2649     QListIterator<SMESH_Actor*> it( myActorsList );
2650     while ( it.hasNext() ) {
2651       SMESH_Actor* anActor = it.next();
2652       if ( IsActorVisible(anActor) )
2653         anActor->SetPickable(true);
2654     }
2655   }
2656
2657   return ( isActor || (myActorsList.count() > 0) );
2658 }
2659
2660 //=======================================================================
2661 //function : setShowEntityMode
2662 //purpose  : make shown only entity corresponding to my type
2663 //=======================================================================
2664 void SMESHGUI_GroupDlg::setShowEntityMode()
2665 {
2666   if ( !myMesh->_is_nil() ) {
2667     if ( SMESH_Actor* actor = SMESH::FindActorByObject(myMesh) ) {
2668       if (!myStoredShownEntity)
2669         myStoredShownEntity = actor->GetEntityMode();
2670       switch ( myTypeId ) {
2671       case grpNodeSelection:   restoreShowEntityMode();                          break;
2672       case grp0DSelection:     actor->SetEntityMode( SMESH_Actor::e0DElements ); break;
2673       case grpBallSelection:   actor->SetEntityMode( SMESH_Actor::eBallElem );   break;
2674       case grpEdgeSelection:   actor->SetEntityMode( SMESH_Actor::eEdges );      break;
2675       case grpFaceSelection:   actor->SetEntityMode( SMESH_Actor::eFaces );      break;
2676       case grpVolumeSelection: actor->SetEntityMode( SMESH_Actor::eVolumes );    break;
2677       }
2678     }
2679   }
2680 }
2681
2682 //=======================================================================
2683 //function : restoreShowEntityMode
2684 //purpose  : restore ShowEntity mode of myActor
2685 //=======================================================================
2686 void SMESHGUI_GroupDlg::restoreShowEntityMode()
2687 {
2688   if ( myStoredShownEntity && !myMesh->_is_nil() ) {
2689     if ( SMESH_Actor* actor = SMESH::FindActorByObject(myMesh) ) {
2690       actor->SetEntityMode(myStoredShownEntity);
2691     }
2692   }
2693   myStoredShownEntity = 0;
2694 }
2695
2696 //=======================================================================
2697 //function : IsActorVisible
2698 //purpose  : return visibility of the actor
2699 //=======================================================================
2700 bool SMESHGUI_GroupDlg::IsActorVisible( SMESH_Actor* theActor )
2701 {
2702   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
2703   if (theActor && aViewWindow)
2704     return aViewWindow->isVisible(theActor->getIO());
2705   return false;
2706 }
2707
2708 //================================================================
2709 //function : setIsApplyAndClose
2710 //purpose  : Set value of the flag indicating that the dialog is
2711 //           accepted by Apply & Close button
2712 //================================================================
2713 void SMESHGUI_GroupDlg::setIsApplyAndClose( const bool theFlag )
2714 {
2715   myIsApplyAndClose = theFlag;
2716 }
2717
2718 //================================================================
2719 //function : isApplyAndClose
2720 //purpose  : Get value of the flag indicating that the dialog is
2721 //           accepted by Apply & Close button
2722 //================================================================
2723 bool SMESHGUI_GroupDlg::isApplyAndClose() const
2724 {
2725   return myIsApplyAndClose;
2726 }