Salome HOME
Update from local sources
[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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESHGUI_GroupOpDlg.cxx
25 //  Author : Sergey LITONIN
26 //  Module : SMESH
27
28 #include "SMESHGUI_GroupOpDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32
33 #include "SMESH_TypeFilter.hxx"
34
35 #include "SUIT_ResourceMgr.h"
36 #include "SUIT_Desktop.h"
37
38 #include "SalomeApp_SelectionMgr.h"
39 #include "SVTK_Selection.h"
40 #include "SALOME_ListIO.hxx"
41
42 // QT Includes
43 #include <qframe.h>
44 #include <qlayout.h>
45 #include <qpushbutton.h>
46 #include <qgroupbox.h>
47 #include <qlabel.h>
48 #include <qlistbox.h>
49 #include <qlineedit.h>
50 #include <qmessagebox.h>
51
52 #define SPACING 5
53 #define MARGIN  10
54
55 /*!
56  *  Class       : SMESHGUI_GroupOpDlg
57  *  Description : Perform boolean operations on groups
58  */
59
60 //=======================================================================
61 // name    : SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg
62 // Purpose : Constructor
63 //=======================================================================
64 SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg (QWidget*                theParent,
65                                           SalomeApp_SelectionMgr* theSelection,
66                                           const int               theMode)
67      : QDialog(theParent, "SMESHGUI_GroupOpDlg", false,
68                WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
69 {
70   myMode = theMode;
71
72   if (myMode == UNION) setCaption(tr("UNION_OF_TWO_GROUPS"));
73   else if (myMode == INTERSECT) setCaption(tr("INTERSECTION_OF_TWO_GROUPS"));
74   else setCaption(tr("CUT_OF_TWO_GROUPS"));
75
76   QVBoxLayout* aDlgLay = new QVBoxLayout (this, MARGIN, SPACING);
77
78   QFrame* aMainFrame = createMainFrame  (this);
79   QFrame* aBtnFrame  = createButtonFrame(this);
80
81   aDlgLay->addWidget(aMainFrame);
82   aDlgLay->addWidget(aBtnFrame);
83
84   aDlgLay->setStretchFactor(aMainFrame, 1);
85
86   Init(theSelection);
87 }
88
89 //=======================================================================
90 // name    : SMESHGUI_GroupOpDlg::createMainFrame
91 // Purpose : Create frame containing dialog's input fields
92 //=======================================================================
93 QFrame* SMESHGUI_GroupOpDlg::createMainFrame (QWidget* theParent)
94 {
95   QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
96   aMainGrp->setFrameStyle(QFrame::NoFrame);
97   aMainGrp->setInsideMargin(0);
98
99   QGroupBox* aNameGrp = new QGroupBox(1, Qt::Vertical, tr("NAME"), aMainGrp);
100   new QLabel(tr("RESULT_NAME"), aNameGrp);
101   myNameEdit = new QLineEdit(aNameGrp);
102
103   QGroupBox* anArgGrp = new QGroupBox(3, Qt::Horizontal, tr("ARGUMENTS"), aMainGrp);
104
105   new QLabel(myMode == CUT ? tr("MAIN_OBJECT") :tr("OBJECT_1"), anArgGrp);
106   myBtn1 = new QPushButton(anArgGrp);
107   myEdit1 = new QLineEdit(anArgGrp);
108   myEdit1->setAlignment( Qt::AlignLeft );
109
110   new QLabel(myMode == CUT ? tr("TOOL_OBJECT") :tr("OBJECT_2"), anArgGrp);
111   myBtn2 = new QPushButton(anArgGrp);
112   myEdit2 = new QLineEdit(anArgGrp);
113   myEdit2->setAlignment( Qt::AlignLeft );
114
115   myEdit1->setReadOnly(true);
116   myEdit2->setReadOnly(true);
117
118   QPixmap aPix (SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT")));
119   myBtn1->setPixmap(aPix);
120   myBtn2->setPixmap(aPix);
121
122   return aMainGrp;
123 }
124
125 //=======================================================================
126 // name    : SMESHGUI_GroupOpDlg::createButtonFrame
127 // Purpose : Create frame containing buttons
128 //=======================================================================
129 QFrame* SMESHGUI_GroupOpDlg::createButtonFrame (QWidget* theParent)
130 {
131   QFrame* aFrame = new QFrame(theParent);
132   aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
133
134   myOkBtn     = new QPushButton(tr("SMESH_BUT_OK"   ), aFrame);
135   myApplyBtn  = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame);
136   myCloseBtn  = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame);
137
138   QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
139
140   QHBoxLayout* aLay = new QHBoxLayout(aFrame, MARGIN, SPACING);
141
142   aLay->addWidget(myOkBtn);
143   aLay->addWidget(myApplyBtn);
144   aLay->addItem(aSpacer);
145   aLay->addWidget(myCloseBtn);
146
147   // connect signals and slots
148   connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
149   connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
150   connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
151
152   return aFrame;
153 }
154
155 //=======================================================================
156 // name    : SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg
157 // Purpose : Destructor
158 //=======================================================================
159 SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg()
160 {
161 }
162
163 //=======================================================================
164 // name    : SMESHGUI_GroupOpDlg::Init
165 // Purpose : Init dialog fields, connect signals and slots, show dialog
166 //=======================================================================
167 void SMESHGUI_GroupOpDlg::Init (SalomeApp_SelectionMgr* theSelection)
168 {
169   mySelectionMgr = theSelection;
170   SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
171   aSMESHGUI->SetActiveDialogBox((QDialog*)this);
172   myFocusWg = myEdit1;
173
174   myGroup1 = SMESH::SMESH_GroupBase::_nil();
175   myGroup2 = SMESH::SMESH_GroupBase::_nil();
176
177   // selection and SMESHGUI
178   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
179   connect(aSMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
180   connect(aSMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnClose()));
181
182   connect(myBtn1, SIGNAL(clicked()), this, SLOT(onFocusChanged()));
183   connect(myBtn2, SIGNAL(clicked()), this, SLOT(onFocusChanged()));
184
185   int x, y;
186   aSMESHGUI->DefineDlgPosition(this, x, y);
187   this->move(x, y);
188   this->show();
189
190   // set selection mode
191 #ifdef NEW_GUI
192   mySelectionMgr->setSelectionModes(ActorSelection, true);
193 #else
194   mySelectionMgr->setSelectionModes(ActorSelection);
195 #endif
196   mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
197
198   return;
199 }
200
201 //=======================================================================
202 // name    : SMESHGUI_GroupOpDlg::isValid
203 // Purpose : Verify validity of input data
204 //=======================================================================
205 bool SMESHGUI_GroupOpDlg::isValid()
206 {
207   // Verify validity of group name
208   if (myNameEdit->text() == "") {
209     QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
210                              tr("EMPTY_NAME"), QMessageBox::Ok);
211     return false;
212   }
213
214   // Verufy wheter arguments speciffiyed
215   if (myGroup1->_is_nil() || myGroup2->_is_nil()) {
216     QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
217                              tr("INCORRECT_ARGUMENTS"), QMessageBox::Ok);
218     return false;
219   }
220
221   // Verify whether arguments belongs to same mesh
222   SMESH::SMESH_Mesh_ptr aMesh1 = myGroup1->GetMesh();
223   SMESH::SMESH_Mesh_ptr aMesh2 = myGroup2->GetMesh();
224
225   int aMeshId1 = !aMesh1->_is_nil() ? aMesh1->GetId() : -1;
226   int aMeshId2 = !aMesh2->_is_nil() ? aMesh2->GetId() : -1;
227
228   if (aMeshId1 != aMeshId2 || aMeshId1 == -1) {
229     QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
230                              tr("DIFF_MESHES"), QMessageBox::Ok);
231     return false;
232   }
233
234   // Verify whether groups have same types of entities
235   if (myGroup1->GetType() != myGroup2->GetType()) {
236     QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
237                              tr("DIFF_TYPES"), QMessageBox::Ok);
238     return false;
239   }
240
241   return true;
242 }
243
244 //=======================================================================
245 // name    : SMESHGUI_GroupOpDlg::onApply
246 // Purpose : SLOT called when "Apply" button pressed.
247 //=======================================================================
248 bool SMESHGUI_GroupOpDlg::onApply()
249 {
250   if (!isValid() || SMESHGUI::GetSMESHGUI()->isActiveStudyLocked())
251     return false;
252
253   SMESH::SMESH_Mesh_ptr aMesh = myGroup1->GetMesh();
254   QString aName = myNameEdit->text();
255   SMESH::SMESH_Group_ptr aNewGrp = SMESH::SMESH_Group::_nil();
256
257   if (myMode == UNION) aNewGrp = aMesh->UnionGroups(myGroup1, myGroup2, aName.latin1());
258   else if (myMode == INTERSECT) aNewGrp = aMesh->IntersectGroups(myGroup1, myGroup2, aName.latin1());
259   else aNewGrp = aMesh->CutGroups(myGroup1, myGroup2, aName.latin1());
260
261   if (!aNewGrp->_is_nil()) {
262     SMESHGUI::GetSMESHGUI()->updateObjBrowser(true);
263     reset();
264     return true;
265   } else {
266     QMessageBox::critical(SMESHGUI::desktop(), tr("SMESH_ERROR"),
267                           tr("SMESH_OPERATION_FAILED"), "OK");
268     return false;
269   }
270 }
271
272 //=======================================================================
273 // name    : SMESHGUI_GroupOpDlg::onOk
274 // Purpose : SLOT called when "Ok" button pressed.
275 //=======================================================================
276 void SMESHGUI_GroupOpDlg::onOk()
277 {
278   if (onApply())
279     onClose();
280 }
281
282 //=======================================================================
283 // name    : SMESHGUI_GroupOpDlg::onClose
284 // Purpose : SLOT called when "Close" button pressed. Close dialog
285 //=======================================================================
286 void SMESHGUI_GroupOpDlg::onClose()
287 {
288   mySelectionMgr->setSelectionModes(ActorSelection);
289   disconnect(mySelectionMgr, 0, this, 0);
290   disconnect(SMESHGUI::GetSMESHGUI(), 0, this, 0);
291   SMESHGUI::GetSMESHGUI()->ResetState();
292   mySelectionMgr->clearFilters();
293   reject();
294 }
295
296 //=======================================================================
297 // name    : SMESHGUI_GroupOpDlg::onSelectionDone
298 // Purpose : SLOT called when selection changed
299 //=======================================================================
300 void SMESHGUI_GroupOpDlg::onSelectionDone()
301 {
302   if (myFocusWg == myEdit1)
303     myGroup1 = SMESH::SMESH_GroupBase::_nil();
304   else
305     myGroup2 = SMESH::SMESH_GroupBase::_nil();
306
307   myFocusWg->setText("");
308
309   SALOME_ListIO aList;
310   mySelectionMgr->selectedObjects(aList);
311
312   if (aList.Extent() == 1) {
313     SMESH::SMESH_GroupBase_var aGroup =
314       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First());
315
316     if (!aGroup->_is_nil())
317     {
318       myFocusWg->setText(aGroup->GetName());
319       myFocusWg->setCursorPosition( 0 );
320
321       if (myFocusWg == myEdit1)
322         myGroup1 = aGroup;
323       else
324         myGroup2 = aGroup;
325     }
326   }
327 }
328
329 //=======================================================================
330 // name    : SMESHGUI_GroupOpDlg::onDeactivate
331 // Purpose : SLOT called when dialog must be deativated
332 //=======================================================================
333 void SMESHGUI_GroupOpDlg::onDeactivate()
334 {
335   setEnabled(false);
336   mySelectionMgr->clearFilters();
337 }
338
339 //=======================================================================
340 // name    : SMESHGUI_GroupOpDlg::enterEvent
341 // Purpose : Event filter
342 //=======================================================================
343 void SMESHGUI_GroupOpDlg::enterEvent (QEvent*)
344 {
345   SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
346   setEnabled(true);
347 #ifdef NEW_GUI
348   mySelectionMgr->setSelectionModes(ActorSelection, true);
349 #else
350   mySelectionMgr->setSelectionModes(ActorSelection);
351 #endif
352   mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
353 }
354
355 //=======================================================================
356 // name    : SMESHGUI_GroupOpDlg::closeEvent
357 // purpose :
358 //=======================================================================
359 void SMESHGUI_GroupOpDlg::closeEvent (QCloseEvent*)
360 {
361   onClose();
362 }
363
364 //=======================================================================
365 // name    : SMESHGUI_GroupOpDlg::onFocusChanged
366 // Purpose : SLOT. Called when "Select" button pressed.
367 //=======================================================================
368 void SMESHGUI_GroupOpDlg::onFocusChanged()
369 {
370   const QObject* aSender = sender();
371   myFocusWg = aSender == myBtn1 ? myEdit1 : myEdit2;
372   onSelectionDone();
373 }
374
375 //=======================================================================
376 // name    : SMESHGUI_GroupOpDlg::reset
377 // Purpose : Rest state of dialog
378 //=======================================================================
379 void SMESHGUI_GroupOpDlg::reset()
380 {
381   myNameEdit->setText("");
382   myEdit1->setText("");
383   myEdit2->setText("");
384   myFocusWg = myEdit1;
385   myNameEdit->setFocus();
386 }