package org.openlca.app.editors.lcia_methods;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
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.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.openlca.app.M;
import org.openlca.app.editors.InfoSection;
import org.openlca.app.editors.ModelPage;
import org.openlca.app.preferencepages.FeatureFlag;
import org.openlca.app.util.Actions;
import org.openlca.app.util.Editors;
import org.openlca.app.rcp.images.Images;
import org.openlca.app.util.UI;
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.core.model.ImpactCategory;
import org.openlca.core.model.ImpactMethod;
import org.openlca.core.model.ModelType;
import org.openlca.core.model.NwFactor;
import org.openlca.core.model.NwSet;
import org.openlca.util.Strings;
class ImpactMethodInfoPage extends ModelPage<ImpactMethod> {
private final String NAME = M.Name;
private final String DESCRIPTION = M.Description;
private final String REFERENCE_UNIT = M.ReferenceUnit;
private TableViewer viewer;
private FormToolkit toolkit;
private ImpactMethodEditor editor;
private ScrolledForm form;
ImpactMethodInfoPage(ImpactMethodEditor editor) {
super(editor, "ImpactMethodInfoPage", M.GeneralInformation);
this.editor = editor;
}
@Override
protected void createFormContent(IManagedForm managedForm) {
form = UI.formHeader(managedForm);
updateFormTitle();
if (FeatureFlag.SHOW_REFRESH_BUTTONS.isEnabled())
Editors.addRefresh(form, editor);
toolkit = managedForm.getToolkit();
Composite body = UI.formBody(form, toolkit);
InfoSection infoSection = new InfoSection(getEditor());
infoSection.render(body, toolkit);
createImpactCategoryViewer(body);
body.setFocus();
form.reflow(true);
}
@Override
protected void updateFormTitle() {
if (form == null)
return;
form.setText(M.ImpactAssessmentMethod + ": " + getModel().getName());
}
private void createImpactCategoryViewer(Composite body) {
Section section = UI.section(body, toolkit, M.ImpactCategories);
UI.gridData(section, true, true);
Composite client = UI.sectionClient(section, toolkit);
String[] properties = { NAME, DESCRIPTION, REFERENCE_UNIT };
viewer = Tables.createViewer(client, properties);
viewer.setLabelProvider(new CategoryLabelProvider());
viewer.setInput(getCategories(true));
Tables.bindColumnWidths(viewer, 0.5, 0.25, 0.25);
bindModifySupport();
bindActions(viewer, section);
editor.onSaved(() -> viewer.setInput(getCategories(false)));
}
private void bindModifySupport() {
ModifySupport<ImpactCategory> support = new ModifySupport<>(viewer);
support.bind(NAME, ImpactCategory::getName, (category, text) -> {
category.setName(text);
fireCategoryChange();
});
support.bind(DESCRIPTION, ImpactCategory::getDescription, (category,
text) -> {
category.setDescription(text);
fireCategoryChange();
});
support.bind(REFERENCE_UNIT, ImpactCategory::getReferenceUnit, (
category, text) -> {
category.setReferenceUnit(text);
fireCategoryChange();
});
}
private List<ImpactCategory> getCategories(boolean sorted) {
ImpactMethod method = editor.getModel();
List<ImpactCategory> categories = method.getImpactCategories();
if (!sorted)
return categories;
Collections.sort(categories,
(c1, c2) -> Strings.compare(c1.getName(), c2.getName()));
return categories;
}
private void bindActions(TableViewer viewer, Section section) {
Action add = Actions.onAdd(() -> onAdd());
Action remove = Actions.onRemove(() -> onRemove());
Action copy = TableClipboard.onCopy(viewer);
Actions.bind(viewer, add, remove, copy);
Actions.bind(section, add, remove);
Tables.onDeletePressed(viewer, (event) -> onRemove());
Tables.onDoubleClick(viewer, (event) -> {
TableItem item = Tables.getItem(viewer, event);
if (item == null) {
onAdd();
}
});
}
private void onAdd() {
ImpactMethod method = editor.getModel();
ImpactCategory category = new ImpactCategory();
category.setRefId(UUID.randomUUID().toString());
category.setName(M.NewImpactCategory);
method.getImpactCategories().add(category);
viewer.setInput(method.getImpactCategories());
fireCategoryChange();
}
private void onRemove() {
ImpactMethod method = editor.getModel();
List<ImpactCategory> categories = Viewers.getAllSelected(viewer);
for (ImpactCategory category : categories) {
method.getImpactCategories().remove(category);
for (NwSet set : method.getNwSets()) {
NwFactor factor = set.getFactor(category);
if (factor != null)
set.getFactors().remove(factor);
}
}
viewer.setInput(method.getImpactCategories());
fireCategoryChange();
}
private void fireCategoryChange() {
editor.postEvent(editor.IMPACT_CATEGORY_CHANGE, this);
editor.setDirty(true);
}
private class CategoryLabelProvider extends LabelProvider implements
ITableLabelProvider {
@Override
public Image getColumnImage(Object element, int column) {
if (column == 0)
return Images.get(ModelType.IMPACT_CATEGORY);
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
if (!(element instanceof ImpactCategory))
return null;
ImpactCategory category = (ImpactCategory) element;
switch (columnIndex) {
case 0:
return category.getName();
case 1:
return category.getDescription();
case 2:
return category.getReferenceUnit();
default:
return null;
}
}
}
}