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