blob: 1f2670539735a5336cbda0da247aa336468f288e [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.examples._300_Data;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.copy.InternalCellClipboard;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.export.ExportConfigAttributes;
import org.eclipse.nebula.widgets.nattable.extension.poi.HSSFExcelExporter;
import org.eclipse.nebula.widgets.nattable.extension.poi.PoiExcelExporter;
import org.eclipse.nebula.widgets.nattable.formula.FormulaDataProvider;
import org.eclipse.nebula.widgets.nattable.formula.FormulaLayerPainter;
import org.eclipse.nebula.widgets.nattable.formula.FormulaTooltipErrorReporter;
import org.eclipse.nebula.widgets.nattable.formula.command.DisableFormulaEvaluationCommand;
import org.eclipse.nebula.widgets.nattable.formula.command.EnableFormulaEvaluationCommand;
import org.eclipse.nebula.widgets.nattable.formula.config.DefaultFormulaConfiguration;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.config.DefaultGridLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
/**
* Example that demonstrates the usage of formulas using the
* FormulaDataProvider.
*/
public class _305_FormulaDataExample extends AbstractNatExample {
boolean evaluationEnabled = true;
public static void main(String[] args) throws Exception {
StandaloneNatExampleRunner.run(new _305_FormulaDataExample());
}
@Override
public String getDescription() {
return "This example demonstrates the usage of formulas to calculate cell values dynamically similar to spreadsheet applications.\n"
+ "Currently the following functions are supported: SUM, NEGATE, PRODUCT, QUOTIENT, MOD, POWER, SQRT and AVERAGE.";
}
@Override
public Control createExampleControl(Composite parent) {
Composite panel = new Composite(parent, SWT.NONE);
panel.setLayout(new GridLayout());
GridDataFactory.fillDefaults().grab(true, true).applyTo(panel);
// TODO add combo box and text field for editing formulas
Composite gridPanel = new Composite(panel, SWT.NONE);
gridPanel.setLayout(new GridLayout());
GridDataFactory.fillDefaults().grab(true, true).applyTo(gridPanel);
Composite buttonPanel = new Composite(panel, SWT.NONE);
buttonPanel.setLayout(new GridLayout());
GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonPanel);
ConfigRegistry configRegistry = new ConfigRegistry();
final FormulaGridLayer gridLayer = new FormulaGridLayer();
final NatTable natTable = new NatTable(gridPanel, gridLayer, false);
natTable.setConfigRegistry(configRegistry);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
final FormulaBodyLayerStack bodyLayer = gridLayer.getBodyLayer();
// This is the formula specific configuration
InternalCellClipboard clipboard = new InternalCellClipboard();
natTable.addConfiguration(
new DefaultFormulaConfiguration(bodyLayer.getFormulaDataProvider(), bodyLayer.getSelectionLayer(), clipboard));
bodyLayer.getFormulaDataProvider().setErrorReporter(new FormulaTooltipErrorReporter(natTable, bodyLayer.getDataLayer()));
bodyLayer.getSelectionLayer().setLayerPainter(new FormulaLayerPainter(clipboard));
natTable.addConfiguration(new AbstractRegistryConfiguration() {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
PoiExcelExporter exporter = new HSSFExcelExporter();
exporter.setApplyBackgroundColor(false);
exporter.setFormulaParser(bodyLayer.getFormulaDataProvider().getFormulaParser());
configRegistry.registerConfigAttribute(
ExportConfigAttributes.EXPORTER,
exporter);
}
});
natTable.configure();
GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
final Button toggleFormulaButton = new Button(panel, SWT.PUSH);
toggleFormulaButton.setText("Disable Formula Evaluation");
toggleFormulaButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
_305_FormulaDataExample.this.evaluationEnabled = !_305_FormulaDataExample.this.evaluationEnabled;
if (_305_FormulaDataExample.this.evaluationEnabled) {
natTable.doCommand(new EnableFormulaEvaluationCommand());
toggleFormulaButton.setText("Disable Formula Evaluation");
}
else {
natTable.doCommand(new DisableFormulaEvaluationCommand());
toggleFormulaButton.setText("Enable Formula Evaluation");
}
}
});
return panel;
}
/**
* The body layer stack for the {@link _305_FormulaDataExample}. Consists of
* <ol>
* <li>ViewportLayer</li>
* <li>SelectionLayer</li>
* <li>ColumnHideShowLayer</li>
* <li>ColumnReorderLayer</li>
* <li>DataLayer</li>
* </ol>
*/
class FormulaBodyLayerStack extends AbstractLayerTransform {
private final FormulaDataProvider formulaDataProvider;
private final DataLayer bodyDataLayer;
private final ColumnReorderLayer columnReorderLayer;
private final ColumnHideShowLayer columnHideShowLayer;
private final SelectionLayer selectionLayer;
private final ViewportLayer viewportLayer;
public FormulaBodyLayerStack() {
IDataProvider dataProvider = new TwoDimensionalArrayDataProvider(new String[26][50]);
this.formulaDataProvider = new FormulaDataProvider(dataProvider);
this.bodyDataLayer = new DataLayer(this.formulaDataProvider);
this.columnReorderLayer = new ColumnReorderLayer(this.bodyDataLayer);
this.columnHideShowLayer = new ColumnHideShowLayer(this.columnReorderLayer);
this.selectionLayer = new SelectionLayer(this.columnHideShowLayer);
this.viewportLayer = new ViewportLayer(this.selectionLayer);
setUnderlyingLayer(this.viewportLayer);
}
public FormulaDataProvider getFormulaDataProvider() {
return this.formulaDataProvider;
}
public DataLayer getDataLayer() {
return this.bodyDataLayer;
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
}
/**
* The {@link GridLayer} used by the {@link _305_FormulaDataExample}.
*/
class FormulaGridLayer extends GridLayer {
public FormulaGridLayer() {
super(false);
addConfiguration(new DefaultGridLayerConfiguration(this) {
@Override
protected void addAlternateRowColoringConfig(CompositeLayer gridLayer) {
// do nothing as we don't want to see alternate row coloring
}
});
init();
}
private void init() {
// Body
FormulaBodyLayerStack bodyLayer = new FormulaBodyLayerStack();
SelectionLayer selectionLayer = bodyLayer.getSelectionLayer();
// Column header
IDataProvider columnHeaderDataProvider = new LetterColumnHeaderDataProvider(26);
ILayer columnHeaderLayer = new ColumnHeaderLayer(
new DefaultColumnHeaderDataLayer(columnHeaderDataProvider), bodyLayer, selectionLayer);
// Row header
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
bodyLayer.getDataLayer().getDataProvider());
ILayer rowHeaderLayer = new RowHeaderLayer(
new DefaultRowHeaderDataLayer(rowHeaderDataProvider),
bodyLayer, selectionLayer);
// Corner
ILayer cornerLayer = new CornerLayer(new DataLayer(
new DefaultCornerDataProvider(columnHeaderDataProvider,
rowHeaderDataProvider)), rowHeaderLayer,
columnHeaderLayer);
setBodyLayer(bodyLayer);
setColumnHeaderLayer(columnHeaderLayer);
setRowHeaderLayer(rowHeaderLayer);
setCornerLayer(cornerLayer);
}
@Override
public FormulaBodyLayerStack getBodyLayer() {
return (FormulaBodyLayerStack) super.getBodyLayer();
}
public DataLayer getBodyDataLayer() {
return getBodyLayer().getDataLayer();
}
public FormulaDataProvider getBodyDataProvider() {
return getBodyLayer().getFormulaDataProvider();
}
}
class LetterColumnHeaderDataProvider implements IDataProvider {
private int columns = 0;
public LetterColumnHeaderDataProvider(int columns) {
this.columns = columns;
}
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
return (char) (65 + columnIndex);
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
throw new UnsupportedOperationException();
}
@Override
public int getColumnCount() {
return this.columns;
}
@Override
public int getRowCount() {
return 1;
}
}
class TwoDimensionalArrayDataProvider implements IDataProvider {
private String[][] data;
public TwoDimensionalArrayDataProvider(String[][] data) {
this.data = data;
}
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
return this.data[columnIndex][rowIndex];
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
this.data[columnIndex][rowIndex] = newValue != null ? newValue.toString() : null;
}
@Override
public int getColumnCount() {
return this.data.length;
}
@Override
public int getRowCount() {
return this.data[0] != null ? this.data[0].length : 0;
}
}
}