Salome HOME
Merge from V6_3_BR 06/06/2011
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_StandardMeshInfosDlg.cxx
1 // Copyright (C) 2007-2011  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.
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_StandardMeshInfosDlg.cxx
25 // Author : Michael ZORIN, Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_StandardMeshInfosDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_MeshUtils.h"
33
34 #include <SMESH_TypeFilter.hxx>
35
36 // SALOME KERNEL includes 
37 #include <SALOMEDSClient_Study.hxx>
38 #include <SALOMEDSClient_SObject.hxx>
39
40 // SALOME GUI includes
41 #include <SUIT_Desktop.h>
42 #include <SUIT_Session.h>
43 #include <SUIT_OverrideCursor.h>
44 #include <SUIT_MessageBox.h>
45 #include <SUIT_ResourceMgr.h>
46
47 #include <LightApp_Application.h>
48 #include <LightApp_SelectionMgr.h>
49
50 #include <SALOME_ListIO.hxx>
51
52 // Qt includes
53 #include <QGroupBox>
54 #include <QLabel>
55 #include <QVBoxLayout>
56 #include <QHBoxLayout>
57 #include <QLineEdit>
58 #include <QTextBrowser>
59 #include <QPushButton>
60 #include <QKeyEvent>
61
62 // IDL includes
63 #include <SALOMEconfig.h>
64 #include CORBA_SERVER_HEADER(SMESH_Mesh)
65 #include CORBA_SERVER_HEADER(SMESH_Group)
66
67 #define SPACING 6
68 #define MARGIN  11
69
70 //=================================================================================
71 /*!
72  *  SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg
73  *
74  *  Constructor
75  */
76 //=================================================================================
77 SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg( SMESHGUI* theModule )
78   : QDialog( SMESH::GetDesktop( theModule ) ),
79     mySMESHGUI( theModule ),
80     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
81 {
82   setModal(false);
83   setAttribute(Qt::WA_DeleteOnClose, true);
84   setWindowTitle(tr("SMESH_STANDARD_MESHINFO_TITLE"));
85   setSizeGripEnabled(true);
86
87   myStartSelection = true;
88   myIsActiveWindow = true;
89
90   // dialog layout
91   QVBoxLayout* aDlgLayout = new QVBoxLayout(this);
92   aDlgLayout->setSpacing(SPACING);
93   aDlgLayout->setMargin(MARGIN);
94
95   // mesh group box
96   myMeshGroup = new QGroupBox(tr("SMESH_MESH"), this);
97   QHBoxLayout* myMeshGroupLayout = new QHBoxLayout(myMeshGroup);
98   myMeshGroupLayout->setSpacing(SPACING);
99   myMeshGroupLayout->setMargin(MARGIN);
100
101   // select button, label and line edit with mesh name
102   myNameLab = new QLabel(tr("SMESH_NAME"), myMeshGroup);
103   myMeshGroupLayout->addWidget(myNameLab);
104
105   QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("SMESH",tr("ICON_SELECT")));
106   mySelectBtn = new QPushButton(myMeshGroup);
107   mySelectBtn->setIcon(image0);
108   myMeshGroupLayout->addWidget(mySelectBtn);
109
110   myMeshLine = new QLineEdit(myMeshGroup);
111   myMeshGroupLayout->addWidget(myMeshLine);
112
113   aDlgLayout->addWidget(myMeshGroup);
114
115   // information group box
116   myInfoGroup  = new QGroupBox(tr("SMESH_INFORMATION"), this);
117   QVBoxLayout* myInfoGroupLayout = new QVBoxLayout(myInfoGroup);
118   myInfoGroupLayout->setSpacing(SPACING);
119   myInfoGroupLayout->setMargin(MARGIN);
120
121   // information text browser
122   myInfo = new QTextBrowser(myInfoGroup);
123   myInfo->setMinimumSize(200, 150);
124   myInfoGroupLayout->addWidget(myInfo);
125
126   aDlgLayout->addWidget(myInfoGroup);
127
128   // buttons group
129   myButtonsGroup = new QGroupBox(this);
130   QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout(myButtonsGroup);
131   myButtonsGroupLayout->setSpacing(SPACING);
132   myButtonsGroupLayout->setMargin(MARGIN);
133
134   // buttons --> OK and Help buttons
135   myOkBtn = new QPushButton(tr("SMESH_BUT_OK"), myButtonsGroup);
136   myOkBtn->setAutoDefault(true); myOkBtn->setDefault(true);
137   myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), myButtonsGroup);
138   myHelpBtn->setAutoDefault(true);
139
140   myButtonsGroupLayout->addWidget(myOkBtn);
141   myButtonsGroupLayout->addSpacing(10);
142   myButtonsGroupLayout->addStretch();
143   myButtonsGroupLayout->addWidget(myHelpBtn);
144
145   aDlgLayout->addWidget(myButtonsGroup);
146
147   mySMESHGUI->SetActiveDialogBox(this);
148
149   // connect signals
150   connect( myOkBtn,         SIGNAL(clicked()),                      this, SLOT(close()));
151   connect( myHelpBtn,       SIGNAL(clicked()),                      this, SLOT(onHelp()));
152   connect( mySelectBtn,     SIGNAL(clicked()),                      this, SLOT(onStartSelection()));
153   connect( mySMESHGUI,      SIGNAL(SignalCloseAllDialogs()),        this, SLOT(close()));
154   connect( mySMESHGUI,      SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
155   connect( mySelectionMgr,  SIGNAL(currentSelectionChanged()),      this, SLOT(onSelectionChanged()));
156
157   // init dialog with current selection
158   myMeshFilter = new SMESH_TypeFilter (MESH);
159   mySelectionMgr->installFilter(myMeshFilter);
160   onSelectionChanged();
161
162   myHelpFileName = "mesh_infos_page.html#standard_mesh_infos_anchor";
163 }
164
165 //=================================================================================
166 /*!
167  *  SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg
168  *
169  *  Destructor
170  */
171 //=================================================================================
172 SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg()
173 {
174 }
175
176 //=================================================================================
177 /*!
178  *  SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos
179  */
180 //=================================================================================
181 void SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos()
182 {
183   SUIT_OverrideCursor wc;
184
185   SALOME_ListIO aList;
186   mySelectionMgr->selectedObjects(aList);
187
188   int nbSel = aList.Extent();
189   myInfo->clear();
190   if (nbSel == 1) {
191     myStartSelection = false;
192     myMeshLine->setText("");
193     SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(aList.First());
194
195     if (!aMesh->_is_nil()) {
196       QString aName, anInfo;
197       SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
198       myMeshLine->setText(aName);
199       int aNbNodes =   (int)aMesh->NbNodes();
200       int aNbEdges =   (int)aMesh->NbEdges();
201       int aNbFaces =   (int)aMesh->NbFaces();
202       int aNbVolumes = (int)aMesh->NbVolumes();
203
204       int aDimension = 0;
205       double aNbDimElements = 0;
206       if (aNbVolumes > 0) {
207         aNbDimElements = aNbVolumes;
208         aDimension = 3;
209       }
210       else if(aNbFaces > 0) {
211         aNbDimElements = aNbFaces;
212         aDimension = 2;
213       }
214       else if(aNbEdges > 0) {
215         aNbDimElements = aNbEdges;
216         aDimension = 1;
217       }
218       else if(aNbNodes > 0) {
219         aNbDimElements = aNbNodes;
220         aDimension = 0;
221       }
222
223       // information about the mesh
224       anInfo.append(QString("Nb of element of dimension %1:<b> %2</b><br>").arg(aDimension).arg(aNbDimElements));
225       anInfo.append(QString("Nb of nodes: <b>%1</b><br><br>").arg(aNbNodes));
226
227       // information about the groups of the mesh
228       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
229       _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
230       _PTR(SObject) anObj;
231
232       bool hasGroup = false;
233
234       // info about groups on nodes
235       aMeshSO->FindSubObject(SMESH::Tag_NodeGroups, anObj);
236       if (anObj) {
237         _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
238         if (it->More()) {
239           anInfo.append(QString("Groups:<br><br>"));
240           hasGroup = true;
241         }
242         for ( ; it->More(); it->Next()) {
243           _PTR(SObject) subObj = it->Value();
244           CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
245           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
246           if (!aGroup->_is_nil()) {
247             anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
248             anInfo.append(QString("%1<br>").arg("on nodes"));
249             anInfo.append(QString("%1<br>").arg(aGroup->Size()));
250             // check if the group based on geometry
251             SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
252             if (!aGroupOnGeom->_is_nil()) {
253               GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
254               QString aShapeName = "<unknown>";
255               _PTR(SObject) aGeomObj, aRef;
256               if (subObj->FindSubObject(1, aGeomObj) &&  aGeomObj->ReferencedObject(aRef))
257                 aShapeName = aRef->GetName().c_str();
258               anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
259             } else {
260               anInfo.append(QString("<br>"));
261             }
262           }
263         }
264       }
265
266       // info about groups on edges
267       anObj.reset();
268       aMeshSO->FindSubObject(SMESH::Tag_EdgeGroups, anObj);
269       if (anObj) {
270         _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
271         if (!hasGroup && it->More()) {
272           anInfo.append(QString("Groups:<br><br>"));
273           hasGroup = true;
274         }
275         for ( ; it->More(); it->Next()) {
276           _PTR(SObject) subObj = it->Value();
277           CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
278           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
279           if (!aGroup->_is_nil()) {
280             anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
281             anInfo.append(QString("%1<br>").arg("on edges"));
282             anInfo.append(QString("%1<br>").arg(aGroup->Size()));
283             // check if the group based on geometry
284             SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
285             if (!aGroupOnGeom->_is_nil()) {
286               GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
287               QString aShapeName = "<unknown>";
288               _PTR(SObject) aGeomObj, aRef;
289               if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef))
290                 aShapeName = aRef->GetName().c_str();
291               anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
292             } else {
293               anInfo.append(QString("<br>"));
294             }
295           }
296         }
297       }
298
299       // info about groups on faces
300       anObj.reset();
301       aMeshSO->FindSubObject(SMESH::Tag_FaceGroups, anObj);
302       if (anObj) {
303         _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
304         if (!hasGroup && it->More()) {
305           anInfo.append(QString("Groups:<br><br>"));
306           hasGroup = true;
307         }
308         for ( ; it->More(); it->Next()) {
309           _PTR(SObject) subObj = it->Value();
310           CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
311           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
312           if (!aGroup->_is_nil()) {
313             anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
314             anInfo.append(QString("%1<br>").arg("on faces"));
315             anInfo.append(QString("%1<br>").arg(aGroup->Size()));
316             // check if the group based on geometry
317             SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
318             if (!aGroupOnGeom->_is_nil()) {
319               GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
320               QString aShapeName = "<unknown>";
321               _PTR(SObject) aGeomObj, aRef;
322               if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef))
323                 aShapeName = aRef->GetName().c_str();
324               anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
325             } else {
326               anInfo.append(QString("<br>"));
327             }
328           }
329         }
330       }
331
332       // info about groups on volumes
333       anObj.reset();
334       aMeshSO->FindSubObject(SMESH::Tag_VolumeGroups, anObj);
335       if (anObj) {
336         _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
337         if (!hasGroup && it->More())
338           anInfo.append(QString("Groups:<br>"));
339         for ( ; it->More(); it->Next()) {
340           _PTR(SObject) subObj = it->Value();
341           CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
342           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
343           if (!aGroup->_is_nil()) {
344             anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
345             anInfo.append(QString("%1<br>").arg("on volumes"));
346             anInfo.append(QString("%1<br>").arg(aGroup->Size()));
347             // check if the group based on geometry
348             SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
349             if (!aGroupOnGeom->_is_nil()) {
350               GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
351               QString aShapeName = "<unknown>";
352               _PTR(SObject) aGeomObj, aRef;
353               if (subObj->FindSubObject(1, aGeomObj) &&  aGeomObj->ReferencedObject(aRef))
354                 aShapeName = aRef->GetName().c_str();
355               anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
356             } else {
357               anInfo.append(QString("<br>"));
358             }
359           }
360         }
361       }
362
363       myInfo->setText(anInfo);
364       return;
365     }
366   }
367 }
368
369 //=================================================================================
370 // function : SelectionIntoArgument()
371 // purpose  : Called when selection has changed
372 //=================================================================================
373 void SMESHGUI_StandardMeshInfosDlg::onSelectionChanged()
374 {
375   if (myStartSelection)
376     DumpMeshInfos();
377 }
378
379 //=================================================================================
380 // function : closeEvent()
381 // purpose  :
382 //=================================================================================
383 void SMESHGUI_StandardMeshInfosDlg::closeEvent (QCloseEvent* e)
384 {
385   mySelectionMgr->clearFilters();
386   mySMESHGUI->ResetState();
387   QDialog::closeEvent(e);
388 }
389
390 //=================================================================================
391 // function : windowActivationChange()
392 // purpose  : called when window is activated/deactivated
393 //=================================================================================
394 void SMESHGUI_StandardMeshInfosDlg::windowActivationChange (bool oldActive)
395 {
396   QDialog::windowActivationChange(oldActive);
397   if (isActiveWindow() && myIsActiveWindow != isActiveWindow())
398     ActivateThisDialog();
399   myIsActiveWindow = isActiveWindow();
400 }
401
402 //=================================================================================
403 // function : DeactivateActiveDialog()
404 // purpose  :
405 //=================================================================================
406 void SMESHGUI_StandardMeshInfosDlg::DeactivateActiveDialog()
407 {
408   disconnect(mySelectionMgr, 0, this, 0);
409 }
410
411 //=================================================================================
412 // function : ActivateThisDialog()
413 // purpose  :
414 //=================================================================================
415 void SMESHGUI_StandardMeshInfosDlg::ActivateThisDialog()
416 {
417   /* Emit a signal to deactivate any active dialog */
418   mySMESHGUI->EmitSignalDeactivateDialog();
419   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
420 }
421
422 //=================================================================================
423 // function : onStartSelection()
424 // purpose  : starts selection
425 //=================================================================================
426 void SMESHGUI_StandardMeshInfosDlg::onStartSelection()
427 {
428   myStartSelection = true;
429   mySelectionMgr->installFilter(myMeshFilter);
430   myMeshLine->setText(tr("Select a mesh"));
431   onSelectionChanged();
432   myStartSelection = true;
433 }
434
435 //=================================================================================
436 // function : onHelp()
437 // purpose  :
438 //=================================================================================
439 void SMESHGUI_StandardMeshInfosDlg::onHelp()
440 {
441   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
442   if (app)
443     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
444   else {
445     QString platform;
446 #ifdef WIN32
447     platform = "winapplication";
448 #else
449     platform = "application";
450 #endif
451     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
452                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
453                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
454                                                                  platform)).
455                              arg(myHelpFileName));
456   }
457 }
458
459 //=================================================================================
460 // function : keyPressEvent()
461 // purpose  :
462 //=================================================================================
463 void SMESHGUI_StandardMeshInfosDlg::keyPressEvent( QKeyEvent* e )
464 {
465   QDialog::keyPressEvent( e );
466   if ( e->isAccepted() )
467     return;
468
469   if ( e->key() == Qt::Key_F1 ) {
470     e->accept();
471     onHelp();
472   }
473 }