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