blob: d59fe035ba6460d941143ac927f2ba1333ac57ce [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005 BEA Systems, Inc.
* 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 API and implementation
******************************************************************************/
package org.eclipse.wst.common.project.facet.ui.internal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.wst.common.project.facet.core.IListener;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentType;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.eclipse.wst.common.project.facet.ui.IDecorationsProvider;
import org.eclipse.wst.common.project.facet.ui.IRuntimeComponentLabelProvider;
/**
* @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
*/
public final class RuntimesPanel
extends Composite
{
private final Label runtimesLabel;
private final CheckboxTableViewer runtimes;
private final Button makePreferredButton;
private final Label runtimeComponentsLabel;
private final TableViewer runtimeComponents;
private final FacetsSelectionPanel facetsSelectionPanel;
private final Map facetFilters;
private final Set filters;
private IRuntime boundRuntime;
private final Set listeners;
public interface IFilter
{
boolean check( IRuntime runtime );
}
public RuntimesPanel( final Composite parent,
final int style,
final FacetsSelectionPanel facetsSelectionPanel )
{
super( parent, style );
this.facetsSelectionPanel = facetsSelectionPanel;
this.facetFilters = new HashMap();
this.filters = new HashSet();
this.listeners = new HashSet();
// Layout the panel.
final GridLayout layout = new GridLayout( 1, false );
layout.marginHeight = 0;
layout.marginWidth = 0;
setLayout( layout );
this.runtimesLabel = new Label( this, SWT.NONE );
this.runtimesLabel.setText( Resources.runtimesLabel );
this.runtimesLabel.setLayoutData( gdhfill() );
this.runtimes = CheckboxTableViewer.newCheckList( this, SWT.BORDER );
this.runtimes.getTable().setLayoutData( gdfill() );
this.runtimes.setContentProvider( new ContentProvider() );
this.runtimes.setLabelProvider( new LabelProvider() );
this.runtimes.setSorter( new Sorter() );
this.runtimes.setInput( new Object() );
this.runtimes.addSelectionChangedListener
(
new ISelectionChangedListener()
{
public void selectionChanged( final SelectionChangedEvent e )
{
handleRuntimeSelectionChanged();
}
}
);
this.runtimes.addCheckStateListener
(
new ICheckStateListener()
{
public void checkStateChanged( final CheckStateChangedEvent e )
{
handleCheckStateChanged( e );
}
}
);
this.makePreferredButton = new Button( this, SWT.PUSH );
this.makePreferredButton.setText( Resources.makePreferredLabel );
GridData gd = halign( new GridData(), GridData.END );
gd = whint( gd, getPreferredWidth( this.makePreferredButton ) + 15 );
this.makePreferredButton.setLayoutData( gd );
this.makePreferredButton.setEnabled( false );
this.makePreferredButton.addSelectionListener
(
new SelectionAdapter()
{
public void widgetSelected( final SelectionEvent e )
{
handleMakePreferred();
}
}
);
this.runtimeComponentsLabel = new Label( this, SWT.NONE );
this.runtimeComponentsLabel.setText( Resources.runtimeCompositionLabel );
this.runtimeComponentsLabel.setLayoutData( gdhfill() );
this.runtimeComponents = new TableViewer( this, SWT.BORDER );
this.runtimeComponents.getTable().setLayoutData( hhint( gdhfill(), 50 ) );
this.runtimeComponents.setContentProvider( new RuntimeComponentsContentProvider() );
this.runtimeComponents.setLabelProvider( new RuntimeComponentsLabelProvider() );
this.runtimeComponents.getTable().setBackground( new Color( null, 255, 255, 206 ) );
final IListener listener = new IListener()
{
public void handle()
{
refresh();
}
};
RuntimeManager.addRuntimeListener( listener );
addDisposeListener
(
new DisposeListener()
{
public void widgetDisposed( final DisposeEvent e )
{
RuntimeManager.removeRuntimeListener( listener );
}
}
);
}
public IRuntime getRuntime()
{
return this.boundRuntime;
}
public void setRuntime( final IRuntime runtime )
{
final IRuntime old = this.boundRuntime;
if( old != null )
{
removeProjectFacetsFilter( old );
this.boundRuntime = null;
this.runtimes.update( old, null );
}
this.boundRuntime = runtime;
if( runtime != null )
{
addProjectFacetsFilter( runtime );
this.runtimes.update( runtime, null );
}
notifyRuntimeListeners();
}
public void addRuntimeListener( final Listener listener )
{
this.listeners.add( listener );
}
public void removeRuntimeListener( final Listener listener )
{
this.listeners.remove( listener );
}
private void notifyRuntimeListeners()
{
for( Iterator itr = this.listeners.iterator(); itr.hasNext(); )
{
( (Listener) itr.next() ).handleEvent( null );
}
}
public void addFilter( final IFilter filter )
{
this.filters.add( filter );
refresh();
}
public void removeFilter( final IFilter filter )
{
this.filters.remove( filter );
refresh();
}
private boolean isFilteredOut( final IRuntime r )
{
for( Iterator itr = RuntimesPanel.this.filters.iterator();
itr.hasNext(); )
{
final IFilter filter = (IFilter) itr.next();
if( ! filter.check( r ) )
{
return true;
}
}
return false;
}
public void refresh()
{
this.runtimes.refresh();
for( Iterator itr = RuntimeManager.getRuntimes().iterator();
itr.hasNext(); )
{
final IRuntime r = (IRuntime) itr.next();
if( isFilteredOut( r ) )
{
this.runtimes.setGrayed( r, true );
}
else
{
this.runtimes.setGrayed( r, false );
}
}
}
private void addProjectFacetsFilter( final IRuntime r )
{
if( ! this.facetFilters.containsKey( r ) )
{
final FacetsSelectionPanel.IFilter filter
= new SupportedFacetsFilter( r );
this.facetFilters.put( r, filter );
this.facetsSelectionPanel.addFilter( filter );
if( ! this.runtimes.getChecked( r ) )
{
this.runtimes.setChecked( r, true );
}
}
}
private void removeProjectFacetsFilter( final IRuntime r )
{
final FacetsSelectionPanel.IFilter filter
= (FacetsSelectionPanel.IFilter) this.facetFilters.remove( r );
this.facetsSelectionPanel.removeFilter( filter );
if( this.runtimes.getChecked( r ) )
{
this.runtimes.setChecked( r, false );
}
}
private void handleCheckStateChanged( final CheckStateChangedEvent e )
{
final IRuntime runtime = (IRuntime) e.getElement();
if( isFilteredOut( runtime ) && e.getChecked() )
{
this.runtimes.setChecked( runtime, false );
return;
}
if( this.facetFilters.containsKey( runtime ) )
{
removeProjectFacetsFilter( runtime );
if( runtime == this.boundRuntime )
{
if( this.facetFilters.isEmpty() )
{
this.boundRuntime = null;
}
else
{
final IRuntime r
= (IRuntime) this.facetFilters.keySet().iterator().next();
this.boundRuntime = r;
this.runtimes.update( r, null );
final IRuntime selection = getSelection();
if( selection != null && selection.equals( r ) )
{
this.makePreferredButton.setEnabled( false );
}
}
this.runtimes.update( runtime, null );
notifyRuntimeListeners();
}
}
else
{
addProjectFacetsFilter( runtime );
if( this.boundRuntime == null )
{
this.boundRuntime = runtime;
this.runtimes.update( runtime, null );
notifyRuntimeListeners();
}
}
}
private void handleRuntimeSelectionChanged()
{
final IRuntime r = getSelection();
if( r != null )
{
if( this.runtimeComponents.getInput() == null ||
! this.runtimeComponents.getInput().equals( r ) )
{
this.runtimeComponents.setInput( r );
}
if( this.runtimes.getChecked( r ) && this.boundRuntime != null &&
! this.boundRuntime.equals( r ) && ! isFilteredOut( r ) )
{
this.makePreferredButton.setEnabled( true );
}
else
{
this.makePreferredButton.setEnabled( false );
}
}
}
private void handleMakePreferred()
{
final IRuntime old = this.boundRuntime;
this.boundRuntime = getSelection();
this.runtimes.refresh( old );
this.runtimes.refresh( this.boundRuntime );
notifyRuntimeListeners();
}
private IRuntime getSelection()
{
final IStructuredSelection ssel
= (IStructuredSelection) this.runtimes.getSelection();
if( ssel.isEmpty() )
{
return null;
}
else
{
return (IRuntime) ssel.getFirstElement();
}
}
private final class ContentProvider
implements IStructuredContentProvider
{
public Object[] getElements( final Object element )
{
return RuntimeManager.getRuntimes().toArray();
}
public void dispose() { }
public void inputChanged( final Viewer viewer,
final Object oldObject,
final Object newObject ) {}
}
private final class LabelProvider
implements ILabelProvider, IFontProvider, IColorProvider
{
private final Color COLOR_GREY
= new Color( null, 160, 160, 164 );
private final ImageRegistry imageRegistry;
private final Font boldFont;
public LabelProvider()
{
this.imageRegistry = new ImageRegistry();
final FontData system
= Display.getCurrent().getSystemFont().getFontData()[ 0 ];
final FontData bold
= new FontData( system.getName(), system.getHeight(), SWT.BOLD );
this.boldFont = new Font( Display.getCurrent(), bold );
}
public String getText( final Object element )
{
return ( (IRuntime) element ).getName();
}
public Image getImage( final Object element )
{
final IRuntime r = (IRuntime) element;
final IRuntimeComponent rc
= (IRuntimeComponent) r.getRuntimeComponents().get( 0 );
final IRuntimeComponentType rct = rc.getRuntimeComponentType();
Image image = this.imageRegistry.get( rct.getId() );
if( image == null )
{
final IDecorationsProvider decprov
= (IDecorationsProvider) rct.getAdapter( IDecorationsProvider.class );
this.imageRegistry.put( rct.getId(), decprov.getIcon() );
image = this.imageRegistry.get( rct.getId() );
}
if( isFilteredOut( r ) )
{
final String greyedId = rct.getId() + "##greyed##";
Image greyed = this.imageRegistry.get( greyedId );
if( greyed == null )
{
greyed = new Image( null, image, SWT.IMAGE_GRAY );
this.imageRegistry.put( greyedId, greyed );
}
return greyed;
}
else
{
return image;
}
}
public Font getFont( final Object element )
{
if( RuntimesPanel.this.boundRuntime != null &&
RuntimesPanel.this.boundRuntime.equals( element ) )
{
return this.boldFont;
}
return null;
}
public Color getForeground( final Object element )
{
if( isFilteredOut( (IRuntime) element ) )
{
return COLOR_GREY;
}
else
{
return null;
}
}
public Color getBackground( final Object element )
{
return null;
}
public void dispose()
{
this.imageRegistry.dispose();
this.boldFont.dispose();
}
public boolean isLabelProperty( final Object element,
final String property )
{
return false;
}
public void addListener( final ILabelProviderListener listener ) {}
public void removeListener( final ILabelProviderListener listener ) {}
}
private final class Sorter
extends ViewerSorter
{
public int compare( final Viewer viewer,
final Object a,
final Object b )
{
final IRuntime r1 = (IRuntime) a;
final boolean r1fo = isFilteredOut( r1 );
final IRuntime r2 = (IRuntime) b;
final boolean r2fo = isFilteredOut( r2 );
if( r1fo && ! r2fo )
{
return 1;
}
else if( ! r1fo && r2fo )
{
return -1;
}
else
{
return r1.getName().compareToIgnoreCase( r2.getName() );
}
}
}
private final class RuntimeComponentsContentProvider
implements IStructuredContentProvider
{
public Object[] getElements( final Object element )
{
final IRuntime r = (IRuntime) element;
return r.getRuntimeComponents().toArray();
}
public void dispose() { }
public void inputChanged( final Viewer viewer,
final Object oldObject,
final Object newObject ) {}
}
private final class RuntimeComponentsLabelProvider
implements ILabelProvider
{
private final ImageRegistry imageRegistry = new ImageRegistry();
public String getText( final Object element )
{
final IRuntimeComponent comp = (IRuntimeComponent) element;
final IRuntimeComponentLabelProvider provider
= (IRuntimeComponentLabelProvider) comp.getAdapter( IRuntimeComponentLabelProvider.class );
if( provider == null )
{
final StringBuffer label = new StringBuffer();
label.append( comp.getRuntimeComponentType().getId() );
label.append( ' ' );
label.append( comp.getRuntimeComponentVersion().getVersionString() );
return label.toString();
}
else
{
return provider.getLabel();
}
}
public Image getImage( final Object element )
{
final IRuntimeComponent rc = (IRuntimeComponent) element;
final IRuntimeComponentType rct = rc.getRuntimeComponentType();
Image image = this.imageRegistry.get( rct.getId() );
if( image == null )
{
final IDecorationsProvider decprov
= (IDecorationsProvider) rct.getAdapter( IDecorationsProvider.class );
this.imageRegistry.put( rct.getId(), decprov.getIcon() );
image = this.imageRegistry.get( rct.getId() );
}
return image;
}
public void dispose()
{
this.imageRegistry.dispose();
}
public boolean isLabelProperty( final Object element,
final String property )
{
return false;
}
public void addListener( final ILabelProviderListener listener ) {}
public void removeListener( final ILabelProviderListener listener ) {}
}
private static final class SupportedFacetsFilter
implements FacetsSelectionPanel.IFilter
{
private final IRuntime runtime;
public SupportedFacetsFilter( final IRuntime runtime )
{
this.runtime = runtime;
}
public boolean check( final IProjectFacetVersion fv )
{
return this.runtime.supports( fv );
}
}
private static final GridData gdfill()
{
return new GridData( SWT.FILL, SWT.FILL, true, true );
}
private static final GridData gdhfill()
{
return new GridData( GridData.FILL_HORIZONTAL );
}
private static final GridData whint( final GridData gd,
final int width )
{
gd.widthHint = width;
return gd;
}
private static final GridData hhint( final GridData gd,
final int height )
{
gd.heightHint = height;
return gd;
}
private static final GridData halign( final GridData gd,
final int alignment )
{
gd.horizontalAlignment = alignment;
return gd;
}
private static final int getPreferredWidth( final Control control )
{
return control.computeSize( SWT.DEFAULT, SWT.DEFAULT ).x;
}
private static final class Resources
extends NLS
{
public static String runtimesLabel;
public static String runtimeCompositionLabel;
public static String makePreferredLabel;
static
{
initializeMessages( RuntimesPanel.class.getName(),
Resources.class );
}
}
}