org.eclipse.team.internal.ccvs.ui.CVSDecoration.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.team.internal.ccvs.ui.CVSDecoration.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.swt.graphics.*;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager;
import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.ui.ISharedImages;
import org.eclipse.team.ui.synchronize.TeamStateDescription;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.themes.ITheme;

/**
 * A decoration describes the annotations to a user interface element. The
 * annotations can apply to text (e.g. prefix, suffix, color, font) and to an
 * image (e.g. overlays).
 * <p>
 * This class is derived from an internal workbench class
 * <code>IDecoration</code> and is often used in conjunction with the label
 * decoration APIs. As such a client can convert between them using helpers
 * defined in this class.
 * </p>
 * TODO: 
 * profile
 * add colors and fonts to preferences instead of being hard coded
 * what to do with CVSDecorationConfiguration class?
 * preference page externalizations
 * preference page preview should update when theme changes
 * 
 * @since 3.1
 */
public class CVSDecoration {

    public static final int MODEL = 1000;

    // Decorations
    private String prefix;
    private String suffix;
    private ImageDescriptor overlay;
    private Color bkgColor;
    private Color fgColor;
    private Font font;

    // Properties
    private int resourceType = IResource.FILE;
    private boolean watchEditEnabled = false;
    private boolean isDirty = false;
    private boolean isIgnored = false;
    private boolean isAdded = false;
    private boolean isNewResource = false;
    private boolean hasRemote = false;
    private boolean readOnly = false;
    private boolean needsMerge = false;
    private boolean virtualFolder = false;
    private String tag;
    private String revision;
    private String repository;
    private ICVSRepositoryLocation location;
    private String keywordSubstitution;
    private int stateFlags;

    // Text formatters
    private String fileFormatter;
    private String folderFormatter;
    private String projectFormatter;

    //   Images cached for better performance
    private static ImageDescriptor dirty;
    private static ImageDescriptor checkedIn;
    private static ImageDescriptor noRemoteDir;
    private static ImageDescriptor added;
    private static ImageDescriptor merged;
    private static ImageDescriptor newResource;
    private static ImageDescriptor edited;

    // List of preferences used to configure the decorations that
    // are applied.
    private Preferences preferences;

    /*
     * Define a cached image descriptor which only creates the image data once
     */
    public static class CachedImageDescriptor extends ImageDescriptor {

        ImageDescriptor descriptor;
        ImageData data;

        public CachedImageDescriptor(ImageDescriptor descriptor) {
            Assert.isNotNull(descriptor);
            this.descriptor = descriptor;
        }

        public ImageData getImageData() {
            if (data == null) {
                data = descriptor.getImageData();
            }
            return data;
        }
    }

    static {
        dirty = new CachedImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DIRTY_OVR));
        checkedIn = new CachedImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CHECKEDIN_OVR));
        added = new CachedImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CHECKEDIN_OVR));
        merged = new CachedImageDescriptor(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_MERGED));
        newResource = new CachedImageDescriptor(
                CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_QUESTIONABLE));
        edited = new CachedImageDescriptor(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_EDITED));
        noRemoteDir = new CachedImageDescriptor(
                CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_NO_REMOTEDIR));
    }

    /**
     * Default constructor uses the plug-in's preferences to determine text decoration
     * formatters and preferences.
     */
    public CVSDecoration() {
        //    TODO: for efficiency don't look up a pref until its needed
        IPreferenceStore store = getStore();
        Preferences prefs = new Preferences();

        prefs.setValue(ICVSUIConstants.PREF_SHOW_DIRTY_DECORATION,
                store.getBoolean(ICVSUIConstants.PREF_SHOW_DIRTY_DECORATION));
        prefs.setValue(ICVSUIConstants.PREF_SHOW_ADDED_DECORATION,
                store.getBoolean(ICVSUIConstants.PREF_SHOW_ADDED_DECORATION));
        prefs.setValue(ICVSUIConstants.PREF_SHOW_HASREMOTE_DECORATION,
                store.getBoolean(ICVSUIConstants.PREF_SHOW_HASREMOTE_DECORATION));
        prefs.setValue(ICVSUIConstants.PREF_SHOW_NEWRESOURCE_DECORATION,
                store.getBoolean(ICVSUIConstants.PREF_SHOW_NEWRESOURCE_DECORATION));
        prefs.setValue(ICVSUIConstants.PREF_CALCULATE_DIRTY,
                store.getBoolean(ICVSUIConstants.PREF_CALCULATE_DIRTY));
        prefs.setValue(ICVSUIConstants.PREF_DIRTY_FLAG, store.getString(ICVSUIConstants.PREF_DIRTY_FLAG));
        prefs.setValue(ICVSUIConstants.PREF_ADDED_FLAG, store.getString(ICVSUIConstants.PREF_ADDED_FLAG));
        prefs.setValue(ICVSUIConstants.PREF_USE_FONT_DECORATORS,
                store.getString(ICVSUIConstants.PREF_USE_FONT_DECORATORS));

        initialize(prefs, store.getString(ICVSUIConstants.PREF_FILETEXT_DECORATION),
                store.getString(ICVSUIConstants.PREF_FOLDERTEXT_DECORATION),
                store.getString(ICVSUIConstants.PREF_PROJECTTEXT_DECORATION));
    }

    public CVSDecoration(Preferences preferences, String fileFormater, String folderFormatter,
            String projectFormatter) {
        initialize(preferences, fileFormater, folderFormatter, projectFormatter);
    }

    private IPreferenceStore getStore() {
        return CVSUIPlugin.getPlugin().getPreferenceStore();
    }

    private void initialize(Preferences preferences, String fileFormater, String folderFormatter,
            String projectFormatter) {
        this.preferences = preferences;
        this.fileFormatter = updateOldDirtyFlag(fileFormater);
        this.folderFormatter = updateOldDirtyFlag(folderFormatter);
        this.projectFormatter = updateOldDirtyFlag(projectFormatter);
    }

    //see bug 110022
    public static String updateOldDirtyFlag(String param) {
        return param.replaceAll(CVSDecoratorConfiguration.OLD_DIRTY_FLAG, CVSDecoratorConfiguration.NEW_DIRTY_FLAG);
    }

    public void addPrefix(String prefix) {
        this.prefix = prefix;
    }

    public void addSuffix(String suffix) {
        this.suffix = suffix;
    }

    public void setForegroundColor(Color fgColor) {
        this.fgColor = fgColor;
    }

    public void setBackgroundColor(Color bkgColor) {
        this.bkgColor = bkgColor;
    }

    public void setFont(Font font) {
        this.font = font;
    }

    public Color getBackgroundColor() {
        return bkgColor;
    }

    public Color getForegroundColor() {
        return fgColor;
    }

    public Font getFont() {
        return font;
    }

    public ImageDescriptor getOverlay() {
        return overlay;
    }

    public String getPrefix() {
        return prefix;
    }

    public String getSuffix() {
        return suffix;
    }

    public void setResourceType(int type) {
        this.resourceType = type;
    }

    public void apply(IDecoration decoration) {
        compute();
        // apply changes
        String suffix = getSuffix();
        if (suffix != null)
            decoration.addSuffix(suffix);
        String prefix = getPrefix();
        if (prefix != null)
            decoration.addPrefix(prefix);
        ImageDescriptor overlay = getOverlay();
        if (overlay != null)
            decoration.addOverlay(overlay);
        Color bc = getBackgroundColor();
        if (bc != null)
            decoration.setBackgroundColor(bc);
        Color fc = getForegroundColor();
        if (fc != null)
            decoration.setForegroundColor(fc);
        Font f = getFont();
        if (f != null)
            decoration.setFont(f);
    }

    public void compute() {
        computeText();
        overlay = computeImage();
        computeColorsAndFonts();
    }

    private void computeText() {
        if (isIgnored())
            return;
        Map bindings = new HashMap();
        if (isDirty()) {
            bindings.put(CVSDecoratorConfiguration.NEW_DIRTY_FLAG,
                    preferences.getString(ICVSUIConstants.PREF_DIRTY_FLAG));
        }
        if (isAdded()) {
            bindings.put(CVSDecoratorConfiguration.ADDED_FLAG,
                    preferences.getString(ICVSUIConstants.PREF_ADDED_FLAG));
        } else if (isHasRemote()) {
            bindings.put(CVSDecoratorConfiguration.FILE_REVISION, getRevision());
            bindings.put(CVSDecoratorConfiguration.RESOURCE_TAG, getTag());
        }
        bindings.put(CVSDecoratorConfiguration.FILE_KEYWORD, getKeywordSubstitution());
        if ((resourceType == IResource.FOLDER || resourceType == IResource.PROJECT) && location != null) {
            bindings.put(CVSDecoratorConfiguration.REMOTELOCATION_HOST, location.getHost());
            bindings.put(CVSDecoratorConfiguration.REMOTELOCATION_METHOD, location.getMethod().getName());
            bindings.put(CVSDecoratorConfiguration.REMOTELOCATION_USER, location.getUsername());
            bindings.put(CVSDecoratorConfiguration.REMOTELOCATION_ROOT, location.getRootDirectory());
            bindings.put(CVSDecoratorConfiguration.REMOTELOCATION_REPOSITORY, repository);

            RepositoryManager repositoryManager = CVSUIPlugin.getPlugin().getRepositoryManager();
            RepositoryRoot root = repositoryManager.getRepositoryRootFor(location);
            CVSUIPlugin.getPlugin().getRepositoryManager();
            String label = root.getName();
            if (label == null) {
                label = location.getLocation(true);
            }
            bindings.put(CVSDecoratorConfiguration.REMOTELOCATION_LABEL, label);
        }
        CVSDecoratorConfiguration.decorate(this, getTextFormatter(), bindings);
    }

    private ImageDescriptor computeImage() {
        // show newResource icon
        if (preferences.getBoolean(ICVSUIConstants.PREF_SHOW_NEWRESOURCE_DECORATION) && isNewResource()) {
            return newResource;
        }
        // show dirty icon
        if (preferences.getBoolean(ICVSUIConstants.PREF_SHOW_DIRTY_DECORATION) && isDirty()) {
            return dirty;
        }
        // show added
        if (preferences.getBoolean(ICVSUIConstants.PREF_SHOW_ADDED_DECORATION) && isAdded()) {
            return added;
        }
        // show watch edit
        if (isWatchEditEnabled() && resourceType == IResource.FILE && !isReadOnly() && isHasRemote()) {
            return edited;
        }
        if (needsMerge)
            return merged;
        // show checked in
        if (preferences.getBoolean(ICVSUIConstants.PREF_SHOW_HASREMOTE_DECORATION) && isHasRemote()) {
            if ((resourceType == IResource.FOLDER || resourceType == IResource.PROJECT) && isVirtualFolder()) {
                return noRemoteDir;
            }
            return checkedIn;
        }

        //nothing matched
        return null;
    }

    private void computeColorsAndFonts() {
        if (!preferences.getBoolean(ICVSUIConstants.PREF_USE_FONT_DECORATORS))
            return;

        ITheme current = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
        if (isIgnored()) {
            setBackgroundColor(current.getColorRegistry().get(CVSDecoratorConfiguration.IGNORED_BACKGROUND_COLOR));
            setForegroundColor(current.getColorRegistry().get(CVSDecoratorConfiguration.IGNORED_FOREGROUND_COLOR));
            setFont(current.getFontRegistry().get(CVSDecoratorConfiguration.IGNORED_FONT));
        } else if (isDirty()) {
            setBackgroundColor(
                    current.getColorRegistry().get(CVSDecoratorConfiguration.OUTGOING_CHANGE_BACKGROUND_COLOR));
            setForegroundColor(
                    current.getColorRegistry().get(CVSDecoratorConfiguration.OUTGOING_CHANGE_FOREGROUND_COLOR));
            setFont(current.getFontRegistry().get(CVSDecoratorConfiguration.OUTGOING_CHANGE_FONT));
        }
    }

    private String getTextFormatter() {
        switch (resourceType) {
        case IResource.FILE:
            return fileFormatter;
        case IResource.FOLDER:
            return folderFormatter;
        case IResource.PROJECT:
            return projectFormatter;
        case MODEL:
            return folderFormatter;
        }
        return "no format specified"; //$NON-NLS-1$
    }

    public boolean isAdded() {
        return isAdded;
    }

    public void setAdded(boolean isAdded) {
        this.isAdded = isAdded;
    }

    public boolean isDirty() {
        return isDirty;
    }

    public void setDirty(boolean isDirty) {
        this.isDirty = isDirty;
    }

    public boolean isIgnored() {
        return isIgnored;
    }

    public void setIgnored(boolean isIgnored) {
        this.isIgnored = isIgnored;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public boolean isWatchEditEnabled() {
        return watchEditEnabled;
    }

    public void setWatchEditEnabled(boolean watchEditEnabled) {
        this.watchEditEnabled = watchEditEnabled;
    }

    public boolean isNewResource() {
        return isNewResource;
    }

    public void setNewResource(boolean isNewResource) {
        this.isNewResource = isNewResource;
    }

    public void setLocation(ICVSRepositoryLocation location) {
        this.location = location;
    }

    public String getRevision() {
        return revision;
    }

    public void setRevision(String revision) {
        this.revision = revision;
    }

    public String getKeywordSubstitution() {
        return keywordSubstitution;
    }

    public void setKeywordSubstitution(String keywordSubstitution) {
        this.keywordSubstitution = keywordSubstitution;
    }

    public void setNeedsMerge(boolean needsMerge) {
        this.needsMerge = needsMerge;
    }

    public boolean isHasRemote() {
        return hasRemote;
    }

    public void setHasRemote(boolean hasRemote) {
        this.hasRemote = hasRemote;
    }

    public void setRepository(String repository) {
        this.repository = repository;
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    public boolean isVirtualFolder() {
        return virtualFolder;
    }

    public void setVirtualFolder(boolean virtualFolder) {
        this.virtualFolder = virtualFolder;
    }

    public void setStateFlags(int stateFlags) {
        this.stateFlags = stateFlags;
        if ((stateFlags & IThreeWayDiff.OUTGOING) != 0) {
            setDirty(true);
        }
    }

    public TeamStateDescription asTeamStateDescription(String[] properties) {
        TeamStateDescription desc = new CVSTeamStateDescription(stateFlags);
        Object o = computeImage();
        if (o != null && isRequestedProperty(properties, CVSTeamStateDescription.PROP_RESOURCE_STATE)) {
            desc.setProperty(CVSTeamStateDescription.PROP_RESOURCE_STATE, o);
        }
        if (tag != null && isRequestedProperty(properties, CVSTeamStateDescription.PROP_TAG)) {
            desc.setProperty(CVSTeamStateDescription.PROP_TAG, tag);
        }
        return desc;
    }

    private boolean isRequestedProperty(String[] properties, String property) {
        if (properties == null)
            return true;
        for (int i = 0; i < properties.length; i++) {
            String string = properties[i];
            if (string.equals(property))
                return true;
        }
        return false;
    }
}