1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
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, or (at your option) any later version.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : GEOMToolsGUI_MaterialPropertiesDlg.cxx
21 // Author : Margarita KARPUNINA, Open CASCADE S.A.S. (margarita.karpunina@opencascade.com)
23 #include "GEOMToolsGUI_MaterialPropertiesDlg.h"
25 #include "GeometryGUI.h"
26 #include "GEOM_Constants.h"
27 #include "GEOM_VTKPropertyMaterial.hxx"
29 #include "GEOM_Displayer.h"
31 #include <QtxColorButton.h>
32 #include <QtxDoubleSpinBox.h>
33 #include <SUIT_Desktop.h>
34 #include <SUIT_MessageBox.h>
35 #include <SUIT_OverrideCursor.h>
36 #include <SUIT_ResourceMgr.h>
37 #include <SUIT_Session.h>
38 #include <SUIT_ViewManager.h>
39 #include <SALOME_ListIO.hxx>
40 #include <OCCViewer_ViewModel.h>
41 #include <SVTK_ViewModel.h>
42 #include <SVTK_ViewWindow.h>
43 #include <SVTK_View.h>
44 #include <LightApp_SelectionMgr.h>
45 #include <SalomeApp_Application.h>
46 #include <SalomeApp_Study.h>
47 #include <SalomeApp_Tools.h>
50 #include <QGridLayout>
51 #include <QHBoxLayout>
57 #include <QPushButton>
58 #include <QVBoxLayout>
60 #define MARGIN 9 // layout spacing
61 #define SPACING 6 // layout margin
64 \class GEOMToolsGUI_MaterialList
65 \brief Internal class, used to handle context menu event from materials list
72 GEOMToolsGUI_MaterialList::GEOMToolsGUI_MaterialList( QWidget* parent )
73 : QListWidget( parent )
77 \brief Context menu event, emits context menu signal passing event as parameter
79 void GEOMToolsGUI_MaterialList::contextMenuEvent( QContextMenuEvent* e )
81 emit contextMenu( e );
85 \class GEOMToolsGUI_MaterialPropertiesDlg
86 \brief GEOM material properties dialog box class
88 The dialog box is used to set material properties for the presentation objects.
93 \param parent parent widget
94 \param showSelWidget if \c true then objects can be selected by user
95 \param modal if \c true dialog box is modal
96 \param f specified control buttons for dialog box (QtxDialog::ButtonFlags)
98 GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* parent,bool showSelWidget, bool modal,const int f )
99 : QtxDialog( parent, modal, true, f )
101 myShowSelWidget = showSelWidget;
103 setWindowTitle( tr( "MATERIAL_PROPERTIES_TLT" ) );
106 QVBoxLayout* main = new QVBoxLayout( mainFrame() );
107 main->setMargin( 0 );
108 main->setSpacing( SPACING );
110 // add top-level frame box to enclose all main widgets (excluding buttons)
111 QFrame* fr = new QFrame( mainFrame() );
112 fr->setFrameStyle( QFrame::Box | QFrame::Sunken );
113 main->addWidget( fr );
115 myLineEditCurArg = new QLineEdit(fr);
116 myLineEditCurArg->setReadOnly(true);
117 myPushBtn = new QPushButton(fr);
118 QLabel* PushBtnLab = new QLabel( tr( "GEOM_OBJECTS" ), fr );
120 // materials list widget
121 myMaterials = new GEOMToolsGUI_MaterialList( fr );
123 QWidget* propWidget = new QWidget( fr );
125 // layout main widgets
126 QHBoxLayout* frLayout = new QHBoxLayout( fr );
127 frLayout->setMargin( MARGIN );
128 frLayout->setSpacing( SPACING );
129 frLayout->addWidget( myMaterials );
130 frLayout->addWidget( propWidget );
132 // layout for material properties widgets
133 QGridLayout* propLayout = new QGridLayout( propWidget );
134 propLayout->setMargin( 0 );
135 propLayout->setSpacing( SPACING );
137 // current color widgets
138 myColorLab = new QLabel( tr( "CURRENT_COLOR" ), propWidget );
139 myColor = new QtxColorButton( propWidget );
141 // "physical" material type widgets
142 myPhysical = new QCheckBox( tr( "PHYSICAL" ), propWidget );
144 // Labels for front and back reflection components
145 QLabel* aFrontLabel = new QLabel( tr( "FRONT_FACE" ), propWidget );
146 QLabel* aBackLabel = new QLabel( tr( "BACK_FACE" ), propWidget );
148 // reflection components widgets
149 for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
153 refl.enabled = new QCheckBox( propWidget );
155 refl.label = new QLabel( tr( QString( "REFLECTION_%1" ).arg( i ).toLatin1().data() ), propWidget );
157 refl.color = new QtxColorButton( propWidget );
158 //refl.color->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
160 refl.front_coef = new QtxDoubleSpinBox( propWidget );
161 refl.front_coef->setPrecision( 4 );
162 refl.front_coef->setDecimals( 4 );
163 refl.front_coef->setRange( 0., 1. );
164 refl.front_coef->setSingleStep( 0.05 );
165 refl.front_coef->setMinimumWidth( 80 );
167 refl.back_coef = new QtxDoubleSpinBox( propWidget );
168 refl.back_coef->setPrecision( 4 );
169 refl.back_coef->setDecimals( 4 );
170 refl.back_coef->setRange( 0., 1. );
171 refl.back_coef->setSingleStep( 0.05 );
172 refl.back_coef->setMinimumWidth( 80 );
174 myReflection << refl;
178 QLabel* shininessLab = new QLabel( tr( "SHININESS" ), propWidget );
179 myFrontShininess = new QtxDoubleSpinBox( propWidget );
180 myFrontShininess->setPrecision( 4 );
181 myFrontShininess->setDecimals( 4 );
182 myFrontShininess->setRange( 0., 1. );
183 myFrontShininess->setSingleStep( 0.05 );
185 myBackShininess = new QtxDoubleSpinBox( propWidget );
186 myBackShininess->setPrecision( 4 );
187 myBackShininess->setDecimals( 4 );
188 myBackShininess->setRange( 0., 1. );
189 myBackShininess->setSingleStep( 0.05 );
192 QFrame* line1 = new QFrame( propWidget );
193 line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
194 QFrame* line2 = new QFrame( propWidget );
195 line2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
196 QFrame* line3 = new QFrame( propWidget );
197 line3->setFrameStyle( QFrame::VLine | QFrame::Sunken );
198 QFrame* line4 = new QFrame( propWidget );
199 line4->setFrameStyle( QFrame::VLine | QFrame::Sunken );
200 QFrame* line5 = new QFrame( propWidget );
201 line5->setFrameStyle( QFrame::HLine | QFrame::Sunken );
203 // add / remove material buttons
204 myAddButton = new QPushButton( tr( "ADD_MATERIAL" ), propWidget );
205 myDelButton = new QPushButton( tr( "DELETE_MATERIAL" ), propWidget );
208 QHBoxLayout* btnLayout = new QHBoxLayout;
209 btnLayout->setMargin( 0 );
210 btnLayout->setSpacing( SPACING );
211 btnLayout->addWidget( myAddButton );
212 btnLayout->addWidget( myDelButton );
214 // layout all properties widgets together
215 propLayout->addWidget( PushBtnLab,0,0);
216 propLayout->addWidget( myPushBtn,0,1);
217 propLayout->addWidget( myLineEditCurArg, 0, 2, 1, 5 );
218 propLayout->addWidget( line1, 1, 0, 1, 7 );
219 propLayout->addWidget( myColorLab, 2, 1 );
220 propLayout->addWidget( myColor, 2, 2 );
221 propLayout->addWidget( myPhysical, 2, 0 );
222 propLayout->addWidget( line2, 3, 0, 1, 7 );
223 propLayout->addWidget( aFrontLabel, 4, 4);
224 propLayout->addWidget( aBackLabel, 4, 6);
226 propLayout->addWidget( line3, 4, 3, 6, 1 );
227 propLayout->addWidget( line4, 4, 5, 6, 1 );
229 if( !myShowSelWidget ) {
233 myLineEditCurArg->hide();
237 for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) {
238 propLayout->addWidget( myReflection[i].enabled, i+5, 0 );
239 propLayout->addWidget( myReflection[i].label, i+5, 1 );
240 propLayout->addWidget( myReflection[i].color, i+5, 2 );
241 propLayout->addWidget( myReflection[i].front_coef, i+5, 4 );
242 propLayout->addWidget( myReflection[i].back_coef, i+5, 6 );
245 propLayout->addWidget( shininessLab, 9, 0 );
246 propLayout->addWidget( myFrontShininess, 9, 4 );
247 propLayout->addWidget( myBackShininess, 9, 6 );
248 propLayout->addWidget( line5, 10, 0, 1, 7 );
249 propLayout->setRowStretch( 11, 5 );
250 propLayout->addLayout( btnLayout, 12, 0, 1, 7 );
252 // initialize dialog box
253 setButtonPosition( Right, Close );
255 // fill in the list of materials
256 QStringList globalMaterials = myResourceMgr.materials( Material_ResourceMgr::Global );
257 QStringList userMaterials = myResourceMgr.materials( Material_ResourceMgr::User );
259 QListWidgetItem* item;
261 // - current material
262 item = new QListWidgetItem( tr( "CURRENT_MATERIAL" ) );
263 item->setForeground( QColor( Qt::red ) );
264 item->setData( TypeRole, QVariant( Current ) );
265 myMaterials->addItem( item );
266 // - global materials
267 foreach( QString material, globalMaterials ) {
268 item = new QListWidgetItem( material );
269 item->setForeground( QColor( Qt::blue ) );
270 item->setData( TypeRole, QVariant( Global ) );
271 item->setData( NameRole, QVariant( material ) );
272 myMaterials->addItem( item );
275 foreach ( QString material, userMaterials ) {
276 item = new QListWidgetItem( material );
277 item->setData( TypeRole, QVariant( User ) );
278 item->setData( NameRole, QVariant( material ) );
279 item->setFlags( item->flags() | Qt::ItemIsEditable );
280 myMaterials->addItem( item );
282 // install event filter to the materials list to process key press events
283 myMaterials->installEventFilter( this );
286 myPushBtn->setIcon(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
289 // note: all widgets, that change material properties, are connected to the common signal
290 // changed(), instead of connecting directly to the slot - this allows easy temporary blocking
291 // of the change signal
292 connect( myPhysical, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
293 for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) {
294 connect( myReflection[i].color, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) );
295 connect( myReflection[i].front_coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
296 connect( myReflection[i].back_coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
297 connect( myReflection[i].enabled, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
299 connect( myFrontShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
300 connect( myBackShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
301 connect( myMaterials, SIGNAL( itemSelectionChanged() ),
302 this, SLOT( onMaterialChanged() ) );
303 connect( myMaterials, SIGNAL( itemChanged( QListWidgetItem* ) ),
304 this, SLOT( onItemChanged( QListWidgetItem* ) ) );
305 connect( myMaterials, SIGNAL( contextMenu( QContextMenuEvent* ) ),
306 this, SLOT( onContextMenu( QContextMenuEvent* ) ) );
307 connect( myAddButton, SIGNAL( clicked() ), this, SLOT( onAddMaterial() ) );
308 connect( myDelButton, SIGNAL( clicked() ), this, SLOT( onDeleteMaterial() ) );
309 connect( this, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
310 connect( this, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
311 connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
312 connect(myPushBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
313 connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
314 SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
316 // initialize current material model according to the selection
317 myColor->setColor( SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ) );
318 myCurrentModel.fromResources( SUIT_Session::session()->resourceMgr()->stringValue( "Geometry", "material", "Plastic" ) );
319 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
320 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
321 LightApp_SelectionMgr* selMgr = app->selectionMgr();
323 SALOME_ListIO selected;
324 selMgr->selectedObjects( selected );
325 if ( selected.Extent() > 0 ) {
326 Handle(SALOME_InteractiveObject) io = selected.First();
327 if ( !io.IsNull() ) {
328 SUIT_ViewWindow* window = app->desktop()->activeWindow();
330 int mgrId = window->getViewManager()->getGlobalId();
331 PropMap propMap = study->getObjectProperties( mgrId, io->getEntry() );
332 QString matProp = propMap.value(GEOM::propertyName( GEOM::Material )).toString();
333 if ( !matProp.isEmpty() )
334 myCurrentModel.fromProperties( matProp );
335 QColor c = propMap.value(GEOM::propertyName( GEOM::Color )).value<QColor>();
337 myColor->setColor( c );
342 myLineEditCurArg->setText("");
344 SelectionIntoArgument();
346 // finally activate current material properties
347 myMaterials->setCurrentRow( 0 );
353 GEOMToolsGUI_MaterialPropertiesDlg::~GEOMToolsGUI_MaterialPropertiesDlg()
358 \brief Called when "OK" button is clicked
360 void GEOMToolsGUI_MaterialPropertiesDlg::accept()
371 bool GEOMToolsGUI_MaterialPropertiesDlg::eventFilter( QObject* o, QEvent* e )
373 // process key press event from materials list
374 if ( o == myMaterials && e->type() == QEvent::KeyPress ) {
375 QKeyEvent* ke = (QKeyEvent*)e;
376 if ( ke->key() == Qt::Key_Delete ) {
380 return QtxDialog::eventFilter( o, e );
384 \brief Initialize dialog box widgets from material model
385 \param model material model
387 void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( const Material_Model& model )
389 // reflection components
390 for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
392 myReflection[i].color->setColor( model.color( (Material_Model::ReflectionType)i ) );
393 myReflection[i].front_coef->setValue( model.reflection( (Material_Model::ReflectionType)i, true ) );
394 myReflection[i].back_coef->setValue( model.reflection( (Material_Model::ReflectionType)i, false ) );
395 myReflection[i].enabled->setChecked( model.hasReflection( (Material_Model::ReflectionType)i ) );
399 myFrontShininess->setValue( model.shininess( true ) );
400 myBackShininess->setValue( model.shininess( false ) );
402 // type (physical or no)
403 myPhysical->setChecked( model.isPhysical() );
407 \brief Save values from dialog box widgets to material model
408 \param model material model to be filled in
410 void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model& model ) const
412 // type (physical or no)
413 model.setPhysical( myPhysical->isChecked() );
416 model.setShininess( myFrontShininess->value(), true );
417 model.setShininess( myBackShininess->value(), false );
419 // reflection components
420 for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
422 model.setColor ( (Material_Model::ReflectionType)i, myReflection[i].color->color() );
423 model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].front_coef->value(), true );
424 model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].back_coef->value(), false );
425 model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].enabled->isChecked() );
430 \brief Find unique name for the material name
431 \param name material name template
432 \param item the item to be ignored when browsing through the materials list
433 \param addSuffix if \c true, the integrer suffix is always added to the material name (otherwise
434 suffix is added only if item name is not unique)
435 \return new unique material name
437 QString GEOMToolsGUI_MaterialPropertiesDlg::findUniqueName( const QString& name, QListWidgetItem* item, bool addSuffix )
441 for( int i = 1; i < myMaterials->count(); i++ ) {
442 if ( item == myMaterials->item( i ) ) continue;
443 QString iname = myMaterials->item( i )->text();
444 if ( iname == name ) {
447 else if ( iname.startsWith( name ) ) {
448 iname = iname.mid( name.length() ).trimmed();
450 int nx = iname.toInt( &ok );
451 if ( ok ) idx = qMax( idx, nx );
454 return found || addSuffix ? QString( "%1 %2" ).arg( name ).arg( idx+1 ) : name;
458 \brief Called when "Apply" button is pressed
460 void GEOMToolsGUI_MaterialPropertiesDlg::onApply()
462 // save user materials
463 myResourceMgr.save();
464 if( !myShowSelWidget ) return;
465 // store selected material properties in the current model
466 toModel( myCurrentModel );
468 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
469 LightApp_SelectionMgr* selMgr = app->selectionMgr();
470 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
472 if ( !study ) return;
475 SALOME_ListIO selected;
476 selMgr->selectedObjects( selected );
477 if ( selected.IsEmpty() ) return;
479 SUIT_ViewWindow* window = app->desktop()->activeWindow();
480 int mgrId = window->getViewManager()->getGlobalId();
482 // convert current material properties to the string representation
483 QString prop = myCurrentModel.toProperties();
485 if ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() ) {
487 SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( window );
491 SVTK_View* aView = vtkVW->getView();
493 // get VTK material properties from the current model
494 GEOM_VTKPropertyMaterial* vtkPropF = myCurrentModel.getMaterialVTKProperty();
495 GEOM_VTKPropertyMaterial* vtkPropB = myCurrentModel.getMaterialVTKProperty( false );
497 SUIT_OverrideCursor wc();
499 for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
500 // set material property to the presentation
501 aView->SetMaterial( It.Value(), vtkPropF, vtkPropB );
502 // store chosen material in the property map
503 study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Material ), prop );
504 // set correct color for the non-physical material
505 if ( !myCurrentModel.isPhysical() ) {
506 aView->SetColor( It.Value(), myColor->color() );
507 study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Color ), myColor->color() );
511 GeometryGUI::Modified();
513 else if ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() ) {
515 OCCViewer_Viewer* vm = dynamic_cast<OCCViewer_Viewer*>( window->getViewManager()->getViewModel() );
519 Handle(AIS_InteractiveContext) ic = vm->getAISContext();
521 // get OCC material aspect from the current model
522 Graphic3d_MaterialAspect front_occAspect = myCurrentModel.getMaterialOCCAspect( true );
523 Graphic3d_MaterialAspect back_occAspect = myCurrentModel.getMaterialOCCAspect( false );
525 SUIT_OverrideCursor wc();
527 for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
528 Handle(GEOM_AISShape) aisShape = GEOMBase::ConvertIOinGEOMAISShape( It.Value(), true );
529 if ( !aisShape.IsNull() ) {
530 // Set front material for the selected shape
531 aisShape->SetCurrentFacingModel(Aspect_TOFM_FRONT_SIDE);
532 aisShape->SetMaterial(front_occAspect);
533 // Set back material for the selected shape
534 aisShape->SetCurrentFacingModel(Aspect_TOFM_BACK_SIDE);
535 aisShape->SetMaterial(back_occAspect);
536 // Return to the default facing mode
537 aisShape->SetCurrentFacingModel(Aspect_TOFM_BOTH_SIDE);
538 // store chosen material in the property map
539 study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Material ), prop );
540 // set correct color for the non-physical material
541 if ( !myCurrentModel.isPhysical() ) {
542 aisShape->SetShadingColor( SalomeApp_Tools::color( myColor->color() ) );
543 study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Color ), myColor->color() );
544 ic->RecomputePrsOnly( aisShape, Standard_False );
546 //if ( aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/)
547 ic->Redisplay( aisShape, Standard_False );
550 ic->UpdateCurrentViewer();
551 GeometryGUI::Modified();
556 \brief Called when "Help" button is pressed
558 void GEOMToolsGUI_MaterialPropertiesDlg::onHelp()
560 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
561 app->onHelpContextModule( "GEOM", "material_page.html" );
565 \brief Called when user selects any material item in the materials list
567 void GEOMToolsGUI_MaterialPropertiesDlg::onMaterialChanged()
569 // get currently selected item
570 QListWidgetItem* item = myMaterials->currentItem();
573 bool blocked = blockSignals( true );
575 int type = item->data( TypeRole ).toInt();
576 if ( type == Current ) {
577 // initialize widgets from current material model
578 fromModel( myCurrentModel );
581 // initialize widgets from chosen material model (using resources manager)
582 Material_Model model;
583 model.fromResources( item->data( NameRole ).toString(), &myResourceMgr );
587 blockSignals( blocked );
589 // update buttons state
594 \brief Called when any material parameter is changed by the user
596 void GEOMToolsGUI_MaterialPropertiesDlg::onChanged()
598 // get currently selected item
599 QListWidgetItem* item = myMaterials->currentItem();
600 int type = item->data( TypeRole ).toInt();
603 if ( type == Current ) {
604 // for the current model do not perform any actions except store changed values
605 toModel( myCurrentModel );
607 else if ( type == User ) {
608 // for the user model, simply store the changes in the resource manager
609 Material_Model model;
611 // check if the user model is renamed
612 QString oldName = item->data( NameRole ).toString(), newName = item->text();
613 if ( oldName == newName ) {
614 // model is not renamed: store data using current name
615 model.toResources( oldName, &myResourceMgr );
618 // model is renamed: remove model with old name and store model using new name
619 myResourceMgr.remove( oldName );
620 model.toResources( newName, &myResourceMgr );
621 item->setData( NameRole, newName );
625 // it is no allowed to change global material
626 // user is asked about creating of a new user material model based on the currently selected one
627 if ( SUIT_MessageBox::question( this,
628 tr( "GEOM_WRN_WARNING" ),
629 tr( "QUE_CREATE_NEW_MATERIAL" ),
630 QMessageBox::Yes | QMessageBox::No,
631 QMessageBox::Yes ) == QMessageBox::Yes ) {
632 // user has chosen creation of new user model
636 // user has rejected creation of new user model: revert changes
637 bool blocked = blockSignals( true );
638 Material_Model model;
639 model.fromResources( item->data( NameRole ).toString(), &myResourceMgr );
641 blockSignals( blocked );
645 // update buttons state
650 \brief Called when user material is renamed by the user
652 void GEOMToolsGUI_MaterialPropertiesDlg::onItemChanged( QListWidgetItem* item )
654 // check new name to be unique (add suffix if necessary)
655 QString newName = item->text();
656 QString uniqueName = findUniqueName( newName, item );
657 if ( uniqueName != newName ) {
658 bool blocked = myMaterials->blockSignals( true );
659 item->setText( uniqueName );
660 myMaterials->blockSignals( blocked );
666 \brief Process context menu event from materials list
668 void GEOMToolsGUI_MaterialPropertiesDlg::onContextMenu( QContextMenuEvent* e )
670 QListWidgetItem* item = myMaterials->itemAt( e->pos() );
671 QMap<QAction*, int> actionMap;
674 if ( item && item->data( TypeRole ).toInt() == User ) {
675 actionMap[ m.addAction( tr( "RENAME_MATERIAL" ) ) ] = 0;
679 actionMap[ m.addAction( tr( "ADD_MATERIAL" ) ) ] = 1;
680 // delete user material
681 if ( item && item->data( TypeRole ).toInt() == User ) {
682 actionMap[ m.addAction( tr( "DELETE_MATERIAL" ) ) ] = 2;
684 QAction* a = m.exec( e->globalPos() );
685 switch( actionMap[ a ] ) {
688 myMaterials->editItem( item );
695 // delete user material
704 \brief Delete currently selected user model
706 void GEOMToolsGUI_MaterialPropertiesDlg::onDeleteMaterial()
708 QListWidgetItem* item = myMaterials->currentItem();
709 if ( item && item->data( TypeRole ).toInt() == User ) {
710 if ( SUIT_MessageBox::question( this,
711 tr( "GEOM_WRN_WARNING" ),
712 tr( "QUE_REMOVE_MATERIAL" ).arg( item->text() ),
713 QMessageBox::Yes | QMessageBox::No,
714 QMessageBox::Yes ) == QMessageBox::Yes ) {
715 myResourceMgr.remove( item->data( NameRole ).toString() );
722 \brief Add new user material model
724 void GEOMToolsGUI_MaterialPropertiesDlg::onAddMaterial()
726 QString newName = findUniqueName( tr( "CUSTOM_MATERIAL" ), 0, true );
727 QListWidgetItem* item = new QListWidgetItem( newName );
728 item->setData( TypeRole, QVariant( User ) );
729 item->setData( NameRole, QVariant( newName ) );
730 item->setFlags( item->flags() | Qt::ItemIsEditable );
731 myMaterials->addItem( item );
733 Material_Model model;
735 model.toResources( newName, &myResourceMgr );
736 myMaterials->setCurrentItem( item );
737 myMaterials->editItem( item );
741 \brief Update buttons state
743 void GEOMToolsGUI_MaterialPropertiesDlg::updateState()
745 QListWidgetItem* item = myMaterials->currentItem();
746 myDelButton->setEnabled( item && item->data( TypeRole ).toInt() == User );
747 myColorLab->setEnabled( !myPhysical->isChecked() );
748 myColor->setEnabled( !myPhysical->isChecked() );
749 myReflection[0].color->setEnabled( myPhysical->isChecked() );
753 void GEOMToolsGUI_MaterialPropertiesDlg::SetEditCurrentArgument()
755 QPushButton* send = (QPushButton*)sender();
757 if (send == myPushBtn) {
759 myLineEditCurArg->setEnabled(true);
760 myLineEditCurArg->setFocus();
761 SelectionIntoArgument();
762 // after setFocus(), because it will be setDown(false) when loses focus
768 \brief Called when selection as changed or other case
770 void GEOMToolsGUI_MaterialPropertiesDlg::SelectionIntoArgument()
772 myLineEditCurArg->setText( "" );
773 QString aString = "";
775 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
776 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
777 LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
779 SALOME_ListIO aSelList;
780 aSelMgr->selectedObjects(aSelList);
781 int nbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true);
783 myLineEditCurArg->setText( aString );