Salome HOME
a39a62ed01c10296ea14e30c0d3be66d2ab3d71b
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_CreatePatternDlg.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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( reject() ) );
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( reject() ) );
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 : reject()
486 // purpose  : SLOT called when "Close" button pressed. Close dialog
487 //=======================================================================
488 void SMESHGUI_CreatePatternDlg::reject()
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   QDialog::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 : onSelBtnClicked()
653 // purpose  : SLOT. Called when -> button clicked.
654 //=======================================================================
655 void SMESHGUI_CreatePatternDlg::onSelBtnClicked()
656 {
657   onSelectionDone();
658 }
659
660 //================================================================
661 // function : autoExtension()
662 // purpose  : Append extension to the file name
663 //================================================================
664 QString SMESHGUI_CreatePatternDlg::autoExtension( const QString& theFileName ) const
665 {
666   QString anExt = theFileName.section('.', -1);
667   return anExt != "smp" && anExt != "SMP" ? theFileName + ".smp" : theFileName;
668 }
669
670 //=======================================================================
671 // function : displayPreview()
672 // purpose  : Display preview
673 //=======================================================================
674 void SMESHGUI_CreatePatternDlg::displayPreview()
675 {
676   // Redisplay preview in dialog
677   try {
678     if ( !myIsLoaded ) {
679       erasePreview();
680     }
681     else {
682       SMESH::point_array_var pnts = myPattern->GetPoints();
683       SMESH::long_array_var keyPoints = myPattern->GetKeyPoints();
684       SMESH::array_of_long_array_var elemPoints = myPattern->GetElementPoints( false );
685
686       if ( pnts->length()       == 0 ||
687            keyPoints->length()  == 0 ||
688            elemPoints->length() == 0 ) {
689         myIsLoaded = false;
690         erasePreview();
691         return;
692       }
693
694       PointVector aPoints( pnts->length() );
695       QVector<int> aKeyPoints( keyPoints->length() );
696       ConnectivityVector anElemPoints( elemPoints->length() );
697
698       for ( int i = 0, n = pnts->length(); i < n; i++ )
699         aPoints[ i ] = pnts[ i ];
700
701       for ( int i2 = 0, n2 = keyPoints->length(); i2 < n2; i2++ )
702         aKeyPoints[ i2 ] = keyPoints[ i2 ];
703
704       for (int i3 = 0, n3 = elemPoints->length(); i3 < n3; i3++) {
705         QVector<int> aVec (elemPoints[ i3 ].length());
706         for (int i4 = 0, n4 = elemPoints[ i3 ].length(); i4 < n4; i4++)
707           aVec[ i4 ] = elemPoints[ i3 ][ i4 ];
708
709         anElemPoints[ i3 ] = aVec;
710       }
711
712       myPicture2d->SetPoints( aPoints, aKeyPoints, anElemPoints );
713     }
714
715     return;
716
717   } 
718   catch ( const SALOME::SALOME_Exception& S_ex ) {
719     SalomeApp_Tools::QtCatchCorbaException( S_ex );
720   }
721   catch (...) {
722   }
723   erasePreview();
724 }
725
726 //=======================================================================
727 // function : erasePreview()
728 // purpose  : Erase preview
729 //=======================================================================
730 void SMESHGUI_CreatePatternDlg::erasePreview()
731 {
732   // Erase preview in 2D viewer
733   myPicture2d->SetPoints( PointVector(), QVector<int>(), ConnectivityVector() );
734 }
735
736 //=======================================================================
737 // function : activateSelection()
738 // purpose  : Activate selection in accordance with current pattern type
739 //=======================================================================
740 void SMESHGUI_CreatePatternDlg::activateSelection()
741 {
742   mySelectionMgr->clearFilters();
743   //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection);
744   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
745     aViewWindow->SetSelectionMode( ActorSelection );
746
747   if ( myType == Type_2d ) {
748     mySelectionMgr->installFilter( new SMESH_NumberFilter( "SMESH",
749                                                            TopAbs_SHAPE,
750                                                            -1,
751                                                            TopAbs_FACE ) );
752   } 
753   else {
754     TColStd_MapOfInteger aTypes;
755     aTypes.Add( TopAbs_SHELL );
756     aTypes.Add( TopAbs_SOLID );
757     mySelectionMgr->installFilter( new SMESH_NumberFilter( "SMESH",
758                                                            TopAbs_FACE,
759                                                            6,
760                                                            aTypes,
761                                                            GEOM::GEOM_Object::_nil(),
762                                                            true ) );
763   }
764 }
765
766 //=======================================================================
767 // function : onTypeChanged()
768 // purpose  : SLOT. Called when pattern type changed.
769 //            Change dialog's look and feel
770 //=======================================================================
771 void SMESHGUI_CreatePatternDlg::onTypeChanged( int theType )
772 {
773   if ( myType == theType )
774     return;
775
776   myType = theType;
777
778   myPicture2d->setVisible( theType == Type_2d );
779   myProjectChk->setVisible( theType == Type_2d );
780 }
781
782 //=================================================================================
783 // function : keyPressEvent()
784 // purpose  :
785 //=================================================================================
786 void SMESHGUI_CreatePatternDlg::keyPressEvent( QKeyEvent* e )
787 {
788   QDialog::keyPressEvent( e );
789   if ( e->isAccepted() )
790     return;
791
792   if ( e->key() == Qt::Key_F1 ){
793     e->accept();
794     onHelp();
795   }
796 }