blob: f6da7975f7090ac9e69a16aef958583a5f0da82b [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2015 itemis and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* itemis - Initial API and implementation
*
* </copyright>
*/
package org.eclipse.sphinx.emf.workspace.ui.decorators;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.ServiceCaller;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.IDecorationContext;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.sphinx.emf.workspace.ui.decorators.TreeItemDecorationCalculator.DecorationOverlayKind;
import org.eclipse.sphinx.emf.workspace.ui.internal.Activator;
import org.eclipse.sphinx.platform.resources.IProblemMarkerFinder;
import org.eclipse.sphinx.platform.util.PlatformLogUtil;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.decorators.DecorationBuilder;
/**
* An extensible {@link ILightweightLabelDecorator lightweight label decorator} implementation which can be used to
* decorate {@link TreeViewer tree viewer} items according to the {@link IMarker#PROBLEM problem markers} that relate to
* the tree item in question or to any of its direct or indirect {@link ITreeContentProvider#getChildren(Object)
* children}.
* <p>
* Requires an instance of {@link TreeItemDecorationCalculator} to calculate the decoration state of the given tree item
* and an instance of {@link IProblemMarkerFinder} to detect the problem markers for the given tree item as well as for
* its direct and indirect children.
* </p>
* <p>
* Assumes that the {@link ITreeContentProvider content provider} to be used to retrieve the direct and indirect
* children of the given tree item is made available through a {@link IDecorationContext#getProperties() decoration
* context property} named <code>org.eclipse.jface.viewers.ITreeContentProvider</code> that is stored on the
* {@link IDecoration decoration definition} passed to the {@link #decorate(Object, IDecoration)} method (see
* {@link #getContentProvider(IDecoration)} for details).
* </p>
*
* @see TreeItemDecorationCalculator
* @see IProblemMarkerFinder
*/
@SuppressWarnings("restriction")
public abstract class AbstractTreeContentProblemDecorator implements ILightweightLabelDecorator {
protected TreeItemDecorationCalculator decorationCalculator;
protected IResourceChangeListener problemMarkerChangeListener;
public AbstractTreeContentProblemDecorator() {
IProblemMarkerFinder problemMarkerFinder = createProblemMarkerFinder();
decorationCalculator = createDecorationCalculator(problemMarkerFinder);
problemMarkerChangeListener = createProblemMarkerChangeListener();
ServiceCaller.callOnce(getClass(), IWorkspace.class, ws -> {
ws.addResourceChangeListener(problemMarkerChangeListener, IResourceChangeEvent.POST_CHANGE);
});
}
protected abstract IProblemMarkerFinder createProblemMarkerFinder();
protected TreeItemDecorationCalculator createDecorationCalculator(IProblemMarkerFinder problemMarkerFinder) {
return new TreeItemDecorationCalculator(problemMarkerFinder);
}
/**
* Creates an {@link IResourceChangeListener} in order to wake up decoration of IContainer and IResource.
*/
protected IResourceChangeListener createProblemMarkerChangeListener() {
return new IResourceChangeListener() {
@Override
public void resourceChanged(IResourceChangeEvent event) {
Assert.isNotNull(event);
IMarkerDelta[] markerDelta = event.findMarkerDeltas(IMarker.PROBLEM, true);
if (markerDelta != null && markerDelta.length > 0) {
decorationCalculator.reset();
}
}
};
}
/*
* @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object,
* org.eclipse.jface.viewers.IDecoration)
*/
@Override
public void decorate(Object element, IDecoration decoration) {
ITreeContentProvider contentProvider = getContentProvider(decoration);
if (contentProvider != null) {
String overlayImageName = null;
DecorationOverlayKind overlayKind = decorationCalculator.getDecorationOverlayKind(contentProvider, element);
switch (overlayKind) {
case NONE:
break;
case WARNING:
overlayImageName = ISharedImages.IMG_DEC_FIELD_WARNING;
break;
case ERROR:
overlayImageName = ISharedImages.IMG_DEC_FIELD_ERROR;
break;
default:
PlatformLogUtil.logAsError(Activator.getPlugin(), new RuntimeException("Invalid decoration overlay kind: " + overlayKind)); //$NON-NLS-1$
break;
}
if (overlayImageName != null) {
ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
ImageDescriptor overlayImageDescriptor = sharedImages.getImageDescriptor(overlayImageName);
decoration.addOverlay(overlayImageDescriptor, IDecoration.BOTTOM_LEFT);
}
}
}
protected ITreeContentProvider getContentProvider(IDecoration decoration) {
if (decoration instanceof DecorationBuilder) {
DecorationBuilder builder = (DecorationBuilder) decoration;
IDecorationContext context = builder.getDecorationContext();
return (ITreeContentProvider) context.getProperty(ITreeContentProvider.class.getName());
}
return null;
}
/*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
*/
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
/*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
*/
@Override
public void addListener(ILabelProviderListener listener) {
}
/*
* @see
* org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
*/
@Override
public void removeListener(ILabelProviderListener listener) {
}
/*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
*/
@Override
public void dispose() {
ServiceCaller.callOnce(getClass(), IWorkspace.class, ws -> {
ws.removeResourceChangeListener(problemMarkerChangeListener);
});
}
}