textViewer.getTextWidget( ) .addBidiSegmentListener( new BidiSegmentListener( ) {  public void lineGetSegments( BidiSegmentEvent event ) { event.segments = UIUtil.getExpressionBidiSegments( event.lineText ); } } );
	private void createTextArea( Composite parent )	{		IVerticalRuler ruler = null;		textViewer = new SourceViewer( parent, ruler, SWT.WRAP				| SWT.MULTI				| SWT.BORDER				| SWT.H_SCROLL				| SWT.V_SCROLL				| SWT.FULL_SELECTION );		textViewer.setDocument( new Document( ) );		textEditor = textViewer.getTextWidget( );		{			GridData gd = new GridData( GridData.FILL_BOTH );			gd.horizontalSpan = 3;			gd.widthHint = 600;			gd.heightHint = 300;			textEditor.setLayoutData( gd );			textEditor.setText( oldValue );			textEditor.setFocus( );			textEditor.setFont( JFaceResources.getTextFont( ) );		}		textEditor.addKeyListener( new KeyListener( ) {			public void keyPressed( KeyEvent e )			{				if ( isUndoKeyPress( e ) )				{					textViewer.doOperation( ITextOperationTarget.UNDO );				}				else if ( isRedoKeyPress( e ) )				{					textViewer.doOperation( ITextOperationTarget.REDO );				}			}			public void keyReleased( KeyEvent e )			{				// do nothing			}			private boolean isUndoKeyPress( KeyEvent e )			{				return ( ( e.stateMask & SWT.CONTROL ) > 0 )						&& ( ( e.keyCode == 'z' ) || ( e.keyCode == 'Z' ) );			}			private boolean isRedoKeyPress( KeyEvent e )			{				return ( ( e.stateMask & SWT.CONTROL ) > 0 )						&& ( ( e.keyCode == 'y' ) || ( e.keyCode == 'Y' ) );			}		} );		textViewer.configure( new SourceViewerConfiguration( ) );		textEditor.invokeAction( ST.TEXT_END );		// create actions for context menu and short cut keys		ResourceBundle bundle = ResourceBundle.getBundle( "org.eclipse.birt.report.designer.nls.messages" );//$NON-NLS-1$		final TextEditorAction undoAction = new EBTextAction( bundle,				"TextAreaContextMenu.Undo.",//$NON-NLS-1$				textViewer,				ITextOperationTarget.UNDO );		undoAction.setAccelerator( SWT.CTRL | 'Z' );		final TextEditorAction redoAction = new EBTextAction( bundle,				"TextAreaContextMenu.Redo.",//$NON-NLS-1$				textViewer,				ITextOperationTarget.REDO );		redoAction.setAccelerator( SWT.CTRL | 'Y' );		final TextEditorAction cutAction = new EBTextAction( bundle,				"TextAreaContextMenu.Cut.",//$NON-NLS-1$				textViewer,				ITextOperationTarget.CUT );		cutAction.setAccelerator( SWT.CTRL | 'X' );		final TextEditorAction copyAction = new EBTextAction( bundle,				"TextAreaContextMenu.Copy.",//$NON-NLS-1$				textViewer,				ITextOperationTarget.COPY );		copyAction.setAccelerator( SWT.CTRL | 'C' );		final TextEditorAction pasteAction = new EBTextAction( bundle,				"TextAreaContextMenu.Paste.",//$NON-NLS-1$				textViewer,				ITextOperationTarget.PASTE );		pasteAction.setAccelerator( SWT.CTRL | 'V' );		final TextEditorAction selectAllAction = new EBTextAction( bundle,				"TextAreaContextMenu.SelectAll.",//$NON-NLS-1$				textViewer,				ITextOperationTarget.SELECT_ALL );		selectAllAction.setAccelerator( SWT.CTRL | 'A' );		// Create context menu		MenuManager menuMgr = new MenuManager( "#EB Context" );//$NON-NLS-1$		menuMgr.setRemoveAllWhenShown( true );		menuMgr.addMenuListener( new IMenuListener( ) {			public void menuAboutToShow( IMenuManager menuManager )			{				menuManager.add( new Separator( ITextEditorActionConstants.GROUP_UNDO ) );				menuManager.add( new Separator( ITextEditorActionConstants.GROUP_COPY ) );				menuManager.add( new Separator( ITextEditorActionConstants.GROUP_EDIT ) );				menuManager.add( new Separator( ITextEditorActionConstants.GROUP_REST ) );				undoAction.update( );				redoAction.update( );				copyAction.update( );				cutAction.update( );				pasteAction.update( );				selectAllAction.update( );				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_UNDO,						undoAction );				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_UNDO,						redoAction );				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_COPY,						cutAction );				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_COPY,						copyAction );				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_COPY,						pasteAction );				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_EDIT,						selectAllAction );				IAction action = new Action( ACTION_TEXT_FORMAT_NUMBER ) {					public boolean isEnabled( )					{						return formatChoicer.getSelectionIndex( ) == FORMAT_CHOICE_INDEX_DYNAMIC_TEXT;					}					public void run( )					{						insertFormat( FormatBuilder.NUMBER );					}				};				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_REST,						action );				action = new Action( ACTION_TEXT_FORMAT_STRING ) {					public boolean isEnabled( )					{						return formatChoicer.getSelectionIndex( ) == FORMAT_CHOICE_INDEX_DYNAMIC_TEXT;					}					public void run( )					{						insertFormat( FormatBuilder.STRING );					}				};				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_REST,						action );				action = new Action( ACTION_TEXT_FORMAT_DATE_TIME ) {					public boolean isEnabled( )					{						return formatChoicer.getSelectionIndex( ) == FORMAT_CHOICE_INDEX_DYNAMIC_TEXT;					}					public void run( )					{						insertFormat( FormatBuilder.DATETIME );					}				};				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_REST,						action );				action = new Action( ACTION_TEXT_EDIT_DYNAMIC_TEXT ) {					public boolean isEnabled( )					{						return formatChoicer.getSelectionIndex( ) == FORMAT_CHOICE_INDEX_DYNAMIC_TEXT;					}					public void run( )					{						ExpressionBuilder eb = new ExpressionBuilder( textEditor.getSelectionText( ) ); //$NON-NLS-1$						eb.setExpressionProvier( new ExpressionProvider( handle ) );						if ( eb.open( ) == OK )						{							if ( !eb.getResult( ).equals( "" ) ) //$NON-NLS-1$							{								textEditor.insert( eb.getResult( ) );							}						}					}				};				menuManager.appendToGroup( ITextEditorActionConstants.GROUP_REST,						action );			}		} );		textEditor.setMenu( menuMgr.createContextMenu( textEditor ) );	}