/****************************************************************************** * Copyright (c) 2013 Oracle * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * ******************************************************************************/ package com.liferay.ide.project.ui.wizard; import com.liferay.ide.project.ui.ProjectUI; import java.util.ArrayList; import java.util.List; import org.eclipse.sapphire.ImageData; import org.eclipse.sapphire.LocalizableText; import org.eclipse.sapphire.Property; import org.eclipse.sapphire.Text; import org.eclipse.sapphire.Value; import org.eclipse.sapphire.modeling.util.MiscUtil; import org.eclipse.sapphire.PossibleValuesService; import org.eclipse.sapphire.services.ValueImageService; import org.eclipse.sapphire.services.ValueLabelService; import org.eclipse.sapphire.ui.forms.PropertyEditorDef; import org.eclipse.sapphire.ui.forms.swt.AbstractBinding; import org.eclipse.sapphire.ui.forms.swt.PropertyEditorPresentation; import org.eclipse.sapphire.ui.forms.swt.RadioButtonsGroup; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Control; /** * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> */ public final class PossibleValuesRadioButtonsGroupBinding<T> extends AbstractBinding { @Text( "<value not set>" ) private static LocalizableText nullValueLabel; static { LocalizableText.init( PossibleValuesRadioButtonsGroupBinding.class ); } private RadioButtonsGroup buttonsGroup; private Button badValueButton; private List<String> possibleValues; public PossibleValuesRadioButtonsGroupBinding( final PropertyEditorPresentation propertyEditorPresentation, final RadioButtonsGroup buttonsGroup ) { super( propertyEditorPresentation, buttonsGroup ); } @SuppressWarnings( "unchecked" ) @Override protected void initialize( PropertyEditorPresentation propertyEditorPresentation, Control control ) { super.initialize( propertyEditorPresentation, control ); final PossibleValuesService possibleValuesService = propertyEditorPresentation.property().service( PossibleValuesService.class ); this.possibleValues = new ArrayList<String>( possibleValuesService.values() ); this.buttonsGroup = (RadioButtonsGroup) control; final Property property = propertyEditorPresentation.property(); String auxTextProviderName = propertyEditorPresentation.part().getRenderingHint( "possible.values.aux.text.provider", (String)null ); //$NON-NLS-1 PossibleValuesAuxTextProvider auxTextProvider = null; if( auxTextProviderName != null ) { try { Class<PossibleValuesAuxTextProvider> providerClass = (Class<PossibleValuesAuxTextProvider>) ProjectUI.getDefault().getBundle().loadClass( auxTextProviderName ); auxTextProvider = providerClass.newInstance(); } catch( Exception e ) { } } for( String possibleValue : this.possibleValues ) { final ValueLabelService labelService = property.service( ValueLabelService.class ); final String possibleValueText = labelService.provide( possibleValue ); String auxText = propertyEditorPresentation.part().getRenderingHint( PropertyEditorDef.HINT_AUX_TEXT + "." + possibleValue, null ); //$NON-NLS-1$ if( auxText == null && auxTextProvider != null ) { auxText = auxTextProvider.getAuxText( this.element(), property.definition(), possibleValue ); } ValueImageService imageService = property.service( ValueImageService.class ); ImageData imageData = imageService.provide( possibleValue ); Image image = presentation().resources().image( imageData ); final Button button = this.buttonsGroup.addRadioButton( possibleValueText, auxText, image ); button.setData( possibleValue ); } this.buttonsGroup.addSelectionListener ( new SelectionAdapter() { public void widgetSelected( final SelectionEvent event ) { updateModel(); updateTargetAttributes(); } } ); } private int getSelectionIndex() { return this.buttonsGroup.getSelectionIndex(); } private void setSelectionIndex( final int index ) { this.buttonsGroup.setSelectionIndex( index ); } private void createMalformedItem( String label ) { if( this.badValueButton == null ) { this.badValueButton = this.buttonsGroup.addRadioButton( MiscUtil.EMPTY_STRING ); } this.badValueButton.setText( label ); presentation().layout(); } private void removeMalformedItem() { if( ! this.buttonsGroup.isDisposed() ) { if( this.badValueButton != null ) { this.badValueButton.dispose(); this.badValueButton = null; presentation().layout(); } } } @Override @SuppressWarnings( "unchecked" ) public Value<T> property() { return (Value<T>) super.property(); } @Override protected final void doUpdateModel() { final int index = getSelectionIndex(); if( index >= 0 && index < this.possibleValues.size() ) { property().write( this.possibleValues.get( index ) ); removeMalformedItem(); } } @Override protected final void doUpdateTarget() { final int existingSelection = getSelectionIndex(); final Value<T> value = property(); int newSelection = this.possibleValues.size(); if( ! value.malformed() ) { final T newValue = value.content( true ); for( int i = 0, n = this.possibleValues.size(); i < n; i++ ) { if( this.possibleValues.get( i ).equals( newValue.toString() ) ) { newSelection = i; break; } } } if( newSelection == this.possibleValues.size() ) { final String newValueString = value.text( true ); final String label = ( newValueString == null ? nullValueLabel.text() : newValueString ); createMalformedItem( label ); } else { removeMalformedItem(); } if( existingSelection != newSelection ) { setSelectionIndex( newSelection ); } } }