/*
* 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) 2009 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 javax.swing.Icon;
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.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.TextStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.StyleKey;
/**
* 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 Element 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.getDefinedStyleKeys(), 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 Integer alignmentValue = (Integer) alignment;
if (StyleConstants.ALIGN_CENTER == alignmentValue.intValue())
{
element.getStyle().setStyleProperty(ElementStyleKeys.ALIGNMENT, ElementAlignment.CENTER);
}
else if (StyleConstants.ALIGN_RIGHT == alignmentValue.intValue())
{
element.getStyle().setStyleProperty(ElementStyleKeys.ALIGNMENT, ElementAlignment.RIGHT);
}
else
{
// we do not support justified text at the moment
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");
}
}
}