/*****************************************************************************
* Copyright (c) 2006-2008 g-Eclipse Consortium
* 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
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Mathias Stuempert - initial API and implementation
*****************************************************************************/
package eu.geclipse.ui.providers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Shell;
import eu.geclipse.core.model.IGridContainer;
import eu.geclipse.core.model.IGridElement;
import eu.geclipse.core.reporting.ProblemException;
import eu.geclipse.ui.dialogs.ProblemDialog;
import eu.geclipse.ui.internal.Activator;
/**
* Tree content provider for data contained in the grid model.
*/
public class GridModelContentProvider
implements ITreeContentProvider, ITreeViewerListener {
/**
* The associated tree viewer.
*/
protected TreeViewer treeViewer;
private Hashtable< IGridContainer, ProgressTreeNode > progressNodes
= new Hashtable< IGridContainer, ProgressTreeNode >();
/**
* The comparator used for sorting the children of a node.
*/
private GridModelComparator comparator
= new GridModelComparator();
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren( final Object parentElement ) {
Object[] children = null;
if ( hasChildren( parentElement ) ) {
children = getChildren( ( IGridContainer ) parentElement );
}
if ( children != null ) {
Arrays.sort( children, this.comparator );
}
return children;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
*/
public Object getParent( final Object element ) {
Object parent = null;
if ( element instanceof IGridElement ) {
parent = ( ( IGridElement ) element ).getParent();
}
return parent;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
public boolean hasChildren( final Object element ) {
boolean result = false;
if ( element instanceof IGridContainer ) {
result = ( ( IGridContainer ) element ).hasChildren();
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements( final Object inputElement ) {
Object[] elements = getChildren( inputElement );
if ( elements == null ) {
elements = new Object[0];
}
return elements;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
// empty implementation
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public void inputChanged( final Viewer viewer,
final Object oldInput,
final Object newInput ) {
if ( viewer instanceof TreeViewer ) {
treeViewerChanged( this.treeViewer, ( TreeViewer ) viewer );
}
}
/**
* Get the children of the specified container. If the container
* is lazy and dirty the returned array will contain only one
* element, i.e. a {@link ProgressRunner} that is used to monitor
* the progress of the children fetching operation that will
* be started immediately by this method.
*
* @param container The container from which to fetch the children.
* @return An array containing either the list of children or a
* {@link ProgressRunner} object.
*/
protected Object[] getChildren( final IGridContainer container ) {
Object[] children = null;
if ( container.isLazy() && container.isDirty() ) {
ProgressTreeNode monitor = this.progressNodes.get( container );
if ( monitor == null ) {
FetchChildrenJob fetcher = new FetchChildrenJob( container, this.treeViewer.getControl().getShell() );
monitor = new ProgressTreeNode( this.treeViewer );
this.progressNodes.put( container, monitor );
fetcher.setExternalMonitor( monitor );
fetcher.setSystem( true );
fetcher.schedule();
}
children = new Object[] { monitor };
} else {
this.progressNodes.remove( container );
try {
IGridElement[] childElements = container.getChildren( null );
List< IGridElement > visibleChildren = new ArrayList< IGridElement >();
for ( IGridElement child : childElements ) {
if ( ! child.isHidden() ) {
visibleChildren.add( child );
}
}
children = visibleChildren.toArray( new IGridElement[ visibleChildren.size() ] );
} catch ( ProblemException pExc ) {
if ( this.treeViewer != null ) {
Shell shell = this.treeViewer.getControl().getShell();
ProblemDialog.openProblem( shell,
Messages.getString("GridModelContentProvider.problem_title"), //$NON-NLS-1$
Messages.getString("GridModelContentProvider.problem_text") + container.getName(), //$NON-NLS-1$
pExc );
} else {
Activator.logException( pExc );
}
}
}
return children;
}
/**
* Called when a new tree viewer was set and/or an old viewer
* was unset.
*
* @param oldViewer The old viewer.
* @param newViewer The new viewer.
*/
protected void treeViewerChanged( final TreeViewer oldViewer,
final TreeViewer newViewer ) {
if ( oldViewer != newViewer ) {
this.treeViewer = newViewer;
if ( oldViewer != null ) {
oldViewer.removeTreeListener( this );
}
if ( newViewer != null ) {
newViewer.addTreeListener( this );
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeViewerListener#treeCollapsed(org.eclipse.jface.viewers.TreeExpansionEvent)
*/
public void treeCollapsed( final TreeExpansionEvent event ) {
Object element = event.getElement();
if ( ( element instanceof IGridContainer ) && ( ( IGridContainer ) element ).isLazy() ) {
IGridContainer container = ( IGridContainer ) element;
this.progressNodes.remove( container );
container.setDirty();
try {
container.deleteAll();
} catch( ProblemException pExc ) {
Activator.logException( pExc );
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeViewerListener#treeExpanded(org.eclipse.jface.viewers.TreeExpansionEvent)
*/
public void treeExpanded( final TreeExpansionEvent event ) {
// empty implementation
}
}