package net.sourceforge.pmd.eclipse.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import net.sourceforge.pmd.eclipse.ui.ShapeDescriptor; import net.sourceforge.pmd.eclipse.ui.ShapePainter; import net.sourceforge.pmd.eclipse.ui.preferences.br.RuleFieldAccessor; import net.sourceforge.pmd.eclipse.ui.preferences.br.RuleUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; 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 UniqueItemsAsShapeBuilder extends AbstractCellPainterBuilder { private final int width; private final int height; private final int hAlignment; private final Map<Object, ShapeDescriptor> shapesByItem; public UniqueItemsAsShapeBuilder(int theWidth, int theHeight, int horizAlignment, Map<Object, ShapeDescriptor> theShapesByItem) { width = theWidth; height = theHeight; hAlignment = horizAlignment; shapesByItem = theShapesByItem; } private List<ShapeDescriptor> getterShapesIn(TreeItem tItem, RuleFieldAccessor getter) { Set<Comparable<?>> values = RuleUtil.uniqueItemsIn(tItem.getData(), getter); List<ShapeDescriptor> shapes = new ArrayList<ShapeDescriptor>(values.size()); Iterator<?> iter = values.iterator(); while (iter.hasNext()) { ShapeDescriptor desc = shapesByItem.get(iter.next()); if (desc != null) { shapes.add( desc ); } } return shapes; } public void addPainterFor(final Tree tree, final int columnIndex, final RuleFieldAccessor getter, Map<Integer, List<Listener>> listenersByEventCode) { final int xBoundary = 3; Listener paintListener = new Listener() { final int gap = 2; public void handleEvent(Event event) { if (event.index != columnIndex) return; List<ShapeDescriptor> shapes = getterShapesIn((TreeItem)event.item, getter); if (shapes.isEmpty()) return; GC gc = event.gc; int verticalOffset = (event.height / 2) - (height / 2); Color original = gc.getBackground(); final int cellWidth = widthOf(columnIndex, tree); for (int i=0; i<shapes.size(); i++) { ShapeDescriptor shape = shapes.get(i); Color clr = colorManager().colourFor(shape.rgbColor); gc.setBackground(clr); int xOffset = 0; int step = (width+gap) * i; switch (hAlignment) { case SWT.CENTER: xOffset = (cellWidth / 2) - (width / 2) - xBoundary + step; break; case SWT.RIGHT: xOffset = cellWidth - width - xBoundary; break; case SWT.LEFT: xOffset = xBoundary + step; } ShapePainter.drawShape(width, height, shape.shape, gc, event.x + xOffset, event.y + verticalOffset, null); } gc.setBackground(original); } }; Listener measureListener = new Listener() { public void handleEvent(Event event) { if (event.index != columnIndex) return; Object item = ((TreeItem)event.item).getData(); if (item == null) return; Set<Comparable<?>> items = RuleUtil.uniqueItemsIn(item, getter); event.width = width + (items.size() * width); event.height = height ; } }; addListener(tree, SWT.PaintItem, paintListener, listenersByEventCode); addListener(tree, SWT.MeasureItem, measureListener, listenersByEventCode); } }