blob: 08c6a59e5c9c54bc9d09645419805b95e77b8af7 [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,
* Olivier L. Larouche - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*******************************************************************************/
package org.eclipse.apogy.core.programs.controllers.ui.composite;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.apogy.common.emf.ApogyCommonEMFPackage;
import org.eclipse.apogy.common.emf.FeaturePathAdapter;
import org.eclipse.apogy.common.emf.impl.FeaturePathAdapterCustomImpl;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.common.emf.ui.ApogyCommonEMFUIFactory;
import org.eclipse.apogy.common.emf.ui.NamedSetting;
import org.eclipse.apogy.common.emf.ui.wizards.ApogyEObjectWizard;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFacade;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorPackage;
import org.eclipse.apogy.core.programs.controllers.ApogyCoreProgramsControllersFacade;
import org.eclipse.apogy.core.programs.controllers.ApogyCoreProgramsControllersPackage;
import org.eclipse.apogy.core.programs.controllers.ControllersConfiguration;
import org.eclipse.apogy.core.programs.controllers.ControllersGroup;
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.list.DecoratingObservableList;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.FeaturePath;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
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.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
public class ControllerConfigsComposite extends ScrolledComposite {
private DataBindingContext dataBindingContext;
private final TableViewer tableViewer;
private ControllersGroup controllersGroup;
private List<FeaturePathAdapter> adapters;
private final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
private final Button btnDelete;
private final Button btnActivate;
private final Button btnDeactivate;
/**
* Creates the parentComposite.
*
* @param parent
* @param style
*/
public ControllerConfigsComposite(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(1, true));
setExpandHorizontal(true);
setExpandVertical(true);
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (ControllerConfigsComposite.this.controllersGroup != null) {
for (FeaturePathAdapter adapter : getAdapters()) {
adapter.dispose();
}
}
}
});
Composite composite = new Composite(this, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
this.tableViewer = new TableViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
this.tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ControllerConfigsComposite.this.newSelection(null);
}
});
Table table = this.tableViewer.getTable();
table.setLinesVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 5));
TableColumn tblclmnName = new TableColumn(table, SWT.NONE);
tblclmnName.setWidth(100);
Button btnNew = new Button(composite, SWT.NONE);
btnNew.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
btnNew.setText("New");
btnNew.setEnabled(true);
btnNew.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
NamedSetting setting = ApogyCommonEMFUIFactory.eINSTANCE.createNamedSetting();
setting.setParent(ControllerConfigsComposite.this.controllersGroup);
setting.setContainingFeature(ApogyCoreInvocatorPackage.Literals.PROGRAMS_GROUP__PROGRAMS);
ApogyEObjectWizard wizard = new ApogyEObjectWizard(
ApogyCoreInvocatorPackage.Literals.PROGRAMS_GROUP__PROGRAMS,
ControllerConfigsComposite.this.controllersGroup, setting,
ApogyCoreProgramsControllersPackage.Literals.CONTROLLERS_CONFIGURATION);
WizardDialog dialog = new WizardDialog(getShell(), wizard);
dialog.open();
ControllerConfigsComposite.this.tableViewer
.setSelection(new StructuredSelection(wizard.getCreatedEObject()));
}
});
this.btnDelete = new Button(composite, SWT.NONE);
this.btnDelete.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
this.btnDelete.setText("Delete");
this.btnDelete.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
if (getSelectedControllerConfiguration() != null) {
if (getSelectedControllerConfiguration().isStarted()) {
ApogyCoreProgramsControllersFacade.INSTANCE
.setActiveControllersConfiguration(getSelectedControllerConfiguration(), false);
}
ApogyCommonTransactionFacade.INSTANCE.basicRemove(ControllerConfigsComposite.this.controllersGroup,
ApogyCoreInvocatorPackage.Literals.PROGRAMS_GROUP__PROGRAMS,
getSelectedControllerConfiguration());
}
}
});
Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
this.btnActivate = new Button(composite, SWT.NONE);
this.btnActivate.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
this.btnActivate.setText("Activate");
this.btnActivate.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
ControllersConfiguration config = (ControllersConfiguration) ControllerConfigsComposite.this.tableViewer
.getStructuredSelection().getFirstElement();
ApogyCoreProgramsControllersFacade.INSTANCE.setActiveControllersConfiguration(config, true);
}
});
this.btnDeactivate = new Button(composite, SWT.NONE);
this.btnDeactivate.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
this.btnDeactivate.setText("Deactivate");
this.btnDeactivate.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
ControllersConfiguration config = (ControllersConfiguration) ControllerConfigsComposite.this.tableViewer
.getStructuredSelection().getFirstElement();
ApogyCoreProgramsControllersFacade.INSTANCE.setActiveControllersConfiguration(config, false);
}
});
setContent(composite);
setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
this.dataBindingContext = initDataBindingsCustom();
}
protected void newSelection(ISelection selection) {
}
public ControllersConfiguration getSelectedControllerConfiguration() {
return (ControllersConfiguration) this.tableViewer.getStructuredSelection().getFirstElement();
}
/**
* Sets the root object for the parentComposite
*
* @param eObject The root eObject
*/
@SuppressWarnings("unchecked")
public void setControllersGroup(ControllersGroup controllersGroup) {
if (this.controllersGroup != null) {
for (FeaturePathAdapter adapter : getAdapters()) {
adapter.dispose();
}
}
this.controllersGroup = controllersGroup;
IObservableList<?> programGroupProgramsObserveList = EMFProperties
.list(ApogyCoreInvocatorPackage.Literals.PROGRAMS_GROUP__PROGRAMS).observe(controllersGroup);
this.tableViewer.setInput(programGroupProgramsObserveList);
for (FeaturePathAdapter adapter : getAdapters()) {
adapter.init(this.controllersGroup);
}
}
@SuppressWarnings("unchecked")
protected DataBindingContext initDataBindingsCustom() {
this.dataBindingContext = new DataBindingContext();
this.tableViewer.setContentProvider(new AdapterFactoryContentProvider(this.adapterFactory) {
@Override
public Object[] getElements(Object object) {
List<Object> objects = new ArrayList<>();
for (Object object1 : ((DecoratingObservableList<?>) object)) {
if (object1 instanceof ControllersConfiguration) {
objects.add(object1);
}
}
return objects.toArray();
}
@Override
public boolean hasChildren(Object object) {
return false;
}
});
this.tableViewer.setLabelProvider(new AdapterFactoryLabelProvider(this.adapterFactory) {
@Override
public Image getColumnImage(Object object, int columnIndex) {
return null;
}
@Override
public String getText(Object object) {
return ((ControllersConfiguration) object).getName();
}
});
/**
* Buttons bindings
*/
IObservableValue<?> tableViewerSingleSelectionObserveValue = ViewerProperties.singleSelection()
.observe(this.tableViewer);
IObservableValue<?> variablesInstantiated = EMFProperties
.value(FeaturePath.fromList(ApogyCoreInvocatorPackage.Literals.INVOCATOR_SESSION__ENVIRONMENT,
ApogyCoreInvocatorPackage.Literals.ENVIRONMENT__ACTIVE_CONTEXT,
ApogyCoreInvocatorPackage.Literals.CONTEXT__VARIABLES_INSTANTIATED))
.observe(ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession());
IObservableValue<?> enableDeleteButtonObserveValue = WidgetProperties.enabled().observe(this.btnDelete);
this.dataBindingContext.bindValue(enableDeleteButtonObserveValue, tableViewerSingleSelectionObserveValue,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(ControllersConfiguration.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return updateDelete();
}
}));
this.dataBindingContext.bindValue(enableDeleteButtonObserveValue, variablesInstantiated,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(Boolean.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return updateDelete();
}
}));
IObservableValue<?> enableActivateButtonObserveValue = WidgetProperties.enabled().observe(this.btnActivate);
this.dataBindingContext.bindValue(enableActivateButtonObserveValue, tableViewerSingleSelectionObserveValue,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(ControllersConfiguration.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return updateActivate();
}
}));
this.dataBindingContext.bindValue(enableActivateButtonObserveValue, variablesInstantiated,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(Boolean.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return updateActivate();
}
}));
IObservableValue<?> enableDeactivateButtonObserveValue = WidgetProperties.enabled().observe(this.btnDeactivate);
this.dataBindingContext.bindValue(enableDeactivateButtonObserveValue, tableViewerSingleSelectionObserveValue,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(ControllersConfiguration.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return updateDeactivate();
}
}));
this.dataBindingContext.bindValue(enableDeactivateButtonObserveValue, variablesInstantiated,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(Boolean.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return updateDeactivate();
}
}));
return this.dataBindingContext;
}
/**
* This method is used to update the delete button. This is needed because more
* than one binding will update this value.
*/
private boolean updateDelete() {
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession() != null
&& ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment() != null
&& ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment()
.getActiveContext() != null) {
if (this.tableViewer.getStructuredSelection().getFirstElement() != null) {
return !((ControllersConfiguration) this.tableViewer.getStructuredSelection().getFirstElement())
.isStarted();
}
}
return false;
}
/**
* This method is used to update the activate button. This is needed because
* more than one binding will update this value.
*/
private boolean updateActivate() {
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession() != null
&& ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment() != null
&& ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment()
.getActiveContext() != null) {
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment().getActiveContext()
.isVariablesInstantiated()) {
if (this.tableViewer.getStructuredSelection().getFirstElement() != null) {
return !((ControllersConfiguration) this.tableViewer.getStructuredSelection().getFirstElement())
.isStarted();
}
}
}
return false;
}
/**
* This method is used to update the deactivate button. This is needed because
* more than one binding will update this value.
*/
private boolean updateDeactivate() {
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession() != null
&& ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment() != null
&& ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment()
.getActiveContext() != null) {
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment().getActiveContext()
.isVariablesInstantiated()) {
if (this.tableViewer.getStructuredSelection().getFirstElement() != null) {
return ((ControllersConfiguration) this.tableViewer.getStructuredSelection().getFirstElement())
.isStarted();
}
}
}
return false;
}
private List<FeaturePathAdapter> getAdapters() {
if (this.adapters == null) {
this.adapters = new ArrayList<FeaturePathAdapter>();
this.adapters.add(new FeaturePathAdapterCustomImpl() {
@Override
public void notifyChanged(Notification msg) {
if (!ControllerConfigsComposite.this.tableViewer.isBusy()
&& !ControllerConfigsComposite.this.isDisposed()) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (!ControllerConfigsComposite.this.tableViewer.isBusy()) {
ControllerConfigsComposite.this.tableViewer.refresh();
}
}
});
}
}
@Override
public List<? extends EStructuralFeature> getFeatureList() {
List<EStructuralFeature> features = new ArrayList<>();
features.add(ApogyCoreInvocatorPackage.Literals.PROGRAMS_GROUP__PROGRAMS);
features.add(ApogyCoreInvocatorPackage.Literals.OPERATION_CALL_CONTAINER__OPERATION_CALLS);
features.add(ApogyCommonEMFPackage.Literals.NAMED__NAME);
return features;
}
});
this.adapters.add(new FeaturePathAdapterCustomImpl() {
@Override
public void notifyChanged(Notification msg) {
getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
if (msg.getNotifier() == ControllerConfigsComposite.this.tableViewer
.getStructuredSelection().getFirstElement()) {
ControllerConfigsComposite.this.btnActivate.setEnabled(updateActivate());
ControllerConfigsComposite.this.btnDeactivate.setEnabled(updateDeactivate());
}
}
});
}
@Override
public List<? extends EStructuralFeature> getFeatureList() {
List<EStructuralFeature> features = new ArrayList<>();
features.add(ApogyCoreInvocatorPackage.Literals.PROGRAMS_GROUP__PROGRAMS);
features.add(ApogyCommonEMFPackage.Literals.STARTABLE__STARTED);
return features;
}
});
}
return this.adapters;
}
}