/******************************************************************************* * 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.treekit; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import org.eclipse.rwt.internal.lifecycle.JSConst; import org.eclipse.rwt.internal.service.ContextProvider; import org.eclipse.rwt.lifecycle.*; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.internal.events.EventLCAUtil; import org.eclipse.swt.internal.widgets.ITreeAdapter; import org.eclipse.swt.widgets.*; public final class TreeLCA extends AbstractWidgetLCA { // Property names used by preserve mechanism private static final String PROP_SELECTION_LISTENERS = "selectionListeners"; static final String PROP_HEADER_HEIGHT = "headerHeight"; static final String PROP_HEADER_VISIBLE = "headerVisible"; static final String PROP_COLUMN_ORDER = "columnOrder"; static final String PROP_SCROLL_LEFT = "scrollLeft"; static final String PROP_HAS_H_SCROLL_BAR = "hasHScrollBar"; static final String PROP_HAS_V_SCROLL_BAR = "hasVScrollBar"; private static final Integer DEFAULT_SCROLL_LEFT = new Integer( 0 ); public void preserveValues( final Widget widget ) { Tree tree = ( Tree )widget; ControlLCAUtil.preserveValues( ( Control )widget ); IWidgetAdapter adapter = WidgetUtil.getAdapter( tree ); adapter.preserve( PROP_SELECTION_LISTENERS, Boolean.valueOf( SelectionEvent.hasListener( tree ) ) ); adapter.preserve( PROP_HEADER_HEIGHT, new Integer( tree.getHeaderHeight() ) ); adapter.preserve( PROP_HEADER_VISIBLE, Boolean.valueOf( tree.getHeaderVisible() ) ); int[] values = tree.getColumnOrder(); Integer[] columnOrder = new Integer[ values.length ]; for( int i = 0; i < values.length; i++ ) { columnOrder[ i ] = new Integer( values[ i ] ); } adapter.preserve( PROP_COLUMN_ORDER, columnOrder ); adapter.preserve( PROP_SCROLL_LEFT, getScrollLeft( tree ) ); adapter.preserve( PROP_HAS_H_SCROLL_BAR, hasHScrollBar( tree ) ); adapter.preserve( PROP_HAS_V_SCROLL_BAR, hasVScrollBar( tree ) ); WidgetLCAUtil.preserveCustomVariant( tree ); } public void readData( final Widget widget ) { Tree tree = ( Tree )widget; readSelection( tree ); readScrollPosition( tree ); processWidgetSelectedEvent( tree ); processWidgetDefaultSelectedEvent( tree ); ControlLCAUtil.processMouseEvents( tree ); ControlLCAUtil.processKeyEvents( tree ); ControlLCAUtil.processMenuDetect( tree ); WidgetLCAUtil.processHelp( tree ); } public void renderInitialization( final Widget widget ) throws IOException { Tree tree = ( Tree )widget; JSWriter writer = JSWriter.getWriterFor( tree ); StringBuffer style = new StringBuffer(); if( ( tree.getStyle() & SWT.MULTI ) != 0 ) { style.append( "multi|" ); } if( ( tree.getStyle() & SWT.CHECK ) != 0 ) { style.append( "check|" ); } if( ( tree.getStyle() & SWT.VIRTUAL ) != 0 ) { style.append( "virtual|" ); } writer.newWidget( "org.eclipse.swt.widgets.Tree", new Object[]{ style.toString() } ); ControlLCAUtil.writeStyleFlags( tree ); } public void renderChanges( final Widget widget ) throws IOException { Tree tree = ( Tree )widget; ControlLCAUtil.writeChanges( tree ); updateSelectionListener( tree ); writeHeaderHeight( tree ); writeHeaderVisible( tree ); writeColumnOrder( tree ); writeScrollLeft( tree ); writeOverflow( tree ); WidgetLCAUtil.writeCustomVariant( tree ); } public void renderDispose( final Widget widget ) throws IOException { JSWriter writer = JSWriter.getWriterFor( widget ); writer.dispose(); } public void doRedrawFake( final Control control ) { int evtId = ControlEvent.CONTROL_RESIZED; ControlEvent evt = new ControlEvent( control, evtId ); evt.processEvent(); } private static void processWidgetSelectedEvent( final Tree tree ) { HttpServletRequest request = ContextProvider.getRequest(); String eventName = JSConst.EVENT_WIDGET_SELECTED; if( WidgetLCAUtil.wasEventSent( tree, eventName ) ) { Rectangle bounds = new Rectangle( 0, 0, 0, 0 ); String itemId = request.getParameter( eventName + ".item" ); Item treeItem = ( Item )WidgetUtil.find( tree, itemId ); String detailStr = request.getParameter( eventName + ".detail" ); int detail = "check".equals( detailStr ) ? SWT.CHECK : SWT.NONE; int eventType = SelectionEvent.WIDGET_SELECTED; int stateMask = EventLCAUtil.readStateMask( JSConst.EVENT_WIDGET_SELECTED_MODIFIER ); SelectionEvent event = new SelectionEvent( tree, treeItem, eventType, bounds, stateMask, null, true, detail ); event.processEvent(); } } private static void processWidgetDefaultSelectedEvent( final Tree tree ) { HttpServletRequest request = ContextProvider.getRequest(); String eventName = JSConst.EVENT_WIDGET_DEFAULT_SELECTED; if( WidgetLCAUtil.wasEventSent( tree, eventName ) ) { String itemId = request.getParameter( eventName + ".item" ); Item treeItem = ( Item )WidgetUtil.find( tree, itemId ); int eventType = SelectionEvent.WIDGET_DEFAULT_SELECTED; SelectionEvent event = new SelectionEvent( tree, treeItem, eventType ); event.stateMask = EventLCAUtil.readStateMask( JSConst.EVENT_WIDGET_SELECTED_MODIFIER ); event.processEvent(); } } ///////////////////////////////////////////// // Helping methods to read client-side state private static void readSelection( final Tree tree ) { String value = WidgetLCAUtil.readPropertyValue( tree, "selection" ); if( value != null ) { String[] values = value.split( "," ); TreeItem[] selectedItems = new TreeItem[ values.length ]; boolean validItemFound = false; for( int i = 0; i < values.length; i++ ) { selectedItems[ i ] = ( TreeItem )WidgetUtil.find( tree, values[ i ] ); if( selectedItems[ i ] != null ) { validItemFound = true; } } if( !validItemFound ) { selectedItems = new TreeItem[ 0 ]; } tree.setSelection( selectedItems ); } } private static void readScrollPosition( final Tree tree ) { String left = WidgetLCAUtil.readPropertyValue( tree, "scrollLeft" ); String top = WidgetLCAUtil.readPropertyValue( tree, "scrollTop" ); if( left != null && top != null ) { Object adapter = tree.getAdapter( ITreeAdapter.class ); final ITreeAdapter treeAdapter = ( ITreeAdapter )adapter; final int newScrollLeft = parsePosition( left ); final int newScrollTop = parsePosition( top ); final int oldScrollTop = treeAdapter.getScrollTop(); treeAdapter.setScrollLeft( newScrollLeft ); treeAdapter.setScrollTop( newScrollTop ); if( oldScrollTop != newScrollTop ) { ProcessActionRunner.add( new Runnable() { public void run() { treeAdapter.checkAllData( tree ); } } ); } } } private static int parsePosition( final String position ) { int result = 0; try { result = Integer.valueOf( position ).intValue(); } catch( NumberFormatException e ) { // ignore and use default value } return result; } ////////////////////////////////////////////////////////////// // Helping methods to write JavaScript for changed properties private static void writeHeaderHeight( final Tree tree ) throws IOException { JSWriter writer = JSWriter.getWriterFor( tree ); Integer newValue = new Integer( tree.getHeaderHeight() ); writer.set( PROP_HEADER_HEIGHT, "headerHeight", newValue, null ); } private void writeColumnOrder( final Tree tree ) throws IOException { JSWriter writer = JSWriter.getWriterFor( tree ); int[] values = tree.getColumnOrder(); if( values.length > 0 ) { Integer[] newValue = new Integer[ values.length ]; for( int i = 0; i < values.length; i++ ) { newValue[ i ] = new Integer( values[ i ] ); } if( WidgetLCAUtil.hasChanged( tree, PROP_COLUMN_ORDER, newValue, new Integer[]{} ) ) { writer.set( PROP_COLUMN_ORDER, "columnOrder", newValue, null ); } } } private static void writeHeaderVisible( final Tree tree ) throws IOException { JSWriter writer = JSWriter.getWriterFor( tree ); Boolean newValue = Boolean.valueOf( tree.getHeaderVisible() ); writer.set( PROP_HEADER_VISIBLE, "headerVisible", newValue, Boolean.FALSE ); } private void writeScrollLeft( final Tree tree ) throws IOException { JSWriter writer = JSWriter.getWriterFor( tree ); Integer newValue = getScrollLeft( tree ); writer.set( PROP_SCROLL_LEFT, "scrollLeft", newValue, DEFAULT_SCROLL_LEFT ); } private static void writeOverflow( final Tree tree ) throws IOException { boolean hasHChanged = WidgetLCAUtil.hasChanged( tree, PROP_HAS_H_SCROLL_BAR, hasHScrollBar( tree ), Boolean.TRUE ); boolean hasVChanged = WidgetLCAUtil.hasChanged( tree, PROP_HAS_V_SCROLL_BAR, hasVScrollBar( tree ), Boolean.TRUE ); if( hasHChanged || hasVChanged ) { boolean scrollX = hasHScrollBar( tree ).booleanValue(); boolean scrollY = hasVScrollBar( tree ).booleanValue(); String overflow; if( scrollX && scrollY ) { overflow = "scroll"; } else if( scrollX ) { overflow = "scrollX"; } else if( scrollY ) { overflow = "scrollY"; } else { overflow = "hidden"; } JSWriter writer = JSWriter.getWriterFor( tree ); writer.set( "treeOverflow", overflow ); } } private static void updateSelectionListener( final Tree tree ) throws IOException { Boolean newValue = Boolean.valueOf( SelectionEvent.hasListener( tree ) ); String prop = PROP_SELECTION_LISTENERS; if( WidgetLCAUtil.hasChanged( tree, prop, newValue, Boolean.FALSE ) ) { JSWriter writer = JSWriter.getWriterFor( tree ); writer.set( "selectionListeners", newValue ); } } ////////////////// // Helping methods private static Integer getScrollLeft( final Tree tree ) { Object adapter = tree.getAdapter( ITreeAdapter.class ); ITreeAdapter treeAdapter = ( ITreeAdapter )adapter; return new Integer( treeAdapter.getScrollLeft() ); } private static Boolean hasHScrollBar( final Tree tree ) { Object adapter = tree.getAdapter( ITreeAdapter.class ); ITreeAdapter treeAdapter = ( ITreeAdapter )adapter; return Boolean.valueOf( treeAdapter.hasHScrollBar() ); } private static Boolean hasVScrollBar( final Tree tree ) { Object adapter = tree.getAdapter( ITreeAdapter.class ); ITreeAdapter treeAdapter = ( ITreeAdapter )adapter; return Boolean.valueOf( treeAdapter.hasVScrollBar() ); } }