/*******************************************************************************
* Copyright (c) 2009 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 java.io.IOException;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.rwt.graphics.Graphics;
import org.eclipse.rwt.lifecycle.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.graphics.ResourceFactory;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Widget;
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.*;
public class FormTextLCA extends AbstractWidgetLCA {
private static final Pattern FONT_NAME_FILTER_PATTERN
= Pattern.compile( "\"|\\\\" ); //$NON-NLS-1$
private static final String NBSP = " "; //$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
static final String PROP_PARAGRAPHS = "paragraphs"; //$NON-NLS-1$
static final String PROP_HYPERLINK_SETTINGS
= "hyperlinkSettings"; //$NON-NLS-1$
// Default values
private static final Paragraph[] DEFAULT_PARAGRAPHS = new Paragraph[ 0 ];
public void preserveValues( final Widget widget ) {
FormText formText = ( FormText )widget;
ControlLCAUtil.preserveValues( formText );
IWidgetAdapter adapter = WidgetUtil.getAdapter( formText );
adapter.preserve( PROP_PARAGRAPHS, getParagraphs( formText ) );
adapter.preserve( PROP_HYPERLINK_SETTINGS, formText.getHyperlinkSettings() );
}
public void renderInitialization( final Widget widget ) throws IOException {
FormText formText = ( FormText )widget;
JSWriter writer = JSWriter.getWriterFor( formText );
writer.newWidget( "org.eclipse.ui.forms.widgets.FormText" ); //$NON-NLS-1$
ControlLCAUtil.writeStyleFlags( formText );
}
public void readData( final Widget widget ) {
FormText formText = ( FormText )widget;
ControlLCAUtil.processSelection( formText, null, false );
ControlLCAUtil.processMouseEvents( formText );
ControlLCAUtil.processKeyEvents( formText );
}
public void renderChanges( final Widget widget ) throws IOException {
FormText formText = ( FormText )widget;
ControlLCAUtil.writeChanges( formText );
writeHyperlinkSettings( formText );
writeParagraphs( formText );
WidgetLCAUtil.writeCustomVariant( formText );
}
public void renderDispose( final Widget widget ) throws IOException {
JSWriter writer = JSWriter.getWriterFor( widget );
writer.dispose();
}
////////////////
// Write changes
private static void writeParagraphs( final FormText formText )
throws IOException
{
Paragraph[] paragraphs = getParagraphs( formText );
String prop = PROP_PARAGRAPHS;
Paragraph[] defValue = DEFAULT_PARAGRAPHS;
if( WidgetLCAUtil.hasChanged( formText, prop, paragraphs, defValue )
|| hasLayoutChanged( formText ) )
{
clearContent( formText );
for( int i = 0; i < paragraphs.length; i++ ) {
Paragraph paragraph = paragraphs[ i ];
if( paragraph instanceof BulletParagraph ) {
BulletParagraph bullet = ( BulletParagraph )paragraph;
writeBullet( formText, bullet );
}
ParagraphSegment[] segments = paragraph.getSegments();
writeSegments( formText, segments );
}
updateHyperlinks( formText );
}
}
private static void writeBullet( final FormText formText,
final BulletParagraph bullet )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
int style = bullet.getBulletStyle();
Image image = getBulletImage( formText, bullet );
String imageName = ResourceFactory.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 ) {
Object[] args = new Object[] {
new Integer( style ),
imageName,
text,
new Integer( bounds.x ),
new Integer( bounds.y ),
new Integer( bounds.width ),
new Integer( bounds.height )
};
writer.call( "createBullet", args ); //$NON-NLS-1$
}
}
private static void writeSegments( final FormText formText,
final ParagraphSegment[] segments )
throws IOException
{
for( int i = 0; i < segments.length; i++ ) {
ParagraphSegment segment = segments[ i ];
if( segment instanceof TextHyperlinkSegment ) {
writeTextHyperlinkSegment( formText, ( TextHyperlinkSegment )segment );
} else if( segment instanceof TextSegment ) {
writeTextSegment( formText, ( TextSegment )segment );
} else if( segment instanceof ImageHyperlinkSegment ) {
writeImageHyperlinkSegment( formText, ( ImageHyperlinkSegment )segment );
} else if( segment instanceof ImageSegment ) {
writeImageSegment( formText, ( ImageSegment )segment );
} else if( segment instanceof ControlSegment ) {
writeControlSegment( formText, ( ControlSegment )segment );
} else if( segment instanceof AggregateHyperlinkSegment ) {
writeAggregateHyperlinkSegment( formText,
( AggregateHyperlinkSegment )segment );
}
}
}
private static void writeTextSegment( final FormText formText,
final TextSegment segment )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
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++ ) {
Object[] args = new Object[] {
textFragments[ i ].replaceAll( " ", NBSP ), //$NON-NLS-1$,
new Integer( textFragmentsBounds[ i ].x ),
new Integer( textFragmentsBounds[ i ].y ),
new Integer( textFragmentsBounds[ i ].width ),
new Integer( textFragmentsBounds[ i ].height ),
getFontName( font ),
getFontSize( font ),
getFontStyle( font, SWT.BOLD ),
getFontStyle( font, SWT.ITALIC ),
colorToHtmlString( color )
};
writer.call( "createTextFragment", args ); //$NON-NLS-1$
}
}
private static void writeTextHyperlinkSegment(
final FormText formText,
final TextHyperlinkSegment segment )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
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++ ) {
Object[] args = new Object[] {
textFragments[ i ].replaceAll( " ", NBSP ), //$NON-NLS-1$
tooltipText,
new Integer( textFragmentsBounds[ i ].x ),
new Integer( textFragmentsBounds[ i ].y ),
new Integer( textFragmentsBounds[ i ].width ),
new Integer( textFragmentsBounds[ i ].height ),
getFontName( font ),
getFontSize( font ),
getFontStyle( font, SWT.BOLD ),
getFontStyle( font, SWT.ITALIC )
};
writer.call( "createTextHyperlinkSegment", args ); //$NON-NLS-1$
}
}
private static void writeImageSegment( final FormText formText,
final ImageSegment segment )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
Rectangle bounds = segment.getBounds();
Image image = segment.getImage( getResourceTable( formText ) );
String imageName = ResourceFactory.getImagePath( image );
Object[] args = new Object[] {
imageName,
new Integer( bounds.x ),
new Integer( bounds.y ),
new Integer( bounds.width ),
new Integer( bounds.height )
};
writer.call( "createImageSegment", args ); //$NON-NLS-1$
}
private static void writeImageHyperlinkSegment(
final FormText formText,
final ImageHyperlinkSegment segment )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
String tooltipText = segment.getTooltipText();
Rectangle bounds = segment.getBounds();
Image image = segment.getImage( getResourceTable( formText ) );
String imageName = ResourceFactory.getImagePath( image );
Object[] args = new Object[] {
imageName,
tooltipText,
new Integer( bounds.x ),
new Integer( bounds.y ),
new Integer( bounds.width ),
new Integer( bounds.height )
};
writer.call( "createImageHyperlinkSegment", args ); //$NON-NLS-1$
}
private static void writeControlSegment( final FormText formText,
final ControlSegment segment )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
Control control = segment.getControl( getResourceTable( formText ) );
Object[] args = new Object[] {
WidgetUtil.getId( control )
};
writer.call( "createControlSegment", args ); //$NON-NLS-1$
}
private static void writeAggregateHyperlinkSegment(
final FormText formText,
final AggregateHyperlinkSegment segment )
throws IOException
{
Object[] segments = getHyperlinkSegments( segment );
for( int i = 0; i < segments.length; i++ ) {
Object hyperlinkSegment = segments[ i ];
if( hyperlinkSegment instanceof TextHyperlinkSegment ) {
writeTextHyperlinkSegment( formText,
( TextHyperlinkSegment )hyperlinkSegment );
} else if( hyperlinkSegment instanceof ImageHyperlinkSegment ) {
writeImageHyperlinkSegment( formText,
( ImageHyperlinkSegment )hyperlinkSegment );
}
}
}
private static void writeHyperlinkSettings( final FormText formText )
throws IOException
{
HyperlinkSettings newValue = formText.getHyperlinkSettings();
String prop = PROP_HYPERLINK_SETTINGS;
if( WidgetLCAUtil.hasChanged( formText, prop, newValue ) ) {
int underlineMode = newValue.getHyperlinkUnderlineMode();
Color foreground = newValue.getForeground();
Color activeForeground = newValue.getActiveForeground();
Object[] args = new Object[] {
new Integer( underlineMode ),
colorToHtmlString( foreground ),
colorToHtmlString( activeForeground )
};
JSWriter writer = JSWriter.getWriterFor( formText );
writer.call( "setHyperlinkSettings", args ); //$NON-NLS-1$
}
}
private static void clearContent( final FormText formText ) throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
writer.call( "clearContent", new Object[ 0 ] ); //$NON-NLS-1$
}
private static void updateHyperlinks( final FormText formText )
throws IOException
{
JSWriter writer = JSWriter.getWriterFor( formText );
writer.call( "updateHyperlinks", new Object[ 0 ] ); //$NON-NLS-1$
}
//////////////////
// Helping methods
private static IFormTextAdapter getAdapter( final FormText formText ) {
Object adapter = formText.getAdapter( IFormTextAdapter.class );
return ( IFormTextAdapter )adapter;
}
private static ITextSegmentAdapter getAdapter( final TextSegment segment ) {
Object adapter = segment.getAdapter( ITextSegmentAdapter.class );
return ( ITextSegmentAdapter )adapter;
}
private static IBulletParagraphAdapter getAdapter(
final BulletParagraph bullet )
{
Object adapter = bullet.getAdapter( IBulletParagraphAdapter.class );
return ( IBulletParagraphAdapter )adapter;
}
private static IAggregateHyperlinkSegmentAdapter getAdapter(
final AggregateHyperlinkSegment segment )
{
Object adapter
= segment.getAdapter( IAggregateHyperlinkSegmentAdapter.class );
return ( IAggregateHyperlinkSegmentAdapter )adapter;
}
private static Image getBulletImage( final FormText formText,
final BulletParagraph bullet )
{
ClassLoader classLoader = FormTextLCA.class.getClassLoader();
Image bulletImage = Graphics.getImage( BULLET_CIRCLE_GIF, classLoader );
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( final BulletParagraph bullet ) {
IBulletParagraphAdapter bulletParagraphAdapter = getAdapter( bullet );
return bulletParagraphAdapter.getBulletBounds();
}
private static Paragraph[] getParagraphs( final FormText formText ) {
IFormTextAdapter adapter = getAdapter( formText );
return adapter.getParagraphs();
}
private static Hashtable getResourceTable( final FormText formText ) {
IFormTextAdapter adapter = getAdapter( formText );
return adapter.getResourceTable();
}
private static boolean hasLayoutChanged( final FormText formText ) {
IFormTextAdapter adapter = getAdapter( formText );
return adapter.hasLayoutChanged();
}
private static String[] getTextFragments( final TextSegment segment ) {
ITextSegmentAdapter textSegmentAdapter = getAdapter( segment );
return textSegmentAdapter.getTextFragments();
}
private static Rectangle[] getTextFragmentsBounds( final TextSegment segment )
{
ITextSegmentAdapter textSegmentAdapter = getAdapter( segment );
return textSegmentAdapter.getTextFragmentsBounds();
}
private static String getFontId( final TextSegment segment ) {
ITextSegmentAdapter textSegmentAdapter = getAdapter( segment );
return textSegmentAdapter.getFontId();
}
private static Object[] getHyperlinkSegments(
final AggregateHyperlinkSegment segment )
{
IAggregateHyperlinkSegmentAdapter hyperlinkSegmentAdapter
= getAdapter( segment );
return hyperlinkSegmentAdapter.getHyperlinkSegments();
}
private static String colorToHtmlString( final Color color ) {
String result = null;
if( color != null ) {
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
StringBuffer sb = new StringBuffer();
sb.append( "#" ); //$NON-NLS-1$
sb.append( getHexStr( red ) );
sb.append( getHexStr( green ) );
sb.append( getHexStr( blue ) );
result = sb.toString();
}
return result;
}
private static String getHexStr( final int value ) {
String hex = Integer.toHexString( value );
return hex.length() == 1 ? "0" + hex : hex; //$NON-NLS-1$
}
private static String[] getFontName( final Font font ) {
String[] result = null;
if( font != null ) {
FontData fontData = font.getFontData()[ 0 ];
String fontName = fontData.getName();
result = fontName.split( "," ); //$NON-NLS-1$
for( int i = 0; i < result.length; i++ ) {
result[ i ] = result[ i ].trim();
Matcher matcher = FONT_NAME_FILTER_PATTERN.matcher( result[ i ] );
result[ i ] = matcher.replaceAll( "" ); //$NON-NLS-1$
}
}
return result;
}
private static Integer getFontSize( final Font font ) {
Integer result = null;
if( font != null ) {
FontData fontData = font.getFontData()[ 0 ];
result = new Integer( fontData.getHeight() );
}
return result;
}
private static Boolean getFontStyle( final Font font, final int style ) {
Boolean result = null;
if( font != null ) {
FontData fontData = font.getFontData()[ 0 ];
result = Boolean.valueOf( ( fontData.getStyle() & style ) != 0 );
}
return result;
}
}