Salome HOME
919fa2f9b666a512ec5f2e523c134ed0efe59e7b
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupOpDlg.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 // File   : SMESHGUI_GroupOpDlg.cxx
23 // Author : Sergey LITONIN, Open CASCADE S.A.S.
24 //
25
26 // SMESH includes
27 #include "SMESHGUI_GroupOpDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32
33 #include <SMESH_TypeFilter.hxx>
34
35 // SALOME GUI includes
36 #include <SUIT_ResourceMgr.h>
37 #include <SUIT_Desktop.h>
38 #include <SUIT_Session.h>
39 #include <SUIT_MessageBox.h>
40
41 #include <LightApp_Application.h>
42 #include <LightApp_SelectionMgr.h>
43 #include <SVTK_Selection.h>
44 #include <SVTK_ViewWindow.h>
45 #include <SALOME_ListIO.hxx>
46
47 // Qt includes
48 #include <QHBoxLayout>
49 #include <QVBoxLayout>
50 #include <QGridLayout>
51 #include <QPushButton>
52 #include <QGroupBox>
53 #include <QLabel>
54 #include <QLineEdit>
55 #include <QKeyEvent>
56
57 #define SPACING 6
58 #define MARGIN  11
59
60 /*!
61  *  Class       : SMESHGUI_GroupOpDlg
62  *  Description : Perform boolean operations on groups
63  */
64
65 //=======================================================================
66 // name    : SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg
67 // Purpose : Constructor
68 //=======================================================================
69 SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule, const int theMode )
70   : QDialog( SMESH::GetDesktop( theModule ) ),
71     mySMESHGUI( theModule ),
72     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
73 {
74   setModal(false);
75
76   myMode = theMode;
77
78   if (myMode == UNION) {
79     setWindowTitle(tr("UNION_OF_TWO_GROUPS"));
80     myHelpFileName = "using_operations_on_groups_page.html#union_anchor";
81   }
82   else if (myMode == INTERSECT) {
83     setWindowTitle(tr("INTERSECTION_OF_TWO_GROUPS"));
84     myHelpFileName = "using_operations_on_groups_page.html#intersection_anchor";
85   }
86   else {
87     setWindowTitle(tr("CUT_OF_TWO_GROUPS"));
88     myHelpFileName = "using_operations_on_groups_page.html#cut_anchor";
89   }
90
91   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
92
93   QVBoxLayout* aDlgLay = new QVBoxLayout (this);
94   aDlgLay->setMargin(MARGIN);
95   aDlgLay->setSpacing(SPACING);
96
97   QWidget* aMainFrame = createMainFrame  (this);
98   QWidget* aBtnFrame  = createButtonFrame(this);
99
100   aDlgLay->addWidget(aMainFrame);
101   aDlgLay->addWidget(aBtnFrame);
102
103   Init();
104 }
105
106 //=======================================================================
107 // name    : SMESHGUI_GroupOpDlg::createMainFrame
108 // Purpose : Create frame containing dialog's input fields
109 //=======================================================================
110 QWidget* SMESHGUI_GroupOpDlg::createMainFrame (QWidget* theParent)
111 {
112   QWidget* aMainGrp = new QWidget(theParent);
113   QVBoxLayout* aLay = new QVBoxLayout(aMainGrp);
114   aLay->setMargin(0);
115   aLay->setSpacing(SPACING);
116   
117   // ------------------------------------------------------
118   QGroupBox* aNameGrp = new QGroupBox(tr("NAME"), aMainGrp);
119   QHBoxLayout* aNameGrpLayout = new QHBoxLayout(aNameGrp);
120   aNameGrpLayout->setMargin(MARGIN);
121   aNameGrpLayout->setSpacing(SPACING);
122
123   QLabel* aNameLab = new QLabel(tr("RESULT_NAME"), aNameGrp);
124   myNameEdit = new QLineEdit(aNameGrp);
125
126   aNameGrpLayout->addWidget(aNameLab);
127   aNameGrpLayout->addWidget(myNameEdit);
128
129   // ------------------------------------------------------
130   QGroupBox* anArgGrp = new QGroupBox(tr("ARGUMENTS"), aMainGrp);
131   QGridLayout* anArgGrpLayout = new QGridLayout(anArgGrp);
132   anArgGrpLayout->setMargin(MARGIN);
133   anArgGrpLayout->setSpacing(SPACING);
134
135   QLabel* aObj1Lab = new QLabel(myMode == CUT ? tr("MAIN_OBJECT") :tr("OBJECT_1"), anArgGrp);
136   myBtn1 = new QPushButton(anArgGrp);
137   myEdit1 = new QLineEdit(anArgGrp);
138   myEdit1->setAlignment( Qt::AlignLeft );
139
140   QLabel* aObj2Lab = new QLabel(myMode == CUT ? tr("TOOL_OBJECT") :tr("OBJECT_2"), anArgGrp);
141   myBtn2 = new QPushButton(anArgGrp);
142   myEdit2 = new QLineEdit(anArgGrp);
143   myEdit2->setAlignment( Qt::AlignLeft );
144
145   myEdit1->setReadOnly(true);
146   myEdit2->setReadOnly(true);
147
148   QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
149   myBtn1->setIcon(aPix);
150   myBtn2->setIcon(aPix);
151
152   anArgGrpLayout->addWidget(aObj1Lab, 0, 0);
153   anArgGrpLayout->addWidget(myBtn1,   0, 1);
154   anArgGrpLayout->addWidget(myEdit1,  0, 2);
155   anArgGrpLayout->addWidget(aObj2Lab, 1, 0);
156   anArgGrpLayout->addWidget(myBtn2,   1, 1);
157   anArgGrpLayout->addWidget(myEdit2,  1, 2);
158
159   // ------------------------------------------------------
160   aLay->addWidget(aNameGrp);
161   aLay->addWidget(anArgGrp);
162
163   return aMainGrp;
164 }
165
166 //=======================================================================
167 // name    : SMESHGUI_GroupOpDlg::createButtonFrame
168 // Purpose : Create frame containing buttons
169 //=======================================================================
170 QWidget* SMESHGUI_GroupOpDlg::createButtonFrame (QWidget* theParent)
171 {
172   QGroupBox* aFrame = new QGroupBox(theParent);
173
174   myOkBtn    = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aFrame);
175   myApplyBtn = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame);
176   myCloseBtn = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame);
177   myHelpBtn  = new QPushButton(tr("SMESH_BUT_HELP"),  aFrame);
178
179   QHBoxLayout* aLay = new QHBoxLayout(aFrame);
180   aLay->setMargin(MARGIN);
181   aLay->setSpacing(SPACING);
182
183   aLay->addWidget(myOkBtn);
184   aLay->addSpacing(10);
185   aLay->addWidget(myApplyBtn);
186   aLay->addSpacing(10);
187   aLay->addStretch();
188   aLay->addWidget(myCloseBtn);
189   aLay->addWidget(myHelpBtn);
190
191   // connect signals and slots
192   connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
193   connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
194   connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
195   connect(myHelpBtn,  SIGNAL(clicked()), SLOT(onHelp()));
196
197   return aFrame;
198 }
199
200 //=======================================================================
201 // name    : SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg
202 // Purpose : Destructor
203 //=======================================================================
204 SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg()
205 {
206 }
207
208 //=======================================================================
209 // name    : SMESHGUI_GroupOpDlg::Init
210 // Purpose : Init dialog fields, connect signals and slots, show dialog
211 //=======================================================================
212 void SMESHGUI_GroupOpDlg::Init()
213 {
214   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
215   myFocusWg = myEdit1;
216
217   myGroup1 = SMESH::SMESH_GroupBase::_nil();
218   myGroup2 = SMESH::SMESH_GroupBase::_nil();
219
220   // selection and SMESHGUI
221   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
222   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
223   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnClose()));
224
225   connect(myBtn1, SIGNAL(clicked()), this, SLOT(onFocusChanged()));
226   connect(myBtn2, SIGNAL(clicked()), this, SLOT(onFocusChanged()));
227
228   // set selection mode
229   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
230     aViewWindow->SetSelectionMode(ActorSelection);
231   mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
232 }
233
234 //=======================================================================
235 // name    : SMESHGUI_GroupOpDlg::isValid
236 // Purpose : Verify validity of input data
237 //=======================================================================
238 bool SMESHGUI_GroupOpDlg::isValid()
239 {
240   // Verify validity of group name
241   if (myNameEdit->text() == "") {
242     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
243                                  tr("EMPTY_NAME"));
244     return false;
245   }
246
247   // Verufy wheter arguments speciffiyed
248   if (myGroup1->_is_nil() || myGroup2->_is_nil()) {
249     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
250                                  tr("INCORRECT_ARGUMENTS"));
251     return false;
252   }
253
254   // Verify whether arguments belongs to same mesh
255   SMESH::SMESH_Mesh_ptr aMesh1 = myGroup1->GetMesh();
256   SMESH::SMESH_Mesh_ptr aMesh2 = myGroup2->GetMesh();
257
258   int aMeshId1 = !aMesh1->_is_nil() ? aMesh1->GetId() : -1;
259   int aMeshId2 = !aMesh2->_is_nil() ? aMesh2->GetId() : -1;
260
261   if (aMeshId1 != aMeshId2 || aMeshId1 == -1) {
262     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
263                                  tr("DIFF_MESHES"));
264     return false;
265   }
266
267   // Verify whether groups have same types of entities
268   if (myGroup1->GetType() != myGroup2->GetType()) {
269     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
270                                  tr("DIFF_TYPES"));
271     return false;
272   }
273
274   return true;
275 }
276
277 //=======================================================================
278 // name    : SMESHGUI_GroupOpDlg::onApply
279 // Purpose : SLOT called when "Apply" button pressed.
280 //=======================================================================
281 bool SMESHGUI_GroupOpDlg::onApply()
282 {
283   if (!isValid() || mySMESHGUI->isActiveStudyLocked())
284     return false;
285
286   SMESH::SMESH_Mesh_ptr aMesh = myGroup1->GetMesh();
287   QString aName = myNameEdit->text();
288   SMESH::SMESH_Group_ptr aNewGrp = SMESH::SMESH_Group::_nil();
289
290   if (myMode == UNION) aNewGrp = aMesh->UnionGroups(myGroup1, myGroup2, aName.toLatin1().data());
291   else if (myMode == INTERSECT) aNewGrp = aMesh->IntersectGroups(myGroup1, myGroup2, aName.toLatin1().data());
292   else aNewGrp = aMesh->CutGroups(myGroup1, myGroup2, aName.toLatin1().data());
293
294   if (!aNewGrp->_is_nil()) {
295     mySMESHGUI->updateObjBrowser(true);
296     reset();
297     return true;
298   } else {
299     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
300                               tr("SMESH_OPERATION_FAILED"));
301     return false;
302   }
303 }
304
305 //=======================================================================
306 // name    : SMESHGUI_GroupOpDlg::onOk
307 // Purpose : SLOT called when "Ok" button pressed.
308 //=======================================================================
309 void SMESHGUI_GroupOpDlg::onOk()
310 {
311   if (onApply())
312     onClose();
313 }
314
315 //=======================================================================
316 // name    : SMESHGUI_GroupOpDlg::onClose
317 // Purpose : SLOT called when "Close" button pressed. Close dialog
318 //=======================================================================
319 void SMESHGUI_GroupOpDlg::onClose()
320 {
321   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
322     aViewWindow->SetSelectionMode(ActorSelection);
323   disconnect(mySelectionMgr, 0, this, 0);
324   disconnect(mySMESHGUI, 0, this, 0);
325   mySMESHGUI->ResetState();
326   mySelectionMgr->clearFilters();
327   reject();
328 }
329
330 //=================================================================================
331 // function : onHelp()
332 // purpose  :
333 //=================================================================================
334 void SMESHGUI_GroupOpDlg::onHelp()
335 {
336   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
337   if (app) 
338     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
339   else {
340     QString platform;
341 #ifdef WIN32
342     platform = "winapplication";
343 #else
344     platform = "application";
345 #endif
346     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
347                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
348                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
349                                                                  platform)).
350                              arg(myHelpFileName));
351   }
352 }
353
354 //=======================================================================
355 // name    : SMESHGUI_GroupOpDlg::onSelectionDone
356 // Purpose : SLOT called when selection changed
357 //=======================================================================
358 void SMESHGUI_GroupOpDlg::onSelectionDone()
359 {
360   if (myFocusWg == myEdit1)
361     myGroup1 = SMESH::SMESH_GroupBase::_nil();
362   else
363     myGroup2 = SMESH::SMESH_GroupBase::_nil();
364
365   myFocusWg->setText("");
366
367   SALOME_ListIO aList;
368   mySelectionMgr->selectedObjects(aList);
369
370   if (aList.Extent() == 1) {
371     SMESH::SMESH_GroupBase_var aGroup =
372       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First());
373
374     if (!aGroup->_is_nil())
375     {
376       myFocusWg->setText(aGroup->GetName());
377       myFocusWg->setCursorPosition( 0 );
378
379       if (myFocusWg == myEdit1)
380         myGroup1 = aGroup;
381       else
382         myGroup2 = aGroup;
383     }
384   }
385 }
386
387 //=======================================================================
388 // name    : SMESHGUI_GroupOpDlg::onDeactivate
389 // Purpose : SLOT called when dialog must be deativated
390 //=======================================================================
391 void SMESHGUI_GroupOpDlg::onDeactivate()
392 {
393   setEnabled(false);
394   mySelectionMgr->clearFilters();
395 }
396
397 //=======================================================================
398 // name    : SMESHGUI_GroupOpDlg::enterEvent
399 // Purpose : Event filter
400 //=======================================================================
401 void SMESHGUI_GroupOpDlg::enterEvent (QEvent*)
402 {
403   mySMESHGUI->EmitSignalDeactivateDialog();
404   setEnabled(true);
405   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
406     aViewWindow->SetSelectionMode(ActorSelection);
407   mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
408 }
409
410 //=======================================================================
411 // name    : SMESHGUI_GroupOpDlg::closeEvent
412 // purpose :
413 //=======================================================================
414 void SMESHGUI_GroupOpDlg::closeEvent (QCloseEvent*)
415 {
416   onClose();
417 }
418
419 //=======================================================================
420 // name    : SMESHGUI_GroupOpDlg::onFocusChanged
421 // Purpose : SLOT. Called when "Select" button pressed.
422 //=======================================================================
423 void SMESHGUI_GroupOpDlg::onFocusChanged()
424 {
425   const QObject* aSender = sender();
426   myFocusWg = aSender == myBtn1 ? myEdit1 : myEdit2;
427   onSelectionDone();
428 }
429
430 //=======================================================================
431 // name    : SMESHGUI_GroupOpDlg::reset
432 // Purpose : Rest state of dialog
433 //=======================================================================
434 void SMESHGUI_GroupOpDlg::reset()
435 {
436   myNameEdit->setText("");
437   myEdit1->setText("");
438   myEdit2->setText("");
439   myFocusWg = myEdit1;
440   myNameEdit->setFocus();
441 }
442
443 //=================================================================================
444 // function : keyPressEvent()
445 // purpose  :
446 //=================================================================================
447 void SMESHGUI_GroupOpDlg::keyPressEvent( QKeyEvent* e )
448 {
449   QDialog::keyPressEvent( e );
450   if ( e->isAccepted() )
451     return;
452
453   if ( e->key() == Qt::Key_F1 ) {
454     e->accept();
455     onHelp();
456   }
457 }