package org.openlca.app.editors.flows; import java.util.List; import java.util.Objects; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ITableFontProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.TableItem; import org.openlca.app.App; import org.openlca.app.M; import org.openlca.app.components.ModelSelectionDialog; import org.openlca.app.db.Database; import org.openlca.app.rcp.images.Icon; import org.openlca.app.rcp.images.Images; import org.openlca.app.util.Error; import org.openlca.app.util.UI; import org.openlca.app.util.tables.Tables; import org.openlca.app.viewers.table.AbstractTableViewer; import org.openlca.app.viewers.table.modify.CheckBoxCellModifier; 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.database.usage.FlowPropertyFactorUseSearch; import org.openlca.core.model.Flow; import org.openlca.core.model.FlowProperty; import org.openlca.core.model.FlowPropertyFactor; import org.openlca.core.model.ModelType; import org.openlca.core.model.Unit; import org.openlca.core.model.UnitGroup; import org.openlca.core.model.descriptors.BaseDescriptor; import org.openlca.core.model.descriptors.CategorizedDescriptor; import org.openlca.core.model.descriptors.FlowPropertyDescriptor; class FlowPropertyFactorViewer extends AbstractTableViewer<FlowPropertyFactor> { private static final String NAME = M.Name; private static final String CONVERSION_FACTOR = M.ConversionFactor; private static final String REFERENCE_UNIT = M.ReferenceUnit; private static final String FORMULA = M.Formula; private static final String IS_REFERENCE = M.IsReference; private final EntityCache cache; private final FlowEditor editor; public FlowPropertyFactorViewer(Composite parent, EntityCache cache, FlowEditor editor) { super(parent); ModifySupport<FlowPropertyFactor> ms = getModifySupport(); this.editor = editor; ms.bind(CONVERSION_FACTOR, new ConversionModifier()); ms.bind(IS_REFERENCE, new ReferenceModifier()); this.cache = cache; Tables.bindColumnWidths(getViewer(), 0.2, 0.2, 0.2, 0.2, 0.2); addDoubleClickHandler(); getViewer().getTable().getColumns()[1].setAlignment(SWT.RIGHT); } private void addDoubleClickHandler() { Tables.onDoubleClick(getViewer(), (event) -> { TableItem item = Tables.getItem(getViewer(), event); if (item == null) { onCreate(); return; } FlowPropertyFactor factor = getSelected(); if (factor != null) App.openEditor(factor.getFlowProperty()); }); } public void setInput(Flow flow) { if (flow == null) setInput(new FlowPropertyFactor[0]); else setInput(flow.getFlowPropertyFactors()); } @Override protected IBaseLabelProvider getLabelProvider() { return new FactorLabelProvider(); } @Override protected String[] getColumnHeaders() { return new String[] { NAME, CONVERSION_FACTOR, REFERENCE_UNIT, FORMULA, IS_REFERENCE }; } @OnAdd protected void onCreate() { BaseDescriptor[] descriptors = ModelSelectionDialog .multiSelect(ModelType.FLOW_PROPERTY); if (descriptors == null) return; for (BaseDescriptor descriptor : descriptors) { if (!(descriptor instanceof FlowPropertyDescriptor)) continue; add((FlowPropertyDescriptor) descriptor); } } private void add(FlowPropertyDescriptor descriptor) { FlowProperty property = cache.get(FlowProperty.class, descriptor.getId()); Flow flow = editor.getModel(); if (flow.getFactor(property) != null) return; FlowPropertyFactor factor = new FlowPropertyFactor(); factor.setFlowProperty(property); factor.setConversionFactor(1); flow.getFlowPropertyFactors().add(factor); setInput(flow.getFlowPropertyFactors()); editor.setDirty(true); } @OnRemove protected void onRemove() { FlowPropertyFactor fac = getSelected(); if (fac == null) return; Flow flow = editor.getModel(); if (fac.equals(flow.getReferenceFactor())) { Error.showBox(M.CannotDeleteReferenceFlowProperty, M.ReferenceFlowPropertyCannotBeDeleted); return; } FlowPropertyFactorUseSearch search = new FlowPropertyFactorUseSearch( flow, Database.get()); List<CategorizedDescriptor> list = search.findUses(fac); if (!list.isEmpty()) { Error.showBox(M.CannotDeleteFlowProperty, M.FlowPropertyIsUsed); return; } flow.getFlowPropertyFactors().remove(fac); setInput(flow.getFlowPropertyFactors()); editor.setDirty(true); } @OnDrop protected void onDrop(FlowPropertyDescriptor descriptor) { if (descriptor != null) add(descriptor); } private class FactorLabelProvider extends LabelProvider implements ITableLabelProvider, ITableFontProvider { @Override public Image getColumnImage(Object element, int column) { if (column == 0) return Images.get(ModelType.FLOW_PROPERTY); if (column == 2) return Images.get(ModelType.UNIT_GROUP); if (column != 4) return null; Flow flow = editor.getModel(); if (flow == null || flow.getReferenceFactor() == null) return Icon.CHECK_FALSE.get(); FlowPropertyFactor refFactor = flow.getReferenceFactor(); if (refFactor == null || !refFactor.equals(element)) return Icon.CHECK_FALSE.get(); return Icon.CHECK_TRUE.get(); } @Override public String getColumnText(Object element, int columnIndex) { if (!(element instanceof FlowPropertyFactor)) return null; FlowPropertyFactor factor = (FlowPropertyFactor) element; switch (columnIndex) { case 0: if (factor.getFlowProperty() == null) return null; return factor.getFlowProperty().getName(); case 1: return Double.toString(factor.getConversionFactor()); case 2: if (factor.getFlowProperty() == null) return null; if (factor.getFlowProperty().getUnitGroup() == null) return null; if (factor.getFlowProperty().getUnitGroup().getReferenceUnit() == null) return null; return factor.getFlowProperty().getUnitGroup().getReferenceUnit().getName(); case 3: return getFormula(factor); default: return null; } } private String getFormula(FlowPropertyFactor factor) { Flow flow = editor.getModel(); FlowPropertyFactor refFactor = flow.getReferenceFactor(); Unit refUnit = getUnit(refFactor); Unit unit = getUnit(factor); if (unit == null || refUnit == null) return null; return "1.0 " + refUnit.getName() + " = " + Double.toString(factor.getConversionFactor()) + " " + unit.getName(); } private Unit getUnit(FlowPropertyFactor factor) { if (factor == null || factor.getFlowProperty() == null) return null; UnitGroup unitGroup = factor.getFlowProperty().getUnitGroup(); if (unitGroup == null) return null; return unitGroup.getReferenceUnit(); } @Override public Font getFont(Object element, int columnIndex) { Flow flow = editor.getModel(); if (flow == null || flow.getReferenceFactor() == null) return null; if (!flow.getReferenceFactor().equals(element)) return null; return UI.boldFont(); } } private class ConversionModifier extends DoubleModifier<FlowPropertyFactor> { private ConversionModifier() { super(editor, "conversionFactor"); } @Override public boolean canModify(FlowPropertyFactor element) { if (element == null) return false; return !element.equals(editor.getModel().getReferenceFactor()); } } private class ReferenceModifier extends CheckBoxCellModifier<FlowPropertyFactor> { @Override protected boolean isChecked(FlowPropertyFactor element) { Flow flow = editor.getModel(); return Objects.equals(flow.getReferenceFactor(), element); } @Override protected void setChecked(FlowPropertyFactor element, boolean value) { Flow flow = editor.getModel(); if (!value) return; if (Objects.equals(flow.getReferenceFlowProperty(), element.getFlowProperty())) return; flow.setReferenceFlowProperty(element.getFlowProperty()); double f = element.getConversionFactor(); for (FlowPropertyFactor fpFactor : flow.getFlowPropertyFactors()) { double factor = fpFactor.getConversionFactor() / f; fpFactor.setConversionFactor(factor); } editor.setDirty(true); } @Override public boolean affectsOtherElements() { return true; } } }