| // Created on 22.08.2009 |
| package org.eclipse.swt.custom; |
| |
| import java.text.MessageFormat; |
| import java.util.*; |
| |
| import org.eclipse.swt.graphics.Rectangle; |
| |
| |
| class SpreadSheetModel { |
| static final int DEFAULT_ROW_HEIGHT = 20; |
| static final int DEFAULT_COLUMN_WIDTH = 100; |
| |
| private final Map rows; |
| private final Map columns; |
| private final Map texts; |
| private final Set listeners; |
| private int rowOffset; |
| private int columnOffset; |
| private int visibleColumns; |
| private int visibleRows; |
| |
| |
| static class Event { |
| private final static int ROW_HEIGHT_CHANGED = 0; |
| private final static int COLUMN_WIDTH_CHANGED = 1; |
| private final static int TEXT_CHANGED = 2; |
| private final static int ROW_OFFSET_CHANGED = 3; |
| private final static int COLUMN_OFFSET_CHANGED = 4; |
| |
| int type; |
| int rowIndex; |
| int columnIndex; |
| int rowHeight; |
| int columnWidth; |
| String text; |
| int rowOffset; |
| int columnOffset; |
| |
| public void fire( final Listener listener ) { |
| switch( type ) { |
| case ROW_HEIGHT_CHANGED: |
| listener.rowHeightChanged( this ); |
| break; |
| |
| case COLUMN_WIDTH_CHANGED: |
| listener.columnWidthChanged( this ); |
| break; |
| |
| case TEXT_CHANGED: |
| listener.textChanged( this ); |
| break; |
| |
| case ROW_OFFSET_CHANGED: |
| listener.rowOffsetChanged( this ); |
| break; |
| |
| case COLUMN_OFFSET_CHANGED: |
| listener.columnOffsetChanged( this ); |
| break; |
| |
| default: |
| String txt = "Event Type ''{0}''not supported"; |
| Object[] param = new Object[] { new Integer( type ) }; |
| String msg = MessageFormat.format( txt, param ); |
| throw new IllegalStateException( msg ); |
| } |
| } |
| } |
| |
| static interface Listener { |
| void rowHeightChanged( Event evt ); |
| void columnOffsetChanged( Event evt ); |
| void rowOffsetChanged( Event evt ); |
| void columnWidthChanged( Event evt ); |
| void textChanged( Event evt ); |
| } |
| |
| static abstract class Adapter implements Listener { |
| public void rowHeightChanged( final Event evt ) {}; |
| public void columnWidthChanged( final Event evt ) {}; |
| public void textChanged( final Event evt ) {}; |
| public void columnOffsetChanged( Event evt ) {}; |
| public void rowOffsetChanged( Event evt ) {}; |
| } |
| |
| |
| public SpreadSheetModel() { |
| rows = new HashMap(); |
| columns = new HashMap(); |
| texts = new HashMap(); |
| listeners = new HashSet(); |
| visibleColumns = 0; |
| visibleRows = 0; |
| } |
| |
| int getRowHeight( final int rowIndex ) { |
| int result = DEFAULT_ROW_HEIGHT; |
| Integer key = new Integer( rowIndex ); |
| Integer height = ( Integer )rows.get( key ); |
| if( height != null ) { |
| result = height.intValue(); |
| } |
| return result; |
| } |
| |
| void setRowHeight( final int rowIndex, final int rowHeight ) { |
| SpreadSheetUtils.checkNotNegative( rowIndex, "rowIndex" ); |
| SpreadSheetUtils.checkNotNegative( rowHeight, "rowHeight" ); |
| |
| Integer key = new Integer( rowIndex ); |
| Integer oldRowHeight = ( Integer )rows.get( key ); |
| Integer newRowHeight = new Integer( rowHeight ); |
| |
| if( rowHeight == SpreadSheetModel.DEFAULT_ROW_HEIGHT ) { |
| rows.remove( key ); |
| } else { |
| rows.put( key, newRowHeight ); |
| } |
| |
| if( !newRowHeight.equals( oldRowHeight ) ) { |
| Event event = new Event(); |
| event.type = Event.ROW_HEIGHT_CHANGED; |
| event.rowIndex = rowIndex; |
| event.rowHeight = rowHeight; |
| fireEvent( event ); |
| } |
| } |
| |
| int getColumnWidth( final int columnIndex ) { |
| int result = DEFAULT_COLUMN_WIDTH; |
| Integer key = new Integer( columnIndex ); |
| Integer width = ( Integer )columns.get( key ); |
| if( width != null ) { |
| result = width.intValue(); |
| } |
| return result; |
| } |
| |
| void setColumnWidth( final int columnIndex, final int columnWidth ) { |
| SpreadSheetUtils.checkNotNegative( columnIndex, "columnIndex" ); |
| SpreadSheetUtils.checkNotNegative( columnWidth, "columnWidth" ); |
| |
| Integer key = new Integer( columnIndex ); |
| Integer newColumnWidth = new Integer( columnWidth ); |
| Integer oldColumnWidth = ( Integer )columns.get( key ); |
| |
| if( columnWidth == DEFAULT_COLUMN_WIDTH ) { |
| columns.remove( key ); |
| } else { |
| columns.put( key, newColumnWidth ); |
| } |
| |
| if( !newColumnWidth.equals( oldColumnWidth ) ) { |
| Event event = new Event(); |
| event.type = Event.COLUMN_WIDTH_CHANGED; |
| event.columnIndex = columnIndex; |
| event.columnWidth = columnWidth; |
| fireEvent( event ); |
| } |
| } |
| |
| String getText( final CellPosition position ) { |
| return getText( position.getRowIndex(), position.getColumnIndex() ); |
| } |
| |
| String getText( final int rowIndex, final int columnIndex ) { |
| SpreadSheetUtils.checkNotNegative( rowIndex, "rowIndex" ); |
| SpreadSheetUtils.checkNotNegative( columnIndex, "columnIndex" ); |
| |
| CellPosition position = new CellPosition( rowIndex, columnIndex ); |
| String result = ( String )texts.get( position ); |
| return result == null ? "" : result; |
| } |
| |
| void setText( final String text, final CellPosition position ) { |
| setText( text, position.getRowIndex(), position.getColumnIndex() ); |
| } |
| |
| void setText( final String text, |
| final int rowIndex, |
| final int columnIndex ) |
| { |
| SpreadSheetUtils.checkNotNull( text, "text" ); |
| SpreadSheetUtils.checkNotNegative( rowIndex, "rowIndex" ); |
| SpreadSheetUtils.checkNotNegative( columnIndex, "columnIndex" ); |
| |
| CellPosition position = new CellPosition( rowIndex, columnIndex ); |
| Object oldText = texts.get( position ); |
| |
| if( "".equals( text ) ) { |
| texts.remove( position ); |
| } else { |
| texts.put( position, text ); |
| } |
| |
| if( !text.equals( oldText ) ) { |
| Event event = new Event(); |
| event.type = Event.TEXT_CHANGED; |
| event.rowIndex = rowIndex; |
| event.columnIndex = columnIndex; |
| event.text = text; |
| fireEvent( event ); |
| } |
| } |
| |
| void setColumnOffset( final int columnOffset ) { |
| SpreadSheetUtils.checkNotNegative( columnOffset, "columnOffset" ); |
| int oldOffset = this.columnOffset; |
| this.columnOffset = columnOffset; |
| if( oldOffset != columnOffset ) { |
| Event event = new Event(); |
| event.type = Event.COLUMN_OFFSET_CHANGED; |
| event.columnOffset = columnOffset; |
| fireEvent( event ); |
| } |
| } |
| |
| int getColumnOffset() { |
| return columnOffset; |
| } |
| |
| void setRowOffset( final int rowOffset ) { |
| SpreadSheetUtils.checkNotNegative( rowOffset, "rowOffset" ); |
| int oldOffset = this.rowOffset; |
| this.rowOffset = rowOffset; |
| if( oldOffset != rowOffset ) { |
| Event event = new Event(); |
| event.type = Event.ROW_OFFSET_CHANGED; |
| event.rowOffset = rowOffset; |
| fireEvent( event ); |
| } |
| |
| } |
| |
| int getRowOffset() { |
| return rowOffset; |
| } |
| |
| void updateVisibleRowAndColumns( final Rectangle clientArea ) { |
| visibleColumns |
| = SpreadSheetUtils.calcVisibleColumns( clientArea.width, this ); |
| visibleRows = SpreadSheetUtils.calcVisibleRows( clientArea.height, this ); |
| } |
| |
| int getVisibleRows() { |
| return visibleRows; |
| } |
| |
| int getVisibleColumns() { |
| return visibleColumns; |
| } |
| |
| void addListener( final Listener listener ) { |
| listeners.add( listener ); |
| } |
| |
| void removeListener( final Listener listener ) { |
| listeners.remove( listener ); |
| } |
| |
| private void fireEvent( final Event event ) { |
| Listener[] lsnrs = new Listener[ listeners.size() ]; |
| listeners.toArray( lsnrs ); |
| for( int i = 0; i < lsnrs.length; i++ ) { |
| event.fire( lsnrs[ i ] ); |
| } |
| } |
| } |