/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.designer.internal.ui.views.attributes.page;

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

import org.eclipse.birt.report.designer.core.model.SessionHandleAdapter;
import org.eclipse.birt.report.designer.internal.ui.views.attributes.provider.FilterHandleProvider;
import org.eclipse.birt.report.designer.internal.ui.views.attributes.provider.GroupHandleProvider;
import org.eclipse.birt.report.designer.internal.ui.views.attributes.provider.IFormHandleProvider;
import org.eclipse.birt.report.designer.nls.Messages;
import org.eclipse.birt.report.model.api.CommandStack;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.ParamBindingHandle;
import org.eclipse.birt.report.model.api.ReportItemHandle;
import org.eclipse.birt.report.model.api.activity.NotificationEvent;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

/**
 * The contained page of Filters, Sorting, Groups and Hight-lights.The page
 * provides all table-based operations such as moving, adding, deleting. The
 * Filters, Sorting, Groups and Hight-lights will use FormPage as UI and
 * provides corresponding Model processors.
 * 
 * 
 */
public class FormPage extends AttributePage
{

	/**
	 * The simple UI type,not support moving and editing operations.
	 */
	public final static int SIMPLE_FUNCTION = 1;

	/**
	 * The normal function UI type.
	 */
	public final static int NORMAL_FUNCTION = 2;

	/**
	 * The full function UI type with editing operations
	 */
	public final static int FULL_FUNCTION = 3;
	
	/**
	 * The full function UI type with editing operations, and the buttons are horizontal
	 */
	public final static int FULL_FUNCTION_HORIZONTAL = 4;
	

	/**
	 * The UI type.
	 */
	private int style;

	/**
	 * When Add button is clicked, whether invoke dialogs.
	 */
	private boolean bAddWithDialog;

	/**
	 * The prompted text that present the FormPage served as Filters, Sorting,
	 * Groups and Hight-lights.
	 */
	private Label title;

	/**
	 * Buttons for moving operations.
	 */
	protected Button btnUp, btnDown;

	/**
	 * Buttons for modifying operations.
	 */
	protected Button btnAdd, btnDel, btnEdit;

	/**
	 * The table widget that present the data of Filters, Sorting, Groups or
	 * Hight-lights.
	 */
	private Table table;

	/**
	 * The TableViewer of the table widget.
	 */
	private TableViewer tableViewer;

	/**
	 * The data provider and processor.
	 */
	private IFormHandleProvider provider;

	/**
	 * The current selection index.
	 */
	private int selectIndex;

	/**
	 * Constructor
	 * 
	 * @param parent
	 *            A widget which will be the parent of the new instance (cannot
	 *            be null)
	 * @param style
	 *            The style of widget to construct
	 * @param provider
	 *            The data provider and processor
	 */
	public FormPage( Composite parent, int style, IFormHandleProvider provider,
			boolean bAddWithDialog )
	{
		super( parent, SWT.NONE );
		assert provider != null;
		this.provider = provider;
		this.style = style;
		this.bAddWithDialog = bAddWithDialog;
		createControl( );
	}

	protected TableViewer getTableViewer( )
	{
		return tableViewer;
	}

	/**
	 * Constructor
	 * 
	 * @param parent
	 *            A widget which will be the parent of the new instance (cannot
	 *            be null)
	 * @param style
	 *            The style of widget to construct
	 * @param provider
	 *            The data provider and processor
	 */
	public FormPage( Composite parent, int style, IFormHandleProvider provider )
	{
		this( parent, style, provider, false );
	}

	private void enableUI( boolean enabled )
	{
		if ( tableViewer != null )
		{
			table.setEnabled( enabled );
			if ( style != SIMPLE_FUNCTION )
			{
				btnUp.setEnabled( enabled );
				btnDown.setEnabled( enabled );
			}
			btnAdd.setEnabled( enabled );
			btnDel.setEnabled( enabled );

			if ( style == FULL_FUNCTION || style == FULL_FUNCTION_HORIZONTAL)
			{
				btnEdit.setEnabled( enabled );
			}

			if ( enabled )
			{
				updateArraw( );
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.designer.internal.ui.views.attributes.page.TabPage#setInput(java.util.List)
	 */
	public void setInput( List elements )
	{
		if ( elements.size( ) != 1 )
		{
			enableUI( false );
			return;
		}

		enableUI( true );
		super.setInput( elements );
		tableViewer.setInput( elements );
		updateArraw( );
		updateBindingParameters( );
	}

	/**
	 * Creates UI widgets
	 * 
	 */
	protected void createControl( )
	{
		title = new Label( this, SWT.NONE );
		title.setText( provider.getTitle( ) );

		table = new Table( this, SWT.SINGLE
				| SWT.BORDER
				| SWT.H_SCROLL
				| SWT.V_SCROLL
				| SWT.FULL_SELECTION );
		table.setLinesVisible( true );
		table.setHeaderVisible( true );
		String[] columnNames = provider.getColumnNames( );
		for ( int i = 0; i < columnNames.length; i++ )
		{
			TableColumn column = new TableColumn( table, SWT.LEFT );
			column.setText( columnNames[i] );
			column.setWidth( provider.getColumnWidths( )[i] );
		}
		table.addKeyListener( new KeyAdapter( ) {

			public void keyPressed( KeyEvent e )
			{
				if ( e.keyCode == SWT.DEL )
				{
					int itemCount = table.getItemCount( );
					int pos = table.getSelectionIndex( );
					if ( selectIndex == itemCount - 1 )
					{
						selectIndex--;
					}
					try
					{
						provider.doDeleteItem( pos );
					}
					catch ( Exception e1 )
					{
						WidgetUtil.processError( FormPage.this.getShell( ), e1 );
					}
				}else
				if(e.character == '\r') // return is pressed
				{
					if ( style == FULL_FUNCTION || style == FULL_FUNCTION_HORIZONTAL)
					{
						edit( );
					}
				}
			}
		} );

		table.addSelectionListener( new SelectionAdapter( ) {

			public void widgetSelected( SelectionEvent e )
			{
				selectIndex = table.getSelectionIndex( );
				updateArraw( );
			}
		} );
		table.addMouseListener( new MouseAdapter( ) {

			public void mouseDoubleClick( MouseEvent e )
			{
				if ( style == FULL_FUNCTION || style == FULL_FUNCTION_HORIZONTAL)
				{
					edit( );
				}
			}
		} );
		createTableViewer( );

		btnDel = new Button( this, SWT.BORDER );
		btnDel.setText( Messages.getString( "FormPage.Button.Delete" ) ); //$NON-NLS-1$

		btnDel.addSelectionListener( new SelectionAdapter( ) {

			public void widgetSelected( SelectionEvent e )
			{
				if ( tableViewer.isCellEditorActive( ) )
				{
					tableViewer.cancelEditing( );
				}
				int pos = table.getSelectionIndex( );
				if ( pos == -1 )
				{
					table.setFocus( );
					return;
				}
				selectIndex = pos;
				int itemCount = table.getItemCount( );
				if ( selectIndex == itemCount - 1 )
				{
					selectIndex--;
				}
				try
				{
					provider.doDeleteItem( pos );
				}
				catch ( Exception e1 )
				{
					WidgetUtil.processError( FormPage.this.getShell( ), e1 );
				}
				updateArraw( );
			}
		} );
		btnAdd = new Button( this, SWT.BORDER );
		if ( bAddWithDialog == true )
		{
			btnAdd.setText( Messages.getString( "FormPage.Button.AddWithDialog" ) ); //$NON-NLS-1$
		}
		else
		{
			btnAdd.setText( Messages.getString( "FormPage.Button.Add" ) ); //$NON-NLS-1$
		}

		btnAdd.addSelectionListener( new SelectionAdapter( ) {

			public void widgetSelected( SelectionEvent e )
			{
				CommandStack stack = getActionStack( );
				stack.startTrans( Messages.getString( "FormPage.Menu.ModifyProperty" ) ); //$NON-NLS-1$
				int pos = table.getSelectionIndex( );
				boolean sucess = false;
				try
				{
					sucess = provider.doAddItem( pos );
				}
				catch ( Exception e1 )
				{
					stack.rollback( );
					WidgetUtil.processError( FormPage.this.getShell( ), e1 );
					return;
				}
				if ( sucess )
				{
					stack.commit( );
				}
				else
				{
					stack.rollback( );
				}
				table.setSelection( table.getItemCount( ) - 1 );
				updateArraw( );

			}
		} );

		if ( style == FULL_FUNCTION || style == FULL_FUNCTION_HORIZONTAL)
		{
			btnEdit = new Button( this, SWT.BORDER );
			if ( bAddWithDialog == true )
			{
				btnEdit.setText( Messages.getString( "FormPage.Button.EditWithDialog" ) ); //$NON-NLS-1$
			}
			else
			{
				btnEdit.setText( Messages.getString( "FormPage.Button.Edit" ) ); //$NON-NLS-1$
			}

			btnEdit.addSelectionListener( new SelectionAdapter( ) {

				public void widgetSelected( SelectionEvent e )
				{
					edit( );
				}
			} );
		}

		if ( style != SIMPLE_FUNCTION )
		{
			btnUp = new Button( this, SWT.BORDER );
			btnUp.setText( Messages.getString( "FormPage.Button.Up" ) );
			btnUp.setToolTipText( Messages.getString( "FormPage.toolTipText.Up" ) );
			btnUp.addSelectionListener( new SelectionAdapter( ) {

				public void widgetSelected( SelectionEvent e )
				{
					if ( tableViewer.isCellEditorActive( ) )
					{
						tableViewer.cancelEditing( );
					}
					int oldPos = table.getSelectionIndex( );

					selectIndex = oldPos - 1;
					moveItem( oldPos, oldPos - 1 );
					updateArraw( );
				}
			} );

			btnDown = new Button( this, SWT.BORDER );
			btnDown.setText( Messages.getString( "FormPage.Button.Down" ) );
			btnDown.setToolTipText( Messages.getString( "FormPage.toolTipText.Down" ) );
			btnDown.addSelectionListener( new SelectionAdapter( ) {

				public void widgetSelected( SelectionEvent e )
				{
					if ( tableViewer.isCellEditorActive( ) )
					{
						tableViewer.cancelEditing( );
					}
					int oldPos = table.getSelectionIndex( );

					selectIndex = oldPos + 1;
					moveItem( oldPos, oldPos + 1 );
					updateArraw( );
				}
			} );

		}
		switch ( style )
		{
			case SIMPLE_FUNCTION :
				simpleLayout( );
				break;
			case NORMAL_FUNCTION :
				normallLayout( );
				break;
			case FULL_FUNCTION :
				fullLayout( );
				break;
			case FULL_FUNCTION_HORIZONTAL:
				fullLayoutHorizontal();
				break;
		}

	}

	private void edit( )
	{
		int pos = table.getSelectionIndex( );
		if ( pos == -1 )
		{
			table.setFocus( );
			return;
		}
		CommandStack stack = getActionStack( );
		stack.startTrans( Messages.getString( "FormPage.Menu.ModifyProperty" ) ); //$NON-NLS-1$
		if ( !provider.doEditItem( pos ) )
		{
			stack.rollback( );
			return;
		}
		stack.commit( );
		table.setSelection( pos );

	}

	private void updateArraw( )
	{
		if ( style == SIMPLE_FUNCTION )
		{
			return;
		}
		int selectIndex = table.getSelectionIndex( );
		int min = 0;
		int max = table.getItemCount( ) - 1;
		// if ( !( provider instanceof GroupHandleProvider ) )
		// {
		// max--;
		// }
		if ( selectIndex <= 0 )
			btnUp.setEnabled( false );
		else
			btnUp.setEnabled( true );
		if ( selectIndex >= max || ( selectIndex == -1 ) )
		{
			btnDown.setEnabled( false );
			if ( selectIndex > max )
				btnUp.setEnabled( false );
		}
		else
			btnDown.setEnabled( true );
		if ( ( min <= selectIndex ) && ( selectIndex <= max ) )
		{
			btnDel.setEnabled( true );
			if ( btnEdit != null )
				btnEdit.setEnabled( true );
		}
		else
		{
			btnDel.setEnabled( false );
			if ( btnEdit != null )
				btnEdit.setEnabled( false );
		}
	}

	private void updateBindingParameters( )
	{
		if ( provider instanceof FilterHandleProvider )
		{
			ParamBindingHandle[] bindingParams = null;

			if ( input.get( 0 ) instanceof ReportItemHandle )
			{
				ReportItemHandle inputHandle = (ReportItemHandle) input.get( 0 );
				List list = new ArrayList( );
				for ( Iterator iterator = inputHandle.paramBindingsIterator( ); iterator.hasNext( ); )
				{
					ParamBindingHandle handle = (ParamBindingHandle) iterator.next( );
					list.add( handle );
				}
				bindingParams = new ParamBindingHandle[list.size( )];
				list.toArray( bindingParams );
			}
			( (FilterHandleProvider) provider ).setBindingParams( bindingParams );
		}
	}

	/**
	 * Changes the position of one item to a new location.
	 * 
	 * @param oldPos
	 *            The old position
	 * @param newPos
	 *            The new Position
	 */
	private void moveItem( int oldPos, int newPos )
	{
		try
		{
			provider.doMoveItem( oldPos, newPos );
		}
		catch ( Exception e )
		{
			WidgetUtil.processError( FormPage.this.getShell( ), e );
		}
	}

	/**
	 * Creates the TableViewer and set all kinds of processors.
	 * 
	 */
	private void createTableViewer( )
	{

		tableViewer = new TableViewer( table );
		tableViewer.setUseHashlookup( true );
		tableViewer.setColumnProperties( provider.getColumnNames( ) );
		tableViewer.setCellEditors( provider.getEditors( table ) );
		tableViewer.setContentProvider( new FormContentProvider( ) );
		tableViewer.setLabelProvider( new FormLabelProvider( ) );
		tableViewer.setCellModifier( new FormCellModifier( ) );

	}

	protected void simpleLayout( )
	{
		FormLayout layout = new FormLayout( );
		layout.marginHeight = WidgetUtil.SPACING;
		layout.marginWidth = WidgetUtil.SPACING;
		layout.spacing = WidgetUtil.SPACING;
		setLayout( layout );
		// int height = QUICK_BUTTON_HEIGHT - 2;
		FormData data = new FormData( );
		data.left = new FormAttachment( title, 50, SWT.RIGHT );
		// data.height = Math.max( btnAdd.computeSize( -1, -1 ).y, height );
		btnAdd.setLayoutData( data );

		data = new FormData( );
		data.left = new FormAttachment( btnAdd, 0, SWT.RIGHT );
		// data.height = data.height = Math.max( btnDel.computeSize( -1, -1 ).y,
		// height );
		btnDel.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnAdd, 0, SWT.BOTTOM );
		data.left = new FormAttachment( title, 0, SWT.LEFT );
		int width[] = provider.getColumnWidths( );
		int dataWidth = 0;
		for ( int i = 0; i < width.length; i++ )
		{
			dataWidth += width[i];
		}
		data.right = new FormAttachment( title, dataWidth + 15, SWT.LEFT );
		data.bottom = new FormAttachment( 100 );
		table.setLayoutData( data );
	}

	/**
	 * Layouts widgets for simple UI type.
	 * 
	 */
	protected void normallLayout( )
	{
		FormLayout layout = new FormLayout( );
		layout.marginHeight = WidgetUtil.SPACING;
		layout.marginWidth = WidgetUtil.SPACING;
		layout.spacing = WidgetUtil.SPACING;
		setLayout( layout );
		// int height = QUICK_BUTTON_HEIGHT - 2;
		FormData data = new FormData( );
		data.right = new FormAttachment( 100 );
		// data.height = height;
		btnDown.setLayoutData( data );

		data = new FormData( );
		data.right = new FormAttachment( btnDown, 0, SWT.LEFT );
		// data.height = height;
		btnUp.setLayoutData( data );

		data = new FormData( );
		data.right = new FormAttachment( btnUp, 0, SWT.LEFT );
		// data.height = height;
		btnDel.setLayoutData( data );

		data = new FormData( );
		data.right = new FormAttachment( btnDel, 0, SWT.LEFT );
		// data.height = height;
		btnAdd.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnUp, 0, SWT.BOTTOM );
		data.left = new FormAttachment( title, 0, SWT.LEFT );
		data.right = new FormAttachment( 100 );
		data.bottom = new FormAttachment( 100 );
		table.setLayoutData( data );

	}
	
	protected void fullLayoutHorizontal()
	{
		FormLayout layout = new FormLayout( );
		layout.marginHeight = WidgetUtil.SPACING;
		layout.marginWidth = WidgetUtil.SPACING;
		layout.spacing = WidgetUtil.SPACING;
		setLayout( layout );
		// int height = QUICK_BUTTON_HEIGHT - 2;
		FormData data = new FormData( );
		data.right = new FormAttachment( 100 );
		// data.height = height;
		btnDown.setLayoutData( data );

		data = new FormData( );
		data.right = new FormAttachment( btnDown, 0, SWT.LEFT );
		// data.height = height;
		btnUp.setLayoutData( data );
		
		data = new FormData( );
		data.right = new FormAttachment( btnUp, 0, SWT.LEFT );
		// data.height = height;
		btnEdit.setLayoutData( data );

		data = new FormData( );
		data.right = new FormAttachment( btnEdit, 0, SWT.LEFT );
		// data.height = height;
		btnDel.setLayoutData( data );

		data = new FormData( );
		data.right = new FormAttachment( btnDel, 0, SWT.LEFT );
		// data.height = height;
		btnAdd.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnUp, 0, SWT.BOTTOM );
		data.left = new FormAttachment( title, 0, SWT.LEFT );
		data.right = new FormAttachment( 100 );
		data.bottom = new FormAttachment( 100 );
		table.setLayoutData( data );
	}
	
	/**
	 * Layouts widgets for Full UI type.
	 * 
	 */
	protected void fullLayout( )
	{
		FormLayout layout = new FormLayout( );
		layout.marginHeight = WidgetUtil.SPACING;
		layout.marginWidth = WidgetUtil.SPACING;
		layout.spacing = WidgetUtil.SPACING;
		setLayout( layout );

		int btnWidth = 60;
		int height = QUICK_BUTTON_HEIGHT - 2;
		FormData data = new FormData( );
		data.right = new FormAttachment( 90 );
		data.top = new FormAttachment( 0, height + WidgetUtil.SPACING * 2 );
		data.width = Math.max( btnWidth, btnAdd.computeSize( SWT.DEFAULT,
				SWT.DEFAULT,
				true ).x );
		btnAdd.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnAdd, 0, SWT.BOTTOM );
		data.left = new FormAttachment( btnAdd, 0, SWT.LEFT );
		data.width = Math.max( btnWidth, btnEdit.computeSize( SWT.DEFAULT,
				SWT.DEFAULT,
				true ).x );
		btnEdit.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnEdit, 0, SWT.BOTTOM );
		data.left = new FormAttachment( btnEdit, 0, SWT.LEFT );
		data.width = Math.max( btnWidth, btnDel.computeSize( SWT.DEFAULT,
				SWT.DEFAULT,
				true ).x );
		btnDel.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnDel, 0, SWT.BOTTOM );
		data.left = new FormAttachment( btnDel, 0, SWT.LEFT );
		data.width = Math.max( btnWidth, btnUp.computeSize( SWT.DEFAULT,
				SWT.DEFAULT,
				true ).x );
		btnUp.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnUp, 0, SWT.BOTTOM );
		data.left = new FormAttachment( btnUp, 0, SWT.LEFT );
		data.width = Math.max( btnWidth, btnDown.computeSize( SWT.DEFAULT,
				SWT.DEFAULT,
				true ).x );
		btnDown.setLayoutData( data );

		data = new FormData( );
		data.top = new FormAttachment( btnAdd, 0, SWT.TOP );
		data.bottom = new FormAttachment( 100 );
		data.left = new FormAttachment( title, 0, SWT.LEFT );
		data.right = new FormAttachment( btnAdd, 0, SWT.LEFT );
		table.setLayoutData( data );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.model.core.Listener#elementChanged(org.eclipse.birt.model.core.DesignElement,
	 *      org.eclipse.birt.model.activity.NotificationEvent)
	 */
	public void elementChanged( DesignElementHandle arg0,
			NotificationEvent event )
	{
		if ( provider.needRefreshed( event ) )
		{
			tableViewer.refresh( );
			table.select( selectIndex );
			table.setFocus( );
			updateArraw( );
			updateBindingParameters( );
		}
	}

	private class FormLabelProvider extends LabelProvider implements
			ITableLabelProvider
	{

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
		 *      int)
		 */
		public Image getColumnImage( Object element, int columnIndex )
		{
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
		 *      int)
		 */
		public String getColumnText( Object element, int columnIndex )
		{
			return provider.getColumnText( element, columnIndex );
		}
	}

	private class FormContentProvider implements IStructuredContentProvider
	{

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
		 */
		public Object[] getElements( Object inputElement )
		{
			Object[] elements = provider.getElements( inputElement );
			for ( int i = 0; i < elements.length; i++ )
			{
				if ( elements[i] instanceof DesignElementHandle )
				{
					DesignElementHandle element = (DesignElementHandle) elements[i];
					element.removeListener( FormPage.this );
					element.addListener( FormPage.this );
				}
			}
			return elements;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
		 */
		public void dispose( )
		{

			if ( !( provider instanceof GroupHandleProvider ) )
				return;

			Object[] elements = provider.getElements( input );

			if ( elements == null )
			{
				return;
			}
			for ( int i = 0; i < elements.length; i++ )
			{
				if ( elements[i] instanceof DesignElementHandle )
				{
					DesignElementHandle element = (DesignElementHandle) elements[i];
					element.removeListener( FormPage.this );
				}
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
		 *      java.lang.Object, java.lang.Object)
		 */
		public void inputChanged( Viewer viewer, Object oldInput,
				Object newInput )
		{
		}
	}

	private class FormCellModifier implements ICellModifier
	{

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object,
		 *      java.lang.String)
		 */
		public boolean canModify( Object element, String property )
		{
			return provider.canModify( element, property );
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object,
		 *      java.lang.String)
		 */
		public Object getValue( Object element, String property )
		{
			return provider.getValue( element, property );
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object,
		 *      java.lang.String, java.lang.Object)
		 */
		public void modify( Object element, String property, Object value )
		{
			CommandStack stack = getActionStack( );
			TableItem item = (TableItem) element;
			stack.startTrans( Messages.getString( "FormPage.Menu.ModifyProperty" ) ); //$NON-NLS-1$
			try
			{
				provider.modify( item.getData( ), property, value );
				stack.commit( );
			}
			catch ( Exception e )
			{
				stack.rollback( );
				WidgetUtil.processError( FormPage.this.getShell( ), e );
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.designer.internal.ui.views.attributes.page.AttributePage#buildUI()
	 */
	protected void buildUI( )
	{

	}

	/**
	 * Gets the DE CommandStack instance
	 * 
	 * @return CommandStack instance
	 */
	private CommandStack getActionStack( )
	{
		return SessionHandleAdapter.getInstance( ).getCommandStack( );
	}
}