blob: fb93c87b925c371c9b65a6bd01e4e1d074575828 [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.invocator.ui.composites;
import org.eclipse.apogy.common.emf.ApogyCommonEMFPackage;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorPackage;
import org.eclipse.apogy.core.invocator.Context;
import org.eclipse.apogy.core.invocator.ContextsList;
import org.eclipse.apogy.core.invocator.Environment;
import org.eclipse.apogy.core.invocator.ui.wizards.NewContextWizard;
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.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.databinding.property.Properties;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.FeaturePath;
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.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
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.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.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
public class ContextsListComposite extends ScrolledComposite {
private DataBindingContext m_bindingContext;
private WritableValue<Environment> environmentBinder;
private Environment environment;
private final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
private Adapter activeContextAdapter;
private final Button btnNew;
private final Button btnDelete;
private final TableViewer tableViewer;
/**
* Creates the parentComposite.
*
* @param parent
* @param style
*/
public ContextsListComposite(Composite parent, int style) {
super(parent, style);
setLayout(new FillLayout());
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
ContextsListComposite.this.adapterFactory.dispose();
if (ContextsListComposite.this.environment != null) {
ContextsListComposite.this.environment.eAdapters().remove(getActiveContextAdapter());
}
}
});
setExpandHorizontal(true);
setExpandVertical(true);
Composite composite = new Composite(this, SWT.None);
composite.setLayout(new GridLayout(2, false));
this.tableViewer = new TableViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
Table table = this.tableViewer.getTable();
table.setHeaderVisible(false);
table.setLinesVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4));
this.tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
newSelection(event.getSelection());
}
});
TableColumn tblclmnName = new TableColumn(table, SWT.NONE);
tblclmnName.setText("Name");
this.btnNew = new Button(composite, SWT.NONE);
this.btnNew.setText("New");
this.btnNew.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
this.btnNew.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (getEnvironment().getVariablesList() != null
&& !getEnvironment().getVariablesList().getVariables().isEmpty()) {
/**
* Creates and opens the wizard to create a valid context
*/
NewContextWizard newContextWizard = new NewContextWizard(getEnvironment().getInvocatorSession());
WizardDialog dialog = new WizardDialog(getShell(), newContextWizard);
dialog.open();
} else {
MessageBox dialog = new MessageBox(getShell());
dialog.setMessage("Variables list is empty");
dialog.open();
}
}
});
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.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (getEnvironment() != null && getEnvironment().getActiveContext() == getSelectedContext()) {
ApogyCommonTransactionFacade.INSTANCE.basicSet(getEnvironment(),
ApogyCoreInvocatorPackage.Literals.ENVIRONMENT__ACTIVE_CONTEXT, null);
}
ApogyCommonTransactionFacade.INSTANCE.basicRemove(getEnvironment().getContextsList(),
ApogyCoreInvocatorPackage.Literals.CONTEXTS_LIST__CONTEXTS, getSelectedContext());
}
});
Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
Button btnActivate = new Button(composite, SWT.NONE);
btnActivate.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
btnActivate.setText("Activate");
btnActivate.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (ContextsListComposite.this.environment.getActiveContext() != getSelectedContext()) {
ApogyCommonTransactionFacade.INSTANCE.basicSet(ContextsListComposite.this.environment,
ApogyCoreInvocatorPackage.Literals.ENVIRONMENT__ACTIVE_CONTEXT, getSelectedContext());
}
}
});
setContent(composite);
setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
this.m_bindingContext = initDataBindingsCustom();
// Dispose
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (ContextsListComposite.this.m_bindingContext != null)
ContextsListComposite.this.m_bindingContext.dispose();
}
});
}
/**
* Returns the environment that contains the {@link ContextsList}.
*
* @return Reference to the environment.
*/
private Environment getEnvironment() {
return this.environment;
}
/**
* Sets the {@link Environment}.
*
* @param Environment Reference to the Environment.
*/
public void setEnvironment(Environment environment) {
if (this.environment != null) {
this.environment.eAdapters().remove(getActiveContextAdapter());
}
this.environmentBinder.setValue(environment);
this.environment = environment;
if (!this.tableViewer.isBusy()) {
this.tableViewer.refresh();
}
for (TableColumn column : this.tableViewer.getTable().getColumns()) {
column.pack();
}
if (this.environment != null) {
this.environment.eAdapters().add(getActiveContextAdapter());
}
}
public Context getSelectedContext() {
return (Context) this.tableViewer.getStructuredSelection().getFirstElement();
}
/**
* Creates and returns the data bindings context that takes care of the Contexts
* List Viewer.
*
* @return Reference to the data bindings context.
*/
@SuppressWarnings("unchecked")
private DataBindingContext initDataBindingsCustom() {
this.m_bindingContext = new DataBindingContext();
if (this.environmentBinder == null) {
this.environmentBinder = new WritableValue<Environment>();
}
/**
* Context list binding
*/
IObservableList<?> environmentContextListContextsObserveValue = EMFProperties
.list(FeaturePath.fromList(ApogyCoreInvocatorPackage.Literals.ENVIRONMENT__CONTEXTS_LIST,
ApogyCoreInvocatorPackage.Literals.CONTEXTS_LIST__CONTEXTS))
.observeDetail(this.environmentBinder);
ObservableListContentProvider contentProvider = new ObservableListContentProvider();
this.tableViewer.setContentProvider(contentProvider);
this.tableViewer.setLabelProvider(
new ObservableMapLabelProvider(Properties.observeEach(contentProvider.getKnownElements(),
EMFProperties.value(ApogyCoreInvocatorPackage.Literals.ENVIRONMENT__ACTIVE_CONTEXT),
EMFProperties.value(ApogyCommonEMFPackage.Literals.NAMED__NAME))) {
private AdapterFactoryLabelProvider adapterLabelProvider;
private final static int NAME_COLUMN_ID = 0;
@Override
public String getColumnText(Object element, int columnIndex) {
String str = "<undefined>";
if (element instanceof Context) {
switch (columnIndex) {
case NAME_COLUMN_ID:
str = getAdapterLabelProvider().getText(element);
break;
}
}
return str;
}
public AdapterFactoryLabelProvider getAdapterLabelProvider() {
if (this.adapterLabelProvider == null) {
this.adapterLabelProvider = new AdapterFactoryLabelProvider(
ContextsListComposite.this.adapterFactory) {
@Override
public String getText(Object object) {
Context context = (Context) object;
String str = context.getName();
if (ContextsListComposite.this.environment != null
&& ContextsListComposite.this.environment.getActiveContext() == context) {
str += " <Active>";
}
return str;
}
};
}
return this.adapterLabelProvider;
}
});
this.tableViewer.setInput(environmentContextListContextsObserveValue);
IObservableValue<?> observeTableViewerSelection = ViewerProperties.singleSelection().observe(this.tableViewer);
IObservableValue<?> observeBtnDeleteEnabled = WidgetProperties.enabled().observe(this.btnDelete);
this.m_bindingContext.bindValue(observeBtnDeleteEnabled, observeTableViewerSelection,
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE)
.setConverter(new Converter(Object.class, Boolean.class) {
@Override
public Object convert(Object fromObject) {
return fromObject != null;
}
}));
return this.m_bindingContext;
}
/**
* This method is called when a new selection is made in the parentComposite.
*
* @param selection Reference to the selection.
*/
protected void newSelection(ISelection selection) {
}
/**
* This methods gets an adapter to change the labels if the active context is
* changed.
*/
private Adapter getActiveContextAdapter() {
if (this.activeContextAdapter == null) {
this.activeContextAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getFeature() == ApogyCoreInvocatorPackage.Literals.ENVIRONMENT__ACTIVE_CONTEXT) {
ContextsListComposite.this.tableViewer.refresh();
}
}
};
}
return this.activeContextAdapter;
}
}