]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.cxx
Salome HOME
Update copyright information
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI_MaterialPropertiesDlg.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File   : GEOMToolsGUI_MaterialPropertiesDlg.cxx
21 // Author : Margarita KARPUNINA, Open CASCADE S.A.S. (margarita.karpunina@opencascade.com)
22
23 #include "GEOMToolsGUI_MaterialPropertiesDlg.h"
24
25 #include "Material_Model.h"
26 #include "Material_ResourceMgr.h"
27
28 #include <GeometryGUI.h>
29 #include <GEOM_Constants.h>
30 #include <GEOM_Displayer.h>
31 #include <GEOM_Actor.h>
32
33 #include <GEOMBase.h>
34
35 #include <Basics_OCCTVersion.hxx>
36
37 #include <SALOME_ListIO.hxx>
38 #include <SALOME_ListIteratorOfListIO.hxx>
39
40 #include <SVTK_Functor.h>
41 #include <SVTK_Prs.h>
42 #include <SVTK_ViewModel.h>
43 #include <SVTK_ViewWindow.h>
44 #include <SVTK_View.h>
45
46 #include <VTKViewer_Algorithm.h>
47
48 #include <OCCViewer_ViewModel.h>
49
50 #include <SUIT_Desktop.h>
51 #include <SUIT_MessageBox.h>
52 #include <SUIT_OverrideCursor.h>
53 #include <SUIT_ResourceMgr.h>
54 #include <SUIT_Session.h>
55 #include <SUIT_ViewManager.h>
56
57 #include <SalomeApp_Application.h>
58 #include <SalomeApp_Study.h>
59
60 #include <LightApp_SelectionMgr.h>
61
62 #include <QtxColorButton.h>
63 #include <QtxDoubleSpinBox.h>
64
65 // OCCT Includes
66 #include <Graphic3d_AspectFillArea3d.hxx>
67
68 // VTK includes
69 #include <vtkRenderer.h>
70 #include <vtkProperty.h>
71
72 // QT Includes
73 #include <QApplication>
74 #include <QButtonGroup>
75 #include <QCheckBox>
76 #include <QGridLayout>
77 #include <QGroupBox>
78 #include <QHBoxLayout>
79 #include <QKeyEvent>
80 #include <QLabel>
81 #include <QListWidget>
82 #include <QMap>
83 #include <QMessageBox>
84 #include <QPushButton>
85 #include <QSpinBox>
86 #include <QTabWidget>
87 #include <QVBoxLayout>
88
89 #define MARGIN  9
90 #define SPACING 6
91
92 /*!
93   \class GEOMToolsGUI_MaterialPropertiesDlg
94   \brief GEOM material properties dialog box class.
95
96   The dialog box lists all GEOM materials available via the application and allows
97   user to create own materials.
98 */
99
100 /*!
101   \brief Constructor
102   \param parent parent widget
103 */
104 GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* parent )
105   : QtxDialog( parent, true, true, OK | Close | Apply | Help),
106     myResMgr( 0 )
107 {
108   // Set title
109   setWindowTitle( tr( "MATERIAL_PROPERTIES_TLT" ) );
110
111   // Set viewer type
112   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
113   if ( app ) {
114     SUIT_ViewWindow* window = app->desktop()->activeWindow();
115     if ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() )
116       myViewerType = OCC;
117     else if ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() )
118       myViewerType = VTK;
119   }
120
121   // Create main layout
122   QVBoxLayout* main = new QVBoxLayout( mainFrame() );
123   main->setMargin( 0 ); main->setSpacing( SPACING );
124
125   // Create main widgets
126   myBackMaterialCheck = new QCheckBox( tr( "MATERIAL_BACK_CHK" ), this );
127   QFrame* fr = new QFrame( this );
128   fr->setFrameStyle( QFrame::Box | QFrame::Sunken );
129
130   main->addWidget( myBackMaterialCheck );
131   main->addWidget( fr );
132
133   // Create editor widgets
134   myMaterialList = new QListWidget( fr );
135   myMaterialTab  = new QTabWidget( fr );
136
137   QHBoxLayout* frLayout = new QHBoxLayout( fr );
138   frLayout->setMargin( MARGIN ); frLayout->setSpacing( SPACING );
139   frLayout->addWidget( myMaterialList );
140   frLayout->addWidget( myMaterialTab );
141   frLayout->setStretchFactor( myMaterialList, 1 );
142   frLayout->setStretchFactor( myMaterialTab, 2 );
143
144   // ======================= Create a tab for front material ======================= 
145   QWidget* w1 = new QWidget( myMaterialTab );
146   QVBoxLayout* vLayout1 = new QVBoxLayout( w1 );
147
148   QGridLayout* gLayout1 = new QGridLayout( w1 );
149   gLayout1->setMargin( MARGIN ); gLayout1->setSpacing( SPACING );
150
151   // ----------------- "Ambient" reflection type group box -----------------
152   myAmbientGroupF = new QGroupBox( tr( "AMBIENT_GRP" ), w1 );
153   myAmbientGroupF->setCheckable(true);
154   connect( myAmbientGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) ); 
155
156   // Ambient color
157   QLabel* ambColorLab1 = new QLabel( tr( "COLOR" ), myAmbientGroupF );
158   myAmbientColorF = new QtxColorButton( myAmbientGroupF );
159   myAmbientColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
160   connect( myAmbientColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
161
162   // Ambient coefficient
163   QLabel* ambCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), myAmbientGroupF );
164   myAmbientCoefntF = new QtxDoubleSpinBox( myAmbientGroupF );
165   myAmbientCoefntF->setMaximum(1);
166   myAmbientCoefntF->setSingleStep(0.05);
167   connect( myAmbientCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
168
169   // Ambient group box layout
170   QGridLayout* ambientLayout1 = new QGridLayout( myAmbientGroupF );
171   ambientLayout1->setMargin( MARGIN ); ambientLayout1->setSpacing( SPACING );
172   ambientLayout1->addWidget( ambColorLab1,       0, 0 );
173   ambientLayout1->addWidget( myAmbientColorF,    0, 1 );
174   ambientLayout1->addWidget( ambCoefficientLab1, 1, 0 );
175   ambientLayout1->addWidget( myAmbientCoefntF,   1, 1 );
176
177   // ----------------- "Diffuse" reflection type group box -----------------
178   myDiffuseGroupF = new QGroupBox( tr( "DIFFUSE_GRP" ), w1 );
179   myDiffuseGroupF->setCheckable(true);
180   connect( myDiffuseGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
181
182   // Diffuse color
183   QLabel* difColorLab1 = new QLabel( tr( "COLOR" ), myDiffuseGroupF );
184   myDiffuseColorF = new QtxColorButton( myDiffuseGroupF );
185   myDiffuseColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
186   connect( myDiffuseColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
187
188   // Diffuse coefficient
189   QLabel* difCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), myDiffuseGroupF );
190   myDiffuseCoefntF = new QtxDoubleSpinBox( myDiffuseGroupF );
191   myDiffuseCoefntF->setMaximum(1);
192   myDiffuseCoefntF->setSingleStep(0.05);
193   connect( myDiffuseCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
194
195   // Diffuse group box layout
196   QGridLayout* diffuseLayout1 = new QGridLayout( myDiffuseGroupF );
197   diffuseLayout1->setMargin( MARGIN ); diffuseLayout1->setSpacing( SPACING );
198   diffuseLayout1->addWidget( difColorLab1,       0, 0 );
199   diffuseLayout1->addWidget( myDiffuseColorF,    0, 1 );
200   diffuseLayout1->addWidget( difCoefficientLab1, 1, 0 );
201   diffuseLayout1->addWidget( myDiffuseCoefntF,   1, 1 );
202
203   // ----------------- "Specular" reflection type group box -----------------
204   mySpecularGroupF = new QGroupBox( tr( "SPECULAR_GRP" ), w1 );
205   mySpecularGroupF->setCheckable(true);
206   connect( mySpecularGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
207
208   // Specular color
209   QLabel* specColorLab1 = new QLabel( tr( "COLOR" ), mySpecularGroupF );
210   mySpecularColorF = new QtxColorButton( mySpecularGroupF );
211   mySpecularColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
212   connect( mySpecularColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
213
214   // Specular coefficient
215   QLabel* specCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), mySpecularGroupF );
216   mySpecularCoefntF = new QtxDoubleSpinBox( mySpecularGroupF );
217   mySpecularCoefntF->setMaximum(1);
218   mySpecularCoefntF->setSingleStep(0.05);
219   connect( mySpecularCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
220
221   // Specular group box layout
222   QGridLayout* specularLayout1 = new QGridLayout( mySpecularGroupF );
223   specularLayout1->setMargin( MARGIN ); specularLayout1->setSpacing( SPACING );
224   specularLayout1->addWidget( specColorLab1,       0, 0 );
225   specularLayout1->addWidget( mySpecularColorF,    0, 1 );
226   specularLayout1->addWidget( specCoefficientLab1, 1, 0 );
227   specularLayout1->addWidget( mySpecularCoefntF,   1, 1 );
228
229   // ----------------- "Emission" reflection type group box -----------------
230   myEmissionGroupF = new QGroupBox( tr( "EMISSION_GRP" ), w1 );
231   myEmissionGroupF->setCheckable(true);
232   connect( myEmissionGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
233
234   // Emission color
235   QLabel* emisColorLab1 = new QLabel( tr( "COLOR" ), myEmissionGroupF );
236   myEmissionColorF = new QtxColorButton( myEmissionGroupF );
237   myEmissionColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
238   connect( myEmissionColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
239
240   // Emission coefficient
241   QLabel* emisCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), myEmissionGroupF );
242   myEmissionCoefntF = new QtxDoubleSpinBox( myEmissionGroupF );
243   myEmissionCoefntF->setMaximum(1);
244   myEmissionCoefntF->setSingleStep(0.05);
245   connect( myEmissionCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
246
247   // Emission group box layout
248   QGridLayout* emissionLayout1 = new QGridLayout( myEmissionGroupF );
249   emissionLayout1->setMargin( MARGIN ); emissionLayout1->setSpacing( SPACING );
250   emissionLayout1->addWidget( emisColorLab1,       0, 0 );
251   emissionLayout1->addWidget( myEmissionColorF,    0, 1 );
252   emissionLayout1->addWidget( emisCoefficientLab1, 1, 0 );
253   emissionLayout1->addWidget( myEmissionCoefntF,   1, 1 );
254
255   // Erase emission group in case of VTK viewer
256   if ( myViewerType == VTK )
257     myEmissionGroupF->hide();
258
259   // Add group boxes to the main grid layout of the frame with material properties
260   gLayout1->addWidget( myAmbientGroupF,  0, 0 );
261   gLayout1->addWidget( myDiffuseGroupF,  0, 1 );
262   gLayout1->addWidget( mySpecularGroupF, 1, 0 );
263   gLayout1->addWidget( myEmissionGroupF, 1, 1 );
264
265   // Shininess
266   QLabel* shininessLab1 = new QLabel( tr( "SHININESS" ), w1 );
267   myShininessF = new QtxDoubleSpinBox( w1 );
268   myShininessF->setMaximum(1);
269   myShininessF->setSingleStep(0.05);
270   connect( myShininessF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
271
272   // Shininess layout
273   QHBoxLayout* shLayout1 = new QHBoxLayout( w1 );
274   shLayout1->setMargin( MARGIN ); shLayout1->setSpacing( SPACING );
275   shLayout1->addWidget( shininessLab1 );
276   shLayout1->addWidget( myShininessF );
277
278   // Fill initial vertical layout of the reflection type group box
279   vLayout1->addLayout( gLayout1 );
280   vLayout1->addLayout( shLayout1 );
281   vLayout1->addStretch();
282
283   // ======================= Create a tab for back material ======================= 
284   myMaterialBWidget = new QWidget( myMaterialTab );
285   QVBoxLayout* vLayout2 = new QVBoxLayout( myMaterialBWidget );
286
287   QGridLayout* gLayout2 = new QGridLayout( myMaterialBWidget );
288   gLayout2->setMargin( MARGIN ); gLayout2->setSpacing( SPACING );
289
290   // ----------------- "Ambient" reflection type group box -----------------
291   myAmbientGroupB = new QGroupBox( tr( "AMBIENT_GRP" ), myMaterialBWidget );
292   myAmbientGroupB->setCheckable(true);
293   connect( myAmbientGroupB, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) ); 
294
295   // Ambient color
296   QLabel* ambColorLab2 = new QLabel( tr( "COLOR" ), myAmbientGroupB );
297   myAmbientColorB = new QtxColorButton( myAmbientGroupB );
298   myAmbientColorB->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
299   connect( myAmbientColorB, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
300
301   // Ambient coefficient
302   QLabel* ambCoefficientLab2 = new QLabel( tr( "COEFFICIENT" ), myAmbientGroupB );
303   myAmbientCoefntB = new QtxDoubleSpinBox( myAmbientGroupB );
304   myAmbientCoefntB->setMaximum(1);
305   myAmbientCoefntB->setSingleStep(0.05);
306   connect( myAmbientCoefntB, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
307
308   // Ambient group box layout
309   QGridLayout* ambientLayout2 = new QGridLayout( myAmbientGroupB );
310   ambientLayout2->setMargin( MARGIN ); ambientLayout2->setSpacing( SPACING );
311   ambientLayout2->addWidget( ambColorLab2,       0, 0 );
312   ambientLayout2->addWidget( myAmbientColorB,    0, 1 );
313   ambientLayout2->addWidget( ambCoefficientLab2, 1, 0 );
314   ambientLayout2->addWidget( myAmbientCoefntB,   1, 1 );
315
316   // ----------------- "Diffuse" reflection type group box -----------------
317   myDiffuseGroupB = new QGroupBox( tr( "DIFFUSE_GRP" ), myMaterialBWidget );
318   myDiffuseGroupB->setCheckable(true);
319   connect( myDiffuseGroupB, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
320
321   // Diffuse color
322   QLabel* difColorLab2 = new QLabel( tr( "COLOR" ), myDiffuseGroupB );
323   myDiffuseColorB = new QtxColorButton( myDiffuseGroupB );
324   myDiffuseColorB->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
325   connect( myDiffuseColorB, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
326
327   // Diffuse coefficient
328   QLabel* difCoefficientLab2 = new QLabel( tr( "COEFFICIENT" ), myDiffuseGroupB );
329   myDiffuseCoefntB = new QtxDoubleSpinBox( myDiffuseGroupB );
330   myDiffuseCoefntB->setMaximum(1);
331   myDiffuseCoefntB->setSingleStep(0.05);
332   connect( myDiffuseCoefntB, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
333
334   // Diffuse group box layout
335   QGridLayout* diffuseLayout2 = new QGridLayout( myDiffuseGroupB );
336   diffuseLayout2->setMargin( MARGIN ); diffuseLayout2->setSpacing( SPACING );
337   diffuseLayout2->addWidget( difColorLab2,       0, 0 );
338   diffuseLayout2->addWidget( myDiffuseColorB,    0, 1 );
339   diffuseLayout2->addWidget( difCoefficientLab2, 1, 0 );
340   diffuseLayout2->addWidget( myDiffuseCoefntB,   1, 1 );
341
342   // ----------------- "Specular" reflection type group box -----------------
343   mySpecularGroupB = new QGroupBox( tr( "SPECULAR_GRP" ), myMaterialBWidget );
344   mySpecularGroupB->setCheckable(true);
345   connect( mySpecularGroupB, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
346
347   // Specular color
348   QLabel* specColorLab2 = new QLabel( tr( "COLOR" ), mySpecularGroupB );
349   mySpecularColorB = new QtxColorButton( mySpecularGroupB );
350   mySpecularColorB->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
351   connect( mySpecularColorB, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
352
353   // Specular coefficient
354   QLabel* specCoefficientLab2 = new QLabel( tr( "COEFFICIENT" ), mySpecularGroupB );
355   mySpecularCoefntB = new QtxDoubleSpinBox( mySpecularGroupB );
356   mySpecularCoefntB->setMaximum(1);
357   mySpecularCoefntB->setSingleStep(0.05);
358   connect( mySpecularCoefntB, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
359
360   // Specular group box layout
361   QGridLayout* specularLayout2 = new QGridLayout( mySpecularGroupB );
362   specularLayout2->setMargin( MARGIN ); specularLayout2->setSpacing( SPACING );
363   specularLayout2->addWidget( specColorLab2,       0, 0 );
364   specularLayout2->addWidget( mySpecularColorB,    0, 1 );
365   specularLayout2->addWidget( specCoefficientLab2, 1, 0 );
366   specularLayout2->addWidget( mySpecularCoefntB,   1, 1 );
367
368   // ----------------- "Emission" reflection type group box -----------------
369   myEmissionGroupB = new QGroupBox( tr( "EMISSION_GRP" ), myMaterialBWidget );
370   myEmissionGroupB->setCheckable(true);
371   connect( myEmissionGroupB, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
372
373   // Emission color
374   QLabel* emisColorLab2 = new QLabel( tr( "COLOR" ), myEmissionGroupB );
375   myEmissionColorB = new QtxColorButton( myEmissionGroupB );
376   myEmissionColorB->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
377   connect( myEmissionColorB, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
378
379   // Emission coefficient
380   QLabel* emisCoefficientLab2 = new QLabel( tr( "COEFFICIENT" ), myEmissionGroupB );
381   myEmissionCoefntB = new QtxDoubleSpinBox( myEmissionGroupB );
382   myEmissionCoefntB->setMaximum(1);
383   myEmissionCoefntB->setSingleStep(0.05);
384   connect( myEmissionCoefntB, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
385
386   // Emission group box layout
387   QGridLayout* emissionLayout2 = new QGridLayout( myEmissionGroupB );
388   emissionLayout2->setMargin( MARGIN ); emissionLayout2->setSpacing( SPACING );
389   emissionLayout2->addWidget( emisColorLab2,       0, 0 );
390   emissionLayout2->addWidget( myEmissionColorB,    0, 1 );
391   emissionLayout2->addWidget( emisCoefficientLab2, 1, 0 );
392   emissionLayout2->addWidget( myEmissionCoefntB,   1, 1 );
393
394   // Erase emission group in case of VTK viewer
395   if ( myViewerType == VTK )
396     myEmissionGroupB->hide();
397
398   // Add group boxes to the main grid layout of the frame with material properties
399   gLayout2->addWidget( myAmbientGroupB,  0, 0 );
400   gLayout2->addWidget( myDiffuseGroupB,  0, 1 );
401   gLayout2->addWidget( mySpecularGroupB, 1, 0 );
402   gLayout2->addWidget( myEmissionGroupB, 1, 1 );
403
404   // Shininess
405   QLabel* shininessLab2 = new QLabel( tr( "SHININESS" ), myMaterialBWidget );
406   myShininessB = new QtxDoubleSpinBox( myMaterialBWidget );
407   myShininessB->setMaximum(1);
408   myShininessB->setSingleStep(0.05);
409   connect( myShininessB, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
410
411   // Shininess layout
412   QHBoxLayout* shLayout2 = new QHBoxLayout( myMaterialBWidget );
413   shLayout2->setMargin( MARGIN ); shLayout2->setSpacing( SPACING );
414   shLayout2->addWidget( shininessLab2 );
415   shLayout2->addWidget( myShininessB );
416
417   // Fill initial vertical layout of the reflection type group box
418   vLayout2->addLayout( gLayout2 );
419   vLayout2->addLayout( shLayout2 );
420   vLayout2->addStretch();
421
422   // Add tabs to material tab widget
423   myMaterialTab->addTab( w1, tr( "Front material" ) );
424   myMaterialTab->addTab( myMaterialBWidget, tr( "Back material" ) );
425
426   // Initialize dialog box
427   setFocusProxy( fr );
428   setButtonPosition( Right, Close );
429   setDialogFlags( AlignOnce );
430   myMaterialList->setEditTriggers( QAbstractItemView::EditKeyPressed );
431   myMaterialList->installEventFilter( this );
432
433   // ! RESOURCES
434   QStringList globalMaterials = resourceMgr()->materials( Material_ResourceMgr::Global );
435   QStringList userMaterials = resourceMgr()->materials( Material_ResourceMgr::User );
436
437   QListWidgetItem* item;
438
439   // Current material
440   item = new QListWidgetItem( tr( "[ Current ]" ) );
441   item->setForeground( QColor( Qt::red ) );
442   item->setData( TypeRole, QVariant( Current ) );
443   myMaterialList->addItem( item );
444   // Default material
445   item = new QListWidgetItem( tr( "[ Default ]" ) );
446   item->setForeground( QColor( Qt::green ) );
447   item->setData( TypeRole, QVariant( Default ) );
448   myMaterialList->addItem( item );  
449   // ! RESOURCES
450   // Global materials
451   foreach ( QString sname, globalMaterials ) {
452     item = new QListWidgetItem( sname );
453     item->setForeground( QColor( Qt::blue ) );
454     item->setData( TypeRole, QVariant( Global ) );
455     item->setData( NameRole, QVariant( sname ) );
456     myMaterialList->addItem( item );
457   }
458   // ! RESOURCES
459   // User materials
460   foreach ( QString sname, userMaterials ) {
461     item = new QListWidgetItem( sname );
462     item->setData( TypeRole, QVariant( User ) );
463     item->setData( NameRole, QVariant( sname ) );
464     item->setFlags( item->flags() | Qt::ItemIsEditable );
465     myMaterialList->addItem( item );
466   }
467   
468   // Connect signals
469   connect( myMaterialTab,       SIGNAL( currentChanged( int ) ),
470            this,                SLOT( onCurrentTabChanged( int ) ) );
471   connect( myBackMaterialCheck, SIGNAL( toggled( bool ) ),
472            this,                SLOT( onBackMaterialChecked( bool ) ) );
473
474   connect( myMaterialList,      SIGNAL( itemSelectionChanged() ),
475            this,                SLOT( onMaterialChanged() ) );
476   connect( myMaterialList,      SIGNAL( itemChanged( QListWidgetItem* ) ),       
477            this,                SLOT( onItemChanged( QListWidgetItem* ) ) );
478   connect( myMaterialList,      SIGNAL( itemDoubleClicked( QListWidgetItem* ) ), 
479            this,                SLOT( onApply() ) );
480
481   connect( this, SIGNAL( changed() ),      this, SIGNAL( materialChanged() ) );
482   connect( this, SIGNAL( materialChanged() ), this, SLOT( onChanged() ) );
483   
484   connect( this, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
485   connect( this, SIGNAL( dlgHelp() ),  this, SLOT( onHelp() ) );
486
487   // Initialize current fornt and back material models of the selected shape
488   if ( app ) {
489     LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
490     if ( aSelMgr ) {
491       SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
492       if( aStudy ) {
493         SALOME_ListIO selected;
494         aSelMgr->selectedObjects( selected );
495
496         Handle(SALOME_InteractiveObject) FirstIOS =  selected.First();
497         if ( !FirstIOS.IsNull() ) {
498           SUIT_ViewWindow* window = app->desktop()->activeWindow();
499           int aMgrId = window->getViewManager()->getGlobalId();
500           
501           QString aMaterialF;
502           QString aMaterialB;
503
504           for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
505
506             PropMap aPropMap = aStudy->getObjectPropMap( aMgrId, It.Value()->getEntry() );
507             aMaterialF = aPropMap.value(FRONT_MATERIAL_PROP).toString();            
508             aMaterialB = aPropMap.value(BACK_MATERIAL_PROP).toString();
509               
510             if ( !aMaterialF.isEmpty() ) {
511               
512               QStringList aPropsF = aMaterialF.split(DIGIT_SEPARATOR);
513               
514               myCurrentModelF = Material_Model::getMaterialModel( aPropsF );            
515               
516               if ( !aMaterialB.isEmpty() ) {            
517                 QStringList aPropsB = aMaterialB.split(DIGIT_SEPARATOR);                
518                 myCurrentModelB = Material_Model::getMaterialModel( aPropsB );
519                 
520                 myBackMaterialCheck->setChecked( true );
521               }
522               else {
523                 myCurrentModelB = Material_Model::getMaterialModel( aPropsF );
524                 
525                 myBackMaterialCheck->setChecked( false );
526                 myMaterialTab->removeTab( 1 );
527               }
528               
529               break;
530             }
531           }
532             
533           if ( aMaterialF.isEmpty() ) {
534             myCurrentModelF = new Material_Model();
535             myCurrentModelF->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry" );
536
537             myCurrentModelB = new Material_Model();
538             myCurrentModelB->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry", false );
539           }
540         }
541       }
542     }
543   }
544
545   myMaterialList->setCurrentRow( 0 );
546   myMaterialListFId = 0;
547   myMaterialListBId = 0;
548
549   myIsBTabWasActivated = false;
550
551   myHelpFileName = "material_page.html";
552 }
553
554 /*!
555   \brief Destructor
556 */
557 GEOMToolsGUI_MaterialPropertiesDlg::~GEOMToolsGUI_MaterialPropertiesDlg()
558 {
559   if ( myCurrentModelF )
560     delete myCurrentModelF;
561
562   if ( myCurrentModelB )
563     delete myCurrentModelB;
564 }
565
566 /*!
567   \brief Called when "OK" button is clicked
568 */
569 void GEOMToolsGUI_MaterialPropertiesDlg::accept()
570 {
571   onApply();
572   QtxDialog::accept();
573 }
574
575 /*!
576   \brief Process key press event
577   \param o sender
578   \param e key event
579 */
580 bool GEOMToolsGUI_MaterialPropertiesDlg::eventFilter( QObject* o, QEvent* e )
581 {
582   if ( o == myMaterialList && e->type() == QEvent::KeyPress ) {
583     QKeyEvent* ke = (QKeyEvent*)e;
584     if ( ke->key() == Qt::Key_Delete ) {
585       QListWidgetItem* item = myMaterialList->currentItem();
586       if ( item && item->data( TypeRole ).toInt() == User ) {
587         if ( QMessageBox::question( this,
588                                     tr( "Delete user material" ),
589                                     tr( "Remove material %1?" ).arg( item->text() ),
590                                     QMessageBox::Yes | QMessageBox::No,
591                                     QMessageBox::Yes ) == QMessageBox::Yes ) {
592           resourceMgr()->remove( item->data( NameRole ).toString() );
593           resourceMgr()->save();
594           delete item;
595         }
596       }
597     }
598   }
599   return QtxDialog::eventFilter( o, e );
600 }
601
602 /*!
603   \brief Get GEOM materials resource manager
604   \return materials resource manager
605 */
606 Material_ResourceMgr* GEOMToolsGUI_MaterialPropertiesDlg::resourceMgr()
607 {
608   if ( !myResMgr )
609     myResMgr = new Material_ResourceMgr();
610   return myResMgr;
611 }
612
613 /*!
614   \brief Initialize dialog box fields from material model
615   \param model material model
616 */
617 void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( Material_Model* model)
618 {
619   if ( !model ) return;
620
621   bool isReflectionTypeActive;
622
623   if ( isFrontTabActive() ) { // Fill in front material tab
624     
625     // Ambient reflection type
626     isReflectionTypeActive = model->hasAmbientReflection();
627     myAmbientGroupF->setChecked( isReflectionTypeActive );
628     if ( isReflectionTypeActive ) {
629       // Load ambient color
630       myAmbientColorF->setColor( model->color(Material_Model::Ambient) );
631       // Load ambient coefficient
632       myAmbientCoefntF->setValue( model->coefficient(Material_Model::Ambient) );
633     }
634     
635     // Diffuse reflection type
636     isReflectionTypeActive = model->hasDiffuseReflection();
637     myDiffuseGroupF->setChecked( isReflectionTypeActive );
638     if ( isReflectionTypeActive ) {
639       // Load diffuse color
640       myDiffuseColorF->setColor( model->color(Material_Model::Diffuse) );
641       // Load diffuse coefficient
642       myDiffuseCoefntF->setValue( model->coefficient(Material_Model::Diffuse) );
643     }
644     
645     // Specular reflection type
646     isReflectionTypeActive = model->hasSpecularReflection();
647     mySpecularGroupF->setChecked( isReflectionTypeActive );
648     if ( isReflectionTypeActive ) {
649       // Load specular color
650       mySpecularColorF->setColor( model->color(Material_Model::Specular) );
651       // Load specular coefficient
652       mySpecularCoefntF->setValue( model->coefficient(Material_Model::Specular) );
653     }
654     
655     // Emission reflection type
656     isReflectionTypeActive = model->hasEmissionReflection();
657     myEmissionGroupF->setChecked( isReflectionTypeActive );
658     if ( isReflectionTypeActive ) {
659       // Load emission color
660       myEmissionColorF->setColor( model->color(Material_Model::Emission) );
661       // Load emission coefficient
662       myEmissionCoefntF->setValue( model->coefficient(Material_Model::Emission) );
663     }
664     
665     // Shininess
666     myShininessF->setValue( model->shininess() );
667     
668   }
669   else { // Fill in back material tab
670     
671     // Ambient reflection type
672     isReflectionTypeActive = model->hasAmbientReflection();
673     myAmbientGroupB->setChecked( isReflectionTypeActive );
674     if ( isReflectionTypeActive ) {
675       // Load ambient color
676       myAmbientColorB->setColor( model->color(Material_Model::Ambient) );
677       // Load ambient coefficient
678       myAmbientCoefntB->setValue( model->coefficient(Material_Model::Ambient) );
679     }
680     
681     // Diffuse reflection type
682     isReflectionTypeActive = model->hasDiffuseReflection();
683     myDiffuseGroupB->setChecked( isReflectionTypeActive );
684     if ( isReflectionTypeActive ) {
685       // Load diffuse color
686       myDiffuseColorB->setColor( model->color(Material_Model::Diffuse) );
687       // Load diffuse coefficient
688       myDiffuseCoefntB->setValue( model->coefficient(Material_Model::Diffuse) );
689     }
690     
691     // Specular reflection type
692     isReflectionTypeActive = model->hasSpecularReflection();
693     mySpecularGroupB->setChecked( isReflectionTypeActive );
694     if ( isReflectionTypeActive ) {
695       // Load specular color
696       mySpecularColorB->setColor( model->color(Material_Model::Specular) );
697       // Load specular coefficient
698       mySpecularCoefntB->setValue( model->coefficient(Material_Model::Specular) );
699     }
700     
701     // Emission reflection type
702     isReflectionTypeActive = model->hasEmissionReflection();
703     myEmissionGroupB->setChecked( isReflectionTypeActive );
704     if ( isReflectionTypeActive ) {
705       // Load emission color
706       myEmissionColorB->setColor( model->color(Material_Model::Emission) );
707       // Load emission coefficient
708       myEmissionCoefntB->setValue( model->coefficient(Material_Model::Emission) );
709     }
710     
711     // Shininess
712     myShininessB->setValue( model->shininess() );
713     
714   }
715 }
716  
717 /*!
718   \brief Save values from dialog box fields to material model
719   \param model material model
720 */
721 void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model* model ) const
722 {
723   if ( !model ) return;
724     
725   if ( isFrontTabActive() )
726     toFrontModel( model );
727   else
728     toBackModel( model );
729 }
730
731 /*!
732   \brief Save values from dialog box fields to front material model
733   \param model front material model to be filled
734 */
735 void GEOMToolsGUI_MaterialPropertiesDlg::toFrontModel( Material_Model* model ) const
736 {
737   if ( !model ) return;
738     
739   // "Ambient" reflection type
740   if ( myAmbientGroupF->isChecked() ) {
741     model->setColor( Material_Model::Ambient, myAmbientColorF->color() );
742     model->setCoefficient( Material_Model::Ambient, myAmbientCoefntF->value() );
743   }
744   else {
745     model->removeColor( Material_Model::Ambient );
746     model->removeCoefficient( Material_Model::Ambient );
747   }
748   
749   // "Diffuse" reflection type
750   if ( myDiffuseGroupF->isChecked() ) {
751     model->setColor( Material_Model::Diffuse, myDiffuseColorF->color() );
752     model->setCoefficient( Material_Model::Diffuse, myDiffuseCoefntF->value() );
753   }
754   else {
755     model->removeColor( Material_Model::Diffuse );
756     model->removeCoefficient( Material_Model::Diffuse );
757   }
758   
759   // "Specular" reflection type
760   if ( mySpecularGroupF->isChecked() ) {
761     model->setColor( Material_Model::Specular, mySpecularColorF->color() );
762     model->setCoefficient( Material_Model::Specular, mySpecularCoefntF->value() );
763   }
764   else {
765     model->removeColor( Material_Model::Specular );
766     model->removeCoefficient( Material_Model::Specular );
767   }
768   
769   // "Emission" reflection type
770   if ( myEmissionGroupF->isChecked() ) {
771     model->setColor( Material_Model::Emission, myEmissionColorF->color() );
772     model->setCoefficient( Material_Model::Emission, myEmissionCoefntF->value() );
773   }
774   else {
775     model->removeColor( Material_Model::Emission );
776     model->removeCoefficient( Material_Model::Emission );
777   }
778   
779   // Shininess
780   model->setShininess( myShininessF->value() );
781 }
782
783 /*!
784   \brief Save values from dialog box fields to back material model
785   \param model back material model to be filled
786 */
787 void GEOMToolsGUI_MaterialPropertiesDlg::toBackModel( Material_Model* model ) const
788 {
789   if ( !model )
790     return;
791
792   // "Ambient" reflection type
793   if ( myAmbientGroupB->isChecked() ) {
794     model->setColor( Material_Model::Ambient, myAmbientColorB->color() );
795     model->setCoefficient( Material_Model::Ambient, myAmbientCoefntB->value() );
796   }
797   else {
798     model->removeColor( Material_Model::Ambient );
799     model->removeCoefficient( Material_Model::Ambient );
800   }
801   
802   // "Diffuse" reflection type
803   if ( myDiffuseGroupB->isChecked() ) {
804     model->setColor( Material_Model::Diffuse, myDiffuseColorB->color() );
805     model->setCoefficient( Material_Model::Diffuse, myDiffuseCoefntB->value() );
806   }
807   else {
808     model->removeColor( Material_Model::Diffuse );
809     model->removeCoefficient( Material_Model::Diffuse );
810   }
811   
812   // "Specular" reflection type
813   if ( mySpecularGroupB->isChecked() ) {
814     model->setColor( Material_Model::Specular, mySpecularColorB->color() );
815     model->setCoefficient( Material_Model::Specular, mySpecularCoefntB->value() );
816   }
817   else {
818     model->removeColor( Material_Model::Specular );
819     model->removeCoefficient( Material_Model::Specular );
820   }
821   
822   // "Emission" reflection type
823   if ( myEmissionGroupB->isChecked() ) {
824     model->setColor( Material_Model::Emission, myEmissionColorB->color() );
825     model->setCoefficient( Material_Model::Emission, myEmissionCoefntB->value() );
826   }
827   else {
828     model->removeColor( Material_Model::Emission );
829     model->removeCoefficient( Material_Model::Emission );
830   }
831   
832   // Shininess
833   model->setShininess( myShininessB->value() );
834 }
835
836 /*!
837   \brief Find unique name for the material name
838   \param name material name template
839   \param item if not 0, used to be ignored when browsing through items list
840   \param addSuffix if \c true, the integrer suffix is always added to the material name (otherwise
841   suffix is added only if item name is not unique)
842   \return new unique material name
843 */
844 QString GEOMToolsGUI_MaterialPropertiesDlg::findUniqueName( const QString& name, QListWidgetItem* item, bool addSuffix )
845 {
846   bool found = false;
847   int idx = 0;
848   for( int i = 2; i < myMaterialList->count(); i++ ) {
849     if ( item == myMaterialList->item( i ) ) continue;
850     QString iname = myMaterialList->item( i )->text();
851     if ( iname == name ) {
852       found = true;
853     }
854     else {
855       iname = iname.mid( name.length() ).trimmed();
856       bool ok = false;
857       int nx = iname.toInt( &ok );
858       if ( ok ) idx = qMax( idx, nx );
859     }
860   }
861   return found || addSuffix ? QString( "%1 %2" ).arg( name ).arg( idx+1 ) : name;
862 }
863
864 /*!
865   \brief Check if tab with front material properties is currently active
866   \return true if front material tab is active
867 */
868 bool GEOMToolsGUI_MaterialPropertiesDlg::isFrontTabActive() const
869 {
870   return ( myMaterialTab->currentIndex() == 0 ? true : false );
871 }
872
873 /*!
874   \brief Called when "Apply" button is pressed
875 */
876 void GEOMToolsGUI_MaterialPropertiesDlg::onApply()
877 {  
878   // save user materials
879   resourceMgr()->save();
880
881   toFrontModel( myCurrentModelF );
882   if ( myBackMaterialCheck->isChecked() && myIsBTabWasActivated )
883     toBackModel( myCurrentModelB );
884
885   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
886   if ( !app )
887     return;
888   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
889   if ( !aSelMgr )
890     return;
891   
892   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
893   
894   if(!aStudy)
895     return;
896   
897   SALOME_ListIO selected;
898   aSelMgr->selectedObjects( selected );
899   if ( selected.IsEmpty() )
900     return;
901
902   Handle(SALOME_InteractiveObject) FirstIOS =  selected.First();
903   if ( FirstIOS.IsNull() )
904     return;
905         
906   SUIT_ViewWindow* window = app->desktop()->activeWindow();
907   int aMgrId = window->getViewManager()->getGlobalId();
908
909   // Parse material properties and form a string for persistent purpose
910   QString aMaterialF = myCurrentModelF->getMaterialProperty();
911   QString aMaterialB;
912   if ( myBackMaterialCheck->isChecked() )
913     aMaterialB = myCurrentModelB->getMaterialProperty();
914   
915   if ( myViewerType == VTK ) {    
916     // Get material properties from the current model
917     /*
918     vtkProperty* aPropertyF;
919     if ( !unsetMaterial )
920       aPropertyF = myCurrentModelF->getMaterialVTKProperty();
921     */
922     vtkProperty* aPropertyF = myCurrentModelF->getMaterialVTKProperty();
923     vtkProperty* aPropertyB = aPropertyF;
924     if ( myBackMaterialCheck->isChecked() )
925       aPropertyB = myCurrentModelB->getMaterialVTKProperty();
926
927     SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( window );
928     if ( !vtkVW )
929       return;
930     SVTK_View* aView = vtkVW->getView();
931
932     SUIT_OverrideCursor();
933     for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
934
935       /*
936       if ( unsetMaterial || aMaterialF.isEmpty() )
937         // Unset material for the selected shape
938         aisShape->UnsetMaterial();
939       else
940         // Set material for the selected shape
941       */
942         aView->SetMaterial( It.Value(), aPropertyF, aPropertyB );
943
944       // Persistent
945       aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), FRONT_MATERIAL_PROP, aMaterialF );
946       aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), BACK_MATERIAL_PROP, aMaterialB );
947     } // for...
948     aView->Repaint();
949     GeometryGUI::Modified();
950   } // if ( VTK )
951         
952   else if ( myViewerType == OCC ) {
953     // Get material properties from the current model
954     /*
955     Graphic3d_MaterialAspect aMatF;
956     if ( !unsetMaterial )
957       aMatF = myCurrentModelF->getMaterialOCCAspect();
958     */
959     Graphic3d_MaterialAspect aMatF = myCurrentModelF->getMaterialOCCAspect();
960     Graphic3d_MaterialAspect aMatB = aMatF;
961     if ( myBackMaterialCheck->isChecked() )
962       aMatB = myCurrentModelB->getMaterialOCCAspect();
963
964     Handle(GEOM_AISShape) aisShape;
965     
966     SUIT_OverrideCursor();
967     OCCViewer_Viewer* vm = dynamic_cast<OCCViewer_Viewer*>( window->getViewManager()->getViewModel() );
968     if ( !vm )
969       return;
970
971     GEOMBase* gb = new GEOMBase();
972
973     Handle(AIS_InteractiveContext) ic = vm->getAISContext();
974     for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
975       aisShape = gb->ConvertIOinGEOMAISShape( It.Value(), true );
976       if ( !aisShape.IsNull() ) {
977
978         if(!aisShape->HasInteractiveContext())
979           aisShape->SetContext(ic);
980
981         /*
982         if ( unsetMaterial || aMaterialF.isEmpty() )
983           // Unset material for the selected shape
984           aisShape->UnsetMaterial();
985         else
986         */
987           if ( myBackMaterialCheck->isChecked() ) {
988             // Set front material for the selected shape
989             aisShape->SetCurrentFacingModel(Aspect_TOFM_FRONT_SIDE);
990             aisShape->SetMaterial(aMatF);
991             // Set back material for the selected shape
992             aisShape->SetCurrentFacingModel(Aspect_TOFM_BACK_SIDE);
993             aisShape->SetMaterial(aMatB);
994             // Return to the default facing mode
995             aisShape->SetCurrentFacingModel(Aspect_TOFM_BOTH_SIDE);
996           }
997           else {
998             // Set the same front and back (is equal to front) materials for the selected shape
999             aisShape->SetMaterial(aMatF);
1000           }
1001
1002         if (aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/)
1003           ic->RecomputePrsOnly( aisShape, Standard_False );
1004
1005         // Persistent   
1006         aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), FRONT_MATERIAL_PROP, aMaterialF );
1007         aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), BACK_MATERIAL_PROP, aMaterialB );
1008       }
1009     } // for...    
1010     ic->UpdateCurrentViewer();
1011     GeometryGUI::Modified();
1012   } // if ( OCC )
1013 }
1014
1015 /*!
1016   \brief Called when "Help" button is pressed
1017 */
1018 void GEOMToolsGUI_MaterialPropertiesDlg::onHelp()
1019 {
1020   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1021   if (app) {
1022     GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
1023     app->onHelpContextModule(aGeomGUI ? app->moduleName(aGeomGUI->moduleName()) : QString(""), myHelpFileName);
1024   }
1025   else {
1026                 QString platform;
1027 #ifdef WIN32
1028                 platform = "winapplication";
1029 #else
1030                 platform = "application";
1031 #endif
1032     SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
1033                              QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1034                              arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
1035                              QObject::tr("BUT_OK"));
1036   }  
1037 }
1038
1039 /*!
1040   \brief Called when user check/uncheck "Enable back material" check box
1041   \param theIsChecked the check state of the check box
1042 */
1043 void GEOMToolsGUI_MaterialPropertiesDlg::onBackMaterialChecked( bool theIsChecked )
1044 {
1045   if ( theIsChecked ) {
1046     // Tab with back material properties is displayed
1047     myMaterialTab->addTab( myMaterialBWidget, tr( "Back material" ) );
1048
1049     // Create a current model of back material
1050     if ( !myCurrentModelB ) {
1051       myCurrentModelB = new Material_Model();
1052       myCurrentModelB->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry", false );
1053     }
1054     
1055     myMaterialListBId = 0;
1056   }
1057   else {
1058     // Tab with back material properties is hidden
1059     myMaterialTab->removeTab( 1 );
1060     
1061     // Remove the current model for back material
1062     if ( myCurrentModelB ) {
1063       delete myCurrentModelB;
1064       myCurrentModelB = 0;
1065     }
1066   }
1067 }
1068
1069 /*!
1070   \brief Called when user activates material tab
1071   \param theIndex the index of the tab which was activated by the user
1072 */
1073 void GEOMToolsGUI_MaterialPropertiesDlg::onCurrentTabChanged(int theIndex)
1074 {
1075   blockSignals( true );
1076
1077   // Change selection in the list of materials
1078   if ( isFrontTabActive() )
1079     myMaterialList->setCurrentRow( myMaterialListFId );
1080   else if ( myBackMaterialCheck->isChecked() )
1081     myMaterialList->setCurrentRow( myMaterialListBId );    
1082
1083   if ( theIndex == 1 )
1084     myIsBTabWasActivated = true;
1085
1086   blockSignals( false );
1087
1088   onMaterialChanged();
1089 }
1090
1091 /*!
1092   \brief Called when user selects any material item in the materials list
1093 */
1094 void GEOMToolsGUI_MaterialPropertiesDlg::onMaterialChanged()
1095 {
1096   blockSignals( true );
1097
1098   QListWidgetItem* item = myMaterialList->currentItem();
1099   int type = item->data( TypeRole ).toInt();
1100   
1101   Material_Model* model = 0;
1102
1103   bool isFrontTab = isFrontTabActive();
1104
1105   if ( isFrontTab )
1106     myMaterialListFId = myMaterialList->currentRow();
1107   else
1108     myMaterialListBId = myMaterialList->currentRow();
1109
1110   switch ( type ) {    
1111   case Current:
1112     // current material
1113     model = ( isFrontTab ? myCurrentModelF : myCurrentModelB );
1114     break;    
1115   case Default:
1116     // default material
1117     model = new Material_Model();
1118     model->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry", ( isFrontTab ? true : false ) );
1119     break;    
1120   case Global:
1121   case User:
1122     // global material, user material
1123     model = new Material_Model();
1124     model->fromResources( resourceMgr(), item->data( NameRole ).toString() );
1125     break;
1126   default:
1127     break;
1128   }
1129
1130   fromModel( model );
1131   if ( type != Current )
1132     delete model;
1133
1134   blockSignals( false );
1135 }
1136
1137 /*!
1138   \brief Called when any material parameter is changed by the user
1139 */
1140 void GEOMToolsGUI_MaterialPropertiesDlg::onChanged()
1141 {
1142   QListWidgetItem* item = myMaterialList->currentItem();
1143   int type = item->data( TypeRole ).toInt();
1144
1145   bool isFrontTab = isFrontTabActive();
1146
1147   // for the current and user schemas do not perform any actions
1148   if ( type == Current ) {    
1149     Material_Model model = ( isFrontTab ? *( myCurrentModelF ) : *( myCurrentModelB ) );
1150     toModel( &model );
1151     model.save( 0, QString(), isFrontTab );
1152     blockSignals( true );
1153     fromModel( &model );
1154     blockSignals( false );    
1155   }
1156   else if ( type == User ) {    
1157     Material_Model model;
1158     toModel( &model );
1159     QString oldName = item->data( NameRole ).toString(), newName = item->text();
1160     if ( oldName == newName ) {
1161       model.save( resourceMgr(), oldName, isFrontTab );
1162     }
1163     else {
1164       resourceMgr()->remove( oldName );
1165       model.save( resourceMgr(), newName, isFrontTab );
1166       item->setData( NameRole, newName );
1167     }
1168     blockSignals( true );
1169     fromModel( &model );
1170     blockSignals( false );    
1171   }
1172   else {
1173     // if user tries to change global (or default, or no material) material,
1174     // we create a new user material basing on selected one
1175     QString newName = findUniqueName( tr( "CUSTOM_MATERIAL" ), 0, true );
1176     item = new QListWidgetItem( newName );
1177     item->setData( TypeRole, QVariant( User ) );
1178     item->setData( NameRole, QVariant( newName ) );
1179     item->setFlags( item->flags() | Qt::ItemIsEditable );
1180     myMaterialList->addItem( item );
1181     
1182     Material_Model model;
1183     toModel( &model );
1184     model.save( resourceMgr(), newName, isFrontTab );
1185     
1186     myMaterialList->setCurrentItem( item );
1187
1188     if ( isFrontTab )
1189       myMaterialListFId = myMaterialList->currentRow();
1190     else
1191       myMaterialListBId = myMaterialList->currentRow();
1192
1193   }
1194 }
1195
1196 /*!
1197   \brief Called when user material is renamed by the user
1198 */
1199 void GEOMToolsGUI_MaterialPropertiesDlg::onItemChanged( QListWidgetItem* item )
1200 {
1201   QString newName = item->text();
1202   QString uniqueName = findUniqueName( newName, item );
1203   if ( uniqueName != newName ) {
1204     myMaterialList->blockSignals( true );
1205     item->setText( uniqueName );
1206     myMaterialList->blockSignals( false );
1207   }
1208   onChanged();
1209 }                               
1210
1211 /*!
1212   \brief Called when widget effect is changed
1213 */
1214 void GEOMToolsGUI_MaterialPropertiesDlg::onReflectionTypeToggled( bool theIsOn )
1215 {
1216   QGroupBox* anObj = (QGroupBox*)sender();
1217
1218   // Set an empty values for color and coefficient
1219   // of the checked/unchecked reflection type
1220   QColor c;
1221
1222
1223   // Make changes on front material tab
1224   if ( anObj == myAmbientGroupF ) {    
1225     myAmbientColorF->setColor( c );
1226     myAmbientCoefntF->setValue( 0.0 );
1227   }
1228   else if ( anObj == myDiffuseGroupF ) {
1229     myDiffuseColorF->setColor( c );
1230     myDiffuseCoefntF->setValue( 0.0 );
1231   }
1232   else if ( anObj == mySpecularGroupF ) {
1233     mySpecularColorF->setColor( c );
1234     mySpecularCoefntF->setValue( 0.0 );
1235   }
1236   else if ( anObj == myEmissionGroupF ) {
1237     myEmissionColorF->setColor( c );
1238     myEmissionCoefntF->setValue( 0.0 );
1239   }
1240
1241   // Make changes on back material tab    
1242   if ( anObj == myAmbientGroupB ) {    
1243     myAmbientColorB->setColor( c );
1244     myAmbientCoefntB->setValue( 0.0 );
1245   }
1246   else if ( anObj == myDiffuseGroupB ) {
1247     myDiffuseColorB->setColor( c );
1248     myDiffuseCoefntB->setValue( 0.0 );
1249   }
1250   else if ( anObj == mySpecularGroupB ) {
1251     mySpecularColorB->setColor( c );
1252     mySpecularCoefntB->setValue( 0.0 );
1253   }
1254   else if ( anObj == myEmissionGroupB ) {
1255     myEmissionColorB->setColor( c );
1256     myEmissionCoefntB->setValue( 0.0 );
1257   }
1258   
1259   emit( changed() );
1260 }