Package org.eclipse.sapphire.ui.forms.swt.internal

Source Code of org.eclipse.sapphire.ui.forms.swt.internal.NamedValuesPropertyEditorPresentation$NamedValuesBinding

/******************************************************************************
* Copyright (c) 2014 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
*
* Contributors:
*    Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/

package org.eclipse.sapphire.ui.forms.swt.internal;

import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gd;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdhfill;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdhindent;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdhspan;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdvalign;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdvindent;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.gdwhint;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.glayout;
import static org.eclipse.sapphire.ui.forms.swt.GridLayoutUtil.glspacing;
import static org.eclipse.sapphire.ui.forms.swt.SwtUtil.changeRadioButtonSelection;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.sapphire.LoggingService;
import org.eclipse.sapphire.PropertyDef;
import org.eclipse.sapphire.Sapphire;
import org.eclipse.sapphire.Value;
import org.eclipse.sapphire.ValueProperty;
import org.eclipse.sapphire.modeling.CapitalizationType;
import org.eclipse.sapphire.modeling.EditFailedException;
import org.eclipse.sapphire.modeling.annotations.NamedValues;
import org.eclipse.sapphire.modeling.annotations.NamedValues.NamedValue;
import org.eclipse.sapphire.modeling.util.MiscUtil;
import org.eclipse.sapphire.ui.assist.internal.PropertyEditorAssistDecorator;
import org.eclipse.sapphire.ui.forms.FormComponentPart;
import org.eclipse.sapphire.ui.forms.PropertyEditorPart;
import org.eclipse.sapphire.ui.forms.swt.AbstractBinding;
import org.eclipse.sapphire.ui.forms.swt.PropertyEditorPresentation;
import org.eclipse.sapphire.ui.forms.swt.PropertyEditorPresentationFactory;
import org.eclipse.sapphire.ui.forms.swt.SwtPresentation;
import org.eclipse.sapphire.ui.forms.swt.ValuePropertyEditorPresentation;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/

public final class NamedValuesPropertyEditorPresentation extends ValuePropertyEditorPresentation
{
    private Composite rootComposite;
    private boolean updating;
    private String defaultArbitraryValue;
    private Label overallLabelControl;
    private Button arbitraryValueRadioButton;
    private Text arbitraryValueTextField;
    private NamedValueLocal[] namedValues;
    private Button[] namedValuesRadioButtons;
    private List<Button> radioButtonGroup;
   
    public NamedValuesPropertyEditorPresentation( final FormComponentPart part, final SwtPresentation parent, final Composite composite )
    {
        super( part, parent, composite );
    }
   
    protected void createContents( final Composite parent )
    {
        final PropertyEditorPart part = part();
        final ValueProperty property = (ValueProperty) part.property().definition();
       
        this.rootComposite = new Composite( parent, SWT.NONE )
        {
            @Override
            public void setEnabled( final boolean enabled )
            {
                super.setEnabled( enabled );
               
                NamedValuesPropertyEditorPresentation.this.overallLabelControl.setEnabled( enabled );
                NamedValuesPropertyEditorPresentation.this.arbitraryValueRadioButton.setEnabled( enabled );
                NamedValuesPropertyEditorPresentation.this.arbitraryValueTextField.setEnabled( enabled && ( NamedValuesPropertyEditorPresentation.this.arbitraryValueRadioButton.getSelection() == true ) );
               
                for( Button b : NamedValuesPropertyEditorPresentation.this.namedValuesRadioButtons )
                {
                    b.setEnabled( enabled );
                }
            }
        };
       
        this.rootComposite.setLayout( glayout( 1, 0, 0 ) );
       
        final int baseIndent = part.getMarginLeft();
        this.rootComposite.setLayoutData( gdvindent( gdhindent( gdhspan( gdhfill(), 2 ), baseIndent ), 5 ) );
       
        final NamedValues namedValuesAnnotation = property.getAnnotation( NamedValues.class );
        final NamedValue[] namedValueAnnotations = namedValuesAnnotation.namedValues();
       
        this.namedValues = new NamedValueLocal[ namedValueAnnotations.length ];
       
        for( int i = 0, n = namedValueAnnotations.length; i < n; i++ )
        {
            final NamedValue x = namedValueAnnotations[ i ];
           
            final String namedValueLabel
                = property.getLocalizationService().text( x.label(), CapitalizationType.FIRST_WORD_ONLY, true );
           
            this.namedValues[ i ] = new NamedValueLocal( x.value(), namedValueLabel );
        }
       
        this.updating = false;
       
        this.defaultArbitraryValue = namedValuesAnnotation.defaultArbitraryValue();
        this.defaultArbitraryValue = property.encodeKeywords( this.defaultArbitraryValue );
       
        final Composite composite = new Composite( this.rootComposite, SWT.NONE );
        composite.setLayoutData( gdhfill() );
        composite.setLayout( glspacing( glayout( 2, 0, 0 ), 2 ) );
       
        final PropertyEditorAssistDecorator decorator = new PropertyEditorAssistDecorator( part, composite );
       
        decorator.control().setLayoutData( gdvalign( gd(), SWT.CENTER ) );
        decorator.addEditorControl( this.rootComposite );
        decorator.addEditorControl( composite );
       
        this.overallLabelControl = new Label( composite, SWT.WRAP );
        this.overallLabelControl.setLayoutData( gd() );
        this.overallLabelControl.setText( property.getLabel( true, CapitalizationType.FIRST_WORD_ONLY, true ) );
        decorator.addEditorControl( this.overallLabelControl );
       
        final SelectionListener selectionListener = new SelectionAdapter()
        {
            @Override
            public void widgetSelected( final SelectionEvent event )
            {
                handleRadioButtonSelectedEvent( event );
            }
        };
       
        final Composite radioButtonsComposite = new Composite( this.rootComposite, SWT.NONE );
        radioButtonsComposite.setLayoutData( gdhindent( gdhfill(), 20 ) );
        radioButtonsComposite.setLayout( glayout( 2, 0, 0, 0, 0 ) );
        decorator.addEditorControl( radioButtonsComposite );
       
        this.radioButtonGroup = new ArrayList<Button>();
       
        final String arbitraryValueLabel
            = property.getLocalizationService().text( namedValuesAnnotation.arbitraryValueLabel(), CapitalizationType.FIRST_WORD_ONLY, true ) + ":";
   
        this.arbitraryValueRadioButton = createRadioButton( radioButtonsComposite, arbitraryValueLabel );
        this.arbitraryValueRadioButton.setLayoutData( gd() );
        this.arbitraryValueRadioButton.addSelectionListener( selectionListener );
        this.radioButtonGroup.add( this.arbitraryValueRadioButton );
        decorator.addEditorControl( this.arbitraryValueRadioButton );

        this.arbitraryValueTextField = new Text( radioButtonsComposite, SWT.BORDER );
        this.arbitraryValueTextField.setLayoutData( gdwhint( gd(), 150 ) );
        decorator.addEditorControl( this.arbitraryValueTextField );
       
        this.arbitraryValueTextField.addModifyListener
        (
            new ModifyListener()
            {
                public void modifyText( final ModifyEvent event )
                {
                    handleArbitraryValueTextFieldChangedEvent( event );
                }
            }
        );
       
        final TextOverlayPainter.Controller textOverlayPainterController = new TextOverlayPainter.Controller()
        {
            @Override
            public String overlay()
            {
                return ( (Value<?>) property() ).getDefaultText();
            }
        };
   
        TextOverlayPainter.install( this.arbitraryValueTextField, textOverlayPainterController );
       
        this.namedValuesRadioButtons = new Button[ this.namedValues.length ];
       
        for( int i = 0; i < this.namedValues.length; i++ )
        {
            final Button rb = createRadioButton( radioButtonsComposite, this.namedValues[ i ].valueName );
            rb.addSelectionListener( selectionListener );
            decorator.addEditorControl( rb );
            this.namedValuesRadioButtons[ i ] = rb;
            this.radioButtonGroup.add( rb );
        }
       
        this.rootComposite.setData( "peditor", this );
       
        this.binding = new NamedValuesBinding();
       
        this.rootComposite.setData( PropertyEditorPart.DATA_BINDING, this.binding );
       
        addControl( this.rootComposite );
    }
   
    private Button createRadioButton( final Composite parent,
                                      final String label )
    {
        final Button b = new Button( parent, SWT.RADIO );
        b.setLayoutData( gdhspan( gd(), 2 ) );
        b.setText( label );
       
        return b;
    }
   
    private void handleRadioButtonSelectedEvent( final SelectionEvent event )
    {
        final Button b = (Button) event.getSource();
       
        if( b == this.arbitraryValueRadioButton )
        {
            setPropertyValue2( this.defaultArbitraryValue );
        }
        else
        {
            for( int i = 0; i < this.namedValuesRadioButtons.length; i++ )
            {
                if( b == this.namedValuesRadioButtons[ i ] )
                {
                    setPropertyValue2( this.namedValues[ i ].value );
                    break;
                }
            }
        }
    }
   
    private void handleArbitraryValueTextFieldChangedEvent( final ModifyEvent event )
    {
        if( this.updating )
        {
            return;
        }
       
        setPropertyValue2( this.arbitraryValueTextField.getText() );
    }
   
    private void update()
    {
        if( this.updating )
        {
            return;
        }
       
        this.updating = true;
       
        try
        {
            final Value<?> val = property();
            final String valueWithDefault = val.text( true );
            NamedValueLocal namedValue = null;

            if( valueWithDefault != null )
            {
                for( int i = 0; i < this.namedValues.length; i++ )
                {
                    final NamedValueLocal nm = this.namedValues[ i ];
                   
                    if( valueWithDefault.equals( nm.value ) )
                    {
                        namedValue = nm;
                        break;
                    }
                }
            }
           
            if( namedValue != null )
            {
                Button buttonToSelect = null;
               
                for( int i = 0; i < this.namedValues.length; i++ )
                {
                    if( namedValue == this.namedValues[ i ] )
                    {
                        buttonToSelect = this.namedValuesRadioButtons[ i ];
                        break;
                    }
                }
               
                if( buttonToSelect == null )
                {
                    throw new IllegalStateException();
                }

                changeRadioButtonSelection( this.radioButtonGroup, buttonToSelect );

                this.arbitraryValueTextField.setEnabled( false );
                this.arbitraryValueTextField.setText( MiscUtil.EMPTY_STRING );
            }
            else
            {
                changeRadioButtonSelection( this.radioButtonGroup, this.arbitraryValueRadioButton );
               
                this.arbitraryValueTextField.setEnabled( true );
               
                final String existingValue = this.arbitraryValueTextField.getText();
                String valueWithoutDefault = val.text( false );
                valueWithoutDefault = ( valueWithoutDefault == null ? "" : valueWithoutDefault );

                if( ! existingValue.equals( valueWithoutDefault ) )
                {
                    this.arbitraryValueTextField.setText( valueWithoutDefault );
                }
            }
        }
        finally
        {
            this.updating = false;
        }
    }
   
    private void setPropertyValue2( final String value )
    {
        try
        {
            property().write( value, true );
        }
        catch( Exception e )
        {
            final EditFailedException editFailedException = EditFailedException.findAsCause( e );
           
            if( editFailedException != null )
            {
                update();
            }
            else
            {
                Sapphire.service( LoggingService.class ).log( e );
            }
        }
    }
   
    @Override
    protected void handleFocusReceivedEvent()
    {
        this.namedValuesRadioButtons[ 0 ].setFocus();
    }

    public static final class Factory extends PropertyEditorPresentationFactory
    {
        @Override
        public PropertyEditorPresentation create( final PropertyEditorPart part, final SwtPresentation parent, final Composite composite )
        {
            final PropertyDef property = part.property().definition();
           
            if( property instanceof ValueProperty && property.hasAnnotation( NamedValues.class ) )
            {
                return new NamedValuesPropertyEditorPresentation( part, parent, composite );
            }
           
            return null;
        }
    }
   
    private static class NamedValueLocal
    {
        public String value;
        public final String valueName;
       
        public NamedValueLocal( final String value,
                                final String valueName )
        {
            this.value = value;
            this.valueName = valueName;
        }
    }
   
    private final class NamedValuesBinding extends AbstractBinding
    {
        public NamedValuesBinding()
        {
            super( NamedValuesPropertyEditorPresentation.this, NamedValuesPropertyEditorPresentation.this.rootComposite );
        }
       
        @Override
        protected void doUpdateModel()
        {
        }
       
        @Override
        protected void doUpdateTarget()
        {
            update();
        }
    }
   
}
TOP

Related Classes of org.eclipse.sapphire.ui.forms.swt.internal.NamedValuesPropertyEditorPresentation$NamedValuesBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.