/******************************************************************************* * Copyright (c) 2009, 2015 EclipseSource and others. * 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: * EclipseSource - initial API and implementation ******************************************************************************/ package org.eclipse.ui.forms.internal.widgets.formtextkit; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetLCAUtil.preserveProperty; import static org.eclipse.rap.rwt.internal.protocol.RemoteObjectFactory.createRemoteObject; import static org.eclipse.rap.rwt.internal.protocol.RemoteObjectFactory.getRemoteObject; import static org.eclipse.rap.rwt.widgets.WidgetUtil.getId; import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.rap.json.*; import org.eclipse.rap.rwt.internal.lifecycle.*; import org.eclipse.rap.rwt.remote.RemoteObject; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.graphics.ImageFactory; import org.eclipse.ui.forms.HyperlinkSettings; import org.eclipse.ui.forms.internal.widgets.*; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.internal.forms.widgets.*; @SuppressWarnings("restriction") public class FormTextLCA extends WidgetLCA<FormText> { public static final FormTextLCA INSTANCE = new FormTextLCA(); private static final String TYPE = "forms.widgets.FormText"; //$NON-NLS-1$ private static final Pattern FONT_NAME_FILTER_PATTERN = Pattern.compile( "\"|\\\\" ); //$NON-NLS-1$ private static final String PREFIX = "resource/widget/rap/formtext/"; //$NON-NLS-1$ private static final String BULLET_CIRCLE_GIF = PREFIX + "bullet_circle.gif"; //$NON-NLS-1$ // Property names for preserveValues private static final String PROP_BOUNDS = "bounds"; //$NON-NLS-1$ private static final String PROP_TEXT = "text"; //$NON-NLS-1$ private static final String PROP_HYPERLINK_SETTINGS = "hyperlinkSettings"; //$NON-NLS-1$ private static final String PROP_HYPERLINK_UNDERLINE_MODE = "hyperlinkUnderlineMode"; //$NON-NLS-1$ private static final String PROP_HYPERLINK_FOREGROUND = "hyperlinkForeground"; //$NON-NLS-1$ private static final String PROP_HYPERLINK_ACTIVE_FOREGROUND = "hyperlinkActiveForeground"; //$NON-NLS-1$ private static final String PROP_RESOURCE_TABLE = "resourceTable"; //$NON-NLS-1$ @Override public void preserveValues( FormText formText ) { HyperlinkSettings settings = formText.getHyperlinkSettings(); preserveProperty( formText, PROP_HYPERLINK_UNDERLINE_MODE, settings.getHyperlinkUnderlineMode() ); preserveProperty( formText, PROP_HYPERLINK_FOREGROUND, settings.getForeground() ); preserveProperty( formText, PROP_HYPERLINK_ACTIVE_FOREGROUND, settings.getActiveForeground() ); preserveProperty( formText, PROP_RESOURCE_TABLE, getResourceTable( formText ) ); } @Override public void renderInitialization( FormText formText ) throws IOException { RemoteObject remoteObject = createRemoteObject( formText, TYPE ); remoteObject.setHandler( new FormTextOperationHandler( formText ) ); remoteObject.set( "parent", getId( formText.getParent() ) ); //$NON-NLS-1$ } @Override public void renderChanges( FormText formText ) throws IOException { ControlLCAUtil.renderChanges( formText ); WidgetLCAUtil.renderCustomVariant( formText ); renderHyperlinkSettings( formText ); renderText( formText ); } //////////////////////////// // Render changed properties private static void renderHyperlinkSettings( FormText formText ) { if( hasHyperlinkSettingsChanged( formText ) ) { HyperlinkSettings newValue = formText.getHyperlinkSettings(); int underlineMode = newValue.getHyperlinkUnderlineMode(); Color foreground = newValue.getForeground(); Color activeForeground = newValue.getActiveForeground(); JsonArray args = new JsonArray() .add( underlineMode ) .add( getColorAsArray( foreground ) ) .add( getColorAsArray( activeForeground ) ); getRemoteObject( formText ).set( PROP_HYPERLINK_SETTINGS, args ); } } private static void renderText( FormText formText ) { if( hasLayoutChanged( formText ) || hasResourceTableChanged( formText ) || hasBoundsChanged( formText ) ) { Paragraph[] paragraphs = getParagraphs( formText ); JsonArray buffer = new JsonArray(); for( int i = 0; i < paragraphs.length; i++ ) { Paragraph paragraph = paragraphs[ i ]; if( paragraph instanceof BulletParagraph ) { BulletParagraph bullet = ( BulletParagraph )paragraph; appendBullet( formText, bullet, buffer ); } ParagraphSegment[] segments = paragraph.getSegments(); appendSegments( formText, segments, buffer ); } getRemoteObject( formText ).set( PROP_TEXT, buffer ); } } private static void appendBullet( FormText formText, BulletParagraph bullet, JsonArray buffer ) { int style = bullet.getBulletStyle(); Image image = getBulletImage( formText, bullet ); String imageName = ImageFactory.getImagePath( image ); String text = bullet.getBulletText(); Rectangle bounds = getBulletBounds( bullet ); // [if] If <li> "style" attribute is set to "text" and there is no text set // ( no "value" attribute ) the bullet bounds are null if( bounds != null ) { JsonArray args = new JsonArray() .add( "bullet" ) //$NON-NLS-1$ .add( style ) .add( imageName ) .add( text ) .add( getBoundsAsArray( bounds ) ); buffer.add( args ); } } private static void appendSegments( FormText formText, ParagraphSegment[] segments, JsonArray buffer ) { for( int i = 0; i < segments.length; i++ ) { ParagraphSegment segment = segments[ i ]; if( segment instanceof TextHyperlinkSegment ) { appendTextHyperlinkSegment( formText, ( TextHyperlinkSegment )segment, buffer ); } else if( segment instanceof TextSegment ) { appendTextSegment( formText, ( TextSegment )segment, buffer ); } else if( segment instanceof ImageHyperlinkSegment ) { appendImageHyperlinkSegment( formText, ( ImageHyperlinkSegment )segment, buffer ); } else if( segment instanceof ImageSegment ) { appendImageSegment( formText, ( ImageSegment )segment, buffer ); } else if( segment instanceof AggregateHyperlinkSegment ) { appendAggregateHyperlinkSegment( formText, ( AggregateHyperlinkSegment )segment, buffer ); } } } private static void appendTextHyperlinkSegment( FormText formText, TextHyperlinkSegment segment, JsonArray buffer ) { String[] textFragments = getTextFragments( segment ); String tooltipText = segment.getTooltipText(); Rectangle[] textFragmentsBounds = getTextFragmentsBounds( segment ); String fontId = getFontId( segment ); Font font = null; if( fontId != null ) { font = ( Font )getResourceTable( formText ).get( fontId ); } for( int i = 0; i < textFragments.length; i++ ) { JsonArray args = new JsonArray() .add( "textHyperlink" ) //$NON-NLS-1$ .add( textFragments[ i ] ) .add( tooltipText ) .add( getBoundsAsArray( textFragmentsBounds[ i ] ) ) .add( getFontAsArray( font ) ); buffer.add( args ); } } private static void appendTextSegment( FormText formText, TextSegment segment, JsonArray buffer ) { String[] textFragments = getTextFragments( segment ); Rectangle[] textFragmentsBounds = getTextFragmentsBounds( segment ); String fontId = getFontId( segment ); Font font = null; if( fontId != null ) { font = ( Font )getResourceTable( formText ).get( fontId ); } String colorId = segment.getColorId(); Color color = null; if( colorId != null ) { color = ( Color )getResourceTable( formText ).get( colorId ); } for( int i = 0; i < textFragments.length; i++ ) { JsonArray args = new JsonArray() .add( "text" ) //$NON-NLS-1$ .add( textFragments[ i ] ) .add( getBoundsAsArray( textFragmentsBounds[ i ] ) ) .add( getFontAsArray( font ) ) .add( getColorAsArray( color ) ); buffer.add( args ); } } private static void appendImageHyperlinkSegment( FormText formText, ImageHyperlinkSegment segment, JsonArray buffer ) { String tooltipText = segment.getTooltipText(); Rectangle bounds = segment.getBounds(); Image image = segment.getImage( getResourceTable( formText ) ); String imageName = ImageFactory.getImagePath( image ); JsonArray args = new JsonArray() .add( "imageHyperlink" ) //$NON-NLS-1$ .add( imageName ) .add( tooltipText ) .add( getBoundsAsArray( bounds ) ); buffer.add( args ); } private static void appendImageSegment( FormText formText, ImageSegment segment, JsonArray buffer ) { Rectangle bounds = segment.getBounds(); Image image = segment.getImage( getResourceTable( formText ) ); String imageName = ImageFactory.getImagePath( image ); JsonArray args = new JsonArray() .add( "image" ) //$NON-NLS-1$ .add( imageName ) .add( getBoundsAsArray( bounds ) ); buffer.add( args ); } private static void appendAggregateHyperlinkSegment( FormText formText, AggregateHyperlinkSegment segment, JsonArray buffer ) { Object[] segments = getHyperlinkSegments( segment ); for( int i = 0; i < segments.length; i++ ) { Object hyperlinkSegment = segments[ i ]; if( hyperlinkSegment instanceof TextHyperlinkSegment ) { appendTextHyperlinkSegment( formText, ( TextHyperlinkSegment )hyperlinkSegment, buffer ); } else if( hyperlinkSegment instanceof ImageHyperlinkSegment ) { appendImageHyperlinkSegment( formText, ( ImageHyperlinkSegment )hyperlinkSegment, buffer ); } } } ////////////////// // Helping methods private static boolean hasHyperlinkSettingsChanged( FormText formText ) { HyperlinkSettings newValue = formText.getHyperlinkSettings(); Integer underlineMode = new Integer( newValue.getHyperlinkUnderlineMode() ); Color foreground = newValue.getForeground(); Color actForeground = newValue.getActiveForeground(); return WidgetLCAUtil.hasChanged( formText, PROP_HYPERLINK_UNDERLINE_MODE, underlineMode ) || WidgetLCAUtil.hasChanged( formText, PROP_HYPERLINK_FOREGROUND, foreground ) || WidgetLCAUtil.hasChanged( formText, PROP_HYPERLINK_ACTIVE_FOREGROUND, actForeground ); } private static Paragraph[] getParagraphs( FormText formText ) { IFormTextAdapter adapter = getAdapter( formText ); return adapter.getParagraphs(); } private static boolean hasLayoutChanged( FormText formText ) { IFormTextAdapter adapter = getAdapter( formText ); return adapter.hasLayoutChanged(); } private static boolean hasResourceTableChanged( FormText formText ) { Hashtable resourceTable = getResourceTable( formText ); return WidgetLCAUtil.hasChanged( formText, PROP_RESOURCE_TABLE, resourceTable ); } private static boolean hasBoundsChanged( FormText formText ) { return WidgetLCAUtil.hasChanged( formText, PROP_BOUNDS, formText.getBounds() ); } private static IFormTextAdapter getAdapter( FormText formText ) { Object adapter = formText.getAdapter( IFormTextAdapter.class ); return ( IFormTextAdapter )adapter; } private static ITextSegmentAdapter getAdapter( TextSegment segment ) { Object adapter = segment.getAdapter( ITextSegmentAdapter.class ); return ( ITextSegmentAdapter )adapter; } private static IBulletParagraphAdapter getAdapter( BulletParagraph bullet ) { Object adapter = bullet.getAdapter( IBulletParagraphAdapter.class ); return ( IBulletParagraphAdapter )adapter; } private static IAggregateHyperlinkSegmentAdapter getAdapter( AggregateHyperlinkSegment segment ) { Object adapter = segment.getAdapter( IAggregateHyperlinkSegmentAdapter.class ); return ( IAggregateHyperlinkSegmentAdapter )adapter; } private static Image getBulletImage( FormText formText, BulletParagraph bullet ) { Image bulletImage = getImage( formText.getDisplay(), BULLET_CIRCLE_GIF ); if( bullet.getBulletStyle() == BulletParagraph.IMAGE ) { String text = bullet.getBulletText(); if( text != null ) { Image img = ( Image )getResourceTable( formText ).get( text ); if( img != null ) { bulletImage = img; } } } return bulletImage; } private static Rectangle getBulletBounds( BulletParagraph bullet ) { return getAdapter( bullet ).getBulletBounds(); } private static Hashtable getResourceTable( FormText formText ) { return getAdapter( formText ).getResourceTable(); } private static String[] getTextFragments( TextSegment segment ) { return getAdapter( segment ).getTextFragments(); } private static Rectangle[] getTextFragmentsBounds( TextSegment segment ) { return getAdapter( segment ).getTextFragmentsBounds(); } private static String getFontId( TextSegment segment ) { return getAdapter( segment ).getFontId(); } private static Object[] getHyperlinkSegments( AggregateHyperlinkSegment segment ) { return getAdapter( segment ).getHyperlinkSegments(); } private static JsonArray getBoundsAsArray( Rectangle bounds ) { return new JsonArray().add( bounds.x ).add( bounds.y ).add( bounds.width ).add( bounds.height ); } private static JsonValue getFontAsArray( Font font ) { JsonValue result = JsonObject.NULL; if( font != null ) { result = new JsonArray() .add( getFontName( font ) ) .add( getFontSize( font ) ) .add( getFontStyle( font, SWT.BOLD ) ) .add( getFontStyle( font, SWT.ITALIC ) ); } return result; } private static JsonArray getFontName( Font font ) { JsonArray resutl = new JsonArray(); FontData fontData = font.getFontData()[ 0 ]; String fontName = fontData.getName(); String[] names = fontName.split( "," ); //$NON-NLS-1$ for( int i = 0; i < names.length; i++ ) { names[ i ] = names[ i ].trim(); Matcher matcher = FONT_NAME_FILTER_PATTERN.matcher( names[ i ] ); names[ i ] = matcher.replaceAll( "" ); //$NON-NLS-1$ resutl.add( names[ i ] ); } return resutl; } private static int getFontSize( Font font ) { return font.getFontData()[ 0 ].getHeight(); } private static boolean getFontStyle( Font font, int style ) { return ( font.getFontData()[ 0 ].getStyle() & style ) != 0; } private static JsonValue getColorAsArray( Color color ) { JsonValue result = JsonObject.NULL; if( color != null ) { RGB rgb = color.getRGB(); result = new JsonArray().add( rgb.red ).add( rgb.green ).add( rgb.blue ).add( 255 ); } return result; } public static Image getImage( Device device, String path ) { ClassLoader classLoader = FormTextLCA.class.getClassLoader(); InputStream inputStream = classLoader.getResourceAsStream( path ); Image result = null; if( inputStream != null ) { try { result = new Image( device, inputStream ); } finally { try { inputStream.close(); } catch( IOException e ) { // ignore } } } return result; } }