| /******************************************************************************* |
| * 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; |
| } |
| } |