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