/*
* ARX: Powerful Data Anonymization
* Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.deidentifier.arx.gui.view.impl.common.table;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.LayerUtil;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.layer.cell.LayerCell;
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent;
import org.eclipse.nebula.widgets.nattable.resize.command.ColumnResizeCommand;
import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEvent;
/**
* Adds an additional column to fill up the space.
*
* @author Fabian Prasser
*/
public class LayerColumnFillLayout extends CTLayer implements IUniqueIndexLayer {
/** TODO */
private final boolean equalWidth;
/** TODO */
private boolean modified = false;
/** TODO */
private boolean ignore = false;
/**
*
*
* @param underlyingDataLayer
* @param config
* @param context
*/
public LayerColumnFillLayout(IUniqueIndexLayer underlyingDataLayer,
CTConfiguration config,
CTContext context) {
this(underlyingDataLayer, config, context, false);
}
/**
*
*
* @param underlyingDataLayer
* @param config
* @param context
* @param equalWidth
*/
public LayerColumnFillLayout(IUniqueIndexLayer underlyingDataLayer,
CTConfiguration config,
CTContext context,
boolean equalWidth) {
super(underlyingDataLayer, config, context);
this.equalWidth = equalWidth;
this.addConfiguration(new StyleConfigurationFillLayout(config));
}
@Override
public boolean doCommand(ILayerCommand command) {
if (command instanceof FillLayerResetCommand) {
this.modified = false;
this.ignore = true;
for (int i = 0; i < getColumnCount(); i++) {
ColumnResizeCommand resize = new ColumnResizeCommand(this, i, DataLayer.DEFAULT_COLUMN_WIDTH);
underlyingLayer.doCommand(resize);
}
this.ignore = false;
}
return super.doCommand(command);
}
@Override
public ILayerCell getCellByPosition(int columnPosition, int rowPosition) {
if (isAdditionalColumnActive() && isAdditionalColumn(columnPosition)) { return new LayerCell(this, columnPosition, rowPosition); }
return super.getCellByPosition(columnPosition, rowPosition);
}
@Override
public int getColumnCount() {
return isAdditionalColumnActive() ? super.getColumnCount() + 1 : super.getColumnCount();
}
@Override
public int getColumnIndexByPosition(int columnPosition) {
if (isAdditionalColumnActive() && isAdditionalColumn(columnPosition)) { return columnPosition; }
return super.getColumnIndexByPosition(columnPosition);
}
@Override
public int getColumnPositionByIndex(int columnIndex) {
if (columnIndex >= 0 && columnIndex < getColumnCount()) {
return columnIndex;
} else {
return -1;
}
}
@Override
public int getColumnPositionByX(int x) {
if (isEqualWidthActive()) {
int min = 0;
int width = getEqualWidth();
for (int i=0; i<super.getColumnCount(); i++) {
if (x>=min && x<=min+width) {
return i;
} else {
min += width;
}
}
return -1;
} else {
return LayerUtil.getColumnPositionByX(this, x);
}
}
@Override
public int getColumnWidthByPosition(int columnPosition) {
if (isEqualWidthActive()) {
return getEqualWidth();
} else if (isAdditionalColumnActive() && isAdditionalColumn(columnPosition)) {
return getGapWidth();
} else {
return super.getColumnWidthByPosition(columnPosition);
}
}
@Override
public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
if (isAdditionalColumnActive() && isAdditionalColumn(columnPosition)) {
return new LabelStack(StyleConfigurationFillLayout.DEFAULT_FILL_LAYOUT_CELL_CONFIG_LABEL);
} else {
return super.getConfigLabelsByPosition(columnPosition, rowPosition);
}
}
/**
* NOTE: Since this is a {@link IUniqueIndexLayer} sitting close to the {@link DataLayer}, columnPosition == columnIndex.
*
* @param columnPosition
* @param rowPosition
* @return
*/
@Override
public Object getDataValueByPosition(final int columnPosition, final int rowPosition) {
if (isAdditionalColumnActive() && isAdditionalColumn(columnPosition)) {
return ""; //$NON-NLS-1$
} else {
return super.getDataValueByPosition(columnPosition, rowPosition);
}
}
@Override
public int getPreferredColumnCount() {
return getColumnCount();
}
@Override
public int getPreferredWidth() {
return isEqualWidthActive() ? super.getWidth() + getGapWidth() :
isAdditionalColumnActive() ? super.getPreferredWidth()+ getColumnWidthByPosition(getAdditionalColumnPosition()) : super.getPreferredWidth();
}
@Override
public int getRowPositionByIndex(int rowIndex) {
if (rowIndex >= 0 && rowIndex < getRowCount()) {
return rowIndex;
} else {
return -1;
}
}
@Override
public int getStartXOfColumnPosition(int columnPosition) {
if (isEqualWidthActive()) {
return columnPosition * getEqualWidth();
} else {
return super.getStartXOfColumnPosition(columnPosition);
}
}
@Override
public int getWidth() {
return isEqualWidthActive() ? super.getWidth() + getGapWidth() :
isAdditionalColumnActive() ? super.getWidth() + getColumnWidthByPosition(getAdditionalColumnPosition()) : super.getWidth();
}
@Override
public void handleLayerEvent(ILayerEvent event) {
if (event instanceof ColumnResizeEvent) {
if (!ignore && isEqualWidthActive()) {
modified = true;
int index = ((ColumnResizeEvent)event).getColumnPositionRanges().iterator().next().start;
for (int i=0; i<getColumnCount(); i++) {
if (i != index) {
ColumnResizeCommand command = new ColumnResizeCommand(this, i, getEqualWidth());
underlyingLayer.doCommand(command);
}
}
}
}
if (!getContext().getTable().isDisposed()) {
super.handleLayerEvent(event);
}
}
/**
*
*
* @return
*/
private int getAdditionalColumnPosition() {
return getColumnCount() - 1;
}
/**
*
*
* @return
*/
private int getEqualWidth() {
NatTable table = getContext().getTable();
if (table.isDisposed()) return 0;
int offset = underlyingLayer.getClientAreaProvider().getClientArea().x;
int width = table.getSize().x - offset;
if (underlyingLayer.getColumnCount()==0) {
return width;
}
return width / underlyingLayer.getColumnCount();
}
/**
*
*
* @return
*/
private int getGapWidth() {
NatTable table = getContext().getTable();
if (table.isDisposed()) return 0;
return table != null ? table.getSize().x - super.getWidth() : 0;
}
/**
*
*
* @param columnPosition
* @return
*/
private boolean isAdditionalColumn(int columnPosition) {
return columnPosition == getAdditionalColumnPosition();
}
/**
*
*
* @return
*/
private boolean isAdditionalColumnActive() {
if (isEqualWidthActive()) {
getContext().setColumnExpanded(true);
return false;
} else {
boolean result = getGapWidth()>0;
getContext().setColumnExpanded(result);
return result;
}
}
/**
*
*
* @return
*/
private boolean isEqualWidthActive() {
boolean result = equalWidth && !modified && getGapWidth()>0;
getContext().setColumnExpanded(result);
return result;
}
}