Salome HOME
Update copyright information
[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
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_RemoveElementsDlg()
76 // purpose  :
77 //=================================================================================
78 SMESHGUI_RemoveElementsDlg
79 ::SMESHGUI_RemoveElementsDlg(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_ELEMENTS_TITLE"));
89   setSizeGripEnabled(true);
90   
91   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_REM_ELEMENT")));
92   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
93
94   QVBoxLayout* SMESHGUI_RemoveElementsDlgLayout = new QVBoxLayout(this);
95   SMESHGUI_RemoveElementsDlgLayout->setSpacing(SPACING);
96   SMESHGUI_RemoveElementsDlgLayout->setMargin(MARGIN);
97
98   /***************************************************************/
99   GroupConstructors = new QGroupBox(tr("SMESH_ELEMENTS"), 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_ELEMENTS"), 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_RemoveElementsDlgLayout->addWidget(GroupConstructors);
154   SMESHGUI_RemoveElementsDlgLayout->addWidget(GroupC1);
155   SMESHGUI_RemoveElementsDlgLayout->addWidget(GroupButtons);
156
157   myHelpFileName = "removing_nodes_and_elements_page.html#removing_elements_anchor";
158
159   Init(); /* Initialisations */
160 }
161
162 //=================================================================================
163 // function : ~SMESHGUI_RemoveElementsDlg()
164 // purpose  : Destroys the object and frees any allocated resources
165 //=================================================================================
166 SMESHGUI_RemoveElementsDlg::~SMESHGUI_RemoveElementsDlg()
167 {
168 }
169
170 //=================================================================================
171 // function : Init()
172 // purpose  :
173 //=================================================================================
174 void SMESHGUI_RemoveElementsDlg::Init()
175 {
176   myConstructorId = 0;
177   Constructor1->setChecked(true);
178   myEditCurrentArgument = LineEditC1A1;
179
180   myNbOkElements = 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   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
200     aViewWindow->SetSelectionMode(CellSelection);
201
202   SelectionIntoArgument();
203 }
204
205 //=================================================================================
206 // function : ClickOnApply()
207 // purpose  :
208 //=================================================================================
209 void SMESHGUI_RemoveElementsDlg::ClickOnApply()
210 {
211   if (mySMESHGUI->isActiveStudyLocked())
212     return;
213
214   if (myNbOkElements) {
215     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
216     SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
217     anArrayOfIdeces->length(aListId.count());
218     for (int i = 0; i < aListId.count(); i++)
219       anArrayOfIdeces[i] = aListId[ i ].toInt();
220
221     bool aResult = false;
222     try {
223       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
224       aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.inout());
225     } catch (const SALOME::SALOME_Exception& S_ex) {
226       SalomeApp_Tools::QtCatchCorbaException(S_ex);
227       myEditCurrentArgument->clear();
228     } catch (...){
229       myEditCurrentArgument->clear();
230     }
231
232     if (aResult) {
233       myEditCurrentArgument->clear();
234       mySelector->ClearIndex();
235       SMESH::UpdateView();
236     }
237   }
238 }
239
240 //=================================================================================
241 // function : ClickOnOk()
242 // purpose  :
243 //=================================================================================
244 void SMESHGUI_RemoveElementsDlg::ClickOnOk()
245 {
246   ClickOnApply();
247   ClickOnCancel();
248 }
249
250 //=================================================================================
251 // function : ClickOnCancel()
252 // purpose  :
253 //=================================================================================
254 void SMESHGUI_RemoveElementsDlg::ClickOnCancel()
255 {
256   //mySelectionMgr->clearSelected();
257   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
258     aViewWindow->SetSelectionMode(ActorSelection);
259   disconnect(mySelectionMgr, 0, this, 0);
260   mySMESHGUI->ResetState();
261   reject();
262 }
263
264 //=================================================================================
265 // function : ClickOnHelp()
266 // purpose  :
267 //=================================================================================
268 void SMESHGUI_RemoveElementsDlg::ClickOnHelp()
269 {
270   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
271   if (app) 
272     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
273   else {
274     QString platform;
275 #ifdef WIN32
276     platform = "winapplication";
277 #else
278     platform = "application";
279 #endif
280     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
281                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
282                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
283                                                                  platform)).
284                              arg(myHelpFileName));
285   }
286 }
287
288 //=======================================================================
289 //function : onTextChange
290 //purpose  :
291 //=======================================================================
292 void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
293 {
294   if (myBusy) return;
295   myBusy = true;
296
297   myNbOkElements = 0;
298
299   buttonOk->setEnabled(false);
300   buttonApply->setEnabled(false);
301
302   // hilight entered elements
303   if(myActor){
304     if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
305       Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
306       
307       TColStd_MapOfInteger newIndices;
308       
309       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
310       for (int i = 0; i < aListId.count(); i++) {
311         if(const SMDS_MeshElement *anElem = aMesh->FindElement(aListId[i].toInt())) {
312           newIndices.Add(anElem->GetID());
313           myNbOkElements++;
314         }
315       }
316       
317       mySelector->AddOrRemoveIndex(anIO,newIndices,false);
318       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
319         aViewWindow->highlight(anIO,true,true);
320     }
321   }
322   
323   if (myNbOkElements) {
324     buttonOk->setEnabled(true);
325     buttonApply->setEnabled(true);
326   }
327   
328   myBusy = false;
329 }
330
331 //=================================================================================
332 // function : SelectionIntoArgument()
333 // purpose  : Called when selection as changed or other case
334 //=================================================================================
335 void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument()
336 {
337   if (myBusy) return;
338
339   // clear
340
341   myNbOkElements = false;
342   myActor = 0;
343
344   myBusy = true;
345   myEditCurrentArgument->setText("");
346   myBusy = false;
347
348   if (!GroupButtons->isEnabled()) // inactive
349     return;
350
351   buttonOk->setEnabled(false);
352   buttonApply->setEnabled(false);
353
354   // get selected mesh
355
356   SALOME_ListIO aList;
357   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
358
359   int nbSel = aList.Extent();
360   if (nbSel != 1)
361     return;
362
363   Handle(SALOME_InteractiveObject) anIO = aList.First();
364   myMesh = SMESH::GetMeshByIO(anIO);
365   if (myMesh->_is_nil())
366     return;
367
368   myActor = SMESH::FindActorByEntry(anIO->getEntry());
369   if (!myActor)
370     return;
371
372   // get selected nodes
373   QString aString = "";
374   int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString);
375   if(nbElems < 1)
376     return;
377   myBusy = true;
378   myEditCurrentArgument->setText(aString);
379   myBusy = false;
380
381   // OK
382
383   myNbOkElements = nbElems;
384
385   buttonOk->setEnabled(true);
386   buttonApply->setEnabled(true);
387 }
388
389 //=================================================================================
390 // function : SetEditCurrentArgument()
391 // purpose  :
392 //=================================================================================
393 void SMESHGUI_RemoveElementsDlg::SetEditCurrentArgument()
394 {
395   QPushButton* send = (QPushButton*)sender();
396   switch (myConstructorId) {
397   case 0: /* default constructor */
398     {
399       if(send == SelectButtonC1A1) {
400         LineEditC1A1->setFocus();
401         myEditCurrentArgument = LineEditC1A1;
402       }
403       SelectionIntoArgument();
404       break;
405     }
406   }
407 }
408
409 //=================================================================================
410 // function : DeactivateActiveDialog()
411 // purpose  :
412 //=================================================================================
413 void SMESHGUI_RemoveElementsDlg::DeactivateActiveDialog()
414 {
415   if (GroupConstructors->isEnabled()) {
416     GroupConstructors->setEnabled(false);
417     GroupC1->setEnabled(false);
418     GroupButtons->setEnabled(false);
419     mySMESHGUI->ResetState(); // ??
420     mySMESHGUI->SetActiveDialogBox(0); // ??
421   }
422 }
423
424 //=================================================================================
425 // function : ActivateThisDialog()
426 // purpose  :
427 //=================================================================================
428 void SMESHGUI_RemoveElementsDlg::ActivateThisDialog()
429 {
430   /* Emit a signal to deactivate the active dialog */
431   mySMESHGUI->EmitSignalDeactivateDialog();
432
433   GroupConstructors->setEnabled(true);
434   GroupC1->setEnabled(true);
435   GroupButtons->setEnabled(true);
436
437   mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
438
439   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
440     aViewWindow->SetSelectionMode(CellSelection);
441
442   SelectionIntoArgument(); // ??
443 }
444
445 //=================================================================================
446 // function : enterEvent()
447 // purpose  :
448 //=================================================================================
449 void SMESHGUI_RemoveElementsDlg::enterEvent(QEvent*)
450 {
451   if (!GroupConstructors->isEnabled())
452     ActivateThisDialog();
453 }
454
455 //=================================================================================
456 // function : closeEvent()
457 // purpose  :
458 //=================================================================================
459 void SMESHGUI_RemoveElementsDlg::closeEvent(QCloseEvent*)
460 {
461   /* same than click on cancel button */
462   ClickOnCancel();
463 }
464
465 //=======================================================================
466 //function : hideEvent
467 //purpose  : caused by ESC key
468 //=======================================================================
469 void SMESHGUI_RemoveElementsDlg::hideEvent( QHideEvent* )
470 {
471   if (!isMinimized())
472     ClickOnCancel();
473 }
474
475 //=================================================================================
476 // function : keyPressEvent()
477 // purpose  :
478 //=================================================================================
479 void SMESHGUI_RemoveElementsDlg::keyPressEvent( QKeyEvent* e )
480 {
481   QDialog::keyPressEvent( e );
482   if ( e->isAccepted() )
483     return;
484
485   if ( e->key() == Qt::Key_F1 ) {
486     e->accept();
487     ClickOnHelp();
488   }
489 }