Salome HOME
Bug 0019389: Impossible to create a group with a selection in another group.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupDlg.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : SMESHGUI_GroupDlg.cxx
25 //  Author : Natalia KOPNOVA
26 //  Module : SMESH
27 //  $Header$
28
29 #include "SMESHGUI_GroupDlg.h"
30 #include "SMESHGUI_FilterDlg.h"
31 #include "SMESHGUI_ShapeByMeshDlg.h"
32
33 #include "SMESHGUI.h"
34 #include "SMESHGUI_Utils.h"
35 #include "SMESHGUI_VTKUtils.h"
36 #include "SMESHGUI_MeshUtils.h"
37 #include "SMESHGUI_GroupUtils.h"
38 #include "SMESHGUI_FilterUtils.h"
39 #include "SMESHGUI_GEOMGenUtils.h"
40
41 #include "SMESH_TypeFilter.hxx"
42 #include "SMESH_Actor.h"
43 #include "SMESH_ActorUtils.h"
44
45 #include "GEOMBase.h"
46 #include "GEOM_SelectionFilter.h"
47
48 #include "SUIT_Desktop.h"
49 #include "SUIT_ResourceMgr.h"
50 #include "SUIT_Session.h"
51 #include "SUIT_MessageBox.h"
52
53 #include "SalomeApp_Tools.h"
54 #include "SalomeApp_Application.h"
55 #include "SalomeApp_Study.h"
56 #include "LightApp_Application.h"
57 #include "SALOMEDSClient_Study.hxx"
58 #include "SALOME_ListIO.hxx"
59 #include "SALOME_ListIteratorOfListIO.hxx"
60
61 #include "SVTK_ViewWindow.h"
62 #include "SVTK_Selector.h"
63
64 #include "utilities.h"
65
66 // VTK Includes
67 #include <vtkRenderer.h>
68 #include <vtkActorCollection.h>
69
70 // OCCT Includes
71 #include <TColStd_MapOfInteger.hxx>
72
73 // QT Includes
74 #include <qbuttongroup.h>
75 #include <qcursor.h>
76 #include <qgroupbox.h>
77 #include <qhbox.h>
78 #include <qlabel.h>
79 #include <qlineedit.h>
80 #include <qpushbutton.h>
81 #include <qtoolbutton.h>
82 #include <qradiobutton.h>
83 #include <qcheckbox.h>
84 #include <qlayout.h>
85 #include <qlistbox.h>
86 #include <qimage.h>
87 #include <qpixmap.h>
88 #include <qmemarray.h>
89 #include <qwidgetstack.h>
90 #include <qcolordialog.h>
91
92 #include <QtxIntSpinBox.h>
93
94 // STL includes
95 #include <vector>
96 #include <algorithm>
97 #include <set>
98
99 using namespace std;
100
101 //=================================================================================
102 // function : SMESHGUI_GroupDlg()
103 // purpose  :
104 //=================================================================================
105 SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name,
106                                       SMESH::SMESH_Mesh_ptr theMesh, bool modal, WFlags fl)
107      : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
108                 WStyle_Title | WStyle_SysMenu | WDestructiveClose),
109      mySMESHGUI( theModule ),
110      mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
111      mySelector(SMESH::GetViewWindow( theModule )->GetSelector()),
112      myIsBusy( false ),
113      myActor( 0 )
114 {
115   if (!name) setName("SMESHGUI_GroupDlg");
116   initDialog(true);
117   if (!theMesh->_is_nil())
118     init(theMesh);
119   else {
120     mySelectSubMesh->setEnabled(false);
121     mySelectGroup->setEnabled(false);
122     myGeomGroupBtn->setEnabled(false);
123     myGeomGroupLine->setEnabled(false);
124   }
125 }
126
127 //=================================================================================
128 // function : SMESHGUI_GroupDlg()
129 // purpose  :
130 //=================================================================================
131 SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name,
132                                       SMESH::SMESH_GroupBase_ptr theGroup, bool modal, WFlags fl)
133      : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
134                 WStyle_Title | WStyle_SysMenu | WDestructiveClose),
135      mySMESHGUI( theModule ),
136      mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
137      mySelector(SMESH::GetViewWindow( theModule )->GetSelector()),
138      myIsBusy( false )
139 {
140   if (!name) setName("SMESHGUI_GroupDlg");
141
142   initDialog(false);
143   if (!theGroup->_is_nil())
144     init(theGroup);
145   else {
146     mySelectSubMesh->setEnabled(false);
147     mySelectGroup->setEnabled(false);
148
149     myCurrentLineEdit = myMeshGroupLine;
150     setSelectionMode(5);
151   }
152 }
153
154 //=================================================================================
155 // function : SMESHGUI_GroupDlg()
156 // purpose  :
157 //=================================================================================
158 void SMESHGUI_GroupDlg::initDialog(bool create)
159 {
160   myFilterDlg = 0;
161   myCreate = create;
162   myCurrentLineEdit = 0;
163
164   myShapeByMeshOp = 0;
165   myGeomPopup = 0;
166   myGeomObjects = new GEOM::ListOfGO();
167   myGeomObjects->length(0);
168
169   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
170
171   if (create) {
172     setCaption(tr("SMESH_CREATE_GROUP_TITLE"));
173     myHelpFileName = "creating_groups_page.html";
174   }
175   else {
176     setCaption(tr("SMESH_EDIT_GROUP_TITLE"));
177     myHelpFileName = "editing_groups_page.html";
178   }
179
180   setSizeGripEnabled(TRUE);
181
182   QGridLayout* aMainLayout = new QGridLayout(this, 7, 3, 11, 6);
183
184   /***************************************************************/
185   QLabel* meshGroupLab = new QLabel(this, "mesh/group label");
186   if (create)
187     meshGroupLab->setText(tr("SMESH_MESH"));
188   else
189     meshGroupLab->setText(tr("SMESH_GROUP"));
190   myMeshGroupBtn = new QPushButton(this, "mesh/group button");
191   myMeshGroupBtn->setPixmap(image0);
192   myMeshGroupLine = new QLineEdit(this, "mesh/group line");
193   myMeshGroupLine->setReadOnly(true);
194
195   /***************************************************************/
196   myTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Group types");
197   myTypeGroup->setTitle(tr("SMESH_ELEMENTS_TYPE"));
198   myTypeGroup->setExclusive(true);
199
200   QStringList types;
201   types.append(tr("MESH_NODE"));
202   types.append(tr("SMESH_EDGE"));
203   types.append(tr("SMESH_FACE"));
204   types.append(tr("SMESH_VOLUME"));
205   QRadioButton* rb;
206   for (int i = 0; i < types.count(); i++) {
207     rb = new QRadioButton(types[i], myTypeGroup);
208   }
209   myTypeGroup->setEnabled(create);
210   myTypeId = -1;
211
212   /***************************************************************/
213   QLabel* aName = new QLabel(this, "name label");
214   aName->setText(tr("SMESH_NAME"));
215   aName->setMinimumSize(50,0);
216   myName = new QLineEdit(this, "name");
217
218   /***************************************************************/
219   myGrpTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Type of group");
220   myGrpTypeGroup->setTitle(tr("SMESH_GROUP_TYPE"));
221   myGrpTypeGroup->setExclusive(true);
222   QRadioButton* rb1 = new QRadioButton( tr("SMESH_GROUP_STANDALONE"), myGrpTypeGroup);
223   QRadioButton* rb2 = new QRadioButton( tr("SMESH_GROUP_GEOMETRY"),   myGrpTypeGroup);
224   myGrpTypeGroup->setEnabled(create);
225   myGrpTypeId = -1;
226
227   /***************************************************************/
228   myWGStack = new QWidgetStack( this, "widget stack");
229   QWidget* wg1 = new QFrame( myWGStack, "first widget" );
230   QWidget* wg2 = new QFrame( myWGStack, "second widget" );
231
232   /***************************************************************/
233   QGroupBox* aContentBox = new QGroupBox(1, Qt::Horizontal, wg1, "content box");
234   aContentBox->setTitle(tr("SMESH_CONTENT"));
235   QFrame* aContent = new QFrame(aContentBox, "content");
236   QGridLayout* aLayout = new QGridLayout(aContent, 7, 4);
237   aLayout->setSpacing(6);
238   aLayout->setAutoAdd(false);
239
240   QLabel* aLabel = new QLabel(aContent, "elements label");
241   aLabel->setText(tr("SMESH_ID_ELEMENTS"));
242   myElements = new QListBox(aContent, "elements list");
243   myElements->setSelectionMode(QListBox::Extended);
244
245   myFilter = new QPushButton(aContent, "filter");
246   myFilter->setText(tr("SMESH_BUT_FILTER"));
247   QPushButton* aAddBtn = new QPushButton(aContent, "add");
248   aAddBtn->setText(tr("SMESH_BUT_ADD"));
249   QPushButton* aRemoveBtn = new QPushButton(aContent, "remove");
250   aRemoveBtn->setText(tr("SMESH_BUT_REMOVE"));
251   QPushButton* aSortBtn = new QPushButton(aContent, "sort");
252   aSortBtn->setText(tr("SMESH_BUT_SORT"));
253
254   aLayout->addWidget(aLabel, 0, 0);
255   aLayout->addMultiCellWidget(myElements, 1, 6, 0, 0);
256   aLayout->addWidget(myFilter, 1, 2);
257   aLayout->addWidget(aAddBtn, 3, 2);
258   aLayout->addWidget(aRemoveBtn, 4, 2);
259   aLayout->addWidget(aSortBtn, 6, 2);
260
261   aLayout->setColStretch(0, 1);
262   aLayout->addColSpacing(1, 20);
263   aLayout->addColSpacing(3, 20);
264   aLayout->setRowStretch(2, 1);
265   aLayout->setRowStretch(5, 1);
266
267   /***************************************************************/
268   QGroupBox* aSelectBox = new QGroupBox(3, Qt::Horizontal, wg1, "select box");
269   aSelectBox->setTitle(tr("SMESH_SELECT_FROM"));
270
271   mySelectSubMesh = new QCheckBox(aSelectBox, "submesh checkbox");
272   mySelectSubMesh->setText(tr("SMESH_SUBMESH"));
273   mySelectSubMesh->setMinimumSize(50, 0);
274   mySubMeshBtn = new QPushButton(aSelectBox, "submesh button");
275   mySubMeshBtn->setText("");
276   mySubMeshBtn->setPixmap(image0);
277   mySubMeshLine = new QLineEdit(aSelectBox, "submesh line");
278   mySubMeshLine->setReadOnly(true);
279   onSelectSubMesh(false);
280
281   mySelectGroup = new QCheckBox(aSelectBox, "group checkbox");
282   mySelectGroup->setText(tr("SMESH_GROUP"));
283   mySelectGroup->setMinimumSize(50, 0);
284   myGroupBtn = new QPushButton(aSelectBox, "group button");
285   myGroupBtn->setText("");
286   myGroupBtn->setPixmap(image0);
287   myGroupLine = new QLineEdit(aSelectBox, "group line");
288   myGroupLine->setReadOnly(true);
289   onSelectGroup(false);
290
291   /***************************************************************/
292   QGridLayout* wg1Layout = new QGridLayout( wg1, 3, 1, 0, 6 );
293   wg1Layout->addWidget(aContentBox, 0, 0);
294   wg1Layout->addWidget(aSelectBox, 1, 0);
295   wg1Layout->setRowStretch(2, 5);
296
297   /***************************************************************/
298   QLabel* geomObject = new QLabel(wg2, "geometry object label");
299   geomObject->setText(tr("SMESH_OBJECT_GEOM"));
300   myGeomGroupBtn = new QToolButton(wg2, "geometry group button");
301   myGeomGroupBtn->setIconSet( QIconSet(image0) );
302   myGeomGroupBtn->setToggleButton(true);
303   myGeomGroupLine = new QLineEdit(wg2, "geometry group line");
304   myGeomGroupLine->setReadOnly(true); //VSR ???
305   onSelectGeomGroup(false);
306
307   if (!create)
308     {
309       myGeomGroupBtn->setEnabled(false);
310       myGeomGroupLine->setEnabled(false);
311     }
312
313   /***************************************************************/
314   QGridLayout* wg2Layout = new QGridLayout( wg2, 2, 3, 0, 6 );
315   wg2Layout->addWidget(geomObject,     0, 0);
316   wg2Layout->addWidget(myGeomGroupBtn, 0, 1);
317   wg2Layout->addWidget(myGeomGroupLine,0, 2);
318   wg2Layout->setRowStretch(1, 5);
319
320   /***************************************************************/
321   QVBoxLayout* dumb = new QVBoxLayout(myWGStack);
322   dumb->addWidget(wg1);
323   dumb->addWidget(wg2);
324   myWGStack->addWidget( wg1, myGrpTypeGroup->id(rb1) );
325   myWGStack->addWidget( wg2, myGrpTypeGroup->id(rb2) );
326
327   /***************************************************************/
328   QGroupBox* aColorBox = new QGroupBox(2, Qt::Horizontal, this, "color box");
329   aColorBox->setTitle(tr("SMESH_SET_COLOR"));
330
331   new QLabel( tr("SMESH_CHECK_COLOR"), aColorBox, "color label" );
332   myColorBtn = new QPushButton(aColorBox, "color button");
333   myColorBtn->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
334
335   /***************************************************************/
336
337   QFrame* aButtons = new QFrame(this, "button box");
338   aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken);
339   QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6);
340   aBtnLayout->setAutoAdd(false);
341
342   QPushButton* aApplyBtn = new QPushButton(aButtons, "apply");
343   aApplyBtn->setText(tr("SMESH_BUT_APPLY"));
344   aApplyBtn->setAutoDefault(true);
345   QPushButton* aCloseBtn = new QPushButton(aButtons, "close");
346   aCloseBtn->setText(tr("SMESH_BUT_CLOSE"));
347   aCloseBtn->setAutoDefault(true);
348   QPushButton* aOKBtn = new QPushButton(aButtons, "ok");
349   aOKBtn->setText(tr("SMESH_BUT_APPLY_AND_CLOSE"));
350   aOKBtn->setAutoDefault(true);
351   aOKBtn->setDefault(true);
352   QPushButton* aHelpBtn = new QPushButton(aButtons, "help");
353   aHelpBtn->setText(tr("SMESH_BUT_HELP"));
354   aHelpBtn->setAutoDefault(true);
355
356   aBtnLayout->addWidget(aOKBtn);
357   aBtnLayout->addWidget(aApplyBtn);
358   aBtnLayout->addStretch();
359   aBtnLayout->addWidget(aCloseBtn);
360   aBtnLayout->addWidget(aHelpBtn);
361
362   /***************************************************************/
363   aMainLayout->addWidget(meshGroupLab,    0, 0);
364   aMainLayout->addWidget(myMeshGroupBtn,  0, 1);
365   aMainLayout->addWidget(myMeshGroupLine, 0, 2);
366   aMainLayout->addMultiCellWidget(myTypeGroup,    1, 1, 0, 2);
367   aMainLayout->addWidget(aName,      2, 0);
368   aMainLayout->addWidget(myName,     2, 2);
369   aMainLayout->addMultiCellWidget(myGrpTypeGroup, 3, 3, 0, 2);
370   aMainLayout->addMultiCellWidget(myWGStack,      4, 4, 0, 2);
371   aMainLayout->setRowStretch( 5, 5 );
372   aMainLayout->addMultiCellWidget(aColorBox,   6, 6, 0, 2);
373   aMainLayout->addMultiCellWidget(aButtons,       7, 7, 0, 2);
374
375   /* signals and slots connections */
376   connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
377
378   connect(myGrpTypeGroup, SIGNAL(clicked(int)), this, SLOT(onGrpTypeChanged(int)));
379
380   connect(myTypeGroup, SIGNAL(clicked(int)), this, SLOT(onTypeChanged(int)));
381
382   connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
383   connect(myElements, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged()));
384
385   connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters()));
386   connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd()));
387   connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove()));
388   connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort()));
389
390   connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool)));
391   connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool)));
392   connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
393   connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
394   connect(myGeomGroupBtn, SIGNAL(toggled(bool)), this, SLOT(onGeomSelectionButton(bool)));
395   connect(myColorBtn, SIGNAL(clicked()), this, SLOT(onSelectColor()));
396
397   connect(aOKBtn, SIGNAL(clicked()), this, SLOT(onOK()));
398   connect(aApplyBtn, SIGNAL(clicked()), this, SLOT(onApply()));
399   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
400   connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
401
402   /* Init selection */
403   mySMESHGUI->SetActiveDialogBox(this);
404   mySMESHGUI->SetState(800);
405
406   mySelectionMode = -1;
407   myMeshFilter = new SMESH_TypeFilter(MESH);
408   mySubMeshFilter = new SMESH_TypeFilter(SUBMESH);
409   myGroupFilter = new SMESH_TypeFilter(GROUP);
410   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
411   myGeomFilter = new GEOM_SelectionFilter( aStudy, true );
412
413   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
414   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(onClose()));
415   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onObjectSelectionChanged()));
416
417   myGrpTypeGroup->setButton(myGrpTypeGroup->id(rb1)); // VSR !!!
418   onGrpTypeChanged(myGrpTypeGroup->id(rb1)); // VSR!!!
419
420   if (myMesh->_is_nil() )
421     myTypeGroup->setButton(0);
422
423   updateButtons();
424   //myName->setText(GetDefaultName(tr("SMESH_GROUP")));
425 }
426
427 //=================================================================================
428 // function : ~SMESHGUI_GroupDlg()
429 // purpose  : Destroys the object and frees any allocated resources
430 //=================================================================================
431 SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg()
432 {
433   // no need to delete child widgets, Qt does it all for us
434   if ( myFilterDlg != 0 )
435   {
436     myFilterDlg->reparent( 0, QPoint() );
437     delete myFilterDlg;
438   }
439 }
440
441 //=================================================================================
442 // function : GetDefaultName()
443 // purpose  : Get the Group Name if Create new Group
444 //=================================================================================
445 QString SMESHGUI_GroupDlg::GetDefaultName(const QString& theOperation)
446 {
447     QString aName = "";
448
449     // collect all object names of SMESH component
450     SalomeApp_Study* appStudy =
451       dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
452     if ( !appStudy ) return aName;
453     _PTR(Study) aStudy = appStudy->studyDS();
454
455     std::set<std::string> aSet;
456     _PTR(SComponent) aMeshCompo (aStudy->FindComponent("SMESH"));
457     if (aMeshCompo) {
458       _PTR(ChildIterator) it (aStudy->NewChildIterator(aMeshCompo));
459       _PTR(SObject) obj;
460       for (it->InitEx(true); it->More(); it->Next()) {
461         obj = it->Value();
462         aSet.insert(obj->GetName());
463       }
464     }
465
466     // build a unique name
467     int aNumber = 0;
468     bool isUnique = false;
469     while (!isUnique) {
470       aName = theOperation + "_" + QString::number(++aNumber);
471       isUnique = (aSet.count(aName.latin1()) == 0);
472     }
473
474     return aName;
475 }
476
477 //=================================================================================
478 // function : Init()
479 // purpose  :
480 //=================================================================================
481 void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
482 {
483   mySelectionMgr->installFilter(myMeshFilter);
484
485   /* init data from current selection */
486   restoreShowEntityMode();
487   myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
488   setShowEntityMode();
489   myGroup = SMESH::SMESH_Group::_nil();
490   myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
491
492   // NPAL19389: create a group with a selection in another group
493   // set actor of myMesh, if it is visible, else try
494   // any visible actor of group or submesh of myMesh
495   SetAppropriateActor();
496
497   setDefaultGroupColor();
498
499   SALOME_ListIO aList;
500   mySelectionMgr->selectedObjects( aList );
501   if ( !aList.IsEmpty() )
502   {
503     QString aName = aList.First()->getName();
504     myMeshGroupLine->setText(aName);
505     myMeshGroupLine->home( false );
506   }
507
508   myCurrentLineEdit = 0;
509
510   myTypeGroup->setButton(0);
511   onTypeChanged(0);
512 }
513
514 //=================================================================================
515 // function : Init()
516 // purpose  :
517 //=================================================================================
518 void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup)
519 {
520   restoreShowEntityMode();
521   myMesh = theGroup->GetMesh();
522   setShowEntityMode();
523
524   myName->setText(theGroup->GetName());
525   myName->home(false);
526
527   SALOMEDS::Color aColor = theGroup->GetColor();
528   setGroupColor( aColor );
529
530   myMeshGroupLine->setText(theGroup->GetName());
531
532   int aType = 0;
533   switch(theGroup->GetType()) {
534   case SMESH::NODE: aType= 0; break;
535   case SMESH::EDGE: aType = 1; break;
536   case SMESH::FACE: aType = 2; break;
537   case SMESH::VOLUME: aType = 3; break;
538   }
539   myTypeGroup->setButton(aType);
540
541   myGroup = SMESH::SMESH_Group::_narrow( theGroup );
542
543   if (!myGroup->_is_nil())
544   {
545     // NPAL19389: create a group with a selection in another group
546     // set actor of myMesh, if it is visible, else set
547     // actor of myGroup, if it is visible, else try
548     // any visible actor of group or submesh of myMesh
549     // commented, because an attempt to set selection on not displayed cells leads to error
550     //SetAppropriateActor();
551     myActor = SMESH::FindActorByObject(myMesh);
552     if ( !myActor )
553       myActor = SMESH::FindActorByObject(myGroup);
554     SMESH::SetPickable(myActor);
555
556     myGrpTypeGroup->setButton(0);
557     onGrpTypeChanged(0);
558
559     myCurrentLineEdit = 0;
560     myElements->clear();
561     setSelectionMode(aType);
562     myTypeId = aType;
563
564     setShowEntityMode(); // depends on myTypeId
565
566     myIdList.clear();
567     if (!myGroup->IsEmpty()) {
568       SMESH::long_array_var anElements = myGroup->GetListOfID();
569       int k = anElements->length();
570       for (int i = 0; i < k; i++) {
571         myIdList.append(anElements[i]);
572         myElements->insertItem(QString::number(anElements[i]));
573       }
574       myElements->selectAll(true);
575     }
576   }
577   else
578   {
579     myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
580
581     if ( !myGroupOnGeom->_is_nil() )
582     {
583       // NPAL19389: create a group with a selection in another group
584       // set actor of myMesh, if it is visible, else set
585       // actor of myGroupOnGeom, if it is visible, else try
586       // any visible actor of group or submesh of myMesh
587       // commented, because an attempt to set selection on not displayed cells leads to error
588       //SetAppropriateActor();
589       myActor = SMESH::FindActorByObject(myMesh);
590       if ( !myActor )
591         myActor = SMESH::FindActorByObject(myGroupOnGeom);
592       SMESH::SetPickable(myActor);
593
594       myGrpTypeGroup->setButton(1);
595       onGrpTypeChanged(1);
596
597       QString aShapeName("");
598       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
599       GEOM::GEOM_Object_var aGroupShape = myGroupOnGeom->GetShape();
600       if (!aGroupShape->_is_nil())
601       {
602         _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry());
603         aShapeName = aGroupShapeSO->GetName().c_str();
604       }
605       myGeomGroupLine->setText( aShapeName );
606       myName->setText("Group On " + aShapeName);
607     }
608   }
609 }
610
611 //=================================================================================
612 // function : updateButtons()
613 // purpose  :
614 //=================================================================================
615 void SMESHGUI_GroupDlg::updateButtons()
616 {
617   bool enable = !myName->text().stripWhiteSpace().isEmpty();
618
619   if (myGrpTypeId == 0) {
620     enable = enable && myElements->count() > 0;
621     enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
622   }
623   else if (myGrpTypeId == 1) {
624     if (CORBA::is_nil(myGroupOnGeom)) { // creation mode
625       enable = enable && myGeomObjects->length() > 0 && !myMesh->_is_nil();
626     }
627   }
628
629   QPushButton* aBtn;
630   aBtn = (QPushButton*) child("ok", "QPushButton");
631   if (aBtn) aBtn->setEnabled(enable);
632   aBtn = (QPushButton*) child("apply", "QPushButton");
633   if (aBtn) aBtn->setEnabled(enable);
634 }
635
636 //=================================================================================
637 // function : onNameChanged()
638 // purpose  :
639 //=================================================================================
640 void SMESHGUI_GroupDlg::onNameChanged (const QString& text)
641 {
642   myOldName = myName->text();
643   updateButtons();
644 }
645
646 //=================================================================================
647 // function : onTypeChanged()
648 // purpose  : Group elements type radio button management
649 //=================================================================================
650 void SMESHGUI_GroupDlg::onTypeChanged (int id)
651 {
652   if (myTypeId != id) {
653     myElements->clear();
654     if (myCurrentLineEdit == 0)
655       setSelectionMode(id);
656     myTypeId = id;
657     setShowEntityMode();
658   }
659 }
660
661 //=================================================================================
662 // function : onGrpTypeChanged()
663 // purpose  : Group type radio button management
664 //=================================================================================
665 void SMESHGUI_GroupDlg::onGrpTypeChanged (int id)
666 {
667   if (myGrpTypeId != id) {
668     myWGStack->raiseWidget( id );
669     myName->setText(myOldName);
670     onSelectGeomGroup(id == 1);
671   }
672   myGrpTypeId = id;
673 }
674
675 //=================================================================================
676 // function : onSelectColor()
677 // purpose  :
678 //=================================================================================
679 void SMESHGUI_GroupDlg::onSelectColor()
680 {
681   QColor color = getGroupQColor();
682   color = QColorDialog::getColor( color );
683   setGroupQColor( color );
684
685   updateButtons();
686 }
687
688 //=================================================================================
689 // function : setSelectionMode()
690 // purpose  : Radio button management
691 //=================================================================================
692 void SMESHGUI_GroupDlg::setSelectionMode (int theMode)
693 {
694   // PAL7314
695   if (myMesh->_is_nil())
696     return;
697   if (mySelectionMode != theMode) {
698     // [PAL10408] mySelectionMgr->clearSelected();
699     mySelectionMgr->clearFilters();
700     if (myActor)
701       myActor->SetPointRepresentation(false);
702     else
703       SMESH::SetPointRepresentation(false);
704     if (theMode < 4) {
705       switch (theMode) {
706       case 0:
707         if (myActor)
708           myActor->SetPointRepresentation(true);
709         else
710           SMESH::SetPointRepresentation(true);
711         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
712           aViewWindow->SetSelectionMode(NodeSelection);
713         break;
714       case 1:
715         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
716           aViewWindow->SetSelectionMode(EdgeSelection);
717         break;
718       case 2:
719         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
720           aViewWindow->SetSelectionMode(FaceSelection);
721         break;
722       default:
723         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
724           aViewWindow->SetSelectionMode(VolumeSelection);
725       }
726     } else {
727       if (theMode == 4)
728         mySelectionMgr->installFilter(mySubMeshFilter);
729       else if (theMode == 5)
730         mySelectionMgr->installFilter(myGroupFilter);
731       else if (theMode == 6)
732         mySelectionMgr->installFilter(myMeshFilter);
733       else if (theMode == 7)
734         mySelectionMgr->installFilter(myGeomFilter);
735
736       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
737         aViewWindow->SetSelectionMode(ActorSelection);
738     }
739     mySelectionMode = theMode;
740   }
741 }
742
743 //=================================================================================
744 // function : onApply()
745 // purpose  :
746 //=================================================================================
747 bool SMESHGUI_GroupDlg::onApply()
748 {
749   if (mySMESHGUI->isActiveStudyLocked())
750     return false;
751
752   if (myName->text().stripWhiteSpace().isEmpty())
753     return false;
754
755   if (myGrpTypeId == 0) { // on mesh elements
756     if (!myElements->count())
757       return false;
758
759     mySelectionMgr->clearSelected();
760
761     if (myGroup->_is_nil()) { // creation
762       if (myMesh->_is_nil())
763         return false;
764
765       SMESH::ElementType aType = SMESH::ALL;
766       switch (myTypeId) {
767       case 0: aType = SMESH::NODE; break;
768       case 1: aType = SMESH::EDGE; break;
769       case 2: aType = SMESH::FACE; break;
770       case 3: aType = SMESH::VOLUME; break;
771       }
772
773       SMESH::long_array_var anIdList = new SMESH::long_array;
774       int i, k = myElements->count();
775       anIdList->length(k);
776       QListBoxItem* anItem;
777       for (i = 0, anItem = myElements->firstItem(); anItem != 0; i++, anItem = anItem->next()) {
778         anIdList[i] = anItem->text().toInt();
779       }
780
781       myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
782       myGroup->Add(anIdList.inout());
783
784       SALOMEDS::Color aColor = getGroupColor();
785       myGroup->SetColor(aColor);
786
787       _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
788
789       //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
790       SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
791
792       /* init for next operation */
793       myName->setText("");
794       myElements->clear();
795       myGroup = SMESH::SMESH_Group::_nil();
796
797     } else { // edition
798       myGroup->SetName(myName->text());
799
800       SALOMEDS::Color aColor = getGroupColor();
801       myGroup->SetColor(aColor);
802
803       _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
804       if (SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
805         anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
806
807       QValueList<int> aAddList;
808       QValueList<int>::iterator anIt;
809       QListBoxItem* anItem;
810
811       for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) {
812         int anId = anItem->text().toInt();
813         if ((anIt = myIdList.find(anId)) == myIdList.end())
814           aAddList.append(anId);
815         else
816           myIdList.remove(anIt);
817       }
818       if (!aAddList.empty()) {
819         SMESH::long_array_var anIdList = new SMESH::long_array;
820         anIdList->length(aAddList.count());
821         int i;
822         for (i = 0, anIt = aAddList.begin(); anIt != aAddList.end(); anIt++, i++)
823           anIdList[i] = *anIt;
824         myGroup->Add(anIdList.inout());
825       }
826       if (!myIdList.empty()) {
827         SMESH::long_array_var anIdList = new SMESH::long_array;
828         anIdList->length(myIdList.count());
829         int i;
830         for (i = 0, anIt = myIdList.begin(); anIt != myIdList.end(); anIt++, i++)
831           anIdList[i] = *anIt;
832         myGroup->Remove(anIdList.inout());
833       }
834       /* init for next operation */
835       myIdList.clear();
836       for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next())
837         myIdList.append(anItem->text().toInt());
838     }
839
840     mySMESHGUI->updateObjBrowser(true);
841     SMESH::UpdateView(); // asv: fix of BUG PAL5515
842     mySelectionMgr->clearSelected();
843     return true;
844   }
845   else if (myGrpTypeId == 1) { // on geom object
846     if (CORBA::is_nil(myGroupOnGeom)) { // creation
847       if (myMesh->_is_nil() || !myGeomObjects->length())
848         return false;
849
850       SMESH::ElementType aType = SMESH::ALL;
851       switch (myTypeId) {
852       case 0: aType = SMESH::NODE; break;
853       case 1: aType = SMESH::EDGE; break;
854       case 2: aType = SMESH::FACE; break;
855       case 3: aType = SMESH::VOLUME; break;
856       }
857
858       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
859       GEOM::GEOM_IGroupOperations_var aGroupOp =
860         SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
861
862       if (myGeomObjects->length() == 1) {
863         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomObjects[0]);
864       }
865       else {
866         SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
867         if ( aSMESHGen->_is_nil() )
868           return false;
869
870         // create a geometry group
871         GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
872         _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
873
874         if (geomGen->_is_nil() || !aStudy)
875           return false;
876
877         GEOM::GEOM_IGroupOperations_var op =
878           geomGen->GetIGroupOperations(aStudy->StudyId());
879         if (op->_is_nil())
880           return false;
881
882         // check and add all selected GEOM objects: they must be
883         // a sub-shapes of the main GEOM and must be of one type
884         TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
885         for ( int i =0; i < myGeomObjects->length(); i++) {
886           TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
887           if (i == 0)
888             aGroupType = aSubShapeType;
889           else if (aSubShapeType != aGroupType) {
890             aGroupType = TopAbs_SHAPE;
891             break;
892           }
893         }
894
895         GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
896         GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
897         op->UnionList(aGroupVar, myGeomObjects);
898
899         if (op->IsDone()) {
900           // publish the GEOM group in study
901           QString aNewGeomGroupName ("Auto_group_for_");
902           aNewGeomGroupName += myName->text();
903           SALOMEDS::SObject_var aNewGroupSO =
904             geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar, aNewGeomGroupName, aMeshShape);
905         }
906
907         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(), aGroupVar);
908       }
909
910       SALOMEDS::Color aColor = getGroupColor();
911       myGroupOnGeom->SetColor(aColor);
912
913       _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
914
915       //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
916       SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
917
918       /* init for next operation */
919       myName->setText("");
920       myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
921     }
922     else { // edition
923       myGroupOnGeom->SetName(myName->text());
924
925       SALOMEDS::Color aColor = getGroupColor();
926       myGroupOnGeom->SetColor(aColor);
927
928       _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
929       if (SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
930         anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
931     }
932
933     mySMESHGUI->updateObjBrowser(true);
934     mySelectionMgr->clearSelected();
935     return true;
936   }
937
938   return false;
939 }
940
941 //=================================================================================
942 // function : onOK()
943 // purpose  :
944 //=================================================================================
945 void SMESHGUI_GroupDlg::onOK()
946 {
947   if ( onApply() )
948     onClose();
949 }
950
951 //=================================================================================
952 // function : onListSelectionChanged()
953 // purpose  : Called when selection in element list is changed
954 //=================================================================================
955 void SMESHGUI_GroupDlg::onListSelectionChanged()
956 {
957   //  MESSAGE("SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor);
958   if ( myIsBusy || !myActor) return;
959     myIsBusy = true;
960
961   if (myCurrentLineEdit == 0) {
962     mySelectionMgr->clearSelected();
963     TColStd_MapOfInteger aIndexes;
964     QListBoxItem* anItem;
965     for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) {
966       if (anItem->isSelected()) {
967         int anId = anItem->text().toInt();
968         aIndexes.Add(anId);
969       }
970     }
971     mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false);
972     SALOME_ListIO aList;
973     aList.Append(myActor->getIO());
974     mySelectionMgr->setSelectedObjects(aList,false);
975   }
976   myIsBusy = false;
977 }
978
979 //=================================================================================
980 // function : onObjectSelectionChanged()
981 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
982 //=================================================================================
983 void SMESHGUI_GroupDlg::onObjectSelectionChanged()
984 {
985   if (myIsBusy || !isEnabled()) return;
986   if (myCurrentLineEdit == myGeomGroupLine && !myGeomGroupBtn->isOn()) return;
987
988   myIsBusy = true;
989
990   SALOME_ListIO aList;
991   mySelectionMgr->selectedObjects( aList );
992
993   int aNbSel = aList.Extent();
994   myElements->clearSelection();
995
996   if (myCurrentLineEdit)
997   {
998     myCurrentLineEdit->setText("");
999     QString aString = "";
1000
1001     if (myCurrentLineEdit == myMeshGroupLine)
1002     {
1003       mySelectSubMesh->setEnabled(false);
1004       mySelectGroup->setEnabled(false);
1005       myGroupLine->setText("");
1006       mySubMeshLine->setText("");
1007
1008       myGeomGroupBtn->setEnabled(false);
1009       myGeomGroupLine->setEnabled(false);
1010       myGeomGroupLine->setText("");
1011       myGeomObjects = new GEOM::ListOfGO();
1012       myGeomObjects->length(0);
1013
1014       if (myGeomGroupBtn->isOn())
1015         myGeomGroupBtn->setOn(false);
1016       if (!myCreate)
1017         myName->setText("");
1018
1019       myElements->clear();
1020
1021       if (aNbSel != 1 ) {
1022         myGroup = SMESH::SMESH_Group::_nil();
1023         myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
1024         restoreShowEntityMode();
1025         myMesh = SMESH::SMESH_Mesh::_nil();
1026         updateGeomPopup();
1027         updateButtons();
1028         myIsBusy = false;
1029         return;
1030       }
1031       Handle(SALOME_InteractiveObject) IO = aList.First();
1032
1033       if (myCreate) {
1034         restoreShowEntityMode();
1035         myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
1036         setShowEntityMode();
1037         updateGeomPopup();
1038         if (myMesh->_is_nil())
1039         {
1040           updateButtons();
1041           myIsBusy = false;
1042           return;
1043         }
1044         myGroup = SMESH::SMESH_Group::_nil();
1045
1046         // NPAL19389: create a group with a selection in another group
1047         // set actor of myMesh, if it is visible, else try
1048         // any visible actor of group or submesh of myMesh
1049         SetAppropriateActor();
1050
1051         aString = aList.First()->getName();
1052         myMeshGroupLine->setText(aString);
1053         myMeshGroupLine->home( false );
1054
1055         mySelectSubMesh->setEnabled(true);
1056         mySelectGroup->setEnabled(true);
1057         myGeomGroupBtn->setEnabled(true);
1058         myGeomGroupLine->setEnabled(true);
1059         updateButtons();
1060       } else {
1061         SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
1062         if (aGroup->_is_nil())
1063         {
1064           myIsBusy = false;
1065           return;
1066         }
1067         myIsBusy = false;
1068         myCurrentLineEdit = 0;
1069
1070         myGroup = SMESH::SMESH_Group::_nil();
1071         myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
1072
1073         init(aGroup);
1074         myIsBusy = true;
1075         mySelectSubMesh->setEnabled(true);
1076         mySelectGroup->setEnabled(true);
1077       }
1078       myCurrentLineEdit = 0;
1079       myIsBusy = false;
1080       if (!myCreate)
1081         return;
1082
1083       if (myGrpTypeId == 0)
1084       {
1085         if (myTypeId == -1)
1086           onTypeChanged(0);
1087         else
1088         {
1089           myElements->clear();
1090           setSelectionMode(myTypeId);
1091         }
1092       }
1093
1094       myIsBusy = false;
1095       return;
1096     }
1097     else if (myCurrentLineEdit == myGeomGroupLine)
1098     {
1099       myGeomObjects = new GEOM::ListOfGO();
1100
1101       // The mesh SObject
1102       _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh);
1103
1104       if (aNbSel == 0 || !aMeshSO)
1105       {
1106         myGeomObjects->length(0);
1107         updateButtons();
1108         myIsBusy = false;
1109         return;
1110       }
1111
1112       myGeomObjects->length(aNbSel);
1113
1114       GEOM::GEOM_Object_var aGeomGroup;
1115       Standard_Boolean testResult;
1116       int i = 0;
1117
1118       SALOME_ListIteratorOfListIO anIt (aList);
1119       for (; anIt.More(); anIt.Next())
1120       {
1121         testResult = Standard_False;
1122         aGeomGroup = GEOMBase::ConvertIOinGEOMObject(anIt.Value(), testResult);
1123
1124         // Check if the object is a geometry group
1125         if (!testResult || CORBA::is_nil(aGeomGroup))
1126           continue;
1127
1128         // Check if group constructed on the same shape as a mesh or on its child
1129         _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
1130         GEOM::GEOM_IGroupOperations_var anOp =
1131           SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
1132
1133         // The main shape of the group
1134         GEOM::GEOM_Object_var aGroupMainShape;
1135         if (aGeomGroup->GetType() == 37)
1136           aGroupMainShape = anOp->GetMainShape(aGeomGroup);
1137         else
1138           aGroupMainShape = GEOM::GEOM_Object::_duplicate(aGeomGroup);
1139         _PTR(SObject) aGroupMainShapeSO =
1140           //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(aGroupMainShape));
1141           aStudy->FindObjectID(aGroupMainShape->GetStudyEntry());
1142
1143         _PTR(SObject) anObj, aRef;
1144         bool isRefOrSubShape = false;
1145         if (aMeshSO->FindSubObject(1, anObj) &&  anObj->ReferencedObject(aRef)) {
1146           //if (strcmp(aRef->GetID(), aGroupMainShapeSO->GetID()) == 0) {
1147           if (aRef->GetID() == aGroupMainShapeSO->GetID()) {
1148             isRefOrSubShape = true;
1149           } else {
1150             _PTR(SObject) aFather = aGroupMainShapeSO->GetFather();
1151             _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent();
1152             //while (!isRefOrSubShape && strcmp(aFather->GetID(), aComponent->GetID()) != 0) {
1153             while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) {
1154               //if (strcmp(aRef->GetID(), aFather->GetID()) == 0)
1155               if (aRef->GetID() == aFather->GetID())
1156                 isRefOrSubShape = true;
1157               else
1158                 aFather = aFather->GetFather();
1159             }
1160           }
1161         }
1162         if (isRefOrSubShape)
1163           myGeomObjects[i++] = aGeomGroup;
1164       }
1165
1166       myGeomObjects->length(i);
1167       if ( i == 0 )
1168         {
1169           myIsBusy = false;
1170           return;
1171         }
1172
1173       aNbSel = i;
1174     }
1175
1176     if (aNbSel >= 1) {
1177       if (aNbSel > 1) {
1178         if (myCurrentLineEdit == mySubMeshLine)
1179           aString = tr("SMESH_SUBMESH_SELECTED").arg(aNbSel);
1180         else if (myCurrentLineEdit == myGroupLine)
1181           aString = tr("SMESH_GROUP_SELECTED").arg(aNbSel);
1182         else if (myCurrentLineEdit == myGeomGroupLine)
1183           aString = tr("%1 Objects").arg(aNbSel);
1184       }
1185       else {
1186         aString = aList.First()->getName();
1187       }
1188     }
1189
1190     myCurrentLineEdit->setText(aString);
1191     myCurrentLineEdit->home(false);
1192     // 07.06.2008 skl for IPAL19574:
1193     // change name of group only if it is empty
1194     QString tmp = myName->text();
1195     tmp.stripWhiteSpace();
1196     if(tmp.isEmpty()) {
1197       myOldName = myName->text();
1198       myName->setText(aString);
1199     }
1200
1201     updateButtons();
1202   }
1203   else // !myCurrentLineEdit: local selection of nodes or elements
1204   {
1205     if (aNbSel == 1 && myActor && myActor->hasIO())
1206     {
1207 #ifdef ENABLE_SWITCH_ACTOR_DURING_ELEMENTS_SELECTION
1208       // NPAL19389: create a group with a selection in another group
1209       // Switch myActor to the newly selected one, if the last
1210       // is visible and belongs to group or submesh of myMesh
1211       Handle(SALOME_InteractiveObject) curIO = myActor->getIO();
1212       Handle(SALOME_InteractiveObject) selIO = aList.First();
1213       if (curIO->hasEntry() && selIO->hasEntry()) {
1214         const char* selEntry = selIO->getEntry();
1215         if (strcmp(curIO->getEntry(), selEntry) != 0) {
1216           // different objects: selected and myActor
1217           SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
1218           if (aViewWindow && aViewWindow->isVisible(selIO)) {
1219             // newly selected actor is visible
1220
1221             // mesh entry
1222             _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
1223             if (aSObject) {
1224               CORBA::String_var meshEntry = aSObject->GetID().c_str();
1225               int len = strlen(meshEntry);
1226
1227               if (strncmp(selEntry, meshEntry, len) == 0) {
1228                 // selected object is myMesh or a part of it
1229                 SMESH_Actor* anActor = SMESH::FindActorByEntry(selEntry);
1230                 if (anActor) {
1231                   myActor = anActor;
1232                   SMESH::SetPickable(myActor);
1233                 }
1234               }
1235             }
1236           }
1237         }
1238       }
1239       // NPAL19389 END
1240 #endif // ENABLE_SWITCH_ACTOR_DURING_ELEMENTS_SELECTION
1241
1242       QString aListStr = "";
1243       int aNbItems = 0;
1244       if (myTypeId == 0) {
1245         aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
1246       } else {
1247         aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr);
1248       }
1249       if (aNbItems > 0) {
1250         QStringList anElements = QStringList::split(" ", aListStr);
1251         QListBoxItem* anItem = 0;
1252         for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
1253           anItem = myElements->findItem(*it, Qt::ExactMatch);
1254           if (anItem) myElements->setSelected(anItem, true);
1255         }
1256       }
1257     }
1258   }
1259
1260   if (!myActor) {
1261     if (!myGroup->_is_nil())
1262       myActor = SMESH::FindActorByObject(myGroup);
1263     else if (!myGroupOnGeom->_is_nil())
1264       myActor = SMESH::FindActorByObject(myGroupOnGeom);
1265     else
1266       myActor = SMESH::FindActorByObject(myMesh);
1267   }
1268
1269   // somehow, if we display the mesh, while selecting from another actor,
1270   // the mesh becomes pickable, and there is no way to select any element
1271   if (myActor)
1272     SMESH::SetPickable(myActor);
1273
1274   myIsBusy = false;
1275 }
1276
1277 //=================================================================================
1278 // function : onSelectSubMesh()
1279 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
1280 //=================================================================================
1281 void SMESHGUI_GroupDlg::onSelectSubMesh(bool on)
1282 {
1283   if (on) {
1284     if (mySelectGroup->isChecked()) {
1285       mySelectGroup->setChecked(false);
1286     }
1287     //VSR: else if (mySelectGeomGroup->isChecked()) {
1288     //VSR:   mySelectGeomGroup->setChecked(false);
1289     //VSR: }
1290     myCurrentLineEdit = mySubMeshLine;
1291     setSelectionMode(4);
1292   }
1293   else {
1294     mySubMeshLine->setText("");
1295     myCurrentLineEdit = 0;
1296     if (myTypeId != -1)
1297       setSelectionMode(myTypeId);
1298   }
1299   mySubMeshBtn->setEnabled(on);
1300   mySubMeshLine->setEnabled(on);
1301 }
1302
1303
1304 //=================================================================================
1305 // function : (onSelectGroup)
1306 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
1307 //=================================================================================
1308 void SMESHGUI_GroupDlg::onSelectGroup(bool on)
1309 {
1310   if (on) {
1311     if (mySelectSubMesh->isChecked()) {
1312       mySelectSubMesh->setChecked(false);
1313     }
1314     myCurrentLineEdit = myGroupLine;
1315     setSelectionMode(5);
1316   }
1317   else {
1318     myGroupLine->setText("");
1319     myCurrentLineEdit = 0;
1320     if (myTypeId != -1)
1321       setSelectionMode(myTypeId);
1322   }
1323   myGroupBtn->setEnabled(on);
1324   myGroupLine->setEnabled(on);
1325 }
1326
1327
1328 //=================================================================================
1329 // function : (onSelectGeomGroup)
1330 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
1331 //=================================================================================
1332 void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
1333 {
1334   if (on) {
1335     if (mySelectSubMesh->isChecked()) {
1336       mySelectSubMesh->setChecked(false);
1337     }
1338     else if (mySelectGroup->isChecked()) {
1339       mySelectGroup->setChecked(false);
1340     }
1341     myCurrentLineEdit = myGeomGroupLine;
1342     updateGeomPopup();
1343     setSelectionMode(8);
1344   }
1345   else {
1346     myGeomGroupBtn->setOn(false);
1347     myGeomObjects->length(0);
1348     myGeomGroupLine->setText("");
1349     myCurrentLineEdit = 0;
1350     if (myTypeId != -1)
1351       setSelectionMode(myTypeId);
1352   }
1353 }
1354
1355
1356 //=================================================================================
1357 // function : setCurrentSelection()
1358 // purpose  :
1359 //=================================================================================
1360 void SMESHGUI_GroupDlg::setCurrentSelection()
1361 {
1362   QPushButton* send = (QPushButton*)sender();
1363   myCurrentLineEdit = 0;
1364   if (send == myMeshGroupBtn) {
1365     myCurrentLineEdit = myMeshGroupLine;
1366     if (myCreate)
1367       setSelectionMode(6);
1368     else
1369       setSelectionMode(5);
1370     onObjectSelectionChanged();
1371   }
1372   else if (send == mySubMeshBtn) {
1373     myCurrentLineEdit = mySubMeshLine;
1374     onObjectSelectionChanged();
1375   }
1376   else if (send == myGroupBtn) {
1377     myCurrentLineEdit = myGroupLine;
1378     onObjectSelectionChanged();
1379   }
1380 }
1381
1382
1383 //=================================================================================
1384 // function : setFilters()
1385 // purpose  : SLOT. Called when "Filter" button pressed.
1386 //=================================================================================
1387 void SMESHGUI_GroupDlg::setFilters()
1388 {
1389   SMESH::ElementType aType = SMESH::ALL;
1390   switch ( myTypeId )
1391   {
1392     case 0 : aType = SMESH::NODE; break;
1393     case 1 : aType = SMESH::EDGE; break;
1394     case 2 : aType = SMESH::FACE; break;
1395     case 3 : aType = SMESH::VOLUME; break;
1396     default: return;
1397   }
1398
1399   if ( myFilterDlg == 0 )
1400   {
1401     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, aType );
1402     connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) );
1403   }
1404   else
1405     myFilterDlg->Init( aType );
1406
1407   myFilterDlg->SetSelection();
1408   myFilterDlg->SetMesh( myMesh );
1409   myFilterDlg->SetSourceWg( myElements );
1410
1411   myFilterDlg->show();
1412 }
1413
1414 //=================================================================================
1415 // function : onFilterAccepted()
1416 // purpose  : SLOT. Called when Filter dlg closed with OK button.
1417 //            Uncheck "Select submesh" and "Select group" checkboxes
1418 //=================================================================================
1419 void SMESHGUI_GroupDlg::onFilterAccepted()
1420 {
1421   if ( mySelectSubMesh->isChecked() || mySelectGroup->isChecked() )
1422   {
1423     mySelectionMode = myTypeId;
1424     mySelectSubMesh->setChecked( false );
1425     mySelectGroup->setChecked( false );
1426   }
1427 }
1428
1429 //=================================================================================
1430 // function : onAdd()
1431 // purpose  :
1432 //=================================================================================
1433 void SMESHGUI_GroupDlg::onAdd()
1434 {
1435   SALOME_ListIO aList;
1436   mySelectionMgr->selectedObjects( aList );
1437
1438   int aNbSel = aList.Extent();
1439
1440   if (aNbSel == 0 || !myActor || myMesh->_is_nil()) return;
1441
1442   myIsBusy = true;
1443
1444   SMESH::ElementType aType = SMESH::ALL;
1445   switch(myTypeId) {
1446   case 0:
1447     aType = SMESH::NODE;
1448     mySelector->SetSelectionMode(NodeSelection);
1449     break;
1450   case 1:
1451     aType = SMESH::EDGE;
1452     mySelector->SetSelectionMode(EdgeSelection);
1453     break;
1454   case 2:
1455     aType = SMESH::FACE;
1456     mySelector->SetSelectionMode(FaceSelection);
1457     break;
1458   case 3:
1459     aType = SMESH::VOLUME;
1460     mySelector->SetSelectionMode(VolumeSelection);
1461     break;
1462   default:
1463     mySelector->SetSelectionMode(ActorSelection);
1464   }
1465
1466   if (myCurrentLineEdit == 0) {
1467     //if (aNbSel != 1) { myIsBusy = false; return; }
1468     QString aListStr = "";
1469     int aNbItems = 0;
1470     if (myTypeId == 0) {
1471       aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
1472     }
1473     else {
1474       aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr);
1475     }
1476     if (aNbItems > 0) {
1477       QStringList anElements = QStringList::split(" ", aListStr);
1478       QListBoxItem* anItem = 0;
1479       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
1480         anItem = myElements->findItem(*it, Qt::ExactMatch);
1481         if (!anItem) {
1482           anItem = new QListBoxText(*it);
1483           myElements->insertItem(anItem);
1484         }
1485         myElements->setSelected(anItem, true);
1486       }
1487     }
1488   } else if (myCurrentLineEdit == mySubMeshLine) {
1489     //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
1490
1491     SALOME_ListIO aList;
1492     mySelectionMgr->selectedObjects( aList );
1493
1494     SALOME_ListIteratorOfListIO anIt (aList);
1495     for (; anIt.More(); anIt.Next()) {
1496       SMESH::SMESH_subMesh_var aSubMesh =
1497         SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
1498       if (!aSubMesh->_is_nil()) {
1499         // check if mesh is the same
1500         if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
1501           try {
1502             SMESH::long_array_var anElements = aSubMesh->GetElementsByType(aType);
1503             int k = anElements->length();
1504             QListBoxItem* anItem = 0;
1505             for (int i = 0; i < k; i++) {
1506               QString aText = QString::number(anElements[i]);
1507               anItem = myElements->findItem(aText, Qt::ExactMatch);
1508               if (!anItem) {
1509                 anItem = new QListBoxText(aText);
1510                 myElements->insertItem(anItem);
1511               }
1512               myElements->setSelected(anItem, true);
1513             }
1514           }
1515           catch (const SALOME::SALOME_Exception& ex) {
1516             SalomeApp_Tools::QtCatchCorbaException(ex);
1517           }
1518         }
1519       }
1520     }
1521     mySelectSubMesh->setChecked(false);
1522     myIsBusy = false;
1523     onListSelectionChanged();
1524
1525   } else if (myCurrentLineEdit == myGroupLine) {
1526     //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
1527     SALOME_ListIO aList;
1528     mySelectionMgr->selectedObjects( aList );
1529
1530     SALOME_ListIteratorOfListIO anIt (aList);
1531     for (; anIt.More(); anIt.Next()) {
1532       SMESH::SMESH_Group_var aGroup =
1533         SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
1534       if (!aGroup->_is_nil()) {
1535         // check if mesh is the same
1536         if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
1537           SMESH::long_array_var anElements = aGroup->GetListOfID();
1538           int k = anElements->length();
1539           QListBoxItem* anItem = 0;
1540           for (int i = 0; i < k; i++) {
1541             QString aText = QString::number(anElements[i]);
1542             anItem = myElements->findItem(aText, Qt::ExactMatch);
1543             if (!anItem) {
1544               anItem = new QListBoxText(aText);
1545               myElements->insertItem(anItem);
1546             }
1547             myElements->setSelected(anItem, true);
1548           }
1549         }
1550       }
1551     }
1552     mySelectGroup->setChecked(false);
1553     myIsBusy = false;
1554     onListSelectionChanged();
1555
1556   } else if (myCurrentLineEdit == myGeomGroupLine && myGeomObjects->length() == 1) {
1557     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
1558     GEOM::GEOM_IGroupOperations_var aGroupOp =
1559       SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
1560
1561     SMESH::ElementType aGroupType = SMESH::ALL;
1562     switch(aGroupOp->GetType(myGeomObjects[0])) {
1563     case 7: aGroupType = SMESH::NODE; break;
1564     case 6: aGroupType = SMESH::EDGE; break;
1565     case 4: aGroupType = SMESH::FACE; break;
1566     case 2: aGroupType = SMESH::VOLUME; break;
1567     default: myIsBusy = false; return;
1568     }
1569
1570     if (aGroupType == aType) {
1571       _PTR(SObject) aGroupSO =
1572         //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(myGeomGroup));
1573         aStudy->FindObjectID(myGeomObjects[0]->GetStudyEntry());
1574       // Construct filter
1575       SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
1576       SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
1577       SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();;
1578       aBelongToGeom->SetGeom(myGeomObjects[0]);
1579       aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str());
1580       aBelongToGeom->SetElementType(aType);
1581       aFilter->SetPredicate(aBelongToGeom);
1582
1583       SMESH::long_array_var anElements = aFilter->GetElementsId(myMesh);
1584
1585       int k = anElements->length();
1586       QListBoxItem* anItem = 0;
1587       for (int i = 0; i < k; i++) {
1588         QString aText = QString::number(anElements[i]);
1589         anItem = myElements->findItem(aText, Qt::ExactMatch);
1590         if (!anItem) {
1591           anItem = new QListBoxText(aText);
1592           myElements->insertItem(anItem);
1593         }
1594         myElements->setSelected(anItem, true);
1595       }
1596     }
1597
1598     //VSR: mySelectGeomGroup->setChecked(false);
1599     myIsBusy = false;
1600     onListSelectionChanged();
1601   }
1602   myIsBusy = false;
1603   //  mySelectionMgr->clearSelected();
1604   updateButtons();
1605 }
1606
1607 //=================================================================================
1608 // function : onRemove()
1609 // purpose  :
1610 //=================================================================================
1611 void SMESHGUI_GroupDlg::onRemove()
1612 {
1613   myIsBusy = true;
1614   if (myCurrentLineEdit == 0) {
1615     for (int i = myElements->count(); i > 0; i--) {
1616       if (myElements->isSelected(i-1)) {
1617         myElements->removeItem(i-1);
1618       }
1619     }
1620   } else {
1621     SALOME_ListIO aList;
1622     mySelectionMgr->selectedObjects( aList );
1623
1624     int aNbSel = aList.Extent();
1625
1626     if (aNbSel == 0) { myIsBusy = false; return; }
1627
1628     SMESH::ElementType aType = SMESH::ALL;
1629     switch(myTypeId) {
1630     case 0: aType = SMESH::NODE; break;
1631     case 1: aType = SMESH::EDGE; break;
1632     case 2: aType = SMESH::FACE; break;
1633     case 3: aType = SMESH::VOLUME; break;
1634     }
1635
1636     if (myCurrentLineEdit == mySubMeshLine) {
1637       //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
1638       SALOME_ListIO aList;
1639       mySelectionMgr->selectedObjects( aList );
1640
1641       SALOME_ListIteratorOfListIO anIt (aList);
1642       for (; anIt.More(); anIt.Next()) {
1643         SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
1644         if (!aSubMesh->_is_nil()) {
1645           // check if mesh is the same
1646           if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
1647             if (aType == SMESH::NODE) {
1648               try {
1649                 SMESH::long_array_var anElements = aSubMesh->GetNodesId();
1650                 int k = anElements->length();
1651                 QListBoxItem* anItem = 0;
1652                 for (int i = 0; i < k; i++) {
1653                   anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
1654                   if (anItem) delete anItem;
1655                 }
1656               }
1657               catch (const SALOME::SALOME_Exception& ex) {
1658                 SalomeApp_Tools::QtCatchCorbaException(ex);
1659               }
1660             }
1661             else {
1662               try {
1663                 SMESH::long_array_var anElements = aSubMesh->GetElementsId();
1664                 int k = anElements->length();
1665                 QListBoxItem* anItem = 0;
1666                 for (int i = 0; i < k; i++) {
1667                   anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
1668                   if (anItem) delete anItem;
1669                 }
1670               }
1671               catch (const SALOME::SALOME_Exception& ex) {
1672                 SalomeApp_Tools::QtCatchCorbaException(ex);
1673               }
1674             }
1675           }
1676         }
1677       }
1678     }
1679     else if (myCurrentLineEdit == myGroupLine) {
1680       Standard_Boolean aRes;
1681       //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
1682       SALOME_ListIO aList;
1683       mySelectionMgr->selectedObjects( aList );
1684
1685       SALOME_ListIteratorOfListIO anIt (aList);
1686       for (; anIt.More(); anIt.Next()) {
1687         SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
1688         if (aRes && !aGroup->_is_nil()) {
1689           // check if mesh is the same
1690           if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
1691             SMESH::long_array_var anElements = aGroup->GetListOfID();
1692             int k = anElements->length();
1693             QListBoxItem* anItem = 0;
1694             for (int i = 0; i < k; i++) {
1695               anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
1696               if (anItem) delete anItem;
1697             }
1698           }
1699         }
1700       }
1701     }
1702   }
1703   myIsBusy = false;
1704   updateButtons();
1705 }
1706
1707 //=================================================================================
1708 // function : onSort()
1709 // purpose  :
1710 //=================================================================================
1711 void SMESHGUI_GroupDlg::onSort()
1712 {
1713   // PAL5412: sorts items in ascending by "string" value
1714   // myElements->sort(true);
1715   // myElements->update();
1716   int i, k = myElements->count();
1717   if (k > 0) {
1718     myIsBusy = true;
1719     QStringList aSelected;
1720     std::vector<int> anArray(k);
1721     //    QMemArray<int> anArray(k);
1722     QListBoxItem* anItem;
1723     // fill the array
1724     for (anItem = myElements->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++) {
1725       anArray[i] = anItem->text().toInt();
1726       if (anItem->isSelected())
1727         aSelected.append(anItem->text());
1728     }
1729     // sort & update list
1730     std::sort(anArray.begin(), anArray.end());
1731     //    anArray.sort();
1732     myElements->clear();
1733     for (i = 0; i < k; i++) {
1734       myElements->insertItem(QString::number(anArray[i]));
1735     }
1736     for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it) {
1737       anItem = myElements->findItem(*it, Qt::ExactMatch);
1738       if (anItem) myElements->setSelected(anItem, true);
1739     }
1740     myIsBusy = false;
1741   }
1742 }
1743
1744 //=================================================================================
1745 // function : closeEvent()
1746 // purpose  :
1747 //=================================================================================
1748 void SMESHGUI_GroupDlg::closeEvent (QCloseEvent*)
1749 {
1750   onClose();
1751 }
1752
1753 //=================================================================================
1754 // function : SMESHGUI_GroupDlg::onClose
1755 // purpose  : SLOT called when "Close" button pressed. Close dialog
1756 //=================================================================================
1757 void SMESHGUI_GroupDlg::onClose()
1758 {
1759   if (SMESH::GetCurrentVtkView()) {
1760     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
1761     SMESH::SetPointRepresentation(false);
1762     SMESH::SetPickable();
1763     restoreShowEntityMode();
1764   }
1765
1766   mySelectionMgr->clearSelected();
1767   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1768     aViewWindow->SetSelectionMode(ActorSelection);
1769   mySelectionMgr->clearFilters();
1770   mySMESHGUI->ResetState();
1771
1772   reject();
1773 }
1774
1775 //=================================================================================
1776 // function : onHelp()
1777 // purpose  :
1778 //=================================================================================
1779 void SMESHGUI_GroupDlg::onHelp()
1780 {
1781   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1782   if (app)
1783     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""),
1784                              myHelpFileName);
1785   else {
1786     QString platform;
1787 #ifdef WIN32
1788     platform = "winapplication";
1789 #else
1790     platform = "application";
1791 #endif
1792     SUIT_MessageBox::warn1
1793       (0, QObject::tr("WRN_WARNING"),
1794        QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1795        arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
1796        QObject::tr("BUT_OK"));
1797   }
1798 }
1799
1800 //=================================================================================
1801 // function : SMESHGUI_GroupDlg::onDeactivate
1802 // purpose  : SLOT called when dialog must be deativated
1803 //=================================================================================
1804 void SMESHGUI_GroupDlg::onDeactivate()
1805 {
1806   mySMESHGUI->ResetState();
1807   setEnabled(false);
1808 }
1809
1810 //=================================================================================
1811 // function : SMESHGUI_GroupDlg::enterEvent
1812 // purpose  : Event filter
1813 //=================================================================================
1814 void SMESHGUI_GroupDlg::enterEvent (QEvent*)
1815 {
1816   if (!isEnabled()) {
1817     mySMESHGUI->EmitSignalDeactivateDialog();
1818     setEnabled(true);
1819     mySelectionMode = -1;
1820     setSelectionMode(myTypeId);
1821     //mySMESHGUI->SetActiveDialogBox((QDialog*)this);
1822     mySMESHGUI->SetActiveDialogBox(this);
1823     mySMESHGUI->SetState(800);
1824   }
1825 }
1826
1827 //=================================================================================
1828 // function : hideEvent
1829 // purpose  : caused by ESC key
1830 //=================================================================================
1831 void SMESHGUI_GroupDlg::hideEvent (QHideEvent*)
1832 {
1833   if (!isMinimized() && !myIsBusy)
1834     onClose();
1835 }
1836
1837 //=================================================================================
1838 // function : keyPressEvent()
1839 // purpose  :
1840 //=================================================================================
1841 void SMESHGUI_GroupDlg::keyPressEvent( QKeyEvent* e )
1842 {
1843   QDialog::keyPressEvent( e );
1844   if ( e->isAccepted() )
1845     return;
1846
1847   if ( e->key() == Key_F1 )
1848     {
1849       e->accept();
1850       onHelp();
1851     }
1852 }
1853
1854 //================================================================================
1855 /*!
1856  * \brief Enable showing of the popup when Geometry selection btn is clicked
1857   * \param enable - true to enable
1858  */
1859 //================================================================================
1860
1861 enum { DIRECT_GEOM_INDEX = 0, GEOM_BY_MESH_INDEX };
1862
1863 void SMESHGUI_GroupDlg::updateGeomPopup()
1864 {
1865   bool enable = false;
1866
1867   if ( !myMesh->_is_nil() )
1868     enable = myMesh->NbEdges() > 0;
1869
1870   if ( myGeomGroupBtn )
1871   {
1872     disconnect( myGeomGroupBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
1873     if ( enable ) {
1874       if ( !myGeomPopup ) {
1875         myGeomPopup = new QPopupMenu();
1876         myGeomPopup->insertItem( tr("DIRECT_GEOM_SELECTION"), DIRECT_GEOM_INDEX );
1877         myGeomPopup->insertItem( tr("GEOM_BY_MESH_ELEM_SELECTION"), GEOM_BY_MESH_INDEX );
1878         connect( myGeomPopup, SIGNAL( activated( int ) ), SLOT( onGeomPopup( int ) ) );
1879       }
1880       connect( myGeomGroupBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
1881     }
1882   }
1883 }
1884
1885
1886 //=================================================================================
1887 // function : onGeomSelectionButton()
1888 // purpose  :
1889 //=================================================================================
1890 void SMESHGUI_GroupDlg::onGeomSelectionButton(bool isBtnOn)
1891 {
1892   if ( myGeomPopup && isBtnOn )
1893     {
1894       myCurrentLineEdit = myGeomGroupLine;
1895       int id = myGeomPopup->exec( QCursor::pos() );
1896       if (id == DIRECT_GEOM_INDEX || id == -1)
1897         setSelectionMode(7);
1898     }
1899   else if (!isBtnOn)
1900     {
1901       myCurrentLineEdit = 0;
1902       setSelectionMode(8);
1903     }
1904 }
1905
1906 //=================================================================================
1907 // function : onGeomPopup()
1908 // purpose  :
1909 //=================================================================================
1910 void SMESHGUI_GroupDlg::onGeomPopup( int index )
1911 {
1912   if ( index == GEOM_BY_MESH_INDEX )
1913     {
1914       mySelectionMode = -1;
1915       if ( !myShapeByMeshOp ) {
1916         myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true);
1917         connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)),
1918                 SLOT(onPublishShapeByMeshDlg(SUIT_Operation*)));
1919         connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)),
1920                 SLOT(onCloseShapeByMeshDlg(SUIT_Operation*)));
1921       }
1922       // set mesh object to SMESHGUI_ShapeByMeshOp and start it
1923       if ( !myMesh->_is_nil() ) {
1924         myIsBusy = true;
1925         hide(); // stop processing selection
1926         myIsBusy = false;
1927         myShapeByMeshOp->setModule( mySMESHGUI );
1928         myShapeByMeshOp->setStudy( 0 ); // it's really necessary
1929         myShapeByMeshOp->SetMesh( myMesh );
1930         myShapeByMeshOp->start();
1931       }
1932     }
1933 }
1934
1935 //================================================================================
1936 /*!
1937  * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg
1938  */
1939 //================================================================================
1940
1941 void SMESHGUI_GroupDlg::onPublishShapeByMeshDlg(SUIT_Operation* op)
1942 {
1943   if ( myShapeByMeshOp == op ) {
1944     mySMESHGUI->getApp()->updateObjectBrowser();
1945     show();
1946     // Select a found geometry object
1947     GEOM::GEOM_Object_var aGeomVar = myShapeByMeshOp->GetShape();
1948     if ( !aGeomVar->_is_nil() )
1949     {
1950       QString ID = aGeomVar->GetStudyEntry();
1951       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
1952       if ( _PTR(SObject) aGeomSO = aStudy->FindObjectID( ID.latin1() )) {
1953         SALOME_ListIO anIOList;
1954         Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
1955           ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() );
1956         anIOList.Append( anIO );
1957               mySelectionMgr->setSelectedObjects( anIOList, false );
1958         onObjectSelectionChanged();
1959       }
1960     }
1961   }
1962 }
1963
1964 //================================================================================
1965 /*!
1966  * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg
1967  */
1968 //================================================================================
1969
1970 void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op)
1971 {
1972   if ( myShapeByMeshOp == op )
1973     {
1974       show();
1975       setSelectionMode(7);
1976     }
1977 }
1978
1979 //=================================================================================
1980 // function : setGroupColor()
1981 // purpose  :
1982 //=================================================================================
1983 void SMESHGUI_GroupDlg::setGroupColor( const SALOMEDS::Color& theColor )
1984 {
1985   QColor aQColor( (int)( theColor.R * 255.0 ),
1986                   (int)( theColor.G * 255.0 ),
1987                   (int)( theColor.B * 255.0 ) );
1988   setGroupQColor( aQColor );
1989 }
1990
1991 //=================================================================================
1992 // function : getGroupColor()
1993 // purpose  :
1994 //=================================================================================
1995 SALOMEDS::Color SMESHGUI_GroupDlg::getGroupColor() const
1996 {
1997   QColor aQColor = getGroupQColor();
1998
1999   SALOMEDS::Color aColor;
2000   aColor.R = (float)aQColor.red() / 255.0;
2001   aColor.G = (float)aQColor.green() / 255.0;
2002   aColor.B = (float)aQColor.blue() / 255.0;
2003
2004   return aColor;
2005 }
2006
2007 //=================================================================================
2008 // function : setGroupQColor()
2009 // purpose  :
2010 //=================================================================================
2011 void SMESHGUI_GroupDlg::setGroupQColor( const QColor& theColor )
2012 {
2013   if ( theColor.isValid() )
2014   {
2015     QPalette pal = myColorBtn->palette();
2016     pal.setColor(QColorGroup::Button, theColor);
2017     myColorBtn->setPalette(pal);
2018   }
2019 }
2020
2021 //=================================================================================
2022 // function : getGroupQColor()
2023 // purpose  :
2024 //=================================================================================
2025 QColor SMESHGUI_GroupDlg::getGroupQColor() const
2026 {
2027   QColor aColor = myColorBtn->palette().active().button();
2028   return aColor;
2029 }
2030
2031 //=================================================================================
2032 // function : setDefaultGroupColor()
2033 // purpose  :
2034 //=================================================================================
2035 void SMESHGUI_GroupDlg::setDefaultGroupColor()
2036 {
2037   if ( myMesh->_is_nil() )
2038     return;
2039
2040   bool isAutoColor = myMesh->GetAutoColor();
2041
2042   QColor aQColor;
2043   if ( !isAutoColor )
2044   {
2045     int r = 0, g = 0, b = 0;
2046     SMESH::GetColor( "SMESH", "fill_color", r, g, b, QColor( 0, 170, 255 ) );
2047     aQColor.setRgb( r, g, b );
2048   }
2049   else
2050   {
2051     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
2052
2053     QValueList<SALOMEDS::Color> aReservedColors;
2054     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ )
2055     {
2056       SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i];
2057       SALOMEDS::Color aReservedColor = aGroupObject->GetColor();
2058       aReservedColors.append( aReservedColor );
2059     }
2060
2061     SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
2062     aQColor.setRgb( (int)( aColor.R * 255.0 ),
2063                     (int)( aColor.G * 255.0 ),
2064                     (int)( aColor.B * 255.0 ) );
2065
2066   }
2067
2068   setGroupQColor( aQColor );
2069 }
2070
2071 //=================================================================================
2072 // function : SetAppropriateActor()
2073 // purpose  : Find more appropriate of visible actors, set it to myActor, allow picking
2074 //            NPAL19389: create a group with a selection in another group.
2075 //            if mesh actor is not visible - find any first visible group or submesh
2076 //=================================================================================
2077 bool SMESHGUI_GroupDlg::SetAppropriateActor()
2078 {
2079   bool isActor = false;
2080
2081   if (myMesh->_is_nil()) return false;
2082
2083   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
2084
2085   // try mesh actor
2086   myActor = SMESH::FindActorByObject(myMesh);
2087   if (myActor && myActor->hasIO())
2088   {
2089     isActor = true;
2090     if (aViewWindow && !aViewWindow->isVisible(myActor->getIO()))
2091         isActor = false;
2092   }
2093
2094   // try current group actor
2095   if (!isActor) {
2096     if (!myGroup->_is_nil()) {
2097       myActor = SMESH::FindActorByObject(myGroup);
2098       if (myActor && myActor->hasIO())
2099       {
2100         isActor = true;
2101         if (aViewWindow && !aViewWindow->isVisible(myActor->getIO()))
2102             isActor = false;
2103       }
2104     }
2105   }
2106
2107   // try current group on geometry actor
2108   if (!isActor) {
2109     if (!myGroupOnGeom->_is_nil()) {
2110       myActor = SMESH::FindActorByObject(myGroupOnGeom);
2111       if (myActor && myActor->hasIO())
2112       {
2113         isActor = true;
2114         if (aViewWindow && !aViewWindow->isVisible(myActor->getIO()))
2115           isActor = false;
2116       }
2117     }
2118   }
2119
2120   // try any visible actor of group or submesh of current mesh
2121   if (!isActor && aViewWindow) {
2122     // mesh entry
2123     _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
2124     if (aSObject) {
2125       CORBA::String_var meshEntry = aSObject->GetID().c_str();
2126       int len = strlen(meshEntry);
2127
2128       // iterate on all actors in current view window, search for
2129       // any visible actor, that belongs to group or submesh of current mesh
2130       vtkActorCollection *aCollection = aViewWindow->getRenderer()->GetActors();
2131       aCollection->InitTraversal();
2132       for (vtkActor *anAct = aCollection->GetNextActor();
2133            anAct && !isActor;
2134            anAct = aCollection->GetNextActor())
2135       {
2136         SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct);
2137         if (anActor && anActor->hasIO()) {
2138           Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
2139           if (aViewWindow->isVisible(anIO)) {
2140             if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0) {
2141               myActor = anActor;
2142               isActor = true;
2143             }
2144           }
2145         }
2146       }
2147     }
2148   }
2149
2150   if (isActor)
2151     SMESH::SetPickable(myActor);
2152
2153   return isActor;
2154 }
2155
2156 //=======================================================================
2157 //function : setShowEntityMode
2158 //purpose  : make shown only entity corresponding to my type
2159 //=======================================================================
2160 void SMESHGUI_GroupDlg::setShowEntityMode()
2161 {
2162   if ( !myMesh->_is_nil() ) {
2163     if ( SMESH_Actor* actor = SMESH::FindActorByObject(myMesh) ) {
2164       if (!myStoredShownEntity)
2165         myStoredShownEntity = actor->GetEntityMode();
2166       switch ( myTypeId ) {
2167       case 0: restoreShowEntityMode(); break;
2168       case 1: actor->SetEntityMode( SMESH_Actor::eEdges ); break;
2169       case 2: actor->SetEntityMode( SMESH_Actor::eFaces ); break;
2170       case 3: actor->SetEntityMode( SMESH_Actor::eVolumes ); break;
2171       }
2172     }
2173   }
2174 }
2175
2176 //=======================================================================
2177 //function : restoreShowEntityMode
2178 //purpose  : restore ShowEntity mode of myActor
2179 //=======================================================================
2180 void SMESHGUI_GroupDlg::restoreShowEntityMode()
2181 {
2182   if ( myStoredShownEntity && !myMesh->_is_nil() ) {
2183     if ( SMESH_Actor* actor = SMESH::FindActorByObject(myMesh) ) {
2184       actor->SetEntityMode(myStoredShownEntity);
2185     }
2186   }
2187   myStoredShownEntity = 0;
2188 }