package net.xoetrope.swt;
import net.xoetrope.xui.XAttributedComponent;
import net.xoetrope.xui.XModelHolder;
import net.xoetrope.xui.XProjectManager;
import net.xoetrope.xui.data.XModel;
import net.xoetrope.xui.data.XRowSelector;
import net.xoetrope.xui.events.XHandlerInvoker;
import net.xoetrope.xui.events.XListenerHelper;
import net.xoetrope.xui.style.XStyle;
import net.xoetrope.xui.style.XStyleComponent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
/**
* <p>
* Provides a simple read-only tables/grid component.
* </p>
* <p>
* Copyright (c) Xoetrope Ltd., 1998-2004<br>
* License: see license.txt $Revision: 2.7 $
*/
public class XTable extends Table implements XAttributedComponent, XModelHolder, XStyleComponent, XRowSelector, XListenerHelper
{
protected XModel model;
protected boolean updateModelSelection = false;
protected XHandlerInvoker invoker;
protected org.eclipse.swt.graphics.Color colorSWTFg, colorSWTBg;
protected boolean usesDatabase = false;
private static final int FACT = 6;
private static final double UPPER = 0.5;
/**
* Create a new table
*
* @param parent
* parent object
*/
public XTable( Object parent )
{
super( (Composite)parent, SWT.SINGLE | SWT.FULL_SELECTION );
setDisplayAttributes();
addListener();
}
/**
* Suppress the subclassing exception
*/
protected void checkSubclass()
{
}
/**
* Add a listener
*/
public void addListener()
{
addListener( SWT.EraseItem, new Listener()
{
public void handleEvent( Event event )
{
if ( ( event.detail & SWT.SELECTED ) != 0 ) {
GC gc = event.gc;
Rectangle area = getClientArea();
/*
* If you wish to paint the selection beyond the end of last column,
* you must change the clipping region.
*/
int columnCount = getColumnCount();
if ( event.index == columnCount - 1 || columnCount == 0 ) {
int width = area.x + area.width - event.x;
if ( width > 0 ) {
Region region = new Region();
gc.getClipping( region );
region.add( event.x, event.y, width, event.height );
gc.setClipping( region );
region.dispose();
}
}
gc.setAdvanced( true );
if ( gc.getAdvanced() )
gc.setAlpha( 127 );
Rectangle rect = event.getBounds();
//Color foreground = gc.getForeground();
Color background = gc.getBackground();
if ( colorSWTFg != null )
gc.setForeground( colorSWTFg );
if ( colorSWTBg != null )
gc.setBackground( colorSWTBg );
gc.fillRectangle( 0, rect.y, 500, rect.height );
gc.setBackground( background );
event.detail &= ~SWT.SELECTED;
}
}
} );
}
/**
* Get the width of a string
*
* @param text
* the text
* @return the width
*/
public static int charLength( String text )
{
int l = text.length();
double sum = 0;
for ( int i = 0; i < l; i++ ) {
if ( Character.isUpperCase( text.charAt( i ) ) || Character.isDigit( text.charAt( i ) ) ) {
sum += UPPER;
}
sum++;
}
return ( new Double( sum ).intValue() + 2 ) * FACT;
}
/**
* Set the display attributes
*/
public void setDisplayAttributes()
{
setHeaderVisible( true );
setLinesVisible( true );
for ( int i = 0; i < getColumnCount(); i++ ) {
getColumn( i ).setResizable( true );
getColumn( i ).setAlignment( SWT.CENTER );
updateWidthColumn( i );
}
}
/**
* Set one or more attributes of the component.
*
* @param attribName
* the name of the attribute
* @param attribValue
* the value of the attribute
* @return 0 for success, non zero for failure or to require some further
* action
*/
public int setAttribute( String attribName, Object attribValue )
{
String attribNameLwr = attribName.toLowerCase();
String attribValueStr = (String)attribValue;
String attribValueLwr = null;
if ( attribValue != null )
attribValueLwr = attribValueStr.toLowerCase();
if ( attribNameLwr.equals( "selectionstyle" ) )
setSelectedStyle( attribValueStr );
else if ( attribNameLwr.equals( "borderstyle" ) )
setBorderStyle( attribValueStr );
else if ( attribNameLwr.equals( "interactive" ) )
setInteractiveTable( attribValueStr.equals( "true" ) );
else if ( attribNameLwr.equals( "selectionmode" ) )
setSelectionMode( attribValueStr );
else if ( attribNameLwr.equals( "headervisible" ) )
setHeaderVisible( attribValueStr.equals( "true" ) );
else if ( attribNameLwr.equals( "linesvisible" ) )
setLinesVisible( attribValueStr.equals( "true" ) );
else if ( attribNameLwr.equals( "tooltip" ) )
setToolTipText( attribValueStr );
else if ( attribNameLwr.equals( "visible" ) )
setVisible( attribValueLwr.equals( "true" ) || attribValueLwr.equals( "1" ) );
else
return -1;
return 0;
}
/**
* Set the style of the selected row
*
* @param style
* XStyle
*/
public void setSelectedStyle( String style )
{
XStyle xstyle = XProjectManager.getStyleManager().getStyle( style );
java.awt.Color colorAWTFg = xstyle.getStyleAsColor( XStyle.COLOR_FORE );
java.awt.Color colorAWTBg = xstyle.getStyleAsColor( XStyle.COLOR_BACK );
colorSWTFg = new org.eclipse.swt.graphics.Color( getDisplay(), colorAWTFg.getRed(), colorAWTFg.getGreen(), colorAWTFg.getBlue() );
colorSWTBg = new org.eclipse.swt.graphics.Color( getDisplay(), colorAWTBg.getRed(), colorAWTBg.getGreen(), colorAWTBg.getBlue() );
}
/**
* Set the style of the border
*
* @param style
* XStyle
*/
public void setBorderStyle( String style )
{
}
/**
* Set the user interaction state
*
* @param state
* true for an user interactive table.
*/
public void setInteractiveTable( boolean state )
{
}
/**
* Tie the model selection to this table's selection
*
* @param doUpdate
* true to tie the selections together, false to ignore
*/
public void setUpdateModelSelection( boolean doUpdate )
{
updateModelSelection = doUpdate;
}
public void setSelectionMode( String value )
{
}
/**
* Set the style of the header data
*
* @param style
* XStyle
*/
public void setStyle( String style )
{
// XStyleManager styleMgr = XProjectManager.getStyleManager();
// XStyle xstyle = styleMgr.getStyle( style );
}
/**
* Sets the indexof the selected row
*
* @param idx
* the new selected row
*/
public void setSelectedRow( int idx )
{
setSelection( idx );
}
/**
* Get the row selection index
*
* @return the current row selection index (zero based)
*/
public int getSelectedRow()
{
return getSelectionIndex();
}
/**
* Add an event handler response method to a component such that the page's
* response method is invoked when the event occurs
*
* @param page
* the page containing the method
* @param handlerType
* the type of event handler
* @param methodName
* the method to invoke
* @throws NoSuchMethodException
* cannot add the handler
*/
public void addHandler( Object page, String handlerType, String methodName ) throws NoSuchMethodException
{
invoker = new XHandlerInvoker( page, this, methodName );
}
/**
* Set the XModel which we will be generating the table from
*
* @param xmodel
* The XModel of data
*/
public void setModel( XModel xmodel )
{
model = xmodel;
if ( model != null ) {
usesDatabase = ( model.getClass().getName().indexOf( "DatabaseTableModel" ) > 0 );
model.get();
}
}
/**
* implemented from XModelHolder interface
*/
public void update()
{
refill();
}
/**
* **************************************************** Other Methods
* **********************************************
*/
/**
* Get the underlying model.
*
* @return the model
*/
public XModel getModel()
{
return model;
}
/**
* Refill the table
*/
public void refill()
{
removeAll();
for ( int i = getColumnCount() - 1; i >= 0; i-- )
getColumn( i ).dispose();
if ( usesDatabase )
databaseRefill();
else
staticRefill();
setDisplayAttributes();
}
/**
* Refill from the database
*/
public void databaseRefill()
{
int nbItems = model.getNumChildren();
if ( nbItems > 0 ) {
int nbColumns = model.getNumAttributes();
for ( int i = 0; i < nbColumns; i++ ) {
String name = model.getAttribName( i );
TableColumn tc = new TableColumn( this, SWT.CENTER );
tc.setText( name );
}
for ( int i = 0; i < nbItems; i++ ) {
String[] values = new String[nbColumns];
for ( int j = 0; j < nbColumns; j++ ) {
values[ j ] = getValueAt( i, j );
}
TableItem ti = new TableItem( this, 0 );
ti.setText( values );
}
}
}
/**
* Get the value of the indexes
*
* @param rowIndex
* row index
* @param columnIndex
* column index
* @return the value
*/
public String getValueAt( int rowIndex, int columnIndex )
{
return (String)model.get( rowIndex ).get( columnIndex ).get();
}
/**
* Refill from static elements
*/
public void staticRefill()
{
int nbItems = model.getNumChildren();
if ( nbItems > 0 ) {
int k = 0;
if ( model.get( 0 ).getTagName().equals( "th" ) ) {
XModel xm = model.get( k++ );
int nbColumns = xm.getNumChildren();
for ( int i = 0; i < nbColumns; i++ ) {
TableColumn tc = new TableColumn( this, SWT.CENTER );
String name = xm.get( i ).getAttribValueAsString( xm.get( i ).getAttribute( "value" ) );
tc.setText( name == null ? "" : name );
}
}
for ( ; k < nbItems; k++ ) {
XModel xm = model.get( k );
int nbColumnsModel = xm.getNumChildren();
int nbColumnsTable = getColumnCount();
String[] values = new String[nbColumnsModel];
if ( nbColumnsModel > nbColumnsTable ) {
for ( int i = nbColumnsTable; i < nbColumnsModel; i++ ) {
TableColumn tc = new TableColumn( this, SWT.CENTER );
tc.setText( "" );
}
}
for ( int i = 0; i < nbColumnsModel; i++ ) {
String value = xm.get( i ).getAttribValueAsString( xm.get( i ).getAttribute( "value" ) );
values[ i ] = value == null ? "" : value;
}
TableItem ti = new TableItem( this, 0 );
ti.setText( values );
}
}
}
/**
* **************************************************** Additionnal Methods
* **********************************************
*/
/**
* Update the width of a column
*
* @param index
* index of the column
*/
public void updateWidthColumn( int index )
{
int max = charLength( getColumn( index ).getText() );
for ( int i = 0; i < getItemCount(); i++ ) {
int n = charLength( getItem( i ).getText( index ) );
if ( n > max )
max = n;
}
getColumn( index ).setWidth( max );
}
}