Salome HOME
Update copyright information
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_CreatePatternDlg.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_CreatePatternDlg.cxx
24 //  Author : Sergey LITONIN
25 //  Module : SMESH
26 //
27 #include "SMESHGUI_CreatePatternDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_SpinBox.h"
31 #include "SMESHGUI_PatternWidget.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_VTKUtils.h"
34 #include "SMESHGUI_PatternUtils.h"
35 #include "SMESHGUI_GEOMGenUtils.h"
36
37 #include "SMESH_NumberFilter.hxx"
38
39 #include "SUIT_ResourceMgr.h"
40 #include "SUIT_Desktop.h"
41 #include "SUIT_FileDlg.h"
42 #include "SUIT_Session.h"
43 #include "SUIT_MessageBox.h"
44
45 #include "SalomeApp_Study.h"
46 #include "LightApp_Application.h"
47 #include "LightApp_DataOwner.h"
48 #include "LightApp_SelectionMgr.h"
49 #include "SalomeApp_Tools.h"
50
51 #include "SALOMEDS_SObject.hxx"
52
53 #include "SALOME_ListIO.hxx"
54 #include "SVTK_ViewModel.h"
55 #include "SVTK_ViewWindow.h"
56 #include "SVTK_Selector.h"
57 #include "SVTK_Selection.h"
58
59 // OCCT Includes
60 #include <TColStd_MapOfInteger.hxx>
61
62 // QT Includes
63 #include <qframe.h>
64 #include <qlayout.h>
65 #include <qlineedit.h>
66 #include <qpushbutton.h>
67 #include <qgroupbox.h>
68 #include <qlabel.h>
69 #include <qradiobutton.h>
70 #include <qcheckbox.h>
71 #include <qbuttongroup.h>
72 #include <qmessagebox.h>
73 #include <qapplication.h>
74
75 #define SPACING 5
76 #define MARGIN  10
77
78 /*!
79  *  Class       : SMESHGUI_CreatePatternDlg
80  *  Description : Dialog to specify filters for VTK viewer
81  */
82
83 //=======================================================================
84 // function : SMESHGUI_CreatePatternDlg()
85 // purpose  : Constructor
86 //=======================================================================
87 SMESHGUI_CreatePatternDlg::SMESHGUI_CreatePatternDlg( SMESHGUI*   theModule,
88                                                       const int   theType,
89                                                       const char* theName)
90      : QDialog( SMESH::GetDesktop( theModule ), theName, false,
91                 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
92      mySMESHGUI( theModule ),
93      mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
94 {
95   setCaption(tr("CAPTION"));
96
97   QVBoxLayout* aDlgLay = new QVBoxLayout (this, MARGIN, SPACING);
98
99   QFrame* aMainFrame = createMainFrame  (this);
100   QFrame* aBtnFrame  = createButtonFrame(this);
101
102   aDlgLay->addWidget(aMainFrame);
103   aDlgLay->addWidget(aBtnFrame);
104
105   aDlgLay->setStretchFactor(aMainFrame, 1);
106
107   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
108     mySelector = aViewWindow->GetSelector();
109
110   myHelpFileName = "pattern_mapping_page.html";
111
112   Init(theType);
113 }
114
115 //=======================================================================
116 // function : createMainFrame()
117 // purpose  : Create frame containing dialog's input fields
118 //=======================================================================
119 QFrame* SMESHGUI_CreatePatternDlg::createMainFrame (QWidget* theParent)
120 {
121   QPixmap iconSlct     (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
122   QPixmap icon2d       (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_PATTERN_2d")));
123   QPixmap icon3d       (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_PATTERN_3d")));
124   QPixmap iconSample2d (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_PATTERN_SAMPLE_2D")));
125
126   QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
127   aMainGrp->setFrameStyle(QFrame::NoFrame);
128   aMainGrp->setInsideMargin(0);
129
130   // Pattern type group
131
132   myTypeGrp = new QButtonGroup (1, Qt::Vertical, tr("PATTERN_TYPE"), aMainGrp);
133   mySwitch2d = new QRadioButton (myTypeGrp);
134   mySwitch3d = new QRadioButton (myTypeGrp);
135   mySwitch2d->setPixmap(icon2d);
136   mySwitch3d->setPixmap(icon3d);
137   myTypeGrp->insert(mySwitch2d, Type_2d);
138   myTypeGrp->insert(mySwitch3d, Type_3d);
139
140   QGroupBox* aPatternGrp = new QGroupBox(1, Qt::Horizontal, tr("PATTERN"), aMainGrp);
141
142   // Mesh and pattern name group
143
144   QGroupBox* aMeshGrp = new QGroupBox(1, Qt::Vertical, aPatternGrp);
145   aMeshGrp->setFrameStyle(QFrame::NoFrame);
146   aMeshGrp->setInsideMargin(0);
147
148   new QLabel(tr("MESH_OR_SUBMESH"), aMeshGrp);
149
150   QPushButton* aSelBtn = new QPushButton(aMeshGrp);
151   aSelBtn->setPixmap(iconSlct);
152   myMeshEdit = new QLineEdit(aMeshGrp);
153   myMeshEdit->setReadOnly(true);
154
155   QGroupBox* aPattGrp = new QGroupBox(1, Qt::Vertical, aPatternGrp);
156   aPattGrp->setFrameStyle(QFrame::NoFrame);
157   aPattGrp->setInsideMargin(0);
158
159   new QLabel(tr("PATTERN_NAME"), aPattGrp);
160   myName = new QLineEdit(aPattGrp);
161
162   // Picture 2d
163
164   myPicture2d = new SMESHGUI_PatternWidget(aPatternGrp),
165   myPicture2d->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
166
167   // Project check box
168
169   myProjectChk = new QCheckBox(tr("PROJECT"), aPatternGrp);
170
171   // Connect signals and slots
172
173   connect(myTypeGrp,    SIGNAL(clicked(int) ), SLOT(onTypeChanged(int)));
174   connect(myProjectChk, SIGNAL(toggled(bool)), SLOT(onProject(bool)   ));
175   connect(aSelBtn,      SIGNAL(clicked()      ), SLOT(onSelBtnClicked()));
176
177   return aMainGrp;
178 }
179
180 //=======================================================================
181 // function : createButtonFrame()
182 // purpose  : Create frame containing buttons
183 //=======================================================================
184 QFrame* SMESHGUI_CreatePatternDlg::createButtonFrame (QWidget* theParent)
185 {
186   QFrame* aFrame = new QFrame(theParent);
187   aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
188
189   myOkBtn    = new QPushButton(tr("SMESH_BUT_OK"    ), aFrame);
190   mySaveBtn  = new QPushButton(tr("SAVE"            ), aFrame);
191   myCloseBtn = new QPushButton(tr("SMESH_BUT_CANCEL"), aFrame);
192   myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), aFrame);
193
194   QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
195
196   QHBoxLayout* aLay = new QHBoxLayout(aFrame, MARGIN, SPACING);
197
198   aLay->addWidget(myOkBtn);
199   aLay->addWidget(mySaveBtn);
200   aLay->addItem(aSpacer);
201   aLay->addWidget(myCloseBtn);
202   aLay->addWidget(myHelpBtn);
203
204   connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
205   connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
206   connect(mySaveBtn, SIGNAL(clicked()), SLOT(onSave()));
207   connect(myHelpBtn, SIGNAL(clicked()), SLOT(onHelp()));
208
209   return aFrame;
210 }
211
212 //=======================================================================
213 // function : ~SMESHGUI_CreatePatternDlg()
214 // purpose  : Destructor
215 //=======================================================================
216 SMESHGUI_CreatePatternDlg::~SMESHGUI_CreatePatternDlg()
217 {
218   // no need to delete child widgets, Qt does it all for us
219 }
220
221 //=======================================================================
222 // function : onProject()
223 // purpose  : SLOT. Called when state of "Project nodes on ther face"
224 //            checkbox is changed
225 //=======================================================================
226 void SMESHGUI_CreatePatternDlg::onProject (bool)
227 {
228   loadFromObject(false);
229   displayPreview();
230 }
231
232 //=======================================================================
233 // function : Init()
234 // purpose  : Init dialog fields, connect signals and slots, show dialog
235 //=======================================================================
236 void SMESHGUI_CreatePatternDlg::Init( const int theType )
237 {
238   myIsLoaded     = false;
239   myType         = -1;
240   myNbPoints     = -1;
241   mySubMesh      = SMESH::SMESH_subMesh::_nil();
242   myMesh         = SMESH::SMESH_Mesh::_nil();
243   myGeomObj      = GEOM::GEOM_Object::_nil();
244   myPattern      = SMESH::SMESH_Pattern::_nil();
245
246   erasePreview();
247
248   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
249
250   // selection and SMESHGUI
251   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
252   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
253   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
254
255   mySwitch2d->setEnabled(theType == Type_2d);
256   mySwitch3d->setEnabled(theType == Type_3d);
257
258   if (theType == Type_2d)
259     myProjectChk->show();
260   else
261     myProjectChk->hide();
262
263   myTypeGrp->setButton(theType);
264   onTypeChanged(theType);
265
266   myName->setText(getDefaultName());
267   myMeshEdit->setText("");
268
269   setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
270   qApp->processEvents();
271   updateGeometry();
272   myPicture2d->updateGeometry();
273   adjustSize();
274   resize(minimumSize());
275
276   activateSelection();
277   onSelectionDone();
278
279   this->show();
280 }
281
282 //=======================================================================
283 // function : SetMesh()
284 // purpose  : Set mesh to dialog
285 //=======================================================================
286 void SMESHGUI_CreatePatternDlg::SetMesh (SMESH::SMESH_Mesh_ptr thePtr)
287 {
288   myMesh = SMESH::SMESH_Mesh::_duplicate(thePtr);
289   mySubMesh = SMESH::SMESH_subMesh::_nil();
290
291   bool isValidMesh = false;
292   if (!myMesh->_is_nil())
293   {
294     _PTR(SObject) aSobj = SMESH::FindSObject(myMesh.in());
295     //Handle(SALOME_InteractiveObject) anIObj =
296     //  new SALOME_InteractiveObject(aSobj->GetID().c_str(), "SMESH");
297     SUIT_DataOwnerPtr anIObj (new LightApp_DataOwner(aSobj->GetID().c_str()));
298
299     isValidMesh = mySelectionMgr->isOk(anIObj);
300   }
301
302   if (isValidMesh) {
303     _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in());
304     myMeshEdit->setText(aSO->GetName().c_str());
305     myGeomObj = SMESH::GetGeom(aSO);
306   } else {
307     myMeshEdit->setText("");
308     myGeomObj = GEOM::GEOM_Object::_nil();
309   }
310
311   if (myType == Type_2d) {
312     loadFromObject(false);
313     displayPreview();
314   }
315 }
316
317 //=======================================================================
318 // function : isValid()
319 // purpose  : Verify validity of entry data
320 //=======================================================================
321 bool SMESHGUI_CreatePatternDlg::isValid()
322 {
323   if (myGeomObj->_is_nil()) {
324     QMessageBox::information(SMESH::GetDesktop( mySMESHGUI ),
325                              tr("SMESH_INSUFFICIENT_DATA"),
326                              tr("SMESHGUI_INVALID_PARAMETERS"),
327                              QMessageBox::Ok);
328     return false;
329   }
330   else
331     return true;
332 }
333
334 //=======================================================================
335 // function : getDefaultName()
336 // purpose  : Get default pattern name
337 //=======================================================================
338 QString SMESHGUI_CreatePatternDlg::getDefaultName() const
339 {
340   return myType == Type_2d ? tr("DEFAULT_2D") : tr("DEFAULT_3D");
341 }
342
343 //=======================================================================
344 // function : onSave()
345 // purpose  : SLOT called when "Save" button pressed. Build pattern and
346 //           save it to disk
347 //=======================================================================
348 void SMESHGUI_CreatePatternDlg::onSave()
349 {
350   try {
351     if (!isValid())
352       return;
353
354     if (!myIsLoaded)
355       loadFromObject(true);
356
357     // Load pattern from object
358     if (!myIsLoaded)
359       return;
360
361     ///////////////////////////////////////////////////////
362     SUIT_FileDlg* aDlg = new SUIT_FileDlg (this, false);
363     aDlg->setCaption(tr("SAVE_PATTERN"));
364     aDlg->setMode(QFileDialog::AnyFile);
365     aDlg->setFilters(tr("PATTERN_FILT"));
366     if (myName->text() != "")
367       aDlg->setSelection(myName->text());
368
369     if (aDlg->exec() != Accepted)
370       return;
371
372     QString fName = aDlg->selectedFile();
373     if (fName.isEmpty())
374       return;
375
376     if (QFileInfo(fName).extension().isEmpty())
377       fName = autoExtension(fName);
378
379     fName = QDir::convertSeparators(fName);
380
381     QString aData (myPattern->GetString());
382     long aLen = aData.length();
383
384     QFile aFile (fName);
385     aFile.open(IO_WriteOnly);
386     long aWritten = aFile.writeBlock(aData, aLen);
387     aFile.close();
388
389     if (aWritten != aLen) {
390       QMessageBox::information(SMESH::GetDesktop( mySMESHGUI ), tr("SMESH_ERROR"),
391                                tr("ERROR_OF_SAVING"), QMessageBox::Ok);
392     } else {
393       //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection);
394       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
395         aViewWindow->SetSelectionMode(ActorSelection);
396       disconnect(mySelectionMgr, 0, this, 0);
397       disconnect(mySMESHGUI, 0, this, 0);
398       mySMESHGUI->ResetState();
399       accept();
400       emit NewPattern();
401     }
402   } catch (const SALOME::SALOME_Exception& S_ex) {
403     SalomeApp_Tools::QtCatchCorbaException(S_ex);
404   } catch (...) {
405   }
406 }
407
408 //=======================================================================
409 // function : GetPatternName()
410 // purpose  : Get name of pattern
411 //=======================================================================
412 QString SMESHGUI_CreatePatternDlg::GetPatternName() const
413 {
414   return myName->text();
415 }
416
417 //=======================================================================
418 // function : GetPattern()
419 // purpose  : Get result pattern
420 //=======================================================================
421 SMESH::SMESH_Pattern_ptr SMESHGUI_CreatePatternDlg::GetPattern()
422 {
423   return myPattern.in();
424 }
425
426 //=======================================================================
427 // function : onOk()
428 // purpose  : SLOT called when "Ok" button pressed.
429 //=======================================================================
430 void SMESHGUI_CreatePatternDlg::onOk()
431 {
432   try {
433     if (!isValid())
434       return;
435
436     if (!myIsLoaded)
437       loadFromObject(true);
438
439     // Load pattern from object
440     if (!myIsLoaded) {
441       return;
442     } else {
443       //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection);
444       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
445         aViewWindow->SetSelectionMode(ActorSelection);
446       disconnect(mySelectionMgr, 0, this, 0);
447       disconnect(mySMESHGUI, 0, this, 0);
448       mySMESHGUI->ResetState();
449       accept();
450       emit NewPattern();
451     }
452   } catch (const SALOME::SALOME_Exception& S_ex) {
453     SalomeApp_Tools::QtCatchCorbaException(S_ex);
454   } catch (...) {
455   }
456 }
457
458 //=======================================================================
459 // function : onClose()
460 // purpose  : SLOT called when "Close" button pressed. Close dialog
461 //=======================================================================
462 void SMESHGUI_CreatePatternDlg::onClose()
463 {
464   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
465     aViewWindow->SetSelectionMode(ActorSelection);
466   disconnect(mySelectionMgr, 0, this, 0);
467   disconnect(mySMESHGUI, 0, this, 0);
468   mySMESHGUI->ResetState();
469   reject();
470   emit Close();
471 }
472
473 //=================================================================================
474 // function : onHelp()
475 // purpose  :
476 //=================================================================================
477 void SMESHGUI_CreatePatternDlg::onHelp()
478 {
479   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
480   if (app) 
481     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
482   else {
483                 QString platform;
484 #ifdef WIN32
485                 platform = "winapplication";
486 #else
487                 platform = "application";
488 #endif
489     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
490                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
491                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
492                            QObject::tr("BUT_OK"));
493   }
494 }
495
496 //=======================================================================
497 // function : loadFromObject()
498 // purpose  : Load pattern from geom object corresponding to the mesh/submesh
499 //=======================================================================
500 bool SMESHGUI_CreatePatternDlg::loadFromObject (const bool theMess)
501 {
502   try {
503     myIsLoaded = false;
504
505     if (myPattern->_is_nil())
506       myPattern = SMESH::GetPattern();
507
508     if (myMesh->_is_nil() && mySubMesh->_is_nil() || myGeomObj->_is_nil())
509       return false;
510
511     SMESH::SMESH_Mesh_ptr aMesh = mySubMesh->_is_nil() ? myMesh.in() : mySubMesh->GetFather();
512
513     myIsLoaded = myType == Type_2d
514       ? myPattern->LoadFromFace(aMesh, myGeomObj, myProjectChk->isChecked())
515       : myPattern->LoadFrom3DBlock(aMesh, myGeomObj);
516
517     if (!myIsLoaded && theMess) {
518       QString aMess;
519       SMESH::SMESH_Pattern::ErrorCode aCode = myPattern->GetErrorCode();
520
521       if      (aCode == SMESH::SMESH_Pattern::ERR_LOAD_EMPTY_SUBMESH  ) aMess = tr("ERR_LOAD_EMPTY_SUBMESH");
522       else if (aCode == SMESH::SMESH_Pattern::ERR_LOADF_NARROW_FACE   ) aMess = tr("ERR_LOADF_NARROW_FACE");
523       else if (aCode == SMESH::SMESH_Pattern::ERR_LOADF_CLOSED_FACE   ) aMess = tr("ERR_LOADF_CLOSED_FACE");
524       else if (aCode == SMESH::SMESH_Pattern::ERR_LOADF_CANT_PROJECT   ) aMess = tr("ERR_LOADF_CANT_PROJECT");
525       else if (aCode == SMESH::SMESH_Pattern::ERR_LOADV_BAD_SHAPE     ) aMess = tr("ERR_LOADV_BAD_SHAPE");
526       else if (aCode == SMESH::SMESH_Pattern::ERR_LOADV_COMPUTE_PARAMS) aMess = tr("ERR_LOADV_COMPUTE_PARAMS");
527       else                                                              aMess = tr("ERROR_OF_CREATION");
528
529       QMessageBox::information(SMESH::GetDesktop( mySMESHGUI ),
530                                tr("SMESH_ERROR"), aMess, QMessageBox::Ok);
531     }
532   } catch (const SALOME::SALOME_Exception& S_ex) {
533     SalomeApp_Tools::QtCatchCorbaException(S_ex);
534   }
535
536   return myIsLoaded;
537 }
538
539 //=======================================================================
540 // function : onSelectionDone()
541 // purpose  : SLOT called when selection changed
542 //=======================================================================
543 void SMESHGUI_CreatePatternDlg::onSelectionDone()
544 {
545   try {
546     SALOME_ListIO aList;
547     mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
548     if (aList.Extent() != 1)
549       return;
550
551     // Get mesh or sub-mesh from selection
552     Handle(SALOME_InteractiveObject) anIO = aList.First();
553     SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIO);
554     SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
555     if (aMesh->_is_nil() && aSubMesh->_is_nil())
556       return;
557
558     // Get geom object corresponding to the mesh
559     _PTR(SObject) aSO;
560     if (!aMesh->_is_nil())
561       aSO = SMESH::FindSObject(aMesh.in());
562     else
563       aSO = SMESH::FindSObject(aSubMesh.in());
564
565     GEOM::GEOM_Object_var aGeomObj = SMESH::GetGeom(aSO);
566     if (aGeomObj->_is_nil())
567       return;
568
569     myGeomObj = aGeomObj;
570
571     // init class fields
572     if (!aMesh->_is_nil()) {
573       myMesh = aMesh;
574       mySubMesh = SMESH::SMESH_subMesh::_nil();
575     } else {
576       mySubMesh = aSubMesh;
577       myMesh = SMESH::SMESH_Mesh::_nil();
578     }
579
580     QString aName;
581     SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
582     myMeshEdit->setText(aName);
583
584     if (myType == Type_2d) {
585       loadFromObject(true);
586       displayPreview();
587     }
588   } catch (...) {
589     myMesh = SMESH::SMESH_Mesh::_nil();
590     mySubMesh = SMESH::SMESH_subMesh::_nil();
591     myGeomObj = GEOM::GEOM_Object::_nil();
592     erasePreview();
593   }
594 }
595
596 //=======================================================================
597 // function : onDeactivate()
598 // purpose  : SLOT called when dialog must be deativated
599 //=======================================================================
600 void SMESHGUI_CreatePatternDlg::onDeactivate()
601 {
602   disconnect(mySelectionMgr, 0, this, 0);
603   setEnabled(false);
604 }
605
606 //=======================================================================
607 // function : enterEvent()
608 // purpose  : Event filter
609 //=======================================================================
610 void SMESHGUI_CreatePatternDlg::enterEvent (QEvent*)
611 {
612   // there is a stange problem that enterEvent() comes after onSave()
613   if ( isVisible () ) {
614     mySMESHGUI->EmitSignalDeactivateDialog();
615     setEnabled(true);
616     activateSelection();
617     connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
618   }
619 }
620
621 //=================================================================================
622 // function : closeEvent()
623 // purpose  : Close dialog box
624 //=================================================================================
625 void SMESHGUI_CreatePatternDlg::closeEvent (QCloseEvent*)
626 {
627   onClose();
628 }
629
630 //=======================================================================
631 // function : onSelBtnClicked()
632 // purpose  : SLOT. Called when -> button clicked.
633 //=======================================================================
634 void SMESHGUI_CreatePatternDlg::onSelBtnClicked()
635 {
636   onSelectionDone();
637 }
638
639 //================================================================
640 // function : autoExtension()
641 // purpose  : Append extension to the file name
642 //================================================================
643 QString SMESHGUI_CreatePatternDlg::autoExtension (const QString& theFileName) const
644 {
645   QString anExt = theFileName.section('.', -1);
646   return anExt != "smp" && anExt != "SMP" ? theFileName + ".smp" : theFileName;
647 }
648
649 //=======================================================================
650 // function : displayPreview()
651 // purpose  : Display preview
652 //=======================================================================
653 void SMESHGUI_CreatePatternDlg::displayPreview()
654 {
655   // Redisplay preview in dialog
656   try {
657     if (!myIsLoaded) {
658       erasePreview();
659     } else {
660       SMESH::point_array_var pnts = myPattern->GetPoints();
661       SMESH::long_array_var keyPoints = myPattern->GetKeyPoints();
662       SMESH::array_of_long_array_var elemPoints = myPattern->GetElementPoints(false);
663
664       if (pnts->length()       == 0 ||
665           keyPoints->length()  == 0 ||
666           elemPoints->length() == 0) {
667         myIsLoaded = false;
668         erasePreview();
669         return;
670       }
671
672       PointVector aPoints (pnts->length());
673       QValueVector<int> aKeyPoints (keyPoints->length());
674       ConnectivityVector anElemPoints (elemPoints->length());
675
676       for (int i = 0, n = pnts->length(); i < n; i++)
677         aPoints[ i ] = pnts[ i ];
678
679       for (int i2 = 0, n2 = keyPoints->length(); i2 < n2; i2++)
680         aKeyPoints[ i2 ] = keyPoints[ i2 ];
681
682       for (int i3 = 0, n3 = elemPoints->length(); i3 < n3; i3++) {
683         QValueVector<int> aVec (elemPoints[ i3 ].length());
684         for (int i4 = 0, n4 = elemPoints[ i3 ].length(); i4 < n4; i4++)
685           aVec[ i4 ] = elemPoints[ i3 ][ i4 ];
686
687         anElemPoints[ i3 ] = aVec;
688       }
689
690       myPicture2d->SetPoints(aPoints, aKeyPoints, anElemPoints);
691     }
692
693     return;
694
695   } catch (const SALOME::SALOME_Exception& S_ex) {
696     SalomeApp_Tools::QtCatchCorbaException(S_ex);
697   } catch (...) {
698   }
699   erasePreview();
700 }
701
702 //=======================================================================
703 // function : erasePreview()
704 // purpose  : Erase preview
705 //=======================================================================
706 void SMESHGUI_CreatePatternDlg::erasePreview()
707 {
708   // Erase preview in 2D viewer
709   myPicture2d->SetPoints(PointVector(), QValueVector<int>(), ConnectivityVector());
710 }
711
712 //=======================================================================
713 // function : activateSelection()
714 // purpose  : Activate selection in accordance with current pattern type
715 //=======================================================================
716 void SMESHGUI_CreatePatternDlg::activateSelection()
717 {
718   mySelectionMgr->clearFilters();
719   //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection);
720   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
721     aViewWindow->SetSelectionMode(ActorSelection);
722
723   if (myType == Type_2d) {
724     mySelectionMgr->installFilter(new SMESH_NumberFilter
725       ("SMESH", TopAbs_SHAPE, -1, TopAbs_FACE));
726   } else {
727     TColStd_MapOfInteger aTypes;
728     aTypes.Add(TopAbs_SHELL);
729     aTypes.Add(TopAbs_SOLID);
730     mySelectionMgr->installFilter(new SMESH_NumberFilter
731       ("SMESH", TopAbs_FACE, 6, aTypes, GEOM::GEOM_Object::_nil(), true));
732   }
733 }
734
735 //=======================================================================
736 // function : onTypeChanged()
737 // purpose  : SLOT. Called when pattern type changed.
738 //            Change dialog's look and feel
739 //=======================================================================
740 void SMESHGUI_CreatePatternDlg::onTypeChanged (int theType)
741 {
742   if (myType == theType)
743     return;
744
745   myType = theType;
746
747   if (theType == Type_2d)
748     myPicture2d->show();
749   else
750     myPicture2d->hide();
751 }
752
753 //=================================================================================
754 // function : keyPressEvent()
755 // purpose  :
756 //=================================================================================
757 void SMESHGUI_CreatePatternDlg::keyPressEvent( QKeyEvent* e )
758 {
759   QDialog::keyPressEvent( e );
760   if ( e->isAccepted() )
761     return;
762
763   if ( e->key() == Key_F1 )
764     {
765       e->accept();
766       onHelp();
767     }
768 }