/******************************************************************************
* Copyright (c) 2010-2013, Linagora
*
* 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:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.services.eip.designer.tabbedproperties;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import com.ebmwebsourcing.petals.services.eip.designer.edit.commands.NodeSwitchCommand;
import com.ebmwebsourcing.petals.services.eip.designer.edit.parts.AbstractNodeEditPart;
import com.ebmwebsourcing.petals.services.eip.designer.edit.parts.EipNodeEditPart;
import com.ebmwebsourcing.petals.services.eip.designer.model.EipConnection;
import com.ebmwebsourcing.petals.services.eip.designer.model.EipNode;
import com.ebmwebsourcing.petals.services.eip.designer.model.Endpoint;
/**
* The section for EIP's outgoing connections.
* <p>
* This section helps to sort connections and define the invocation order.
* </p>
*
* @author Vincent Zurczak - EBM WebSourcing
*/
public class EipOutgoingConnectionsSection extends AbstractPropertySection implements PropertyChangeListener {
private EipNode eip;
private TableViewer outgoingConnectionsViewer;
/**
* Constructor.
*/
public EipOutgoingConnectionsSection() {
// nothing
}
/*
* (non-Jsdoc)
* @see java.beans.PropertyChangeListener
* #propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange( PropertyChangeEvent evt ) {
if( EipNode.PROPERTY_OUTGOING_CONNECTION.equals( evt.getPropertyName()))
refresh();
}
/*
* (non-Jsdoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #shouldUseExtraSpace()
*/
@Override
public boolean shouldUseExtraSpace() {
return true;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
*/
@Override
public void createControls( Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage ) {
// Create the container
super.createControls( parent, aTabbedPropertySheetPage );
Composite container = getWidgetFactory().createComposite( parent, SWT.NONE );
GridLayout layout = new GridLayout( 2, false );
layout.marginTop = 10;
layout.marginBottom = 8;
container.setLayout( layout );
// Add the table
String[] PROPERTIES = new String[] { "Index", "Connection Target" };
Table table = getWidgetFactory().createTable( container, SWT.SINGLE | SWT.FULL_SELECTION | SWT.HIDE_SELECTION );
table.setHeaderVisible( true );
GridData layoutData = new GridData( GridData.FILL_BOTH );
layoutData.horizontalIndent = 7;
table.setLayoutData( layoutData );
TableLayout tlayout = new TableLayout();
tlayout.addColumnData( new ColumnWeightData( 10, 70, true ));
tlayout.addColumnData( new ColumnWeightData( 90, 300, true ));
table.setLayout( tlayout );
TableColumn column = new TableColumn( table, SWT.CENTER );
column.setText( PROPERTIES[ 0 ]);
column = new TableColumn( table, SWT.LEFT );
column.setText( PROPERTIES[ 1 ]);
this.outgoingConnectionsViewer = new TableViewer( table );
this.outgoingConnectionsViewer.setColumnProperties( PROPERTIES );
this.outgoingConnectionsViewer.setContentProvider( new ArrayContentProvider());
this.outgoingConnectionsViewer.setLabelProvider( new ITableLabelProvider() {
public void addListener( ILabelProviderListener listener ) {
// nothing
}
public void dispose() {
// nothing
}
public boolean isLabelProperty( Object element, String property ) {
return false;
}
public void removeListener( ILabelProviderListener listener ) {
// nothing
}
public Image getColumnImage( Object element, int columnIndex ) {
return null;
}
public String getColumnText( Object element, int columnIndex ) {
StringBuilder sb = new StringBuilder();
EipConnection conn = (EipConnection) element;
if( columnIndex == 0 ) {
int index = -1;
if( conn.getSource() != null )
index = conn.getSource().getOutgoingConnections().indexOf( conn );
if( index != -1 ) {
sb.append( ++ index );
sb.append( ". " );
}
} else {
if( conn.getTarget() instanceof EipNode )
sb.append( conn.getTarget().getServiceName() + " - EIP" );
else if( conn.getTarget() instanceof Endpoint )
sb.append( conn.getTarget().getServiceName() + " - Petals Service" );
}
return sb.toString();
}
});
// Add the buttons
Composite buttonsComposite = getWidgetFactory().createComposite( container );
layout = new GridLayout();
layout.marginHeight = 0;
buttonsComposite.setLayout( layout );
buttonsComposite.setLayoutData( new GridData( GridData.FILL_VERTICAL ));
final Button upButton = getWidgetFactory().createButton( buttonsComposite, "Up", SWT.PUSH );
upButton.setToolTipText( "Push up this target node and its connection" );
layoutData = new GridData();
layoutData.widthHint = 100;
upButton.setLayoutData( layoutData );
upButton.setEnabled( false );
final Button downButton = getWidgetFactory().createButton( buttonsComposite, "Down", SWT.PUSH );
downButton.setToolTipText( "Pull down this target node and its connection" );
layoutData = new GridData();
layoutData.widthHint = 100;
downButton.setLayoutData( layoutData );
downButton.setEnabled( false );
// Add the listeners
this.outgoingConnectionsViewer.addSelectionChangedListener( new ISelectionChangedListener() {
public void selectionChanged( SelectionChangedEvent event ) {
EipConnection conn = (EipConnection) ((IStructuredSelection) event.getSelection()).getFirstElement();
int size = EipOutgoingConnectionsSection.this.outgoingConnectionsViewer.getTable().getItemCount();
int pos = conn.getSource().getOutgoingConnections().indexOf( conn );
upButton.setEnabled( pos > 0 );
downButton.setEnabled( pos < size-1 );
}
});
upButton.addSelectionListener( new SelectionListener() {
public void widgetSelected( SelectionEvent e ) {
moveSelectedConnection( true );
}
public void widgetDefaultSelected( SelectionEvent e ) {
moveSelectedConnection( true );
}
});
downButton.addSelectionListener( new SelectionListener() {
public void widgetSelected( SelectionEvent e ) {
moveSelectedConnection( false );
}
public void widgetDefaultSelected( SelectionEvent e ) {
moveSelectedConnection( false );
}
});
}
/**
* Moves the connection target in the invocation order.
* @param conn
* @param up
*/
private void moveSelectedConnection( boolean up ) {
// Get the connections
EipConnection conn = (EipConnection) ((IStructuredSelection) this.outgoingConnectionsViewer.getSelection()).getFirstElement();
int index1 = conn.getSource().getOutgoingConnections().indexOf( conn );
EipConnection conn2;
if( up )
conn2 = conn.getSource().getOutgoingConnections().get( index1 - 1 );
else
conn2 = conn.getSource().getOutgoingConnections().get( index1 + 1 );
// Get the target edit parts
IEditorPart part = getPart().getSite().getPage().getActiveEditor();
Map<?,?> map = ((GraphicalViewer) part.getAdapter( GraphicalViewer.class )).getEditPartRegistry();
List<AbstractNodeEditPart> parts = new ArrayList<AbstractNodeEditPart> ();
for( Map.Entry<?,?> entry : map.entrySet()) {
if( entry.getKey().equals( conn.getTarget())
|| entry.getKey().equals( conn2.getTarget())) {
if( entry.getValue() instanceof AbstractNodeEditPart )
parts.add((AbstractNodeEditPart) entry.getValue());
}
}
// Create and execute the command
if( parts.size() == 2 ) {
NodeSwitchCommand cmd = new NodeSwitchCommand( parts.get( 0 ), parts.get( 1 ));
CommandStack commandStack = (CommandStack) part.getAdapter( CommandStack.class );
if( commandStack != null )
commandStack.execute( cmd );
}
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #setInput(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
@Override
public void setInput( IWorkbenchPart part, ISelection selection ) {
super.setInput( part, selection );
// Do not listen to model changes from the previous input
if( this.eip != null )
this.eip.removePropertyChangeListener( this );
if( selection instanceof IStructuredSelection ) {
Object input = ((IStructuredSelection) selection).getFirstElement();
if( input instanceof EipNodeEditPart )
this.eip = (EipNode) ((EipNodeEditPart) input).getModel();
}
// Listen to changes in the new model
if( this.eip != null )
this.eip.addPropertyChangeListener( this );
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #refresh()
*/
@Override
public void refresh() {
if( this.outgoingConnectionsViewer != null
&& ! this.outgoingConnectionsViewer.getTable().isDisposed()
&& this.eip != null ) {
this.outgoingConnectionsViewer.setInput( this.eip.getOutgoingConnections());
this.outgoingConnectionsViewer.refresh();
// Invoke pack to force the use of the ColumnWeightData
this.outgoingConnectionsViewer.getTable().pack();
}
}
}