Package org.erlide.ui.util

Source Code of org.erlide.ui.util.ProblemsLabelDecorator$ProblemsLabelChangedEvent

package org.erlide.ui.util;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.erlide.engine.model.erlang.ISourceRange;
import org.erlide.engine.model.erlang.ISourceReference;
import org.erlide.engine.model.root.IErlElement;
import org.erlide.ui.ErlideImage;
import org.erlide.ui.editors.erl.outline.ErlangElementImageDescriptor;
import org.erlide.ui.internal.ErlideUIPlugin;

public class ProblemsLabelDecorator implements ILabelDecorator,
        ILightweightLabelDecorator {

    /**
     * This is a special <code>LabelProviderChangedEvent</code> carrying
     * additional information whether the event origins from a maker change.
     * <p>
     * <code>ProblemsLabelChangedEvent</code>s are only generated by <code>
     * ProblemsLabelDecorator</code> s.
     * </p>
     */
    public static class ProblemsLabelChangedEvent extends LabelProviderChangedEvent {

        /**
         *
         */
        private static final long serialVersionUID = 1L;
        private final boolean fMarkerChange;

        /**
         * Note: This constructor is for internal use only. Clients should not
         * call this constructor.
         */
        public ProblemsLabelChangedEvent(final IBaseLabelProvider source,
                final IResource[] changedResource, final boolean isMarkerChange) {
            super(source, changedResource);
            fMarkerChange = isMarkerChange;
        }

        /**
         * Returns whether this event origins from marker changes. If
         * <code>false</code> an annotation model change is the origin. In this
         * case viewers not displaying working copies can ignore these events.
         *
         * @return if this event origins from a marker change.
         */
        public boolean isMarkerChange() {
            return fMarkerChange;
        }

    }

    private static final int ERRORTICK_WARNING = ErlangElementImageDescriptor.WARNING;
    private static final int ERRORTICK_ERROR = ErlangElementImageDescriptor.ERROR;
    private ListenerList fListeners;
    private IProblemChangedListener fProblemChangedListener;

    /*
     * Creates decorator with a shared image registry.
     *
     * @param registry The registry to use or <code>null</code> to use the
     * erlide plugin's image registry.
     */

    /**
     * Note: This method is for internal use only. Clients should not call this
     * method.
     *
     * @param obj
     *            the element to compute the flags for
     *
     * @return the adornment flags
     */
    protected int computeAdornmentFlags(final Object obj) {
        try {
            final ISourceReference r = obj instanceof ISourceReference ? (ISourceReference) obj
                    : null;
            if (obj instanceof IResource) {
                return getErrorTicksFromMarkers((IResource) obj,
                        IResource.DEPTH_INFINITE, r);
            } else if (obj instanceof IErlElement) {
                final IErlElement e = (IErlElement) obj;
                return getErrorTicksFromMarkers(e.getResource(),
                        IResource.DEPTH_INFINITE, r);
            }
        } catch (final CoreException e) {
            if (e.getStatus().getCode() == IResourceStatus.MARKER_NOT_FOUND) {
                return 0;
            }
        }
        return 0;
    }

    public static int getErrorTicksFromMarkers(final IResource res, final int depth,
            final ISourceReference sourceElement) throws CoreException {
        if (res == null || !res.isAccessible()) {
            return 0;
        }
        int severity = 0;
        if (sourceElement == null) {
            severity = res.findMaxProblemSeverity(IMarker.PROBLEM, true, depth);
        } else {
            final IMarker[] markers = res.findMarkers(IMarker.PROBLEM, true, depth);
            if (markers != null && markers.length > 0) {
                for (int i = 0; i < markers.length && severity != IMarker.SEVERITY_ERROR; i++) {
                    final IMarker curr = markers[i];
                    if (isMarkerInRange(curr, sourceElement)) {
                        final int val = curr.getAttribute(IMarker.SEVERITY, -1);
                        if (val == IMarker.SEVERITY_WARNING
                                || val == IMarker.SEVERITY_ERROR) {
                            severity = val;
                        }
                    }
                }
            }
        }
        if (severity == IMarker.SEVERITY_ERROR) {
            return ERRORTICK_ERROR;
        } else if (severity == IMarker.SEVERITY_WARNING) {
            return ERRORTICK_WARNING;
        }
        return 0;
    }

    private static boolean isMarkerInRange(final IMarker marker,
            final ISourceReference sourceElement) throws CoreException {
        final int pos = marker.getAttribute(IMarker.CHAR_START, -1);
        if (pos != -1) {
            return isInside(pos, sourceElement);
        }
        final int line = marker.getAttribute(IMarker.LINE_NUMBER, -1);
        if (line != -1) {
            return isInsideLines(line - 1, sourceElement);
        }
        return false;
    }

    // private boolean isInside(Position pos, ISourceReference sourceElement)
    // throws CoreException {
    // return pos != null && isInside(pos.getOffset(), sourceElement);
    // }

    private static boolean isInsideLines(final int line,
            final ISourceReference sourceElement) {
        return line >= sourceElement.getLineStart() && line <= sourceElement.getLineEnd();
    }

    /**
     * Tests if a position is inside the source range of an element.
     *
     * @param pos
     *            Position to be tested.
     * @param sourceElement
     *            Source element (must be a IErlElement)
     * @return boolean Return <code>true</code> if position is located inside
     *         the source element.
     * @throws CoreException
     *             Exception thrown if element range could not be accessed.
     *
     */
    protected static boolean isInside(final int pos, final ISourceReference sourceElement)
            throws CoreException {
        // if (fCachedRange == null) {
        // fCachedRange= sourceElement.getSourceRange();
        // }
        // ISourceRange range= fCachedRange;
        final ISourceRange range = sourceElement.getSourceRange();
        if (range != null) {
            final int rangeOffset = range.getOffset();
            return rangeOffset <= pos && rangeOffset + range.getLength() > pos;
        }
        return false;
    }

    @Override
    public void decorate(final Object element, final IDecoration decoration) {
        final int adornmentFlags = computeAdornmentFlags(element);
        if (adornmentFlags == ERRORTICK_ERROR) {
            decoration.addOverlay(ErlideImage.OVR_ERROR.getDescriptor());
        } else if (adornmentFlags == ERRORTICK_WARNING) {
            decoration.addOverlay(ErlideImage.OVR_WARNING.getDescriptor());
        }

    }

    @Override
    public void addListener(final ILabelProviderListener listener) {
        if (fListeners == null) {
            fListeners = new ListenerList();
        }
        fListeners.add(listener);
        if (fProblemChangedListener == null) {
            fProblemChangedListener = new IProblemChangedListener() {
                @Override
                public void problemsChanged(final IResource[] changedResources,
                        final boolean isMarkerChange) {
                    fireProblemsChanged(changedResources, isMarkerChange);
                }
            };
            ErlideUIPlugin.getDefault().getProblemMarkerManager()
                    .addListener(fProblemChangedListener);
        }
    }

    void fireProblemsChanged(final IResource[] changedResources,
            final boolean isMarkerChange) {
        if (fListeners != null && !fListeners.isEmpty()) {
            final LabelProviderChangedEvent event = new ProblemsLabelChangedEvent(this,
                    changedResources, isMarkerChange);
            final Object[] listeners = fListeners.getListeners();
            for (int i = 0; i < listeners.length; i++) {
                ((ILabelProviderListener) listeners[i]).labelProviderChanged(event);
            }
        }
    }

    @Override
    public void dispose() {
        if (fProblemChangedListener != null) {
            ErlideUIPlugin.getDefault().getProblemMarkerManager()
                    .removeListener(fProblemChangedListener);
            fProblemChangedListener = null;
        }
        // if (fRegistry != null && fUseNewRegistry) {
        // fRegistry.dispose();
        // }
    }

    @Override
    public boolean isLabelProperty(final Object element, final String property) {
        return true;
    }

    @Override
    public void removeListener(final ILabelProviderListener listener) {
        if (fListeners != null) {
            fListeners.remove(listener);
            if (fListeners.isEmpty() && fProblemChangedListener != null) {
                ErlideUIPlugin.getDefault().getProblemMarkerManager()
                        .removeListener(fProblemChangedListener);
                fProblemChangedListener = null;
            }
        }
    }

    @Override
    public String decorateText(final String text, final Object element) {
        return text;
    }

    @Override
    public Image decorateImage(final Image image, final Object obj) {
        final int adornmentFlags = computeAdornmentFlags(obj);
        if (adornmentFlags != 0) {
            final ImageDescriptor baseImage = new ImageImageDescriptor(image);
            final Rectangle bounds = image.getBounds();
            return ErlideUIPlugin.getImageDescriptorRegistry().get(
                    new ErlangElementImageDescriptor(baseImage, adornmentFlags,
                            new Point(bounds.width, bounds.height)));
        }
        return image;
    }

}
TOP

Related Classes of org.erlide.ui.util.ProblemsLabelDecorator$ProblemsLabelChangedEvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.