blob: 06fbde3e5841e4c611a8025402f112958efa80da [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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;
}
}