blob: 1a09fe0c0195d6055ea482250e002d6c4e9b40d3 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2015 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dirk Fauth <dirk.fauth@googlemail.com> - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.nebula.widgets.nattable.formula;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.copy.InternalCellClipboard;
import org.eclipse.nebula.widgets.nattable.formula.config.FormulaStyleLabels;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayerPainter;
import org.eclipse.nebula.widgets.nattable.style.BorderStyle;
import org.eclipse.nebula.widgets.nattable.style.BorderStyle.LineStyleEnum;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.IStyle;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
/**
* Specialized {@link SelectionLayerPainter} that renders a border around cells
* that are currently in the stored in the {@link InternalCellClipboard}.
* <p>
* Note: Needs to be set to the {@link SelectionLayer} in order to work
* correctly.
* </p>
*
* @since 1.4
*/
public class FormulaLayerPainter extends SelectionLayerPainter {
protected InternalCellClipboard clipboard;
/**
* Create a FormulaLayerPainter that renders gray grid lines and uses the
* default clipping behavior.
*
* @param clipboard
* The {@link InternalCellClipboard} that stores the cells that
* are currently copied.
*/
public FormulaLayerPainter(InternalCellClipboard clipboard) {
this.clipboard = clipboard;
}
/**
* Create a FormulaLayerPainter that renders grid lines in the specified
* color and uses the specified clipping behavior.
*
* @param clipboard
* The {@link InternalCellClipboard} that stores the cells that
* are currently copied.
* @param gridColor
* The color that should be used to render the grid lines.
* @param clipLeft
* Configure the rendering behavior when cells overlap. If set to
* <code>true</code> the left cell will be clipped, if set to
* <code>false</code> the right cell will be clipped. The default
* value is <code>false</code>.
* @param clipTop
* Configure the rendering behavior when cells overlap. If set to
* <code>true</code> the top cell will be clipped, if set to
* <code>false</code> the bottom cell will be clipped. The
* default value is <code>false</code>.
*/
public FormulaLayerPainter(InternalCellClipboard clipboard, final Color gridColor, boolean clipLeft, boolean clipTop) {
super(gridColor, clipLeft, clipTop);
this.clipboard = clipboard;
}
/**
* Create a FormulaLayerPainter that renders gray grid lines and uses the
* specified clipping behavior.
*
* @param clipboard
* The {@link InternalCellClipboard} that stores the cells that
* are currently copied.
* @param clipLeft
* Configure the rendering behavior when cells overlap. If set to
* <code>true</code> the left cell will be clipped, if set to
* <code>false</code> the right cell will be clipped. The default
* value is <code>false</code>.
* @param clipTop
* Configure the rendering behavior when cells overlap. If set to
* <code>true</code> the top cell will be clipped, if set to
* <code>false</code> the bottom cell will be clipped. The
* default value is <code>false</code>.
*/
public FormulaLayerPainter(InternalCellClipboard clipboard, boolean clipLeft, boolean clipTop) {
this(clipboard, GUIHelper.COLOR_GRAY, clipLeft, clipTop);
}
@Override
public void paintLayer(ILayer natLayer, GC gc, int xOffset, int yOffset,
Rectangle pixelRectangle, IConfigRegistry configRegistry) {
super.paintLayer(natLayer, gc, xOffset, yOffset, pixelRectangle, configRegistry);
if (this.clipboard.getCopiedCells() != null) {
Rectangle positionRectangle = getPositionRectangleFromPixelRectangle(natLayer, pixelRectangle);
int columnPositionOffset = positionRectangle.x;
int rowPositionOffset = positionRectangle.y;
// Save gc settings
int originalLineStyle = gc.getLineStyle();
Color originalForeground = gc.getForeground();
applyCopyBorderStyle(gc, configRegistry);
int x0 = 0;
int x1 = 0;
int y0 = 0;
int y1 = 0;
boolean isFirst = true;
for (ILayerCell[] cells : this.clipboard.getCopiedCells()) {
for (ILayerCell cell : cells) {
if (isFirst) {
x0 = cell.getBounds().x;
x1 = cell.getBounds().x + cell.getBounds().width;
y0 = cell.getBounds().y;
y1 = cell.getBounds().y + cell.getBounds().height;
isFirst = false;
}
else {
x0 = Math.min(x0, cell.getBounds().x);
x1 = Math.max(x1, cell.getBounds().x + cell.getBounds().width);
y0 = Math.min(y0, cell.getBounds().y);
y1 = Math.max(y1, cell.getBounds().y + cell.getBounds().height);
}
}
}
x0 += xOffset - columnPositionOffset;
x1 += xOffset - columnPositionOffset;
y0 += yOffset - rowPositionOffset;
y1 += yOffset - rowPositionOffset;
gc.drawLine(x0, y0, x0, y1);
gc.drawLine(x0, y0, x1, y0);
gc.drawLine(x0, y1, x1, y1);
gc.drawLine(x1, y0, x1, y1);
// Restore original gc settings
gc.setLineStyle(originalLineStyle);
gc.setForeground(originalForeground);
}
}
/**
* Apply the border style that should be used to render the border for cells
* that are currently copied to the {@link InternalCellClipboard}. Checks
* the {@link ConfigRegistry} for a registered {@link IStyle} for the
* {@link FormulaStyleLabels#COPY_BORDER_STYLE} label. If none is
* registered, a default line style will be used to render the border.
*
* @param gc
* The current {@link GC} that is used for rendering.
* @param configRegistry
* The {@link ConfigRegistry} to retrieve the style information
* from.
*/
protected void applyCopyBorderStyle(GC gc, IConfigRegistry configRegistry) {
IStyle cellStyle = configRegistry.getConfigAttribute(
CellConfigAttributes.CELL_STYLE,
DisplayMode.NORMAL,
FormulaStyleLabels.COPY_BORDER_STYLE);
BorderStyle borderStyle = cellStyle != null ? cellStyle.getAttributeValue(CellStyleAttributes.BORDER_STYLE) : null;
// if there is no border style configured, use the default
if (borderStyle == null) {
gc.setLineStyle(SWT.LINE_DASH);
gc.setLineDash(new int[] { 2, 2 });
gc.setForeground(GUIHelper.COLOR_BLACK);
} else {
gc.setLineStyle(LineStyleEnum.toSWT(borderStyle.getLineStyle()));
gc.setLineWidth(borderStyle.getThickness());
gc.setForeground(borderStyle.getColor());
}
}
}