001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.commands;
011:
012: import java.net.URL;
013: import java.util.HashMap;
014: import java.util.HashSet;
015: import java.util.Map;
016: import java.util.Set;
017:
018: import org.eclipse.core.commands.common.EventManager;
019: import org.eclipse.jface.resource.ImageDescriptor;
020:
021: /**
022: * <p>
023: * A central lookup facility for images for commands. Images can be associated
024: * with commands using this manager.
025: * </p>
026: * <p>
027: * Clients may instantiate, but must not extend.
028: * </p>
029: * <p>
030: * <strong>PROVISIONAL</strong>. This class or interface has been added as
031: * part of a work in progress. There is a guarantee neither that this API will
032: * work nor that it will remain the same. Please do not use this API without
033: * consulting with the Platform/UI team.
034: * </p>
035: * <p>
036: * This class is eventually intended to exist in
037: * <code>org.eclipse.jface.commands</code>.
038: * </p>
039: *
040: * @since 3.2
041: */
042: public final class CommandImageManager extends EventManager {
043:
044: /**
045: * The type of image to display in the default case.
046: */
047: public static final int TYPE_DEFAULT = 0;
048:
049: /**
050: * The type of image to display if the corresponding command is disabled.
051: */
052: public static final int TYPE_DISABLED = 1;
053:
054: /**
055: * The type of image to display if the mouse is hovering over the command
056: * and the command is enabled.
057: */
058: public static final int TYPE_HOVER = 2;
059:
060: /**
061: * The map of command identifiers (<code>String</code>) to images. The
062: * images are an array indexed by type. The values in the array are either
063: * an <code>ImageDescriptor</code> or a <code>Map</code> of style (<code>String</code>)
064: * to <code>ImageDescriptor</code>.
065: */
066: private final Map imagesById = new HashMap();
067:
068: /**
069: * Adds a listener to this command image manager. The listener will be
070: * notified when the set of image bindings changes. This can be used to
071: * track the global appearance and disappearance of image bindings.
072: *
073: * @param listener
074: * The listener to attach; must not be <code>null</code>.
075: */
076: public final void addCommandImageManagerListener(
077: final ICommandImageManagerListener listener) {
078: addListenerObject(listener);
079: }
080:
081: /**
082: * Binds a particular image path to a command id, type and style triple
083: *
084: * @param commandId
085: * The identifier of the command to which the image should be
086: * bound; must not be <code>null</code>.
087: * @param type
088: * The type of image to retrieve. This value must be one of the
089: * <code>TYPE</code> constants defined in this class.
090: * @param style
091: * The style of the image; may be <code>null</code>.
092: * @param url
093: * The URL to the image. Should not be <code>null</code>.
094: */
095: public final void bind(final String commandId, final int type,
096: final String style, final URL url) {
097: final ImageDescriptor descriptor = ImageDescriptor
098: .createFromURL(url);
099: bind(commandId, type, style, descriptor);
100: }
101:
102: /**
103: * Binds a particular image path to a command id, type and style triple
104: *
105: * @param commandId
106: * The identifier of the command to which the image should be
107: * bound; must not be <code>null</code>.
108: * @param type
109: * The type of image to retrieve. This value must be one of the
110: * <code>TYPE</code> constants defined in this class.
111: * @param style
112: * The style of the image; may be <code>null</code>.
113: * @param descriptor
114: * The image descriptor. Should not be <code>null</code>.
115: */
116: public final void bind(final String commandId, final int type,
117: final String style, final ImageDescriptor descriptor) {
118: Object[] images = (Object[]) imagesById.get(commandId);
119: if (images == null) {
120: images = new Object[3];
121: imagesById.put(commandId, images);
122: }
123:
124: if ((type < 0) || (type >= images.length)) {
125: throw new IllegalArgumentException(
126: "The type must be one of TYPE_DEFAULT, TYPE_DISABLED and TYPE_HOVER."); //$NON-NLS-1$
127: }
128:
129: final Object typedImage = images[type];
130: if (style == null) {
131: if ((typedImage == null)
132: || (typedImage instanceof ImageDescriptor)) {
133: images[type] = descriptor;
134: } else if (typedImage instanceof Map) {
135: final Map styleMap = (Map) typedImage;
136: styleMap.put(style, descriptor);
137: }
138: } else {
139: if (typedImage instanceof Map) {
140: final Map styleMap = (Map) typedImage;
141: styleMap.put(style, descriptor);
142: } else if (typedImage instanceof ImageDescriptor) {
143: final Map styleMap = new HashMap();
144: styleMap.put(null, typedImage);
145: styleMap.put(style, descriptor);
146: images[type] = descriptor;
147: }
148: }
149:
150: fireManagerChanged(new CommandImageManagerEvent(this ,
151: new String[] { commandId }, type, style));
152: }
153:
154: /**
155: * Removes all of the images from this manager.
156: */
157: public final void clear() {
158: imagesById.clear();
159: if (isListenerAttached()) {
160: final String[] commandIds = (String[]) imagesById.keySet()
161: .toArray(new String[imagesById.size()]);
162: fireManagerChanged(new CommandImageManagerEvent(this ,
163: commandIds, TYPE_DEFAULT, null));
164: }
165: }
166:
167: /**
168: * Notifies all of the listeners to this manager that the image bindings
169: * have changed.
170: *
171: * @param event
172: * The event to send to all of the listeners; must not be
173: * <code>null</code>.
174: */
175: private final void fireManagerChanged(
176: final CommandImageManagerEvent event) {
177: if (event == null) {
178: throw new NullPointerException();
179: }
180:
181: final Object[] listeners = getListeners();
182: for (int i = 0; i < listeners.length; i++) {
183: final ICommandImageManagerListener listener = (ICommandImageManagerListener) listeners[i];
184: listener.commandImageManagerChanged(event);
185: }
186: }
187:
188: /**
189: * Generates a style tag that is not currently used for the given command.
190: * This can be used by applications trying to create a unique style for a
191: * new set of images.
192: *
193: * @param commandId
194: * The identifier of the command for which a unique style is
195: * required; must not be <code>null</code>.
196: * @return A style tag that is not currently used; may be <code>null</code>.
197: */
198: public final String generateUnusedStyle(final String commandId) {
199: final Object[] existingImages = (Object[]) imagesById
200: .get(commandId);
201: if (existingImages == null) {
202: return null;
203: }
204:
205: final Set existingStyles = new HashSet(3);
206: for (int type = 0; type < existingImages.length; type++) {
207: final Object styledImages = existingImages[type];
208: if (styledImages instanceof ImageDescriptor) {
209: existingStyles.add(null);
210: } else if (styledImages instanceof Map) {
211: final Map styleMap = (Map) styledImages;
212: existingStyles.addAll(styleMap.keySet());
213: }
214: }
215:
216: if (!existingStyles.contains(null)) {
217: return null;
218: }
219:
220: String generatedStyle = "AUTOGEN:::"; //$NON-NLS-1$
221: int index = 0;
222: while (existingStyles.contains(generatedStyle)) {
223: generatedStyle += (index++ % 10);
224: }
225:
226: return generatedStyle;
227: }
228:
229: /**
230: * Retrieves the default image associated with the given command in the
231: * default style.
232: *
233: * @param commandId
234: * The identifier to find; must not be <code>null</code>.
235: * @return An image appropriate for the given command; never
236: * <code>null</code>.
237: */
238: public final ImageDescriptor getImageDescriptor(
239: final String commandId) {
240: return getImageDescriptor(commandId, TYPE_DEFAULT, null);
241: }
242:
243: /**
244: * Retrieves the image of the given type associated with the given command
245: * in the default style.
246: *
247: * @param commandId
248: * The identifier to find; must not be <code>null</code>.
249: * @param type
250: * The type of image to retrieve. This value must be one of the
251: * <code>TYPE</code> constants defined in this class.
252: * @return An image appropriate for the given command; <code>null</code>
253: * if the given image type cannot be found.
254: */
255: public final ImageDescriptor getImageDescriptor(
256: final String commandId, final int type) {
257: return getImageDescriptor(commandId, type, null);
258: }
259:
260: /**
261: * Retrieves the image of the given type associated with the given command
262: * in the given style.
263: *
264: * @param commandId
265: * The identifier to find; must not be <code>null</code>.
266: * @param type
267: * The type of image to retrieve. This value must be one of the
268: * <code>TYPE</code> constants defined in this class.
269: * @param style
270: * The style of the image to retrieve; may be <code>null</code>.
271: * @return An image appropriate for the given command; <code>null</code>
272: * if the given image style and type cannot be found.
273: */
274: public final ImageDescriptor getImageDescriptor(
275: final String commandId, final int type, final String style) {
276: if (commandId == null) {
277: throw new NullPointerException();
278: }
279:
280: final Object[] images = (Object[]) imagesById.get(commandId);
281: if (images == null) {
282: return null;
283: }
284:
285: if ((type < 0) || (type >= images.length)) {
286: throw new IllegalArgumentException(
287: "The type must be one of TYPE_DEFAULT, TYPE_DISABLED and TYPE_HOVER."); //$NON-NLS-1$
288: }
289:
290: Object typedImage = images[type];
291:
292: if (typedImage == null) {
293: typedImage = images[TYPE_DEFAULT];
294: }
295:
296: if (typedImage instanceof ImageDescriptor) {
297: return (ImageDescriptor) typedImage;
298: }
299:
300: if (typedImage instanceof Map) {
301: final Map styleMap = (Map) typedImage;
302: Object styledImage = styleMap.get(style);
303: if (styledImage instanceof ImageDescriptor) {
304: return (ImageDescriptor) styledImage;
305: }
306:
307: if (style != null) {
308: styledImage = styleMap.get(null);
309: if (styledImage instanceof ImageDescriptor) {
310: return (ImageDescriptor) styledImage;
311: }
312: }
313: }
314:
315: return null;
316: }
317:
318: /**
319: * Retrieves the default image associated with the given command in the
320: * given style.
321: *
322: * @param commandId
323: * The identifier to find; must not be <code>null</code>.
324: * @param style
325: * The style of the image to retrieve; may be <code>null</code>.
326: * @return An image appropriate for the given command; <code>null</code>
327: * if the given image style cannot be found.
328: */
329: public final ImageDescriptor getImageDescriptor(
330: final String commandId, final String style) {
331: return getImageDescriptor(commandId, TYPE_DEFAULT, style);
332: }
333:
334: /**
335: * Removes a listener from this command image manager.
336: *
337: * @param listener
338: * The listener to be removed; must not be <code>null</code>.
339: */
340: public final void removeCommandImageManagerListener(
341: final ICommandImageManagerListener listener) {
342: removeListenerObject(listener);
343: }
344: }
|