/******************************************************************************* * Copyright (c) 2012, 2013 Original authors and others. * 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: * Original authors and others - initial API and implementation ******************************************************************************/ package org.eclipse.nebula.widgets.nattable.layer; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Properties; import org.eclipse.nebula.widgets.nattable.command.ILayerCommand; import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry; import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry; import org.eclipse.nebula.widgets.nattable.coordinate.Range; import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator; import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; import org.eclipse.nebula.widgets.nattable.layer.cell.TranslatedLayerCell; import org.eclipse.nebula.widgets.nattable.layer.event.IStructuralChangeEvent; import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter; import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter; import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry; import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider; /** * Abstract base class for layers that expose transformed views of an underlying * unique index layer. By default the AbstractLayerTransform behaves as an * identity transform of its underlying layer; that is, it exposes its * underlying layer as is without any changes. Subclasses are expected to * override methods in this class to implement specific kinds of layer * transformations. */ public class AbstractIndexLayerTransform extends AbstractLayer implements IUniqueIndexLayer { private IUniqueIndexLayer underlyingLayer; public AbstractIndexLayerTransform() {} public AbstractIndexLayerTransform(IUniqueIndexLayer underlyingLayer) { setUnderlyingLayer(underlyingLayer); } protected void setUnderlyingLayer(IUniqueIndexLayer underlyingLayer) { if (this.underlyingLayer != null) { this.underlyingLayer.removeLayerListener(this); } this.underlyingLayer = underlyingLayer; this.underlyingLayer.setClientAreaProvider(getClientAreaProvider()); this.underlyingLayer.addLayerListener(this); } protected final IUniqueIndexLayer getUnderlyingLayer() { return this.underlyingLayer; } // Dispose @Override public void dispose() { this.underlyingLayer.dispose(); } // Persistence @Override public void saveState(String prefix, Properties properties) { this.underlyingLayer.saveState(prefix, properties); super.saveState(prefix, properties); } /** * Underlying layers <i>must</i> load state first. If this is not done, * {@link IStructuralChangeEvent} from underlying layers will reset caches * after state has been loaded */ @Override public void loadState(String prefix, Properties properties) { super.loadState(prefix, properties); this.underlyingLayer.loadState(prefix, properties); } // Configuration @Override public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) { super.configure(configRegistry, uiBindingRegistry); this.underlyingLayer.configure(configRegistry, uiBindingRegistry); } @Override public ILayerPainter getLayerPainter() { return (this.layerPainter != null) ? this.layerPainter : this.underlyingLayer.getLayerPainter(); } // Command @Override public boolean doCommand(ILayerCommand command) { if (super.doCommand(command)) { return true; } return this.underlyingLayer.doCommand(command); } // Client area @Override public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) { super.setClientAreaProvider(clientAreaProvider); if (this.underlyingLayer != null) { this.underlyingLayer.setClientAreaProvider(clientAreaProvider); } } // Horizontal features // Columns @Override public int getColumnCount() { return this.underlyingLayer.getColumnCount(); } @Override public int getPreferredColumnCount() { return this.underlyingLayer.getPreferredColumnCount(); } @Override public int getColumnIndexByPosition(int columnPosition) { return this.underlyingLayer.getColumnIndexByPosition(localToUnderlyingColumnPosition(columnPosition)); } @Override public int localToUnderlyingColumnPosition(int localColumnPosition) { return localColumnPosition; } @Override public int underlyingToLocalColumnPosition(ILayer sourceUnderlyingLayer, int underlyingColumnPosition) { if (sourceUnderlyingLayer != this.underlyingLayer) { return -1; } return underlyingColumnPosition; } @Override public Collection<Range> underlyingToLocalColumnPositions( ILayer sourceUnderlyingLayer, Collection<Range> underlyingColumnPositionRanges) { Collection<Range> localColumnPositionRanges = new ArrayList<Range>(underlyingColumnPositionRanges.size()); for (Range underlyingColumnPositionRange : underlyingColumnPositionRanges) { localColumnPositionRanges.add(new Range( underlyingToLocalColumnPosition(sourceUnderlyingLayer, underlyingColumnPositionRange.start), underlyingToLocalColumnPosition(sourceUnderlyingLayer, underlyingColumnPositionRange.end))); } return localColumnPositionRanges; } @Override public int getColumnPositionByIndex(int columnIndex) { return underlyingToLocalColumnPosition( this.underlyingLayer, this.underlyingLayer.getColumnPositionByIndex(columnIndex)); } // Width @Override public int getWidth() { return this.underlyingLayer.getWidth(); } @Override public int getPreferredWidth() { return this.underlyingLayer.getPreferredWidth(); } @Override public int getColumnWidthByPosition(int columnPosition) { return this.underlyingLayer.getColumnWidthByPosition(localToUnderlyingColumnPosition(columnPosition)); } // Column resize @Override public boolean isColumnPositionResizable(int columnPosition) { return this.underlyingLayer.isColumnPositionResizable(localToUnderlyingColumnPosition(columnPosition)); } // X @Override public int getColumnPositionByX(int x) { return this.underlyingLayer.getColumnPositionByX(x); } @Override public int getStartXOfColumnPosition(int columnPosition) { return this.underlyingLayer.getStartXOfColumnPosition(localToUnderlyingColumnPosition(columnPosition)); } // Underlying @Override public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition) { Collection<ILayer> underlyingLayers = new HashSet<ILayer>(); underlyingLayers.add(this.underlyingLayer); return underlyingLayers; } // Vertical features // Rows @Override public int getRowCount() { return this.underlyingLayer.getRowCount(); } @Override public int getPreferredRowCount() { return this.underlyingLayer.getPreferredRowCount(); } @Override public int getRowIndexByPosition(int rowPosition) { return this.underlyingLayer.getRowIndexByPosition(localToUnderlyingRowPosition(rowPosition)); } @Override public int localToUnderlyingRowPosition(int localRowPosition) { return localRowPosition; } @Override public int underlyingToLocalRowPosition(ILayer sourceUnderlyingLayer, int underlyingRowPosition) { if (sourceUnderlyingLayer != this.underlyingLayer) { return -1; } return underlyingRowPosition; } @Override public Collection<Range> underlyingToLocalRowPositions( ILayer sourceUnderlyingLayer, Collection<Range> underlyingRowPositionRanges) { Collection<Range> localRowPositionRanges = new ArrayList<Range>(underlyingRowPositionRanges.size()); for (Range underlyingRowPositionRange : underlyingRowPositionRanges) { localRowPositionRanges.add(new Range( underlyingToLocalRowPosition(sourceUnderlyingLayer, underlyingRowPositionRange.start), underlyingToLocalRowPosition(sourceUnderlyingLayer, underlyingRowPositionRange.end))); } return localRowPositionRanges; } @Override public int getRowPositionByIndex(int rowIndex) { return underlyingToLocalRowPosition( this.underlyingLayer, this.underlyingLayer.getRowPositionByIndex(rowIndex)); } // Height @Override public int getHeight() { return this.underlyingLayer.getHeight(); } @Override public int getPreferredHeight() { return this.underlyingLayer.getPreferredHeight(); } @Override public int getRowHeightByPosition(int rowPosition) { return this.underlyingLayer.getRowHeightByPosition(localToUnderlyingRowPosition(rowPosition)); } // Row resize @Override public boolean isRowPositionResizable(int rowPosition) { return this.underlyingLayer.isRowPositionResizable(localToUnderlyingRowPosition(rowPosition)); } // Y @Override public int getRowPositionByY(int y) { return this.underlyingLayer.getRowPositionByY(y); } @Override public int getStartYOfRowPosition(int rowPosition) { return this.underlyingLayer.getStartYOfRowPosition(localToUnderlyingRowPosition(rowPosition)); } // Underlying @Override public Collection<ILayer> getUnderlyingLayersByRowPosition(int rowPosition) { Collection<ILayer> underlyingLayers = new HashSet<ILayer>(); underlyingLayers.add(this.underlyingLayer); return underlyingLayers; } // Cell features @Override public ILayerCell getCellByPosition(int columnPosition, int rowPosition) { ILayerCell cell = this.underlyingLayer.getCellByPosition( localToUnderlyingColumnPosition(columnPosition), localToUnderlyingRowPosition(rowPosition)); if (cell == null) { return null; } return new TranslatedLayerCell(cell, this, underlyingToLocalColumnPosition(this.underlyingLayer, cell.getOriginColumnPosition()), underlyingToLocalRowPosition(this.underlyingLayer, cell.getOriginRowPosition()), underlyingToLocalColumnPosition(this.underlyingLayer, cell.getColumnPosition()), underlyingToLocalRowPosition(this.underlyingLayer, cell.getRowPosition())); } @Override public String getDisplayModeByPosition(int columnPosition, int rowPosition) { return this.underlyingLayer.getDisplayModeByPosition( localToUnderlyingColumnPosition(columnPosition), localToUnderlyingRowPosition(rowPosition)); } @Override public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) { LabelStack configLabels = this.underlyingLayer.getConfigLabelsByPosition( localToUnderlyingColumnPosition(columnPosition), localToUnderlyingRowPosition(rowPosition)); IConfigLabelAccumulator configLabelAccumulator = getConfigLabelAccumulator(); if (configLabelAccumulator != null) { configLabelAccumulator.accumulateConfigLabels(configLabels, columnPosition, rowPosition); } String regionName = getRegionName(); if (regionName != null) { configLabels.addLabel(regionName); } return configLabels; } @Override public Object getDataValueByPosition(int columnPosition, int rowPosition) { return this.underlyingLayer.getDataValueByPosition( localToUnderlyingColumnPosition(columnPosition), localToUnderlyingRowPosition(rowPosition)); } @Override public ICellPainter getCellPainter( int columnPosition, int rowPosition, ILayerCell cell, IConfigRegistry configRegistry) { return this.underlyingLayer.getCellPainter(columnPosition, rowPosition, cell, configRegistry); } // IRegionResolver @Override public LabelStack getRegionLabelsByXY(int x, int y) { LabelStack regionLabels = this.underlyingLayer.getRegionLabelsByXY(x, y); String regionName = getRegionName(); if (regionName != null) { regionLabels.addLabel(regionName); } return regionLabels; } @Override public ILayer getUnderlyingLayerByPosition(int columnPosition, int rowPosition) { return this.underlyingLayer; } @Override public boolean isDynamicSizeLayer() { return this.underlyingLayer instanceof AbstractLayer && ((AbstractLayer) this.underlyingLayer).isDynamicSizeLayer(); } }