Salome HOME
23514: EDF 16031 - SMESH freezes
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupOpDlg.cxx
1 // Copyright (C) 2007-2016  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_GroupOpDlg.cxx
25 // Author : Sergey LITONIN, Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_GroupOpDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESH_TypeFilter.hxx"
34 #include <SMESH_ActorUtils.h>
35
36 #include <LightApp_Application.h>
37 #include <LightApp_SelectionMgr.h>
38 #include <QtxColorButton.h>
39 #include <SALOMEDSClient_SObject.hxx>
40 #include <SALOME_ListIO.hxx>
41 #include <SUIT_Desktop.h>
42 #include <SUIT_MessageBox.h>
43 #include <SUIT_OverrideCursor.h>
44 #include <SUIT_ResourceMgr.h>
45 #include <SUIT_Session.h>
46 #include <SVTK_Selection.h>
47 #include <SVTK_ViewWindow.h>
48
49 // Qt includes
50 #include <QButtonGroup>
51 #include <QCheckBox>
52 #include <QComboBox>
53 #include <QGridLayout>
54 #include <QGroupBox>
55 #include <QHBoxLayout>
56 #include <QKeyEvent>
57 #include <QLabel>
58 #include <QLineEdit>
59 #include <QListWidget>
60 #include <QPushButton>
61 #include <QVBoxLayout>
62
63 #define SPACING 6
64 #define MARGIN  11
65
66 /*!
67  *  Class       : SMESHGUI_GroupOpDlg
68  *  Description : Perform boolean operations on groups
69  */
70
71 /*!
72   \brief Constructor
73   \param theModule pointer on module instance
74 */
75 SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule )
76   : QDialog( SMESH::GetDesktop( theModule ) ),
77     mySMESHGUI( theModule ),
78     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
79     myIsApplyAndClose( false )
80 {
81   setModal(false);
82
83   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
84
85   QVBoxLayout* aDlgLay = new QVBoxLayout (this);
86   aDlgLay->setMargin(MARGIN);
87   aDlgLay->setSpacing(SPACING);
88
89   QWidget* aMainFrame = createMainFrame  (this);
90   QWidget* aBtnFrame  = createButtonFrame(this);
91
92   aDlgLay->addWidget(aMainFrame);
93   aDlgLay->addWidget(aBtnFrame);
94
95   Init();
96 }
97
98 /*!
99   \brief Creates frame containing dialog's input fields
100   \param theParent parent widget
101   \return pointer on created widget
102 */
103 QWidget* SMESHGUI_GroupOpDlg::createMainFrame( QWidget* theParent )
104 {
105   QWidget* aMainGrp = new QWidget(theParent);
106   QVBoxLayout* aLay = new QVBoxLayout(aMainGrp);
107   aLay->setMargin(0);
108   aLay->setSpacing(SPACING);
109   
110   // ------------------------------------------------------
111   QGroupBox* aNameGrp = new QGroupBox(tr("RESULT"), aMainGrp);
112   QHBoxLayout* aNameGrpLayout = new QHBoxLayout(aNameGrp);
113   aNameGrpLayout->setMargin(MARGIN);
114   aNameGrpLayout->setSpacing(SPACING);
115
116   QLabel* aNameLab = new QLabel(tr("RESULT_NAME"), aNameGrp);
117   myNameEdit = new QLineEdit(aNameGrp);
118
119   aNameGrpLayout->addWidget(aNameLab);
120   aNameGrpLayout->addWidget(myNameEdit);
121
122   // ------------------------------------------------------
123   myArgGrp = new QGroupBox(tr("ARGUMENTS"), aMainGrp);
124
125
126   // ------------------------------------------------------
127   
128   QGroupBox* aColorBox = new QGroupBox(tr( "SMESH_SET_COLOR" ), this);
129   QHBoxLayout* aColorBoxLayout = new QHBoxLayout(aColorBox);
130   aColorBoxLayout->setMargin(MARGIN);
131   aColorBoxLayout->setSpacing(SPACING);
132
133   QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox );
134   myColorBtn = new QtxColorButton(aColorBox);
135   myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding, 
136                              myColorBtn->sizePolicy().verticalPolicy() );
137
138   aColorBoxLayout->addWidget(aColorLab);
139   aColorBoxLayout->addWidget(myColorBtn);
140
141   // ------------------------------------------------------
142   aLay->addWidget( aNameGrp );
143   aLay->addWidget( myArgGrp );
144   aLay->addWidget( aColorBox );
145
146   return aMainGrp;
147 }
148
149 /*!
150   \brief Gets pointer on arguments group box
151   \return pointer on arguments group box
152 */
153 QGroupBox* SMESHGUI_GroupOpDlg::getArgGrp() const
154 {
155   return myArgGrp;
156 }
157
158 /*!
159   \brief Sets help file name
160   \param theFName help file name
161 */
162 void SMESHGUI_GroupOpDlg::setHelpFileName( const QString& theFName )
163 {
164   myHelpFileName = theFName;
165 }
166
167 /*!
168   \brief Gets pointer to the module instance
169   \return pointer to the module instance
170 */
171 SMESHGUI* SMESHGUI_GroupOpDlg::getSMESHGUI() const
172 {
173   return mySMESHGUI;
174 }
175
176 /*!
177   \brief Create frame containing buttons
178   \param theParent parent widget
179   \return pointer to the created frame
180 */
181 QWidget* SMESHGUI_GroupOpDlg::createButtonFrame (QWidget* theParent)
182 {
183   QGroupBox* aFrame = new QGroupBox(theParent);
184
185   myOkBtn    = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aFrame);
186   myApplyBtn = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame);
187   myCloseBtn = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame);
188   myHelpBtn  = new QPushButton(tr("SMESH_BUT_HELP"),  aFrame);
189
190   QHBoxLayout* aLay = new QHBoxLayout(aFrame);
191   aLay->setMargin(MARGIN);
192   aLay->setSpacing(SPACING);
193
194   aLay->addWidget(myOkBtn);
195   aLay->addSpacing(10);
196   aLay->addWidget(myApplyBtn);
197   aLay->addSpacing(10);
198   aLay->addStretch();
199   aLay->addWidget(myCloseBtn);
200   aLay->addWidget(myHelpBtn);
201
202   // connect signals and slots
203   connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
204   connect(myCloseBtn, SIGNAL(clicked()), SLOT(reject()));
205   connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
206   connect(myHelpBtn,  SIGNAL(clicked()), SLOT(onHelp()));
207
208   return aFrame;
209 }
210
211 /*!
212   \brief Destructor
213 */
214 SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg()
215 {
216 }
217
218 /*!
219   \brief Init dialog fields, connect signals and slots, show dialog
220 */
221 void SMESHGUI_GroupOpDlg::Init()
222 {
223   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
224   
225   // selection and SMESHGUI
226   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
227   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
228   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(reject()));
229   connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), SLOT(onOpenView()));
230   connect(mySMESHGUI, SIGNAL(SignalCloseView()), SLOT(onCloseView()));
231
232   // set selection mode
233   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
234     aViewWindow->SetSelectionMode(ActorSelection);
235   mySelectionMgr->installFilter(new SMESH_TypeFilter (SMESH::GROUP));
236
237   setDefaultGroupColor();
238 }
239
240 /*!
241   \brief Validate list of groups used for operation. Checks whether they corresponds 
242   to the same face and have one type
243   \param theListGrp input list of groups 
244   \return TRUE if groups are valid, FALSE otherwise
245 */
246 bool SMESHGUI_GroupOpDlg::isValid( const QList<SMESH::SMESH_GroupBase_var>& theListGrp )
247 {
248   if ( theListGrp.isEmpty() )
249   {
250     SUIT_MessageBox::information( this, tr("SMESH_INSUFFICIENT_DATA"),
251                                   tr("INCORRECT_ARGUMENTS") );
252     return false;
253   }
254
255   int aMeshId = -1, aGrpType = -1;
256   QList<SMESH::SMESH_GroupBase_var>::const_iterator anIter;
257   for ( anIter = theListGrp.begin(); anIter != theListGrp.end(); ++anIter )
258   {
259     SMESH::SMESH_GroupBase_var aGrp = *anIter;
260     if ( CORBA::is_nil( aGrp ) )
261       continue; // nonsense
262
263     SMESH::SMESH_Mesh_var aMesh = aGrp->GetMesh();
264     if ( CORBA::is_nil( aMesh ) )
265       continue;
266
267     // mesh id
268     int aCurrId = aMesh->GetId();
269     if ( aMeshId == -1 )
270       aMeshId = aCurrId;
271     else 
272     {
273       if ( aMeshId != aCurrId )
274       {
275         aMeshId = -1; // different meshes
276         break;
277       }
278     }
279
280     // group type
281     int aCurrType = aGrp->GetType();
282     if ( aGrpType == -1 )
283       aGrpType = aCurrType;
284     else 
285     {
286       if ( aGrpType != aCurrType )
287       {
288         aGrpType = -1; // different types
289         break;
290       }
291     }
292
293   }
294
295   if ( aMeshId == -1 )
296   {
297     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
298                                  tr("DIFF_MESHES"));
299     return false;
300   }
301
302   if ( aGrpType == -1 ) 
303   {
304     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
305                                  tr("DIFF_TYPES"));
306     return false;
307   }
308
309   return true;
310 }
311
312 /*!
313   \brief SLOT called when "Ok" button pressed performs operation and closes dialog box
314 */
315 void SMESHGUI_GroupOpDlg::onOk()
316 {
317   SUIT_OverrideCursor oc;
318   setIsApplyAndClose( true );
319   if ( onApply() )
320     reject();
321   setIsApplyAndClose( false );
322 }
323
324 /*!
325   \brief SLOT called when dialog is closed
326 */
327 void SMESHGUI_GroupOpDlg::reject()
328 {
329   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
330     aViewWindow->SetSelectionMode(ActorSelection);
331   disconnect( mySelectionMgr, 0, this, 0 );
332   disconnect( mySMESHGUI, 0, this, 0 );
333   mySMESHGUI->ResetState();
334   mySelectionMgr->clearFilters();
335   reset();
336   QDialog::reject();
337 }
338
339 //=================================================================================
340 // function : onOpenView()
341 // purpose  :
342 //=================================================================================
343 void SMESHGUI_GroupOpDlg::onOpenView()
344 {
345   if ( mySelector ) {
346     SMESH::SetPointRepresentation(false);
347   }
348   else {
349     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
350     mySMESHGUI->EmitSignalDeactivateDialog();
351     setEnabled(true);
352   }
353 }
354
355 //=================================================================================
356 // function : onCloseView()
357 // purpose  :
358 //=================================================================================
359 void SMESHGUI_GroupOpDlg::onCloseView()
360 {
361   onDeactivate();
362   mySelector = 0;
363 }
364
365 /*!
366   \brief SLOT called when "Help" button pressed shows "Help" page
367 */
368 void SMESHGUI_GroupOpDlg::onHelp()
369 {
370   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
371   if (app) 
372     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
373   else {
374     QString platform;
375 #ifdef WIN32
376     platform = "winapplication";
377 #else
378     platform = "application";
379 #endif
380     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
381                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
382                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
383                                                                  platform)).
384                              arg(myHelpFileName));
385   }
386 }
387
388 /*!
389   \brief Gets list of currently selected groups from selection manager
390   \param theOutList out list of groups
391   \param theOutNames out list of group of group names
392   \return TRUE if operation theOutList is not empty, FALSE otherwise
393 */
394 bool SMESHGUI_GroupOpDlg::getSelectedGroups( QList<SMESH::SMESH_GroupBase_var>& theOutList, 
395                                              QStringList& theOutNames )
396 {
397   theOutList.clear();
398
399   theOutList.clear();
400   theOutNames.clear();
401
402   SALOME_ListIO aListIO;
403   mySelectionMgr->selectedObjects( aListIO );
404   SALOME_ListIteratorOfListIO anIter ( aListIO );
405   for ( ; anIter.More(); anIter.Next()) 
406   {
407     SMESH::SMESH_GroupBase_var aGroup =
408       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
409     if ( !aGroup->_is_nil()) 
410     {
411       theOutList.append( aGroup );
412       theOutNames.append( aGroup->GetName() );
413     }
414   }
415
416   return theOutList.count() > 0;
417 }
418
419 /*!
420   \brief Converts QT-list of group to the list acceptable by IDL interface
421   \param theIn input list
422   \return list acceptable by IDL interface
423 */
424 SMESH::ListOfGroups* SMESHGUI_GroupOpDlg::convert( 
425   const QList<SMESH::SMESH_GroupBase_var>& theIn )
426 {
427   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
428   aList->length( theIn.count() );
429
430   QList<SMESH::SMESH_GroupBase_var>::const_iterator anIter = theIn.begin();
431   for ( int i = 0; anIter != theIn.end(); ++anIter, ++i )
432     aList[ i ] = *anIter;
433
434   return aList._retn();
435 }
436
437 /*!
438   \brief Get color to be assigned to group
439   \return color to be assigned to group
440 */
441 SALOMEDS::Color SMESHGUI_GroupOpDlg::getColor() const
442 {
443   QColor aQColor = myColorBtn->color();
444
445   SALOMEDS::Color aColor;
446   aColor.R = (float)aQColor.red() / 255.0;
447   aColor.G = (float)aQColor.green() / 255.0;
448   aColor.B = (float)aQColor.blue() / 255.0;
449
450   return aColor;
451 }
452
453 /*!
454   \brief Set default color for group
455 */
456 void SMESHGUI_GroupOpDlg::setDefaultGroupColor()
457 {
458   myColorBtn->setColor( SMESH::GetColor( "SMESH", "default_grp_color", QColor( 255, 170, 0 ) ) );
459 }
460
461 /*!
462   \brief SLOT, called when selection is changed. Current implementation does 
463    nothing. The method should be redefined in derived classes to update 
464    corresponding GUI controls
465 */
466 void SMESHGUI_GroupOpDlg::onSelectionDone()
467 {
468 }
469
470 /*!
471   \brief Calls onSelectionDone() and setVisible() method of base class
472   \param visible the visible state of the dialog 
473 */
474 void SMESHGUI_GroupOpDlg::setVisible( bool visible )
475 {
476   if ( visible )
477   {
478     onSelectionDone();
479     resize( minimumSizeHint().width(), sizeHint().height() );
480   }
481   QDialog::setVisible( visible );
482 }
483
484 /*!
485   \brief SLOT called when dialog must be deativated
486 */
487 void SMESHGUI_GroupOpDlg::onDeactivate()
488 {
489   setEnabled(false);
490   mySelectionMgr->clearFilters();
491 }
492
493 /*!
494   \brief Event filter updates selection mode and selection filter. This virtual method 
495   is redefined from the base class it is called when dialog obtains input focus
496 */
497 void SMESHGUI_GroupOpDlg::enterEvent(QEvent*)
498 {
499   mySMESHGUI->EmitSignalDeactivateDialog();
500   setEnabled(true);
501   SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
502   if ( aViewWindow ) {
503     aViewWindow->SetSelectionMode(ActorSelection);
504     if (!mySelector)
505       mySelector = aViewWindow->GetSelector();
506   }
507   mySelectionMgr->installFilter(new SMESH_TypeFilter (SMESH::GROUP));
508 }
509
510 /*!
511   \brief Resets state of the dialog, initializes its fields with default value, etc. 
512   Usually called by onApply() slot to reinitialize dialog  fields. This virtual method 
513   should be redefined in derived class to update its own fileds
514 */
515 void SMESHGUI_GroupOpDlg::reset()
516 {
517   myNameEdit->setText("");
518   myNameEdit->setFocus();
519   setDefaultGroupColor();
520 }
521
522 /*!
523   \brief Gets name of group to be created
524   \return name of group to be created
525   \sa setName()
526 */
527 QString SMESHGUI_GroupOpDlg::getName() const
528 {
529   return myNameEdit->text();
530 }
531
532 /*!
533   \brief Sets name of group to be created
534   \param theName name of group to be created
535   \sa getName()
536 */
537 void SMESHGUI_GroupOpDlg::setName( const QString& theName )
538 {
539   myNameEdit->setText( theName );
540 }
541
542 /*!
543   \brief Provides reaction on ï¿½F1� button pressing
544   \param e  key press event
545 */
546 void SMESHGUI_GroupOpDlg::keyPressEvent( QKeyEvent* e )
547 {
548   QDialog::keyPressEvent( e );
549   if ( e->isAccepted() )
550     return;
551
552   if ( e->key() == Qt::Key_F1 ) {
553     e->accept();
554     onHelp();
555   }
556 }
557
558 /*!
559   \brief This virtual slot does nothing and should be redefined in derived classes
560   \return return false;
561 */
562 bool SMESHGUI_GroupOpDlg::onApply()
563 {
564   return false;
565 }
566
567 /*!
568   \brief Set value of the flag indicating that the dialog is
569   accepted by Apply & Close button
570   \param theFlag value of the flag
571   \sa isApplyAndClose()
572 */
573 void SMESHGUI_GroupOpDlg::setIsApplyAndClose( const bool theFlag )
574 {
575   myIsApplyAndClose = theFlag;
576 }
577
578 /*!
579   \brief Get value of the flag indicating that the dialog is
580   accepted by Apply & Close button
581   \return value of the flag
582   \sa setApplyAndClose()
583 */
584 bool SMESHGUI_GroupOpDlg::isApplyAndClose() const
585 {
586   return myIsApplyAndClose;
587 }
588
589 // === === === === === === === === === === === === === === === === === === === === === 
590
591 /*!
592   \brief Constructor
593   \param theModule module
594 */
595 SMESHGUI_UnionGroupsDlg::SMESHGUI_UnionGroupsDlg( SMESHGUI* theModule )
596 : SMESHGUI_GroupOpDlg( theModule )
597 {
598   setWindowTitle(tr("UNION_OF_GROUPS"));
599   setHelpFileName( "using_operations_on_groups_page.html#union_anchor" );
600
601   QGroupBox* anArgGrp = getArgGrp();
602   myListWg = new QListWidget( anArgGrp );
603
604   QHBoxLayout* aLay = new QHBoxLayout( anArgGrp );
605   aLay->addWidget( myListWg );
606 }
607
608 /*!
609   \brief Destructor
610 */
611 SMESHGUI_UnionGroupsDlg::~SMESHGUI_UnionGroupsDlg()
612 {
613 }
614
615 /*!
616   \brief This virtual method redefined from the base class resets state 
617   of the dialog, initializes its fields with default value, etc. 
618 */
619 void SMESHGUI_UnionGroupsDlg::reset()
620 {
621   SMESHGUI_GroupOpDlg::reset();
622   myListWg->clear();
623   myGroups.clear();
624 }
625
626 /*!
627   \brief SLOT called when apply button is pressed performs operation
628   \return TRUE if operation has been completed successfully, FALSE otherwise
629 */
630 bool SMESHGUI_UnionGroupsDlg::onApply()
631 {
632   if ( getSMESHGUI()->isActiveStudyLocked())
633     return false;
634
635   // Verify validity of group name
636   if ( getName() == "" ) 
637   {
638     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
639                                  SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
640     return false;
641   }
642
643   if ( !isValid( myGroups ) )
644     return false;
645
646   SMESH::SMESH_Mesh_var aMesh = myGroups.first()->GetMesh();
647   QString aName = getName();
648   
649   bool aRes = false;
650   QStringList anEntryList;
651   try
652   {
653     SMESH::ListOfGroups_var aList = convert( myGroups );
654     SMESH::SMESH_Group_var aNewGrp = 
655       aMesh->UnionListOfGroups( aList, aName.toLatin1().constData() );
656     if ( !CORBA::is_nil( aNewGrp ) )
657     {
658       aNewGrp->SetColor(  getColor() );
659       if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
660         anEntryList.append( aSObject->GetID().c_str() );
661       aRes = true;
662     }
663   }
664   catch( ... )
665   {
666     aRes = false;
667   }
668
669   if ( aRes ) 
670   {
671     SMESHGUI::Modified();
672     getSMESHGUI()->updateObjBrowser(true);
673     reset();
674     if( LightApp_Application* anApp =
675         dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
676       anApp->browseObjects( anEntryList, isApplyAndClose() );
677     return true;
678   } 
679   else 
680   {
681     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
682                               tr("SMESH_OPERATION_FAILED"));
683     return false;
684   }
685 }
686
687 /*!
688   \brief SLOT, called when selection is changed, updates corresponding GUI controls
689 */
690 void SMESHGUI_UnionGroupsDlg::onSelectionDone()
691 {
692   QStringList aNames;
693   getSelectedGroups( myGroups, aNames );
694   myListWg->clear();
695   myListWg->addItems( aNames );
696 }
697
698 // === === === === === === === === === === === === === === === === === === === === === 
699
700 /*!
701   \brief Constructor
702   \param theModule module
703 */
704 SMESHGUI_IntersectGroupsDlg::SMESHGUI_IntersectGroupsDlg( SMESHGUI* theModule )
705 : SMESHGUI_GroupOpDlg( theModule )
706 {
707   setWindowTitle(tr("INTERSECTION_OF_GROUPS"));
708   setHelpFileName( "using_operations_on_groups_page.html#intersection_anchor" );
709
710   QGroupBox* anArgGrp = getArgGrp();
711   myListWg = new QListWidget( anArgGrp );
712
713   QHBoxLayout* aLay = new QHBoxLayout( anArgGrp );
714   aLay->addWidget( myListWg );
715 }
716
717 /*!
718   \brief Destructor
719 */
720 SMESHGUI_IntersectGroupsDlg::~SMESHGUI_IntersectGroupsDlg()
721 {
722 }
723
724 /*!
725   \brief This virtual method redefined from the base class resets state 
726   of the dialog, initializes its fields with default value, etc. 
727 */
728 void SMESHGUI_IntersectGroupsDlg::reset()
729 {
730   SMESHGUI_GroupOpDlg::reset();
731   myListWg->clear();
732   myGroups.clear();
733 }
734
735 /*!
736   \brief SLOT called when apply button is pressed performs operation
737   \return TRUE if operation has been completed successfully, FALSE otherwise
738 */
739 bool SMESHGUI_IntersectGroupsDlg::onApply()
740 {
741   if ( getSMESHGUI()->isActiveStudyLocked())
742     return false;
743
744   // Verify validity of group name
745   if ( getName() == "" ) 
746   {
747     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
748                                  SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
749     return false;
750   }
751
752   if ( !isValid( myGroups ) )
753     return false;
754
755   SMESH::SMESH_Mesh_var aMesh = myGroups.first()->GetMesh();
756   QString aName = getName();
757   
758   bool aRes = false;
759   QStringList anEntryList;
760   try
761   {
762     SMESH::ListOfGroups_var aList = convert( myGroups );
763     SMESH::SMESH_Group_var aNewGrp = 
764       aMesh->IntersectListOfGroups( aList, aName.toLatin1().constData() );
765     if ( !CORBA::is_nil( aNewGrp ) )
766     {
767       aNewGrp->SetColor(  getColor() );
768       if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
769         anEntryList.append( aSObject->GetID().c_str() );
770       aRes = true;
771     }
772   }
773   catch( ... )
774   {
775     aRes = false;
776   }
777
778   if ( aRes ) 
779   {
780     SMESHGUI::Modified();
781     getSMESHGUI()->updateObjBrowser(true);
782     reset();
783     if( LightApp_Application* anApp =
784         dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
785       anApp->browseObjects( anEntryList, isApplyAndClose() );
786     return true;
787   } 
788   else 
789   {
790     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
791                               tr("SMESH_OPERATION_FAILED"));
792     return false;
793   }
794 }
795
796 /*!
797   \brief SLOT, called when selection is changed, updates corresponding GUI controls
798 */
799 void SMESHGUI_IntersectGroupsDlg::onSelectionDone()
800 {
801   QStringList aNames;
802   getSelectedGroups( myGroups, aNames );
803   myListWg->clear();
804   myListWg->addItems( aNames );
805 }
806
807 // === === === === === === === === === === === === === === === === === === === === === 
808
809 /*!
810   \brief Constructor
811   \param theModule module
812 */
813 SMESHGUI_CutGroupsDlg::SMESHGUI_CutGroupsDlg( SMESHGUI* theModule )
814 : SMESHGUI_GroupOpDlg( theModule )
815 {
816   setWindowTitle(tr("CUT_OF_GROUPS"));
817   setHelpFileName( "using_operations_on_groups_page.html#cut_anchor" );
818
819   QGroupBox* anArgGrp = getArgGrp();
820
821   QPixmap aPix (SMESH::GetResourceMgr( getSMESHGUI() )->loadPixmap("SMESH", tr("ICON_SELECT")));
822   
823   // frame 1
824   QFrame* aFrame1 = new QFrame( anArgGrp );
825   QLabel* aLbl1 = new QLabel( tr("MAIN_OBJECT"), aFrame1 );
826   aLbl1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
827   myBtn1 = new QPushButton( aFrame1 );
828   myBtn1->setIcon(aPix);
829   myListWg1 = new QListWidget( aFrame1 );
830
831   QGridLayout* aLay1 = new QGridLayout( aFrame1 );
832   aLay1->setSpacing( SPACING );
833   aLay1->addWidget( aLbl1, 0, 0 );
834   aLay1->addWidget( myBtn1, 0, 1 );
835   aLay1->addWidget( myListWg1, 1, 0, 1, 2 );
836   //QSpacerItem* aHSpacer1 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
837   //aLay1->addItem( aHSpacer1, 0, 2 );
838
839
840   // frame 2
841   QFrame* aFrame2 = new QFrame( anArgGrp );
842   QLabel* aLbl2 = new QLabel( tr("TOOL_OBJECT"), aFrame2 );
843   aLbl2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
844   myBtn2 = new QPushButton( aFrame2 );
845   myBtn2->setIcon(aPix);
846   myListWg2 = new QListWidget( aFrame2 );
847
848   QGridLayout* aLay2 = new QGridLayout( aFrame2 );
849   aLay2->setSpacing( SPACING );
850   aLay2->addWidget( aLbl2, 0, 0 );
851   aLay2->addWidget( myBtn2, 0, 1 );
852   aLay2->addWidget( myListWg2, 1, 0, 1, 2 );
853   //QSpacerItem* aHSpacer2 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
854   //aLay2->addItem( aHSpacer2, 0, 2 );
855
856   // create button group 
857
858   QButtonGroup* aGrp = new QButtonGroup( anArgGrp );
859   aGrp->addButton( myBtn1, 0 );
860   aGrp->addButton( myBtn2, 1 );
861   myBtn1->setCheckable( true );
862   myBtn2->setCheckable( true );
863   aGrp->setExclusive( true );
864   myBtn1->setChecked( true );
865   
866   // fill layout
867   QHBoxLayout* aLay = new QHBoxLayout( anArgGrp );
868   aLay->setSpacing( SPACING );
869   aLay->addWidget( aFrame1 );
870   aLay->addWidget( aFrame2 );
871 }
872
873 /*!
874   \brief Destructor
875 */
876 SMESHGUI_CutGroupsDlg::~SMESHGUI_CutGroupsDlg()
877 {
878 }
879
880 /*!
881   \brief This virtual method redefined from the base class resets state 
882   of the dialog, initializes its fields with default value, etc. 
883 */
884 void SMESHGUI_CutGroupsDlg::reset()
885 {
886   SMESHGUI_GroupOpDlg::reset();
887
888   myListWg1->clear();
889   myGroups1.clear();
890
891   myListWg2->clear();
892   myGroups2.clear();
893 }
894
895 /*!
896   \brief SLOT called when apply button is pressed performs operation
897   \return TRUE if operation has been completed successfully, FALSE otherwise
898 */
899 bool SMESHGUI_CutGroupsDlg::onApply()
900 {
901   if ( getSMESHGUI()->isActiveStudyLocked())
902     return false;
903
904   // Verify validity of group name
905   if ( getName() == "" ) 
906   {
907     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
908                                  SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
909     return false;
910   }
911
912   if ( myGroups1.isEmpty() || myGroups2.isEmpty() )
913   {
914     SUIT_MessageBox::information( this, tr("SMESH_INSUFFICIENT_DATA"),
915                                   SMESHGUI_GroupOpDlg::tr("INCORRECT_ARGUMENTS") );
916     return false;
917   }
918
919   QList<SMESH::SMESH_GroupBase_var> aGroups = myGroups1;
920   QList<SMESH::SMESH_GroupBase_var>::iterator anIter;
921   for ( anIter = myGroups2.begin(); anIter != myGroups2.end(); ++anIter )
922     aGroups.append( *anIter );
923
924   if ( !isValid( aGroups ) )
925     return false;
926
927   SMESH::SMESH_Mesh_var aMesh = myGroups1.first()->GetMesh();
928   QString aName = getName();
929   
930   bool aRes = false;
931   QStringList anEntryList;
932   try
933   {
934     SMESH::ListOfGroups_var aList1 = convert( myGroups1 );
935     SMESH::ListOfGroups_var aList2 = convert( myGroups2 );
936     SMESH::SMESH_Group_var aNewGrp = 
937       aMesh->CutListOfGroups( aList1, aList2, aName.toLatin1().constData() );
938     if ( !CORBA::is_nil( aNewGrp ) )
939     {
940       aNewGrp->SetColor(  getColor() );
941       if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
942         anEntryList.append( aSObject->GetID().c_str() );
943       aRes = true;
944     }
945   }
946   catch( ... )
947   {
948     aRes = false;
949   }
950
951   if ( aRes ) 
952   {
953     SMESHGUI::Modified();
954     getSMESHGUI()->updateObjBrowser(true);
955     reset();
956     if( LightApp_Application* anApp =
957         dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
958       anApp->browseObjects( anEntryList, isApplyAndClose() );
959     return true;
960   } 
961   else 
962   {
963     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
964                               tr("SMESH_OPERATION_FAILED"));
965     return false;
966   }
967 }
968
969 /*!
970   \brief SLOT, called when selection is changed, updates corresponding GUI controls
971 */
972 void SMESHGUI_CutGroupsDlg::onSelectionDone()
973 {
974   QStringList aNames;
975   if ( myBtn2->isChecked() )
976   {
977     getSelectedGroups( myGroups2, aNames );
978     myListWg2->clear();
979     myListWg2->addItems( aNames );
980   }
981   else 
982   {
983     getSelectedGroups( myGroups1, aNames );
984     myListWg1->clear();
985     myListWg1->addItems( aNames );
986   }
987 }
988
989 // === === === === === === === === === === === === === === === === === === === === === 
990
991 /*!
992   \brief Constructor
993   \param theModule module
994 */
995 SMESHGUI_DimGroupDlg::SMESHGUI_DimGroupDlg( SMESHGUI* theModule )
996   : SMESHGUI_GroupOpDlg( theModule )
997 {
998   setWindowTitle( tr( "CREATE_GROUP_OF_UNDERLYING_ELEMS" ) );
999   setHelpFileName( "group_of_underlying_elements_page.html" );
1000
1001   QGroupBox* anArgGrp = getArgGrp();
1002
1003   QLabel* aTypeLbl = new QLabel( tr( "ELEMENTS_TYPE" ), anArgGrp );
1004
1005   myTypeCombo = new QComboBox( anArgGrp );
1006   QStringList anItems;
1007   {
1008     anItems.append( tr( "MESH_NODE" ) );
1009     anItems.append( tr( "SMESH_EDGE" ) );
1010     anItems.append( tr( "SMESH_FACE" ) );
1011     anItems.append( tr( "SMESH_VOLUME" ) );
1012     anItems.append( tr( "SMESH_ELEM0D" ) );
1013     anItems.append( tr( "SMESH_BALL" ) );
1014   }
1015   myTypeCombo->addItems( anItems );
1016   myTypeCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1017
1018   QLabel* aNbNoLbl = new QLabel( tr( "NUMBER_OF_COMMON_NODES" ), anArgGrp );
1019
1020   myNbNoCombo = new QComboBox( anArgGrp );
1021   anItems.clear();
1022   {
1023     anItems.append( tr( "ALL" ) );
1024     anItems.append( tr( "MAIN" ) );
1025     anItems.append( tr( "AT_LEAST_ONE" ) );
1026     anItems.append( tr( "MAJORITY" ) );
1027   }
1028   myNbNoCombo->addItems( anItems );
1029   myNbNoCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1030
1031   myListWg = new QListWidget( anArgGrp );
1032
1033   myUnderlOnlyChk = new QCheckBox( tr("UNDERLYING_ENTITIES_ONLY"), anArgGrp );
1034   myUnderlOnlyChk->setChecked( false );
1035
1036   // layout
1037   QGridLayout* aLay = new QGridLayout( anArgGrp );
1038   aLay->setSpacing( SPACING );
1039   aLay->addWidget( aTypeLbl,        0, 0 );
1040   aLay->addWidget( myTypeCombo,     0, 1 );
1041   aLay->addWidget( aNbNoLbl,        1, 0 );
1042   aLay->addWidget( myNbNoCombo,     1, 1 );
1043   aLay->addWidget( myListWg,        2, 0, 1, 2 );
1044   aLay->addWidget( myUnderlOnlyChk, 3, 0 );
1045 }
1046
1047 /*!
1048   \brief Destructor
1049 */
1050 SMESHGUI_DimGroupDlg::~SMESHGUI_DimGroupDlg()
1051 {
1052 }
1053
1054 /*!
1055   \brief This virtual method redefined from the base class resets state 
1056   of the dialog, initializes its fields with default value, etc. 
1057 */
1058 void SMESHGUI_DimGroupDlg::reset()
1059 {
1060   SMESHGUI_GroupOpDlg::reset();
1061   myListWg->clear();
1062   myGroups.clear();
1063 }
1064
1065 /*!
1066   \brief Gets elements type
1067   \return elements type
1068   \sa setElementType()
1069 */
1070 SMESH::ElementType SMESHGUI_DimGroupDlg::getElementType() const
1071 {
1072   return (SMESH::ElementType)( myTypeCombo->currentIndex() + 1 );
1073 }
1074
1075 /*!
1076   \brief Sets elements type
1077   \param theElemType elements type
1078   \sa getElementType()
1079 */
1080 void SMESHGUI_DimGroupDlg::setElementType( const SMESH::ElementType& theElemType )
1081 {
1082   myTypeCombo->setCurrentIndex( theElemType - 1 );
1083 }
1084
1085 /*!
1086   \brief SLOT called when apply button is pressed performs operation
1087   \return TRUE if operation has been completed successfully, FALSE otherwise
1088 */
1089 bool SMESHGUI_DimGroupDlg::onApply()
1090 {
1091   if ( getSMESHGUI()->isActiveStudyLocked())
1092     return false;
1093
1094   // Verify validity of group name
1095   if ( getName() == "" ) 
1096   {
1097     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
1098                                  SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
1099     return false;
1100   }
1101
1102   if ( !isValid( myGroups ) )
1103     return false;
1104
1105   SMESH::SMESH_Mesh_var aMesh = myGroups.first()->GetMesh();
1106   QString aName = getName();
1107   
1108   bool aRes = false;
1109   QStringList anEntryList;
1110   try
1111   {
1112     SMESH::ListOfIDSources_var aList = new SMESH::ListOfIDSources();
1113     aList->length( myGroups.count() );
1114     QList<SMESH::SMESH_GroupBase_var>::const_iterator anIter = myGroups.begin();
1115     for ( int i = 0; anIter != myGroups.end(); ++anIter, ++i )
1116       aList[ i ] = SMESH::SMESH_IDSource::_narrow( *anIter );
1117
1118     SMESH::ElementType anElemType = getElementType();
1119     SMESH::NB_COMMON_NODES_ENUM aNbCoNodes =
1120       (SMESH::NB_COMMON_NODES_ENUM) myNbNoCombo->currentIndex();
1121
1122     SMESH::SMESH_Group_var aNewGrp =
1123       aMesh->CreateDimGroup( aList, anElemType, aName.toLatin1().constData(),
1124                              aNbCoNodes, myUnderlOnlyChk->isChecked() );
1125     if ( !CORBA::is_nil( aNewGrp ) )
1126     {
1127       aNewGrp->SetColor(  getColor() );
1128       if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
1129         anEntryList.append( aSObject->GetID().c_str() );
1130       aRes = true;
1131     }
1132   }
1133   catch( ... )
1134   {
1135     aRes = false;
1136   }
1137
1138   if ( aRes ) 
1139   {
1140     SMESHGUI::Modified();
1141     getSMESHGUI()->updateObjBrowser(true);
1142     reset();
1143     if( LightApp_Application* anApp =
1144         dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
1145       anApp->browseObjects( anEntryList, isApplyAndClose() );
1146     return true;
1147   } 
1148   else 
1149   {
1150     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
1151                               tr("SMESH_OPERATION_FAILED"));
1152     return false;
1153   }
1154 }
1155
1156 /*!
1157   \brief SLOT, called when selection is changed, updates corresponding GUI controls
1158 */
1159 void SMESHGUI_DimGroupDlg::onSelectionDone()
1160 {
1161   QStringList aNames;
1162   getSelectedGroups( myGroups, aNames );
1163   myListWg->clear();
1164   myListWg->addItems( aNames );
1165 }