blob: 60119d6a3d4d1facbcef40ac5d760387cb533de5 [file] [log] [blame]
package org.eclipse.apogy.core.programs.controllers.ui.composite;
import java.util.List;
import org.eclipse.apogy.common.emf.ApogyCommonEMFFacade;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.common.emf.ui.composites.SubClassesListComposite;
import org.eclipse.apogy.common.emf.ui.emfforms.ApogyCommonEMFUiEMFFormsFacade;
import org.eclipse.apogy.common.io.jinput.ApogyCommonIOJInputFactory;
import org.eclipse.apogy.common.io.jinput.EComponentQualifier;
import org.eclipse.apogy.common.io.jinput.ui.composites.AutomaticControllerSelectionComposite;
import org.eclipse.apogy.common.io.jinput.ui.composites.ManualControllerSelectionComposite;
import org.eclipse.apogy.common.ui.composites.NoContentComposite;
import org.eclipse.apogy.core.programs.controllers.ApogyCoreProgramsControllersFacade;
import org.eclipse.apogy.core.programs.controllers.ApogyCoreProgramsControllersPackage;
import org.eclipse.apogy.core.programs.controllers.BindedEDataTypeArgument;
import org.eclipse.apogy.core.programs.controllers.ControllerValueSource;
import org.eclipse.apogy.core.programs.controllers.FixedValueSource;
import org.eclipse.apogy.core.programs.controllers.ToggleValueSource;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.ViewerCell;
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.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
/********************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* Contributors: Pierre Allard (Pierre.Allard@canada.ca), Regent L'Archeveque
* (Regent.Larcheveque@canada.ca), Sebastien Gemme (Sebastien.Gemme@canada.ca),
* Canadian Space Agency (CSA) - Initial API and implementation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 1.0 which is available at
* http://www.eclipse.org/legal/epl-v10.html.
*
* SPDX-License-Identifier: EPL-1.0
********************************************************************************/
public class ValueSourceComposite extends ScrolledComposite {
private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
private Composite composite;
private Section typesSection;
private SubClassesListComposite valueSourcesTypesComposite;
private Section valueSection;
private Composite valueComposite;
private Composite valueSelectionComposite;
private BindedEDataTypeArgument bindedEDataTypeArgument;
private Button autoDetectEnabled = null;
private final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
/**
* Create the parentComposite.
*
* @param parent Reference to the parent parentComposite.
* @param style Composite style.
*/
public ValueSourceComposite(Composite parent, int style) {
super(parent, style);
setExpandHorizontal(true);
setExpandVertical(true);
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
ValueSourceComposite.this.toolkit.dispose();
}
});
this.composite = new Composite(this, SWT.None);
GridLayout gridLayout = new GridLayout();
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.marginBottom = 5;
this.setLayout(gridLayout);
this.composite.setLayout(gridLayout);
/**
* Value source
*/
this.typesSection = this.toolkit.createSection(this.composite,
ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR);
this.typesSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
this.typesSection.setLayout(new FillLayout());
this.typesSection.setText("Source");
this.valueSourcesTypesComposite = new SubClassesListComposite(this.typesSection, SWT.None) {
@Override
protected void newSelection(TreeSelection selection) {
if (selection.getFirstElement() != null) {
if (ValueSourceComposite.this.bindedEDataTypeArgument.getValueSource()
.eClass() != ValueSourceComposite.this.valueSourcesTypesComposite.getSelectedSubClass()) {
if (ValueSourceComposite.this.valueSourcesTypesComposite
.getSelectedSubClass() == ApogyCoreProgramsControllersPackage.Literals.CONTROLLER_VALUE_SOURCE) {
ApogyCoreProgramsControllersFacade.INSTANCE
.initBindedEDataTypeArgument(ValueSourceComposite.this.bindedEDataTypeArgument);
} else {
// Set the new value source.
ApogyCommonTransactionFacade.INSTANCE.basicSet(
ValueSourceComposite.this.bindedEDataTypeArgument,
ApogyCoreProgramsControllersPackage.Literals.BINDED_EDATA_TYPE_ARGUMENT__VALUE_SOURCE,
EcoreUtil.create((EClass) selection.getFirstElement()));
}
setValueComposite();
ValueSourceComposite.this.newSelection(selection);
}
}
}
/**
* This content provider removes the ToggleValueSource if the EParameter of the
* Argument is not a boolean.
*/
@Override
protected AdapterFactoryContentProvider getContentProvider() {
return new AdapterFactoryContentProvider(ValueSourceComposite.this.adapterFactory) {
@Override
public boolean hasChildren(Object object) {
return false;
}
@Override
public Object[] getElements(Object object) {
List<EClass> eClasses = ApogyCommonEMFFacade.INSTANCE.getAllSubEClasses((EClass) object);
if (ValueSourceComposite.this.bindedEDataTypeArgument != null
&& ValueSourceComposite.this.bindedEDataTypeArgument.getEParameter()
.getEType() != EcorePackage.Literals.EBOOLEAN) {
eClasses.remove(ApogyCoreProgramsControllersPackage.Literals.TOGGLE_VALUE_SOURCE);
}
return eClasses.toArray();
}
};
}
@Override
protected StyledCellLabelProvider getLabelProvider() {
return new StyledCellLabelProvider() {
@Override
public void update(ViewerCell cell) {
if (cell.getElement() instanceof EClass) {
cell.setText(((EClass) cell.getElement()).getName());
}
}
};
}
};
this.valueSourcesTypesComposite.setSuperClass(ApogyCoreProgramsControllersPackage.Literals.VALUE_SOURCE);
this.typesSection.setClient(this.valueSourcesTypesComposite);
/**
* Value source value
*/
this.valueSection = this.toolkit.createSection(this.composite,
ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR);
this.valueSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
this.valueSection.setLayout(new FillLayout());
this.valueSection.setText("Value");
this.valueComposite = new Composite(this.valueSection, SWT.None);
GridLayout gridLayoutValue = new GridLayout(1, false);
gridLayoutValue.marginWidth = 0;
gridLayoutValue.marginHeight = 0;
this.valueComposite.setLayout(gridLayoutValue);
this.autoDetectEnabled = new Button(this.valueComposite, SWT.CHECK);
this.autoDetectEnabled.setText("Auto Detect");
this.autoDetectEnabled.setToolTipText("Enables auto detection of the selected controller component.");
this.autoDetectEnabled.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent arg0) {
setValueComposite();
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {
}
});
this.valueSelectionComposite = new Composite(this.valueComposite, SWT.NONE);
GridLayout gridLayoutValueSelectionComposite = new GridLayout(1, false);
gridLayoutValueSelectionComposite.marginWidth = 0;
gridLayoutValueSelectionComposite.marginHeight = 0;
this.valueSelectionComposite.setLayout(gridLayoutValueSelectionComposite);
this.valueSelectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
this.valueSection.setClient(this.valueComposite);
setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
setContent(this.composite);
}
/**
* This method is called when a new selection is made.
*
* @param selection Reference to the selection.
*/
protected void newSelection(ISelection selection) {
}
/**
* Sets the value composite depending on the ValueSource
*/
private void setValueComposite() {
if (this.valueSelectionComposite != null && !this.valueSelectionComposite.isDisposed()) {
for (Control control : this.valueSelectionComposite.getChildren()) {
if (!control.isDisposed())
control.dispose();
}
}
/** Controller value source */
if (this.bindedEDataTypeArgument.getValueSource() instanceof ControllerValueSource) {
if (((ControllerValueSource) this.bindedEDataTypeArgument.getValueSource())
.getEComponentQualifier() == null) {
EComponentQualifier eComponentQualifier = ApogyCommonIOJInputFactory.eINSTANCE
.createEComponentQualifier();
ApogyCommonTransactionFacade.INSTANCE.basicSet(this.bindedEDataTypeArgument.getValueSource(),
ApogyCoreProgramsControllersPackage.Literals.CONTROLLER_VALUE_SOURCE__ECOMPONENT_QUALIFIER,
eComponentQualifier);
}
if (this.autoDetectEnabled.getSelection()) {
// Creates the ControllerSelectionComposite that implements autodetect.
AutomaticControllerSelectionComposite controllerSelectionComposite = new AutomaticControllerSelectionComposite(
this.valueSelectionComposite, SWT.None) {
@Override
protected void newSelection(ISelection selection) {
ValueSourceComposite.this.newSelection(selection);
}
};
controllerSelectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
controllerSelectionComposite
.setEComponentQualifier(((ControllerValueSource) this.bindedEDataTypeArgument.getValueSource())
.getEComponentQualifier());
controllerSelectionComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
controllerSelectionComposite.layout();
} else {
ManualControllerSelectionComposite manualValueSourceComposite = new ManualControllerSelectionComposite(
this.valueSelectionComposite, SWT.None);
manualValueSourceComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
manualValueSourceComposite
.setEComponentQualifier(((ControllerValueSource) this.bindedEDataTypeArgument.getValueSource())
.getEComponentQualifier());
manualValueSourceComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
manualValueSourceComposite.layout();
}
}
/** Fixed value source */
else if (this.bindedEDataTypeArgument.getValueSource() instanceof FixedValueSource) {
ApogyCommonEMFUiEMFFormsFacade.INSTANCE.createEMFForms(this.valueComposite,
this.bindedEDataTypeArgument.getValueSource());
}
/** Toggle value source */
else if (this.bindedEDataTypeArgument.getValueSource() instanceof ToggleValueSource) {
NoContentComposite noContentComposite = new NoContentComposite(this.valueComposite, SWT.None) {
@Override
protected String getMessage() {
return "No compatible selection";
}
};
noContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
noContentComposite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
}
this.composite.layout();
this.valueSection.layout(true, true);
}
/**
* Binds the {@link BindedEDataTypeArgument} with the UI components.
*
* @param bindedEDataTypeArgument Reference to the
* {@link BindedEDataTypeArgument}.
*/
public void setBindedEDataTypeArgument(BindedEDataTypeArgument bindedEDataTypeArgument) {
this.bindedEDataTypeArgument = bindedEDataTypeArgument;
if (bindedEDataTypeArgument.getValueSource() != null) {
this.valueSourcesTypesComposite.setSelectedEClass(bindedEDataTypeArgument.getValueSource().eClass());
}
this.valueSourcesTypesComposite.refresh();
setValueComposite();
}
}