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