1 // SMESH SMESHGUI : GUI for SMESH 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESHGUI_MoveNodesDlg.cxx
25 // Author : Nicolas REJNERI
29 #include "SMESHGUI_MoveNodesDlg.h"
32 #include "SMESHGUI_SpinBox.h"
33 #include "SMESHGUI_IdValidator.h"
35 #include "SMESHGUI_Utils.h"
36 #include "SMESHGUI_VTKUtils.h"
37 #include "SMESHGUI_MeshUtils.h"
39 #include "SMESH_Actor.h"
40 #include "SMDS_Mesh.hxx"
41 #include "SMDS_MeshNode.hxx"
43 #include "SALOME_Selection.h"
44 #include "VTKViewer_ViewFrame.h"
45 #include "QAD_Desktop.h"
46 #include "QAD_RightFrame.h"
47 #include "QAD_MessageBox.h"
49 #include "utilities.h"
52 #include <vtkIdList.h>
53 #include <vtkIntArray.h>
54 #include <vtkCellArray.h>
55 #include <vtkUnsignedCharArray.h>
56 #include <vtkUnstructuredGrid.h>
57 #include <vtkDataSetMapper.h>
59 #include <qgroupbox.h>
61 #include <qlineedit.h>
62 #include <qpushbutton.h>
63 #include <qradiobutton.h>
66 #include <qmessagebox.h>
67 #include <qbuttongroup.h>
70 #include <SALOMEconfig.h>
71 #include CORBA_SERVER_HEADER(SMESH_Mesh)
77 //=================================================================================
78 // class : SMESHGUI_MoveNodesDlg()
80 //=================================================================================
81 SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg( QWidget* theParent,
82 SALOME_Selection* theSelection,
85 : QDialog( theParent, theName, false,
86 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
92 setCaption( tr( "CAPTION" ) );
94 QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
96 QFrame* aMainFrame = createMainFrame ( this );
97 QFrame* aBtnFrame = createButtonFrame( this );
99 aDlgLay->addWidget( aMainFrame );
100 aDlgLay->addWidget( aBtnFrame );
102 aDlgLay->setStretchFactor( aMainFrame, 1 );
104 Init( theSelection ) ;
107 //=======================================================================
108 // name : SMESHGUI_MoveNodesDlg::createButtonFrame
109 // Purpose : Create frame containing buttons
110 //=======================================================================
111 QFrame* SMESHGUI_MoveNodesDlg::createButtonFrame( QWidget* theParent )
113 QFrame* aFrame = new QFrame( theParent );
114 aFrame->setFrameStyle( QFrame::Box | QFrame::Sunken );
116 myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aFrame );
117 myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aFrame );
118 myCloseBtn = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aFrame );
120 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
122 QHBoxLayout* aLay = new QHBoxLayout( aFrame, MARGIN, SPACING );
124 aLay->addWidget( myOkBtn );
125 aLay->addWidget( myApplyBtn );
126 aLay->addItem( aSpacer);
127 aLay->addWidget( myCloseBtn );
129 connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) );
130 connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
131 connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
136 //=======================================================================
137 // name : SMESHGUI_MoveNodesDlg::createMainFrame
138 // Purpose : Create frame containing dialog's input fields
139 //=======================================================================
140 QFrame* SMESHGUI_MoveNodesDlg::createMainFrame( QWidget* theParent )
142 QFrame* aFrame = new QFrame( theParent );
144 QPixmap iconMoveNode(
145 QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_DLG_MOVE_NODE" ) ) );
147 QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) );
149 QButtonGroup* aPixGrp = new QButtonGroup( 1, Qt::Vertical, tr( "MESH_NODE" ), aFrame );
150 aPixGrp->setExclusive( TRUE );
151 QRadioButton* aRBut = new QRadioButton( aPixGrp );
152 aRBut->setPixmap( iconMoveNode );
153 aRBut->setChecked( TRUE );
155 QGroupBox* anIdGrp = new QGroupBox( 1, Qt::Vertical, tr( "SMESH_MOVE" ), aFrame );
156 new QLabel( tr( "NODE_ID" ), anIdGrp );
157 ( new QPushButton( anIdGrp ) )->setPixmap( iconSelect );
158 myId = new QLineEdit( anIdGrp );
159 myId->setValidator( new SMESHGUI_IdValidator( this, "validator", 1 ));
161 QGroupBox* aCoordGrp = new QGroupBox( 1, Qt::Vertical, tr( "SMESH_COORDINATES" ), aFrame );
162 new QLabel( tr( "SMESH_X" ), aCoordGrp );
163 myX = new SMESHGUI_SpinBox( aCoordGrp );
164 new QLabel( tr( "SMESH_Y" ), aCoordGrp );
165 myY = new SMESHGUI_SpinBox( aCoordGrp );
166 new QLabel( tr( "SMESH_Z" ), aCoordGrp );
167 myZ = new SMESHGUI_SpinBox( aCoordGrp );
169 myX->RangeStepAndValidator( -999999.999, +999999.999, 25.0, 3 );
170 myY->RangeStepAndValidator( -999999.999, +999999.999, 25.0, 3 );
171 myZ->RangeStepAndValidator( -999999.999, +999999.999, 25.0, 3 );
173 QVBoxLayout* aLay = new QVBoxLayout( aFrame );
174 aLay->addWidget( aPixGrp );
175 aLay->addWidget( anIdGrp );
176 aLay->addWidget( aCoordGrp );
178 // connect signale and slots
179 connect( myX, SIGNAL ( valueChanged( double) ), this, SLOT( redisplayPreview() ) );
180 connect( myY, SIGNAL ( valueChanged( double) ), this, SLOT( redisplayPreview() ) );
181 connect( myZ, SIGNAL ( valueChanged( double) ), this, SLOT( redisplayPreview() ) );
182 connect( myId, SIGNAL( textChanged(const QString&) ), SLOT( onTextChange(const QString&) ));
187 //=======================================================================
188 // name : SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg
190 //=======================================================================
191 SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg()
196 //=======================================================================
197 // name : SMESHGUI_MoveNodesDlg::Init
198 // Purpose : Init dialog fields
199 //=======================================================================
200 void SMESHGUI_MoveNodesDlg::Init( SALOME_Selection* theSelection )
205 mySelection = theSelection;
207 SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
208 aSMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
210 // selection and SMESHGUI
211 connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
212 connect( aSMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
213 connect( aSMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
219 aSMESHGUI->DefineDlgPosition( this, x, y );
223 // set selection mode
224 SMESH::SetPointRepresentation(true);
225 QAD_Application::getDesktop()->SetSelectionMode( NodeSelection, true );
229 //=======================================================================
230 // name : SMESHGUI_MoveNodesDlg::isValid
231 // Purpose : Verify validity of entry information
232 //=======================================================================
233 bool SMESHGUI_MoveNodesDlg::isValid( const bool theMess ) const
235 if ( myId->text().isEmpty() )
238 QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
239 tr( "SMESH_WARNING" ), tr( "NODE_ID_IS_NOT_DEFINED" ), QMessageBox::Ok );
245 //=======================================================================
246 // name : SMESHGUI_MoveNodesDlg::reset
247 // Purpose : Reset the dialog state
248 //=======================================================================
249 void SMESHGUI_MoveNodesDlg::reset()
259 //=======================================================================
260 // name : SMESHGUI_MoveNodesDlg::nApply
261 // Purpose : SLOT called when "Apply" button pressed.
262 //=======================================================================
263 bool SMESHGUI_MoveNodesDlg::onApply()
265 if (SMESHGUI::GetSMESHGUI()->ActiveStudyLocked())
268 if ( !isValid( true ) )
271 SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( myMeshActor->getIO() );
272 if(aMesh->_is_nil() )
274 QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
275 tr( "SMESH_ERROR" ), tr( "SMESHG_NO_MESH" ), QMessageBox::Ok );
279 SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
280 if ( aMeshEditor->_is_nil() )
283 int anId = myId->text().toInt();
284 bool aResult = false;
287 aResult = aMeshEditor->MoveNode( anId, myX->GetValue(), myY->GetValue(), myZ->GetValue() );
295 Handle(SALOME_InteractiveObject) anIO = myMeshActor->getIO();
296 mySelection->ClearIObjects();
298 mySelection->AddIObject( anIO, false );
306 //=======================================================================
307 // name : SMESHGUI_MoveNodesDlg::onOk
308 // Purpose : SLOT called when "Ok" button pressed.
309 //=======================================================================
310 void SMESHGUI_MoveNodesDlg::onOk()
317 //=======================================================================
318 // name : SMESHGUI_MoveNodesDlg::onClose
319 // Purpose : SLOT called when "Close" button pressed. Close dialog
320 //=======================================================================
321 void SMESHGUI_MoveNodesDlg::onClose()
323 mySelection->ClearIObjects();
324 SMESH::SetPointRepresentation(false);
325 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
326 disconnect( mySelection, 0, this, 0 );
327 disconnect( SMESHGUI::GetSMESHGUI(), 0, this, 0 );
328 SMESHGUI::GetSMESHGUI()->ResetState();
334 //=======================================================================
335 //function : onTextChange
337 //=======================================================================
339 void SMESHGUI_MoveNodesDlg::onTextChange(const QString& theNewText)
341 if ( myBusy ) return;
343 myOkBtn->setEnabled( false );
344 myApplyBtn->setEnabled( false );
347 // select entered node
348 SMDS_Mesh* aMesh = 0;
350 aMesh = myMeshActor->GetObject()->GetMesh();
354 mySelection->ClearIObjects();
355 mySelection->AddIObject( myMeshActor->getIO() );
358 const SMDS_MeshElement * e = aMesh->FindElement( theNewText.toInt() );
360 mySelection->AddOrRemoveIndex (myMeshActor->getIO(), e->GetID(), true);
364 //=======================================================================
365 // name : SMESHGUI_MoveNodesDlg::onSelectionDone
366 // Purpose : SLOT called when selection changed
367 //=======================================================================
368 void SMESHGUI_MoveNodesDlg::onSelectionDone()
370 if ( myBusy ) return;
373 if ( mySelection->IObjectCount() == 1 ) {
374 myMeshActor = SMESH::FindActorByEntry(mySelection->firstIObject()->getEntry());
378 if ( SMESH::GetNameOfSelectedNodes( mySelection, aText ) == 1 ) {
379 if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()) {
380 if(const SMDS_MeshNode* aNode = aMesh->FindNode(aText.toInt())) {
382 myId->setText( aText );
383 myX->SetValue( aNode->X() );
384 myY->SetValue( aNode->Y() );
385 myZ->SetValue( aNode->Z() );
387 erasePreview(); // avoid overlapping of a selection and a preview
400 //=======================================================================
401 // name : SMESHGUI_MoveNodesDlg::onDeactivate
402 // Purpose : SLOT called when dialog must be deativated
403 //=======================================================================
404 void SMESHGUI_MoveNodesDlg::onDeactivate()
411 //=======================================================================
412 // name : SMESHGUI_MoveNodesDlg::enterEvent
413 // Purpose : Event filter
414 //=======================================================================
415 void SMESHGUI_MoveNodesDlg::enterEvent( QEvent* )
419 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
421 // set selection mode
422 SMESH::SetPointRepresentation(true);
423 QAD_Application::getDesktop()->SetSelectionMode( NodeSelection, true );
432 //=================================================================================
433 // function : closeEvent()
435 //=================================================================================
436 void SMESHGUI_MoveNodesDlg::closeEvent( QCloseEvent* e )
439 SMESH::GetCurrentVtkView()->Repaint();
442 //=======================================================================
443 //function : hideEvent
444 //purpose : may be caused by ESC key
445 //=======================================================================
447 void SMESHGUI_MoveNodesDlg::hideEvent ( QHideEvent * e )
449 if ( !isMinimized() )
453 //=======================================================================
454 // name : SMESHGUI_MoveNodesDlg::updateButtons
455 // Purpose : Update buttons state
456 //=======================================================================
457 void SMESHGUI_MoveNodesDlg::updateButtons()
459 bool isEnabled = isValid( false );
460 myOkBtn->setEnabled( isEnabled );
461 myApplyBtn->setEnabled( isEnabled );
464 //=======================================================================
465 // name : SMESHGUI_MoveNodesDlg::erasePreview
466 // Purpose : Erase preview
467 //=======================================================================
468 void SMESHGUI_MoveNodesDlg::erasePreview()
470 if ( myPreviewActor == 0 )
473 if ( VTKViewer_ViewFrame* vf = SMESH::GetCurrentVtkView() )
474 vf->RemoveActor(myPreviewActor);
475 myPreviewActor->Delete();
477 SMESH::GetCurrentVtkView()->Repaint();
480 //=======================================================================
481 // name : SMESHGUI_MoveNodesDlg::redisplayPreview
482 // Purpose : Redisplay preview
483 //=======================================================================
484 void SMESHGUI_MoveNodesDlg::redisplayPreview()
489 if ( myPreviewActor != 0 )
492 if ( !isValid( false ) )
495 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
497 vtkPoints* aPoints = vtkPoints::New();
498 aPoints->SetNumberOfPoints( 1 );
499 aPoints->SetPoint( 0, myX->GetValue(), myY->GetValue(), myZ->GetValue() );
503 vtkIdList *anIdList = vtkIdList::New();
504 anIdList->SetNumberOfIds( 1 );
506 vtkCellArray *aCells = vtkCellArray::New();
507 aCells->Allocate( 2, 0 );
509 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
510 aCellTypesArray->SetNumberOfComponents( 1 );
511 aCellTypesArray->Allocate( 1 );
513 anIdList->SetId( 0, 0 );
514 aCells->InsertNextCell( anIdList );
515 aCellTypesArray->InsertNextValue( VTK_VERTEX );
517 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
518 aCellLocationsArray->SetNumberOfComponents( 1 );
519 aCellLocationsArray->SetNumberOfTuples( 1 );
521 aCells->InitTraversal();
523 aCellLocationsArray->SetValue( 0, aCells->GetTraversalLocation( npts ) );
525 aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
527 aGrid->SetPoints( aPoints );
528 aGrid->SetCells( aCellTypesArray, aCellLocationsArray,aCells );
530 // Create and display actor
531 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
532 aMapper->SetInput( aGrid );
534 myPreviewActor = SALOME_Actor::New();
535 myPreviewActor->PickableOff();
536 myPreviewActor->SetMapper( aMapper );
538 vtkProperty* aProp = vtkProperty::New();
539 aProp->SetRepresentationToWireframe();
540 aProp->SetColor( 250, 0, 250 );
541 aProp->SetPointSize( 5 );
542 myPreviewActor->SetProperty( aProp );
544 SMESH::GetCurrentVtkView()->AddActor( myPreviewActor );
545 SMESH::GetCurrentVtkView()->Repaint();
548 aCellLocationsArray->Delete();
549 aCellTypesArray->Delete();