blob: b70a6d9c2dad164b4d5100dd5af8b1596f8fae90 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 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.jface.fieldassist;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.Image;
/**
* FieldDecorationRegistry is a common registry used to define shared field
* decorations within an application. Unlike resource registries, the
* FieldDecorationRegistry does not perform any lifecycle management of the
* decorations.
* </p>
* <p>
* Clients may specify images for the decorations in several different ways.
* Images may be described by their image id in a specified
* {@link ImageRegistry}. In this case, the life cycle of the image is managed
* by the image registry, and the decoration registry will not attempt to obtain
* an image from the image registry until the decoration is actually requested.
* In cases where the client has access to an already-created image, the image
* itself can be specified when registering the decoration. In this case, the
* life cycle should be managed by the specifying client.
* </p>
*
* @see FieldDecoration
* @see ImageRegistry
*
* @since 3.2
*/
public class FieldDecorationRegistry {
/**
* Decoration id for the decoration that should be used to cue the user that
* content proposals are available.
*/
public static final String DEC_CONTENT_PROPOSAL = "DEC_CONTENT_PROPOSAL"; //$NON-NLS-1$
/**
* Decoration id for the decoration that should be used to cue the user that
* a field is required.
*/
public static final String DEC_REQUIRED = "DEC_REQUIRED"; //$NON-NLS-1$
/**
* Decoration id for the decoration that should be used to cue the user that
* a field has an error.
*/
public static final String DEC_ERROR = "DEC_ERROR"; //$NON-NLS-1$
/**
* Decoration id for the decoration that should be used to cue the user that
* a field has a warning.
*/
public static final String DEC_WARNING = "DEC_WARNING"; //$NON-NLS-1$
/**
* Decoration id for the decoration that should be used to cue the user that
* a field has additional information.
*
* @since 3.3
*/
public static final String DEC_INFORMATION = "DEC_INFORMATION"; //$NON-NLS-1$
/**
* Decoration id for the decoration that should be used to cue the user that
* a field has an error with quick fix available.
*
* @since 3.3
*/
public static final String DEC_ERROR_QUICKFIX = "DEC_ERRORQUICKFIX"; //$NON-NLS-1$
/*
* Image id's
*/
private static final String IMG_DEC_FIELD_CONTENT_PROPOSAL = "org.eclipse.jface.fieldassist.IMG_DEC_FIELD_CONTENT_PROPOSAL"; //$NON-NLS-1$
private static final String IMG_DEC_FIELD_REQUIRED = "org.eclipse.jface.fieldassist.IMG_DEC_FIELD_REQUIRED"; //$NON-NLS-1$
private static final String IMG_DEC_FIELD_ERROR = "org.eclipse.jface.fieldassist.IMG_DEC_FIELD_ERROR"; //$NON-NLS-1$
private static final String IMG_DEC_FIELD_ERROR_QUICKFIX = "org.eclipse.jface.fieldassist.IMG_DEC_FIELD_ERROR_QUICKFIX"; //$NON-NLS-1$
private static final String IMG_DEC_FIELD_WARNING = "org.eclipse.jface.fieldassist.IMG_DEC_FIELD_WARNING"; //$NON-NLS-1$
private static final String IMG_DEC_FIELD_INFO = "org.eclipse.jface.fieldassist.IMG_DEC_FIELD_INFO"; //$NON-NLS-1$
/*
* Declare images and decorations immediately.
*/
static {
ImageRegistry imageRegistry = JFaceResources.getImageRegistry();
// Define the images used in the standard decorations.
imageRegistry.put(IMG_DEC_FIELD_CONTENT_PROPOSAL, ImageDescriptor
.createFromFile(FieldDecorationRegistry.class,
"images/contassist_ovr.gif"));//$NON-NLS-1$
imageRegistry.put(IMG_DEC_FIELD_ERROR, ImageDescriptor.createFromFile(
FieldDecorationRegistry.class, "images/error_ovr.gif"));//$NON-NLS-1$
imageRegistry.put(IMG_DEC_FIELD_WARNING, ImageDescriptor
.createFromFile(FieldDecorationRegistry.class,
"images/warn_ovr.gif"));//$NON-NLS-1$
imageRegistry.put(IMG_DEC_FIELD_REQUIRED, ImageDescriptor
.createFromFile(FieldDecorationRegistry.class,
"images/required_field_cue.gif"));//$NON-NLS-1$
imageRegistry.put(IMG_DEC_FIELD_ERROR_QUICKFIX, ImageDescriptor
.createFromFile(FieldDecorationRegistry.class,
"images/errorqf_ovr.gif"));//$NON-NLS-1$
imageRegistry.put(IMG_DEC_FIELD_INFO, ImageDescriptor
.createFromFile(FieldDecorationRegistry.class,
"images/info_ovr.gif"));//$NON-NLS-1$
// Define the standard decorations. Some do not have standard
// descriptions. Use null in these cases.
getDefault()
.registerFieldDecoration(
DEC_CONTENT_PROPOSAL,
JFaceResources
.getString("FieldDecorationRegistry.contentAssistMessage"), //$NON-NLS-1$
IMG_DEC_FIELD_CONTENT_PROPOSAL, imageRegistry);
getDefault().registerFieldDecoration(
DEC_ERROR,
JFaceResources
.getString("FieldDecorationRegistry.errorMessage"), //$NON-NLS-1$
IMG_DEC_FIELD_ERROR, imageRegistry);
getDefault().registerFieldDecoration(
DEC_ERROR_QUICKFIX,
JFaceResources
.getString("FieldDecorationRegistry.errorQuickFixMessage"), //$NON-NLS-1$
IMG_DEC_FIELD_ERROR_QUICKFIX, imageRegistry);
getDefault().registerFieldDecoration(DEC_WARNING, null,
IMG_DEC_FIELD_WARNING, imageRegistry);
getDefault().registerFieldDecoration(DEC_INFORMATION, null,
IMG_DEC_FIELD_INFO, imageRegistry);
getDefault()
.registerFieldDecoration(
DEC_REQUIRED,
JFaceResources
.getString("FieldDecorationRegistry.requiredFieldMessage"), //$NON-NLS-1$
IMG_DEC_FIELD_REQUIRED, imageRegistry);
}
/*
* Data structure that holds onto the decoration image info and description,
* and can produce a decorator on request.
*/
class Entry {
private String description;
private String imageId;
private ImageRegistry imageRegistry;
private Image image;
private FieldDecoration decoration;
Entry(String description, String imageId, ImageRegistry registry) {
this.description = description;
this.imageId = imageId;
this.imageRegistry = registry;
}
Entry(String description, Image image) {
this.description = description;
this.image = image;
}
FieldDecoration getDecoration() {
if (decoration == null) {
if (image == null) {
if (imageRegistry == null) {
imageRegistry = JFaceResources.getImageRegistry();
}
image = imageRegistry.get(imageId);
}
decoration = new FieldDecoration(image, description);
}
// Null out all other fields now that the decoration has an image
description = null;
imageId = null;
imageRegistry = null;
image = null;
return decoration;
}
}
/**
* Default instance of the registry. Applications may install their own
* registry.
*/
private static FieldDecorationRegistry defaultInstance;
/**
* Maximum width and height used by decorations in this registry. Clients
* may use these values to reserve space in dialogs for decorations or to
* adjust layouts so that decorated and non-decorated fields line up.
*/
private int maxDecorationWidth = 0;
private int maxDecorationHeight = 0;
private HashMap /* <String id, FieldDecoration> */decorations = new HashMap();
/**
* Get the default FieldDecorationRegistry.
*
* @return the singleton FieldDecorationRegistry that is used to manage
* shared field decorations.
*/
public static FieldDecorationRegistry getDefault() {
if (defaultInstance == null) {
defaultInstance = new FieldDecorationRegistry();
}
return defaultInstance;
}
/**
* Set the default FieldDecorationRegistry.
*
* @param defaultRegistry
* the singleton FieldDecorationRegistry that is used to manage
* shared field decorations.
*/
public static void setDefault(FieldDecorationRegistry defaultRegistry) {
defaultInstance = defaultRegistry;
}
/**
* Construct a FieldDecorationRegistry.
*/
public FieldDecorationRegistry() {
maxDecorationWidth = 0;
maxDecorationHeight = 0;
}
/**
* Get the maximum width (in pixels) of any decoration retrieved so far in
* the registry. This value changes as decorations are added and retrieved.
* This value can be used by clients to reserve space or otherwise compute
* margins when aligning non-decorated fields with decorated fields.
*
* @return the maximum width in pixels of any accessed decoration
*/
public int getMaximumDecorationWidth() {
return maxDecorationWidth;
}
/**
* Get the maximum height (in pixels) of any decoration retrieved so far in
* the registry. This value changes as decorations are added and retrieved.
* This value can be used by clients to reserve space or otherwise compute
* margins when aligning non-decorated fields with decorated fields.
*
*
* @return the maximum height in pixels of any accessed decoration
*/
public int getMaximumDecorationHeight() {
return maxDecorationHeight;
}
/**
* Registers a field decoration using the specified id. The lifecyle of the
* supplied image should be managed by the client. That is, it will never be
* disposed by this registry and the decoration should be removed from the
* registry if the image is ever disposed elsewhere.
*
* @param id
* the String id used to identify and access the decoration.
* @param description
* the String description to be used in the decoration, or
* <code>null</code> if the decoration has no description.
* @param image
* the image to be used in the decoration
*/
public void registerFieldDecoration(String id, String description,
Image image) {
decorations.put(id, new Entry(description, image));
// Recompute the maximums since this might be a replacement
recomputeMaximums();
}
/**
* Registers a field decoration using the specified id. An image id of an
* image located in the default JFaceResources image registry is supplied.
* The image will not be created until the decoration is requested.
*
* @param id
* the String id used to identify and access the decoration.
* @param description
* the String description to be used in the decoration, or
* <code>null</code> if the decoration has no description. *
* @param imageId
* the id of the image in the JFaceResources image registry that
* is used for this decorator
*/
public void registerFieldDecoration(String id, String description,
String imageId) {
decorations.put(id, new Entry(description, imageId, JFaceResources
.getImageRegistry()));
// Recompute the maximums as this could be a replacement of a previous
// image.
recomputeMaximums();
}
/**
* Registers a field decoration using the specified id. An image id and an
* image registry are supplied. The image will not be created until the
* decoration is requested.
*
* @param id
* the String id used to identify and access the decoration.
* @param description
* the String description to be used in the decoration, or
* <code>null</code> if the decoration has no description. *
* @param imageId
* the id of the image in the supplied image registry that is
* used for this decorator
* @param imageRegistry
* the registry used to obtain the image
*/
public void registerFieldDecoration(String id, String description,
String imageId, ImageRegistry imageRegistry) {
decorations.put(id, new Entry(description, imageId, imageRegistry));
// Recompute the maximums since this could be a replacement
recomputeMaximums();
}
/**
* Unregisters the field decoration with the specified id. No lifecycle
* management is performed on the decoration's image. This message has no
* effect if no field decoration with the specified id was previously
* registered.
* </p>
* <p>
* This method need not be called if the registered decoration's image is
* managed in an image registry. In that case, leaving the decoration in the
* registry will do no harm since the image will remain valid and will be
* properly disposed when the application is shut down. This method should
* be used in cases where the caller intends to dispose of the image
* referred to by the decoration, or otherwise determines that the
* decoration should no longer be used.
*
* @param id
* the String id of the decoration to be unregistered.
*/
public void unregisterFieldDecoration(String id) {
decorations.remove(id);
recomputeMaximums();
}
/**
* Returns the field decoration registered by the specified id .
*
* @param id
* the String id used to access the decoration.
* @return the FieldDecoration with the specified id, or <code>null</code>
* if there is no decoration with the specified id.
*/
public FieldDecoration getFieldDecoration(String id) {
Object entry = decorations.get(id);
if (entry == null) {
return null;
}
return ((Entry) entry).getDecoration();
}
/*
* The maximum decoration width and height must be recomputed. Typically
* called in response to adding, removing, or replacing a decoration.
*/
private void recomputeMaximums() {
Iterator entries = decorations.values().iterator();
maxDecorationHeight = 0;
maxDecorationWidth = 0;
while (entries.hasNext()) {
Image image = ((Entry)entries.next()).getDecoration().getImage();
if (image != null) {
maxDecorationHeight = Math.max(maxDecorationHeight, image.getBounds().height);
maxDecorationWidth = Math.max(maxDecorationWidth, image.getBounds().width);
}
}
}
}