package net.sourceforge.pmd.eclipse.util; import java.util.List; import java.util.Map; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.eclipse.ui.IndexedString; import net.sourceforge.pmd.eclipse.ui.preferences.br.RuleFieldAccessor; import net.sourceforge.pmd.util.StringUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.TextLayout; import org.eclipse.swt.graphics.TextStyle; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; public class StyledTextBuilder extends AbstractCellPainterBuilder { private Display display = Display.getCurrent(); // NOPMD by br on 2/22/11 11:22 PM private TextLayout layout = new TextLayout(display); private final TextStyle style; public StyledTextBuilder(final FontBuilder theBuilder) { style = theBuilder.style(display); } private Font adjust(TreeItem tItem, RuleFieldAccessor getter, Tree tree) { Object value = valueFor(tItem, getter); IndexedString is = (IndexedString)value; String text = value == null ? "" : is.string; Rule rule = ruleFrom(tItem); if (rule != null) style.font = fontFor(tree, rule); layout.setText( text ); if (StringUtil.isEmpty(text)) { layout.setStyle(style, 0, 0); } else { for (int i=0; i<is.indexSpans.size(); i++) { layout.setStyle(style, is.indexSpans.get(i)[0], is.indexSpans.get(i)[1]-1); } } return style.font; } public void addPainterFor(final Tree tree, final int columnIndex, final RuleFieldAccessor getter, Map<Integer, List<Listener>> listenersByEventCode) { Listener paintListener = new Listener() { public void handleEvent(Event event) { if (event.index != columnIndex) return; Font font = adjust((TreeItem)event.item, getter, tree); event.gc.setFont(font); layout.setFont(font); int descent = event.gc.getFontMetrics().getDescent(); layout.draw(event.gc, event.x, event.y+descent); }; }; Listener measureListener = new Listener() { public void handleEvent(Event event) { if (event.index != columnIndex) return; adjust((TreeItem)event.item, getter, tree); final Rectangle textLayoutBounds = layout.getBounds(); event.width = textLayoutBounds.width + 2; event.height = textLayoutBounds.height + 2; } }; addListener(tree, SWT.PaintItem, paintListener, listenersByEventCode); addListener(tree, SWT.MeasureItem, measureListener, listenersByEventCode); }; }