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

Source Code of org.eclipse.sapphire.ui.forms.internal.OutlineNodeAddActionHandlerFactory$ListPropertyActionHandler

/******************************************************************************
* 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.internal;

import static java.util.Collections.sort;

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

import org.eclipse.sapphire.DisposeEvent;
import org.eclipse.sapphire.Element;
import org.eclipse.sapphire.ElementHandle;
import org.eclipse.sapphire.ElementList;
import org.eclipse.sapphire.ElementType;
import org.eclipse.sapphire.Event;
import org.eclipse.sapphire.FilteredListener;
import org.eclipse.sapphire.ImageData;
import org.eclipse.sapphire.ImpliedElementProperty;
import org.eclipse.sapphire.Listener;
import org.eclipse.sapphire.LoggingService;
import org.eclipse.sapphire.Property;
import org.eclipse.sapphire.PropertyEvent;
import org.eclipse.sapphire.Sapphire;
import org.eclipse.sapphire.modeling.CapitalizationType;
import org.eclipse.sapphire.modeling.EditFailedException;
import org.eclipse.sapphire.services.PossibleTypesService;
import org.eclipse.sapphire.ui.PartVisibilityEvent;
import org.eclipse.sapphire.ui.Presentation;
import org.eclipse.sapphire.ui.SapphireAction;
import org.eclipse.sapphire.ui.SapphireActionHandler;
import org.eclipse.sapphire.ui.SapphireActionHandlerFactory;
import org.eclipse.sapphire.ui.def.ActionHandlerDef;
import org.eclipse.sapphire.ui.def.ActionHandlerFactoryDef;
import org.eclipse.sapphire.ui.forms.MasterDetailsContentNodePart;
import org.eclipse.sapphire.ui.forms.MasterDetailsContentOutline;
import org.eclipse.sapphire.ui.forms.MasterDetailsEditorPagePart;

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

public final class OutlineNodeAddActionHandlerFactory extends SapphireActionHandlerFactory
{
    public static final String ID_BASE = "Sapphire.Add.";
   
    private Listener possibleTypesServiceListener;
    private Listener nodeFactoryListener;
   
    @Override
    public void init( final SapphireAction action,
                      final ActionHandlerFactoryDef def )
    {
        super.init( action, def );
       
        this.possibleTypesServiceListener = new Listener()
        {
            @Override
            public void handle( final Event event )
            {
                broadcast( new Event() );
            }
        };
       
        this.nodeFactoryListener = new FilteredListener<PartVisibilityEvent>()
        {
            @Override
            protected void handleTypedEvent( final PartVisibilityEvent event )
            {
                broadcast( new Event() );
            }
        };
       
        final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) getPart();

        node.executeAfterInitialization
        (
            new Runnable()
            {
                public void run()
                {
                    for( MasterDetailsContentNodePart.NodeFactory factory : node.factories() )
                    {
                        factory.attach( OutlineNodeAddActionHandlerFactory.this.nodeFactoryListener );
                       
                        final PossibleTypesService possibleTypesService = factory.property().service( PossibleTypesService.class );
                        possibleTypesService.attach( OutlineNodeAddActionHandlerFactory.this.possibleTypesServiceListener );
                    }
                   
                    broadcast( new Event() );
                }
            }
        );
    }

    @Override
    public List<SapphireActionHandler> create()
    {
        final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) getPart();
        final List<SapphireActionHandler> handlers = new ArrayList<SapphireActionHandler>();
       
        for( MasterDetailsContentNodePart.NodeFactory factory : node.factories() )
        {
            final Property property = factory.property();
           
            if( factory.visible() && ! property.definition().isReadOnly() )
            {
                final PossibleTypesService possibleTypesService = property.service( PossibleTypesService.class );
   
                if( property instanceof ElementList )
                {
                    for( final ElementType memberType : possibleTypesService.types() )
                    {
                        final ListPropertyActionHandler handler = new ListPropertyActionHandler( (ElementList<?>) property, memberType );
                        handlers.add( handler );
                    }
                }
                else if( property instanceof ElementHandle && ! ( property.definition() instanceof ImpliedElementProperty ) )
                {
                    for( final ElementType memberType : possibleTypesService.types() )
                    {
                        final ElementPropertyActionHandler handler = new ElementPropertyActionHandler( (ElementHandle<?>) property, memberType );
                        handlers.add( handler );
                    }
                }
                else
                {
                    throw new IllegalStateException();
                }
            }
           
            sort
            (
                handlers,
                new Comparator<SapphireActionHandler>()
                {
                    @Override
                    public int compare( final SapphireActionHandler x, SapphireActionHandler y )
                    {
                        final String xLabel = ( (AbstractActionHandler) x ).type().getLabel( true, CapitalizationType.NO_CAPS, false );
                        final String yLabel = ( (AbstractActionHandler) y ).type().getLabel( true, CapitalizationType.NO_CAPS, false );
                        return xLabel.compareToIgnoreCase( yLabel );
                    }
                }
            );
        }
       
        return handlers;
    }
   
    @Override
    public void dispose()
    {
        super.dispose();
       
        final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) getPart();

        for( final MasterDetailsContentNodePart.NodeFactory factory : node.factories() )
        {
            factory.detach( this.nodeFactoryListener );
           
            final Property property = factory.property();
           
            if( ! property.disposed() )
            {
                final PossibleTypesService possibleTypesService = property.service( PossibleTypesService.class );
                possibleTypesService.detach( this.possibleTypesServiceListener );
            }
        }
    }

    private static abstract class AbstractActionHandler extends SapphireActionHandler
    {
        private final Property property;
        private final ElementType type;
        private MasterDetailsContentOutline contentTree;
       
        public AbstractActionHandler( final Property property, final ElementType type )
        {
            this.property = property;
            this.type = type;
        }
   
        @Override
        public void init( final SapphireAction action,
                          final ActionHandlerDef def )
        {
            super.init( action, def );
           
            setId( ID_BASE + this.type.getSimpleName() );
            setLabel( this.type.getLabel( true, CapitalizationType.NO_CAPS, false ) );
           
            final ImageData typeSpecificAddImage = this.type.image();
           
            if( typeSpecificAddImage != null )
            {
                addImage( typeSpecificAddImage );
            }
           
            this.contentTree = ( (MasterDetailsContentNodePart) getPart() ).getContentTree();
           
            final Listener contentTreeListener = new Listener()
            {
                @Override
                public void handle( final Event event )
                {
                    if( event instanceof MasterDetailsContentOutline.FilterChangedEvent )
                    {
                        refreshEnablementState();
                    }
                }
            };
           
            this.contentTree.attach( contentTreeListener );
           
            refreshEnablementState();
           
            attach
            (
                new Listener()
                {
                    @Override
                    public void handle( final Event event )
                    {
                        if( event instanceof DisposeEvent )
                        {
                            AbstractActionHandler.this.contentTree.detach( contentTreeListener );
                        }
                    }
                }
            );
        }
       
        public final ElementType type()
        {
            return this.type;
        }
   
        protected final void refreshEnablementState()
        {
            setEnabled( computeEnablementState() );
        }
       
        protected boolean computeEnablementState()
        {
            return ( this.contentTree != null && this.contentTree.getFilterText().length() == 0 );
        }
       
        public Property property()
        {
            return this.property;
        }
       
        @Override
        protected final Object run( final Presentation context )
        {
            final MasterDetailsContentNodePart node = (MasterDetailsContentNodePart) getPart();
           
            Element newModelElement = null;
           
            try
            {
                newModelElement = create( this.property, this.type );
            }
            catch( Exception e )
            {
                // Log this exception unless the cause is EditFailedException. These exception
                // are the result of the user declining a particular action that is necessary
                // before the edit can happen (such as making a file writable).
               
                final EditFailedException editFailedException = EditFailedException.findAsCause( e );
               
                if( editFailedException == null )
                {
                    Sapphire.service( LoggingService.class ).log( e );
                }
            }

            if( newModelElement != null )
            {
                for( MasterDetailsContentNodePart n : node.nodes().visible() )
                {
                    if( n.getModelElement() == newModelElement )
                    {
                        n.select();
                        getPart().nearest( MasterDetailsEditorPagePart.class ).setFocusOnDetails();
                        break;
                    }
                }
            }
           
            return newModelElement;
        }
       
        protected abstract Element create( Property property, ElementType type );
    }
   
    private static final class ListPropertyActionHandler extends AbstractActionHandler
    {
        public ListPropertyActionHandler( final ElementList<?> property, final ElementType type )
        {
            super( property, type );
        }
       
        @Override
        protected Element create( final Property property, final ElementType type )
        {
            return ( (ElementList<?>) property ).insert( type );
        }
    }

    private static final class ElementPropertyActionHandler extends AbstractActionHandler
    {
        public ElementPropertyActionHandler( final ElementHandle<?> property, final ElementType type )
        {
            super( property, type );
        }
       
        @Override
        public void init( final SapphireAction action, final ActionHandlerDef def )
        {
            super.init( action, def );
           
            final Listener listener = new FilteredListener<PropertyEvent>()
            {
                @Override
                protected void handleTypedEvent( final PropertyEvent event )
                {
                    refreshEnablementState();
                }
            };
           
            property().attach( listener );
           
            attach
            (
                new Listener()
                {
                    @Override
                    public void handle( final Event event )
                    {
                        if( event instanceof DisposeEvent )
                        {
                            property().detach( listener );
                        }
                    }
                }
            );
        }

        @Override
        public ElementHandle<?> property()
        {
            return (ElementHandle<?>) super.property();
        }
       
        @Override
        protected Element create( final Property property, final ElementType type )
        {
            return ( (ElementHandle<?>) property ).content( true, type );
        }

        @Override
        protected boolean computeEnablementState()
        {
            boolean state = super.computeEnablementState();
           
            if( state == true )
            {
                state = ( property().content() == null );
            }
           
            return state;
        }
    }

}
TOP

Related Classes of org.eclipse.sapphire.ui.forms.internal.OutlineNodeAddActionHandlerFactory$ListPropertyActionHandler

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.