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.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESHGUI_MoveNodesDlg.cxx
23 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
27 #include "SMESHGUI_MoveNodesDlg.h"
30 #include "SMESHGUI_SpinBox.h"
31 #include "SMESHGUI_IdValidator.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_VTKUtils.h"
34 #include "SMESHGUI_MeshUtils.h"
36 #include <SMESH_Actor.h>
37 #include <SMDS_Mesh.hxx>
39 // SALOME GUI includes
40 #include <LightApp_SelectionMgr.h>
41 #include <LightApp_Application.h>
42 #include <SUIT_ResourceMgr.h>
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
47 #include <SVTK_ViewModel.h>
48 #include <SVTK_ViewWindow.h>
49 #include <SALOME_ListIO.hxx>
51 #include <VTKViewer_CellLocationsArray.h>
54 #include <TColStd_MapOfInteger.hxx>
57 #include <vtkIdList.h>
58 #include <vtkCellArray.h>
59 #include <vtkUnsignedCharArray.h>
60 #include <vtkUnstructuredGrid.h>
61 #include <vtkDataSetMapper.h>
62 #include <vtkProperty.h>
68 #include <QPushButton>
69 #include <QRadioButton>
70 #include <QHBoxLayout>
71 #include <QVBoxLayout>
75 #include <SALOMEconfig.h>
76 #include CORBA_SERVER_HEADER(SMESH_Mesh)
77 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
82 //=================================================================================
83 // name : SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg
85 //=================================================================================
86 SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg(SMESHGUI* theModule):
87 QDialog(SMESH::GetDesktop(theModule)),
88 mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
95 setWindowTitle(tr("CAPTION"));
97 QVBoxLayout* aDlgLay = new QVBoxLayout(this);
98 aDlgLay->setSpacing(SPACING);
99 aDlgLay->setMargin(MARGIN);
101 QWidget* aMainFrame = createMainFrame (this);
102 QWidget* aBtnFrame = createButtonFrame(this);
104 aDlgLay->addWidget(aMainFrame);
105 aDlgLay->addWidget(aBtnFrame);
107 mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
109 myHelpFileName = "moving_nodes_page.html";
114 //=======================================================================
115 // name : SMESHGUI_MoveNodesDlg::createButtonFrame
116 // Purpose : Create frame containing buttons
117 //=======================================================================
118 QWidget* SMESHGUI_MoveNodesDlg::createButtonFrame (QWidget* theParent)
120 QFrame* aFrame = new QFrame(theParent);
121 aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
123 myOkBtn = new QPushButton(tr("SMESH_BUT_OK" ), aFrame);
124 myApplyBtn = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame);
125 myCloseBtn = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame);
126 myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), aFrame);
128 QHBoxLayout* aLay = new QHBoxLayout(aFrame);
129 aLay->setSpacing(SPACING);
130 aLay->setMargin(MARGIN);
132 aLay->addWidget(myOkBtn);
133 aLay->addSpacing(10);
134 aLay->addWidget(myApplyBtn);
135 aLay->addSpacing(10);
137 aLay->addWidget(myCloseBtn);
138 aLay->addWidget(myHelpBtn);
140 connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
141 connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
142 connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
143 connect(myHelpBtn, SIGNAL(clicked()), SLOT(onHelp()));
148 //=======================================================================
149 // name : SMESHGUI_MoveNodesDlg::createMainFrame
150 // Purpose : Create frame containing dialog's input fields
151 //=======================================================================
152 QWidget* SMESHGUI_MoveNodesDlg::createMainFrame (QWidget* theParent)
154 QWidget* aFrame = new QWidget(theParent);
156 QPixmap iconMoveNode (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MOVE_NODE")));
157 QPixmap iconSelect (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
159 //------------------------------------------------------------
160 QGroupBox* aPixGrp = new QGroupBox(tr("MESH_NODE"), aFrame);
161 QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
162 aPixGrpLayout->setSpacing(SPACING);
163 aPixGrpLayout->setMargin(MARGIN);
165 QRadioButton* aRBut = new QRadioButton(aPixGrp);
166 aRBut->setIcon(iconMoveNode);
167 aRBut->setChecked(true);
169 aPixGrpLayout->addWidget(aRBut);
170 aPixGrpLayout->addStretch();
172 //------------------------------------------------------------
173 QGroupBox* anIdGrp = new QGroupBox(tr("SMESH_MOVE"), aFrame);
174 QHBoxLayout* anIdGrpLayout = new QHBoxLayout(anIdGrp);
175 anIdGrpLayout->setSpacing(SPACING);
176 anIdGrpLayout->setMargin(MARGIN);
178 QLabel* idLabl = new QLabel(tr("NODE_ID"), anIdGrp);
179 QPushButton* idBtn = new QPushButton(anIdGrp);
180 idBtn->setIcon(iconSelect);
181 myId = new QLineEdit(anIdGrp);
182 myId->setValidator(new SMESHGUI_IdValidator(this, 1));
184 anIdGrpLayout->addWidget(idLabl);
185 anIdGrpLayout->addWidget(idBtn);
186 anIdGrpLayout->addWidget(myId);
188 //------------------------------------------------------------
189 QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame);
190 QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp);
191 aCoordGrpLayout->setSpacing(SPACING);
192 aCoordGrpLayout->setMargin(MARGIN);
194 QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
195 myX = new SMESHGUI_SpinBox(aCoordGrp);
197 QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
198 myY = new SMESHGUI_SpinBox(aCoordGrp);
200 QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
201 myZ = new SMESHGUI_SpinBox(aCoordGrp);
203 aCoordGrpLayout->addWidget(aXLabel);
204 aCoordGrpLayout->addWidget(myX);
205 aCoordGrpLayout->addWidget(aYLabel);
206 aCoordGrpLayout->addWidget(myY);
207 aCoordGrpLayout->addWidget(aZLabel);
208 aCoordGrpLayout->addWidget(myZ);
210 //------------------------------------------------------------
211 myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY);
212 myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY);
213 myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY);
215 //------------------------------------------------------------
216 QVBoxLayout* aLay = new QVBoxLayout(aFrame);
218 aLay->setMargin(SPACING);
219 aLay->addWidget(aPixGrp);
220 aLay->addWidget(anIdGrp);
221 aLay->addWidget(aCoordGrp);
223 //------------------------------------------------------------
224 // connect signale and slots
225 connect(myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
226 connect(myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
227 connect(myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
228 connect(myId, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
233 //=======================================================================
234 // name : SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg
236 //=======================================================================
237 SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg()
242 //=======================================================================
243 // name : SMESHGUI_MoveNodesDlg::Init
244 // Purpose : Init dialog fields
245 //=======================================================================
246 void SMESHGUI_MoveNodesDlg::Init()
252 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
254 // selection and SMESHGUI
255 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
256 connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
257 connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
262 // set selection mode
263 SMESH::SetPointRepresentation(true);
264 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
265 aViewWindow->SetSelectionMode(NodeSelection);
270 //=======================================================================
271 // name : SMESHGUI_MoveNodesDlg::isValid
272 // Purpose : Verify validity of entry information
273 //=======================================================================
274 bool SMESHGUI_MoveNodesDlg::isValid (const bool theMess)
276 if (myId->text().isEmpty()) {
278 SUIT_MessageBox::information(this, tr("SMESH_WARNING"),
279 tr("NODE_ID_IS_NOT_DEFINED"));
285 //=======================================================================
286 // name : SMESHGUI_MoveNodesDlg::reset
287 // Purpose : Reset the dialog state
288 //=======================================================================
289 void SMESHGUI_MoveNodesDlg::reset()
299 //=======================================================================
300 // name : SMESHGUI_MoveNodesDlg::onApply
301 // Purpose : SLOT called when "Apply" button pressed.
302 //=======================================================================
303 bool SMESHGUI_MoveNodesDlg::onApply()
305 if (mySMESHGUI->isActiveStudyLocked())
311 SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
312 if (aMesh->_is_nil()) {
313 SUIT_MessageBox::information(this, tr("SMESH_ERROR"),
314 tr("SMESHG_NO_MESH"));
318 SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
319 if (aMeshEditor->_is_nil())
322 int anId = myId->text().toInt();
323 bool aResult = false;
325 aResult = aMeshEditor->MoveNode(anId, myX->GetValue(), myY->GetValue(), myZ->GetValue());
331 aList.Append(myMeshActor->getIO());
332 mySelectionMgr->setSelectedObjects(aList,false);
340 //=======================================================================
341 // name : SMESHGUI_MoveNodesDlg::onOk
342 // Purpose : SLOT called when "Ok" button pressed.
343 //=======================================================================
344 void SMESHGUI_MoveNodesDlg::onOk()
350 //=======================================================================
351 // name : SMESHGUI_MoveNodesDlg::onClose
352 // Purpose : SLOT called when "Close" button pressed. Close dialog
353 //=======================================================================
354 void SMESHGUI_MoveNodesDlg::onClose()
356 //mySelectionMgr->clearSelected();
357 SMESH::SetPointRepresentation(false);
358 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
359 aViewWindow->SetSelectionMode(ActorSelection);
360 disconnect(mySelectionMgr, 0, this, 0);
361 disconnect(mySMESHGUI, 0, this, 0);
363 mySMESHGUI->ResetState();
367 //=================================================================================
368 // function : onHelp()
370 //=================================================================================
371 void SMESHGUI_MoveNodesDlg::onHelp()
373 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
375 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
379 platform = "winapplication";
381 platform = "application";
383 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
384 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
385 arg(app->resourceMgr()->stringValue("ExternalBrowser",
387 arg(myHelpFileName));
391 //=======================================================================
392 // name : SMESHGUI_MoveNodesDlg::onTextChange
394 //=======================================================================
395 void SMESHGUI_MoveNodesDlg::onTextChange (const QString& theNewText)
399 myOkBtn->setEnabled(false);
400 myApplyBtn->setEnabled(false);
403 // select entered node
405 if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()){
407 Handle(SALOME_InteractiveObject) anIO = myMeshActor->getIO();
410 mySelectionMgr->setSelectedObjects(aList,false);
413 if(const SMDS_MeshElement *anElem = aMesh->FindElement(theNewText.toInt())) {
414 TColStd_MapOfInteger aListInd;
415 aListInd.Add(anElem->GetID());
416 mySelector->AddOrRemoveIndex(anIO,aListInd, false);
417 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
418 aViewWindow->highlight(anIO,true,true);
426 //=======================================================================
427 // name : SMESHGUI_MoveNodesDlg::onSelectionDone
428 // Purpose : SLOT called when selection changed
429 //=======================================================================
430 void SMESHGUI_MoveNodesDlg::onSelectionDone()
436 mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
438 if (aList.Extent() == 1) {
439 Handle(SALOME_InteractiveObject) anIO = aList.First();
440 myMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
443 if (SMESH::GetNameOfSelectedNodes(mySelector,anIO,aText) == 1) {
444 if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()) {
445 if(const SMDS_MeshNode* aNode = aMesh->FindNode(aText.toInt())) {
447 myId->setText(aText);
448 myX->SetValue(aNode->X());
449 myY->SetValue(aNode->Y());
450 myZ->SetValue(aNode->Z());
452 erasePreview(); // avoid overlapping of a selection and a preview
464 //=======================================================================
465 // name : SMESHGUI_MoveNodesDlg::onDeactivate
466 // Purpose : SLOT called when dialog must be deativated
467 //=======================================================================
468 void SMESHGUI_MoveNodesDlg::onDeactivate()
474 //=======================================================================
475 // name : SMESHGUI_MoveNodesDlg::enterEvent
476 // Purpose : Event filter
477 //=======================================================================
478 void SMESHGUI_MoveNodesDlg::enterEvent (QEvent*)
481 mySMESHGUI->EmitSignalDeactivateDialog();
483 // set selection mode
484 SMESH::SetPointRepresentation(true);
485 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
486 aViewWindow->SetSelectionMode(NodeSelection);
494 //=======================================================================
495 // name : SMESHGUI_MoveNodesDlg::closeEvent
497 //=======================================================================
498 void SMESHGUI_MoveNodesDlg::closeEvent (QCloseEvent*)
501 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
502 aViewWindow->Repaint();
505 //=======================================================================
506 // name : SMESHGUI_MoveNodesDlg::hideEvent
507 // Purpose : may be caused by ESC key
508 //=======================================================================
509 void SMESHGUI_MoveNodesDlg::hideEvent (QHideEvent*)
515 //=======================================================================
516 // name : SMESHGUI_MoveNodesDlg::updateButtons
517 // Purpose : Update buttons state
518 //=======================================================================
519 void SMESHGUI_MoveNodesDlg::updateButtons()
521 bool isEnabled = isValid(false);
522 myOkBtn->setEnabled(isEnabled);
523 myApplyBtn->setEnabled(isEnabled);
526 //=======================================================================
527 // name : SMESHGUI_MoveNodesDlg::erasePreview
528 // Purpose : Erase preview
529 //=======================================================================
530 void SMESHGUI_MoveNodesDlg::erasePreview()
532 if (myPreviewActor == 0)
535 SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
537 aViewWindow->RemoveActor(myPreviewActor);
538 myPreviewActor->Delete();
541 aViewWindow->Repaint();
544 //=======================================================================
545 // name : SMESHGUI_MoveNodesDlg::redisplayPreview
546 // Purpose : Redisplay preview
547 //=======================================================================
548 void SMESHGUI_MoveNodesDlg::redisplayPreview()
553 if (myPreviewActor != 0)
559 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
561 vtkPoints* aPoints = vtkPoints::New();
562 aPoints->SetNumberOfPoints(1);
563 aPoints->SetPoint(0, myX->GetValue(), myY->GetValue(), myZ->GetValue());
567 vtkIdList *anIdList = vtkIdList::New();
568 anIdList->SetNumberOfIds(1);
570 vtkCellArray *aCells = vtkCellArray::New();
571 aCells->Allocate(2, 0);
573 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
574 aCellTypesArray->SetNumberOfComponents(1);
575 aCellTypesArray->Allocate(1);
577 anIdList->SetId(0, 0);
578 aCells->InsertNextCell(anIdList);
579 aCellTypesArray->InsertNextValue(VTK_VERTEX);
582 VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
583 aCellLocationsArray->SetNumberOfComponents(1);
584 aCellLocationsArray->SetNumberOfTuples(1);
586 aCells->InitTraversal();
588 aCellLocationsArray->SetValue(0, aCells->GetTraversalLocation(npts));
590 aGrid->SetPoints(aPoints);
593 aGrid->SetCells(aCellTypesArray,aCellLocationsArray,aCells);
594 aCellLocationsArray->Delete();
595 aCellTypesArray->Delete();
598 // Create and display actor
599 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
600 aMapper->SetInput(aGrid);
603 myPreviewActor = SALOME_Actor::New();
604 myPreviewActor->PickableOff();
605 myPreviewActor->SetMapper(aMapper);
608 vtkProperty* aProp = vtkProperty::New();
609 aProp->SetRepresentationToWireframe();
610 aProp->SetColor(250, 0, 250);
611 aProp->SetPointSize(5);
612 myPreviewActor->SetProperty(aProp);
615 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
617 aViewWindow->AddActor(myPreviewActor);
618 aViewWindow->Repaint();
622 //=================================================================================
623 // function : keyPressEvent()
625 //=================================================================================
626 void SMESHGUI_MoveNodesDlg::keyPressEvent( QKeyEvent* e )
628 QDialog::keyPressEvent( e );
629 if ( e->isAccepted() )
632 if ( e->key() == Qt::Key_F1 ) {