1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMESHGUI : GUI for SMESH component
23 // File : SMESHGUI_WhatIsDlg.cxx
24 // Author : Vladimir TURIN
28 #include "SMESHGUI_WhatIsDlg.h"
31 #include "SMESHGUI_SpinBox.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_VTKUtils.h"
34 #include "SMESHGUI_MeshUtils.h"
35 #include "SMESHGUI_IdValidator.h"
37 #include "SMESH_Actor.h"
38 #include "SMESH_TypeFilter.hxx"
39 #include "SMESH_LogicalFilter.hxx"
40 #include "SMDS_Mesh.hxx"
41 #include "SMDS_VolumeTool.hxx"
43 #include "SUIT_Desktop.h"
44 #include "SUIT_ResourceMgr.h"
45 #include "SUIT_Session.h"
46 #include "SUIT_MessageBox.h"
48 #include "LightApp_Application.h"
50 #include "SVTK_ViewModel.h"
51 #include "SVTK_Selection.h"
52 #include "SVTK_ViewWindow.h"
53 #include "SVTK_Selector.h"
54 #include "SALOME_ListIO.hxx"
56 #include "utilities.h"
59 #include <TColStd_MapOfInteger.hxx>
60 #include <TColStd_IndexedMapOfInteger.hxx>
64 #include <qapplication.h>
65 #include <qbuttongroup.h>
66 #include <qgroupbox.h>
68 #include <qlineedit.h>
69 #include <qpushbutton.h>
70 #include <qradiobutton.h>
71 #include <qcheckbox.h>
75 #include <qtextbrowser.h>
78 #include "SALOMEconfig.h"
79 #include CORBA_SERVER_HEADER(SMESH_Group)
80 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
84 //=================================================================================
85 // class : SMESHGUI_WhatIsDlg()
87 //=================================================================================
88 SMESHGUI_WhatIsDlg::SMESHGUI_WhatIsDlg( SMESHGUI* theModule, const char* name,
89 bool modal, WFlags fl)
90 : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
91 WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
92 mySMESHGUI( theModule ),
93 mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
96 setName("SMESHGUI_WhatIsDlg");
98 setCaption(tr("SMESH_WHAT_IS_TITLE"));
99 setSizeGripEnabled(TRUE);
100 SMESHGUI_WhatIsDlgLayout = new QGridLayout(this);
101 SMESHGUI_WhatIsDlgLayout->setSpacing(6);
102 SMESHGUI_WhatIsDlgLayout->setMargin(11);
104 /***************************************************************/
105 GroupMesh = new QButtonGroup(this, "GroupSelections");
106 GroupMesh->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)5, (QSizePolicy::SizeType)0, 0, 0, GroupMesh->sizePolicy().hasHeightForWidth()));
107 GroupMesh->setTitle(tr(""));
108 GroupMesh->setColumnLayout(0, Qt::Vertical);
109 GroupMesh->layout()->setSpacing(0);
110 GroupMesh->layout()->setMargin(0);
111 GroupMeshLayout = new QGridLayout(GroupMesh->layout());
112 GroupMeshLayout->setAlignment(Qt::AlignTop);
113 GroupMeshLayout->setSpacing(6);
114 GroupMeshLayout->setMargin(11);
115 MeshLabel = new QLabel(GroupMesh, "MeshLabel");
116 MeshLabel->setText(tr("SMESH_NAME"));
117 GroupMeshLayout->addWidget(MeshLabel, 0, 0);
118 MeshName = new QLabel(GroupMesh, "MeshName");
119 MeshName->setText(tr(""));
120 GroupMeshLayout->addWidget(MeshName, 0, 1);
121 SMESHGUI_WhatIsDlgLayout->addWidget(GroupMesh, 0, 0);
123 /***************************************************************/
124 GroupSelections = new QButtonGroup(this, "GroupSelections");
125 GroupSelections->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)5, (QSizePolicy::SizeType)0, 0, 0, GroupSelections->sizePolicy().hasHeightForWidth()));
126 GroupSelections->setTitle(tr("ENTITY_TYPE" ));
127 GroupSelections->setExclusive(TRUE);
128 GroupSelections->setColumnLayout(0, Qt::Vertical);
129 GroupSelections->layout()->setSpacing(0);
130 GroupSelections->layout()->setMargin(0);
131 GroupSelectionsLayout = new QGridLayout(GroupSelections->layout());
132 GroupSelectionsLayout->setAlignment(Qt::AlignTop);
133 GroupSelectionsLayout->setSpacing(6);
134 GroupSelectionsLayout->setMargin(11);
135 RadioButtonNodes = new QRadioButton(GroupSelections, "RadioButtonNodes");
136 RadioButtonNodes->setText(tr("SMESH_NODES"));
137 GroupSelectionsLayout->addWidget(RadioButtonNodes, 0, 0);
138 RadioButtonElements = new QRadioButton(GroupSelections, "RadioButtonElements");
139 RadioButtonElements->setText(tr("SMESH_ELEMENTS"));
140 GroupSelectionsLayout->addWidget(RadioButtonElements, 0, 1 );
141 SMESHGUI_WhatIsDlgLayout->addWidget(GroupSelections, 1, 0);
143 /***************************************************************/
144 GroupArguments = new QGroupBox(this, "GroupArguments");
145 GroupArguments->setTitle(tr("SMESH_INFORMATION"));
146 GroupArguments->setColumnLayout(0, Qt::Vertical);
147 GroupArguments->layout()->setSpacing(0);
148 GroupArguments->layout()->setMargin(0);
149 GroupArgumentsLayout = new QGridLayout(GroupArguments->layout());
150 GroupArgumentsLayout->setAlignment(Qt::AlignTop);
151 GroupArgumentsLayout->setSpacing(6);
152 GroupArgumentsLayout->setMargin(11);
154 // Controls for elements selection
155 TextLabelElements = new QLabel(GroupArguments, "TextLabelElements");
156 TextLabelElements->setText(tr("SMESH_ID_ELEMENTS" ));
157 TextLabelElements->setFixedWidth(74);
158 GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
160 LineEditElements = new QLineEdit(GroupArguments, "LineEditElements");
161 LineEditElements->setValidator(new SMESHGUI_IdValidator(this, "validator"));
162 GroupArgumentsLayout->addMultiCellWidget(LineEditElements, 0, 0, 2, 7);
164 // information text browser
165 Info = new QTextBrowser(GroupArguments, "Info");
166 Info->setHScrollBarMode(QScrollView::AlwaysOff);
167 Info->setVScrollBarMode(QScrollView::AlwaysOff);
168 GroupArgumentsLayout->addMultiCellWidget(Info, 1, 1, 0, 7);
170 SMESHGUI_WhatIsDlgLayout->addWidget(GroupArguments, 2, 0);
172 /***************************************************************/
173 GroupButtons = new QGroupBox(this, "GroupButtons");
174 GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, 0, 0, GroupButtons->sizePolicy().hasHeightForWidth()));
175 GroupButtons->setTitle(tr("" ));
176 GroupButtons->setColumnLayout(0, Qt::Vertical);
177 GroupButtons->layout()->setSpacing(0);
178 GroupButtons->layout()->setMargin(0);
179 GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
180 GroupButtonsLayout->setAlignment(Qt::AlignTop);
181 GroupButtonsLayout->setSpacing(6);
182 GroupButtonsLayout->setMargin(11);
183 buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
184 buttonHelp->setText(tr("SMESH_BUT_HELP" ));
185 buttonHelp->setAutoDefault(TRUE);
186 GroupButtonsLayout->addWidget(buttonHelp, 0, 3);
187 QSpacerItem* spacer_9 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
188 GroupButtonsLayout->addItem(spacer_9, 0, 1);
189 buttonOk = new QPushButton(GroupButtons, "buttonOk");
190 buttonOk->setText(tr("SMESH_BUT_OK" ));
191 buttonOk->setAutoDefault(TRUE);
192 buttonOk->setDefault(TRUE);
193 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
194 SMESHGUI_WhatIsDlgLayout->addWidget(GroupButtons, 3, 0);
196 GroupArguments->show();
197 RadioButtonNodes->setChecked(TRUE);
199 mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
201 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
203 // Costruction of the logical filter
204 SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
205 SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP);
207 QPtrList<SUIT_SelectionFilter> aListOfFilters;
208 if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
209 if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter);
211 myMeshOrSubMeshOrGroupFilter =
212 new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR);
214 myHelpFileName = "mesh_infos_page.html#mesh_element_info_anchor";
218 /* signals and slots connections */
219 connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
220 connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
221 connect(GroupSelections, SIGNAL(clicked(int)), SLOT(SelectionsClicked(int)));
223 connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
224 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
225 /* to close dialog if study change */
226 connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
227 connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
228 this->show(); /* displays Dialog */
230 SelectionsClicked(0);
231 SelectionIntoArgument();
234 //=================================================================================
235 // function : ~SMESHGUI_WhatIsDlg()
236 // purpose : Destroys the object and frees any allocated resources
237 //=================================================================================
238 SMESHGUI_WhatIsDlg::~SMESHGUI_WhatIsDlg()
240 // no need to delete child widgets, Qt does it all for us
243 //=================================================================================
246 //=================================================================================
247 void SMESHGUI_WhatIsDlg::Init (bool ResetControls)
251 LineEditElements->clear();
254 myMesh = SMESH::SMESH_Mesh::_nil();
257 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
258 aViewWindow->SetSelectionMode( CellSelection );
259 onTextChange(LineEditElements->text());
261 SelectionIntoArgument();
265 //=================================================================================
266 // function : SelectionsClicked()
267 // purpose : Radio button management
268 //=================================================================================
269 void SMESHGUI_WhatIsDlg::SelectionsClicked (int selectionId)
271 disconnect(mySelectionMgr, 0, this, 0);
273 mySelectionMgr->clearFilters();
275 switch (selectionId) {
278 SMESH::SetPointRepresentation(true);
279 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
280 aViewWindow->SetSelectionMode( NodeSelection );
285 SMESH::SetPointRepresentation(false);
286 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
287 aViewWindow->SetSelectionMode( CellSelection );
292 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
293 SelectionIntoArgument();
296 //=================================================================================
297 // function : ClickOnOk()
299 //=================================================================================
300 void SMESHGUI_WhatIsDlg::ClickOnOk()
302 if (mySMESHGUI->isActiveStudyLocked())
307 SelectionIntoArgument();
311 //=================================================================================
312 // function : ClickOnCancel()
314 //=================================================================================
315 void SMESHGUI_WhatIsDlg::ClickOnCancel()
317 disconnect(mySelectionMgr, 0, this, 0);
318 mySelectionMgr->clearFilters();
319 SMESH::SetPointRepresentation(false);
320 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
321 aViewWindow->SetSelectionMode( ActorSelection );
322 mySMESHGUI->ResetState();
326 //=================================================================================
327 // function : ClickOnHelp()
329 //=================================================================================
330 void SMESHGUI_WhatIsDlg::ClickOnHelp()
332 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
334 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
336 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
337 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
338 arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(myHelpFileName),
339 QObject::tr("BUT_OK"));
343 //=======================================================================
344 // function : onTextChange()
346 //=======================================================================
347 void SMESHGUI_WhatIsDlg::onTextChange (const QString& theNewText)
352 // hilight entered elements
353 SMDS_Mesh* aMesh = 0;
355 aMesh = myActor->GetObject()->GetMesh();
358 Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
360 TColStd_MapOfInteger newIndices;
362 QStringList aListId = QStringList::split(" ", theNewText, false);
364 for (int i = 0; i < aListId.count(); i++) {
365 const SMDS_MeshElement * e = RadioButtonNodes->isChecked()?
366 aMesh->FindNode(aListId[ i ].toInt()):
367 aMesh->FindElement(aListId[ i ].toInt());
369 newIndices.Add(e->GetID());
372 mySelector->AddOrRemoveIndex( anIO, newIndices, false );
373 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
374 aViewWindow->highlight( anIO, true, true );
377 SelectionIntoArgument();
382 //=================================================================================
383 // function : SelectionIntoArgument()
384 // purpose : Called when selection as changed or other case
385 //=================================================================================
386 void SMESHGUI_WhatIsDlg::SelectionIntoArgument()
388 int curBusy = myBusy;
392 QString aString = "";
396 LineEditElements->setText(aString);
397 MeshName->setText(aString);
398 GroupMesh->setTitle(tr(""));
402 if (!GroupButtons->isEnabled()) // inactive
407 mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
409 int nbSel = aList.Extent();
414 Handle(SALOME_InteractiveObject) IO = aList.First();
415 myMesh = SMESH::GetMeshByIO(IO);
416 if (myMesh->_is_nil())
419 myActor = SMESH::FindActorByObject(myMesh);
421 myActor = SMESH::FindActorByEntry(IO->getEntry());
426 SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
427 MeshName->setText(aName);
428 if(!SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO)->_is_nil()) {
429 GroupMesh->setTitle(tr("SMESH_MESH"));
430 } else if(!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil()) {
431 GroupMesh->setTitle(tr("SMESH_SUBMESH"));
432 } else if(!SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) {
433 GroupMesh->setTitle(tr("SMESH_GROUP"));
438 aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
443 const SMDS_MeshElement * e = RadioButtonNodes->isChecked()?
444 myActor->GetObject()->GetMesh()->FindNode(aString.toInt()):
445 myActor->GetObject()->GetMesh()->FindElement(aString.toInt());
448 anInfo=tr("ENTITY_TYPE") + ": ";
449 if(e->GetType() == SMDSAbs_Node) {
450 anInfo+=tr("MESH_NODE")+"\n";
451 const SMDS_MeshNode *en = (SMDS_MeshNode*) e;
452 } else if(e->GetType() == SMDSAbs_Edge) {
453 anInfo+=tr("SMESH_EDGE")+"\n";
454 anInfo+=tr("SMESH_MESHINFO_TYPE")+": ";
455 const SMDS_MeshEdge *ee = (SMDS_MeshEdge*) e;
456 anInfo+=(ee->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+"\n";
457 } else if(e->GetType() == SMDSAbs_Face) {
458 const SMDS_MeshFace *ef = (SMDS_MeshFace*) e;
459 anInfo+=tr("SMESH_FACE")+"\n";
460 anInfo+=tr("SMESH_MESHINFO_TYPE")+": ";
462 anInfo+=(ef->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+" ";
463 switch(ef->NbNodes()) {
467 anInfo+=tr("SMESH_TRIANGLE");
473 anInfo+=tr("SMESH_QUADRANGLE");
480 } else if(e->GetType() == SMDSAbs_Volume) {
481 anInfo+=tr("SMESH_VOLUME")+"\n";
482 anInfo+=tr("SMESH_MESHINFO_TYPE")+": ";
483 const SMDS_MeshVolume *ev = (SMDS_MeshVolume*) e;
484 SMDS_VolumeTool vt(ev);
485 if(vt.GetVolumeType() != SMDS_VolumeTool::POLYHEDA)
486 anInfo+=(ev->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+" ";
487 switch(vt.GetVolumeType()) {
488 case SMDS_VolumeTool::TETRA:
489 case SMDS_VolumeTool::QUAD_TETRA:
491 anInfo+=tr("SMESH_TETRAS");
494 case SMDS_VolumeTool::PYRAM:
495 case SMDS_VolumeTool::QUAD_PYRAM:
497 anInfo+=tr("SMESH_PYRAMID");
500 case SMDS_VolumeTool::PENTA:
501 case SMDS_VolumeTool::QUAD_PENTA:
503 anInfo+=tr("SMESH_PRISM");
506 case SMDS_VolumeTool::HEXA:
507 case SMDS_VolumeTool::QUAD_HEXA:
509 anInfo+=tr("SMESH_HEXAS");
512 case SMDS_VolumeTool::POLYHEDA:
514 anInfo+=tr("SMESH_POLYEDRON");
522 if(e->GetType() != SMDSAbs_Node)
523 anInfo+=tr("GRAVITY_CENTER") + ":\n";
524 gp_XYZ anXYZ(0.,0.,0.);
525 SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
527 for(; nodeIt->more(); nbNodes++) {
528 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
529 anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
531 anXYZ.Divide(e->NbNodes()) ;
532 anInfo+=QString("X=%1\nY=%2\nZ=%3\n").arg(anXYZ.X()).arg(anXYZ.Y()).arg(anXYZ.Z());
533 Info->setText(anInfo);
538 LineEditElements->setText(aString);
543 //=================================================================================
544 // function : DeactivateActiveDialog()
546 //=================================================================================
547 void SMESHGUI_WhatIsDlg::DeactivateActiveDialog()
549 if (GroupArguments->isEnabled()) {
550 GroupSelections->setEnabled(false);
551 GroupMesh->setEnabled(false);
552 GroupArguments->setEnabled(false);
553 GroupButtons->setEnabled(false);
554 mySMESHGUI->ResetState();
555 mySMESHGUI->SetActiveDialogBox(0);
559 //=================================================================================
560 // function : ActivateThisDialog()
562 //=================================================================================
563 void SMESHGUI_WhatIsDlg::ActivateThisDialog()
565 /* Emit a signal to deactivate the active dialog */
566 mySMESHGUI->EmitSignalDeactivateDialog();
567 GroupArguments->setEnabled(true);
568 GroupButtons->setEnabled(true);
569 GroupSelections->setEnabled(true);
570 GroupMesh->setEnabled(true);
572 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
574 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
575 SelectionsClicked(RadioButtonNodes->isChecked()?0:1);
577 SelectionIntoArgument();
580 //=================================================================================
581 // function : enterEvent()
583 //=================================================================================
584 void SMESHGUI_WhatIsDlg::enterEvent (QEvent*)
586 if (!GroupArguments->isEnabled())
587 ActivateThisDialog();
590 //=================================================================================
591 // function : closeEvent()
593 //=================================================================================
594 void SMESHGUI_WhatIsDlg::closeEvent (QCloseEvent*)
596 /* same than click on cancel button */
597 this->ClickOnCancel();
600 //=======================================================================
601 //function : hideEvent
602 //purpose : caused by ESC key
603 //=======================================================================
604 void SMESHGUI_WhatIsDlg::hideEvent (QHideEvent*)
610 //=================================================================================
611 // function : keyPressEvent()
613 //=================================================================================
614 void SMESHGUI_WhatIsDlg::keyPressEvent( QKeyEvent* e )
616 QDialog::keyPressEvent( e );
617 if ( e->isAccepted() )
620 if ( e->key() == Key_F1 )