/*******************************************************************************
* ALMA - Atacama Large Millimeter Array
* Copyright (c) ESO - European Southern Observatory, 2011
* (in the framework of the ALMA collaboration).
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*******************************************************************************/
package alma.acs.eventbrowser.parts;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import alma.acs.nsstatistics.ChannelConsumers;
import alma.acs.nsstatistics.ChannelData;
import alma.acs.nsstatistics.ChannelParticipantName;
import alma.acs.nsstatistics.ChannelSuppliers;
import alma.acs.nsstatistics.MCStatistics;
import alma.acs.nsstatistics.NotifyServiceData;
import alma.acs.nsstatistics.NotifyServices;
/**
* Code is derived from the older class alma/acs/eventbrowser/views/EventGuiAdapterFactory.java,
* although here in E4 we do not yet use an adapter pattern but a straight 'instanceof'-based check
* for the different levels of the tree hierarchy.
* TODO: Check http://wiki.eclipse.org/E4/EAS/Adapting_Objects if we can also do it in e4.
*
* TODO: Find replacement for E3 org.eclipse.ui.model.BaseWorkbenchContentProvider
* Check out org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider.
* See local project 'NotifyDomainEmf' about using EMF generated domain model classes.
*/
public class ChannelTreeProviders {
static class ChannelTreeContentProvider implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// cannot happen -- we always work on the same domain model (regardless of selections in other parts etc)
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof NotifyServices) {
NotifyServices allServices = (NotifyServices) inputElement;
return allServices.getServices().toArray();
}
System.out.println("*** ChannelTreeContentProvider#getElements(Object) called with unexpected arg=" + inputElement.getClass().getName());
return null;
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof NotifyServiceData) {
// a notify service node
return ((NotifyServiceData)parentElement).getChannels().toArray();
}
else if (parentElement instanceof ChannelData) {
// NC node
return ((ChannelData)parentElement).getStatistics().toArray();
}
else if (parentElement instanceof MCStatistics) {
return ((MCStatistics)parentElement).getChildren();
}
return null;
}
@Override
public Object getParent(Object element) {
if (element instanceof NotifyServices) {
return null;
}
else if (element instanceof NotifyServiceData) {
return null;
}
else if (element instanceof ChannelData) {
return ((ChannelData)element).getParent();
}
else if (element instanceof MCStatistics) {
return ((MCStatistics)element).getParent();
}
else if (element instanceof ChannelParticipantName) {
return ((ChannelParticipantName)element).getParent();
}
return null;
}
@Override
public boolean hasChildren(Object element) {
// If this is a performance problem, we already had it before,
// in org.eclipse.ui.model.BaseWorkbenchContentProvider.hasChildren(Object)
Object[] children = getChildren(element);
return ( children != null && children.length > 0 );
}
}
/**
* See http://www.vogella.com/articles/EclipseJFaceTree/article.html
*/
static class ChannelTreeLabelProvider extends StyledCellLabelProvider /* implements IFontProvider*/ {
// private FontRegistry registry = new FontRegistry();
// private final String systemFontSymbolicName = Display.getCurrent().getSystemFont().getFontData()[0].getName();
private final Map<String, Image> iconMap = new HashMap<String, Image>();
private final Styler ERROR_HIGHLIGHT_STYLER;
ChannelTreeLabelProvider() {
super();
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
String ERROR_HIGHLIGHT_STYLER_NAME = "custom_foreground_color";
colorRegistry.put(ERROR_HIGHLIGHT_STYLER_NAME, new RGB(255, 0, 0));
ERROR_HIGHLIGHT_STYLER = StyledString.createColorRegistryStyler(ERROR_HIGHLIGHT_STYLER_NAME, null);
}
@Override
public void update(ViewerCell cell) {
Object element = cell.getElement();
Image image = null;
StyledString text = new StyledString();
if (element instanceof NotifyServiceData) {
// a notify service node
image = getImageFromFile("fldr_obj.gif");
NotifyServiceData notifyServiceData = (NotifyServiceData) element;
text.append(notifyServiceData.getName());
if (!notifyServiceData.isReachable()) {
text.append(" Unreachable!", ERROR_HIGHLIGHT_STYLER);
}
}
else if (element instanceof ChannelData) {
// NC node
ChannelData channelData = (ChannelData) element;
// both 'Channel' and 'Class' start with a 'C'...
if (channelData.isNewNc()) {
image = getImageFromFile("newclass_wiz.gif");
}
else {
image = getImageFromFile("class_obj.gif");
}
text.append(channelData.getName());
}
else if (element instanceof MCStatistics) {
text.append(((MCStatistics)element).getStatistics());
if (element instanceof ChannelConsumers) {
// TODO find better icon
image = getImageFromFile("import_brkpts.gif");
}
else if (element instanceof ChannelSuppliers) {
// TODO find better icon
image = getImageFromFile("export_brkpts.gif");
}
}
else if (element instanceof ChannelParticipantName) {
text.append(((ChannelParticipantName)element).getName());
}
else {
text.append("unexpected tree node " + element.getClass(), ERROR_HIGHLIGHT_STYLER);
}
cell.setImage(image);
cell.setText(text.toString());
cell.setStyleRanges(text.getStyleRanges());
super.update(cell);
}
/**
* Helper Method to load the images.
*/
private Image getImageFromFile(String file) {
Image ret = iconMap.get(file);
if (ret == null) {
Bundle bundle = FrameworkUtil.getBundle(ChannelTreeLabelProvider.class);
URL url = FileLocator.find(bundle, new Path("icons/" + file), null);
ImageDescriptor image = ImageDescriptor.createFromURL(url);
ret = image.createImage();
iconMap.put(file, ret);
}
return ret;
}
// Uncomment this to show new NCs in bold font. Probably the Class / new Class icons we have are better though.
// @Override
// public Font getFont(Object element) {
// if (element instanceof ChannelData) {
// ChannelData channelData = (ChannelData)element;
// if (channelData.isNewNc()) {
// return registry.getBold(systemFontSymbolicName);
// }
// }
// return null;
// }
}
}