/******************************************************************************* * Copyright (c) 2002, 2009 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 * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.swt.internal.widgets.listkit; import java.io.IOException; import org.eclipse.rwt.lifecycle.*; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.internal.widgets.*; import org.eclipse.swt.widgets.*; public class ListLCA extends AbstractWidgetLCA { private static final String QX_TYPE = "org.eclipse.swt.widgets.List"; // Property names, used when preserving values static final String PROP_SELECTION = "selection"; static final String PROP_ITEMS = "items"; static final String PROP_FOCUS_INDEX = "focusIndex"; static final String PROP_TOP_INDEX = "topIndex"; static final String PROP_HAS_H_SCROLL_BAR = "hasHScrollBar"; static final String PROP_HAS_V_SCROLL_BAR = "hasVScrollBar"; private static final Integer DEFAULT_SINGLE_SELECTION = new Integer( -1 ); private static final int[] DEFAULT_MULTI_SELECTION = new int[ 0 ]; private static final String[] DEFAUT_ITEMS = new String[ 0 ]; private static final Integer DEFAULT_FOCUS_INDEX = new Integer( -1 ); private static final Integer DEFAULT_TOP_INDEX = new Integer( 0 ); public void preserveValues( final Widget widget ) { List list = ( List )widget; ControlLCAUtil.preserveValues( list ); IWidgetAdapter adapter = WidgetUtil.getAdapter( widget ); adapter.preserve( Props.SELECTION_LISTENERS, Boolean.valueOf( SelectionEvent.hasListener( list ) ) ); adapter.preserve( PROP_ITEMS, list.getItems() ); adapter.preserve( PROP_TOP_INDEX, new Integer( list.getTopIndex() ) ); adapter.preserve( PROP_FOCUS_INDEX, new Integer( list.getFocusIndex() ) ); adapter.preserve( PROP_HAS_H_SCROLL_BAR, hasHScrollBar( list ) ); adapter.preserve( PROP_HAS_V_SCROLL_BAR, hasVScrollBar( list ) ); preserveSelection( list ); WidgetLCAUtil.preserveCustomVariant( list ); } public void readData( final Widget widget ) { List list = ( List )widget; readTopIndex( list ); readSelection( list ); readFocusIndex( list ); ControlLCAUtil.processSelection( list, null, true ); ControlLCAUtil.processMouseEvents( list ); ControlLCAUtil.processKeyEvents( list ); ControlLCAUtil.processMenuDetect( list ); WidgetLCAUtil.processHelp( list ); } public void renderInitialization( final Widget widget ) throws IOException { List list = ( List )widget; JSWriter writer = JSWriter.getWriterFor( list ); Boolean multiSelection = Boolean.valueOf( !isSingle( list ) ); writer.newWidget( QX_TYPE, new Object[] { multiSelection } ); ControlLCAUtil.writeStyleFlags( list ); } // TODO [rh] keep scroll position, even when exchanging items public void renderChanges( final Widget widget ) throws IOException { List list = ( List )widget; // order of writeChanges, writeItems, writeSelection, writeFocus is crucial ControlLCAUtil.writeChanges( list ); writeItems( list ); writeSelection( list ); writeTopIndex( list ); writeFocusIndex( list ); writeOverflow( list ); updateSelectionListeners( list ); WidgetLCAUtil.writeCustomVariant( list ); } public void renderDispose( final Widget widget ) throws IOException { JSWriter writer = JSWriter.getWriterFor( widget ); writer.dispose(); } //////////////////////////////////// // Helping methods to preserve state private static void preserveSelection( final List list ) { IWidgetAdapter adapter = WidgetUtil.getAdapter( list ); Object selection; if( isSingle( list ) ) { selection = new Integer( list.getSelectionIndex() ); } else { selection = list.getSelectionIndices(); } adapter.preserve( PROP_SELECTION, selection ); } /////////////////////////////////////////// // Helping methods to write JavaScript code private static void writeItems( final List list ) throws IOException { JSWriter writer = JSWriter.getWriterFor( list ); String[] items = list.getItems(); if( WidgetLCAUtil.hasChanged( list, PROP_ITEMS, items, DEFAUT_ITEMS ) ) { // Convert newlines into whitespaces for( int i = 0; i < items.length; i++ ) { items[ i ] = WidgetLCAUtil.replaceNewLines( items[ i ], " " ); items[ i ] = WidgetLCAUtil.escapeText( items[ i ], false ); } writer.set( "items", new Object[]{ items } ); } } private static void writeSelection( final List list ) throws IOException { JSWriter writer = JSWriter.getWriterFor( list ); String prop = PROP_SELECTION; if( isSingle( list ) ) { Integer newValue = new Integer( list.getSelectionIndex() ); Integer defValue = DEFAULT_SINGLE_SELECTION; if( WidgetLCAUtil.hasChanged( list, prop, newValue, defValue )) { writer.call( "selectItem", new Object[] { newValue } ); } } else { int[] newValue = list.getSelectionIndices(); int[] defValue = DEFAULT_MULTI_SELECTION; if( WidgetLCAUtil.hasChanged( list, prop, newValue, defValue ) ) { if( list.getSelectionCount() == list.getItemCount() ) { writer.call( "selectAll", null ); } else { int[] selection = list.getSelectionIndices(); Integer[] newSelection = new Integer[ selection.length ]; for( int i = 0; i < newSelection.length; i++ ) { newSelection[ i ] = new Integer( selection[ i ] ); } writer.call( "selectItems", new Object[] { newSelection } ); } } } } private static void writeFocusIndex( final List list ) throws IOException { String prop = PROP_FOCUS_INDEX; Integer newValue = new Integer( list.getFocusIndex() ); if( WidgetLCAUtil.hasChanged( list, prop, newValue, DEFAULT_FOCUS_INDEX ) ) { JSWriter writer = JSWriter.getWriterFor( list ); writer.call( "focusItem", new Object[] { newValue} ); } } private static void writeTopIndex( final List list ) throws IOException { JSWriter writer = JSWriter.getWriterFor( list ); Integer newValue = new Integer( list.getTopIndex() ); writer.set( PROP_TOP_INDEX, "topIndex", newValue, DEFAULT_TOP_INDEX ); } private static void writeOverflow( final List list ) throws IOException { boolean hasHChanged = WidgetLCAUtil.hasChanged( list, PROP_HAS_H_SCROLL_BAR, hasHScrollBar( list ), Boolean.FALSE ); boolean hasVChanged = WidgetLCAUtil.hasChanged( list, PROP_HAS_V_SCROLL_BAR, hasVScrollBar( list ), Boolean.FALSE ); if( hasHChanged || hasVChanged ) { boolean scrollX = hasHScrollBar( list ).booleanValue(); boolean scrollY = hasVScrollBar( list ).booleanValue(); String overflow; if( scrollX && scrollY ) { overflow = "auto"; } else if( scrollX ) { overflow = "scrollX"; } else if( scrollY ) { overflow = "scrollY"; } else { overflow = "hidden"; } JSWriter writer = JSWriter.getWriterFor( list ); writer.set( "overflow", overflow ); } } private static void updateSelectionListeners( final List list ) throws IOException { String prop = Props.SELECTION_LISTENERS; Boolean newValue = Boolean.valueOf( SelectionEvent.hasListener( list ) ); Boolean defValue = Boolean.FALSE; if( WidgetLCAUtil.hasChanged( list, prop, newValue, defValue ) ) { JSWriter writer = JSWriter.getWriterFor( list ); String value = newValue.booleanValue() ? "action" : "state"; writer.set( "changeSelectionNotification", value ); } } //////////////////////////////////////////// // Helping methods to read client-side state private static void readSelection( final List list ) { String value = WidgetLCAUtil.readPropertyValue( list, "selection" ); if( value != null ) { String[] indiceStrings; if( "".equals( value ) ) { indiceStrings = new String[ 0 ]; } else { indiceStrings = value.split( "," ); } int[] indices = new int[ indiceStrings.length ]; for( int i = 0; i < indices.length; i++ ) { indices[ i ] = Integer.parseInt( indiceStrings[ i ] ); } list.setSelection( indices ); } } private static void readTopIndex( final List list ) { String value = WidgetLCAUtil.readPropertyValue( list, "topIndex" ); if( value != null ) { list.setTopIndex( Integer.parseInt( value ) ); } } private static void readFocusIndex( final List list ) { String paramValue = WidgetLCAUtil.readPropertyValue( list, "focusIndex" ); if( paramValue != null ) { int focusIndex = Integer.parseInt( paramValue ); Object adapter = list.getAdapter( IListAdapter.class ); IListAdapter listAdapter = ( IListAdapter )adapter; listAdapter.setFocusIndex( focusIndex ); } } ////////////////// // Helping methods private static boolean isSingle( final List list ) { return ( list.getStyle() & SWT.SINGLE ) != 0; } private static Boolean hasHScrollBar( final List list ) { Object adapter = list.getAdapter( IListAdapter.class ); IListAdapter listAdapter = ( IListAdapter )adapter; return Boolean.valueOf( listAdapter.hasHScrollBar() ); } private static Boolean hasVScrollBar( final List list ) { Object adapter = list.getAdapter( IListAdapter.class ); IListAdapter listAdapter = ( IListAdapter )adapter; return Boolean.valueOf( listAdapter.hasVScrollBar() ); } }