Salome HOME
0021514: EDF GEOM: Partition failure. A fix by PKV.
[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 o sender
577   \param e key event
578 */
579 bool GEOMToolsGUI_MaterialPropertiesDlg::eventFilter( QObject* o, QEvent* e )
580 {
581   if ( o == myMaterialList && e->type() == QEvent::KeyPress ) {
582     QKeyEvent* ke = (QKeyEvent*)e;
583     if ( ke->key() == Qt::Key_Delete ) {
584       QListWidgetItem* item = myMaterialList->currentItem();
585       if ( item && item->data( TypeRole ).toInt() == User ) {
586         if ( QMessageBox::question( this,
587                                     tr( "Delete user material" ),
588                                     tr( "Remove material %1?" ).arg( item->text() ),
589                                     QMessageBox::Yes | QMessageBox::No,
590                                     QMessageBox::Yes ) == QMessageBox::Yes ) {
591           resourceMgr()->remove( item->data( NameRole ).toString() );
592           resourceMgr()->save();
593           delete item;
594         }
595       }
596     }
597   }
598   return QtxDialog::eventFilter( o, e );
599 }
600
601 /*!
602   \brief Get GEOM materials resource manager
603   \return materials resource manager
604 */
605 Material_ResourceMgr* GEOMToolsGUI_MaterialPropertiesDlg::resourceMgr()
606 {
607   if ( !myResMgr )
608     myResMgr = new Material_ResourceMgr();
609   return myResMgr;
610 }
611
612 /*!
613   \brief Initialize dialog box fields from material model
614   \param model material model
615 */
616 void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( Material_Model* model)
617 {
618   if ( !model ) return;
619
620   bool isReflectionTypeActive;
621
622   if ( isFrontTabActive() ) { // Fill in front material tab
623     
624     // Ambient reflection type
625     isReflectionTypeActive = model->hasAmbientReflection();
626     myAmbientGroupF->setChecked( isReflectionTypeActive );
627     if ( isReflectionTypeActive ) {
628       // Load ambient color
629       myAmbientColorF->setColor( model->color(Material_Model::Ambient) );
630       // Load ambient coefficient
631       myAmbientCoefntF->setValue( model->coefficient(Material_Model::Ambient) );
632     }
633     
634     // Diffuse reflection type
635     isReflectionTypeActive = model->hasDiffuseReflection();
636     myDiffuseGroupF->setChecked( isReflectionTypeActive );
637     if ( isReflectionTypeActive ) {
638       // Load diffuse color
639       myDiffuseColorF->setColor( model->color(Material_Model::Diffuse) );
640       // Load diffuse coefficient
641       myDiffuseCoefntF->setValue( model->coefficient(Material_Model::Diffuse) );
642     }
643     
644     // Specular reflection type
645     isReflectionTypeActive = model->hasSpecularReflection();
646     mySpecularGroupF->setChecked( isReflectionTypeActive );
647     if ( isReflectionTypeActive ) {
648       // Load specular color
649       mySpecularColorF->setColor( model->color(Material_Model::Specular) );
650       // Load specular coefficient
651       mySpecularCoefntF->setValue( model->coefficient(Material_Model::Specular) );
652     }
653     
654     // Emission reflection type
655     isReflectionTypeActive = model->hasEmissionReflection();
656     myEmissionGroupF->setChecked( isReflectionTypeActive );
657     if ( isReflectionTypeActive ) {
658       // Load emission color
659       myEmissionColorF->setColor( model->color(Material_Model::Emission) );
660       // Load emission coefficient
661       myEmissionCoefntF->setValue( model->coefficient(Material_Model::Emission) );
662     }
663     
664     // Shininess
665     myShininessF->setValue( model->shininess() );
666     
667   }
668   else { // Fill in back material tab
669     
670     // Ambient reflection type
671     isReflectionTypeActive = model->hasAmbientReflection();
672     myAmbientGroupB->setChecked( isReflectionTypeActive );
673     if ( isReflectionTypeActive ) {
674       // Load ambient color
675       myAmbientColorB->setColor( model->color(Material_Model::Ambient) );
676       // Load ambient coefficient
677       myAmbientCoefntB->setValue( model->coefficient(Material_Model::Ambient) );
678     }
679     
680     // Diffuse reflection type
681     isReflectionTypeActive = model->hasDiffuseReflection();
682     myDiffuseGroupB->setChecked( isReflectionTypeActive );
683     if ( isReflectionTypeActive ) {
684       // Load diffuse color
685       myDiffuseColorB->setColor( model->color(Material_Model::Diffuse) );
686       // Load diffuse coefficient
687       myDiffuseCoefntB->setValue( model->coefficient(Material_Model::Diffuse) );
688     }
689     
690     // Specular reflection type
691     isReflectionTypeActive = model->hasSpecularReflection();
692     mySpecularGroupB->setChecked( isReflectionTypeActive );
693     if ( isReflectionTypeActive ) {
694       // Load specular color
695       mySpecularColorB->setColor( model->color(Material_Model::Specular) );
696       // Load specular coefficient
697       mySpecularCoefntB->setValue( model->coefficient(Material_Model::Specular) );
698     }
699     
700     // Emission reflection type
701     isReflectionTypeActive = model->hasEmissionReflection();
702     myEmissionGroupB->setChecked( isReflectionTypeActive );
703     if ( isReflectionTypeActive ) {
704       // Load emission color
705       myEmissionColorB->setColor( model->color(Material_Model::Emission) );
706       // Load emission coefficient
707       myEmissionCoefntB->setValue( model->coefficient(Material_Model::Emission) );
708     }
709     
710     // Shininess
711     myShininessB->setValue( model->shininess() );
712     
713   }
714 }
715  
716 /*!
717   \brief Save values from dialog box fields to material model
718   \param model material model
719 */
720 void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model* model ) const
721 {
722   if ( !model ) return;
723     
724   if ( isFrontTabActive() )
725     toFrontModel( model );
726   else
727     toBackModel( model );
728 }
729
730 /*!
731   \brief Save values from dialog box fields to front material model
732   \param model front material model to be filled
733 */
734 void GEOMToolsGUI_MaterialPropertiesDlg::toFrontModel( Material_Model* model ) const
735 {
736   if ( !model ) return;
737     
738   // "Ambient" reflection type
739   if ( myAmbientGroupF->isChecked() ) {
740     model->setColor( Material_Model::Ambient, myAmbientColorF->color() );
741     model->setCoefficient( Material_Model::Ambient, myAmbientCoefntF->value() );
742   }
743   else {
744     model->removeColor( Material_Model::Ambient );
745     model->removeCoefficient( Material_Model::Ambient );
746   }
747   
748   // "Diffuse" reflection type
749   if ( myDiffuseGroupF->isChecked() ) {
750     model->setColor( Material_Model::Diffuse, myDiffuseColorF->color() );
751     model->setCoefficient( Material_Model::Diffuse, myDiffuseCoefntF->value() );
752   }
753   else {
754     model->removeColor( Material_Model::Diffuse );
755     model->removeCoefficient( Material_Model::Diffuse );
756   }
757   
758   // "Specular" reflection type
759   if ( mySpecularGroupF->isChecked() ) {
760     model->setColor( Material_Model::Specular, mySpecularColorF->color() );
761     model->setCoefficient( Material_Model::Specular, mySpecularCoefntF->value() );
762   }
763   else {
764     model->removeColor( Material_Model::Specular );
765     model->removeCoefficient( Material_Model::Specular );
766   }
767   
768   // "Emission" reflection type
769   if ( myEmissionGroupF->isChecked() ) {
770     model->setColor( Material_Model::Emission, myEmissionColorF->color() );
771     model->setCoefficient( Material_Model::Emission, myEmissionCoefntF->value() );
772   }
773   else {
774     model->removeColor( Material_Model::Emission );
775     model->removeCoefficient( Material_Model::Emission );
776   }
777   
778   // Shininess
779   model->setShininess( myShininessF->value() );
780 }
781
782 /*!
783   \brief Save values from dialog box fields to back material model
784   \param model back material model to be filled
785 */
786 void GEOMToolsGUI_MaterialPropertiesDlg::toBackModel( Material_Model* model ) const
787 {
788   if ( !model )
789     return;
790
791   // "Ambient" reflection type
792   if ( myAmbientGroupB->isChecked() ) {
793     model->setColor( Material_Model::Ambient, myAmbientColorB->color() );
794     model->setCoefficient( Material_Model::Ambient, myAmbientCoefntB->value() );
795   }
796   else {
797     model->removeColor( Material_Model::Ambient );
798     model->removeCoefficient( Material_Model::Ambient );
799   }
800   
801   // "Diffuse" reflection type
802   if ( myDiffuseGroupB->isChecked() ) {
803     model->setColor( Material_Model::Diffuse, myDiffuseColorB->color() );
804     model->setCoefficient( Material_Model::Diffuse, myDiffuseCoefntB->value() );
805   }
806   else {
807     model->removeColor( Material_Model::Diffuse );
808     model->removeCoefficient( Material_Model::Diffuse );
809   }
810   
811   // "Specular" reflection type
812   if ( mySpecularGroupB->isChecked() ) {
813     model->setColor( Material_Model::Specular, mySpecularColorB->color() );
814     model->setCoefficient( Material_Model::Specular, mySpecularCoefntB->value() );
815   }
816   else {
817     model->removeColor( Material_Model::Specular );
818     model->removeCoefficient( Material_Model::Specular );
819   }
820   
821   // "Emission" reflection type
822   if ( myEmissionGroupB->isChecked() ) {
823     model->setColor( Material_Model::Emission, myEmissionColorB->color() );
824     model->setCoefficient( Material_Model::Emission, myEmissionCoefntB->value() );
825   }
826   else {
827     model->removeColor( Material_Model::Emission );
828     model->removeCoefficient( Material_Model::Emission );
829   }
830   
831   // Shininess
832   model->setShininess( myShininessB->value() );
833 }
834
835 /*!
836   \brief Find unique name for the material name
837   \param name material name template
838   \param item if not 0, used to be ignored when browsing through items list
839   \param addSuffix if \c true, the integrer suffix is always added to the material name (otherwise
840   suffix is added only if item name is not unique)
841   \return new unique material name
842 */
843 QString GEOMToolsGUI_MaterialPropertiesDlg::findUniqueName( const QString& name, QListWidgetItem* item, bool addSuffix )
844 {
845   bool found = false;
846   int idx = 0;
847   for( int i = 2; i < myMaterialList->count(); i++ ) {
848     if ( item == myMaterialList->item( i ) ) continue;
849     QString iname = myMaterialList->item( i )->text();
850     if ( iname == name ) {
851       found = true;
852     }
853     else {
854       iname = iname.mid( name.length() ).trimmed();
855       bool ok = false;
856       int nx = iname.toInt( &ok );
857       if ( ok ) idx = qMax( idx, nx );
858     }
859   }
860   return found || addSuffix ? QString( "%1 %2" ).arg( name ).arg( idx+1 ) : name;
861 }
862
863 /*!
864   \brief Check if tab with front material properties is currently active
865   \return true if front material tab is active
866 */
867 bool GEOMToolsGUI_MaterialPropertiesDlg::isFrontTabActive() const
868 {
869   return ( myMaterialTab->currentIndex() == 0 ? true : false );
870 }
871
872 /*!
873   \brief Called when "Apply" button is pressed
874 */
875 void GEOMToolsGUI_MaterialPropertiesDlg::onApply()
876 {  
877   // save user materials
878   resourceMgr()->save();
879
880   toFrontModel( myCurrentModelF );
881   if ( myBackMaterialCheck->isChecked() && myIsBTabWasActivated )
882     toBackModel( myCurrentModelB );
883
884   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
885   if ( !app )
886     return;
887   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
888   if ( !aSelMgr )
889     return;
890   
891   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
892   
893   if(!aStudy)
894     return;
895   
896   SALOME_ListIO selected;
897   aSelMgr->selectedObjects( selected );
898   if ( selected.IsEmpty() )
899     return;
900
901   Handle(SALOME_InteractiveObject) FirstIOS =  selected.First();
902   if ( FirstIOS.IsNull() )
903     return;
904         
905   SUIT_ViewWindow* window = app->desktop()->activeWindow();
906   int aMgrId = window->getViewManager()->getGlobalId();
907
908   // Parse material properties and form a string for persistent purpose
909   QString aMaterialF = myCurrentModelF->getMaterialProperty();
910   QString aMaterialB;
911   if ( myBackMaterialCheck->isChecked() )
912     aMaterialB = myCurrentModelB->getMaterialProperty();
913   
914   if ( myViewerType == VTK ) {    
915     // Get material properties from the current model
916     /*
917     vtkProperty* aPropertyF;
918     if ( !unsetMaterial )
919       aPropertyF = myCurrentModelF->getMaterialVTKProperty();
920     */
921     vtkProperty* aPropertyF = myCurrentModelF->getMaterialVTKProperty();
922     vtkProperty* aPropertyB = aPropertyF;
923     if ( myBackMaterialCheck->isChecked() )
924       aPropertyB = myCurrentModelB->getMaterialVTKProperty();
925
926     SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( window );
927     if ( !vtkVW )
928       return;
929     SVTK_View* aView = vtkVW->getView();
930
931     SUIT_OverrideCursor();
932     for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
933
934       /*
935       if ( unsetMaterial || aMaterialF.isEmpty() )
936         // Unset material for the selected shape
937         aisShape->UnsetMaterial();
938       else
939         // Set material for the selected shape
940       */
941         aView->SetMaterial( It.Value(), aPropertyF, aPropertyB );
942
943       // Persistent
944       aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), FRONT_MATERIAL_PROP, aMaterialF );
945       aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), BACK_MATERIAL_PROP, aMaterialB );
946     } // for...
947     aView->Repaint();
948     GeometryGUI::Modified();
949   } // if ( VTK )
950         
951   else if ( myViewerType == OCC ) {
952     // Get material properties from the current model
953     /*
954     Graphic3d_MaterialAspect aMatF;
955     if ( !unsetMaterial )
956       aMatF = myCurrentModelF->getMaterialOCCAspect();
957     */
958     Graphic3d_MaterialAspect aMatF = myCurrentModelF->getMaterialOCCAspect();
959     Graphic3d_MaterialAspect aMatB = aMatF;
960     if ( myBackMaterialCheck->isChecked() )
961       aMatB = myCurrentModelB->getMaterialOCCAspect();
962
963     Handle(GEOM_AISShape) aisShape;
964     
965     SUIT_OverrideCursor();
966     OCCViewer_Viewer* vm = dynamic_cast<OCCViewer_Viewer*>( window->getViewManager()->getViewModel() );
967     if ( !vm )
968       return;
969
970     GEOMBase* gb = new GEOMBase();
971
972     Handle(AIS_InteractiveContext) ic = vm->getAISContext();
973     for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
974       aisShape = gb->ConvertIOinGEOMAISShape( It.Value(), true );
975       if ( !aisShape.IsNull() ) {
976
977         if(!aisShape->HasInteractiveContext())
978           aisShape->SetContext(ic);
979
980         /*
981         if ( unsetMaterial || aMaterialF.isEmpty() )
982           // Unset material for the selected shape
983           aisShape->UnsetMaterial();
984         else
985         */
986           if ( myBackMaterialCheck->isChecked() ) {
987             // Set front material for the selected shape
988             aisShape->SetCurrentFacingModel(Aspect_TOFM_FRONT_SIDE);
989             aisShape->SetMaterial(aMatF);
990             // Set back material for the selected shape
991             aisShape->SetCurrentFacingModel(Aspect_TOFM_BACK_SIDE);
992             aisShape->SetMaterial(aMatB);
993             // Return to the default facing mode
994             aisShape->SetCurrentFacingModel(Aspect_TOFM_BOTH_SIDE);
995           }
996           else {
997             // Set the same front and back (is equal to front) materials for the selected shape
998             aisShape->SetMaterial(aMatF);
999           }
1000
1001         if (aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/)
1002           ic->RecomputePrsOnly( aisShape, Standard_False );
1003
1004         // Persistent   
1005         aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), FRONT_MATERIAL_PROP, aMaterialF );
1006         aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), BACK_MATERIAL_PROP, aMaterialB );
1007       }
1008     } // for...    
1009     ic->UpdateCurrentViewer();
1010     GeometryGUI::Modified();
1011   } // if ( OCC )
1012 }
1013
1014 /*!
1015   \brief Called when "Help" button is pressed
1016 */
1017 void GEOMToolsGUI_MaterialPropertiesDlg::onHelp()
1018 {
1019   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1020   if (app) {
1021     GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
1022     app->onHelpContextModule(aGeomGUI ? app->moduleName(aGeomGUI->moduleName()) : QString(""), myHelpFileName);
1023   }
1024   else {
1025                 QString platform;
1026 #ifdef WIN32
1027                 platform = "winapplication";
1028 #else
1029                 platform = "application";
1030 #endif
1031     SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
1032                              QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1033                              arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
1034                              QObject::tr("BUT_OK"));
1035   }  
1036 }
1037
1038 /*!
1039   \brief Called when user check/uncheck "Enable back material" check box
1040   \param theIsChecked the check state of the check box
1041 */
1042 void GEOMToolsGUI_MaterialPropertiesDlg::onBackMaterialChecked( bool theIsChecked )
1043 {
1044   if ( theIsChecked ) {
1045     // Tab with back material properties is displayed
1046     myMaterialTab->addTab( myMaterialBWidget, tr( "Back material" ) );
1047
1048     // Create a current model of back material
1049     if ( !myCurrentModelB ) {
1050       myCurrentModelB = new Material_Model();
1051       myCurrentModelB->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry", false );
1052     }
1053     
1054     myMaterialListBId = 0;
1055   }
1056   else {
1057     // Tab with back material properties is hidden
1058     myMaterialTab->removeTab( 1 );
1059     
1060     // Remove the current model for back material
1061     if ( myCurrentModelB ) {
1062       delete myCurrentModelB;
1063       myCurrentModelB = 0;
1064     }
1065   }
1066 }
1067
1068 /*!
1069   \brief Called when user activates material tab
1070   \param theIndex the index of the tab which was activated by the user
1071 */
1072 void GEOMToolsGUI_MaterialPropertiesDlg::onCurrentTabChanged(int theIndex)
1073 {
1074   blockSignals( true );
1075
1076   // Change selection in the list of materials
1077   if ( isFrontTabActive() )
1078     myMaterialList->setCurrentRow( myMaterialListFId );
1079   else if ( myBackMaterialCheck->isChecked() )
1080     myMaterialList->setCurrentRow( myMaterialListBId );    
1081
1082   if ( theIndex == 1 )
1083     myIsBTabWasActivated = true;
1084
1085   blockSignals( false );
1086
1087   onMaterialChanged();
1088 }
1089
1090 /*!
1091   \brief Called when user selects any material item in the materials list
1092 */
1093 void GEOMToolsGUI_MaterialPropertiesDlg::onMaterialChanged()
1094 {
1095   blockSignals( true );
1096
1097   QListWidgetItem* item = myMaterialList->currentItem();
1098   int type = item->data( TypeRole ).toInt();
1099   
1100   Material_Model* model = 0;
1101
1102   bool isFrontTab = isFrontTabActive();
1103
1104   if ( isFrontTab )
1105     myMaterialListFId = myMaterialList->currentRow();
1106   else
1107     myMaterialListBId = myMaterialList->currentRow();
1108
1109   switch ( type ) {    
1110   case Current:
1111     // current material
1112     model = ( isFrontTab ? myCurrentModelF : myCurrentModelB );
1113     break;    
1114   case Default:
1115     // default material
1116     model = new Material_Model();
1117     model->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry", ( isFrontTab ? true : false ) );
1118     break;    
1119   case Global:
1120   case User:
1121     // global material, user material
1122     model = new Material_Model();
1123     model->fromResources( resourceMgr(), item->data( NameRole ).toString() );
1124     break;
1125   default:
1126     break;
1127   }
1128
1129   fromModel( model );
1130   if ( type != Current )
1131     delete model;
1132
1133   blockSignals( false );
1134 }
1135
1136 /*!
1137   \brief Called when any material parameter is changed by the user
1138 */
1139 void GEOMToolsGUI_MaterialPropertiesDlg::onChanged()
1140 {
1141   QListWidgetItem* item = myMaterialList->currentItem();
1142   int type = item->data( TypeRole ).toInt();
1143
1144   bool isFrontTab = isFrontTabActive();
1145
1146   // for the current and user schemas do not perform any actions
1147   if ( type == Current ) {    
1148     Material_Model model = ( isFrontTab ? *( myCurrentModelF ) : *( myCurrentModelB ) );
1149     toModel( &model );
1150     model.save( 0, QString(), isFrontTab );
1151     blockSignals( true );
1152     fromModel( &model );
1153     blockSignals( false );    
1154   }
1155   else if ( type == User ) {    
1156     Material_Model model;
1157     toModel( &model );
1158     QString oldName = item->data( NameRole ).toString(), newName = item->text();
1159     if ( oldName == newName ) {
1160       model.save( resourceMgr(), oldName, isFrontTab );
1161     }
1162     else {
1163       resourceMgr()->remove( oldName );
1164       model.save( resourceMgr(), newName, isFrontTab );
1165       item->setData( NameRole, newName );
1166     }
1167     blockSignals( true );
1168     fromModel( &model );
1169     blockSignals( false );    
1170   }
1171   else {
1172     // if user tries to change global (or default, or no material) material,
1173     // we create a new user material basing on selected one
1174     QString newName = findUniqueName( tr( "CUSTOM_MATERIAL" ), 0, true );
1175     item = new QListWidgetItem( newName );
1176     item->setData( TypeRole, QVariant( User ) );
1177     item->setData( NameRole, QVariant( newName ) );
1178     item->setFlags( item->flags() | Qt::ItemIsEditable );
1179     myMaterialList->addItem( item );
1180     
1181     Material_Model model;
1182     toModel( &model );
1183     model.save( resourceMgr(), newName, isFrontTab );
1184     
1185     myMaterialList->setCurrentItem( item );
1186
1187     if ( isFrontTab )
1188       myMaterialListFId = myMaterialList->currentRow();
1189     else
1190       myMaterialListBId = myMaterialList->currentRow();
1191
1192   }
1193 }
1194
1195 /*!
1196   \brief Called when user material is renamed by the user
1197 */
1198 void GEOMToolsGUI_MaterialPropertiesDlg::onItemChanged( QListWidgetItem* item )
1199 {
1200   QString newName = item->text();
1201   QString uniqueName = findUniqueName( newName, item );
1202   if ( uniqueName != newName ) {
1203     myMaterialList->blockSignals( true );
1204     item->setText( uniqueName );
1205     myMaterialList->blockSignals( false );
1206   }
1207   onChanged();
1208 }                               
1209
1210 /*!
1211   \brief Called when widget effect is changed
1212 */
1213 void GEOMToolsGUI_MaterialPropertiesDlg::onReflectionTypeToggled( bool theIsOn )
1214 {
1215   QGroupBox* anObj = (QGroupBox*)sender();
1216
1217   // Set an empty values for color and coefficient
1218   // of the checked/unchecked reflection type
1219   QColor c;
1220
1221
1222   // Make changes on front material tab
1223   if ( anObj == myAmbientGroupF ) {    
1224     myAmbientColorF->setColor( c );
1225     myAmbientCoefntF->setValue( 0.0 );
1226   }
1227   else if ( anObj == myDiffuseGroupF ) {
1228     myDiffuseColorF->setColor( c );
1229     myDiffuseCoefntF->setValue( 0.0 );
1230   }
1231   else if ( anObj == mySpecularGroupF ) {
1232     mySpecularColorF->setColor( c );
1233     mySpecularCoefntF->setValue( 0.0 );
1234   }
1235   else if ( anObj == myEmissionGroupF ) {
1236     myEmissionColorF->setColor( c );
1237     myEmissionCoefntF->setValue( 0.0 );
1238   }
1239
1240   // Make changes on back material tab    
1241   if ( anObj == myAmbientGroupB ) {    
1242     myAmbientColorB->setColor( c );
1243     myAmbientCoefntB->setValue( 0.0 );
1244   }
1245   else if ( anObj == myDiffuseGroupB ) {
1246     myDiffuseColorB->setColor( c );
1247     myDiffuseCoefntB->setValue( 0.0 );
1248   }
1249   else if ( anObj == mySpecularGroupB ) {
1250     mySpecularColorB->setColor( c );
1251     mySpecularCoefntB->setValue( 0.0 );
1252   }
1253   else if ( anObj == myEmissionGroupB ) {
1254     myEmissionColorB->setColor( c );
1255     myEmissionCoefntB->setValue( 0.0 );
1256   }
1257   
1258   emit( changed() );
1259 }