Salome HOME
2f2a5e3f934fc76648e66c8a6ec8ebb35a8fdf16
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_RemoveNodesDlg.cxx
1 // SMESH SMESHGUI : GUI for SMESH component
2 //
3 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 //
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. 
10 //
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. 
15 //
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 
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File   : SMESHGUI_RemoveNodesDlg.cxx
23 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
24 //
25
26 // SMESH includes
27 #include "SMESHGUI_RemoveNodesDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32 #include "SMESHGUI_MeshUtils.h"
33 #include "SMESHGUI_IdValidator.h"
34
35 #include <SMESH_Actor.h>
36 #include <SMDS_Mesh.hxx>
37
38 // SALOME GUI includes
39 #include <SUIT_ResourceMgr.h>
40 #include <SUIT_Desktop.h>
41 #include <SUIT_Session.h>
42 #include <SUIT_MessageBox.h>
43
44 #include <LightApp_Application.h>
45 #include <LightApp_SelectionMgr.h>
46 #include <SalomeApp_Tools.h>
47
48 #include <SVTK_Selector.h>
49 #include <SVTK_ViewModel.h>
50 #include <SVTK_ViewWindow.h>
51 #include <SALOME_ListIO.hxx>
52
53 // OCCT includes
54 #include <TColStd_MapOfInteger.hxx>
55
56 // Qt includes
57 #include <QGroupBox>
58 #include <QLabel>
59 #include <QLineEdit>
60 #include <QPushButton>
61 #include <QRadioButton>
62 #include <QVBoxLayout>
63 #include <QHBoxLayout>
64 #include <QKeyEvent>
65 #include <QButtonGroup>
66
67 // IDL includes
68 #include <SALOMEconfig.h>
69 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
70
71 #define SPACING 6
72 #define MARGIN  11
73
74 //=================================================================================
75 // class    : SMESHGUI_RemoveNodesDlg()
76 // purpose  :
77 //=================================================================================
78 SMESHGUI_RemoveNodesDlg
79 ::SMESHGUI_RemoveNodesDlg(SMESHGUI* theModule)
80   : QDialog(SMESH::GetDesktop(theModule)),
81     mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
82     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
83     mySMESHGUI(theModule),
84     myBusy(false)
85 {
86   setModal( false );
87   setAttribute( Qt::WA_DeleteOnClose, true );
88   setWindowTitle(tr("SMESH_REMOVE_NODES_TITLE"));
89   setSizeGripEnabled(true);
90   
91   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_REM_NODE")));
92   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
93
94   QVBoxLayout* SMESHGUI_RemoveNodesDlgLayout = new QVBoxLayout(this);
95   SMESHGUI_RemoveNodesDlgLayout->setSpacing(SPACING);
96   SMESHGUI_RemoveNodesDlgLayout->setMargin(MARGIN);
97
98   /***************************************************************/
99   GroupConstructors = new QGroupBox(tr("SMESH_NODES"), this);
100   QButtonGroup* ButtonGroup = new QButtonGroup(this);
101   QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
102   GroupConstructorsLayout->setSpacing(SPACING);
103   GroupConstructorsLayout->setMargin(MARGIN);
104
105   Constructor1 = new QRadioButton(GroupConstructors);
106   Constructor1->setIcon(image0);
107   Constructor1->setChecked(true);
108
109   GroupConstructorsLayout->addWidget(Constructor1);
110   ButtonGroup->addButton(Constructor1, 0);
111
112   /***************************************************************/
113   GroupC1 = new QGroupBox(tr("SMESH_REMOVE"), this);
114   QHBoxLayout* GroupC1Layout = new QHBoxLayout(GroupC1);
115   GroupC1Layout->setSpacing(SPACING);
116   GroupC1Layout->setMargin(MARGIN);
117
118   TextLabelC1A1 = new QLabel(tr("SMESH_ID_NODES"), GroupC1);
119   SelectButtonC1A1 = new QPushButton(GroupC1);
120   SelectButtonC1A1->setIcon(image1);
121   LineEditC1A1 = new QLineEdit(GroupC1);
122   LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
123
124   GroupC1Layout->addWidget(TextLabelC1A1);
125   GroupC1Layout->addWidget(SelectButtonC1A1);
126   GroupC1Layout->addWidget(LineEditC1A1);
127
128   /***************************************************************/
129   GroupButtons = new QGroupBox(this);
130   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
131   GroupButtonsLayout->setSpacing(SPACING);
132   GroupButtonsLayout->setMargin(MARGIN);
133
134   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
135   buttonOk->setAutoDefault(true);
136   buttonOk->setDefault(true);
137   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
138   buttonApply->setAutoDefault(true);
139   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
140   buttonCancel->setAutoDefault(true);
141   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
142   buttonHelp->setAutoDefault(true);
143
144   GroupButtonsLayout->addWidget(buttonOk);
145   GroupButtonsLayout->addSpacing(10);
146   GroupButtonsLayout->addWidget(buttonApply);
147   GroupButtonsLayout->addSpacing(10);
148   GroupButtonsLayout->addStretch();
149   GroupButtonsLayout->addWidget(buttonCancel);
150   GroupButtonsLayout->addWidget(buttonHelp);
151
152   /***************************************************************/
153   SMESHGUI_RemoveNodesDlgLayout->addWidget(GroupConstructors);
154   SMESHGUI_RemoveNodesDlgLayout->addWidget(GroupC1);
155   SMESHGUI_RemoveNodesDlgLayout->addWidget(GroupButtons);
156
157   myHelpFileName = "removing_nodes_and_elements_page.html#removing_nodes_anchor";
158
159   Init(); /* Initialisations */
160 }
161
162 //=================================================================================
163 // function : ~SMESHGUI_RemoveNodesDlg()
164 // purpose  : Destroys the object and frees any allocated resources
165 //=================================================================================
166 SMESHGUI_RemoveNodesDlg::~SMESHGUI_RemoveNodesDlg()
167 {
168 }
169
170 //=================================================================================
171 // function : Init()
172 // purpose  :
173 //=================================================================================
174 void SMESHGUI_RemoveNodesDlg::Init()
175 {
176   myConstructorId = 0;
177   Constructor1->setChecked(true);
178   myEditCurrentArgument = LineEditC1A1;
179
180   myNbOkNodes = 0;
181   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
182   myActor = 0;
183   myBusy = false;
184
185   /* signals and slots connections */
186   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
187   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
188   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
189   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
190
191   connect(SelectButtonC1A1, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
192   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
193   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
194   /* to close dialog if study change */
195   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
196   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
197           SLOT(onTextChange(const QString&)));
198   
199   SMESH::SetPointRepresentation(true);
200   
201   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
202     aViewWindow->SetSelectionMode(NodeSelection);
203
204   SelectionIntoArgument();
205 }
206
207 //=================================================================================
208 // function : ClickOnApply()
209 // purpose  :
210 //=================================================================================
211 void SMESHGUI_RemoveNodesDlg::ClickOnApply()
212 {
213   if (mySMESHGUI->isActiveStudyLocked())
214     return;
215
216   if (myNbOkNodes) {
217     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
218     SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
219     anArrayOfIdeces->length(aListId.count());
220     for (int i = 0; i < aListId.count(); i++)
221       anArrayOfIdeces[i] = aListId[ i ].toInt();
222
223     bool aResult = false;
224     try {
225       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
226       aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.inout());
227     } catch (const SALOME::SALOME_Exception& S_ex) {
228       SalomeApp_Tools::QtCatchCorbaException(S_ex);
229       myEditCurrentArgument->clear();
230     } catch (...){
231       myEditCurrentArgument->clear();
232     }
233
234     if (aResult) {
235       myEditCurrentArgument->clear();
236       mySelector->ClearIndex();
237       SMESH::UpdateView();
238     }
239
240     SMESH::SetPointRepresentation(true);
241   }
242 }
243
244 //=================================================================================
245 // function : ClickOnOk()
246 // purpose  :
247 //=================================================================================
248 void SMESHGUI_RemoveNodesDlg::ClickOnOk()
249 {
250   ClickOnApply();
251   ClickOnCancel();
252 }
253
254 //=================================================================================
255 // function : ClickOnCancel()
256 // purpose  :
257 //=================================================================================
258 void SMESHGUI_RemoveNodesDlg::ClickOnCancel()
259 {
260   //mySelectionMgr->clearSelected();
261   SMESH::SetPointRepresentation(false);
262   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
263     aViewWindow->SetSelectionMode(ActorSelection);
264   disconnect(mySelectionMgr, 0, this, 0);
265   mySMESHGUI->ResetState();
266   reject();
267 }
268
269 //=================================================================================
270 // function : ClickOnHelp()
271 // purpose  :
272 //=================================================================================
273 void SMESHGUI_RemoveNodesDlg::ClickOnHelp()
274 {
275   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
276   if (app) 
277     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
278   else {
279     QString platform;
280 #ifdef WIN32
281     platform = "winapplication";
282 #else
283     platform = "application";
284 #endif
285     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
286                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
287                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
288                                                                  platform)).
289                              arg(myHelpFileName));
290   }
291 }
292
293 //=======================================================================
294 //function : onTextChange
295 //purpose  :
296 //=======================================================================
297 void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
298 {
299   if (myBusy) return;
300   myBusy = true;
301
302   myNbOkNodes = 0;
303
304   buttonOk->setEnabled(false);
305   buttonApply->setEnabled(false);
306
307   // hilight entered nodes
308   if(myActor){
309     if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
310       Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
311            
312       TColStd_MapOfInteger newIndices;
313       
314       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
315       for (int i = 0; i < aListId.count(); i++) {
316         if (const SMDS_MeshNode *aNode = aMesh->FindNode(aListId[i].toInt())) {
317           newIndices.Add(aNode->GetID());
318           myNbOkNodes++;
319         }
320       }
321
322       mySelector->AddOrRemoveIndex(anIO,newIndices,false);
323       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
324         aViewWindow->highlight(anIO,true,true);
325     }
326   }
327
328   if (myNbOkNodes) {
329     buttonOk->setEnabled(true);
330     buttonApply->setEnabled(true);
331   }
332
333   myBusy = false;
334 }
335
336 //=================================================================================
337 // function : SelectionIntoArgument()
338 // purpose  : Called when selection as changed or other case
339 //=================================================================================
340 void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
341 {
342   if (myBusy) return;
343
344   // clear
345
346   myNbOkNodes = false;
347   myActor = 0;
348
349   myBusy = true;
350   myEditCurrentArgument->setText("");
351   myBusy = false;
352
353   if (!GroupButtons->isEnabled()) // inactive
354     return;
355
356   buttonOk->setEnabled(false);
357   buttonApply->setEnabled(false);
358
359   // get selected mesh
360   SALOME_ListIO aList;
361   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
362
363   int nbSel = aList.Extent();
364   if (nbSel != 1)
365     return;
366
367   Handle(SALOME_InteractiveObject) anIO = aList.First();
368   myMesh = SMESH::GetMeshByIO(anIO);
369   if (myMesh->_is_nil())
370     return;
371
372   myActor = SMESH::FindActorByEntry(anIO->getEntry());
373   if (!myActor)
374     return;
375
376   // get selected nodes
377
378   QString aString = "";
379   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString);
380   if(nbNodes < 1)
381     return;
382   myBusy = true;
383   myEditCurrentArgument->setText(aString);
384   myBusy = false;
385
386   // OK
387
388   myNbOkNodes = true;
389
390   buttonOk->setEnabled(true);
391   buttonApply->setEnabled(true);
392 }
393
394 //=================================================================================
395 // function : SetEditCurrentArgument()
396 // purpose  :
397 //=================================================================================
398 void SMESHGUI_RemoveNodesDlg::SetEditCurrentArgument()
399 {
400   QPushButton* send = (QPushButton*)sender();
401   switch (myConstructorId) {
402   case 0: /* default constructor */
403     {
404       if(send == SelectButtonC1A1) {
405         LineEditC1A1->setFocus();
406         myEditCurrentArgument = LineEditC1A1;
407       }
408       SelectionIntoArgument();
409       break;
410     }
411   }
412 }
413
414 //=================================================================================
415 // function : DeactivateActiveDialog()
416 // purpose  :
417 //=================================================================================
418 void SMESHGUI_RemoveNodesDlg::DeactivateActiveDialog()
419 {
420   if (GroupConstructors->isEnabled()) {
421     GroupConstructors->setEnabled(false);
422     GroupC1->setEnabled(false);
423     GroupButtons->setEnabled(false);
424     mySMESHGUI->ResetState(); // ??
425     mySMESHGUI->SetActiveDialogBox(0); // ??
426   }
427 }
428
429 //=================================================================================
430 // function : ActivateThisDialog()
431 // purpose  :
432 //=================================================================================
433 void SMESHGUI_RemoveNodesDlg::ActivateThisDialog()
434 {
435   /* Emit a signal to deactivate the active dialog */
436   mySMESHGUI->EmitSignalDeactivateDialog();
437
438   GroupConstructors->setEnabled(true);
439   GroupC1->setEnabled(true);
440   GroupButtons->setEnabled(true);
441
442   mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
443
444   SMESH::SetPointRepresentation(true);
445   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
446     aViewWindow->SetSelectionMode(NodeSelection);
447
448   SelectionIntoArgument(); // ??
449 }
450
451 //=================================================================================
452 // function : enterEvent()
453 // purpose  :
454 //=================================================================================
455 void SMESHGUI_RemoveNodesDlg::enterEvent(QEvent*)
456 {
457   if (!GroupConstructors->isEnabled())
458     ActivateThisDialog();
459 }
460
461 //=================================================================================
462 // function : closeEvent()
463 // purpose  :
464 //=================================================================================
465 void SMESHGUI_RemoveNodesDlg::closeEvent(QCloseEvent*)
466 {
467   /* same than click on cancel button */
468   ClickOnCancel();
469 }
470
471 //=======================================================================
472 //function : hideEvent
473 //purpose  : caused by ESC key
474 //=======================================================================
475 void SMESHGUI_RemoveNodesDlg::hideEvent( QHideEvent* )
476 {
477   if (!isMinimized())
478     ClickOnCancel();
479 }
480
481 //=================================================================================
482 // function : keyPressEvent()
483 // purpose  :
484 //=================================================================================
485 void SMESHGUI_RemoveNodesDlg::keyPressEvent( QKeyEvent* e )
486 {
487   QDialog::keyPressEvent( e );
488   if ( e->isAccepted() )
489     return;
490
491   if ( e->key() == Qt::Key_F1 ) {
492     e->accept();
493     ClickOnHelp();
494   }
495 }