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