1 // VISU VISUGUI : GUI of VISU component
3 // Copyright (C) 2003 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
24 // File : VisuGUI_Selection.cxx
25 // Author : Laurent CORNABE & Hubert ROLLAND
29 #include "VisuGUI_Selection.h"
32 #include "VisuGUI_Tools.h"
33 #include "VisuGUI_ViewTools.h"
35 #include "VISU_Actor.h"
36 #include "VISU_PrsObject_i.hh"
37 #include "VISU_Prs3d_i.hh"
38 #include "VISU_PipeLine.hxx"
40 #include "SalomeApp_Study.h"
41 #include "SalomeApp_Application.h"
42 #include "LightApp_Application.h"
43 #include "LightApp_SelectionMgr.h"
44 #include "LightApp_VTKSelector.h"
46 #include "SUIT_MessageBox.h"
47 #include "SUIT_ViewWindow.h"
48 #include "SUIT_Session.h"
49 #include "SUIT_ResourceMgr.h"
51 #include "SALOME_ListIO.hxx"
52 #include "SALOME_ListIteratorOfListIO.hxx"
54 #include "SVTK_ViewWindow.h"
55 #include "SVTK_Selector.h"
57 #include "utilities.h"
60 #include <TColStd_IndexedMapOfInteger.hxx>
61 #include <TColStd_MapOfInteger.hxx>
69 #include <qhbuttongroup.h>
70 #include <qradiobutton.h>
71 #include <qvalidator.h>
72 #include <qpushbutton.h>
73 #include <qwidgetstack.h>
75 #include <qgroupbox.h>
76 #include <qlineedit.h>
77 #include <qvalidator.h>
81 #include <vtkDataSetMapper.h>
82 #include <vtkDataSet.h>
83 #include <vtkPointData.h>
84 #include <vtkCellData.h>
92 static VisuGUI_SelectionDlg* mySelectionDlg = NULL;
94 VisuGUI_SelectionDlg::VisuGUI_SelectionDlg (const SalomeApp_Module* theModule):
95 QDialog(VISU::GetDesktop(theModule),
98 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
103 mySelectionDlg->close(true);
105 setCaption( "Data on elements" );
106 setSizeGripEnabled(TRUE);
108 QGridLayout* TopLayout = new QGridLayout (this);
109 TopLayout->setSpacing(6);
110 TopLayout->setMargin(11);
111 TopLayout->setRowStretch(0, 0);
112 TopLayout->setRowStretch(1, 0);
113 TopLayout->setRowStretch(2, 1);
114 TopLayout->setRowStretch(3, 0);
116 QHButtonGroup* aTypeBox = new QHButtonGroup ("Selection", this);
118 QRadioButton* aPointBtn =
119 new QRadioButton ("Point", aTypeBox);
120 new QRadioButton ("Cell" , aTypeBox);
121 new QRadioButton ("Actor", aTypeBox);
122 aPointBtn->setChecked(true);
124 connect(aTypeBox, SIGNAL(clicked(int)), this, SLOT(onSelectionChange(int)));
126 TopLayout->addWidget(aTypeBox, 0, 0);
128 QWidget* aNamePane = new QWidget (this);
129 QGridLayout* aNameLay = new QGridLayout (aNamePane);
131 QLabel* aMeshLbl = new QLabel ("Mesh name: ", aNamePane);
132 myMeshName = new QLabel (aNamePane);
134 QLabel* aFieldLbl = new QLabel ("Field name: ", aNamePane);
135 myFieldName = new QLabel (aNamePane);
137 aNameLay->addWidget(aMeshLbl, 0, 0);
138 aNameLay->addWidget(myMeshName, 0, 1);
139 aNameLay->addWidget(aFieldLbl, 1, 0);
140 aNameLay->addWidget(myFieldName, 1, 1);
142 TopLayout->addWidget(aNamePane, 1, 0);
144 myWidgetStack = new QWidgetStack (this);
146 // Create Points pane
147 myPointsPane = new QVBox (myWidgetStack);
148 myPointsPane->layout()->setSpacing(6);
150 QGroupBox* aDataGrp = new QGroupBox (2, Qt::Horizontal, "Data of Point", myPointsPane);
151 aDataGrp->layout()->setSpacing(6);
153 new QLabel ("ID:", aDataGrp);
154 myIDValLbl = new QLineEdit ("", aDataGrp);
155 QIntValidator* aIntValidator = new QIntValidator (myIDValLbl);
156 aIntValidator->setBottom(0);
157 myIDValLbl->setValidator(aIntValidator);
158 connect(myIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onPointIdEdit(const QString&)));
160 new QLabel ("Scalar Value:", aDataGrp);
161 myScalarValLbl = new QLabel ("", aDataGrp);
162 new QLabel ("Vector Value:", aDataGrp);
163 myVectorValLbl = new QLabel ("", aDataGrp);
164 myVectorValLbl->setMinimumWidth(150);
166 QGroupBox* aCoordGrp = new QGroupBox (2, Qt::Horizontal, "Coordinates", myPointsPane);
167 aCoordGrp->layout()->setSpacing(6);
168 new QLabel ("X:", aCoordGrp);
169 myXValLbl = new QLabel ("", aCoordGrp);
170 new QLabel ("Y:", aCoordGrp);
171 myYValLbl = new QLabel ("", aCoordGrp);
172 new QLabel ("Z:",aCoordGrp );
173 myZValLbl = new QLabel ("", aCoordGrp);
176 myWidgetStack->addWidget(myPointsPane, 0);
179 myCellsPane = new QWidget (myWidgetStack);
180 QGridLayout* aCellLayout = new QGridLayout (myCellsPane);
181 aCellLayout->setSpacing(6);
182 aCellLayout->setRowStretch(0, 0);
183 aCellLayout->setRowStretch(1, 1);
185 QGroupBox* aCellGrp = new QGroupBox(2, Qt::Horizontal, "Data of Cell", myCellsPane);
187 new QLabel ("ID:", aCellGrp);
188 myCellIDValLbl = new QLineEdit ("", aCellGrp);
189 myCellIDValLbl->setValidator(aIntValidator);
190 connect(myCellIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onCellIdEdit(const QString&)));
192 new QLabel ("Scalar Value:", aCellGrp);
193 myCellScalarValLbl = new QLabel ("", aCellGrp);
194 new QLabel ("Vector Value:", aCellGrp);
195 myCellVectorValLbl = new QLabel ("", aCellGrp);
197 aCellLayout->addWidget(aCellGrp, 0, 0);
199 myListPoints = new QTable (myCellsPane);
200 myListPoints->setReadOnly(true);
201 myListPoints->setNumCols(6);
202 myListPoints->setNumRows(0);
203 myListPoints->setColumnWidth(0, 40);
204 myListPoints->setColumnWidth(1, 40);
205 myListPoints->setColumnWidth(2, 40);
206 myListPoints->setColumnWidth(3, 40);
207 myListPoints->setSelectionMode(QTable::NoSelection);
208 QHeader* aHeader = myListPoints->horizontalHeader();
209 aHeader->setLabel( 0, "ID" );
210 aHeader->setLabel( 1, "X" );
211 aHeader->setLabel( 2, "Y" );
212 aHeader->setLabel( 3, "Z" );
213 aHeader->setLabel( 4, "Scalar" );
214 aHeader->setLabel( 5, "Vector" );
216 aCellLayout->addWidget(myListPoints, 1, 0);
218 myWidgetStack->addWidget(myCellsPane, 1);
221 myActorsPane = new QVBox (myWidgetStack);
222 myActorsPane->layout()->setSpacing(6);
224 QGroupBox* aPosGrp = new QGroupBox (2, Qt::Horizontal, "Position", myActorsPane);
225 aPosGrp->layout()->setSpacing(6);
226 new QLabel ("X:", aPosGrp);
227 myXPosLbl = new QLabel ("0", aPosGrp);
228 new QLabel ("Y:", aPosGrp);
229 myYPosLbl = new QLabel ("0", aPosGrp);
230 new QLabel ("Z:", aPosGrp);
231 myZPosLbl = new QLabel ("0", aPosGrp);
233 QGroupBox* aSizeGrp = new QGroupBox (2, Qt::Horizontal, "Size", myActorsPane);
234 aSizeGrp->layout()->setSpacing(6);
235 new QLabel ("dX:", aSizeGrp);
236 myDXLbl = new QLabel ("0", aSizeGrp);
237 new QLabel ("dY:", aSizeGrp);
238 myDYLbl = new QLabel ("0", aSizeGrp);
239 new QLabel ("dZ:",aSizeGrp );
240 myDZLbl = new QLabel ("0", aSizeGrp);
242 myWidgetStack->addWidget(myActorsPane, 2);
245 TopLayout->addWidget(myWidgetStack, 2, 0);
247 // Create buttons group
248 QHBox* aBtnBox = new QHBox (this);
249 QHBoxLayout* aBtnLayout = (QHBoxLayout*)aBtnBox->layout();
250 aBtnLayout->addStretch();
252 QPushButton* aCloseBtn = new QPushButton (tr("BUT_CLOSE"), aBtnBox);
253 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
255 QPushButton* aHelpBtn = new QPushButton (tr("BUT_HELP"), aBtnBox);
256 connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
258 TopLayout->addWidget(aBtnBox, 3, 0);
260 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
261 (SUIT_Session::session()->activeApplication());
262 mySelectionMgr = anApp->selectionMgr();
263 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionEvent()));
265 //connect(visuGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close()));
269 // Activate Points pane
270 myWidgetStack->raiseWidget(myPointsPane);
271 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule))
272 aViewWindow->SetSelectionMode(NodeSelection);
275 mySelectionDlg = this;
278 VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()
282 void VisuGUI_SelectionDlg::onSelectionChange (int theId)
284 SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule);
285 if (!aViewWindow) return;
289 myWidgetStack->raiseWidget(myPointsPane);
290 aViewWindow->SetSelectionMode(NodeSelection);
291 onPointIdEdit(myIDValLbl->text());
294 myWidgetStack->raiseWidget(myCellsPane);
295 aViewWindow->SetSelectionMode(CellSelection);
296 onCellIdEdit(myCellIDValLbl->text());
299 myWidgetStack->raiseWidget(myActorsPane);
300 aViewWindow->SetSelectionMode(ActorSelection);
306 void VisuGUI_SelectionDlg::closeEvent (QCloseEvent* theEvent)
308 if (mySelectionDlg) {
309 mySelectionDlg = NULL;
310 disconnect(mySelectionMgr,0,0,0);
311 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)) {
312 switch(aViewWindow->SelectionMode()){
315 aViewWindow->SetSelectionMode(ActorSelection);
320 QDialog::closeEvent(theEvent);
323 template<class TData> QString getValue(TData* theData, int theId){
324 if (vtkDataArray *aScalar = theData->GetScalars()){
325 vtkFloatingPointType aVal = aScalar->GetTuple1(theId);
326 return QString::number(aVal);
328 return QString("No data");
332 template<class TData> QString getVector(TData* theData, int theId){
333 if (vtkDataArray *aVector = theData->GetVectors()) {
334 vtkFloatingPointType *aVal = aVector->GetTuple3(theId);
335 return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
337 return QString("No data");
341 #define ABS(a) (a>=0)?a:-a
343 void VisuGUI_SelectionDlg::onSelectionEvent() {
344 SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule);
345 if (!aViewWindow) return;
347 switch (aViewWindow->SelectionMode()) {
360 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
362 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
363 (SUIT_Session::session()->activeApplication());
365 SVTK_Selector* aSelector = aViewWindow->GetSelector();
367 VISU::Prs3d_i* aPrs3d = NULL;
368 _PTR(SObject) aSObject;
369 Handle(SALOME_InteractiveObject) anIO;
371 SALOME_ListIO aListIO;
372 mySelectionMgr->selectedObjects(aListIO);
374 if (aListIO.Extent() == 1) {
375 anIO = aListIO.First();
377 if (anIO->hasEntry()) {
378 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
379 _PTR(Study) aStudy = theStudy->studyDS();
380 aSObject = aStudy->FindObjectID(anIO->getEntry());
383 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
385 if (!CORBA::is_nil(anObject)) {
386 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
389 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
397 VISU::Storable::TRestoringMap aMap;
399 _PTR(GenericAttribute) anAttr;
400 if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
401 _PTR(AttributeComment) aComment (anAttr);
402 std::string aString = aComment->Value();
403 QString strIn( aString.c_str() );
404 VISU::Storable::StrToMap(strIn, aMap);
408 QString aMeshName("NULL"), aFieldName("NULL");
410 aMeshName = VISU::Storable::FindValue(aMap, "myMeshName");
411 aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
414 myMeshName ->setText((aMeshName == "NULL") ? QString("No name") : aMeshName);
415 myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
417 VISU_Actor* anVISUActor =
418 VISU::FindActor(aViewWindow, aSObject->GetID().c_str());
420 vtkFloatingPointType aCoord[6];
421 anVISUActor->GetBounds(aCoord);
422 myXPosLbl->setText(QString::number( aCoord[0] ));
423 myYPosLbl->setText(QString::number( aCoord[2] ));
424 myZPosLbl->setText(QString::number( aCoord[4] ));
426 myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
427 myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
428 myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
430 TColStd_IndexedMapOfInteger aMapIndex;
431 typedef map<int,vtkFloatingPointType*> PointsMap;
432 PointsMap aPointsMap;
434 aSelector->GetIndex(anIO, aMapIndex);
436 vtkDataSet* aDataSet = anVISUActor->GetInput();
437 vtkPointData* aPntData = aDataSet->GetPointData();
439 for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
440 int anID = aMapIndex(ind);
445 vtkFloatingPointType* aCoord = anVISUActor->GetNodeCoord(anID);
446 int aVTKID = anVISUActor->GetNodeVTKID(anID);
447 myXValLbl->setText( QString::number( aCoord[0] ) );
448 myYValLbl->setText( QString::number( aCoord[1] ) );
449 myZValLbl->setText( QString::number( aCoord[2] ) );
450 myIDValLbl->setText( QString::number(anID) );
451 myScalarValLbl->setText(getValue(aPntData, aVTKID));
452 myVectorValLbl->setText(getVector(aPntData, aVTKID));
457 vtkCellData* aCellData = aDataSet->GetCellData();
458 vtkCell* aCell = anVISUActor->GetElemCell(anID);
459 int aVTKID = anVISUActor->GetElemVTKID(anID);
461 int aNbOfPoints = aCell->GetNumberOfPoints();
462 if ( aNbOfPoints <= 1 ) { // Cell is point
465 myCellIDValLbl->setText( QString::number(anID) );
466 myCellScalarValLbl->setText(getValue(aCellData, aVTKID));
467 myCellVectorValLbl->setText(getVector(aCellData, aVTKID));
469 vtkFloatingPointType* aCoord;
470 vtkIdList *aPointList = aCell->GetPointIds();
472 for (int i = 0; i < aNbOfPoints; i++) {
473 int idCurrent = aPointList->GetId(i);
474 aCoord = aDataSet->GetPoint(idCurrent);
475 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
484 myListPoints->setNumRows(aPointsMap.size());
485 PointsMap::const_iterator It = aPointsMap.begin();
486 for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
487 myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
489 myListPoints->setText(i, 0, QString::number( id ));
490 vtkFloatingPointType* aCoord = It->second;
491 myListPoints->setText(i, 1, QString::number( aCoord[0] ));
492 myListPoints->setText(i, 2, QString::number( aCoord[1] ));
493 myListPoints->setText(i, 3, QString::number( aCoord[2] ));
494 myListPoints->setText(i, 4, getValue(aPntData, id));
495 myListPoints->setText(i, 5, getVector(aPntData, id));
506 void VisuGUI_SelectionDlg::clearFields() {
507 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
510 myXValLbl->setText( "" );
511 myYValLbl->setText( "" );
512 myZValLbl->setText( "" );
513 myIDValLbl->setText( "" );
514 myScalarValLbl->setText("");
515 myVectorValLbl->setText("");
518 myCellIDValLbl->setText( "" );
519 myCellScalarValLbl->setText("");
520 myCellVectorValLbl->setText("");
521 myListPoints->setNumRows(0);
524 myXPosLbl->setText("");
525 myYPosLbl->setText("");
526 myZPosLbl->setText("");
527 myDXLbl->setText("");
528 myDYLbl->setText("");
529 myDZLbl->setText("");
533 typedef vtkIdType (vtkDataSet::* TDataSetMethod)();
535 bool onIdEdit (const QString& theText,
536 TDataSetMethod theMethod,
538 const SalomeApp_Module* theModule,
539 LightApp_SelectionMgr* theSelectionMgr,
542 QLabel* theFieldName)
544 SalomeApp_Application* anApp = theModule->getApp();
545 SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule);
546 if (!aViewWindow) return false;
547 SVTK_Selector* aSelector = aViewWindow->GetSelector();
549 VISU::Prs3d_i* aPrs3d = NULL;
550 Handle(SALOME_InteractiveObject) anIO;
552 SALOME_ListIO aListIO;
553 theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
555 if (aListIO.Extent() == 1) {
556 anIO = aListIO.First();
558 if (anIO->hasEntry()) {
559 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
560 _PTR(Study) aStudy = theStudy->studyDS();
561 _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
564 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
566 if (!CORBA::is_nil(anObject)) {
567 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
570 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
578 int anId = theText.toInt();
579 vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
580 int aMaxId = (aDataSet->*theMethod)();
581 if (anId < 0) anId = 0;
582 if (anId >= aMaxId) anId = aMaxId - 1;
584 TColStd_MapOfInteger newIndices;
585 newIndices.Add(anId);
586 aSelector->AddOrRemoveIndex(anIO, newIndices, false);
587 aViewWindow->highlight(anIO, true, true);
592 theMeshName->setText(theValue);
593 theFieldName->setText("");
598 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
601 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
602 bool anIsSelected = onIdEdit(theText,aMethod,false,myModule,mySelectionMgr,
603 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
606 // as selection manager doesn't send signal currentSelectionChanged()
612 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
615 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
616 bool anIsSelected = onIdEdit(theText,aMethod,true,myModule,mySelectionMgr,
617 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
620 // as selection manager doesn't send signal currentSelectionChanged()
626 void VisuGUI_SelectionDlg::onHelp()
628 QString aHelpFileName = "/files/getting_elements_attributes.htm";
629 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
631 app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
633 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
634 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
635 arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(aHelpFileName),
636 QObject::tr("BUT_OK"));