package org.openlca.app.editors.systems;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.openlca.app.M;
import org.openlca.app.components.ParameterRedefDialog;
import org.openlca.app.components.UncertaintyCellEditor;
import org.openlca.app.db.Cache;
import org.openlca.app.util.Actions;
import org.openlca.app.rcp.images.Images;
import org.openlca.app.util.Labels;
import org.openlca.app.util.UncertaintyLabel;
import org.openlca.app.util.tables.TableClipboard;
import org.openlca.app.util.tables.Tables;
import org.openlca.app.util.viewers.Viewers;
import org.openlca.app.viewers.table.modify.ModifySupport;
import org.openlca.app.viewers.table.modify.field.DoubleModifier;
import org.openlca.core.database.EntityCache;
import org.openlca.core.model.ModelType;
import org.openlca.core.model.ParameterRedef;
import org.openlca.core.model.ProductSystem;
import org.openlca.core.model.descriptors.BaseDescriptor;
import org.openlca.core.model.descriptors.ImpactMethodDescriptor;
import org.openlca.core.model.descriptors.ProcessDescriptor;
import org.openlca.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A table with parameter redefinitions. The list which is modified by this
* table should be directly the live-list of the respective product system.
*/
class ParameterRedefTable {
private Logger log = LoggerFactory.getLogger(getClass());
private ProductSystemEditor editor;
private final String PARAMETER = M.Parameter;
private final String CONTEXT = M.Context;
private final String AMOUNT = M.Amount;
private final String UNCERTAINTY = M.Uncertainty;
private TableViewer viewer;
public ParameterRedefTable(ProductSystemEditor editor) {
this.editor = editor;
}
public void create(FormToolkit toolkit, Composite composite) {
viewer = Tables.createViewer(composite, new String[] { CONTEXT,
PARAMETER, AMOUNT, UNCERTAINTY });
viewer.setLabelProvider(new LabelProvider());
ModifySupport<ParameterRedef> modifySupport = new ModifySupport<>(
viewer);
modifySupport.bind(AMOUNT, new DoubleModifier<>(editor, "value"));
modifySupport.bind(UNCERTAINTY,
new UncertaintyCellEditor(viewer.getTable(), editor));
Tables.bindColumnWidths(viewer, 0.3, 0.3, 0.2, 0.2);
List<ParameterRedef> redefs = editor.getModel().getParameterRedefs();
Collections.sort(redefs, new ParameterComparator());
viewer.setInput(redefs);
}
public void setInput(List<ParameterRedef> redefinitions) {
Collections.sort(redefinitions, new ParameterComparator());
viewer.setInput(redefinitions);
}
public void bindActions(Section section) {
Action addAction = Actions.onAdd(this::add);
Action removeAction = Actions.onRemove(this::remove);
Action copy = TableClipboard.onCopy(viewer);
Actions.bind(section, addAction, removeAction);
Actions.bind(viewer, addAction, removeAction, copy);
Tables.onDeletePressed(viewer, (e) -> remove());
Tables.onDoubleClick(viewer, (event) -> {
TableItem item = Tables.getItem(viewer, event);
if (item == null)
add();
});
}
private void add() {
ProductSystem system = editor.getModel();
List<ParameterRedef> systemRedefs = system.getParameterRedefs();
List<ParameterRedef> redefs = ParameterRedefDialog.select(system
.getProcesses());
if (redefs.isEmpty())
return;
log.trace("add new parameter redef");
for (ParameterRedef redef : redefs) {
if (!contains(redef, systemRedefs)) {
systemRedefs.add(redef.clone());
}
}
viewer.setInput(systemRedefs);
editor.setDirty(true);
}
private boolean contains(ParameterRedef redef, List<ParameterRedef> redefs) {
for (ParameterRedef contained : redefs) {
if (Strings.nullOrEqual(contained.getName(), redef.getName())
&& Objects.equals(contained.getContextId(),
redef.getContextId()))
return true;
}
return false;
}
private void remove() {
log.trace("remove parameter redef");
ProductSystem system = editor.getModel();
List<ParameterRedef> systemRedefs = system.getParameterRedefs();
List<ParameterRedef> redefs = Viewers.getAllSelected(viewer);
for (ParameterRedef redef : redefs)
systemRedefs.remove(redef);
viewer.setInput(systemRedefs);
editor.setDirty(true);
}
private class LabelProvider extends org.eclipse.jface.viewers.LabelProvider
implements ITableLabelProvider {
private EntityCache cache = Cache.getEntityCache();
@Override
public Image getColumnImage(Object element, int columnIndex) {
if (columnIndex != 0)
return null;
if (!(element instanceof ParameterRedef))
return null;
ParameterRedef redef = (ParameterRedef) element;
BaseDescriptor model = getModel(redef);
if (model == null)
return Images.get(ModelType.PARAMETER);
else
return Images.get(model);
}
@Override
public String getColumnText(Object element, int columnIndex) {
if (!(element instanceof ParameterRedef))
return null;
ParameterRedef redef = (ParameterRedef) element;
switch (columnIndex) {
case 0:
BaseDescriptor model = getModel(redef);
if (model != null)
return Labels.getDisplayName(model);
return "global";
case 1:
return redef.getName();
case 2:
return Double.toString(redef.getValue());
case 3:
return UncertaintyLabel.get(redef.getUncertainty());
default:
return null;
}
}
private BaseDescriptor getModel(ParameterRedef redef) {
if (redef == null || redef.getContextId() == null)
return null;
long modelId = redef.getContextId();
BaseDescriptor model = cache.get(ImpactMethodDescriptor.class,
modelId);
if (model != null)
return model;
else
return cache.get(ProcessDescriptor.class, modelId);
}
}
private class ParameterComparator implements Comparator<ParameterRedef> {
private EntityCache cache = Cache.getEntityCache();
@Override
public int compare(ParameterRedef o1, ParameterRedef o2) {
if (Objects.equals(o1.getContextId(), o2.getContextId()))
return byName(o1, o2);
if (o1.getContextId() == null) {
return -1; // global before process
}
if (o2.getContextId() == null)
return 1; // process after global
return compareProcesses(o1.getContextId(), o2.getContextId());
}
private int byName(ParameterRedef o1, ParameterRedef o2) {
return Strings.compare(o1.getName(), o2.getName());
}
private int compareProcesses(Long processId1, Long processId2) {
if (processId1 == null || processId2 == null)
return 0;
BaseDescriptor d1 = cache.get(ProcessDescriptor.class, processId1);
String name1 = Labels.getDisplayName(d1);
BaseDescriptor d2 = cache.get(ProcessDescriptor.class, processId2);
String name2 = Labels.getDisplayName(d2);
return Strings.compare(name1, name2);
}
}
}