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