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