/*******************************************************************************
* Copyright (c) 2002-2007 Innoopract Informationssysteme GmbH.
* 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:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package org.eclipse.rap.rms.ui.internal.chart;
import java.util.Collections;
import java.util.List;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.*;
public class GanttViewer extends StructuredViewer {
private final Gantt control;
private boolean busy;
public GanttViewer( final Gantt gantt ) {
control = gantt;
}
public GanttViewer( final Composite parent ) {
this( parent, SWT.NONE );
}
public GanttViewer( final Composite parent, final int style ) {
this( new Gantt( parent, style ) );
}
public Control getControl() {
return control;
}
public Gantt getGantt() {
return control;
}
protected Widget doFindItem( final Object element ) {
Widget result = null;
Item[] items = control.getItems();
for( int i = 0; result == null && i < items.length; i++ ) {
Item item = items[ i ];
Object data = item.getData();
if( data != null && equals( data, element ) ) {
result = item;
}
}
return result;
}
protected Widget doFindInputItem( final Object element ) {
Widget result = null;
if( equals( element, getRoot() ) ) {
result = getControl();
}
return result;
}
protected void doUpdateItem( final Widget widget,
final Object element,
final boolean fullMap )
{
boolean oldBusy = busy;
busy = true;
try {
GanttItem item = ( GanttItem )widget;
// remember element we are showing
if( fullMap ) {
associate( element, item );
} else {
Object data = item.getData();
if( data != null ) {
unmapElement( data, item );
}
item.setData( element );
mapElement( element, item );
}
updateLabel( item, element );
// As it is possible for user code to run the event
// loop check here.
if( item.isDisposed() ) {
unmapElement( element, item );
}
} finally {
busy = oldBusy;
}
}
protected List getSelectionFromWidget() {
return Collections.EMPTY_LIST;
}
protected void inputChanged( Object input, Object oldInput ) {
getControl().setRedraw( false );
try {
preservingSelection( new Runnable() {
public void run() {
internalRefresh( getRoot() );
}
} );
} finally {
getControl().setRedraw( true );
}
}
protected void internalRefresh( final Object element ) {
internalRefresh( element, true );
}
protected void internalRefresh( final Object element,
final boolean updateLabels )
{
if( element == null || equals( element, getRoot() ) ) {
internalRefreshAll( updateLabels );
} else {
Widget item = findItem( element );
if( item != null ) {
updateItem( item, element );
}
}
}
public void reveal( final Object element ) {
}
protected void setSelectionToWidget( final List list, final boolean reveal ) {
}
///////////////////
// Helping methods
private void internalRefreshAll( final boolean updateLabels ) {
if( updateLabels ) {
updateLabel( control, getRoot() );
}
// in the code below, it is important to do all disassociates
// before any associates, since a later disassociate can undo an
// earlier associate
// e.g. if (a, b) is replaced by (b, a), the disassociate of b to
// item 1 could undo
// the associate of b to item 0.
Object[] children = getSortedChildren( getRoot() );
Item[] items = control.getItems();
int min = Math.min( children.length, items.length );
for( int i = 0; i < min; ++i ) {
Item item = items[ i ];
// if the element is unchanged, update its label if appropriate
if( equals( children[ i ], item.getData() ) ) {
if( updateLabels ) {
updateItem( item, children[ i ] );
} else {
// associate the new element, even if equal to the old
// one,
// to remove stale references (see bug 31314)
associate( children[ i ], item );
}
} else {
// updateItem does an associate(...), which can mess up
// the associations if the order of elements has changed.
// E.g. (a, b) -> (b, a) first replaces a->0 with b->0, then
// replaces b->1 with a->1, but this actually removes b->0.
// So, if the object associated with this item has changed,
// just disassociate it for now, and update it below.
// we also need to reset the item (set its text,images etc. to
// default values) because the label decorators rely on this
disassociate( item );
clear( i );
}
}
// dispose of all items beyond the end of the current elements
if( min < items.length ) {
for( int i = items.length; --i >= min; ) {
disassociate( items[ i ] );
}
remove( min, items.length - 1 );
}
// Update items which were disassociated above
for( int i = 0; i < min; ++i ) {
Item item = items[ i ];
if( item.getData() == null ) {
updateItem( item, children[ i ] );
}
}
// add any remaining elements
for( int i = min; i < children.length; ++i ) {
createItem( children[ i ], i );
}
}
private void updateLabel( final Gantt gantt, final Object element ) {
IBaseLabelProvider baseLabelProvider = getLabelProvider();
if( baseLabelProvider instanceof IGanttLabelProvider ) {
IGanttLabelProvider ganttLabelProvider
= ( IGanttLabelProvider )baseLabelProvider;
String[] legendText = ganttLabelProvider.getLegendText( element );
int mark = ganttLabelProvider.getMark( element );
gantt.setLegend( legendText );
gantt.setMark( mark );
}
}
private void updateLabel( final GanttItem item, final Object element ) {
IBaseLabelProvider baseLabelProvider = getLabelProvider();
if( baseLabelProvider instanceof IViewerLabelProvider ) {
IViewerLabelProvider viewerLabelProvider
= ( IViewerLabelProvider )baseLabelProvider;
ViewerLabel viewerLabel = new ViewerLabel( item.getText(), null );
viewerLabelProvider.updateLabel( viewerLabel, element );
item.setBackground( viewerLabel.getBackground() );
item.setForeground( viewerLabel.getForeground() );
item.setText( viewerLabel.getText() );
item.setToolTipText( viewerLabel.getTooltipText() );
} else {
if( baseLabelProvider instanceof IColorProvider ) {
IColorProvider colorProvider = ( IColorProvider )baseLabelProvider;
Color background = colorProvider.getBackground( element );
Color foreground = colorProvider.getForeground( element );
item.setBackground( background );
item.setForeground( foreground );
}
if( baseLabelProvider instanceof ILabelProvider ) {
ILabelProvider labelProvider = ( ILabelProvider )baseLabelProvider;
String text = labelProvider.getText( element );
item.setText( text );
}
}
if( baseLabelProvider instanceof IGanttItemLabelProvider ) {
IGanttItemLabelProvider itemLabelProvider
= ( IGanttItemLabelProvider )baseLabelProvider;
int start = itemLabelProvider.getStart( element );
int length = itemLabelProvider.getLength( element );
item.setStart( start );
item.setLength( length );
}
}
////////////////////
// Item manipulation
private void remove( final int start, final int end ) {
Item[] items = control.getItems();
for( int i = 0; i < items.length; i++ ) {
if( i >= start && i <= end ) {
items[ i ].dispose();
}
}
}
private void clear( final int index ) {
GanttItem item = control.getItem( index );
item.setStart( 0 );
item.setLength( 0 );
item.setBackground( null );
item.setText( "" );
item.setBarText( "" );
item.setToolTipText( "" );
item.setImage( null );
}
private void createItem( final Object element, final int index ) {
Item item = new GanttItem( control, SWT.NONE, index );
updateItem( item, element );
}
}