1 // Copyright (C) 2007-2010 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
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File : SMESHGUI_DuplicateNodesDlg.cxx
25 // Author : Michael ZORIN, Open CASCADE S.A.S.
28 #include "SMESHGUI_DuplicateNodesDlg.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
34 #include <SMESH_TypeFilter.hxx>
36 // SALOME GUI includes
37 #include <SUIT_Session.h>
38 #include <SUIT_ResourceMgr.h>
39 #include <SUIT_Desktop.h>
40 #include <SUIT_MessageBox.h>
41 #include <SUIT_OverrideCursor.h>
43 #include <LightApp_Application.h>
44 #include <LightApp_SelectionMgr.h>
46 #include <SalomeApp_Tools.h>
48 #include <SVTK_ViewWindow.h>
49 #include <SALOME_ListIO.hxx>
52 #include <QApplication>
53 #include <QButtonGroup>
57 #include <QPushButton>
58 #include <QRadioButton>
60 #include <QHBoxLayout>
61 #include <QVBoxLayout>
64 #include <utilities.h>
67 #include <SALOMEconfig.h>
68 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
76 \param theModule Mesh module instance
78 SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
79 : QDialog( SMESH::GetDesktop( theModule ) ),
80 mySMESHGUI( theModule ),
81 mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
85 setAttribute(Qt::WA_DeleteOnClose, true);
86 setWindowTitle(tr("SMESH_DUPLICATE_TITLE"));
87 setSizeGripEnabled(true);
89 // Icons for the dialog operation modes and selection button
90 SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
91 QPixmap iconWithoutElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES")));
92 QPixmap iconWithElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES_WITH_ELEM")));
93 QPixmap iconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
96 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
97 aMainLayout->setSpacing(SPACING);
98 aMainLayout->setMargin(MARGIN);
100 // Operation modes selector
101 QGroupBox* aConstructorsBox = new QGroupBox(tr("DUPLICATION_MODE"), this);
102 myGroupConstructors = new QButtonGroup(this);
103 QHBoxLayout* aConstructorsBoxLayout = new QHBoxLayout(aConstructorsBox);
104 aConstructorsBoxLayout->setSpacing(SPACING);
105 aConstructorsBoxLayout->setMargin(MARGIN);
107 QRadioButton* aRadioButton1 = new QRadioButton(aConstructorsBox);
108 aRadioButton1->setIcon(iconWithoutElem);
109 QRadioButton* aRadioButton2 = new QRadioButton(aConstructorsBox);
110 aRadioButton2->setIcon(iconWithElem);
112 aConstructorsBoxLayout->addWidget(aRadioButton1);
113 aConstructorsBoxLayout->addWidget(aRadioButton2);
114 myGroupConstructors->addButton(aRadioButton1, 0);
115 myGroupConstructors->addButton(aRadioButton2, 1);
118 myGroupArguments = new QGroupBox(this);
119 QGridLayout* aGroupArgumentsLayout = new QGridLayout(myGroupArguments);
120 aGroupArgumentsLayout->setSpacing(SPACING);
121 aGroupArgumentsLayout->setMargin(MARGIN);
123 myTextLabel1 = new QLabel(myGroupArguments);
124 mySelectButton1 = new QPushButton(myGroupArguments);
125 mySelectButton1->setIcon(iconSelect);
126 myLineEdit1 = new QLineEdit(myGroupArguments);
127 myLineEdit1->setReadOnly(true);
129 myTextLabel2 = new QLabel(myGroupArguments);
130 mySelectButton2 = new QPushButton(myGroupArguments);
131 mySelectButton2->setIcon(iconSelect);
132 myLineEdit2 = new QLineEdit(myGroupArguments);
133 myLineEdit2->setReadOnly(true);
135 myTextLabel3 = new QLabel(myGroupArguments);
136 mySelectButton3 = new QPushButton(myGroupArguments);
137 mySelectButton3->setIcon(iconSelect);
138 myLineEdit3 = new QLineEdit(myGroupArguments);
139 myLineEdit3->setReadOnly(true);
141 myCheckBoxNewGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments);
143 aGroupArgumentsLayout->addWidget(myTextLabel1, 0, 0);
144 aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1);
145 aGroupArgumentsLayout->addWidget(myLineEdit1, 0, 2);
146 aGroupArgumentsLayout->addWidget(myTextLabel2, 1, 0);
147 aGroupArgumentsLayout->addWidget(mySelectButton2, 1, 1);
148 aGroupArgumentsLayout->addWidget(myLineEdit2, 1, 2);
149 aGroupArgumentsLayout->addWidget(myTextLabel3, 2, 0);
150 aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1);
151 aGroupArgumentsLayout->addWidget(myLineEdit3, 2, 2);
152 aGroupArgumentsLayout->addWidget(myCheckBoxNewGroup, 3, 0);
153 aGroupArgumentsLayout->setRowStretch(4, 1);
156 QGroupBox* aGroupButtons = new QGroupBox(this);
157 QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(aGroupButtons);
158 aGroupButtonsLayout->setSpacing(SPACING);
159 aGroupButtonsLayout->setMargin(MARGIN);
161 myButtonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGroupButtons);
162 myButtonOk->setAutoDefault(true);
163 myButtonOk->setDefault(true);
164 myButtonApply = new QPushButton(tr("SMESH_BUT_APPLY"), aGroupButtons);
165 myButtonApply->setAutoDefault(true);
166 myButtonClose = new QPushButton(tr("SMESH_BUT_CLOSE"), aGroupButtons);
167 myButtonClose->setAutoDefault(true);
168 myButtonHelp = new QPushButton(tr("SMESH_BUT_HELP"), aGroupButtons);
169 myButtonHelp->setAutoDefault(true);
171 aGroupButtonsLayout->addWidget(myButtonOk);
172 aGroupButtonsLayout->addSpacing(10);
173 aGroupButtonsLayout->addWidget(myButtonApply);
174 aGroupButtonsLayout->addSpacing(10);
175 aGroupButtonsLayout->addStretch();
176 aGroupButtonsLayout->addWidget(myButtonClose);
177 aGroupButtonsLayout->addWidget(myButtonHelp);
179 // Add mode selector, arguments and buttons to the main layout
180 aMainLayout->addWidget(aConstructorsBox);
181 aMainLayout->addWidget(myGroupArguments);
182 aMainLayout->addWidget(aGroupButtons);
184 // Initialize the dialog
188 myHelpFileName = "double_nodes_page.html";
190 // Signals and slots connections
191 connect(myGroupConstructors, SIGNAL(buttonClicked(int)), SLOT(onConstructorsClicked(int)));
193 connect(mySelectButton1, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
194 connect(mySelectButton2, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
195 connect(mySelectButton3, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
197 connect(myButtonOk, SIGNAL(clicked()), this, SLOT(onOk()));
198 connect(myButtonClose, SIGNAL(clicked()), this, SLOT(onClose()));
199 connect(myButtonApply, SIGNAL(clicked()), this, SLOT(onApply()));
200 connect(myButtonHelp, SIGNAL(clicked()), this, SLOT(onHelp()));
202 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionChanged()));
204 connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
205 connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(onClose()));
211 SMESHGUI_DuplicateNodesDlg::~SMESHGUI_DuplicateNodesDlg()
218 void SMESHGUI_DuplicateNodesDlg::Init()
220 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
222 // Set initial parameters
224 myCurrentLineEdit = myLineEdit1;
226 myGroup1 = SMESH::SMESH_GroupBase::_nil();
227 myGroup2 = SMESH::SMESH_GroupBase::_nil();
228 myGroup3 = SMESH::SMESH_GroupBase::_nil();
230 // Set selection mode
231 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
232 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
233 aViewWindow->SetSelectionMode(ActorSelection);
235 // Set construction mode
236 int operationMode = myGroupConstructors->checkedId();
237 if (operationMode < 0) {
238 // The dialog has been just displayed
240 myGroupConstructors->button(0)->setChecked(true);
242 onConstructorsClicked(operationMode);
246 \brief SLOT called to change the dialog operation mode.
247 \param constructorId id of the radio button in mode selector button group
249 void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
252 myLineEdit1->clear();
253 myLineEdit2->clear();
254 myLineEdit3->clear();
256 // Checkbox should be checked by default
257 myCheckBoxNewGroup->setChecked(true);
259 // Set the first field as current
260 myCurrentLineEdit = myLineEdit1;
261 myCurrentLineEdit->setFocus();
263 switch (constructorId) {
266 // Set text to the group of arguments and to the first two labels
267 myGroupArguments->setTitle(tr("DUPLICATION_WITHOUT_ELEMS"));
268 myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE"));
269 myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE"));
271 // Set checkbox title
272 myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_NODES"));
274 // Hide the third field
275 myTextLabel3->hide();
276 mySelectButton3->hide();
283 // Set text to the group of arguments and to all the labels
284 myGroupArguments->setTitle(tr("DUPLICATION_WITH_ELEMS"));
285 myTextLabel1->setText(tr("GROUP_ELEMS_TO_DUPLICATE"));
286 myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE"));
287 myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE"));
289 // Set checkbox title
290 myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"));
292 // Show the third field
293 myTextLabel3->show();
294 mySelectButton3->show();
302 onSelectionChanged();
306 \brief SLOT called to apply changes.
308 bool SMESHGUI_DuplicateNodesDlg::onApply()
310 if (mySMESHGUI->isActiveStudyLocked() || !isValid())
315 bool toCreateGroup = myCheckBoxNewGroup->isChecked();
316 int operationMode = myGroupConstructors->checkedId();
320 SUIT_OverrideCursor aWaitCursor;
323 SMESH::SMESH_Mesh_ptr aMesh = myGroup1->GetMesh();
324 SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
326 if (operationMode == 0) {
328 SMESH::SMESH_GroupBase_ptr aNewGroup =
329 aMeshEditor->DoubleNodeGroupNew(myGroup1, myGroup2);
330 if (!CORBA::is_nil(aNewGroup))
334 result = aMeshEditor->DoubleNodeGroup(myGroup1, myGroup2);
338 SMESH::SMESH_GroupBase_ptr aNewGroup =
339 aMeshEditor->DoubleNodeElemGroupNew(myGroup1, myGroup2, myGroup3);
340 if (!CORBA::is_nil(aNewGroup))
344 result = aMeshEditor->DoubleNodeElemGroup(myGroup1, myGroup2, myGroup3);
347 catch (const SALOME::SALOME_Exception& S_ex) {
348 SalomeApp_Tools::QtCatchCorbaException(S_ex);
350 catch ( const std::exception& exc ) {
351 INFOS( "Follow exception was cought:\n\t" << exc.what() );
354 INFOS( "Unknown exception was cought !!!" );
358 SUIT_MessageBox::warning(this,
359 tr("SMESH_WRN_WARNING"),
360 tr("SMESH_OPERATION_FAILED"));
366 mySelectionMgr->clearSelected();
368 SMESHGUI::Modified();
369 mySMESHGUI->updateObjBrowser(true);
371 // Reinitialize the dialog
378 \brief SLOT called to apply changes and close the dialog.
380 void SMESHGUI_DuplicateNodesDlg::onOk()
387 \brief SLOT called to close the dialog.
389 void SMESHGUI_DuplicateNodesDlg::onClose()
391 disconnect(mySelectionMgr, 0, this, 0);
392 disconnect(mySMESHGUI, 0, this, 0);
393 mySMESHGUI->ResetState();
394 mySelectionMgr->clearFilters();
399 \brief SLOT called when selection changed.
401 void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
403 if (myBusy || !isEnabled()) return;
405 // Try to get selected group
407 mySelectionMgr->selectedObjects( aList );
408 int aNbSel = aList.Extent();
410 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_nil();
412 Handle(SALOME_InteractiveObject) IO = aList.First();
413 aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
416 if (!CORBA::is_nil(aGroup)) {
417 int operationMode = myGroupConstructors->checkedId();
418 SMESH::ElementType aGroupType = aGroup->GetType();
419 bool isTypeValid = true;
421 if (operationMode == 0) {
422 if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::NODE) ||
423 (myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE) )
426 else if (operationMode == 1) {
427 if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::EDGE &&
428 aGroupType != SMESH::FACE) ||
429 (myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE) ||
430 (myCurrentLineEdit == myLineEdit3 && aGroupType == SMESH::NODE) )
435 aGroup = SMESH::SMESH_GroupBase::_nil();
439 // Clear current field
440 myCurrentLineEdit->clear();
442 // Set corresponding SMESH group
443 if (myCurrentLineEdit == myLineEdit1) {
444 myGroup1 = SMESH::SMESH_Group::_narrow(aGroup);
446 else if (myCurrentLineEdit == myLineEdit2) {
447 myGroup2 = SMESH::SMESH_Group::_narrow(aGroup);
449 else if (myCurrentLineEdit == myLineEdit3) {
450 myGroup3 = SMESH::SMESH_Group::_narrow(aGroup);
454 if (!CORBA::is_nil(aGroup))
455 myCurrentLineEdit->setText(aGroup->GetName());
457 // Enable/disable "Apply and Close" and "Apply" buttons
458 bool isDataValid = isValid();
459 myButtonOk->setEnabled(isDataValid);
460 myButtonApply->setEnabled(isDataValid);
464 \brief SLOT called when selection button clicked.
466 void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument()
468 QPushButton* send = (QPushButton*)sender();
470 // Set current field for edition
471 if (send == mySelectButton1) {
472 myCurrentLineEdit = myLineEdit1;
474 else if (send == mySelectButton2) {
475 myCurrentLineEdit = myLineEdit2;
477 else if (send == mySelectButton3) {
478 myCurrentLineEdit = myLineEdit3;
481 myCurrentLineEdit->setFocus();
482 onSelectionChanged();
486 \brief Check if the input data is valid.
487 \return \c true id the data is valid
489 bool SMESHGUI_DuplicateNodesDlg::isValid()
491 // Only first group (nodes/elemets to duplicate) is mandatory
492 bool isValid = !CORBA::is_nil(myGroup1);
494 // First (elements to duplicate) and last groups should be defined in the second operation mode
495 if (isValid && myGroupConstructors->checkedId() == 1)
496 isValid = !CORBA::is_nil(myGroup3);
503 \brief SLOT called when dialog shoud be deativated.
505 void SMESHGUI_DuplicateNodesDlg::onDeactivate()
508 mySelectionMgr->clearFilters();
510 mySMESHGUI->ResetState();
511 mySMESHGUI->SetActiveDialogBox(0);
516 \brief Receive dialog enter events.
517 Activates the dialog when the mouse cursor enters.
518 Reimplemented from QWidget class.
520 void SMESHGUI_DuplicateNodesDlg::enterEvent (QEvent*)
522 if ( !isEnabled() ) {
523 mySMESHGUI->EmitSignalDeactivateDialog();
525 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
527 // Set selection mode
528 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
529 aViewWindow->SetSelectionMode(ActorSelection);
530 mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
535 \brief Receive close events.
536 Reimplemented from QWidget class.
538 void SMESHGUI_DuplicateNodesDlg::closeEvent (QCloseEvent*)
544 \brief Receive key press events.
545 Reimplemented from QWidget class.
547 void SMESHGUI_DuplicateNodesDlg::keyPressEvent( QKeyEvent* e )
549 QDialog::keyPressEvent( e );
550 if ( e->isAccepted() )
553 if ( e->key() == Qt::Key_F1 ) {
560 \brief Show the dialog help page.
562 void SMESHGUI_DuplicateNodesDlg::onHelp()
564 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
566 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
570 platform = "winapplication";
572 platform = "application";
574 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
575 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
576 arg(app->resourceMgr()->stringValue("ExternalBrowser",
578 arg(myHelpFileName));