blob: 03838ab0495c610be3d801083e9f46db1b76b6a4 [file] [log] [blame]
/*******************************************************************************
* 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.tickupdate.command;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinate;
import org.eclipse.nebula.widgets.nattable.data.validate.IDataValidator;
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
import org.eclipse.nebula.widgets.nattable.edit.command.EditUtils;
import org.eclipse.nebula.widgets.nattable.edit.command.UpdateDataCommand;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.tickupdate.ITickUpdateHandler;
import org.eclipse.nebula.widgets.nattable.tickupdate.TickUpdateConfigAttributes;
/**
* The command handler that will handle {@link TickUpdateCommand}s on selected cells.
*/
public class TickUpdateCommandHandler extends AbstractLayerCommandHandler<TickUpdateCommand> {
private static final Log log = LogFactory.getLog(TickUpdateCommandHandler.class);
/**
* The {@link SelectionLayer} needed to retrieve the selected cells on
* which the tick update should be processed.
*/
private SelectionLayer selectionLayer;
/**
* @param selectionLayer The {@link SelectionLayer} needed to retrieve the selected cells on
* which the tick update should be processed.
*/
public TickUpdateCommandHandler(SelectionLayer selectionLayer) {
this.selectionLayer = selectionLayer;
}
@Override
public boolean doCommand(TickUpdateCommand command) {
List<PositionCoordinate> selectedPositions = selectionLayer.getSelectedCellPositions();
IConfigRegistry configRegistry = command.getConfigRegistry();
// Tick update for multiple cells in selection
if (selectedPositions.size() > 1) {
// Can all cells be updated ?
if (EditUtils.allCellsEditable(selectionLayer, configRegistry)
&& EditUtils.isEditorSame(selectionLayer, configRegistry)
&& EditUtils.isConverterSame(selectionLayer, configRegistry)) {
for (PositionCoordinate position : selectedPositions) {
updateSingleCell(command, position);
}
}
} else {
// Tick update for single selected cell
updateSingleCell(command, selectionLayer.getLastSelectedCellPosition());
}
return true;
}
/**
* Will calculate the new value after tick update processing for the cell at the given coordinates,
* trying to update the value represented by that cell. The update will only be processed if the
* new value is valid.
* @param command The command to process
* @param selectedPosition The coordinates of the cell on which the tick update
* should be executed
*/
private void updateSingleCell(TickUpdateCommand command, PositionCoordinate selectedPosition) {
ILayerCell cell = selectionLayer.getCellByPosition(
selectedPosition.columnPosition, selectedPosition.rowPosition);
IConfigRegistry configRegistry = command.getConfigRegistry();
IEditableRule editableRule = configRegistry.getConfigAttribute(
EditConfigAttributes.CELL_EDITABLE_RULE,
DisplayMode.EDIT,
cell.getConfigLabels().getLabels());
IDataValidator validator = configRegistry.getConfigAttribute(
EditConfigAttributes.DATA_VALIDATOR,
DisplayMode.EDIT,
cell.getConfigLabels().getLabels());
if (editableRule.isEditable(cell, configRegistry)) {
//process the tick update
Object newValue = getNewCellValue(command, cell);
//validate the value
try {
if (validator == null || validator.validate(cell, configRegistry, newValue)) {
selectionLayer.doCommand(new UpdateDataCommand(
selectionLayer,
selectedPosition.columnPosition,
selectedPosition.rowPosition,
newValue));
}
else {
log.warn("Tick update failed for cell at " + selectedPosition + " and value " + newValue //$NON-NLS-1$ //$NON-NLS-2$
+ ". New value is not valid!"); //$NON-NLS-1$
}
}
catch (Exception e) {
log.warn("Tick update failed for cell at " + selectedPosition + " and value " + newValue //$NON-NLS-1$ //$NON-NLS-2$
+ ". " + e.getLocalizedMessage()); //$NON-NLS-1$
}
}
}
/**
* Will calculate the new value for the given cell after tick update is processed.
* @param command The command to process
* @param cell The cell on which the command should be processed
* @return The processed value after the command was executed on the current cell value
*/
private Object getNewCellValue(TickUpdateCommand command, ILayerCell cell) {
ITickUpdateHandler tickUpdateHandler = command.getConfigRegistry().getConfigAttribute(
TickUpdateConfigAttributes.UPDATE_HANDLER,
DisplayMode.EDIT,
cell.getConfigLabels().getLabels());
Object dataValue = cell.getDataValue();
if (tickUpdateHandler != null && tickUpdateHandler.isApplicableFor(dataValue)) {
if (command.isIncrement()) {
return tickUpdateHandler.getIncrementedValue(dataValue);
} else {
return tickUpdateHandler.getDecrementedValue(dataValue);
}
} else {
return dataValue;
}
}
@Override
public Class<TickUpdateCommand> getCommandClass() {
return TickUpdateCommand.class;
}
}