blob: ace41bd1a7fceec4eb7fd4ce41742ec27dd049ce [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,
* Sebastien Gemme - initial API and implementation
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.addons.ros.ui.composites;
import org.eclipse.apogy.addons.ros.ROSInterface;
import org.eclipse.apogy.addons.ros.ROSService;
import org.eclipse.apogy.addons.ros.ROSServiceState;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.emf.common.notify.Adapter;
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.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.PlatformUI;
public class ROSServiceListComposite extends Composite {
private ROSInterface rosInterface;
private ROSService<?, ?> selectedROSService = null;
private final Tree tree;
private final TreeViewer treeViewer;
private final AdapterFactory adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
private DataBindingContext m_bindingContext;
private Adapter serviceAdapter;
public ROSServiceListComposite(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(1, false));
this.treeViewer = new TreeViewer(this,
SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
this.tree = this.treeViewer.getTree();
GridData gd_tree = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gd_tree.widthHint = 400;
gd_tree.minimumWidth = 400;
this.tree.setLayoutData(gd_tree);
this.tree.setHeaderVisible(true);
this.tree.setLinesVisible(true);
TreeViewerColumn treeViewerColumnItem_State = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnState = treeViewerColumnItem_State.getColumn();
trclmnState.setWidth(150);
trclmnState.setText("State");
TreeViewerColumn treeViewerColumnItem_Name = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnItem = treeViewerColumnItem_Name.getColumn();
trclmnItem.setWidth(350);
trclmnItem.setText("Service Name");
TreeViewerColumn treeViewerColumnItem_AutoReconnect = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnAutoReconnect = treeViewerColumnItem_AutoReconnect.getColumn();
trclmnAutoReconnect.setWidth(120);
trclmnAutoReconnect.setText("Auto-Reconnect");
TreeViewerColumn treeViewerColumnItem_Type = new TreeViewerColumn(this.treeViewer, SWT.NONE);
TreeColumn trclmnType = treeViewerColumnItem_Type.getColumn();
trclmnType.setWidth(350);
trclmnType.setText("Type");
this.treeViewer.setContentProvider(new CustomContentProvider());
this.treeViewer.setLabelProvider(new CustomLabelProvider(this.adapterFactory));
this.treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
ROSServiceListComposite.this.selectedROSService = (ROSService<?, ?>) ((IStructuredSelection) event
.getSelection()).getFirstElement();
newROSServiceSelected(ROSServiceListComposite.this.selectedROSService);
}
});
this.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (ROSServiceListComposite.this.m_bindingContext != null)
ROSServiceListComposite.this.m_bindingContext.dispose();
}
});
}
public ROSInterface getROSInterface() {
return this.rosInterface;
}
public void setROSInterface(ROSInterface rosInterface) {
if (this.m_bindingContext != null) {
this.m_bindingContext.dispose();
}
// Uregister from previous services.
if (this.rosInterface != null && this.rosInterface.getServiceManager() != null) {
for (ROSService<?, ?> service : this.rosInterface.getServiceManager().getServices().values()) {
service.eAdapters().remove(getServiceAdapter());
}
}
this.rosInterface = rosInterface;
if (rosInterface != null) {
this.m_bindingContext = customInitDataBindings();
this.treeViewer.setInput(rosInterface);
// Selects the first EarthSurfaceWorksite found.
this.selectedROSService = getFirstROSService(rosInterface);
if (this.selectedROSService != null)
this.treeViewer.setSelection(new StructuredSelection(this.selectedROSService), true);
newROSServiceSelected(this.selectedROSService);
// Registers to all services.
if (this.rosInterface.getServiceManager() != null) {
for (ROSService<?, ?> service : this.rosInterface.getServiceManager().getServices().values()) {
service.eAdapters().add(getServiceAdapter());
}
}
} else {
this.treeViewer.setInput(null);
this.treeViewer.setSelection(null, true);
newROSServiceSelected(null);
}
}
protected void newROSServiceSelected(ROSService<?, ?> rosService) {
}
protected DataBindingContext customInitDataBindings() {
DataBindingContext bindingContext = new DataBindingContext();
// IObservableValue<?> observeSingleSelectionViewer =
// ViewerProperties.singleSelection().observe(treeViewer);
return bindingContext;
}
protected ROSService<?, ?> getFirstROSService(ROSInterface rosInterface) {
if (rosInterface.getServiceManager() != null && !rosInterface.getServiceManager().getServices().isEmpty()) {
return (ROSService<?, ?>) rosInterface.getServiceManager().getServices().values().toArray()[0];
} else {
return null;
}
}
private class CustomContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof ROSInterface) {
ROSInterface rosInterface = (ROSInterface) inputElement;
if (rosInterface.getServiceManager() != null) {
return rosInterface.getServiceManager().getServices().values().toArray();
}
}
return new Object[] {};
}
@Override
public Object[] getChildren(Object parentElement) {
return new Object[] {};
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return false;
}
}
/**
*
* Label Provider.
*
*/
private class CustomLabelProvider extends AdapterFactoryLabelProvider
implements ITableLabelProvider, ITableColorProvider {
private final static int SERVICE_STATE_COLUMN_ID = 0;
private final static int SERVICE_NAME_COLUMN_ID = 1;
private final static int SERVICE_AUTO_RECONNECT_COLUMN_ID = 2;
private final static int SERVICE_TYPE_COLUMN_ID = 3;
public CustomLabelProvider(AdapterFactory adapterFactory) {
super(adapterFactory);
}
@SuppressWarnings("rawtypes")
@Override
public String getColumnText(Object object, int columnIndex) {
String str = "<undefined>";
switch (columnIndex) {
case SERVICE_NAME_COLUMN_ID:
if (object instanceof ROSService) {
ROSService rosService = (ROSService) object;
str = rosService.getServiceName();
}
break;
case SERVICE_AUTO_RECONNECT_COLUMN_ID:
str = "";
if (object instanceof ROSService) {
ROSService rosService = (ROSService) object;
if (rosService.isEnableAutoReconnect()) {
str = "Yes";
} else {
str = "No";
}
}
break;
case SERVICE_STATE_COLUMN_ID:
str = "";
if (object instanceof ROSService) {
ROSService rosService = (ROSService) object;
str = rosService.getServiceState().getLiteral();
}
break;
case SERVICE_TYPE_COLUMN_ID:
if (object instanceof ROSService) {
ROSService rosService = (ROSService) object;
str = rosService.getServiceType();
}
break;
default:
break;
}
return str;
}
@Override
public Image getColumnImage(Object object, int columnIndex) {
return null;
}
@Override
public Color getBackground(Object object, int columnIndex) {
Color color = super.getBackground(object, columnIndex);
if (object instanceof ROSService) {
ROSService<?, ?> rosService = (ROSService<?, ?>) object;
switch (rosService.getServiceState().getValue()) {
case ROSServiceState.INITIALIZING_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_YELLOW);
break;
case ROSServiceState.READY_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_GREEN);
break;
case ROSServiceState.STOPPED_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_GRAY);
break;
case ROSServiceState.FAILED_VALUE:
color = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_RED);
break;
default:
break;
}
}
return color;
}
}
private Adapter getServiceAdapter() {
if (this.serviceAdapter == null) {
this.serviceAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (!ROSServiceListComposite.this.treeViewer.isBusy()) {
ROSServiceListComposite.this.treeViewer.getTree().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
ROSServiceListComposite.this.treeViewer.refresh(true);
}
});
}
}
};
}
return this.serviceAdapter;
}
}