/******************************************************************************* * Copyright (c) 2002, 2010 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.shellkit; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.eclipse.rwt.internal.lifecycle.JSConst; import org.eclipse.rwt.internal.protocol.Chunk; import org.eclipse.rwt.internal.protocol.IChunkAdapter; import org.eclipse.rwt.internal.service.ContextProvider; import org.eclipse.rwt.lifecycle.*; import org.eclipse.rwt.protocol.IWidgetSynchronizer; import org.eclipse.rwt.protocol.WidgetSynchronizerFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.events.ActivateEvent; import org.eclipse.swt.internal.graphics.ResourceFactory; import org.eclipse.swt.internal.widgets.*; import org.eclipse.swt.widgets.*; public final class ShellLCA extends AbstractWidgetLCA implements IChunkAdapter { private static final int MODAL = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL; private static final String QX_TYPE = "org.eclipse.swt.widgets.Shell"; private static final String PROP_TEXT = "text"; private static final String PROP_IMAGE = "image"; private static final String PROP_ALPHA = "alpha"; static final String PROP_ACTIVE_CONTROL = "activeControl"; static final String PROP_ACTIVE_SHELL = "activeShell"; static final String PROP_MODE = "mode"; static final String PROP_FULLSCREEN = "fullScreen"; static final String PROP_MINIMUM_SIZE = "minimumSize"; static final String PROP_SHELL_LISTENER = "shellListener"; private static final String PROP_SHELL_MENU = "menuBar"; private static final String PROP_SHELL_MENU_BOUNDS = "menuBarShellClientArea"; private final static Object[] NULL_PARAMETER = new Object[] { null }; public void preserveValues( final Widget widget ) { ControlLCAUtil.preserveValues( ( Control )widget ); Shell shell = ( Shell )widget; IWidgetAdapter adapter = WidgetUtil.getAdapter( shell ); adapter.preserve( PROP_ACTIVE_CONTROL, getActiveControl( shell ) ); adapter.preserve( PROP_ACTIVE_SHELL, shell.getDisplay().getActiveShell() ); adapter.preserve( PROP_TEXT, shell.getText() ); adapter.preserve( PROP_IMAGE, shell.getImage() ); adapter.preserve( PROP_ALPHA, new Integer( shell.getAlpha() ) ); adapter.preserve( PROP_MODE, getMode( shell ) ); adapter.preserve( PROP_FULLSCREEN, Boolean.valueOf( shell.getFullScreen() ) ); adapter.preserve( PROP_SHELL_LISTENER, Boolean.valueOf( ShellEvent.hasListener( shell ) ) ); adapter.preserve( PROP_SHELL_MENU, shell.getMenuBar() ); adapter.preserve( PROP_MINIMUM_SIZE, shell.getMinimumSize() ); WidgetLCAUtil.preserveCustomVariant( shell ); } public void readData( final Widget widget ) { // HttpServletRequest request = ContextProvider.getRequest(); // String parameter = request.getParameter( "JSON" ); // if( parameter != null ) { // System.out.println( "#### BEGIN ####"); // System.out.println( parameter ); // System.out.println( "#### END ####"); // } Shell shell = ( Shell )widget; // [if] Preserve the menu bounds before setting the new shell bounds. preserveMenuBounds( shell ); // Important: Order matters, readMode() before readBounds() readBounds( shell ); if( WidgetLCAUtil.wasEventSent( shell, JSConst.EVENT_SHELL_CLOSED ) ) { shell.close(); } processActiveShell( shell ); processActivate( shell ); ControlLCAUtil.processMouseEvents( shell ); ControlLCAUtil.processKeyEvents( shell ); ControlLCAUtil.processMenuDetect( shell ); WidgetLCAUtil.processHelp( shell ); } public void readData( final Widget widget, final Chunk chunk ) { Object value = chunk.getValue( "mode" ); if( value != null && value instanceof String ) { readMode( ( Shell )widget, ( String) value ); } } public void processEvent( final Widget widget, final String eventName ) { //System.out.println(eventName); } public void renderInitialization( final Widget widget ) throws IOException { IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( widget ); List styleList = new ArrayList(); int style = widget.getStyle(); if( ( style & SWT.BORDER ) != 0 ) { styleList.add( "BORDER" ); } if( ( style & MODAL ) != 0 ) { styleList.add( "MODAL" ); } if( ( style & SWT.ON_TOP ) != 0 ) { styleList.add( "ON_TOP" ); } if( ( style & SWT.TITLE ) != 0 ) { styleList.add( "TITLE" ); } if( ( style & SWT.TOOL ) != 0 ) { styleList.add( "TOOL" ); } if( ( style & SWT.SHEET ) != 0 ) { styleList.add( "SHEET" ); } if( ( style & SWT.MIN ) != 0 ) { styleList.add( "MIN" ); } if( ( style & SWT.MAX ) != 0 ) { styleList.add( "MAX" ); } if( ( style & SWT.CLOSE ) != 0 ) { styleList.add( "CLOSE" ); } if( ( style & SWT.RESIZE ) != 0 ) { styleList.add( "RESIZE" ); } String[] styles = new String[ styleList.size() ]; styleList.toArray( styles ); Composite parent = ( ( Shell )widget ).getParent(); if( parent instanceof Shell ) { String parentId = WidgetUtil.getId( parent ); synchronizer.newWidget( styles, new Object[] { parentId } ); } synchronizer.newWidget( styles ); // old // JSWriter writer = JSWriter.getWriterFor( widget ); // Shell shell = ( Shell )widget; // writer.newWidget( QX_TYPE ); // ControlLCAUtil.writeStyleFlags( shell ); // if( ( style & MODAL ) != 0 ) { // writer.call( "addState", new Object[] { "rwt_APPLICATION_MODAL" } ); // } // if( ( style & SWT.ON_TOP ) != 0 ) { // writer.call( "addState", new Object[] { "rwt_ON_TOP" } ); // } // if( ( style & SWT.TITLE ) != 0 ) { // writer.call( "addState", new Object[]{ "rwt_TITLE" } ); // } // if( ( style & SWT.TOOL ) != 0 ) { // writer.call( "addState", new Object[]{ "rwt_TOOL" } ); // } // if( ( style & SWT.SHEET ) != 0 ) { // writer.call( "addState", new Object[]{ "rwt_SHEET" } ); // } // writer.set( "showMinimize", ( style & SWT.MIN ) != 0 ); // writer.set( "allowMinimize", ( style & SWT.MIN ) != 0 ); // writer.set( "showMaximize", ( style & SWT.MAX ) != 0 ); // writer.set( "allowMaximize", ( style & SWT.MAX ) != 0 ); // writer.set( "showClose", ( style & SWT.CLOSE ) != 0 ); // writer.set( "allowClose", ( style & SWT.CLOSE ) != 0 ); // Boolean resizable = Boolean.valueOf( ( style & SWT.RESIZE ) != 0 ); // writer.set( "resizable", // new Object[] { resizable, resizable, resizable, resizable } ); // if( parent instanceof Shell ) { // writer.set( "parentShell", parent ); // } // writer.call( "initialize", null ); } public void renderChanges( final Widget widget ) throws IOException { Shell shell = ( Shell )widget; writeImage( shell ); writeText( shell ); writeAlpha( shell ); // Important: Order matters, writing setActive() before open() leads to // strange behavior! writeOpen( shell ); writeActiveShell( shell ); // Important: Order matters, write setMode() after open() and before // setBounds() - see bug 302224 writeMode( shell ); writeFullScreen( shell ); writeCloseListener( shell ); writeMinimumSize( shell ); writeDefaultButton( shell ); ControlLCAUtil.writeChanges( shell ); WidgetLCAUtil.writeCustomVariant( shell ); } public void renderDispose( final Widget widget ) throws IOException { // JSWriter writer = JSWriter.getWriterFor( widget ); // writer.call( "doClose", null ); // writer.dispose(); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( widget ); synchronizer.disposeWidget(); } ////////////////// // Helping methods private static void writeText( final Shell shell ) throws IOException { String text = shell.getText(); if( WidgetLCAUtil.hasChanged( shell, PROP_TEXT, text, "" ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); text = WidgetLCAUtil.escapeText( text, false ); // writer.set( JSConst.QX_FIELD_CAPTION, text ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( JSConst.QX_FIELD_CAPTION, text ); } } private void writeAlpha( final Shell shell ) throws IOException { int alpha = shell.getAlpha(); if( WidgetLCAUtil.hasChanged( shell, PROP_ALPHA, new Integer( alpha ), new Integer( 0xFF ) ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); float opacity = ( alpha & 0xFF ) * 1000 / 0xFF / 1000.0f; // writer.set( "opacity", opacity ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( "opacity", opacity ); } } private static void writeOpen( final Shell shell ) throws IOException { // TODO [rst] workaround: qx window should be opened only once. Boolean defValue = Boolean.FALSE; Boolean actValue = Boolean.valueOf( shell.getVisible() ); if( WidgetLCAUtil.hasChanged( shell, Props.VISIBLE, actValue, defValue ) && shell.getVisible() ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.call( "open", null ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.call( "open" ); } } private static void writeMinimumSize( final Shell shell ) throws IOException { Point newValue = shell.getMinimumSize(); if( WidgetLCAUtil.hasChanged( shell, PROP_MINIMUM_SIZE, newValue ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.set( "minWidth", new Integer( newValue.x ) ); // writer.set( "minHeight", new Integer( newValue.y ) ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( "minWidth", newValue.x ); synchronizer.setWidgetProperty( "minHeight", newValue.y ); } } private static void writeDefaultButton( final Shell shell ) throws IOException { Button defaultButton = shell.getDefaultButton(); if( defaultButton != null && defaultButton.isDisposed() ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.call( "setDefaultButton", NULL_PARAMETER ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.call( "setDefaultButton" ); } } ///////////////////////////////////////////// // Methods to read and write the active shell private static void writeActiveShell( final Shell shell ) throws IOException { Shell activeShell = shell.getDisplay().getActiveShell(); boolean hasChanged = WidgetLCAUtil.hasChanged( shell, PROP_ACTIVE_SHELL, activeShell, null ); if( shell == activeShell && hasChanged ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.set( "active", true ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( "active", true ); } } private static void processActiveShell( final Shell shell ) { if( WidgetLCAUtil.wasEventSent( shell, JSConst.EVENT_SHELL_ACTIVATED ) ) { Shell lastActiveShell = shell.getDisplay().getActiveShell(); setActiveShell( shell ); ActivateEvent event; if( lastActiveShell != null ) { event = new ActivateEvent( lastActiveShell, ActivateEvent.DEACTIVATED ); event.processEvent(); } event = new ActivateEvent( shell, ActivateEvent.ACTIVATED ); event.processEvent(); } } private static void setActiveShell( final Shell shell ) { Object adapter = shell.getDisplay().getAdapter( IDisplayAdapter.class ); IDisplayAdapter displayAdapter = ( IDisplayAdapter )adapter; displayAdapter.setActiveShell( shell ); } ///////////////////////////////////////////////////// // Methods to handle activeControl and ActivateEvents /* (intentionally non-JavaDoc'ed) * This method is declared public only to be accessible from DisplayLCA */ public static void writeActiveControl( final Shell shell ) throws IOException { final Control activeControl = getActiveControl( shell ); String prop = PROP_ACTIVE_CONTROL; if( WidgetLCAUtil.hasChanged( shell, prop, activeControl, null ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.set( "activeControl", new Object[] { activeControl } ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( "activeControl", WidgetUtil.getId( activeControl ) ); } } // TODO [rh] is this safe for multiple shells? private static void processActivate( final Shell shell ) { HttpServletRequest request = ContextProvider.getRequest(); String widgetId = request.getParameter( JSConst.EVENT_WIDGET_ACTIVATED ); if( widgetId != null ) { Widget widget = WidgetUtil.find( shell, widgetId ); if( widget != null ) { setActiveControl( shell, widget ); } } else { String activeControlId = WidgetLCAUtil.readPropertyValue( shell, "activeControl" ); Widget widget = WidgetUtil.find( shell, activeControlId ); if( widget != null ) { setActiveControl( shell, widget ); } } } private static Control getActiveControl( final Shell shell ) { Object adapter = shell.getAdapter( IShellAdapter.class ); IShellAdapter shellAdapter = ( IShellAdapter )adapter; Control activeControl = shellAdapter.getActiveControl(); return activeControl; } private static void setActiveControl( final Shell shell, final Widget widget ) { if( EventUtil.isAccessible( widget ) ) { Object adapter = shell.getAdapter( IShellAdapter.class ); IShellAdapter shellAdapter = ( IShellAdapter )adapter; shellAdapter.setActiveControl( ( Control )widget ); } } private static void writeImage( final Shell shell ) throws IOException { if( ( shell.getStyle() & SWT.TITLE ) != 0 ) { Image image = shell.getImage(); if( image == null ) { Image[] defaultImages = shell.getImages(); if( defaultImages.length > 0 ) { image = defaultImages[0]; } } if( WidgetLCAUtil.hasChanged( shell, PROP_IMAGE, image, null ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.set( JSConst.QX_FIELD_ICON, // ResourceFactory.getImagePath( image ) ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( JSConst.QX_FIELD_ICON, ResourceFactory.getImagePath( image ) ); } } } private static void readBounds( final Shell shell ) { Rectangle bounds = WidgetLCAUtil.readBounds( shell, shell.getBounds() ); Object adapter = shell.getAdapter( IShellAdapter.class ); IShellAdapter shellAdapter = ( IShellAdapter )adapter; shellAdapter.setBounds( bounds ); } private static void readMode( final Shell shell, final String mode ) { if( mode != null ) { if( "maximized".equals( mode ) ) { shell.setMaximized( true ); } else if( "minimized".equals( mode ) ) { shell.setMinimized( true ); } else { shell.setMinimized( false ); shell.setMaximized( false ); } } } private static void writeMode( final Shell shell ) throws IOException { Object defValue = null; Object newValue = getMode( shell ); if( WidgetLCAUtil.hasChanged( shell, PROP_MODE, newValue, defValue ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.set( "mode", newValue ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( "mode", newValue ); } } private static void writeCloseListener( final Shell shell ) throws IOException { // JSWriter writer = JSWriter.getWriterFor( shell ); Boolean newValue = Boolean.valueOf( ShellEvent.hasListener( shell ) ); Boolean defValue = Boolean.FALSE; // writer.set( PROP_SHELL_LISTENER, "hasShellListener", newValue, defValue ); boolean hasChanged = WidgetLCAUtil.hasChanged( shell, PROP_SHELL_LISTENER, newValue, defValue ); if( hasChanged ) { IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); if( newValue.booleanValue() ) { synchronizer.addListener( "closelistener" ); } else { synchronizer.removeListener( "closelistener" ); } } } private static void writeFullScreen( final Shell shell ) throws IOException { Object defValue = Boolean.FALSE; Boolean newValue = Boolean.valueOf( shell.getFullScreen() ); if( WidgetLCAUtil.hasChanged( shell, PROP_FULLSCREEN, newValue, defValue ) ) { // JSWriter writer = JSWriter.getWriterFor( shell ); // writer.set( "fullScreen", newValue ); IWidgetSynchronizer synchronizer = WidgetSynchronizerFactory.getSynchronizerForWidget( shell ); synchronizer.setWidgetProperty( "fullScreen", newValue ); } } private static String getMode( final Shell shell ) { String result = null; if( shell.getMinimized() ) { result = "minimized"; } else if( shell.getMaximized() || shell.getFullScreen() ) { result = "maximized"; } return result; } private static void preserveMenuBounds( final Shell shell ) { Object adapter = shell.getAdapter( IShellAdapter.class ); IShellAdapter shellAdapter = ( IShellAdapter )adapter; Rectangle menuBounds = shellAdapter.getMenuBounds(); IWidgetAdapter widgetAdapter = WidgetUtil.getAdapter( shell ); widgetAdapter.preserve( PROP_SHELL_MENU_BOUNDS, menuBounds ); } }