blob: c7b20df38a69474b77b3ad7ca85c11dfe6f16282 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* 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:
* Pierre Allard,
* Regent L'Archeveque - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.common.math.ui.composites;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.common.math.ApogyCommonMathFactory;
import org.eclipse.apogy.common.math.Tuple3d;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.conversion.Converter;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tuple3dListComposite extends Composite {
private static final Logger Logger = LoggerFactory.getLogger(Tuple3dListComposite.class);
private EObject owner = null;
private EStructuralFeature feature = null;
private Tuple3dListAdapter adapter;
private final TableViewer tableViewer;
private final Table table;
private final Button btnNew;
private final Button btnDelete;
private final AdapterFactory adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
private DataBindingContext m_bindingContext;
public Tuple3dListComposite(Composite parent, int style) {
this(parent, style, null, null, null);
}
public Tuple3dListComposite(Composite parent, int style, String label, EObject owner, EStructuralFeature feature) {
super(parent, style);
setLayout(new GridLayout(2, false));
this.owner = owner;
this.feature = feature;
this.tableViewer = new TableViewer(this,
SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
this.table = this.tableViewer.getTable();
GridData gd_tree = new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1);
gd_tree.widthHint = 300;
gd_tree.minimumWidth = 300;
this.table.setLayoutData(gd_tree);
this.table.setLinesVisible(true);
TableViewerColumn tableViewerColumnItem_Name = new TableViewerColumn(this.tableViewer, SWT.NONE);
TableColumn trclmnItemName = tableViewerColumnItem_Name.getColumn();
trclmnItemName.setWidth(200);
this.tableViewer.setContentProvider(ArrayContentProvider.getInstance());
this.tableViewer.setLabelProvider(new AdapterFactoryLabelProvider(this.adapterFactory));
this.tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
newTuple3dSelected((Tuple3d) ((IStructuredSelection) event.getSelection()).getFirstElement());
}
});
// Buttons.
Composite composite = new Composite(this, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
composite.setLayout(new GridLayout(1, false));
this.btnNew = new Button(composite, SWT.NONE);
this.btnNew.setSize(74, 29);
this.btnNew.setText("New");
this.btnNew.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
this.btnNew.setEnabled(true);
this.btnNew.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
if (event.type == SWT.Selection) {
Tuple3d newTuple3d = ApogyCommonMathFactory.eINSTANCE.createTuple3d();
// Adds the slope range.
ApogyCommonTransactionFacade.INSTANCE.basicAdd(getOwner(), getFeature(), newTuple3d);
// Forces the viewer to refresh its input.
if (!Tuple3dListComposite.this.tableViewer.isBusy()) {
Tuple3dListComposite.this.tableViewer.setInput(getOwner().eGet(getFeature()));
}
// Selects the range just created.
Tuple3dListComposite.this.tableViewer.setSelection(new StructuredSelection(newTuple3d));
}
}
});
this.btnDelete = new Button(composite, SWT.NONE);
this.btnDelete.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
this.btnDelete.setSize(74, 29);
this.btnDelete.setText("Delete");
this.btnDelete.setEnabled(false);
this.btnDelete.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
String imageMapLayersToDeleteMessage = "";
MessageDialog dialog = new MessageDialog(null, "Delete the selected Tuple 3D", null,
"Are you sure to delete these Tuple 3D: " + imageMapLayersToDeleteMessage,
MessageDialog.QUESTION, new String[] { "Yes", "No" }, 1);
int result = dialog.open();
if (result == 0) {
for (Tuple3d slopeRange : getSelectedTuple3dList()) {
try {
ApogyCommonTransactionFacade.INSTANCE.basicRemove(getOwner(), getFeature(), slopeRange);
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}
}
}
// Forces the viewer to refresh its input.
if (!Tuple3dListComposite.this.tableViewer.isBusy()) {
Tuple3dListComposite.this.tableViewer.setInput(getOwner().eGet(getFeature()));
}
}
});
updateDisplayedList();
this.m_bindingContext = customInitDataBindings();
// Forces update
setOwner(owner);
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (Tuple3dListComposite.this.m_bindingContext != null)
Tuple3dListComposite.this.m_bindingContext.dispose();
if (getOwner() != null) {
getOwner().eAdapters().remove(getAdapter());
getAdapter().unregisterFromAll();
}
}
});
}
public EObject getOwner() {
return this.owner;
}
@SuppressWarnings("unchecked")
public void setOwner(EObject newOwner) {
if (this.m_bindingContext != null)
this.m_bindingContext.dispose();
// Un-Register listener from past owner.
if (this.owner != null) {
this.owner.eAdapters().remove(getAdapter());
getAdapter().unregisterFromAll();
}
this.owner = newOwner;
if (newOwner != null) {
this.m_bindingContext = customInitDataBindings();
// Update displayed list.
updateDisplayedList();
// Register listener to the new owner.
newOwner.eAdapters().add(getAdapter());
if (getOwner().eGet(getFeature()) != null) {
getAdapter().registerTo((Collection<Tuple3d>) getOwner().eGet(getFeature()));
}
}
}
public EStructuralFeature getFeature() {
return this.feature;
}
public void setFeature(EStructuralFeature feature) {
if (this.m_bindingContext != null)
this.m_bindingContext.dispose();
this.feature = feature;
// Update displayed list.
updateDisplayedList();
if (feature != null) {
this.m_bindingContext = customInitDataBindings();
}
}
@SuppressWarnings("unchecked")
public List<Tuple3d> getSelectedTuple3dList() {
return ((IStructuredSelection) this.tableViewer.getSelection()).toList();
}
public Tuple3d getSelectedTuple3d() {
List<Tuple3d> selected = getSelectedTuple3dList();
if (selected != null && !selected.isEmpty()) {
return selected.get(0);
} else {
return null;
}
}
protected void newTuple3dSelected(Tuple3d tuple3d) {
}
protected DataBindingContext customInitDataBindings() {
DataBindingContext bindingContext = new DataBindingContext();
IObservableValue<?> observeSingleSelectionViewer = ViewerProperties.singleSelection().observe(this.tableViewer);
/* Delete Button Enabled Binding. */
IObservableValue<?> observeEnabledBtnDeleteObserveWidget = WidgetProperties.enabled().observe(this.btnDelete);
bindingContext.bindValue(observeEnabledBtnDeleteObserveWidget, observeSingleSelectionViewer, null,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(Object.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
Boolean result = (fromObject != null);
Collection<Tuple3d> list = getReferedTuple3dCollection();
if (list != null) {
result = result && (list.size() > 3);
return result;
} else {
return false;
}
}
}));
return bindingContext;
}
private void updateDisplayedList() {
if (getOwner() != null && getFeature() != null) {
this.tableViewer.setInput(getOwner().eGet(getFeature()));
}
}
@SuppressWarnings("unchecked")
private Collection<Tuple3d> getReferedTuple3dCollection() {
if (getOwner() != null && getFeature() != null) {
Collection<Tuple3d> list = (Collection<Tuple3d>) getOwner().eGet(getFeature());
return list;
} else {
return null;
}
}
private Tuple3dListAdapter getAdapter() {
if (this.adapter == null) {
this.adapter = new Tuple3dListAdapter();
}
return this.adapter;
}
private class Tuple3dListAdapter extends AdapterImpl {
private final List<Tuple3d> points = new ArrayList<Tuple3d>();
@SuppressWarnings("unchecked")
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof Tuple3d) {
updateDisplayedList();
} else if (msg.getNotifier() == getOwner()) {
if (msg.getFeature() == getFeature()) {
switch (msg.getEventType()) {
case Notification.ADD:
if (msg.getNewValue() instanceof Tuple3d) {
Tuple3d newPoint = (Tuple3d) msg.getNewValue();
newPoint.eAdapters().add(getAdapter());
this.points.add(newPoint);
}
break;
case Notification.ADD_MANY:
Collection<Tuple3d> newPoints = (Collection<Tuple3d>) msg.getNewValue();
for (Tuple3d point : newPoints) {
point.eAdapters().add(getAdapter());
this.points.add(point);
}
break;
case Notification.REMOVE:
if (msg.getOldValue() instanceof Tuple3d) {
Tuple3d oldPoint = (Tuple3d) msg.getOldValue();
oldPoint.eAdapters().remove(getAdapter());
this.points.remove(oldPoint);
}
break;
case Notification.REMOVE_MANY:
Collection<Tuple3d> oldPoints = (Collection<Tuple3d>) msg.getOldValue();
for (Tuple3d point : oldPoints) {
point.eAdapters().remove(getAdapter());
this.points.remove(point);
}
break;
default:
break;
}
updateDisplayedList();
}
}
}
public void unregisterFromAll() {
for (Tuple3d point : this.points) {
point.eAdapters().remove(getAdapter());
}
this.points.clear();
}
public void registerTo(Collection<Tuple3d> list) {
for (Tuple3d point : list) {
point.eAdapters().add(getAdapter());
this.points.add(point);
}
}
}
}