/*
* Copyright (c) 2004 Christopher Lenz and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* Christopher Lenz - initial implementation
*
* $Id: ProblemsLabelDecorator.java,v 1.3 2006-10-21 23:13:54 pombredanne Exp $
*/
package net.sourceforge.phpeclipse.ui.views.outline;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.phpeclipse.core.model.ISourceReference;
import net.sourceforge.phpeclipse.ui.WebUI;
import net.sourceforge.phpeclipse.ui.views.util.ImageDescriptorRegistry;
import net.sourceforge.phpeclipse.ui.views.util.ImageImageDescriptor;
import net.sourceforge.phpeclipse.ui.views.util.OverlayImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Label decorator for the outline page that adds error and warning overlay
* icons to elements in the outline. The information is retrieved from the
* annotation model corresponding to the input of the associated text editor.
*/
public class ProblemsLabelDecorator extends LabelProvider implements
ILabelDecorator {
// Constants ---------------------------------------------------------------
private static final String ANNOTATION_TYPE_ERROR = "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
private static final String ANNOTATION_TYPE_WARNING = "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
// Instance Variables ------------------------------------------------------
/** The associated text editor if the decorator is used in the outline. */
private ITextEditor editor;
/** Registry of icons and overlay icons. */
private ImageDescriptorRegistry registry = new ImageDescriptorRegistry();
// Constructors ------------------------------------------------------------
/**
* Constructor.
*
* @param editor
* the associated text editor
*/
public ProblemsLabelDecorator(ITextEditor editor) {
this.editor = editor;
}
// ILabelDecorator Implementation ------------------------------------------
/*
* @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
*/
public void dispose() {
super.dispose();
registry.dispose();
}
/*
* @see ILabelDecorator#decorateImage(Image, Object)
*/
public Image decorateImage(Image image, Object element) {
Annotation annotations[] = getAssociatedAnnotations((ISourceReference) element);
ImageDescriptor overlay = null;
for (int i = 0; i < annotations.length; i++) {
if (isError(annotations[i])) {
overlay = WebUI.getDefault().getImageRegistry().getDescriptor(
WebUI.ICON_OVERLAY_ERROR);
} else if (isWarning(annotations[i])) {
overlay = WebUI.getDefault().getImageRegistry().getDescriptor(
WebUI.ICON_OVERLAY_WARNING);
}
}
if (overlay != null) {
ImageDescriptor base = new ImageImageDescriptor(image);
return registry.get(new OverlayImageDescriptor(base,
new ImageDescriptor[][] { null, null, { overlay }, null },
null));
} else {
}
return image;
}
/*
* @see ILabelDecorator#decorateText(String, Object)
*/
public String decorateText(String text, Object element) {
return text;
}
// Private Methods ---------------------------------------------------------
/**
* Returns all annotations associated with the given model element.
*
* @param element
* the model element for which annotations should be collected
* @return an array containing all annotations for the given element, or an
* empty array if no annotations are found
*/
private Annotation[] getAssociatedAnnotations(ISourceReference element) {
List retVal = new ArrayList();
if (editor != null) {
IEditorInput input = editor.getEditorInput();
IAnnotationModel model = editor.getDocumentProvider()
.getAnnotationModel(input);
if (model != null) { // bug #1120670
for (Iterator i = model.getAnnotationIterator(); i.hasNext();) {
Annotation annotation = (Annotation) i.next();
Position pos = model.getPosition(annotation);
if (pos != null && isInside(pos.getOffset(), element)) {
retVal.add(annotation);
}
}
}
}
return (Annotation[]) retVal.toArray(new Annotation[retVal.size()]);
}
/**
* Determines whether the given annotation is an error.
*
* @param annotation
* the annotation to check
* @return true if the annotation is to be displayed as an error,
* false otherwise
*/
private boolean isError(Annotation annotation) {
return ANNOTATION_TYPE_ERROR.equals(annotation.getType());
}
/**
* Determines whether the given annotation is a warning.
*
* @param annotation
* the annotation to check
* @return true if the annotation is to be displayed as a
* warning, false otherwise
*/
private boolean isWarning(Annotation annotation) {
return ANNOTATION_TYPE_WARNING.equals(annotation.getType());
}
/**
* Tests if the given position is inside the source region of a model
* element.
*
* @param pos
* the position to be tested
* @param element
* the source element
* @return boolean true if position is located inside the
* element, otherwise false
*/
private boolean isInside(int pos, ISourceReference element) {
IRegion region = element.getSourceRegion();
if (region != null) {
int offset = region.getOffset();
return ((offset <= pos) && (offset + region.getLength() > pos));
}
return false;
}
}