blob: 63a5e738e81b1d6564bb9ed08792cc6f673efbd8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018, 2020 Dirk Fauth.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.datachange;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.nebula.widgets.nattable.edit.event.DataUpdateEvent;
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEventHandler;
/**
* {@link DataChangeHandler} to handle {@link DataUpdateEvent}s for data changes
* that where performed on the backing data. Creates {@link UpdateDataChange}s
* to track data changes and to be able to revert those changes.
*
* @since 1.6
*/
public class PersistenceUpdateDataChangeHandler extends UpdateDataChangeHandler<PersistenceUpdateDataChange> implements ILayerEventHandler<DataUpdateEvent> {
/**
* Creates an {@link PersistenceUpdateDataChangeHandler} to handle
* {@link DataUpdateEvent}s to be able to track and revert data changes.
*
* @param layer
* The {@link DataChangeLayer} this handler should be assigned
* to.
* @param keyHandler
* The {@link CellKeyHandler} that is used to store data changes
* for a specific key.
*/
public PersistenceUpdateDataChangeHandler(DataChangeLayer layer, CellKeyHandler<?> keyHandler) {
super(layer, keyHandler, new ConcurrentHashMap<>());
}
@Override
public void handleLayerEvent(DataUpdateEvent event) {
// avoid handling of DataUpdateEvents that are caused by restoring
// the previous data states
if (this.handleDataUpdate) {
Object key = this.keyHandler.getKey(event.getColumnPosition(), event.getRowPosition());
if (key != null) {
synchronized (this.dataChanges) {
// store the change in the DataChangeLayer
this.layer.addDataChange(new PersistenceUpdateDataChange(key, event.getOldValue(), this.keyHandler));
// update the local storage of tracked changes
UpdateDataChange stored = this.dataChanges.get(key);
if (stored == null) {
// update the position tracking
this.changedColumns.add(event.getColumnPosition());
this.changedRows.add(event.getRowPosition());
// store the change locally
this.dataChanges.put(key, new PersistenceUpdateDataChange(key, event.getOldValue(), this.keyHandler));
} else if ((stored.getValue() != null && stored.getValue().equals(event.getNewValue())
|| (stored.getValue() == null && event.getNewValue() == null))) {
// the value was changed back to the original value in
// the underlying layer simply remove the local storage
// to not showing the cell as dirty
this.dataChanges.remove(key);
// rebuild the position tracking
rebuildPositionCollections();
}
}
}
}
}
@Override
public Class<DataUpdateEvent> getLayerEventClass() {
return DataUpdateEvent.class;
}
}