// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : SMESHGUI_Measurements.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) #include "SMESHGUI_Measurements.h" #include "SMESH_Actor.h" #include "SMESHGUI.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CORBA_SERVER_HEADER(SMESH_MeshEditor) #include CORBA_SERVER_HEADER(SMESH_Measurements) const int SPACING = 6; // layout spacing const int MARGIN = 9; // layout margin const int MAX_NB_FOR_EDITOR = 40; // max nb of items in the ID list editor field // Uncomment as soon as elements are supported by Min Distance operation //#define MINDIST_ENABLE_ELEMENT // Uncomment as soon as objects are supported by Min Distance operation //#define MINDIST_ENABLE_OBJECT /*! \class SMESHGUI_MinDistance \brief Minimum distance measurement widget. Widget to calculate minimum distance between two objects. */ /*! \brief Constructor. \param parent parent widget */ SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent ) : QWidget( parent ), myCurrentTgt( FirstTgt ), myFirstActor( 0 ), mySecondActor( 0 ) { QGroupBox* aFirstTgtGrp = new QGroupBox( tr( "FIRST_TARGET" ), this ); QRadioButton* aFNode = new QRadioButton( tr( "NODE" ), aFirstTgtGrp ); QRadioButton* aFElem = new QRadioButton( tr( "ELEMENT" ), aFirstTgtGrp ); QRadioButton* aFObject = new QRadioButton( tr( "OBJECT" ), aFirstTgtGrp ); myFirstTgt = new QLineEdit( aFirstTgtGrp ); QGridLayout* fl = new QGridLayout( aFirstTgtGrp ); fl->setMargin( MARGIN ); fl->setSpacing( SPACING ); fl->addWidget( aFNode, 0, 0 ); fl->addWidget( aFElem, 0, 1 ); fl->addWidget( aFObject, 0, 2 ); fl->addWidget( myFirstTgt, 1, 0, 1, 3 ); myFirst = new QButtonGroup( this ); myFirst->addButton( aFNode, NodeTgt ); myFirst->addButton( aFElem, ElementTgt ); myFirst->addButton( aFObject, ObjectTgt ); QGroupBox* aSecondTgtGrp = new QGroupBox( tr( "SECOND_TARGET" ), this ); QRadioButton* aSOrigin = new QRadioButton( tr( "ORIGIN" ), aSecondTgtGrp ); QRadioButton* aSNode = new QRadioButton( tr( "NODE" ), aSecondTgtGrp ); QRadioButton* aSElem = new QRadioButton( tr( "ELEMENT" ), aSecondTgtGrp ); QRadioButton* aSObject = new QRadioButton( tr( "OBJECT" ), aSecondTgtGrp ); mySecondTgt = new QLineEdit( aSecondTgtGrp ); QGridLayout* sl = new QGridLayout( aSecondTgtGrp ); sl->setMargin( MARGIN ); sl->setSpacing( SPACING ); sl->addWidget( aSOrigin, 0, 0 ); sl->addWidget( aSNode, 0, 1 ); sl->addWidget( aSElem, 0, 2 ); sl->addWidget( aSObject, 0, 3 ); sl->addWidget( mySecondTgt, 1, 0, 1, 4 ); mySecond = new QButtonGroup( this ); mySecond->addButton( aSOrigin, OriginTgt ); mySecond->addButton( aSNode, NodeTgt ); mySecond->addButton( aSElem, ElementTgt ); mySecond->addButton( aSObject, ObjectTgt ); QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this ); QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this ); QLabel* aDxLab = new QLabel( "dX", aResults ); myDX = new QLineEdit( aResults ); QLabel* aDyLab = new QLabel( "dY", aResults ); myDY = new QLineEdit( aResults ); QLabel* aDzLab = new QLabel( "dZ", aResults ); myDZ = new QLineEdit( aResults ); QLabel* aDistLab = new QLabel( tr( "DISTANCE" ), aResults ); myDistance = new QLineEdit( aResults ); QGridLayout* rl = new QGridLayout( aResults ); rl->setMargin( MARGIN ); rl->setSpacing( SPACING ); rl->addWidget( aDxLab, 0, 0 ); rl->addWidget( myDX, 0, 1 ); rl->addWidget( aDyLab, 1, 0 ); rl->addWidget( myDY, 1, 1 ); rl->addWidget( aDzLab, 2, 0 ); rl->addWidget( myDZ, 2, 1 ); rl->addWidget( aDistLab, 0, 2 ); rl->addWidget( myDistance, 0, 3 ); QGridLayout* l = new QGridLayout( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); l->addWidget( aFirstTgtGrp, 0, 0, 1, 2 ); l->addWidget( aSecondTgtGrp, 1, 0, 1, 2 ); l->addWidget( aCompute, 2, 0 ); l->addWidget( aResults, 3, 0, 1, 2 ); l->setColumnStretch( 1, 5 ); l->setRowStretch( 4, 5 ); aFNode->setChecked( true ); aSOrigin->setChecked( true ); #ifndef MINDIST_ENABLE_ELEMENT aFElem->setEnabled( false ); // NOT AVAILABLE YET aSElem->setEnabled( false ); // NOT AVAILABLE YET #endif #ifndef MINDIST_ENABLE_OBJECT aFObject->setEnabled( false ); // NOT AVAILABLE YET aSObject->setEnabled( false ); // NOT AVAILABLE YET #endif myDX->setReadOnly( true ); myDY->setReadOnly( true ); myDZ->setReadOnly( true ); myDistance->setReadOnly( true ); myValidator = new SMESHGUI_IdValidator( this, 1 ); myFirstTgt->installEventFilter( this ); mySecondTgt->installEventFilter( this ); connect( myFirst, SIGNAL( buttonClicked( int ) ), this, SLOT( firstChanged() ) ); connect( mySecond, SIGNAL( buttonClicked( int ) ), this, SLOT( secondChanged() ) ); connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) ); connect( myFirstTgt, SIGNAL( textEdited( QString ) ), this, SLOT( firstEdited() ) ); connect( mySecondTgt, SIGNAL( textEdited( QString ) ), this, SLOT( secondEdited() ) ); QList filters; filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); filters.append( new SMESH_TypeFilter( GROUP ) ); myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); clear(); //setTarget( FirstTgt ); } /*! \brief Destructor */ SMESHGUI_MinDistance::~SMESHGUI_MinDistance() { } /*! \brief Event filter \param o object \param o event \return \c true if event is filtered or \c false otherwise */ bool SMESHGUI_MinDistance::eventFilter( QObject* o, QEvent* e ) { if ( e->type() == QEvent::FocusIn ) { if ( o == myFirstTgt ) setTarget( FirstTgt ); else if ( o == mySecondTgt ) setTarget( SecondTgt ); } return QWidget::eventFilter( o, e ); } /*! \brief Setup selection mode depending on the current widget state */ void SMESHGUI_MinDistance::updateSelection() { LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); disconnect( selMgr, 0, this, 0 ); selMgr->clearFilters(); bool nodeMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == NodeTgt ) || ( myCurrentTgt == SecondTgt && mySecond->checkedId() == NodeTgt ); bool elemMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ElementTgt ) || ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ElementTgt ); bool objMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ObjectTgt ) || ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ObjectTgt ) || ( myCurrentTgt == NoTgt ); if ( nodeMode ) { SMESH::SetPointRepresentation( true ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( NodeSelection ); } else if ( elemMode ) { SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( CellSelection ); } else if ( objMode ) { SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( ActorSelection ); selMgr->installFilter( myFilter ); } connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) ); if ( myCurrentTgt == FirstTgt ) firstEdited(); else if ( myCurrentTgt == SecondTgt ) secondEdited(); //selectionChanged(); } /*! \brief Deactivate widget */ void SMESHGUI_MinDistance::deactivate() { disconnect( SMESHGUI::selectionMgr(), 0, this, 0 ); } /*! \brief Set current target for selection \param target new target ID */ void SMESHGUI_MinDistance::setTarget( int target ) { if ( myCurrentTgt != target ) { myCurrentTgt = target; updateSelection(); } } /*! \brief Called when selection is changed */ void SMESHGUI_MinDistance::selectionChanged() { SUIT_OverrideCursor wc; SALOME_ListIO selected; SMESHGUI::selectionMgr()->selectedObjects( selected ); if ( selected.Extent() == 1 ) { Handle(SALOME_InteractiveObject) IO = selected.First(); SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); if ( !CORBA::is_nil( obj ) ) { if ( myCurrentTgt == FirstTgt ) { myFirstSrc = obj; myFirstActor = SMESH::FindActorByEntry( IO->getEntry() ); if ( myFirst->checkedId() == ObjectTgt ) { QString aName; SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); myFirstTgt->setText( aName ); } else { SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); QString ID; int nb = 0; if ( myFirstActor && selector ) { nb = myFirst->checkedId() == NodeTgt ? SMESH::GetNameOfSelectedElements( selector, IO, ID ) : SMESH::GetNameOfSelectedNodes( selector, IO, ID ); } if ( nb == 1 ) myFirstTgt->setText( ID.trimmed() ); else myFirstTgt->clear(); } } else if ( myCurrentTgt == SecondTgt ) { mySecondSrc = obj; mySecondActor = SMESH::FindActorByEntry( IO->getEntry() ); if ( mySecond->checkedId() == ObjectTgt ) { QString aName; SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); mySecondTgt->setText( aName ); } else { SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); QString ID; int nb = 0; if ( mySecondActor && selector ) { nb = mySecond->checkedId() == NodeTgt ? SMESH::GetNameOfSelectedElements( selector, IO, ID ) : SMESH::GetNameOfSelectedNodes( selector, IO, ID ); } if ( nb == 1 ) mySecondTgt->setText( ID.trimmed() ); else mySecondTgt->clear(); } } } } } /*! \brief Called when first target mode is changed by the user */ void SMESHGUI_MinDistance::firstChanged() { myFirstTgt->clear(); myFirstTgt->setReadOnly( myFirst->checkedId() == ObjectTgt ); myFirstTgt->setValidator( myFirst->checkedId() == ObjectTgt ? 0 : myValidator ); setTarget( FirstTgt ); updateSelection(); clear(); } /*! \brief Called when second target mode is changed by the user */ void SMESHGUI_MinDistance::secondChanged() { mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt ); mySecondTgt->setReadOnly( mySecond->checkedId() == ObjectTgt ); mySecondTgt->setValidator( mySecond->checkedId() == ObjectTgt ? 0 : myValidator ); mySecondTgt->clear(); setTarget( mySecond->checkedId() != OriginTgt ? SecondTgt : NoTgt ); updateSelection(); clear(); } /*! \brief Called when first target is edited by the user */ void SMESHGUI_MinDistance::firstEdited() { setTarget( FirstTgt ); clear(); SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); if ( myFirstActor && selector ) { Handle(SALOME_InteractiveObject) IO = myFirstActor->getIO(); if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) { TColStd_MapOfInteger ID; ID.Add( myFirstTgt->text().toLong() ); selector->AddOrRemoveIndex( IO, ID, false ); } if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->highlight( IO, true, true ); } } /*! \brief Called when second target is edited by the user */ void SMESHGUI_MinDistance::secondEdited() { setTarget( SecondTgt ); clear(); SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); if ( mySecondActor && selector ) { Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO(); if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) { TColStd_MapOfInteger ID; ID.Add( mySecondTgt->text().toLong() ); selector->AddOrRemoveIndex( IO, ID, false ); } if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->highlight( IO, true, true ); } } /*! \brief Compute the minimum distance between targets */ void SMESHGUI_MinDistance::compute() { SUIT_OverrideCursor wc; SMESH::SMESH_IDSource_var s1; SMESH::SMESH_IDSource_var s2; bool isOrigin = mySecond->checkedId() == OriginTgt; // process first target if ( !CORBA::is_nil( myFirstSrc ) ) { if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) { SMESH::SMESH_Mesh_var m = myFirstSrc->GetMesh(); long id = myFirstTgt->text().toLong(); if ( !CORBA::is_nil( m ) && id ) { SMESH::long_array_var ids = new SMESH::long_array(); ids->length( 1 ); ids[0] = id; SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); s1 = me->MakeIDSource( ids.in(), myFirst->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE ); } } else { s1 = myFirstSrc; } } // process second target if ( !CORBA::is_nil( mySecondSrc ) ) { if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) { SMESH::SMESH_Mesh_var m = mySecondSrc->GetMesh(); long id = mySecondTgt->text().toLong(); if ( !CORBA::is_nil( m ) && id ) { SMESH::long_array_var ids = new SMESH::long_array(); ids->length( 1 ); ids[0] = id; SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); s2 = me->MakeIDSource( ids.in(), mySecond->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE ); } } else { s2 = mySecondSrc; } } if ( !CORBA::is_nil( s1 ) && ( !CORBA::is_nil( s2 ) || isOrigin ) ) { int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements(); SMESH::Measure result = measure->MinDistance( s1.in(), s2.in() ); measure->Destroy(); myDX->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); myDY->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); myDZ->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); myDistance->setText( QString::number( result.value, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); } else { clear(); } } /*! \brief Reset the widget to the initial state (nullify result fields) */ void SMESHGUI_MinDistance::clear() { myDX->clear(); myDY->clear(); myDZ->clear(); myDistance->clear(); } /*! \class SMESHGUI_BoundingBox \brief Bounding box measurement widget. Widget to calculate bounding box of the selected object(s). */ /*! \brief Constructor. \param parent parent widget */ SMESHGUI_BoundingBox::SMESHGUI_BoundingBox( QWidget* parent ) : QWidget( parent ), myActor( 0 ) { QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE" ), this ); QRadioButton* aObjects = new QRadioButton( tr( "OBJECTS" ), aSourceGrp ); QRadioButton* aNodes = new QRadioButton( tr( "NODES" ), aSourceGrp ); QRadioButton* aElements = new QRadioButton( tr( "ELEMENTS" ), aSourceGrp ); mySource = new QLineEdit( aSourceGrp ); QGridLayout* fl = new QGridLayout( aSourceGrp ); fl->setMargin( MARGIN ); fl->setSpacing( SPACING ); fl->addWidget( aObjects, 0, 0 ); fl->addWidget( aNodes, 0, 1 ); fl->addWidget( aElements, 0, 2 ); fl->addWidget( mySource, 1, 0, 1, 3 ); mySourceMode = new QButtonGroup( this ); mySourceMode->addButton( aObjects, ObjectsSrc ); mySourceMode->addButton( aNodes, NodesSrc ); mySourceMode->addButton( aElements, ElementsSrc ); QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this ); QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this ); QLabel* aXminLab = new QLabel( "Xmin", aResults ); myXmin = new QLineEdit( aResults ); QLabel* aXmaxLab = new QLabel( "Xmax", aResults ); myXmax = new QLineEdit( aResults ); QLabel* aDxLab = new QLabel( "dX", aResults ); myDX = new QLineEdit( aResults ); QLabel* aYminLab = new QLabel( "Ymin", aResults ); myYmin = new QLineEdit( aResults ); QLabel* aYmaxLab = new QLabel( "Ymax", aResults ); myYmax = new QLineEdit( aResults ); QLabel* aDyLab = new QLabel( "dY", aResults ); myDY = new QLineEdit( aResults ); QLabel* aZminLab = new QLabel( "Zmin", aResults ); myZmin = new QLineEdit( aResults ); QLabel* aZmaxLab = new QLabel( "Zmax", aResults ); myZmax = new QLineEdit( aResults ); QLabel* aDzLab = new QLabel( "dZ", aResults ); myDZ = new QLineEdit( aResults ); QGridLayout* rl = new QGridLayout( aResults ); rl->setMargin( MARGIN ); rl->setSpacing( SPACING ); rl->addWidget( aXminLab, 0, 0 ); rl->addWidget( myXmin, 0, 1 ); rl->addWidget( aXmaxLab, 0, 2 ); rl->addWidget( myXmax, 0, 3 ); rl->addWidget( aDxLab, 0, 4 ); rl->addWidget( myDX, 0, 5 ); rl->addWidget( aYminLab, 1, 0 ); rl->addWidget( myYmin, 1, 1 ); rl->addWidget( aYmaxLab, 1, 2 ); rl->addWidget( myYmax, 1, 3 ); rl->addWidget( aDyLab, 1, 4 ); rl->addWidget( myDY, 1, 5 ); rl->addWidget( aZminLab, 2, 0 ); rl->addWidget( myZmin, 2, 1 ); rl->addWidget( aZmaxLab, 2, 2 ); rl->addWidget( myZmax, 2, 3 ); rl->addWidget( aDzLab, 2, 4 ); rl->addWidget( myDZ, 2, 5 ); QGridLayout* l = new QGridLayout( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); l->addWidget( aSourceGrp, 0, 0, 1, 2 ); l->addWidget( aCompute, 1, 0 ); l->addWidget( aResults, 2, 0, 1, 2 ); l->setColumnStretch( 1, 5 ); l->setRowStretch( 3, 5 ); aObjects->setChecked( true ); myXmin->setReadOnly( true ); myXmax->setReadOnly( true ); myDX->setReadOnly( true ); myYmin->setReadOnly( true ); myYmax->setReadOnly( true ); myDY->setReadOnly( true ); myZmin->setReadOnly( true ); myZmax->setReadOnly( true ); myDZ->setReadOnly( true ); myValidator = new SMESHGUI_IdValidator( this ); connect( mySourceMode, SIGNAL( buttonClicked( int ) ), this, SLOT( sourceChanged() ) ); connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) ); connect( mySource, SIGNAL( textEdited( QString ) ), this, SLOT( sourceEdited() ) ); QList filters; filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); filters.append( new SMESH_TypeFilter( GROUP ) ); myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); clear(); } /*! \brief Destructor */ SMESHGUI_BoundingBox::~SMESHGUI_BoundingBox() { } /*! \brief Setup selection mode depending on the current widget state */ void SMESHGUI_BoundingBox::updateSelection() { LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); disconnect( selMgr, 0, this, 0 ); selMgr->clearFilters(); bool nodeMode = mySourceMode->checkedId() == NodesSrc; bool elemMode = mySourceMode->checkedId() == ElementsSrc; bool objMode = mySourceMode->checkedId() == ObjectsSrc; if ( nodeMode ) { SMESH::SetPointRepresentation( true ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( NodeSelection ); } else if ( elemMode ) { SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( CellSelection ); } else if ( objMode ) { SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( ActorSelection ); selMgr->installFilter( myFilter ); } connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) ); sourceEdited(); //selectionChanged(); } /*! \brief Deactivate widget */ void SMESHGUI_BoundingBox::deactivate() { disconnect( SMESHGUI::selectionMgr(), 0, this, 0 ); } /*! \brief Called when selection is changed */ void SMESHGUI_BoundingBox::selectionChanged() { SUIT_OverrideCursor wc; SALOME_ListIO selected; SMESHGUI::selectionMgr()->selectedObjects( selected ); if ( selected.Extent() == 1 ) { Handle(SALOME_InteractiveObject) IO = selected.First(); SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); if ( !CORBA::is_nil( obj ) ) { mySrc.clear(); mySrc.append( obj ); myActor = SMESH::FindActorByEntry( IO->getEntry() ); if ( mySourceMode->checkedId() == ObjectsSrc ) { QString aName; SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); mySource->setText( aName ); } else { SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); QString ID; int nb = 0; if ( myActor && selector ) { nb = mySourceMode->checkedId() == NodesSrc ? SMESH::GetNameOfSelectedElements( selector, IO, ID ) : SMESH::GetNameOfSelectedNodes( selector, IO, ID ); } if ( nb > 0 ) { myIDs = ID.trimmed(); if ( nb < MAX_NB_FOR_EDITOR ) { mySource->setReadOnly( false ); if ( mySource->validator() != myValidator ) mySource->setValidator( myValidator ); mySource->setText( ID.trimmed() ); } else { mySource->setReadOnly( true ); mySource->setValidator( 0 ); mySource->setText( tr( "SELECTED_NB_OBJ" ).arg( nb ) .arg( mySourceMode->checkedId() == NodesSrc ? tr( "NB_NODES" ) : tr( "NB_ELEMENTS") ) ); } } else { myIDs = ""; mySource->clear(); mySource->setReadOnly( false ); mySource->setValidator( myValidator ); } } } } else if ( selected.Extent() > 1 ) { myIDs = ""; SALOME_ListIteratorOfListIO It( selected ); mySrc.clear(); myActor = 0; if ( mySourceMode->checkedId() == ObjectsSrc ) { for( ; It.More(); It.Next()){ Handle(SALOME_InteractiveObject) IO = It.Value(); SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); if ( !CORBA::is_nil( obj ) ) { mySrc.append( obj ); } } QString aName; SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); mySource->setText( aName ); } else { mySource->clear(); } } } /*! \brief Called when source mode is changed by the user */ void SMESHGUI_BoundingBox::sourceChanged() { myIDs = ""; mySource->clear(); mySource->setReadOnly( mySourceMode->checkedId() == ObjectsSrc ); mySource->setValidator( mySourceMode->checkedId() == ObjectsSrc ? 0 : myValidator ); updateSelection(); clear(); } /*! \brief Called when source mode is edited by the user */ void SMESHGUI_BoundingBox::sourceEdited() { clear(); SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); if ( myActor && selector ) { Handle(SALOME_InteractiveObject) IO = myActor->getIO(); if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) { TColStd_MapOfInteger ID; if ( !mySource->isReadOnly() ) myIDs = mySource->text(); QStringList ids = mySource->text().split( " ", QString::SkipEmptyParts ); foreach ( QString id, ids ) ID.Add( id.trimmed().toLong() ); selector->AddOrRemoveIndex( IO, ID, false ); } if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->highlight( IO, true, true ); } } /*! \brief Calculate bounding box of the selected object(s) */ void SMESHGUI_BoundingBox::compute() { SUIT_OverrideCursor wc; if ( mySourceMode->checkedId() == NodesSrc ) { } else { } } /*! \brief Reset the widget to the initial state (nullify result fields) */ void SMESHGUI_BoundingBox::clear() { myXmin->clear(); myXmax->clear(); myDX->clear(); myYmin->clear(); myYmax->clear(); myDY->clear(); myZmin->clear(); myZmax->clear(); myDZ->clear(); } /*! \class SMESHGUI_MeshInfoDlg \brief Centralized dialog box for the measurements */ /*! \brief Constructor \param parent parent widget \param page specifies the dialog page to be shown at the start-up */ SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page ) : QDialog( parent ) { setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); setWindowTitle( tr( "MEASUREMENTS" ) ); setSizeGripEnabled( true ); myTabWidget = new QTabWidget( this ); // min distance myMinDist = new SMESHGUI_MinDistance( myTabWidget ); myTabWidget->addTab( myMinDist, tr( "MIN_DIST" ) ); // bounding box myBndBox = new SMESHGUI_BoundingBox( myTabWidget ); myTabWidget->addTab( myBndBox, tr( "BND_BOX" ) ); // buttons QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); okBtn->setAutoDefault( true ); okBtn->setDefault( true ); okBtn->setFocus(); QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); helpBtn->setAutoDefault( true ); QHBoxLayout* btnLayout = new QHBoxLayout; btnLayout->setSpacing( SPACING ); btnLayout->setMargin( 0 ); btnLayout->addWidget( okBtn ); btnLayout->addStretch( 10 ); btnLayout->addWidget( helpBtn ); QVBoxLayout* l = new QVBoxLayout ( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); l->addWidget( myTabWidget ); l->addStretch(); l->addLayout( btnLayout ); myTabWidget->setCurrentIndex( qMax( (int)MinDistance, qMin( (int)BoundingBox, page ) ) ); connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); updateSelection(); } /*! \brief Destructor */ SMESHGUI_MeasureDlg::~SMESHGUI_MeasureDlg() { } /*! \brief Perform clean-up actions on the dialog box closing. */ void SMESHGUI_MeasureDlg::reject() { LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); selMgr->clearFilters(); SMESH::SetPointRepresentation( false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->SetSelectionMode( ActorSelection ); QDialog::reject(); } /*! \brief Process keyboard event \param e key press event */ void SMESHGUI_MeasureDlg::keyPressEvent( QKeyEvent* e ) { QDialog::keyPressEvent( e ); if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) { e->accept(); help(); } } /*! \brief Reactivate dialog box, when mouse pointer goes into it. */ void SMESHGUI_MeasureDlg::enterEvent( QEvent* ) { activate(); } /*! \brief Setup selection mode depending on the current dialog box state. */ void SMESHGUI_MeasureDlg::updateSelection() { if ( myTabWidget->currentIndex() == MinDistance ) myMinDist->updateSelection(); else if ( myTabWidget->currentIndex() == BoundingBox ) myBndBox->updateSelection(); } /*! \brief Show help page */ void SMESHGUI_MeasureDlg::help() { SMESH::ShowHelpFile( myTabWidget->currentIndex() == MinDistance ? "measurements_page.html#min_distance_anchor" : "measurements_page.html#bounding_box_anchor" ); } /*! \brief Activate dialog box */ void SMESHGUI_MeasureDlg::activate() { SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); myTabWidget->setEnabled( true ); updateSelection(); } /*! \brief Deactivate dialog box */ void SMESHGUI_MeasureDlg::deactivate() { myMinDist->deactivate(); myBndBox->deactivate(); myTabWidget->setEnabled( false ); disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); }