]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
"0021179: EDF 1654 SMESH GEOM: better look'n'feel" issue.
authorana <ana@opencascade.com>
Thu, 3 May 2012 14:09:12 +0000 (14:09 +0000)
committerana <ana@opencascade.com>
Thu, 3 May 2012 14:09:12 +0000 (14:09 +0000)
Material Properties.

src/GEOMGUI/GEOMGUI_Selection.cxx
src/GEOMGUI/GEOM_Displayer.cxx
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMToolsGUI/GEOMToolsGUI_1.cxx
src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.cxx

index 22cef5ef95f872a1bb855c699bdbd561b5a403ab..e0abcd4dccb4c08d0feb0736620ef151843bf4c1 100644 (file)
@@ -569,8 +569,9 @@ bool GEOMGUI_Selection::isPhysicalMaterial( const int idx ) const{
    bool found = false;
    QVariant v = visibleProperty( entry( idx ), MATERIAL_PROP );
    if ( v.canConvert<QString>() ) {
-     Material_Model* aModel = Material_Model::getMaterialModel( v.toString().split(DIGIT_SEPARATOR) );
-     res = aModel->isPhysical();
+     Material_Model material;
+     material.fromProperties( v.toString() );
+     res = material.isPhysical();
      found = true;
    }
 
index 6af5ba4e64f0e6eb3c9e3feaa050541ee618c2c0..112c65f89eb129c23cf64bf822e095405b8fb7d7 100644 (file)
@@ -961,31 +961,20 @@ void GEOM_Displayer::Update( SALOME_OCCPrs* prs )
           }
 
           // get material properties, set material
-          Material_Model* aModelF = 0;
+          Material_Model material;
           if ( useStudy ) {
             // Get material property from study and construct material model
-            QString aMaterialF = aPropMap.value(MATERIAL_PROP).toString();
-            QStringList aProps =  aMaterialF.split(DIGIT_SEPARATOR);
-            aModelF = Material_Model::getMaterialModel( aProps );
+            material.fromProperties( aPropMap.value(MATERIAL_PROP).toString() );
           } else {
             // Get material property from study and construct material model
-            aModelF = new Material_Model();
-            aModelF->fromResources( aResMgr, "Geometry" );
+           QString mname = aResMgr->stringValue( "Geometry", "material", "Plastic" );
+            material.fromResources( mname );
           }
 
-          // Set material property
-          QString aMaterialPropF = aModelF->getMaterialProperty();
-          aStudy->setObjectProperty( aMgrId, anIO->getEntry(), MATERIAL_PROP, aMaterialPropF );
-
-          // Get material properties from the model
-          Graphic3d_MaterialAspect aMatF = aModelF->getMaterialOCCAspect();
+          aStudy->setObjectProperty( aMgrId, anIO->getEntry(), MATERIAL_PROP, material.toProperties() );
 
           // Set material for the selected shape
-           AISShape->SetMaterial(aMatF);
-
-          // Release memory
-          if ( aModelF )
-            delete aModelF;
+         AISShape->SetMaterial( material.getMaterialOCCAspect() );
 
          if(HasWidth())
            aStudy->setObjectProperty( aMgrId, anIO->getEntry(), EDGE_WIDTH_PROP, GetWidth() );
@@ -1174,24 +1163,16 @@ void GEOM_Displayer::Update( SALOME_VTKPrs* prs )
           aGeomGActor->setDisplayMode(aDispModeId);
           aGeomGActor->SetDeflection(aPropMap.value(DEFLECTION_COEFF_PROP).toDouble());
 
-         // Get material property of the object stored in the study
-         QString aMaterialF = aPropMap.value(MATERIAL_PROP).toString();
-         QStringList aPropsF =  aMaterialF.split(DIGIT_SEPARATOR);
          // Create material model
-         Material_Model* aModelF = Material_Model::getMaterialModel( aPropsF );          
+         Material_Model material;
+         material.fromProperties( aPropMap.value(MATERIAL_PROP).toString() );    
          // Set material properties for the object
-         QString aMaterialPropF = aModelF->getMaterialProperty();
-         aStudy->setObjectProperty( aMgrId, anEntry, MATERIAL_PROP, aMaterialPropF );    
-         // Get material properties from the model
-         GEOM_VTKPropertyMaterial* aMatPropF = aModelF->getMaterialVTKProperty();
+         aStudy->setObjectProperty( aMgrId, anEntry, MATERIAL_PROP, material.toProperties() );   
          // Set the same front and back materials for the selected shape
-    std::vector<vtkProperty*> aProps;
-    aProps.push_back( (vtkProperty*) aMatPropF );
+         std::vector<vtkProperty*> aProps;
+         aProps.push_back( material.getMaterialVTKProperty() );
          aGeomGActor->SetMaterial(aProps);
          
-         // Release memory
-         delete aModelF;
-
           vtkFloatingPointType aColor[3] = {1.,0.,0.};
           if(aPropMap.contains(COLOR_PROP)) {
             QColor c = aPropMap.value(COLOR_PROP).value<QColor>();
@@ -1222,26 +1203,24 @@ void GEOM_Displayer::Update( SALOME_VTKPrs* prs )
               }
             }
           }
-          if ( !aMatPropF->GetPhysical() )
+          if ( !material.isPhysical() )
             aGeomGActor->SetColor(aColor[0],aColor[1],aColor[2]);
         }
        else {
          SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
          if ( aResMgr ) {
            // Create material model
-           Material_Model aModelF;
+           Material_Model material;
            // Get material name from resources
-           aModelF.fromResources( aResMgr, "Geometry" );
+           QString mname = aResMgr->stringValue( "Geometry", "material", "Plastic" );
+           material.fromResources( mname );
            // Set material properties for the object
-           QString aMaterialPropF = aModelF.getMaterialProperty();
-           aStudy->setObjectProperty( aMgrId, anEntry, MATERIAL_PROP, aMaterialPropF );            
-           // Get material properties from the model
-           GEOM_VTKPropertyMaterial* aMatPropF = aModelF.getMaterialVTKProperty();
-
+           aStudy->setObjectProperty( aMgrId, anEntry, MATERIAL_PROP, material.toProperties() );
            // Set material for the selected shape
-      std::vector<vtkProperty*> aProps;
-      aProps.push_back( (vtkProperty*) aMatPropF );
-           aGeomGActor->SetMaterial(aProps);     }
+           std::vector<vtkProperty*> aProps;
+           aProps.push_back( material.getMaterialVTKProperty() );
+           aGeomGActor->SetMaterial(aProps);
+         }
        }
       }
 
@@ -1935,10 +1914,10 @@ PropMap GEOM_Displayer::getDefaultPropertyMap(const QString& viewer_type) {
   aDefaultMap.insert( DEFLECTION_COEFF_PROP , aDC);
 
   //8. Material
-  Material_Model aModelF;
-  aModelF.fromResources( aResMgr, "Geometry" );
-  QString aMaterialF = aModelF.getMaterialProperty();
-  aDefaultMap.insert( MATERIAL_PROP , aMaterialF );  
+  Material_Model material;
+  QString mname = aResMgr->stringValue( "Geometry", "material", "Plastic" );
+  material.fromResources( mname );
+  aDefaultMap.insert( MATERIAL_PROP, material.toProperties() );  
 
   //9. Width of the edges
   aDefaultMap.insert( EDGE_WIDTH_PROP , aResMgr->integerValue("Geometry", "edge_width", 1));
index 507d9da6f3a0ea7bc01b44a5d93a85688c1938c7..931d352e4bb2182de07ec82df8f563f745be4ec0 100644 (file)
@@ -5228,35 +5228,27 @@ Would you like to continue?</translation>
     <name>GEOMToolsGUI_MaterialPropertiesDlg</name>
     <message>
         <source>MATERIAL_PROPERTIES_TLT</source>
-        <translation>Set Material Properties</translation>
-    </message>
-    <message>
-        <source>MATERIAL_BACK_CHK</source>
-        <translation>Enable back material</translation>
+        <translation>Color and Material Properties</translation>
     </message>
     <message>
-        <source>AMBIENT_GRP</source>
+        <source>REFLECTION_0</source>
         <translation>Ambient</translation>
     </message>
     <message>
-        <source>DIFFUSE_GRP</source>
+        <source>REFLECTION_1</source>
         <translation>Diffuse</translation>
     </message>
     <message>
-        <source>SPECULAR_GRP</source>
+        <source>REFLECTION_2</source>
         <translation>Specular</translation>
     </message>
     <message>
-        <source>EMISSION_GRP</source>
-        <translation>Emission</translation>
-    </message>
-    <message>
-        <source>COLOR</source>
-        <translation>Color:</translation>
+        <source>REFLECTION_3</source>
+        <translation>Emissive</translation>
     </message>
     <message>
-        <source>COEFFICIENT</source>
-        <translation>Coefficient:</translation>
+        <source>ENABLED</source>
+        <translation>Enabled</translation>
     </message>
     <message>
         <source>SHININESS</source>
@@ -5264,12 +5256,41 @@ Would you like to continue?</translation>
     </message>
     <message>
         <source>PHYSICAL</source>
-        <translation>Physical:</translation>
+        <translation>Physical</translation>
+    </message>
+    <message>
+        <source>ADD_MATERIAL</source>
+        <translation>Add Material</translation>
+    </message>
+    <message>
+        <source>DELETE_MATERIAL</source>
+        <translation>Remove material</translation>
+    </message>
+    <message>
+        <source>RENAME_MATERIAL</source>
+        <translation>Rename material</translation>
+    </message>
+    <message>
+        <source>CURRENT_MATERIAL</source>
+        <translation>[ Current ]</translation>
+    </message>
+    <message>
+        <source>CURRENT_COLOR</source>
+        <translation>Color</translation>
     </message>
     <message>
         <source>CUSTOM_MATERIAL</source>
         <translation>Custom material</translation>
     </message>
+    <message>
+        <source>QUE_CREATE_NEW_MATERIAL</source>
+        <translation>Changing properties of pre-defined material is not allowed.
+Do you want to create new material?</translation>
+    </message>
+    <message>
+        <source>QUE_REMOVE_MATERIAL</source>
+        <translation>Remove material %1?</translation>
+    </message>
     <message>
         <source>OK_BTN</source>
         <translation>&amp;OK</translation>
index fb801459a3b2f4a5036ecf80095c5f90b420ddc6..bff4b0b1a55e10865cef0e4fd83e78b4eaf2a0bb 100644 (file)
@@ -5228,47 +5228,68 @@ Voulez-vous continuer?</translation>
     <name>GEOMToolsGUI_MaterialPropertiesDlg</name>
     <message>
         <source>MATERIAL_PROPERTIES_TLT</source>
-        <translation>Définir une propriétés des matériaux</translation>
+        <translation>Color and Material Properties</translation>
     </message>
     <message>
-        <source>MATERIAL_BACK_CHK</source>
-        <translation>Activer l&apos;arrière du matériau</translation>
+        <source>REFLECTION_0</source>
+        <translation>Ambient</translation>
     </message>
     <message>
-        <source>AMBIENT_GRP</source>
-        <translation>Ambiante</translation>
+        <source>REFLECTION_1</source>
+        <translation>Diffuse</translation>
     </message>
     <message>
-        <source>DIFFUSE_GRP</source>
-        <translation>Diffuse</translation>
+        <source>REFLECTION_2</source>
+        <translation>Specular</translation>
+    </message>
+    <message>
+        <source>REFLECTION_3</source>
+        <translation>Emissive</translation>
     </message>
     <message>
-        <source>SPECULAR_GRP</source>
-        <translation>Spéculaire</translation>
+        <source>ENABLED</source>
+        <translation>Enabled</translation>
     </message>
     <message>
-        <source>EMISSION_GRP</source>
-        <translation>Emission</translation>
+        <source>SHININESS</source>
+        <translation>Shininess:</translation>
     </message>
     <message>
-        <source>COLOR</source>
-        <translation>Couleurs:</translation>
+        <source>PHYSICAL</source>
+        <translation>Physical</translation>
     </message>
     <message>
-        <source>COEFFICIENT</source>
-        <translation>Coefficient:</translation>
+        <source>ADD_MATERIAL</source>
+        <translation>Add Material</translation>
     </message>
     <message>
-        <source>SHININESS</source>
-        <translation>Brillance:</translation>
+        <source>DELETE_MATERIAL</source>
+        <translation>Remove material</translation>
     </message>
     <message>
-        <source>PHYSICAL</source>
-        <translation>Matériau physique (couleur imposée):</translation>
+        <source>RENAME_MATERIAL</source>
+        <translation>Rename material</translation>
+    </message>
+    <message>
+        <source>CURRENT_MATERIAL</source>
+        <translation>[ Current ]</translation>
+    </message>
+    <message>
+        <source>CURRENT_COLOR</source>
+        <translation>Color</translation>
     </message>
     <message>
         <source>CUSTOM_MATERIAL</source>
-        <translation>Matériau personnalisé</translation>
+        <translation>Custom material</translation>
+    </message>
+    <message>
+        <source>QUE_CREATE_NEW_MATERIAL</source>
+        <translation>Changing properties of pre-defined material is not allowed.
+Do you want to create new material?</translation>
+    </message>
+    <message>
+        <source>QUE_REMOVE_MATERIAL</source>
+        <translation>Remove material %1?</translation>
     </message>
     <message>
         <source>OK_BTN</source>
index 1a344a25453d01b721e800faf10dae466a43e29d..918a9f31647e61fcb111e1ef44e67943895f8439 100644 (file)
@@ -592,10 +592,9 @@ void GeometryGUI::OnGUIEvent( int id )
       LightApp_Preferences* pref = preferences();
       if ( pref ) {
        Material_ResourceMgr aMatResMgr;
-       QStringList aPerfMatNames = aMatResMgr.getPreferenceMaterialsNames();
        setPreferenceProperty( pref->rootItem()->findItem( tr( "PREF_MATERIAL" ), true )->id(),
                               "strings",
-                              aPerfMatNames );
+                              aMatResMgr.materials() );
       }
     }
   }
@@ -1814,8 +1813,7 @@ void GeometryGUI::createPreferences()
 
   // Set property for default material
   Material_ResourceMgr aMatResMgr;
-  QStringList aPrefMatNames = aMatResMgr.getPreferenceMaterialsNames();
-  setPreferenceProperty( material, "strings", aPrefMatNames );
+  setPreferenceProperty( material, "strings", aMatResMgr.materials() );
 
   // Set property vertex marker type
   QList<QVariant> aMarkerTypeIndicesList;
index 3442b4654b816612ec67fc5def9c317323aa1c1e..c0f1dbd7fab3461147057e98e65ea11e0b8bc6c4 100644 (file)
@@ -294,18 +294,11 @@ void GEOMToolsGUI::OnColor()
           if ( c.isValid() ) {
             SUIT_OverrideCursor();
             for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
-              QString defMatProp;
-              QVariant mp = appStudy->getObjectProperty(mgrId,It.Value()->getEntry(), MATERIAL_PROP, defMatProp);
-              QString matProp = mp.value<QString>();
-              QStringList aProps =  matProp.split(DIGIT_SEPARATOR);
-              Material_Model* aModelF = Material_Model::getMaterialModel( aProps );
-              bool aPhys = false;
-              if ( aModelF ) {
-                aPhys = aModelF->isPhysical();
-                // Release memory
-                delete aModelF;
-              }
-              if ( !aPhys ) {
+              QString matProp;
+              matProp = appStudy->getObjectProperty(mgrId,It.Value()->getEntry(), MATERIAL_PROP, matProp).toString();
+              Material_Model material;
+             material.fromProperties( matProp );
+              if ( !material.isPhysical() ) {
                 aView->SetColor( It.Value(), c );
                 appStudy->setObjectProperty(mgrId,It.Value()->getEntry(),COLOR_PROP, c);
               }
@@ -332,19 +325,12 @@ void GEOMToolsGUI::OnColor()
               OCCViewer_Viewer* vm = dynamic_cast<OCCViewer_Viewer*> ( window->getViewManager()->getViewModel() );
               Handle (AIS_InteractiveContext) ic = vm->getAISContext();
               for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
-                QString defMatProp;
-                QVariant mp = appStudy->getObjectProperty(mgrId,It.Value()->getEntry(), MATERIAL_PROP, defMatProp);
-                QString matProp = mp.value<QString>();
-                QStringList aProps =  matProp.split(DIGIT_SEPARATOR);
-                Material_Model* aModelF = Material_Model::getMaterialModel( aProps );
-                bool aPhys = false;
-                if ( aModelF ) {
-                  aPhys = aModelF->isPhysical();
-                  // Release memory
-                  delete aModelF;
-                }
+                QString matProp;
+                matProp = appStudy->getObjectProperty(mgrId,It.Value()->getEntry(), MATERIAL_PROP, matProp).toString();
+               Material_Model material;
+               material.fromProperties( matProp );
                 io = GEOMBase::GetAIS( It.Value(), true );
-                if ( !io.IsNull()  && !aPhys ) { // change color only for shapes with not physical type of material
+                if ( !io.IsNull()  && !material.isPhysical() ) { // change color only for shapes with not physical type of material
                   
                   if ( io->IsKind( STANDARD_TYPE(AIS_Shape) ) ) {
                     TopoDS_Shape theShape = Handle(AIS_Shape)::DownCast( io )->Shape();
index ed94f9cc07a4f8a60208ea20ad083a6cd2d43faf..e4b6171b96fa182f754ad59fd8e43f839e44b23d 100644 (file)
 
 #include "GEOMToolsGUI_MaterialPropertiesDlg.h"
 
-#include "Material_Model.h"
-#include "Material_ResourceMgr.h"
-
-#include <GeometryGUI.h>
-#include <GEOM_Constants.h>
-#include <GEOM_Displayer.h>
-#include <GEOM_Actor.h>
-
-#include <GEOMBase.h>
-
-#include <Basics_OCCTVersion.hxx>
-
-#include <SALOME_ListIO.hxx>
-#include <SALOME_ListIteratorOfListIO.hxx>
-
-#include <SVTK_Functor.h>
-#include <SVTK_Prs.h>
-#include <SVTK_ViewModel.h>
-#include <SVTK_ViewWindow.h>
-#include <SVTK_View.h>
-
-#include <VTKViewer_Algorithm.h>
-
-#include <OCCViewer_ViewModel.h>
+#include "GeometryGUI.h"
+#include "GEOM_Constants.h"
+#include "GEOM_VTKPropertyMaterial.hxx"
+#include "GEOMBase.h"
 
+#include <QtxColorButton.h>
 #include <SUIT_Desktop.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_ResourceMgr.h>
 #include <SUIT_Session.h>
 #include <SUIT_ViewManager.h>
-
+#include <SALOME_ListIteratorOfListIO.hxx>
+#include <OCCViewer_ViewModel.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SVTK_View.h>
+#include <LightApp_SelectionMgr.h>
 #include <SalomeApp_Application.h>
 #include <SalomeApp_Study.h>
+#include <SalomeApp_Tools.h>
 
-#include <LightApp_SelectionMgr.h>
-
-#include <QtxColorButton.h>
-#include <QtxDoubleSpinBox.h>
-
-// OCCT Includes
-#include <Graphic3d_AspectFillArea3d.hxx>
-
-// VTK includes
-#include <vtkRenderer.h>
-#include <vtkProperty.h>
-
-// QT Includes
-#include <QApplication>
-#include <QButtonGroup>
 #include <QCheckBox>
 #include <QGridLayout>
-#include <QGroupBox>
 #include <QHBoxLayout>
 #include <QKeyEvent>
 #include <QLabel>
-#include <QListWidget>
 #include <QMap>
-#include <QMessageBox>
+#include <QMenu>
 #include <QPushButton>
-#include <QSpinBox>
-#include <QTabWidget>
+#include <QSlider>
 #include <QVBoxLayout>
 
-#define MARGIN  9
-#define SPACING 6
+#define MARGIN  9  // layout spacing
+#define SPACING 6  // layout margin
+
+// convert floating point value to the integer equivalent
+#define COEF2INT(val) (int)(val*100.)
+// convert integer value to the floating point equivalent
+#define INT2COEF(val) (val/100.)
+
+/*!
+  \class GEOMToolsGUI_MaterialList
+  \brief Internal class, used to handle context menu event from materials list
+  \internal
+*/
+
+/*!
+  \brief Contructor
+ */
+GEOMToolsGUI_MaterialList::GEOMToolsGUI_MaterialList( QWidget* parent )
+  : QListWidget( parent )
+{}
+
+/*!
+  \brief Context menu event, emits context menu signal passing event as parameter
+*/
+void GEOMToolsGUI_MaterialList::contextMenuEvent( QContextMenuEvent* e )
+{
+  emit contextMenu( e );
+}
 
 /*!
   \class GEOMToolsGUI_MaterialPropertiesDlg
-  \brief GEOM material properties dialog box class.
+  \brief GEOM material properties dialog box class
 
-  The dialog box lists all GEOM materials available via the application and allows
-  user to create own materials.
+  The dialog box is used to set material properties for the presentation objects.
 */
 
 /*!
   \param parent parent widget
 */
 GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* parent )
-  : QtxDialog( parent, true, true, OK | Close | Apply | Help),
-    myResMgr( 0 )
+  : QtxDialog( parent, true, true, OK | Close | Apply | Help )
 {
   // Set title
   setWindowTitle( tr( "MATERIAL_PROPERTIES_TLT" ) );
 
-  // Set viewer type
-  SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
-  if ( app ) {
-    SUIT_ViewWindow* window = app->desktop()->activeWindow();
-    if ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() )
-      myViewerType = OCC;
-    else if ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() )
-      myViewerType = VTK;
-  }
-
-  // Create main layout
+  // main layout
   QVBoxLayout* main = new QVBoxLayout( mainFrame() );
-  main->setMargin( 0 ); main->setSpacing( SPACING );
+  main->setMargin( 0 );
+  main->setSpacing( SPACING );
 
-  // Create main widgets
-  QFrame* fr = new QFrame( this );
+  // add top-level frame box to enclose all main widgets (excluding buttons)
+  QFrame* fr = new QFrame( mainFrame() );
   fr->setFrameStyle( QFrame::Box | QFrame::Sunken );
-
   main->addWidget( fr );
 
-  // Create editor widgets
-  myMaterialList = new QListWidget( fr );
-  myMaterialTab  = new QTabWidget( fr );
+  // materials list widget
+  myMaterials = new GEOMToolsGUI_MaterialList( fr );
+  // properties widget
+  QWidget* propWidget = new QWidget( fr );
 
+  // layout main widgets
   QHBoxLayout* frLayout = new QHBoxLayout( fr );
-  frLayout->setMargin( MARGIN ); frLayout->setSpacing( SPACING );
-  frLayout->addWidget( myMaterialList );
-  frLayout->addWidget( myMaterialTab );
-  frLayout->setStretchFactor( myMaterialList, 1 );
-  frLayout->setStretchFactor( myMaterialTab, 2 );
-
-  // ======================= Create a tab for  material ======================= 
-  QWidget* w1 = new QWidget( myMaterialTab );
-  QVBoxLayout* vLayout1 = new QVBoxLayout( w1 );
-
-  QGridLayout* gLayout1 = new QGridLayout( w1 );
-  gLayout1->setMargin( MARGIN ); gLayout1->setSpacing( SPACING );
-
-  // ----------------- "Ambient" reflection type group box -----------------
-  myAmbientGroupF = new QGroupBox( tr( "AMBIENT_GRP" ), w1 );
-  myAmbientGroupF->setCheckable(true);
-  connect( myAmbientGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) ); 
-
-  // Ambient color
-  QLabel* ambColorLab1 = new QLabel( tr( "COLOR" ), myAmbientGroupF );
-  myAmbientColorF = new QtxColorButton( myAmbientGroupF );
-  myAmbientColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  connect( myAmbientColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
-
-  // Ambient coefficient
-  QLabel* ambCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), myAmbientGroupF );
-  myAmbientCoefntF = new QtxDoubleSpinBox( myAmbientGroupF );
-  myAmbientCoefntF->setMaximum(1);
-  myAmbientCoefntF->setSingleStep(0.05);
-  connect( myAmbientCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
-
-  // Ambient group box layout
-  QGridLayout* ambientLayout1 = new QGridLayout( myAmbientGroupF );
-  ambientLayout1->setMargin( MARGIN ); ambientLayout1->setSpacing( SPACING );
-  ambientLayout1->addWidget( ambColorLab1,       0, 0 );
-  ambientLayout1->addWidget( myAmbientColorF,    0, 1 );
-  ambientLayout1->addWidget( ambCoefficientLab1, 1, 0 );
-  ambientLayout1->addWidget( myAmbientCoefntF,   1, 1 );
-
-  // ----------------- "Diffuse" reflection type group box -----------------
-  myDiffuseGroupF = new QGroupBox( tr( "DIFFUSE_GRP" ), w1 );
-  myDiffuseGroupF->setCheckable(true);
-  connect( myDiffuseGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
-
-  // Diffuse color
-  QLabel* difColorLab1 = new QLabel( tr( "COLOR" ), myDiffuseGroupF );
-  myDiffuseColorF = new QtxColorButton( myDiffuseGroupF );
-  myDiffuseColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  connect( myDiffuseColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
-
-  // Diffuse coefficient
-  QLabel* difCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), myDiffuseGroupF );
-  myDiffuseCoefntF = new QtxDoubleSpinBox( myDiffuseGroupF );
-  myDiffuseCoefntF->setMaximum(1);
-  myDiffuseCoefntF->setSingleStep(0.05);
-  connect( myDiffuseCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
-
-  // Diffuse group box layout
-  QGridLayout* diffuseLayout1 = new QGridLayout( myDiffuseGroupF );
-  diffuseLayout1->setMargin( MARGIN ); diffuseLayout1->setSpacing( SPACING );
-  diffuseLayout1->addWidget( difColorLab1,       0, 0 );
-  diffuseLayout1->addWidget( myDiffuseColorF,    0, 1 );
-  diffuseLayout1->addWidget( difCoefficientLab1, 1, 0 );
-  diffuseLayout1->addWidget( myDiffuseCoefntF,   1, 1 );
-
-  // ----------------- "Specular" reflection type group box -----------------
-  mySpecularGroupF = new QGroupBox( tr( "SPECULAR_GRP" ), w1 );
-  mySpecularGroupF->setCheckable(true);
-  connect( mySpecularGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
-
-  // Specular color
-  QLabel* specColorLab1 = new QLabel( tr( "COLOR" ), mySpecularGroupF );
-  mySpecularColorF = new QtxColorButton( mySpecularGroupF );
-  mySpecularColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  connect( mySpecularColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
-
-  // Specular coefficient
-  QLabel* specCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), mySpecularGroupF );
-  mySpecularCoefntF = new QtxDoubleSpinBox( mySpecularGroupF );
-  mySpecularCoefntF->setMaximum(1);
-  mySpecularCoefntF->setSingleStep(0.05);
-  connect( mySpecularCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
-
-  // Specular group box layout
-  QGridLayout* specularLayout1 = new QGridLayout( mySpecularGroupF );
-  specularLayout1->setMargin( MARGIN ); specularLayout1->setSpacing( SPACING );
-  specularLayout1->addWidget( specColorLab1,       0, 0 );
-  specularLayout1->addWidget( mySpecularColorF,    0, 1 );
-  specularLayout1->addWidget( specCoefficientLab1, 1, 0 );
-  specularLayout1->addWidget( mySpecularCoefntF,   1, 1 );
-
-  // ----------------- "Emission" reflection type group box -----------------
-  myEmissionGroupF = new QGroupBox( tr( "EMISSION_GRP" ), w1 );
-  myEmissionGroupF->setCheckable(true);
-  connect( myEmissionGroupF, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) );
-
-  // Emission color
-  QLabel* emisColorLab1 = new QLabel( tr( "COLOR" ), myEmissionGroupF );
-  myEmissionColorF = new QtxColorButton( myEmissionGroupF );
-  myEmissionColorF->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  connect( myEmissionColorF, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); 
-
-  // Emission coefficient
-  QLabel* emisCoefficientLab1 = new QLabel( tr( "COEFFICIENT" ), myEmissionGroupF );
-  myEmissionCoefntF = new QtxDoubleSpinBox( myEmissionGroupF );
-  myEmissionCoefntF->setMaximum(1);
-  myEmissionCoefntF->setSingleStep(0.05);
-  connect( myEmissionCoefntF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
-
-  // Emission group box layout
-  QGridLayout* emissionLayout1 = new QGridLayout( myEmissionGroupF );
-  emissionLayout1->setMargin( MARGIN ); emissionLayout1->setSpacing( SPACING );
-  emissionLayout1->addWidget( emisColorLab1,       0, 0 );
-  emissionLayout1->addWidget( myEmissionColorF,    0, 1 );
-  emissionLayout1->addWidget( emisCoefficientLab1, 1, 0 );
-  emissionLayout1->addWidget( myEmissionCoefntF,   1, 1 );
-
-  // Erase emission group in case of VTK viewer
-  if ( myViewerType == VTK )
-    myEmissionGroupF->hide();
-
-  // Add group boxes to the main grid layout of the frame with material properties
-  gLayout1->addWidget( myAmbientGroupF,  0, 0 );
-  gLayout1->addWidget( myDiffuseGroupF,  0, 1 );
-  gLayout1->addWidget( mySpecularGroupF, 1, 0 );
-  gLayout1->addWidget( myEmissionGroupF, 1, 1 );
-
-  // Shininess and type
-  QLabel* shininessLab1 = new QLabel( tr( "SHININESS" ), w1 );
-  myShininessF = new QtxDoubleSpinBox( w1 );
-  myShininessF->setMaximum(1);
-  myShininessF->setSingleStep(0.05);
-  connect( myShininessF, SIGNAL( valueChanged( double ) ), this, SIGNAL( materialChanged() ) );
-  
-  QLabel* physicalLab1 = new QLabel( tr( "PHYSICAL" ), w1 );
-  myMaterialPhysicalCheck = new QCheckBox( w1 );
-  myMaterialPhysicalCheck->setCheckable( true );
-  connect( myMaterialPhysicalCheck, SIGNAL( toggled( bool ) ), this, SLOT( onReflectionTypeToggled( bool ) ) ); 
-
-  // Shininess and type layout
-  QGridLayout* shLayout1 = new QGridLayout( w1 );
-  shLayout1->setMargin( MARGIN ); shLayout1->setSpacing( SPACING );
-  shLayout1->addWidget( shininessLab1,           0, 0 );
-  shLayout1->addWidget( myShininessF,            0, 1 );
-  shLayout1->addWidget( physicalLab1,            1, 0 );
-  shLayout1->addWidget( myMaterialPhysicalCheck, 1, 1 );
-
-
-  // Fill initial vertical layout of the reflection type group box
-  vLayout1->addLayout( gLayout1 );
-  vLayout1->addLayout( shLayout1 );
-  vLayout1->addStretch();
-
-  // Add tabs to material tab widget
-  myMaterialTab->addTab( w1, tr( "Material" ) );
-
-  // Initialize dialog box
-  setFocusProxy( fr );
+  frLayout->setMargin( MARGIN );
+  frLayout->setSpacing( SPACING );
+  frLayout->addWidget( myMaterials );
+  frLayout->addWidget( propWidget );
+
+  // layout for material properties widgets
+  QGridLayout* propLayout = new QGridLayout( propWidget );
+  propLayout->setMargin( 0 );
+  propLayout->setSpacing( SPACING );
+
+  // current color widgets
+  myColorLab = new QLabel( tr( "CURRENT_COLOR" ), propWidget );
+  myColor = new QtxColorButton( propWidget );
+
+  // "physical" material type widgets
+  myPhysical = new QCheckBox( tr( "PHYSICAL" ), propWidget );
+
+  // reflection components widgets
+  for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
+  {
+    Reflection refl;
+
+    refl.label = new QLabel( tr( QString( "REFLECTION_%1" ).arg( i ).toLatin1().data() ), propWidget );
+
+    refl.color = new QtxColorButton( propWidget );
+    //refl.color->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+    refl.coef = new QSlider( Qt::Horizontal, propWidget );
+    refl.coef->setRange( 0, 100 );
+    refl.coef->setSingleStep( 1 );
+    refl.coef->setPageStep( 10 );
+
+    refl.enabled = new QCheckBox( tr( "ENABLED" ), propWidget );
+
+    myReflection << refl;
+  }
+
+  // shininess widgets
+  QLabel* shininessLab = new QLabel( tr( "SHININESS" ), propWidget );
+  myShininess = new QSlider( Qt::Horizontal, propWidget );
+  myShininess->setRange( 0, 100 );
+  myShininess->setSingleStep( 1 );
+  myShininess->setPageStep( 10 );
+
+  // separator widgets
+  QFrame* line1 = new QFrame( propWidget );
+  line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+  QFrame* line2 = new QFrame( propWidget );
+  line2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+  // add / remove material buttons
+  myAddButton = new QPushButton( tr( "ADD_MATERIAL" ),    propWidget );
+  myDelButton = new QPushButton( tr( "DELETE_MATERIAL" ), propWidget );
+
+  // buttons layout
+  QHBoxLayout* btnLayout = new QHBoxLayout;
+  btnLayout->setMargin( 0 );
+  btnLayout->setSpacing( SPACING );
+  btnLayout->addWidget( myAddButton );
+  btnLayout->addWidget( myDelButton );
+
+  // layout all properties widgets together
+  propLayout->addWidget( myColorLab, 0, 0 );
+  propLayout->addWidget( myColor,    0, 1 );
+  propLayout->addWidget( line1, 1, 0, 1, 4 );
+  propLayout->addWidget( myPhysical,     2, 0 );
+  for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) {
+    propLayout->addWidget( myReflection[i].label,   i+3, 0 );
+    propLayout->addWidget( myReflection[i].color,   i+3, 1 );
+    propLayout->addWidget( myReflection[i].coef,    i+3, 2 );
+    propLayout->addWidget( myReflection[i].enabled, i+3, 3 );
+  }
+  propLayout->addWidget( shininessLab,   7, 0 );
+  propLayout->addWidget( myShininess,    7, 2 );
+  propLayout->addWidget( line2, 8, 0, 1, 4 );
+  propLayout->setRowStretch( 9, 5 );
+  propLayout->addLayout( btnLayout, 10, 0, 1, 4 );
+
+  // initialize dialog box
   setButtonPosition( Right, Close );
-  setDialogFlags( AlignOnce );
-  myMaterialList->setEditTriggers( QAbstractItemView::EditKeyPressed );
-  myMaterialList->installEventFilter( this );
 
-  // ! RESOURCES
-  QStringList globalMaterials = resourceMgr()->materials( Material_ResourceMgr::Global );
-  QStringList userMaterials = resourceMgr()->materials( Material_ResourceMgr::User );
+  // fill in the list of materials
+  QStringList globalMaterials = myResourceMgr.materials( Material_ResourceMgr::Global );
+  QStringList userMaterials   = myResourceMgr.materials( Material_ResourceMgr::User );
 
   QListWidgetItem* item;
 
-  // Current material
-  item = new QListWidgetItem( tr( "[ Current ]" ) );
+  // - current material
+  item = new QListWidgetItem( tr( "CURRENT_MATERIAL" ) );
   item->setForeground( QColor( Qt::red ) );
   item->setData( TypeRole, QVariant( Current ) );
-  myMaterialList->addItem( item );
-  // Default material
-  item = new QListWidgetItem( tr( "[ Default ]" ) );
-  item->setForeground( QColor( Qt::green ) );
-  item->setData( TypeRole, QVariant( Default ) );
-  myMaterialList->addItem( item );  
-  // ! RESOURCES
-  // Global materials
-  foreach ( QString sname, globalMaterials ) {
-    item = new QListWidgetItem( sname );
+  myMaterials->addItem( item );
+  // - global materials
+  foreach( QString material, globalMaterials ) {
+    item = new QListWidgetItem( material );
     item->setForeground( QColor( Qt::blue ) );
     item->setData( TypeRole, QVariant( Global ) );
-    item->setData( NameRole, QVariant( sname ) );
-    myMaterialList->addItem( item );
+    item->setData( NameRole, QVariant( material ) );
+    myMaterials->addItem( item );
   }
-  // ! RESOURCES
-  // User materials
-  foreach ( QString sname, userMaterials ) {
-    item = new QListWidgetItem( sname );
+  // - user materials
+  foreach ( QString material, userMaterials ) {
+    item = new QListWidgetItem( material );
     item->setData( TypeRole, QVariant( User ) );
-    item->setData( NameRole, QVariant( sname ) );
+    item->setData( NameRole, QVariant( material ) );
     item->setFlags( item->flags() | Qt::ItemIsEditable );
-    myMaterialList->addItem( item );
+    myMaterials->addItem( item );
   }
-  
-  // Connect signals
-  connect( myMaterialList,      SIGNAL( itemSelectionChanged() ),
-          this,                SLOT( onMaterialChanged() ) );
-  connect( myMaterialList,      SIGNAL( itemChanged( QListWidgetItem* ) ),       
-           this,                SLOT( onItemChanged( QListWidgetItem* ) ) );
-  connect( myMaterialList,      SIGNAL( itemDoubleClicked( QListWidgetItem* ) ), 
-           this,                SLOT( onApply() ) );
-
-  connect( this, SIGNAL( changed() ),      this, SIGNAL( materialChanged() ) );
-  connect( this, SIGNAL( materialChanged() ), this, SLOT( onChanged() ) );
-  
+  // install event filter to the materials list to process key press events
+  myMaterials->installEventFilter( this );
+
+  // connect signals
+  // note: all widgets, that change material properties, are connected to the common signal
+  // changed(), instead of connecting directly to the slot - this allows easy temporary blocking 
+  // of the change signal
+  connect( myPhysical, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) ); 
+  for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) {
+    connect( myReflection[i].color,   SIGNAL( changed( QColor ) ),   this, SIGNAL( changed() ) );
+    connect( myReflection[i].coef,    SIGNAL( valueChanged( int ) ), this, SIGNAL( changed() ) );
+    connect( myReflection[i].enabled, SIGNAL( toggled( bool ) ),     this, SIGNAL( changed() ) );
+  }
+  connect( myShininess, SIGNAL( valueChanged( int ) ), this, SIGNAL( changed() ) );
+  connect( myMaterials, SIGNAL( itemSelectionChanged() ),
+           this,        SLOT( onMaterialChanged() ) );
+  connect( myMaterials, SIGNAL( itemChanged( QListWidgetItem* ) ),
+           this,        SLOT( onItemChanged( QListWidgetItem* ) ) );
+  connect( myMaterials, SIGNAL( contextMenu( QContextMenuEvent* ) ),
+           this,        SLOT( onContextMenu( QContextMenuEvent* ) ) );
+  connect( myAddButton, SIGNAL( clicked() ), this, SLOT( onAddMaterial() ) );
+  connect( myDelButton, SIGNAL( clicked() ), this, SLOT( onDeleteMaterial() ) );
   connect( this, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
   connect( this, SIGNAL( dlgHelp() ),  this, SLOT( onHelp() ) );
+  connect( this, SIGNAL( changed() ),  this, SLOT( onChanged() ) );
 
-  // Initialize current material models of the selected shape
-  if ( app ) {
-    LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
-    if ( aSelMgr ) {
-      SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
-      if( aStudy ) {
-       SALOME_ListIO selected;
-       aSelMgr->selectedObjects( selected );
-
-       Handle(SALOME_InteractiveObject) FirstIOS =  selected.First();
-       if ( !FirstIOS.IsNull() ) {
-         SUIT_ViewWindow* window = app->desktop()->activeWindow();
-         int aMgrId = window->getViewManager()->getGlobalId();
-         
-         QString aMaterialF;
-
-         for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
-
-           PropMap aPropMap = aStudy->getObjectPropMap( aMgrId, It.Value()->getEntry() );
-           aMaterialF = aPropMap.value(MATERIAL_PROP).toString();          
-             
-           if ( !aMaterialF.isEmpty() ) {
-             
-             QStringList aPropsF = aMaterialF.split(DIGIT_SEPARATOR);
-             
-             myCurrentModelF = Material_Model::getMaterialModel( aPropsF );            
-                     
-             break;
-           }
-         }
-           
-         if ( aMaterialF.isEmpty() ) {
-           myCurrentModelF = new Material_Model();
-           myCurrentModelF->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry" );
-    }
-  }
+  // initialize current material model according to the selection
+  myColor->setColor( SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ) );
+  myCurrentModel.fromResources( SUIT_Session::session()->resourceMgr()->stringValue( "Geometry", "material", "Plastic" ) );
+  SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+  LightApp_SelectionMgr* selMgr = app->selectionMgr();
+  if ( study ) {
+    SALOME_ListIO selected;
+    selMgr->selectedObjects( selected );
+    if ( selected.Extent() > 0 ) {
+      Handle(SALOME_InteractiveObject) io = selected.First();
+      if ( !io.IsNull() ) {
+       SUIT_ViewWindow* window = app->desktop()->activeWindow();
+       if ( window ) {
+         int mgrId = window->getViewManager()->getGlobalId();
+         PropMap propMap = study->getObjectPropMap( mgrId, io->getEntry() );
+         QString matProp = propMap.value(MATERIAL_PROP).toString();        
+         if ( !matProp.isEmpty() )
+           myCurrentModel.fromProperties( matProp );
+         QColor c = propMap.value(COLOR_PROP).value<QColor>();
+         if ( c.isValid() )
+           myColor->setColor( c );
+       }
       }
     }
   }
-
-  myMaterialList->setCurrentRow( 0 );
-  myMaterialListFId = 0;
-
-  myHelpFileName = "material_page.html";
+  
+  // finally activate current material properties
+  myMaterials->setCurrentRow( 0 );
 }
 
 /*!
@@ -396,8 +288,6 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget*
 */
 GEOMToolsGUI_MaterialPropertiesDlg::~GEOMToolsGUI_MaterialPropertiesDlg()
 {
-  if ( myCurrentModelF )
-    delete myCurrentModelF;
 }
 
 /*!
@@ -410,158 +300,68 @@ void GEOMToolsGUI_MaterialPropertiesDlg::accept()
 }
 
 /*!
-  \brief Process key press event
+  \brief Event filter
   \param o sender
-  \param e key event
+  \param e event
 */
 bool GEOMToolsGUI_MaterialPropertiesDlg::eventFilter( QObject* o, QEvent* e )
 {
-  if ( o == myMaterialList && e->type() == QEvent::KeyPress ) {
+  // process key press event from materials list
+  if ( o == myMaterials && e->type() == QEvent::KeyPress ) {
     QKeyEvent* ke = (QKeyEvent*)e;
     if ( ke->key() == Qt::Key_Delete ) {
-      QListWidgetItem* item = myMaterialList->currentItem();
-      if ( item && item->data( TypeRole ).toInt() == User ) {
-       if ( QMessageBox::question( this,
-                                   tr( "Delete user material" ),
-                                   tr( "Remove material %1?" ).arg( item->text() ),
-                                   QMessageBox::Yes | QMessageBox::No,
-                                   QMessageBox::Yes ) == QMessageBox::Yes ) {
-         resourceMgr()->remove( item->data( NameRole ).toString() );
-         resourceMgr()->save();
-         delete item;
-       }
-      }
+      onDeleteMaterial();
     }
   }
   return QtxDialog::eventFilter( o, e );
 }
 
 /*!
-  \brief Get GEOM materials resource manager
-  \return materials resource manager
-*/
-Material_ResourceMgr* GEOMToolsGUI_MaterialPropertiesDlg::resourceMgr()
-{
-  if ( !myResMgr )
-    myResMgr = new Material_ResourceMgr();
-  return myResMgr;
-}
-
-/*!
-  \brief Initialize dialog box fields from material model
+  \brief Initialize dialog box widgets from material model
   \param model material model
 */
-void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( Material_Model* model)
+void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( const Material_Model& model )
 {
-  if ( !model ) return;
-  bool isReflectionTypeActive; 
-  // Ambient reflection type
-  isReflectionTypeActive = model->hasAmbientReflection();
-  myAmbientGroupF->setChecked( isReflectionTypeActive );
-  if ( isReflectionTypeActive ) {
-    // Load ambient color
-    myAmbientColorF->setColor( model->color(Material_Model::Ambient) );
-    // Load ambient coefficient
-    myAmbientCoefntF->setValue( model->coefficient(Material_Model::Ambient) );
-  }
-  
-  // Diffuse reflection type
-  isReflectionTypeActive = model->hasDiffuseReflection();
-  myDiffuseGroupF->setChecked( isReflectionTypeActive );
-  if ( isReflectionTypeActive ) {
-    // Load diffuse color
-    myDiffuseColorF->setColor( model->color(Material_Model::Diffuse) );
-    // Load diffuse coefficient
-    myDiffuseCoefntF->setValue( model->coefficient(Material_Model::Diffuse) );
-  }
-  
-  // Specular reflection type
-  isReflectionTypeActive = model->hasSpecularReflection();
-  mySpecularGroupF->setChecked( isReflectionTypeActive );
-  if ( isReflectionTypeActive ) {
-    // Load specular color
-    mySpecularColorF->setColor( model->color(Material_Model::Specular) );
-    // Load specular coefficient
-    mySpecularCoefntF->setValue( model->coefficient(Material_Model::Specular) );
+  // reflection components
+  for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
+  {
+    myReflection[i].color->setColor( model.color( (Material_Model::ReflectionType)i ) );
+    myReflection[i].coef->setValue( COEF2INT( model.reflection( (Material_Model::ReflectionType)i ) ) );
+    myReflection[i].enabled->setChecked( model.hasReflection( (Material_Model::ReflectionType)i ) );
   }
   
-  // Emission reflection type
-  isReflectionTypeActive = model->hasEmissionReflection();
-  myEmissionGroupF->setChecked( isReflectionTypeActive );
-  if ( isReflectionTypeActive ) {
-    // Load emission color
-    myEmissionColorF->setColor( model->color(Material_Model::Emission) );
-    // Load emission coefficient
-    myEmissionCoefntF->setValue( model->coefficient(Material_Model::Emission) );
-  }
-  
-  // Shininess
-  myShininessF->setValue( model->shininess() );
+  // shininess
+  myShininess->setValue( COEF2INT( model.shininess() ) );
 
-  //Physical
-  myMaterialPhysicalCheck->setChecked( model->isPhysical() );
-  
+  // type (physical or no)
+  myPhysical->setChecked( model.isPhysical() );
 }
  
 /*!
-  \brief Save values from dialog box fields material model
-  \param model material model to be filled
+  \brief Save values from dialog box widgets to material model
+  \param model material model to be filled in
 */
-void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model* model ) const
+void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model& model ) const
 {
-  if ( !model ) return;
-    
-  // "Ambient" reflection type
-  if ( myAmbientGroupF->isChecked() ) {
-    model->setColor( Material_Model::Ambient, myAmbientColorF->color() );
-    model->setCoefficient( Material_Model::Ambient, myAmbientCoefntF->value() );
-  }
-  else {
-    model->removeColor( Material_Model::Ambient );
-    model->removeCoefficient( Material_Model::Ambient );
+  // type (physical or no)
+  model.setPhysical( myPhysical->isChecked() );
+
+  // shininess
+  model.setShininess( INT2COEF( myShininess->value() ) );
+
+  // reflection components
+  for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
+  {
+    model.setColor     ( (Material_Model::ReflectionType)i, myReflection[i].color->color() );
+    model.setReflection( (Material_Model::ReflectionType)i, INT2COEF( myReflection[i].coef->value() ) );
+    model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].enabled->isChecked() );
   }
-  
-  // "Diffuse" reflection type
-  if ( myDiffuseGroupF->isChecked() ) {
-    model->setColor( Material_Model::Diffuse, myDiffuseColorF->color() );
-    model->setCoefficient( Material_Model::Diffuse, myDiffuseCoefntF->value() );
-  }
-  else {
-    model->removeColor( Material_Model::Diffuse );
-    model->removeCoefficient( Material_Model::Diffuse );
-  }
-  
-  // "Specular" reflection type
-  if ( mySpecularGroupF->isChecked() ) {
-    model->setColor( Material_Model::Specular, mySpecularColorF->color() );
-    model->setCoefficient( Material_Model::Specular, mySpecularCoefntF->value() );
-  }
-  else {
-    model->removeColor( Material_Model::Specular );
-    model->removeCoefficient( Material_Model::Specular );
-  }
-  
-  // "Emission" reflection type
-  if ( myEmissionGroupF->isChecked() ) {
-    model->setColor( Material_Model::Emission, myEmissionColorF->color() );
-    model->setCoefficient( Material_Model::Emission, myEmissionCoefntF->value() );
-  }
-  else {
-    model->removeColor( Material_Model::Emission );
-    model->removeCoefficient( Material_Model::Emission );
-  }
-  
-  // Shininess
-  model->setShininess( myShininessF->value() );
-
-  //Type
-  model->setPhysical( myMaterialPhysicalCheck->isChecked()? true : false ); 
 }
 
 /*!
   \brief Find unique name for the material name
   \param name material name template
-  \param item if not 0, used to be ignored when browsing through items list
+  \param item the item to be ignored when browsing through the materials list
   \param addSuffix if \c true, the integrer suffix is always added to the material name (otherwise
   suffix is added only if item name is not unique)
   \return new unique material name
@@ -570,13 +370,13 @@ QString GEOMToolsGUI_MaterialPropertiesDlg::findUniqueName( const QString& name,
 {
   bool found = false;
   int idx = 0;
-  for( int i = 2; i < myMaterialList->count(); i++ ) {
-    if ( item == myMaterialList->item( i ) ) continue;
-    QString iname = myMaterialList->item( i )->text();
+  for( int i = 1; i < myMaterials->count(); i++ ) {
+    if ( item == myMaterials->item( i ) ) continue;
+    QString iname = myMaterials->item( i )->text();
     if ( iname == name ) {
       found = true;
     }
-    else {
+    else if ( iname.startsWith( name ) ) {
       iname = iname.mid( name.length() ).trimmed();
       bool ok = false;
       int nx = iname.toInt( &ok );
@@ -592,122 +392,89 @@ QString GEOMToolsGUI_MaterialPropertiesDlg::findUniqueName( const QString& name,
 void GEOMToolsGUI_MaterialPropertiesDlg::onApply()
 {  
   // save user materials
-  resourceMgr()->save();
+  myResourceMgr.save();
 
-  toModel( myCurrentModelF );
+  // store selected material properties in the current model
+  toModel( myCurrentModel );
 
   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
-  if ( !app )
-    return;
-  LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
-  if ( !aSelMgr )
-    return;
-  
-  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
-  
-  if(!aStudy)
-    return;
+  LightApp_SelectionMgr* selMgr = app->selectionMgr();
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
   
+  if ( !study ) return;
+
+  // get selection
   SALOME_ListIO selected;
-  aSelMgr->selectedObjects( selected );
-  if ( selected.IsEmpty() )
-    return;
-
-  Handle(SALOME_InteractiveObject) FirstIOS =  selected.First();
-  if ( FirstIOS.IsNull() )
-    return;
-        
+  selMgr->selectedObjects( selected );
+  if ( selected.IsEmpty() ) return;
+
   SUIT_ViewWindow* window = app->desktop()->activeWindow();
-  int aMgrId = window->getViewManager()->getGlobalId();
+  int mgrId = window->getViewManager()->getGlobalId();
 
-  // Parse material properties and form a string for persistent purpose
-  QString aMaterialF = myCurrentModelF->getMaterialProperty();
+  // convert current material properties to the string representation
+  QString prop = myCurrentModel.toProperties();
  
-  if ( myViewerType == VTK ) {    
-    // Get material properties from the current model
-    /*
-    vtkProperty* aPropertyF;
-    if ( !unsetMaterial )
-      aPropertyF = myCurrentModelF->getMaterialVTKProperty();
-    */
-    GEOM_VTKPropertyMaterial* aPropertyF = myCurrentModelF->getMaterialVTKProperty();
-
+  if ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() ) {
+    // for VTK viewer
     SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( window );
     if ( !vtkVW )
       return;
+
     SVTK_View* aView = vtkVW->getView();
 
-    SUIT_OverrideCursor();
-    for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
+    // get VTK material properties from the current model
+    GEOM_VTKPropertyMaterial* vtkProp = myCurrentModel.getMaterialVTKProperty();
 
-      /*
-      if ( unsetMaterial || aMaterialF.isEmpty() )
-       // Unset material for the selected shape
-       aisShape->UnsetMaterial();
-      else
-       // Set material for the selected shape
-      */
-           aView->SetMaterial( It.Value(), (vtkProperty*) aPropertyF );
-      // Restore color for not physical materials
-      PropMap aPropMap  =  aStudy->getObjectPropMap( aMgrId, It.Value()->getEntry() );
-      if( !myMaterialPhysicalCheck->isChecked() && aPropMap.contains(COLOR_PROP) ) {
-        aView->SetColor(It.Value(), aPropMap.value(COLOR_PROP).value<QColor>());
-      }
-      int aDispModeId = aPropMap.value(DISPLAY_MODE_PROP).toInt();
-      aView->SetDisplayMode(aDispModeId);
-           // eWireframe - 0, eShading - 1, eShadingWithEdges - 3
+    SUIT_OverrideCursor wc();
 
-      // Persistent
-      aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), MATERIAL_PROP, aMaterialF );
-    } // for...
+    for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
+      // set material property to the presentation
+      aView->SetMaterial( It.Value(), vtkProp );
+      // store chosen material in the property map
+      study->setObjectProperty( mgrId, It.Value()->getEntry(), MATERIAL_PROP, prop );
+      // set correct color for the non-physical material
+      if ( !myCurrentModel.isPhysical() ) {
+        aView->SetColor( It.Value(), myColor->color() );
+       study->setObjectProperty( mgrId, It.Value()->getEntry(), COLOR_PROP, myColor->color() );
+      }
+    }
     aView->Repaint();
     GeometryGUI::Modified();
-  } // if ( VTK )
-        
-  else if ( myViewerType == OCC ) {
-    // Get material properties from the current model
-    /*
-    Graphic3d_MaterialAspect aMatF;
-    if ( !unsetMaterial )
-      aMatF = myCurrentModelF->getMaterialOCCAspect();
-    */
-    Graphic3d_MaterialAspect aMatF = myCurrentModelF->getMaterialOCCAspect();
-
-    Handle(GEOM_AISShape) aisShape;
-    
-    SUIT_OverrideCursor();
+  }
+  else if ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() ) {    
+    // for OCC viewer
     OCCViewer_Viewer* vm = dynamic_cast<OCCViewer_Viewer*>( window->getViewManager()->getViewModel() );
     if ( !vm )
       return;
 
-    GEOMBase* gb = new GEOMBase();
-
     Handle(AIS_InteractiveContext) ic = vm->getAISContext();
-    for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
-      aisShape = gb->ConvertIOinGEOMAISShape( It.Value(), true );
-      if ( !aisShape.IsNull() ) {
 
-       if(!aisShape->HasInteractiveContext())
-         aisShape->SetContext(ic);
+    // get OCC material aspect from the current model
+    Graphic3d_MaterialAspect occAspect = myCurrentModel.getMaterialOCCAspect();
 
-       /*
-       if ( unsetMaterial || aMaterialF.isEmpty() )
-         // Unset material for the selected shape
-         aisShape->UnsetMaterial();
-       else
-       */
-       aisShape->SetMaterial(aMatF);
+    SUIT_OverrideCursor wc();
 
-       if (aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/)
+    printf("material prop:%s\n", qPrintable(prop));
+    for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
+      Handle(GEOM_AISShape) aisShape = GEOMBase::ConvertIOinGEOMAISShape( It.Value(), true );
+      if ( !aisShape.IsNull() ) {
+       // set material property to the presentation
+       aisShape->SetMaterial( occAspect );
+       // store chosen material in the property map
+       study->setObjectProperty( mgrId, It.Value()->getEntry(), MATERIAL_PROP, prop );
+       // set correct color for the non-physical material
+       if ( !myCurrentModel.isPhysical() ) {
+         aisShape->SetShadingColor( SalomeApp_Tools::color( myColor->color() ) );
+         study->setObjectProperty( mgrId, It.Value()->getEntry(), COLOR_PROP, myColor->color() );
          ic->RecomputePrsOnly( aisShape, Standard_False );
-
-       // Persistent   
-       aStudy->setObjectProperty( aMgrId, It.Value()->getEntry(), MATERIAL_PROP, aMaterialF );
+       }
+       //if ( aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/)
+       ic->Redisplay( aisShape, Standard_False );
       }
-    } // for...    
+    }
     ic->UpdateCurrentViewer();
     GeometryGUI::Modified();
-  } // if ( OCC )
+  }
 }
 
 /*!
@@ -716,22 +483,7 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onApply()
 void GEOMToolsGUI_MaterialPropertiesDlg::onHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) {
-    GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
-    app->onHelpContextModule(aGeomGUI ? app->moduleName(aGeomGUI->moduleName()) : QString(""), myHelpFileName);
-  }
-  else {
-                QString platform;
-#ifdef WIN32
-                platform = "winapplication";
-#else
-                platform = "application";
-#endif
-    SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
-                             QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                             arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
-                             QObject::tr("BUT_OK"));
-  }  
+  app->onHelpContextModule( "GEOM", "material_page.html" );
 }
 
 /*!
@@ -739,40 +491,28 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onHelp()
 */
 void GEOMToolsGUI_MaterialPropertiesDlg::onMaterialChanged()
 {
-  blockSignals( true );
+  // get currently selected item
+  QListWidgetItem* item = myMaterials->currentItem();
+  if ( !item ) return;
+
+  bool blocked = blockSignals( true );
 
-  QListWidgetItem* item = myMaterialList->currentItem();
   int type = item->data( TypeRole ).toInt();
-  
-  Material_Model* model = 0;
-
-  myMaterialListFId = myMaterialList->currentRow();
-
-  switch ( type ) {    
-  case Current:
-    // current material
-    model = myCurrentModelF;
-    break;    
-  case Default:
-    // default material
-    model = new Material_Model();
-    model->fromResources( SUIT_Session::session()->resourceMgr(), "Geometry" );
-    break;    
-  case Global:
-  case User:
-    // global material, user material
-    model = new Material_Model();
-    model->fromResources( resourceMgr(), item->data( NameRole ).toString() );
-    break;
-  default:
-    break;
+  if ( type == Current ) {
+    // initialize widgets from current material model
+    fromModel( myCurrentModel );
+  }
+  else {
+    // initialize widgets from chosen material model (using resources manager)
+    Material_Model model;
+    model.fromResources( item->data( NameRole ).toString(), &myResourceMgr );
+    fromModel( model );
   }
 
-  fromModel( model );
-  if ( type != Current )
-    delete model;
+  blockSignals( blocked );
 
-  blockSignals( false );
+  // update buttons state
+  updateState();
 }
 
 /*!
@@ -780,52 +520,55 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onMaterialChanged()
 */
 void GEOMToolsGUI_MaterialPropertiesDlg::onChanged()
 {
-  QListWidgetItem* item = myMaterialList->currentItem();
+  // get currently selected item
+  QListWidgetItem* item = myMaterials->currentItem();
   int type = item->data( TypeRole ).toInt();
+  if ( !item ) return;
 
-  // for the current and user schemas do not perform any actions
   if ( type == Current ) {    
-    Material_Model model = *(myCurrentModelF);
-    toModel( &model );
-    model.save( 0, QString() );
-    blockSignals( true );
-    fromModel( &model );
-    blockSignals( false );    
+    // for the current model do not perform any actions except store changed values
+    toModel( myCurrentModel );
   }
   else if ( type == User ) {    
+    // for the user model, simply store the changes in the resource manager
     Material_Model model;
-    toModel( &model );
+    toModel( model );
+    // check if the user model is renamed
     QString oldName = item->data( NameRole ).toString(), newName = item->text();
     if ( oldName == newName ) {
-      model.save( resourceMgr(), oldName );
+      // model is not renamed: store data using current name
+      model.toResources( oldName, &myResourceMgr );
     }
     else {
-      resourceMgr()->remove( oldName );
-      model.save( resourceMgr(), newName );
+      // model is renamed: remove model with old name and store model using new name
+      myResourceMgr.remove( oldName );
+      model.toResources( newName, &myResourceMgr );
       item->setData( NameRole, newName );
     }
-    blockSignals( true );
-    fromModel( &model );
-    blockSignals( false );    
   }
   else {
-    // if user tries to change global (or default, or no material) material,
-    // we create a new user material basing on selected one
-    QString newName = findUniqueName( tr( "CUSTOM_MATERIAL" ), 0, true );
-    item = new QListWidgetItem( newName );
-    item->setData( TypeRole, QVariant( User ) );
-    item->setData( NameRole, QVariant( newName ) );
-    item->setFlags( item->flags() | Qt::ItemIsEditable );
-    myMaterialList->addItem( item );
-    
-    Material_Model model;
-    toModel( &model );
-    model.save( resourceMgr(), newName );
-    
-    myMaterialList->setCurrentItem( item );
-
-    myMaterialListFId = myMaterialList->currentRow();
+    // it is no allowed to change global material
+    // user is asked about creating of a new user material model based on the currently selected one
+    if ( SUIT_MessageBox::question( this,
+                                   tr( "GEOM_WRN_WARNING" ),
+                                   tr( "QUE_CREATE_NEW_MATERIAL" ),
+                                   QMessageBox::Yes | QMessageBox::No,
+                                   QMessageBox::Yes ) == QMessageBox::Yes ) {
+      // user has chosen creation of new user model
+      onAddMaterial();
+    }
+    else {
+      // user has rejected creation of new user model: revert changes
+      bool blocked = blockSignals( true );
+      Material_Model model;
+      model.fromResources( item->data( NameRole ).toString(), &myResourceMgr );
+      fromModel( model );
+      blockSignals( blocked );
+    }
   }
+
+  // update buttons state
+  updateState();
 }
 
 /*!
@@ -833,45 +576,100 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onChanged()
 */
 void GEOMToolsGUI_MaterialPropertiesDlg::onItemChanged( QListWidgetItem* item )
 {
+  // check new name to be unique (add suffix if necessary)
   QString newName = item->text();
   QString uniqueName = findUniqueName( newName, item );
   if ( uniqueName != newName ) {
-    myMaterialList->blockSignals( true );
+    bool blocked = myMaterials->blockSignals( true );
     item->setText( uniqueName );
-    myMaterialList->blockSignals( false );
+    myMaterials->blockSignals( blocked );
   }
   onChanged();
 }                               
 
 /*!
-  \brief Called when widget effect is changed
+  \brief Process context menu event from materials list
 */
-void GEOMToolsGUI_MaterialPropertiesDlg::onReflectionTypeToggled( bool theIsOn )
+void GEOMToolsGUI_MaterialPropertiesDlg::onContextMenu( QContextMenuEvent* e )
 {
-  QGroupBox* anObj = (QGroupBox*)sender();
-
-  // Set an empty values for color and coefficient
-  // of the checked/unchecked reflection type
-  QColor c;
-
-
-  // Make changes on material tab
-  if ( anObj == myAmbientGroupF ) {    
-    myAmbientColorF->setColor( c );
-    myAmbientCoefntF->setValue( 0.0 );
+  QListWidgetItem* item = myMaterials->itemAt( e->pos() );
+  QMap<QAction*, int> actionMap;
+  QMenu m;
+  // rename
+  if ( item && item->data( TypeRole ).toInt() == User ) {
+    actionMap[ m.addAction( tr( "RENAME_MATERIAL" ) ) ] = 0;
+    m.addSeparator();
   }
-  else if ( anObj == myDiffuseGroupF ) {
-    myDiffuseColorF->setColor( c );
-    myDiffuseCoefntF->setValue( 0.0 );
+  // add user material
+  actionMap[ m.addAction( tr( "ADD_MATERIAL" ) ) ] = 1;
+  // delete user material
+  if ( item && item->data( TypeRole ).toInt() == User ) {
+    actionMap[ m.addAction( tr( "DELETE_MATERIAL" ) ) ] = 2;
   }
-  else if ( anObj == mySpecularGroupF ) {
-    mySpecularColorF->setColor( c );
-    mySpecularCoefntF->setValue( 0.0 );
+  QAction* a = m.exec( e->globalPos() );
+  switch( actionMap[ a ] ) {
+  case 0:
+    // rename
+    myMaterials->editItem( item );
+    break;
+  case 1:
+    // add user material
+    onAddMaterial();
+    break;
+  case 2:
+    // delete user material
+    onDeleteMaterial();
+    break;
+  default:
+    break;
   }
-  else if ( anObj == myEmissionGroupF ) {
-    myEmissionColorF->setColor( c );
-    myEmissionCoefntF->setValue( 0.0 );
+}
+
+/*!
+  \brief Delete currently selected user model
+*/
+void GEOMToolsGUI_MaterialPropertiesDlg::onDeleteMaterial()
+{
+  QListWidgetItem* item = myMaterials->currentItem();
+  if ( item && item->data( TypeRole ).toInt() == User ) {
+    if ( SUIT_MessageBox::question( this,
+                                   tr( "GEOM_WRN_WARNING" ),
+                                   tr( "QUE_REMOVE_MATERIAL" ).arg( item->text() ),
+                                   QMessageBox::Yes | QMessageBox::No,
+                                   QMessageBox::Yes ) == QMessageBox::Yes ) {
+      myResourceMgr.remove( item->data( NameRole ).toString() );
+      delete item;
+    }
   }
+}
+
+/*!
+  \brief Add new user material model
+*/
+void GEOMToolsGUI_MaterialPropertiesDlg::onAddMaterial()
+{
+  QString newName = findUniqueName( tr( "CUSTOM_MATERIAL" ), 0, true );
+  QListWidgetItem* item = new QListWidgetItem( newName );
+  item->setData( TypeRole, QVariant( User ) );
+  item->setData( NameRole, QVariant( newName ) );
+  item->setFlags( item->flags() | Qt::ItemIsEditable );
+  myMaterials->addItem( item );
   
-  emit( changed() );
+  Material_Model model;
+  toModel( model );
+  model.toResources( newName, &myResourceMgr );
+  myMaterials->setCurrentItem( item );
+  myMaterials->editItem( item );
+}
+
+/*!
+  \brief Update buttons state
+*/
+void GEOMToolsGUI_MaterialPropertiesDlg::updateState()
+{
+  QListWidgetItem* item = myMaterials->currentItem();
+  myDelButton->setEnabled( item && item->data( TypeRole ).toInt() == User );
+  myColorLab->setEnabled( !myPhysical->isChecked() );
+  myColor->setEnabled( !myPhysical->isChecked() );
+  myReflection[0].color->setEnabled( myPhysical->isChecked() );
 }