<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <title>BIRT Extension Mechanism : Part 2</title>
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
  <link href="../article.css" type="text/css" rel="stylesheet">
</head>

<body>

<h1>BIRT Extension Mechanism : Part 2a</h1>

<div class="summary">
<h2>Abstract</h2>

<p>This article introduces the extension mechanism of BIRT report
model, engine and designer, and shows how to create custom extended report
items step-by-step.</p>

<div class="author">By&nbsp;Zhiqiang&nbsp;Qian,&nbsp;Actuate Corporation</div>

<div class="copyright">Copyright &copy; 2008
Actuate Corporation.</div>

<div class="date">September 27, 2008</div>

</div>

<div class="content">
<h2>Introduction</h2>

<p>For many people, <a href="http://eclipse.org/birt">BIRT(Business
Intelligence and Reporting Tools)</a> may be only a reporting tool. But in fact, 
the real strength of BIRT is not only its built-in reporting functionality, but 
also its extension capabilities. Using extensions, a user can easily extend the 
functionality of BIRT, creating custom extended report items, adding custom 
emitters, and even having custom editor pages. The power of extensions enables 
the user to create custom reporting features that can meet very specific requirements. 
In this article, we explore how to leverage the BIRT extension mechanism to 
extend the BIRT capabilities. The provided samples cover most of the essential 
extension points that provided by BIRT report model, engine and designer.<br>
</p>

<p>In <a href="http://www.eclipse.org/articles/article.php?file=Article-BIRT-ExtensionTutorial1/index.html">Part 1</a>, 
we already learned the basics for how to create a custom extended report item for BIRT. In this part, we will further 
explore how to polish the extension UI, improving the usability, and enhancing the extension functionality.
</p>

<h2>Beyond the Basics</h2>

<p>In this section, we will take a look at how to add additional UI features for custom  
report items, i.e. report item builder, context menu, 
property page, etc., which would undoubtedly improve the look and usability of your cusotm 
report items.
</p>

<h3>1) WYSIWYG</h3>

<p>Remember how we implemented the look in layout editor for the
RotatedText item in previous part? Yes, we just chose the simplest Label
UI
provider. The disadvantage of this approach is obvious: the label in
layout view always shows the horizontal text, while the preview shows the angled
text. This inconsistency may prevent the end users from getting an intuitive picture when  
designing the report. For most modern editors, WYSIWYG is already encompassed as a de facto
standard. Ideally, we would also want to keep the consistent look between
our layout view and
preview. To achieve this, let's take a look at the 
other two types of the UI
providers:</p>
<ul>
	<li><em>Image UI Provider</em>
	<li><em>Figure UI Provider</em>
</ul>

<p>The Image UI provider is a straightforward choice. It simply
requests an image for the UI presentation. So what we need to do here 
is just to render the rotated text to an image and return it. 
This is very similar to what we already have done for the engine
presentation output.</p>

<p>To register the Image UI provider, we need remove the original Label
UI provider first, adding the new Image UI provider extension,
and specifying the implementor class which must implement
<code>org.eclipse.birt.report.designer.ui.extensions.IReportItemImageProvider</code>.</p>

<p><img style="width: 1000px; height: 226px;" alt="" src="images/image-ui-extension.png"></p>

<p>Here we specify the class as <code>org.eclipse.birt.sample.reportitem.rotatedtext.RotatedTextImageUI</code>, 
the code looks like this:</p>

<pre>public class RotatedTextImageUI implements IReportItemImageProvider
{
	public void disposeImage( ExtendedItemHandle handle, Image image )
	{
		if ( image != null &amp;&amp; !image.isDisposed( ) )
		{
			image.dispose( );
		}
	}
	
	public Image getImage( ExtendedItemHandle handle )
	{
		try
		{
			IReportItem item = handle.getReportItem( );
			
			if ( item instanceof RotatedTextItem )
			{
				int angle = ( (RotatedTextItem) item ).getRotationAngle( );
				String text = ( (RotatedTextItem) item ).getText( );
			
				return SwtGraphicsUtil.createRotatedTextImage( text, angle, null );
			}
		}
		catch ( ExtendedElementException e )
		{
			e.printStackTrace( );
		}
		return null;
	}
}</pre>

<p>The logic seems very trivial. Here we introduced a new class <code>SwtGraphicsUtil</code>.
Since the Eclipse UI is based on SWT (Standard Widget
Toolkit), to make it work, we need an SWT port for
the original <code>SwingGraphicsUtil</code> class. Here is the code for the new SWT version:</p>

<pre>public class SwtGraphicsUtil
{
	public static Image createRotatedTextImage( String text, int angle, Font ft )
	{
		GC gc = null;
		try
		{
			if ( text == null || text.trim( ).length( ) == 0 )
			{
				return null;
			}
			
			Display display = Display.getCurrent( );
			
			gc = new GC( display );
			if ( ft != null )
			{
				gc.setFont( ft );
			}
			
			Point pt = gc.textExtent( text );
			
			gc.dispose( );
			
			TextLayout tl = new TextLayout( display );
			if ( ft != null )
			{
				tl.setFont( ft );
			}
			tl.setText( text );
			
			return createRotatedImage( tl, pt.x, pt.y, angle );
		}
		catch ( Exception e )
		{
			e.printStackTrace( );
			
			if ( gc != null &amp;&amp; !gc.isDisposed( ) )
			{
				gc.dispose( );
			}
		}
		return null;
	}
	
	/**
	 * @return Returns as [rotatedWidth, rotatedHeight, xOffset, yOffset]
	 */
	public static double[] computedRotatedInfo( int width, int height, int angle )
	{
		angle = angle % 360;
		
		if ( angle &lt; 0 )
		{
			angle += 360;
		}
		
		if ( angle == 0 )
		{
			return new double[]{ width, height, 0, 0 };
		}
		else if ( angle == 90 )
		{
			return new double[]{ height, width, -width, 0 };
		}
		else if ( angle == 180 )
		{
			return new double[]{ width, height, -width, -height };
		}
		else if ( angle == 270 )
		{
			return new double[]{ height, width, 0, -height };
		}
		else if ( angle &gt; 0 &amp;&amp; angle &lt; 90 )
		{
			double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
			double cosTheta = Math.abs( Math.cos( angleInRadians ) );
			double sineTheta = Math.abs( Math.sin( angleInRadians ) );
			
			int dW = (int) ( width * cosTheta + height * sineTheta );
			int dH = (int) ( width * sineTheta + height * cosTheta );
			
			return new double[]{ dW, dH, -width * sineTheta * sineTheta, width * sineTheta * cosTheta };
		}
		else if ( angle &gt; 90 &amp;&amp; angle &lt; 180 )
		{
			double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
			double cosTheta = Math.abs( Math.cos( angleInRadians ) );
			double sineTheta = Math.abs( Math.sin( angleInRadians ) );
			
			int dW = (int) ( width * cosTheta + height * sineTheta );
			int dH = (int) ( width * sineTheta + height * cosTheta );
			
			return new double[]{ dW, dH, -( width + height * sineTheta * cosTheta ), -height / 2 };
		}
		else if ( angle &gt; 180 &amp;&amp; angle &lt; 270 )
		{
			double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
			double cosTheta = Math.abs( Math.cos( angleInRadians ) );
			double sineTheta = Math.abs( Math.sin( angleInRadians ) );
			
			int dW = (int) ( width * cosTheta + height * sineTheta );
			int dH = (int) ( width * sineTheta + height * cosTheta );
			
			return new double[]{ dW, dH, -( width * cosTheta * cosTheta ), -( height + width * cosTheta * sineTheta ) };
		}
		else if ( angle &gt; 270 &amp;&amp; angle &lt; 360 )
		{
			double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
			double cosTheta = Math.abs( Math.cos( angleInRadians ) );
			double sineTheta = Math.abs( Math.sin( angleInRadians ) );
			
			int dW = (int) ( width * cosTheta + height * sineTheta );
			int dH = (int) ( width * sineTheta + height * cosTheta );
			
			return new double[]{ dW, dH, ( height * cosTheta * sineTheta ),	-( height * sineTheta * sineTheta ) };
		}
		
		return new double[]{ width, height, 0, 0 };
	}
	
	private static Image createRotatedImage( Object src, int width, int height, int angle )
	{
		angle = angle % 360;
		
		if ( angle &lt; 0 )
		{
			angle += 360;
		}
		
		double[] info = computedRotatedInfo( width, height, angle );
		
		return renderRotatedObject( src, -angle, (int) info[0],	(int) info[1], info[2], info[3] );
	}
	
	private static Image renderRotatedObject( Object src, double angle, int width, int height, double tx, double ty )
	{
		Display display = Display.getCurrent( );
		
		Image dest = null;
		GC gc = null;
		Transform tf = null;
		
		try
		{
			dest = new Image( Display.getCurrent( ), width, height );
			gc = new GC( dest );
			
			gc.setAdvanced( true );
			gc.setAntialias( SWT.ON );
			gc.setTextAntialias( SWT.ON );
			
			tf = new Transform( display );
			tf.rotate( (float) angle );
			tf.translate( (float) tx, (float) ty );
			
			gc.setTransform( tf );
			
			if ( src instanceof TextLayout )
			{
				TextLayout tl = (TextLayout) src;
				tl.draw( gc, 0, 0 );
			}
			else if ( src instanceof Image )
			{
				gc.drawImage( (Image) src, 0, 0 );
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace( );
		}
		finally
		{
			if ( gc != null &amp;&amp; !gc.isDisposed( ) )
			{
				gc.dispose( );
			}
			
			if ( tf != null &amp;&amp; !tf.isDisposed( ) )
			{
				tf.dispose( );
			}
		}
		return dest;
	}
}</pre>

<p>As the SWT API and resource management are not
100% same as SWING, you can see some differences between
the code styles. Nevertheless, the core logic are the same.</p>

<p>Now let's have a test.</p>

<p>Insert a RotatedText item and specify the rotation angle as "45",</p>

<img style="width: 721px; height: 169px;" alt="" src="images/properties.png"><br>

<p>See, now the layout view looks same as the previewing result. The angle
setting is reflected in the editor too. This kind of WYSIWYG can help the 
end user to quickly spot and identify different report items that having
different settings.</p>

<p><img style="width: 861px; height: 204px;" alt="" src="images/image-ui-layout.png"></p>

<img style="width: 554px; height: 115px;" alt="" src="images/image-ui-preview.png">

<p>The Image UI provides the basic possibility for
WYSIWYG support. For most simple extended report items, this is already
sufficient. While for some custom extended report items that requiring more
complicated UI behavior, the Figure UI may be another
choice.</p>

<h3>2) Image VS Figure</h3>

<p>The Figure UI leverages the <code>IFigure</code> interface from <a href="http://www.eclipse.org/gef/">GEF 
(Graphical Editing Framework)</a>. By using this interface, it can provide more flexibility 
and interactive possibilities than the Image UI.</p>

<p>The table below shows a brief summary for major differences between Figure UI and Image UI:</p>

<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <td></td>
      <td style="text-align: center;"><span style="font-weight: bold;">Figure UI</span></td>
      <td style="text-align: center;"><span style="font-weight: bold;">Image UI</span></td>
    </tr>
    <tr>
      <td style="vertical-align: top;"><span style="font-weight: bold;">Life Cycle</span></td>
      <td style="vertical-align: top;">The life cycle of Figure UI is divided into three parts:<br>
      <ul>
        <li><em>Create</em></li>
        <li><em>Update</em></li>
        <li><em>Dispose</em></li>
      </ul>
The  Figure UI normally creates the Figure object once. Each time
any model state changed, the <em>Update</em> action will be invoked. <br>

The advantage of this pattern is it can support incremental and selective
update. For each time <em>Update</em> is called, the figure instance
can check the internal model state and decide if it really needs the update 
or only need update part of the UI.
      </td>

      <td style="vertical-align: top;">The life cycle of Image UI is divided into two parts:<br>
      <ul>
        <li><em>Create</em></li>
        <li><em>Dispose</em></li>
      </ul>
Each time any model state changed, the Image UI will recreate the image presentation.
      </td>
    </tr>
    <tr>
      <td style="vertical-align: top;"><span style="font-weight: bold;">Presentation</span></td>
      <td style="vertical-align: top;">The Figure UI
allows user to create a hierarchical UI structure.
This UI structure can be controlled by the GEF layout
mechanism.</td>
      <td style="vertical-align: top;">The Image UI can only use one single Image for presentation.</td>
    </tr>
    <tr>
      <td style="vertical-align: top;"><span style="font-weight: bold;">Interactivity</span></td>
      <td style="vertical-align: top;">The Figure UI allows user to add listener for certain UI events. This allows custom handling for specific UI events. </td>
      <td style="vertical-align: top;">No interactivity support</td>
    </tr>
  </tbody>
</table>

<p>Image or Figure? That's a question. However though Figure UI provides
more capability than Image UI, it also requires more comprehensive understanding about the GEF framework, 
while Image UI needs nearly nothing new. So the decision still depends on your real needs.</p>

<p>Here we'll give a simple example for Figure UI practice.
In this example, we show how to handle the mouse middle-button click event. For
each middle-button click, we will change the rotation angle by adding
45 degrees to the original value.</p>

<p>Like using the Image UI provider, we first remove any existing
Label UI or Image UI provider, adding the new Figure UI
provider extension,
and specifying the implementor class which must implement
<code>org.eclipse.birt.report.designer.ui.extensions.IReportItemFigureProvider</code>.</p>

<p><img style="width: 1002px; height: 227px;" alt="" src="images/figure-ui-extension.png"></p>

<p>we specify the class as <code>org.eclipse.birt.sample.reportitem.rotatedtext.RotatedTextFigureUI</code>, the code is like this:</p>

<pre>public class RotatedTextFigureUI extends ReportItemFigureProvider
{
	public IFigure createFigure( ExtendedItemHandle handle )
	{
		try
		{
			IReportItem item = handle.getReportItem( );
			
			if ( item instanceof RotatedTextItem )
			{
				return new RotatedTextFigure( (RotatedTextItem) item );
			}
		}
		catch ( ExtendedElementException e )
		{
			e.printStackTrace( );
		}
		return null;
	}
	
	public void updateFigure( ExtendedItemHandle handle, IFigure figure )
	{
		try
		{
			IReportItem item = handle.getReportItem( );
			
			if ( item instanceof RotatedTextItem )
			{
				RotatedTextFigure fig = (RotatedTextFigure) figure;
				
				fig.setRotatedTextItem( (RotatedTextItem) item );
			}
		}
		catch ( ExtendedElementException e )
		{
			e.printStackTrace( );
		}
	}
	
	public void disposeFigure( ExtendedItemHandle handle, IFigure figure )
	{
		( (RotatedTextFigure) figure ).dispose( );
	}
}</pre>

<p>In the Figure UI provider, we create an RotatedTextFigure
instance and delegate all the real logic to this class:</p>

<pre>public class RotatedTextFigure extends Figure
{
	private String lastText;
	private int lastAngle;
	private Image cachedImage;
	private RotatedTextItem textItem;
	
	RotatedTextFigure( RotatedTextItem textItem )
	{
		super( );
		
		this.textItem = textItem;
		
		addMouseListener( new MouseListener.Stub( ) {
		
			public void mousePressed( MouseEvent me )
			{
				if ( me.button == 2 )
				{
					try
					{
						RotatedTextFigure.this.textItem.setRotationAngle( normalize( RotatedTextFigure.this.textItem.getRotationAngle( ) + 45 ) );
					}
					catch ( SemanticException e )
					{
						e.printStackTrace( );
					}
				}
			}
		} );
	}
	
	private int normalize( int angle )
	{
		angle = angle % 360;
		
		if ( angle &lt; 0 )
		{
			angle += 360;
		}
		
		return angle;
	}
	
	public Dimension getMinimumSize( int hint, int hint2 )
	{
		return getPreferredSize( hint, hint2 );
	}
	
	public Dimension getPreferredSize( int hint, int hint2 )
	{
		Display display = Display.getCurrent( );
		
		GC gc = null;
		
		try
		{
			String text = textItem.getText( );
			int angle = textItem.getRotationAngle( );
			
			gc = new GC( display );
			
			Point pt = gc.textExtent( text == null ? "" : text ); //$NON-NLS-1$
			
			double[] info = SwtGraphicsUtil.computedRotatedInfo( pt.x, pt.y, angle );
			
			if ( getBorder( ) != null )
			{
				Insets bdInsets = getBorder( ).getInsets( this );
				
				return new Dimension( (int) info[0] + bdInsets.getWidth( ), (int) info[1] + bdInsets.getHeight( ) );
			}
			return new Dimension( (int) info[0], (int) info[1] );
		}
		finally
		{
			if ( gc != null &amp;&amp; !gc.isDisposed( ) )
			{
				gc.dispose( );
			}
		}
	}
	
	protected void paintClientArea( Graphics graphics )
	{
		final Rectangle r = getClientArea( ).getCopy( );
		
		String text = textItem.getText( );
		int angle = textItem.getRotationAngle( );
		
		if ( text == null )
		{
			text = ""; //$NON-NLS-1$
		}
		
		if ( !text.equals( lastText ) || angle != lastAngle || cachedImage == null || cachedImage.isDisposed( ) )
		{
			lastText = text;
			lastAngle = angle;
			
			if ( cachedImage != null &amp;&amp; !cachedImage.isDisposed( ) )
			{
				cachedImage.dispose( );
			}
			
			cachedImage = SwtGraphicsUtil.createRotatedTextImage( text, angle, null );
		}
		
		if ( cachedImage != null &amp;&amp; !cachedImage.isDisposed( ) )
		{
			graphics.drawImage( cachedImage, r.x, r.y );
		}
	}
	
	void setRotatedTextItem( RotatedTextItem item )
	{
		this.textItem = item;
	}
	
	void dispose( )
	{
		if ( cachedImage != null &amp;&amp; !cachedImage.isDisposed( ) )
		{
			cachedImage.dispose( );
		}
	}
}</pre>

<p>You can see the core rendering logic is the same as the Image UI. We still
call the SwtGraphicsUtil to create an image and then paint it to figure. The
only additional logic is the part about the mouse listener, where we handle the
middle-button click event, adding 45 degrees to the original value per click.</p>

<p>Now run and test. In layout editor, each time you middle-click the
RotatedTextItem, it will automatically change the rotation angle.</p>

<p>Note this is just an example to show the simplest possibility for the Figure UI.
Basically you can create very complex UI
structures based on the GEF framework. As it is mostly related to GEF, we
will not introduce more here. You can refer to <a href="http://www.eclipse.org/gef/">GEF</a> official site for more details.</p>

<h3>3) The Builder</h3>

<p>One common approach for property editing is the <em>Builder</em>. Most built-in
report items in BIRT have the builder support. Each time when you create or
double-click the report item in layout editor, the associated builder for this
report item will pop up and allow you to edit in
a more friendly way. In following sections, we will introduce how to add the builder support
for custom extended report items.</p>

<p>To support the builder, we need add the builder UI extension and specify
the implementor class which must implement
<code>org.eclipse.birt.report.designer.ui.extensions.IReportItemBuilderUI</code>:</p>

<img style="width: 1000px; height: 244px;" alt="" src="images/builder-extension.png">

<p>Here we specify the class as <code>org.eclipse.birt.sample.reportitem.rotatedtext.RotatedTextBuilder</code>, the code is like this:</p>

<pre>public class RotatedTextBuilder extends ReportItemBuilderUI
{
	public int open( ExtendedItemHandle handle )
	{
		try
		{
			IReportItem item = handle.getReportItem( );
			
			if ( item instanceof RotatedTextItem )
			{
				RotatedTextEditor editor = new RotatedTextEditor( Display.getCurrent( ).getActiveShell( ), (RotatedTextItem) item );
				return editor.open( );
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace( );
		}
		return Window.CANCEL;
	}
}</pre>

<p>The code is very simple, we just create another RotatedTextEditor class to populate the actual UI:</p>

<pre>class RotatedTextEditor extends TrayDialog
{
	protected RotatedTextItem textItem;
	protected Text txtText;
	protected Scale sclAngle;
	protected Label lbAngle;
	
	protected RotatedTextEditor( Shell shell, RotatedTextItem textItem )
	{
		super( shell );
		this.textItem = textItem;
	}
	
	protected void configureShell( Shell newShell )
	{
		super.configureShell( newShell );
		newShell.setText( "Rotated Text Builder" ); //$NON-NLS-1$
	}
	
	protected void createTextArea( Composite parent )
	{
		Label lb = new Label( parent, SWT.None );
		lb.setText( "Text Content:" ); //$NON-NLS-1$
		
		txtText = new Text( parent, SWT.BORDER );
		GridData gd = new GridData( GridData.FILL_HORIZONTAL );
		gd.horizontalSpan = 2;
		txtText.setLayoutData( gd );
	}
	
	protected Control createDialogArea( Composite parent )
	{
		Composite composite = new Composite( parent, SWT.NONE );
		GridLayout layout = new GridLayout( 3, false );
		layout.marginHeight = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_MARGIN );
		layout.marginWidth = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_MARGIN );
		layout.verticalSpacing = convertVerticalDLUsToPixels( IDialogConstants.VERTICAL_SPACING );
		layout.horizontalSpacing = convertHorizontalDLUsToPixels( IDialogConstants.HORIZONTAL_SPACING );
		composite.setLayout( layout );
		composite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
		
		createTextArea( composite );
		
		Label lb = new Label( composite, SWT.None );
		lb.setText( "Rotation Angle:" ); //$NON-NLS-1$
		
		sclAngle = new Scale( composite, SWT.None );
		sclAngle.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
		sclAngle.setMinimum( 0 );
		sclAngle.setMaximum( 360 );
		sclAngle.setIncrement( 10 );
		
		lbAngle = new Label( composite, SWT.None );
		GridData gd = new GridData( );
		gd.widthHint = 20;
		lbAngle.setLayoutData( gd );
		
		sclAngle.addSelectionListener( new SelectionListener( ) {
		
			public void widgetDefaultSelected( SelectionEvent e )
			{
				lbAngle.setText( String.valueOf( sclAngle.getSelection( ) ) );
			}
			
			public void widgetSelected( SelectionEvent e )
			{
				lbAngle.setText( String.valueOf( sclAngle.getSelection( ) ) );
			}
		} );
		
		applyDialogFont( composite );
		
		initValues( );
		
		return composite;
	}
	
	private void initValues( )
	{
		txtText.setText( textItem.getText( ) );
		sclAngle.setSelection( textItem.getRotationAngle( ) );
		lbAngle.setText( String.valueOf( textItem.getRotationAngle( ) ) );
	}
	
	protected void okPressed( )
	{
		try
		{
			textItem.setText( txtText.getText( ) );
			textItem.setRotationAngle( sclAngle.getSelection( ) );
		}
		catch ( Exception ex )
		{
			ex.printStackTrace( );
		}
		
		super.okPressed( );
	}
}</pre>

<p>In the RotatedText builder UI, we provide one <code>Text</code> control and one <code>Scale</code>
control, so user can easily change the "text content" and "rotation
angle" properties.</p>

<p>Now let's run the designer. </p>

<p>Create one RotatedText item from palette first. Good, right after the
creation, the builder pops up. Now It's very convenient to edit the
properties. And when you double-click the RotatedText item in layout, it 
also brings up the builder.</p>

<p><img style="width: 497px; height: 380px;" alt="" src="images/builder.png"></p>

<p>By this way, user can create very complicated builder UI for editing. One good example is the built-in Chart builder,
basically it's the most complicated builder in BIRT so far.</p>

<p>Regarding the builder, there are another two extensions:
<code>org.eclipse.birt.core.ui.tasks</code> and
<code>org.eclipse.birt.core.ui.taskWizards</code>.
These two extensions are not directly related to the builder UI
extension, but providing a comprehensive way to create a wizard-like
dialog UI. This dialog UI then can be further integrated to the builder UI
extension. Chart builder is based on this technology. Since we are not going to explore the 
details about these two extensions in this article, you may refer to the 
Chart builder implementation for more details.</p>

<h3>4) Context Menu</h3>

<p>Another well-known UI feature may be the context menu. Through the context menu,
user can get the quick entry points to perform specific actions. In
BIRT, you can also provides a customized context menu for
your extended report item by extensions.</p>

<p>To support custom context menu, you need implement the
extension <code>org.eclipse.birt.report.designer.ui.menuBuilders</code>, the
implementor class must implement the
<code>org.eclipse.birt.report.designer.ui.extensions.IMenuBuilder</code> interface.</p>

<img style="width: 998px; height: 278px;" alt="" src="images/menu-extension.png">

<p>As usual, we specify the element name as "RotatedText" to bind it
to the model extension and give the implementor class name as
<code>org.eclipse.birt.sample.reportitem.rotatedtext.RotatedTextMenuBuilder</code>.</p>

<p>In the menu builder extension for RotatedText item, we add four
custom actions to perform quick rotations, respectively,
set the angle value to -90, 90, 0 and 180 degrees. The code is like this:</p>

<pre>public class RotatedTextMenuBuilder implements IMenuBuilder
{
	public void buildMenu( IMenuManager menu, List selectedList )
	{
		if ( selectedList != null &amp;&amp; selectedList.size( ) == 1 &amp;&amp; selectedList.get( 0 ) instanceof ExtendedItemHandle )
		{
			ExtendedItemHandle handle = (ExtendedItemHandle) selectedList.get( 0 );
			
			if ( !RotatedTextItem.EXTENSION_NAME.equals( handle.getExtensionName( ) ) )
			{
				return;
			}
			
			RotatedTextItem item = null;
			try
			{
				item = (RotatedTextItem) handle.getReportItem( );
			}
			catch ( ExtendedElementException e )
			{
				e.printStackTrace( );
			}
			
			if ( item == null )
			{
				return;
			}
			
			Separator separator = new Separator( "group.rotatedtext" ); //$NON-NLS-1$
			if ( menu.getItems( ).length &gt; 0 )
			{
				menu.insertBefore( menu.getItems( )[0].getId( ), separator );
			}
			else
			{
				menu.add( separator );
			}
			
			menu.appendToGroup( separator.getId( ),	new RotateAction( item, -90 ) );
			menu.appendToGroup( separator.getId( ), new RotateAction( item, 90 ) );
			menu.appendToGroup( separator.getId( ), new RotateAction( item, 0 ) );
			menu.appendToGroup( separator.getId( ),	new RotateAction( item, 180 ) );
		}
	}
	
	static class RotateAction extends Action
	{
		private RotatedTextItem item;
		private int angle;
		
		RotateAction( RotatedTextItem item, int angle )
		{
			this.item = item;
			this.angle = angle;
			
			setText( "Rotate as " + angle + "\u00BA" ); //$NON-NLS-1$ //$NON-NLS-2$
		}
		
		public void run( )
		{
			try
			{
				item.setRotationAngle( angle );
			}
			catch ( SemanticException e )
			{
				e.printStackTrace( );
			}
		}
	}
}</pre>

<p>Each custom action sets the rotation angle to a most commonly
used value, which is just like a shortcut for setting the values.</p>

<p>Run the designer and check again. Right-click on any RotatedText
extended report item in layout editor, now you can see the custom actions in the context menu.</p>

<img style="width: 491px; height: 462px;" alt="" src="images/contextmenu.png">

<p>Through menu builder extension, actually you are not only able to add
actions, it's also possible to remove or overwrite actions. Anyway, this offers you another
chance to provide a smoother UI to the end user.</p>

<h3>5) Property Pages</h3>

<div style="text-align: left;">
<p>An important UI concept in BIRT designer is the <em>Property Editor</em>. The
<em>Property Editor</em> view provides the UI for miscellaneous property editting. It
includes both specific settings for each report item and generic settings for all report items.</p>

<img style="width: 811px; height: 284px;" alt="" src="images/label-general.png"><img style="width: 811px; height: 284px;" alt="" src="images/label-border.png">

<p>So can we also create a similar property UI for our
custom extended report items? And can we reuse the 
generic property UI for custom extended report items?</p>

<p>Both answers are YES. In following sections, we will introduce how to
implement custom property pages as well as how to reuse built-in property pages for
custom extended report items.</p>

<p>Before we start, let's have a brief look at the layout structure of the <em>Property Editor</em> view.</p>

<img style="width: 749px; height: 284px;" alt="" src="images/tab-structure.png">

<p>Normally the Property Editor UI is in a "Tabbed" style. There are
two kinds of tabs: the "Property Tab" and the "Category Tab".
The "Property Tab" divides the entire Property Editor UI into several
pages, while the "Category Tab" divides a single page into several
categories. By default, the first "Properties" tab page is designed to
support categories and other pages not. But this is only the default behavior, user can always 
alter the UI style and overwrite the logic, although the
default behavior in most cases already looks good. </p>

<p>Now let's go on. To support custom property pages, we need implement following extensions:</p>

<img style="width: 1001px; height: 253px;" alt="" src="images/property-page-extension-1.png">

<p>As you see, unlike the previous extension points, this time the
<code>org.eclipse.birt.report.designer.ui.elementAdpaters</code> extension point
looks a little bit different. Actually, this is a very generic extension point
used by BIRT designer. It is not only used to support property page
extension, but also a lot of other UI extensions in various places.</p>

<p>The first thing is to specify the <code>adaptable</code> class. In this case,
we always specify it as
<code>org.eclipse.birt.report.model.api.ExtendedItemHandle</code>, as custom
extended report items are always represented by this class in BIRT model.</p>

<p>The next thing is to specify the <code>adapter</code> settings:</p>

<img style="width: 1001px; height: 251px;" alt="" src="images/property-page-extension-2.png">

<p>Here is a brief explanation for the adapter settings:</p>

<ul>
  <li><em>id</em></li>
  <ul>
    <li>the unique identifier for this adapter. Here we specify it as <code>ReportDesign.AttributeView.RotatedTextPageGenerator</code>.</li>
  </ul>
  <li><em>type</em></li>
  <ul>
    <li>the Java class type this adapter will adapt to. For property
pages, we must specify it as
<code>org.eclipse.birt.report.designer.ui.views.IPageGenerator</code>.</li>
  </ul>
  <li><em>class</em></li>
  <ul>
    <li>The Java class type for the adapter. The class must have a
constructor without any argument. As we are using the factory mode
here, just leave it as blank.</li>
  </ul>
  <li><em>factory</em></li>
  <ul>
    <li>The Java class type for the adapter factory. The class must
implement <code>org.eclipse.core.runtime.IAdapterFactory</code> interface. Here we specify
it as
<code>org.eclipse.birt.sample.reportitem.rotatedtext.views.RotatedTextPageGeneratorFactory</code>.</li>
  </ul>
  <li><em>singleton</em></li>
  <ul>
    <li>Specifies if the adapter object is a singleton or not. For singleton, the adapter object will be cached and reused for all matching
adaptable. Here since we are using the factory mode, just set it to
false.</li>
  </ul>
  <li><em>priority</em></li>
  <ul>
    <li>Specifies the priority for the adapter. This will be used for sorting
when multiple adapters are defined for same adaptable. Just use the
default value by leaving it as blank.</li>
  </ul>
  <li><em>overwrite</em></li>
  <ul>
    <li>Specifies a semicolon separated id list that this adapter want to overwrite. Here we just leave it as blank.</li>
  </ul>
  <li><em>comments</em></li>
  <ul>
    <li>An additional field to put some description text for the adapter.</li>
  </ul>
</ul>

<p>Regarding the <em>class</em> and <em>factory</em> setting, there are already plenty of 
documents talking about them, so we are not repeating any more here. Normally the <em>factory</em> 
mode means more flexibility and extensibility. If <em>class</em> and
<em>factory</em> are both specified, <em>class</em> will take higher priority.</p>

<p>This is not the end yet. As we only want to add custom property pages for
the RotatedText item, we need set some additional constraints 
for the adaptable.</p>

<img style="width: 1002px; height: 252px;" alt="" src="images/property-page-extension-3.png">

<p>To achieve this, we simply create an <em>enablement</em> element with type
<em>test</em> under the <em>adapter</em> node. In the settings, we specify the test property as
<code>ExtendItemHandle.extensionName</code> and the value as <code>RotatedText</code>. As you
can conceive, this effectively restricts the adaptable object to be only
our RotatedText extended report items.</p>

<p>Now let's look at the code of the factory class:</p>

<pre>public class RotatedTextPageGeneratorFactory implements IAdapterFactory
{
	public Object getAdapter( Object adaptableObject, Class adapterType )
	{
		return new RotatedTextPageGenerator( );
	}
	
	public Class[] getAdapterList( )
	{
		return new Class[]{
			IPageGenerator.class
		};
	}
}</pre>

<p>The factory class simply creates a generator instance per call. Each
generator must implement the 
<code>org.eclipse.birt.report.designer.ui.views.IPageGenerator</code> interface,
but usually we just extend it from
<code>org.eclipse.birt.report.designer.ui.views.attributes.AbstractPageGenerator</code>
class, which provides some basic support for the categorized styles.</p>

<p>In this example, we want to overwrite the <code>General</code>
category page in <code>Properties</code> tab, and reuse some built-in categories
like <code>Border</code>, <code>Margin</code>, <code>Page Break</code>, etc. Also we want to add a
<code>Custom</code> property tab to the property editor. Here is the code:</p>

<pre>public class RotatedTextPageGenerator extends AbstractPageGenerator
{
	<span style="font-weight: bold;">private static final String CUSTOM_PAGE_TITLE = "Custom"; //$NON-NLS-1$</span>
	private IPropertyTabUI generalPage;
	
	protected void buildItemContent( CTabItem item )
	{
		if ( itemMap.containsKey( item ) &amp;&amp; itemMap.get( item ) == null )
		{
			String title = tabFolder.getSelection( ).getText( );
			
			<span style="font-weight: bold;">if ( CUSTOM_PAGE_TITLE.equals( title ) )</span>
			<span style="font-weight: bold;">{</span>
			<span style="font-weight: bold;">	TabPage page = new RotatedTextCustomPage( ).getPage( );</span>
			<span style="font-weight: bold;">	if ( page != null )</span>
			<span style="font-weight: bold;">	{</span>
			<span style="font-weight: bold;">		setPageInput( page );</span>
			<span style="font-weight: bold;">		refresh( tabFolder, page, true );</span>
			<span style="font-weight: bold;">		item.setControl( page.getControl( ) );</span>
			<span style="font-weight: bold;">		itemMap.put( item, page );</span>
			<span style="font-weight: bold;">	}</span>
			<span style="font-weight: bold;">}</span>
		}
		else if ( itemMap.get( item ) != null )
		{
			setPageInput( itemMap.get( item ) );
			refresh( tabFolder, itemMap.get( item ), false );
		}
	}
	
	public void refresh( )
	{
		createTabItems( input );
		
		generalPage.setInput( input );
		addSelectionListener( this );
		( (TabPage) generalPage ).refresh( );
	}
	
	public void createTabItems( List input )
	{
		if ( generalPage == null || generalPage.getControl( ).isDisposed( ) )
		{
			tabFolder.setLayout( new FillLayout( ) );
			<span style="font-weight: bold;">generalPage = AttributesUtil.buildGeneralPage( tabFolder,</span>
			<span style="font-weight: bold;">	new String[]{</span>
			<span style="font-weight: bold;">		null,</span>
			<span style="font-weight: bold;">		AttributesUtil.BORDER,</span>
			<span style="font-weight: bold;">		AttributesUtil.MARGIN,</span>
			<span style="font-weight: bold;">		AttributesUtil.SECTION,</span>
			<span style="font-weight: bold;">		AttributesUtil.VISIBILITY,</span>
			<span style="font-weight: bold;">		AttributesUtil.TOC,</span>
			<span style="font-weight: bold;">		AttributesUtil.BOOKMARK,</span>
			<span style="font-weight: bold;">		AttributesUtil.USERPROPERTIES,</span>
			<span style="font-weight: bold;">		AttributesUtil.NAMEDEXPRESSIONS,</span>
			<span style="font-weight: bold;">		AttributesUtil.ADVANCEPROPERTY</span>
			<span style="font-weight: bold;">	},</span>
			<span style="font-weight: bold;">	new String[]{ "General" }, //$NON-NLS-1$</span>
			<span style="font-weight: bold;">	new String[]{ "General" }, //$NON-NLS-1$</span>
			<span style="font-weight: bold;">	new AttributesUtil.PageWrapper[]{ new RotatedTextGeneralPage( )	},</span>
			<span style="font-weight: bold;">	input );</span>
			
			CTabItem tabItem = new CTabItem( tabFolder, SWT.NONE );
			tabItem.setText( ATTRIBUTESTITLE );
			tabItem.setControl( generalPage.getControl( ) );
		}
		
		this.input = input;
		generalPage.setInput( input );
		addSelectionListener( this );
		( (TabPage) generalPage ).refresh( );
		
		<span style="font-weight: bold;">createTabItem( CUSTOM_PAGE_TITLE, ATTRIBUTESTITLE );</span>
		
		if ( tabFolder.getSelection( ) != null )
		{
			buildItemContent( tabFolder.getSelection( ) );
		}
	}
}</pre>

<p>Let's explain a little more here:</p>

<p>In the generator class, we extend it from the <code>AbstractPageGenerator</code> and
overwrite three methods. Among them, the <code>createTabItems</code> and
<code>buildItemContent</code> methods
are the central places that containing the custom logic. In
<code>createTabItem</code> method, we overwrite the creation logic for <code>General</code>
category page, adding interested built-in category pages as well as the 
<code>Custom</code> property page. In <code>buildItemContent</code> method, we insert the
creation logic for the <code>Custom</code> property page. You can focus on the 
text in bold to see how these are achieved. The remaining code are trivial,
normally you can directly use it as a template for other page generator
extensions.</p>

<p>Note one thing you need take care of is when using the built-in pages,
you must ensure the relevant model property definitions are applicable. As for some extended 
report items, they will overwrite
or remove some of the built-in property definitions, in this case,
those built-in page may not work properly.</p>

<p>The last thing is the property page implementation. For
<code>General</code> category page, we simply create two text controls for
property editing. The code is like this:</p>

<pre>public class RotatedTextGeneralPage extends AttributesUtil.PageWrapper
{
	protected FormToolkit toolkit;
	protected Object input;
	protected Composite contentpane;
	private Text txtText, txtAngle;
	
	public void buildUI( Composite parent )
	{
		if ( toolkit == null )
		{
			toolkit = new FormToolkit( Display.getCurrent( ) );
			toolkit.setBorderStyle( SWT.NULL );
		}
		
		Control[] children = parent.getChildren( );
		
		if ( children != null &amp;&amp; children.length &gt; 0 )
		{
			contentpane = (Composite) children[children.length - 1];
			
			GridLayout layout = new GridLayout( 2, false );
			layout.marginLeft = 8;
			layout.verticalSpacing = 12;
			contentpane.setLayout( layout );
			
			toolkit.createLabel( contentpane, "Text Content:" ); //$NON-NLS-1$
			txtText = toolkit.createText( contentpane, "" ); //$NON-NLS-1$
			GridData gd = new GridData( );
			gd.widthHint = 200;
			
			txtText.setLayoutData( gd );
			txtText.addFocusListener( new FocusAdapter( ) {
			
				public void focusLost( org.eclipse.swt.events.FocusEvent e )
				{
					updateModel( RotatedTextItem.TEXT_PROP );
				};
			} );
			
			toolkit.createLabel( contentpane, "Rotation Angle:" ); //$NON-NLS-1$
			txtAngle = toolkit.createText( contentpane, "" ); //$NON-NLS-1$
			gd = new GridData( );
			gd.widthHint = 200;
			
			txtAngle.setLayoutData( gd );
			txtAngle.addFocusListener( new FocusAdapter( ) {
			
				public void focusLost( org.eclipse.swt.events.FocusEvent e )
				{
					updateModel( RotatedTextItem.ROTATION_ANGLE_PROP );
				};
			} );
		}
	}
	
	public void setInput( Object input )
	{
		this.input = input;
	}
	
	public void dispose( )
	{
		if ( toolkit != null )
		{
			toolkit.dispose( );
		}
	}
	
	private void adaptFormStyle( Composite comp )
	{
		Control[] children = comp.getChildren( );
		for ( int i = 0; i &lt; children.length; i++ )
		{
			if ( children[i] instanceof Composite )
			{
				adaptFormStyle( (Composite) children[i] );
			}
		}
		
		toolkit.paintBordersFor( comp );
		toolkit.adapt( comp );
	}
	
	protected RotatedTextItem getItem( )
	{
		Object element = input;
		
		if ( input instanceof List &amp;&amp; ( (List) input ).size( ) &gt; 0 )
		{
			element = ( (List) input ).get( 0 );
		}
		
		if ( element instanceof ExtendedItemHandle )
		{
			try
			{
				return (RotatedTextItem) ( (ExtendedItemHandle) element ).getReportItem( );
			}
			catch ( Exception e )
			{
				e.printStackTrace( );
			}
		}
		
		return null;
	}
	
	public void refresh( )
	{
		if ( contentpane != null &amp;&amp; !contentpane.isDisposed( ) )
		{
			if ( toolkit == null )
			{
				toolkit = new FormToolkit( Display.getCurrent( ) );
				toolkit.setBorderStyle( SWT.NULL );
			}
			
			adaptFormStyle( contentpane );
			
			updateUI( );
		}
	}
	
	public void postElementEvent( )
	{
		if ( contentpane != null &amp;&amp; !contentpane.isDisposed( ) )
		{
			updateUI( );
		}
	}
	
	private void updateModel( String prop )
	{
		RotatedTextItem item = getItem( );
		
		if ( item != null )
		{
			try
			{
				if ( RotatedTextItem.ROTATION_ANGLE_PROP.equals( prop ) )
				{
					item.setRotationAngle( Integer.parseInt( txtAngle.getText( ) ) );
				}
				else if ( RotatedTextItem.TEXT_PROP.equals( prop ) )
				{
					item.setText( txtText.getText( ) );
				}
			}
			catch ( Exception e )
			{
				e.printStackTrace( );
			}
		}
	}
	
	protected void updateUI( )
	{
		RotatedTextItem item = getItem( );
		
		if ( item != null )
		{
			String text = item.getText( );
			txtText.setText( text == null ? "" : text ); //$NON-NLS-1$
			
			txtAngle.setText( String.valueOf( item.getRotationAngle( ) ) );
		}
	}
}</pre>

<p>Note the using of <code>FormToolkit</code> is just to achieve the same look and feel as
the built-in pages. You can always design your own UI styles if no need for
this consistency.</p>

<p>For the <code>Custom</code> property page, as we only want to show the
extension mechanism and the possibility, to simplify, we only give a very trivial example
by implementing a read-only version of the <code>General</code>
category page.</p>

<pre>public class RotatedTextCustomPage extends RotatedTextGeneralPage
{
	private Label lbText, lbAngle;
	
	public void buildUI( Composite parent )
	{
		if ( toolkit == null )
		{
			toolkit = new FormToolkit( Display.getCurrent( ) );
			toolkit.setBorderStyle( SWT.NULL );
		}
		
		Control[] children = parent.getChildren( );
		
		if ( children != null &amp;&amp; children.length &gt; 0 )
		{
			contentpane = (Composite) children[children.length - 1];
			
			GridLayout layout = new GridLayout( 2, false );
			layout.marginTop = 8;
			layout.marginLeft = 8;
			layout.verticalSpacing = 12;
			contentpane.setLayout( layout );
			
			toolkit.createLabel( contentpane, "Text Content:" ); //$NON-NLS-1$
			lbText = toolkit.createLabel( contentpane, "" ); //$NON-NLS-1$
			GridData gd = new GridData( );
			gd.widthHint = 200;
			lbText.setLayoutData( gd );
			
			toolkit.createLabel( contentpane, "Rotation Angle:" ); //$NON-NLS-1$
			lbAngle = toolkit.createLabel( contentpane, "" ); //$NON-NLS-1$
			gd = new GridData( );
			gd.widthHint = 200;
			lbAngle.setLayoutData( gd );
		}
	}
	
	protected void updateUI( )
	{
		RotatedTextItem item = getItem( );
		
		if ( item != null )
		{
			String text = item.getText( );
			lbText.setText( text == null ? "" : text ); //$NON-NLS-1$
			lbAngle.setText( String.valueOf( item.getRotationAngle( ) ) );
		}
	}
}</pre>

<p>OK, now let's wrap all things up and take a look.</p>

<p>Run the designer, ensure the <em>Property Editor</em> view is visible and
select one RotatedText extended report item in layout editor. </p>

<p>Cool, the <code>General</code> category page shows exactly what we designed. You can view 
and edit property values in this page
directly now.</p>

<img style="width: 818px; height: 284px;" alt="" src="images/rotatedtext-general.png">

<p>Click the <code>Border</code> category, it brings up the built-in border
property page as well. You can try change some border settings.
Immediately you can see it works perfectly in layout editor. </p>

<img style="width: 799px; height: 284px;" alt="" src="images/rotatedtext-border.png"><br>

<br>

<img style="width: 340px; height: 265px;" alt="" src="images/border-effect.png">

<p>Now try switching to the <code>Custom</code> page, it brings up our read-only
property page. Since this is only an example, in real practice,
you can implement any custom pages.</p>

<img style="width: 818px; height: 284px;" alt="" src="images/rotatedtext-custom.png">

<p>OK, now we get a nearly complete picture for how to create an
extended report item through model, engine and designer extensions in
BIRT, and the ways to polish the extension UI and improve the usablity. However 
there's another important topic that we'd like to talk about a little
more, that is the <em>Data Driven</em>.</p>

<h2>Data Driven</h2>

<p>An essential topic in BIRT is about the data integration. In the world of 
reporting, data is always the first class citizen. Normally data
integration can be divided into two parts: <em>Data retrieving</em> and <em>Data 
representation</em>. In this chapter, we will focus on the <em>Data representation</em> part,
exploring how to make our RotatedText extended report item data-aware
and capable of leveraging the common data feature in BIRT.</p>

<p>Before the start, we'd like to introduce a little more about the data
infrastructure in BIRT. One important concept in BIRT is <em>Binding</em>. All
report data in BIRT are actually populated through bindings. Binding is an
abstract layer that connects the <em>Data retrieving</em> layer and <em>Data
representation</em> layer. In other words, all report items in BIRT are
actually consuming bindings instead of raw data from data source directly.</p>

<p>There are two kinds of bindings in BIRT: <em>Regular binding</em> and
<em>Aggregation binding</em>. For <em>Regular binding</em>, it normally contains a
JavaScript expression and a data type. For <em>Aggregation binding</em>, it
further contains an aggregation function, aggregation filter and aggregation
target information. By using JavaScript in expression, bindings are
very flexible to organize the data representation logic. You can either simply write 
the expression like:</p>

<pre>row["columnA"]<br></pre>

<p>or like:</p>

<pre>if ( someConditionIsOK )
{
	if ( otherConditionIsOK )
	{
		functionA();
	}
	else
	{
		resultB;
	}
}
else
{
	resultC;
}</pre>

<p>Bindings are associated with report items. Every
report item can consume its own bindings as well as its parent-level
bindings in different scopes. Since 2.3, BIRT also support a new feature called <em>Shared
ResultSet</em>, which allows one report item to share the bindings from another
report item that is not necessarily in its parent tree.</p>

<p>Now let's continue to explorer how we can support bindings for our
Rotated extended report item. The basic idea is to change the <code>text</code>
property to be binding-aware, so the text value can be controlled by
bindings dynamically.
</p>

<h3>1) Model Change</h3>

<p>To support binding for <code>text</code> property, the first thing we need  
change is the model extension definition:</p>

<img style="width: 999px; height: 273px;" alt="" src="images/text-expression-type.png"><br>

<p>Actually the only thing we need is changing the property type of
<code>text</code> from <code>string</code> to <code>expression</code> and adding the quotation mark
around the
original default value. The change means now this property supports
expressions, and as the original default value <code>Rotated Text</code> is
not a valid JavaScript expression, we changed it so it follows the
literal string syntax in JavaScript. </p>

<p>That's all we need for model change, now let's look at the engine part.</p>

<h3>2) Engine Change</h3>

<p>To support expressions, we just need change a piece of code in the <code>onRowSets()</code> method 
of <code>RotatedTextPresentationImpl</code> like this:</p>

<pre>public Object onRowSets( IBaseResultSet[] results ) throws BirtException
{
	if ( textItem == null )
	{
		return null;
	}
	
	int angle = textItem.getRotationAngle( );
	String text = textItem.getText( );
	
	<span style="font-weight: bold;">// XXX added to support expression</span>
	<span style="font-weight: bold;">if ( results != null &amp;&amp; results.length &gt; 0 )</span>
	<span style="font-weight: bold;">{</span>
	<span style="font-weight: bold;">	if ( results[0] instanceof IQueryResultSet &amp;&amp; ( (IQueryResultSet) results[0] ).isBeforeFirst( ) )</span>
	<span style="font-weight: bold;">	{</span>
	<span style="font-weight: bold;">		( (IQueryResultSet) results[0] ).next( );</span>
	<span style="font-weight: bold;">	}</span>
	<span style="font-weight: bold;">	text = String.valueOf( results[0].evaluate( text ) );</span>
	<span style="font-weight: bold;">}</span>
	<span style="font-weight: bold;">else</span>
	<span style="font-weight: bold;">{</span>
	<span style="font-weight: bold;">	text = String.valueOf( context.evaluate( text ) );</span>
	<span style="font-weight: bold;">}</span>
	<span style="font-weight: bold;">// end new code</span>
	
	BufferedImage rotatedImage = SwingGraphicsUtil.createRotatedTextImage( text, angle, new Font( "Default", 0, 12 ) ); //$NON-NLS-1$
	
	ByteArrayInputStream bis = null;
	
	try
	{
		ImageIO.setUseCache( false );
		ByteArrayOutputStream baos = new ByteArrayOutputStream( );
		ImageOutputStream ios = ImageIO.createImageOutputStream( baos );
		
		ImageIO.write( rotatedImage, "png", ios ); //$NON-NLS-1$
		ios.flush( );
		ios.close( );
		bis = new ByteArrayInputStream( baos.toByteArray( ) );
	}
	catch ( IOException e )
	{
		e.printStackTrace( );
	}
	return bis;
}</pre>

<p>The new code adds the extra logic to handle the <code>text</code> property as an
expression, and evaluating it under current engine context to get the
final string result.</p>

<h3>3) UI Change</h3>

<p>Now the UI's turn. Two places need the change. The first applies to the builder, the 
second applies to the property page.</p>

<p>For the builder, we want to add a button besides the text control,
so user can invoke the standard expression builder to edit the
expression. The standard expression builder provides the 
common JavaScript support in BIRT. </p>

<img style="width: 424px; height: 380px;" alt="" src="images/builder-expression-support.png">
<p><img style="width: 702px; height: 594px;" alt="" src="images/expression-builder.png"></p>

<p>To achieve this, we change the code in <code>RotatedTextBuilder</code> class as following:</p>

<pre>public class RotatedTextBuilder extends ReportItemBuilderUI
{
	public int open( ExtendedItemHandle handle )
	{
		try
		{
			IReportItem item = handle.getReportItem( );
			
			if ( item instanceof RotatedTextItem )
			{
				RotatedTextEditor editor = new <span style="font-weight: bold;">RotatedTextEditor2</span>( Display.getCurrent( ).getActiveShell( ), (RotatedTextItem) item );
				return editor.open( );
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace( );
		}
		return Window.CANCEL;
	}
}

class RotatedTextEditor2 extends RotatedTextEditor
{
	protected RotatedTextEditor2( Shell shell, RotatedTextItem textItem )
	{
		super( shell, textItem );
	}
	
	protected void createTextArea( Composite parent )
	{
		Label lb = new Label( parent, SWT.None );
		lb.setText( "Text Content:" ); //$NON-NLS-1$
		
		txtText = new Text( parent, SWT.BORDER );
		GridData gd = new GridData( GridData.FILL_HORIZONTAL );
		txtText.setLayoutData( gd );
		
		Button btnExp = new Button( parent, SWT.PUSH );
		btnExp.setText( "..." ); //$NON-NLS-1$
		btnExp.setToolTipText( "Invoke Expression Builder" ); //$NON-NLS-1$
		
		btnExp.addSelectionListener( new SelectionAdapter( ) {
		
			public void widgetSelected( SelectionEvent event )
			{
				openExpression( txtText );
			}
		} );
	}
	
	private void openExpression( Text textControl )
	{
		String oldValue = textControl.getText( );
		
		ExpressionBuilder eb = new ExpressionBuilder( textControl.getShell( ), oldValue );
		eb.setExpressionProvier( new ExpressionProvider( textItem.getModelHandle( ) ) );
		
		String result = oldValue;
		
		if ( eb.open( ) == Window.OK )
		{
			result = eb.getResult( );
		}
		
		if ( !oldValue.equals( result ) )
		{
			textControl.setText( result );
		}
	}
}</pre>

<p>In the above code, we create another <code>RotatedTextEditor2</code> class to overwrite the UI creation 
logic for the new expression button.</p>

<p>Now let's look at the property page. For <code>General</code> property page, we
also want to add an expression button besides the text control. Here is
the change for the <code>RotatedTextGeneralPage</code> class:</p>

<pre>public class RotatedTextGeneralPage extends AttributesUtil.PageWrapper
{
	//.........
	
	public void buildUI( Composite parent )
	{
		if ( toolkit == null )
		{
			toolkit = new FormToolkit( Display.getCurrent( ) );
			toolkit.setBorderStyle( SWT.NULL );
		}
		
		Control[] children = parent.getChildren( );
		
		if ( children != null &amp;&amp; children.length &gt; 0 )
		{
			contentpane = (Composite) children[children.length - 1];
			
			<span style="font-weight: bold;">GridLayout layout = new GridLayout( 3, false );</span>
			layout.marginLeft = 8;
			layout.verticalSpacing = 12;
			contentpane.setLayout( layout );
			
			toolkit.createLabel( contentpane, "Text Content:" ); //$NON-NLS-1$
			txtText = toolkit.createText( contentpane, "" ); //$NON-NLS-1$
			GridData gd = new GridData( );
			gd.widthHint = 200;
			
			txtText.setLayoutData( gd );
			txtText.addFocusListener( new FocusAdapter( ) {
			
				public void focusLost( org.eclipse.swt.events.FocusEvent e )
				{
					updateModel( RotatedTextItem.TEXT_PROP );
				};
			} );
			
			<span style="font-weight: bold;">Button btnExp = toolkit.createButton( contentpane, "...", SWT.PUSH ); //$NON-NLS-1$</span>
			<span style="font-weight: bold;">btnExp.setToolTipText( "Invoke Expression Builder" ); //$NON-NLS-1$</span>
			<span style="font-weight: bold;">btnExp.addSelectionListener( new SelectionAdapter( ) {</span>
			
			<span style="font-weight: bold;">	public void widgetSelected( SelectionEvent e )</span>
			<span style="font-weight: bold;">	{</span>
			<span style="font-weight: bold;">		openExpression( txtText );</span>
			<span style="font-weight: bold;">	}</span>
			<span style="font-weight: bold;">} );</span>
			
			toolkit.createLabel( contentpane, "Rotation Angle:" ); //$NON-NLS-1$
			txtAngle = toolkit.createText( contentpane, "" ); //$NON-NLS-1$
			gd = new GridData( );
			gd.widthHint = 200;
			<span style="font-weight: bold;">gd.horizontalSpan = 2;</span>
			txtAngle.setLayoutData( gd );
			txtAngle.addFocusListener( new FocusAdapter( ) {
			
				public void focusLost( org.eclipse.swt.events.FocusEvent e )
				{
					updateModel( RotatedTextItem.ROTATION_ANGLE_PROP );
				};
			} );
		}
	}
	
	private void openExpression( Text textControl )
	{
		RotatedTextItem item = getItem( );
		
		if ( item != null )
		{
			String oldValue = textControl.getText( );
			ExpressionBuilder eb = new ExpressionBuilder( textControl.getShell( ), oldValue );
			eb.setExpressionProvier( new ExpressionProvider( item.getModelHandle( ) ) );
			
			String result = oldValue;
			
			if ( eb.open( ) == Window.OK )
			{
				result = eb.getResult( );
			}
			
			if ( !oldValue.equals( result ) )
			{
				textControl.setText( result );
				updateModel( RotatedTextItem.TEXT_PROP );
			}
		}
	}
	
	//..........
}</pre>

<p>You can focus on the code in bold and the newly added methods only. Now the <code>General</code> property page 
looks like this:</p>

<img style="width: 713px; height: 284px;" alt="" src="images/property-page-expression-support.png">

<p>OK, time for an integrated test.</p>

<p>Create one Table report item first, bind it with a dataset, insert
one RotatedText extended report item in the table detail row as well as
several other Data items.</p>

<img style="width: 628px; height: 309px;" alt="" src="images/test-expression-1.png"><br>

<p>Specify the expression of the RotatedText item as:</p>

<img style="width: 702px; height: 594px;" alt="" src="images/test-expression-2.png">

<p>Now preview it in designer. </p>

<img style="width: 688px; height: 545px;" alt="" src="images/test-expression-3.png">

<p>Voila! The text data now comes from the table bindings and automatically changes per row.</p>

<p>Now change the expression as:</p>

<img style="width: 702px; height: 594px;" alt="" src="images/property-page-extension-4.png"><br>

<p>Preview again:</p>

<img style="width: 727px; height: 366px;" alt="" src="images/property-page-extension-5.png">

<p>Perfect! Now we have successfully created a data-driven custom report item.</p>

</div>

<h2>Summary</h2>

<p>BIRT provides very good extension mechanism, which
allows user
to create custom reporting features. This article introduced the techniques that used to
enhance the feature of custom extended report items for BIRT.</p>

<h2>Resources</h2>

<p>[1] <a href="extension-tutorial-2.zip">The
complete source code</a>: you can extract and import it into
Eclipse workspace as a plugin project directly</p>

<p>[2] BIRT Official Site: <a href="http://eclipse.org/birt">http://eclipse.org/birt</a></p>

<p>[3] How to access Eclipse CVS: <a href="http://wiki.eclipse.org/CVS_Howto">http://wiki.eclipse.org/CVS_Howto</a></p>

<p><br>

<br>

</p>

<br>

</div>

</body>
</html>
