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

import org.eclipse.birt.report.designer.core.model.views.property.GroupPropertyHandleWrapper;
import org.eclipse.birt.report.designer.internal.ui.dialogs.expression.ExpressionCellEditor;
import org.eclipse.birt.report.designer.internal.ui.util.AlphabeticallyViewSorter;
import org.eclipse.birt.report.designer.internal.ui.util.UIUtil;
import org.eclipse.birt.report.designer.internal.ui.views.attributes.page.WidgetUtil;
import org.eclipse.birt.report.designer.internal.ui.views.attributes.provider.AdvancePropertyDescriptorProvider;
import org.eclipse.birt.report.designer.internal.ui.views.attributes.provider.IDescriptorProvider;
import org.eclipse.birt.report.designer.internal.ui.views.memento.Memento;
import org.eclipse.birt.report.designer.internal.ui.views.memento.MementoBuilder;
import org.eclipse.birt.report.designer.internal.ui.views.memento.MementoElement;
import org.eclipse.birt.report.designer.nls.Messages;
import org.eclipse.birt.report.designer.ui.dialogs.ExpressionProvider;
import org.eclipse.birt.report.designer.ui.preferences.PreferenceFactory;
import org.eclipse.birt.report.designer.ui.util.ExceptionUtil;
import org.eclipse.birt.report.designer.ui.views.ReportViewsPlugin;
import org.eclipse.birt.report.designer.util.DEUtil;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.GroupPropertyHandle;
import org.eclipse.birt.report.model.api.activity.NotificationEvent;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
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.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;

/**
 * The customized implementation of property sheet page which presents a table
 * of property names and values obtained from the current selection in the
 * active workbench part. This page uses TableTreeViewer as the control to avoid
 * the complicated problem of the default property sheet.
 * <p>
 * This page obtains the information about what to properties display from the
 * current selection (which it tracks).
 * </p>
 * <p>
 * The model for this page is DE model which is selected in the active workbench
 * part. The page is a listener implementation to get notified by model changes.
 * The page may be configured with a custom model by setting the root input.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * 
 * @see IPropertySource
 */
public class AdvancePropertyDescriptor extends PropertyDescriptor
{

	private boolean isFormStyle;
	private static final String COLUMN_TITLE_PROPERTY = Messages.getString( "ReportPropertySheetPage.Column.Title.Property" ); //$NON-NLS-1$
	private static final String COLUMN_TITLE_VALUE = Messages.getString( "ReportPropertySheetPage.Column.Title.Value" ); //$NON-NLS-1$

	private CustomTreeViewer viewer;

	private CellEditor cellEditor;
	private Tree tableTree;
	private TreeEditor tableTreeEditor;

	private int columnToEdit = 1;
	private ICellEditorListener editorListener;
	private Object model;
	private Composite container;
	private IMemento propertySheetMemento;
	private IMemento viewerMemento;
	protected String propertyViewerID = "Report_Property_Sheet_Page_Viewer_ID"; //$NON-NLS-1$

	private static final String SORTING_PREFERENCE_KEY = "AdvancePropertyDescriptor.preference.sorting.type"; //$NON-NLS-1$

	public AdvancePropertyDescriptor( boolean formStyle )
	{
		this.isFormStyle = formStyle;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite
	 * )
	 */
	public Control createControl( Composite parent )
	{
		container = new Composite( parent, SWT.NONE );
		GridLayout layout = UIUtil.createGridLayoutWithoutMargin( 1, false );
		layout.marginTop = 2;
		layout.marginWidth = layout.marginBottom = 1;
		container.setLayout( layout );
		container.setLayoutData( new GridData( GridData.FILL_BOTH ) );

		initSortingType( );

		viewer = new CustomTreeViewer( container, SWT.FULL_SELECTION );

		tableTree = viewer.getTree( );
		GridData gd = new GridData( GridData.FILL_BOTH );
		tableTree.setLayoutData( gd );
		tableTree.setHeaderVisible( true );
		tableTree.setLinesVisible( true );

		viewer.setContentProvider( provider.getContentProvier( ) );

		TreeViewerColumn tvc1 = new TreeViewerColumn( viewer, SWT.NONE );
		tvc1.getColumn( ).setText( COLUMN_TITLE_PROPERTY );
		tvc1.getColumn( ).setWidth( 300 );
		tvc1.setLabelProvider( new DelegatingStyledCellLabelProvider( provider.getNameLabelProvier( ) ) );

		TreeViewerColumn tvc2 = new TreeViewerColumn( viewer, SWT.NONE );
		tvc2.getColumn( ).setText( COLUMN_TITLE_VALUE );
		tvc2.getColumn( ).setWidth( 400 );
		tvc2.setLabelProvider( new DelegatingStyledCellLabelProvider( provider.getValueLabelProvier( ) ) );

		AlphabeticallyViewSorter sorter = new AlphabeticallyViewSorter( );
		sorter.setAscending( true );
		viewer.setSorter( sorter );

		hookControl( );

		// create a new table tree editor
		tableTreeEditor = new TreeEditor( tableTree );

		// create the editor listener
		createEditorListener( );

		MementoBuilder builder = new MementoBuilder( );
		if ( ( propertySheetMemento = builder.getRootMemento( )
				.getChild( IPageLayout.ID_PROP_SHEET ) ) == null )
		{
			propertySheetMemento = builder.getRootMemento( )
					.createChild( IPageLayout.ID_PROP_SHEET,
							MementoElement.Type_View );
		}

		if ( ( viewerMemento = propertySheetMemento.getChild( propertyViewerID ) ) == null )
		{
			viewerMemento = propertySheetMemento.createChild( propertyViewerID,
					MementoElement.Type_Viewer );
		}

		return container;
	}

	public void setInput( Object input )
	{

		this.input = input;
		getDescriptorProvider( ).setInput( input );
	}

	/**
	 * 
	 */
	private void expandToDefaultLevel( )
	{
		// open the root node by default

		viewer.expandToLevel( 2 );

	}

	/**
	 * Creates a new cell editor listener.
	 */
	private void createEditorListener( )
	{
		editorListener = new ICellEditorListener( ) {

			public void cancelEditor( )
			{
				deactivateCellEditor( );
			}

			public void editorValueChanged( boolean oldValidState,
					boolean newValidState )
			{

			}

			public void applyEditorValue( )
			{
				applyValue( );
				if ( changed )
					refresh( );
			}
		};
	}

	/**
	 * Establish this viewer as a listener on the control
	 */
	private void hookControl( )
	{
		// Handle selections in the TableTree
		// Part1: Double click only (allow traversal via keyboard without
		// activation
		tableTree.addSelectionListener( new SelectionAdapter( ) {

			public void widgetDefaultSelected( SelectionEvent e )
			{

				handleSelect( (TreeItem) e.item );
			}

		} );
		// Part2: handle single click activation of cell editor
		tableTree.addMouseListener( new MouseAdapter( ) {

			public void mouseDown( MouseEvent event )
			{
				// only activate if there is a cell editor
				Point pt = new Point( event.x, event.y );
				TreeItem item = tableTree.getItem( pt );
				if ( item != null )
				{
					if ( tableTree.getColumn( 0 ).getWidth( ) < event.x )
					{
						handleSelect( item );
					}
					else
						saveSelection( item );
				}
			}
		} );

		tableTree.addKeyListener( new KeyAdapter( ) {

			public void keyReleased( KeyEvent e )
			{
				if ( tableTree.getSelectionCount( ) > 0 )
					saveSelection( tableTree.getSelection( )[0] );
				if ( e.character == SWT.ESC )
					deactivateCellEditor( );
				else if ( e.keyCode == SWT.F5 )
				{
					// Refresh the table when F5 pressed
					// The following will simulate a reselect
					viewer.setInput( input );
					IMemento memento = viewerMemento.getChild( provider.getElementType( ) );
					if ( memento != null && memento instanceof Memento )
					{
						expandToDefaultLevel( );
						expandTreeFromMemento( (Memento) memento );
					}
				}
			}
		} );
		viewer.addDoubleClickListener( new IDoubleClickListener( ) {

			public void doubleClick( DoubleClickEvent event )
			{
				IStructuredSelection selection = (IStructuredSelection) event.getSelection( );
				Object element = selection.getFirstElement( );

				if ( viewer.isExpandable( element ) )
				{
					viewer.setExpandedState( element,
							!viewer.getExpandedState( element ) );
					int style = SWT.Expand;
					if ( !viewer.getExpandedState( element ) )
						style = SWT.Collapse;
					Event e = new Event( );
					e.widget = tableTree;
					if ( tableTree.getSelectionCount( ) > 0 )
						e.item = tableTree.getSelection( )[0];
					tableTree.notifyListeners( style, e );
				}
			}
		} );

		treeListener = new TreeListener( ) {

			public void treeCollapsed( TreeEvent e )
			{
				if ( e.item instanceof TreeItem )
				{
					TreeItem item = (TreeItem) e.item;
					if ( input != null )
					{
						Object obj = DEUtil.getInputFirstElement( input );
						if ( obj instanceof DesignElementHandle )
						{
							Memento element = (Memento) viewerMemento.getChild( provider.getElementType( ) );
							if ( element != null )
							{
								MementoElement[] path = createItemPath( item );
								provider.removeNode( element, path );
							}
						}
					}
					viewer.getTree( ).setSelection( item );
					saveSelection( item );
				}
			}

			public void treeExpanded( TreeEvent e )
			{
				if ( e.item instanceof TreeItem )
				{
					TreeItem item = (TreeItem) e.item;
					if ( input != null )
					{
						Object obj = DEUtil.getInputFirstElement( input );
						if ( obj instanceof DesignElementHandle )
						{
							Memento element = (Memento) viewerMemento.getChild( provider.getElementType( ) );
							if ( element != null )
							{
								MementoElement[] path = createItemPath( item );
								provider.addNode( element, path );
							}
						}
					}
					viewer.getTree( ).setSelection( item );
					saveSelection( item );
				}

			}

		};

		tableTree.addTreeListener( treeListener );
	}

	protected MementoElement[] createItemPath( TreeItem item )
	{
		MementoElement tempMemento = null;
		while ( item.getParentItem( ) != null )
		{
			TreeItem parent = item.getParentItem( );
			for ( int i = 0; i < parent.getItemCount( ); i++ )
			{
				if ( parent.getItem( i ) == item )
				{
					MementoElement memento = new MementoElement( item.getText( ),
							Integer.valueOf( i ),
							MementoElement.Type_Element );
					if ( tempMemento != null )
						memento.addChild( tempMemento );
					tempMemento = memento;
					item = parent;
					break;
				}
			}
		}
		MementoElement memento = new MementoElement( item.getText( ),
				Integer.valueOf( 0 ),
				MementoElement.Type_Element );
		if ( tempMemento != null )
			memento.addChild( tempMemento );
		return provider.getNodePath( memento );
	}

	private void deactivateCellEditor( )
	{
		tableTreeEditor.setEditor( null, null, columnToEdit );
		if ( cellEditor != null )
		{
			cellEditor.deactivate( );
			applyValue( );
			if ( cellEditor != null )
				cellEditor.removeListener( editorListener );
			cellEditor = null;
		}
	}

	/**
	 * @param item
	 */
	protected void handleSelect( TreeItem selection )
	{
		// deactivate the current cell editor
		if ( cellEditor != null )
		{
			// applyValue( );
			deactivateCellEditor( );
		}

		// get the new selection
		TreeItem[] sel = new TreeItem[]{
			selection
		};
		if ( sel.length == 0 )
		{

		}
		else
		{
			// activate a cell editor on the selection
			// assume single selection
			activateCellEditor( sel[0] );
		}

		saveSelection( selection );
	}

	protected void saveSelection( TreeItem selection )
	{
		MementoElement[] selectPath = createItemPath( selection );
		if ( input != null )
		{
			Object obj = DEUtil.getInputFirstElement( input );
			if ( obj instanceof DesignElementHandle )
			{
				Memento element = (Memento) viewerMemento.getChild( provider.getElementType( ) );
				if ( element != null )
				{
					element.getMementoElement( )
							.setAttribute( MementoElement.ATTRIBUTE_SELECTED,
									selectPath );
				}
			}
		}
	}

	/**
	 * 
	 */
	private void applyValue( )
	{
		if ( cellEditor == null || !cellEditor.isDirty( ) )
		{
			return;
		}

		if ( model instanceof GroupPropertyHandleWrapper )
		{
			try
			{
				GroupPropertyHandle handle = ( (GroupPropertyHandle) ( (GroupPropertyHandleWrapper) model ).getModel( ) );

				if ( cellEditor.getValue( ) instanceof String )
				{
					if ( handle.getStringValue( ) != null
							&& handle.getStringValue( )
									.equals( cellEditor.getValue( ) ) )
						return;
				}
				else
				{
					if ( handle.getValue( ) != null
							&& handle.getValue( )
									.equals( cellEditor.getValue( ) ) )
						return;
				}
				handle.setValue( cellEditor.getValue( ) );
			}
			catch ( SemanticException e )
			{
				ExceptionUtil.handle( e );

				// get the new selection
				TreeItem[] sel = viewer.getTree( ).getSelection( );
				if ( sel.length == 0 )
				{
					// Do nothing
				}
				else
				{
					// activate a cell editor on the selection
					// assume single selection
					activateCellEditor( sel[0] );
				}
			}
		}
	}

	/**
	 * @param item
	 */
	private void activateCellEditor( TreeItem sel )
	{

		if ( sel.isDisposed( ) )
			return;
		model = sel.getData( );

		// ensure the cell editor is visible
		tableTree.showSelection( );

		cellEditor = createCellEditor( model );

		if ( cellEditor == null )
			// unable to create the editor
			return;

		// set the created editor as current editor
		tableTreeEditor.setEditor( cellEditor.getControl( ) );

		// activate the cell editor
		cellEditor.activate( );

		// if the cell editor has no control we can stop now
		Control control = cellEditor.getControl( );
		if ( control == null )
		{
			cellEditor.deactivate( );
			cellEditor = null;
			return;
		}

		// add our editor listener
		cellEditor.addListener( editorListener );

		// set the layout of the table tree editor to match the cell editor
		CellEditor.LayoutData layout = cellEditor.getLayoutData( );
		tableTreeEditor.horizontalAlignment = layout.horizontalAlignment;
		tableTreeEditor.grabHorizontal = layout.grabHorizontal;
		tableTreeEditor.minimumWidth = layout.minimumWidth;
		tableTreeEditor.setEditor( control, sel, columnToEdit );

		// give focus to the cell editor
		cellEditor.setFocus( );

	}

	/**
	 * @param data
	 */
	private CellEditor createCellEditor( Object data )
	{
		CellEditor editor = null;
		if ( data instanceof GroupPropertyHandleWrapper
				&& ( (GroupPropertyHandle) ( ( (GroupPropertyHandleWrapper) data ) ).getModel( ) ).isVisible( ) )
		{
			editor = PropertyEditorFactory.getInstance( )
					.createPropertyEditor( tableTree,
							( (GroupPropertyHandleWrapper) data ).getModel( ) );

			if ( editor instanceof ExpressionCellEditor )
			{
				if ( DEUtil.getInputSize( input ) > 0 )
				{
					( (ExpressionCellEditor) editor ).setExpressionInput( new ExpressionProvider( (DesignElementHandle) DEUtil.getInputFirstElement( input ) ),
							DEUtil.getInputFirstElement( input ) );
				}
			}

		}

		return editor;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.IPage#getControl()
	 */
	public Control getControl( )
	{
		if ( container == null )
			return null;
		return container;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.IPage#setFocus()
	 */
	public void setFocus( )
	{
		getControl( ).setFocus( );

		if ( changed )
			refresh( );

	}

	protected void refresh( )
	{
		viewer.getTree( ).deselectAll( );

		viewer.refresh( true );
		deactivateCellEditor( );
		if ( input != null )
		{
			Object obj = DEUtil.getInputFirstElement( input );
			if ( obj instanceof DesignElementHandle )
			{
				execMemento( );
			}
		}

		changed = false;
	}

	private void expandTreeFromMemento( Memento memento )
	{
		if ( viewer.getTree( ).getItemCount( ) == 0 )
			return;
		TreeItem root = viewer.getTree( ).getItem( 0 );
		if ( memento.getMementoElement( ).getKey( ).equals( root.getText( ) ) )
		{
			restoreExpandedMemento( root, memento.getMementoElement( ) );
			Object obj = memento.getMementoElement( )
					.getAttribute( MementoElement.ATTRIBUTE_SELECTED );
			if ( obj != null )
				restoreSelectedMemento( root, (MementoElement[]) obj );
		}
	}

	private void restoreSelectedMemento( TreeItem root,
			MementoElement[] selectedPath )
	{
		if ( selectedPath.length <= 1 )
			return;
		for ( int i = 1; i < selectedPath.length; i++ )
		{
			MementoElement element = selectedPath[i];
			if ( !root.getExpanded( ) )
			{
				viewer.createChildren( root );
				root.setExpanded( true );
			}
			if ( root.getItemCount( ) > ( (Integer) element.getValue( ) ).intValue( ) )
			{
				root = root.getItem( ( (Integer) element.getValue( ) ).intValue( ) );
			}
			else
				return;
		}
		viewer.getTree( ).setSelection( root );

	}

	private void restoreExpandedMemento( TreeItem root, MementoElement memento )
	{
		if ( memento.getKey( ).equals( root.getText( ) ) )
		{
			if ( !root.getExpanded( ) )
				viewer.createChildren( root );
			if ( root.getItemCount( ) > 0 )
			{
				if ( !root.getExpanded( ) )
					root.setExpanded( true );
				MementoElement[] children = memento.getChildren( );
				for ( int i = 0; i < children.length; i++ )
				{
					MementoElement child = children[i];
					int index = ( (Integer) child.getValue( ) ).intValue( );
					if ( index >= 0 && index < root.getItemCount( ) )
					{
						TreeItem item = root.getItem( index );
						restoreExpandedMemento( item, child );
					}
				}
			}
		}
	}

	private static class CustomTreeViewer extends TreeViewer
	{

		public CustomTreeViewer( Composite parent, int style )
		{
			super( parent, style );
		}

		public void createChildren( Widget widget )
		{
			super.createChildren( widget );
		}
	}

	public void load( )
	{
		// deRegisterEventManager( );

		if ( viewer.getTree( ) != null && !viewer.getTree( ).isDisposed( ) )
		{
			viewer.getTree( ).deselectAll( );
			if ( updateSorting )
				viewer.getTree( ).removeAll( );
			viewer.refresh( true );
		}

		if ( !provider.isEnable( ) )
		{
			viewer.setInput( null );
			return;
		}

		if ( input == null || viewer.getInput( ) == null )
		{
			viewer.setInput( input );
		}
		else if ( input.equals( viewer.getInput( ) ) )
		{
			viewer.refresh( );
		}
		else
			viewer.setInput( input );

		// registerEventManager( );
		execMemento( );
	}

	private boolean execMemento = false;

	private int oldViewMode = -1;

	private void execMemento( )
	{
		if ( !execMemento )
		{
			execMemento = true;

			Display.getCurrent( ).asyncExec( new Runnable( ) {

				public void run( )
				{
					if ( !viewer.getTree( ).isDisposed( ) )
					{
						// deactivateCellEditor( );
						IMemento memento = viewerMemento.getChild( provider.getElementType( ) );
						if ( memento == null )
						{
							provider.setInput( input );
							viewer.getTree( ).removeAll( );
							viewer.refresh( );

							expandToDefaultLevel( );

							if ( viewer.getTree( ).getItemCount( ) > 0 )
							{
								Memento elementMemento = (Memento) viewerMemento.createChild( provider.getElementType( ),
										MementoElement.Type_Element );
								elementMemento.getMementoElement( )
										.setValue( Integer.valueOf( 0 ) );
							}
						}
						else if ( memento instanceof Memento )
						{
							// expandToDefaultLevel( );

							if ( treeListener != null )
								viewer.getTree( )
										.removeTreeListener( treeListener );
							if ( provider.getViewMode( ) != oldViewMode )
							{
								viewer.getTree( ).removeAll( );
								oldViewMode = provider.getViewMode( );
							}
							expandToDefaultLevel( );
							if ( treeListener != null )
								viewer.getTree( )
										.addTreeListener( treeListener );

							if ( provider.getViewMode( ) == AdvancePropertyDescriptorProvider.MODE_GROUPED )
								expandTreeFromMemento( (Memento) memento );

							Object obj = ( (Memento) memento ).getMementoElement( )
									.getAttribute( MementoElement.ATTRIBUTE_SELECTED );
							if ( obj != null )
							{
								restoreSelectedMemento( viewer.getTree( )
										.getItem( 0 ), (MementoElement[]) obj );
							}
						}

					}
					execMemento = false;
				}
			} );

		}

	}

	private void initSortingType( )
	{
		PreferenceFactory.getInstance( )
				.getPreferences( ReportViewsPlugin.getDefault( ) )
				.setDefault( SORTING_PREFERENCE_KEY,
						AdvancePropertyDescriptorProvider.MODE_GROUPED );

		provider.selectViewMode( PreferenceFactory.getInstance( )
				.getPreferences( ReportViewsPlugin.getDefault( ) )
				.getInt( SORTING_PREFERENCE_KEY ) );
	}

	private void saveSortingType( )
	{
		PreferenceFactory.getInstance( )
				.getPreferences( ReportViewsPlugin.getDefault( ) )
				.setValue( SORTING_PREFERENCE_KEY, provider.getViewMode( ) );
	}

	public void save( Object obj ) throws SemanticException
	{
		// TODO Auto-generated method stub

	};

	private AdvancePropertyDescriptorProvider provider;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.birt.report.designer.internal.ui.views.attributes.widget.
	 * PropertyDescriptor
	 * #setDescriptorProvider(org.eclipse.birt.report.designer.
	 * internal.ui.views.attributes.provider.IDescriptorProvider)
	 */
	public void setDescriptorProvider( IDescriptorProvider provider )
	{
		super.setDescriptorProvider( provider );
		if ( getDescriptorProvider( ) instanceof AdvancePropertyDescriptorProvider )
		{
			this.provider = (AdvancePropertyDescriptorProvider) getDescriptorProvider( );
		}
	}

	public void setVisible( boolean isVisible )
	{
		getControl( ).setVisible( isVisible );

	}

	public void setHidden( boolean isHidden )
	{
		WidgetUtil.setExcludeGridData( getControl( ), isHidden );
	}

	public void addElementEvent( DesignElementHandle focus, NotificationEvent ev )
	{

	}

	public void clear( )
	{

	}

	public boolean isOverdued( )
	{
		return viewer.getTree( ) == null || viewer.getTree( ).isDisposed( );
	}

	private boolean changed = false;
	private TreeListener treeListener;

	public Object getAdapter( Class adapter )
	{
		return null;
	}

	boolean updateSorting = false;

	public void updateSorting( int sortingType )
	{
		updateSorting = true;
		if ( cellEditor != null )
		{
			cellEditor.deactivate( );
			applyValue( );
		}
		deactivateCellEditor( );
		Memento memento = (Memento) viewerMemento.getChild( provider.getElementType( ) );
		if ( memento != null )
		{
			saveSortingType( );

			Object obj = ( (Memento) memento ).getMementoElement( )
					.getAttribute( MementoElement.ATTRIBUTE_SELECTED );
			if ( obj != null )
				( (Memento) memento ).getMementoElement( )
						.setAttribute( MementoElement.ATTRIBUTE_SELECTED, null );
		}
		deactivateCellEditor( );
		execMemento( );
		updateSorting = false;
	}
}