/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.layout.richtext;
import java.awt.Color;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.StyleConstants;
import javax.swing.text.rtf.RTFEditorKit;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.Band;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.ElementAlignment;
import org.pentaho.reporting.engine.classic.core.ReportElement;
import org.pentaho.reporting.engine.classic.core.filter.types.LabelType;
import org.pentaho.reporting.engine.classic.core.style.BandStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.ElementStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.StyleKey;
import org.pentaho.reporting.engine.classic.core.style.TextStyleKeys;
/**
* This converter converts the content into a generic rich-text document. It can also be used to convert generic
* swing-documents, as long as they adhere to the Swing StyledDocument system.
*
* @author Thomas Morgner.
*/
public class RtfRichTextConverter implements RichTextConverter {
private RTFEditorKit editorKit;
public RtfRichTextConverter() {
editorKit = new RTFEditorKit();
}
public boolean isRecognizedType( final String mimeType ) {
if ( mimeType.equals( "application/rtf" ) ) {
return true;
}
if ( mimeType.equals( "text/rtf" ) ) {
return true;
}
return false;
}
public Object convert( final ReportElement source, final Object value ) {
try {
final Document doc = RichTextConverterUtilities.parseDocument( editorKit, value );
if ( doc == null ) {
return value;
}
final Element element = process( doc.getDefaultRootElement() );
final Band band = RichTextConverterUtilities.convertToBand( StyleKey.getDefinedStyleKeysList(), source, element );
band.getStyle().setStyleProperty( BandStyleKeys.LAYOUT, "inline" );
return band;
} catch ( Exception e ) {
return value;
}
}
private void configureStyle( final AttributeSet attributes, final Element element ) {
final Object alignment = attributes.getAttribute( StyleConstants.Alignment );
if ( alignment instanceof Integer ) {
final int alignmentValue = (Integer) alignment;
if ( StyleConstants.ALIGN_CENTER == alignmentValue ) {
element.getStyle().setStyleProperty( ElementStyleKeys.ALIGNMENT, ElementAlignment.CENTER );
} else if ( StyleConstants.ALIGN_RIGHT == alignmentValue ) {
element.getStyle().setStyleProperty( ElementStyleKeys.ALIGNMENT, ElementAlignment.RIGHT );
} else if ( StyleConstants.ALIGN_JUSTIFIED == alignmentValue ) {
element.getStyle().setStyleProperty( ElementStyleKeys.ALIGNMENT, ElementAlignment.JUSTIFY );
} else {
element.getStyle().setStyleProperty( ElementStyleKeys.ALIGNMENT, ElementAlignment.LEFT );
}
}
final Object background = attributes.getAttribute( StyleConstants.Background );
if ( background instanceof Color ) {
element.getStyle().setStyleProperty( ElementStyleKeys.BACKGROUND_COLOR, background );
}
// Not handled: attributes.getAttribute(StyleConstants.BidiLevel);
// Not handled: attributes.getAttribute(StyleConstants.ComponentAttribute);
// Not handled: attributes.getAttribute(StyleConstants.ComposedTextAttribute);
final Object bold = attributes.getAttribute( StyleConstants.Bold );
if ( bold instanceof Boolean ) {
element.getStyle().setStyleProperty( TextStyleKeys.BOLD, bold );
}
final Object firstLineIndent = attributes.getAttribute( StyleConstants.FirstLineIndent );
if ( firstLineIndent instanceof Float ) {
element.getStyle().setStyleProperty( TextStyleKeys.FIRST_LINE_INDENT, firstLineIndent );
}
final Object family = attributes.getAttribute( StyleConstants.FontFamily );
if ( family instanceof String ) {
element.getStyle().setStyleProperty( TextStyleKeys.FONT, family );
}
final Object fontSize = attributes.getAttribute( StyleConstants.FontSize );
if ( fontSize instanceof Integer ) {
element.getStyle().setStyleProperty( TextStyleKeys.FONTSIZE, fontSize );
}
final Object foreground = attributes.getAttribute( StyleConstants.Foreground );
if ( foreground instanceof Color ) {
element.getStyle().setStyleProperty( ElementStyleKeys.PAINT, foreground );
}
// final Object iconAttribute = attributes.getAttribute( StyleConstants.IconAttribute );
// if ( iconAttribute instanceof Icon ) {
// not handled yet
// }
final Object italic = attributes.getAttribute( StyleConstants.Italic );
if ( italic instanceof Boolean ) {
element.getStyle().setStyleProperty( TextStyleKeys.ITALIC, italic );
}
final Object leftIndent = attributes.getAttribute( StyleConstants.LeftIndent );
if ( leftIndent instanceof Float ) {
element.getStyle().setStyleProperty( TextStyleKeys.TEXT_INDENT, leftIndent );
}
final Object lineSpacing = attributes.getAttribute( StyleConstants.LineSpacing );
if ( lineSpacing instanceof Float ) {
element.getStyle().setStyleProperty( TextStyleKeys.LINEHEIGHT, lineSpacing );
}
// final Object modelAttribute = attributes.getAttribute( StyleConstants.ModelAttribute );
// if ( modelAttribute instanceof Float ) {
// not handled yet
// }
// final Object nameAttribute = attributes.getAttribute( StyleConstants.NameAttribute );
// if ( nameAttribute instanceof Float ) {
// not handled yet
// }
// final Object orientation = attributes.getAttribute( StyleConstants.Orientation );
// if ( orientation instanceof Float ) {
// not used, also seems to be unused by Swing itself
// }
// final Object resolveAttribute = attributes.getAttribute( StyleConstants.ResolveAttribute );
// if ( resolveAttribute instanceof Float ) {
// not handled yet, maybe never needed to be handled at all.
// }
// final Object rightIndent = attributes.getAttribute( StyleConstants.RightIndent );
// if ( rightIndent instanceof Float ) {
// not handled yet
// }
final Object spaceAbove = attributes.getAttribute( StyleConstants.SpaceAbove );
if ( spaceAbove instanceof Float ) {
element.getStyle().setStyleProperty( ElementStyleKeys.PADDING_TOP, spaceAbove );
}
final Object spaceBelow = attributes.getAttribute( StyleConstants.SpaceBelow );
if ( spaceBelow instanceof Float ) {
element.getStyle().setStyleProperty( ElementStyleKeys.PADDING_BOTTOM, spaceBelow );
}
final Object strikeThrough = attributes.getAttribute( StyleConstants.StrikeThrough );
if ( strikeThrough instanceof Boolean ) {
element.getStyle().setStyleProperty( TextStyleKeys.STRIKETHROUGH, strikeThrough );
}
// final Object subscript = attributes.getAttribute( StyleConstants.Subscript );
// if ( subscript instanceof Boolean ) {
// not handled yet
// }
// final Object superScript = attributes.getAttribute( StyleConstants.Superscript );
// if ( superScript instanceof Boolean ) {
// not handled yet
// }
// final Object tabSet = attributes.getAttribute( StyleConstants.TabSet );
// if ( tabSet instanceof Float ) {
// not handled yet
// }
final Object underline = attributes.getAttribute( StyleConstants.Underline );
if ( underline instanceof Boolean ) {
element.getStyle().setStyleProperty( TextStyleKeys.UNDERLINED, underline );
}
element.getStyle().setStyleProperty( ElementStyleKeys.DYNAMIC_HEIGHT, Boolean.TRUE );
}
private Element process( final javax.swing.text.Element textElement ) throws BadLocationException {
if ( textElement.isLeaf() ) {
final int endOffset = textElement.getEndOffset();
final int startOffset = textElement.getStartOffset();
final String text = textElement.getDocument().getText( startOffset, endOffset - startOffset );
final Element result = new Element();
result.setElementType( LabelType.INSTANCE );
result.setAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, text );
configureStyle( textElement.getAttributes(), result );
return result;
}
final Band band = new Band();
configureStyle( textElement.getAttributes(), band );
configureBand( textElement, band );
final int size = textElement.getElementCount();
for ( int i = 0; i < size; i++ ) {
final Element element = process( textElement.getElement( i ) );
band.addElement( element );
}
return band;
}
private void configureBand( final javax.swing.text.Element textElement, final Band band ) {
if ( "paragraph".equals( textElement.getName() ) || "section".equals( textElement.getName() ) ) {
band.getStyle().setStyleProperty( BandStyleKeys.LAYOUT, "block" );
band.getStyle().setStyleProperty( ElementStyleKeys.MIN_WIDTH, new Float( -100 ) );
} else {
band.getStyle().setStyleProperty( BandStyleKeys.LAYOUT, "inline" );
}
}
}