001: /*******************************************************************************
002: * Copyright (c) 2004, 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.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.HashSet;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.Map;
018: import java.util.Set;
019:
020: import org.eclipse.core.commands.Command;
021: import org.eclipse.core.commands.CommandManager;
022: import org.eclipse.core.commands.contexts.ContextManager;
023: import org.eclipse.core.commands.contexts.ContextManagerEvent;
024: import org.eclipse.core.commands.contexts.IContextManagerListener;
025: import org.eclipse.jface.bindings.Binding;
026: import org.eclipse.jface.bindings.BindingManager;
027: import org.eclipse.jface.bindings.BindingManagerEvent;
028: import org.eclipse.jface.bindings.IBindingManagerListener;
029: import org.eclipse.jface.bindings.Scheme;
030: import org.eclipse.jface.bindings.TriggerSequence;
031: import org.eclipse.jface.bindings.keys.ParseException;
032: import org.eclipse.ui.commands.CommandManagerEvent;
033: import org.eclipse.ui.commands.ICategory;
034: import org.eclipse.ui.commands.ICommand;
035: import org.eclipse.ui.commands.ICommandManager;
036: import org.eclipse.ui.commands.ICommandManagerListener;
037: import org.eclipse.ui.commands.IKeyConfiguration;
038: import org.eclipse.ui.internal.handlers.LegacyHandlerWrapper;
039: import org.eclipse.ui.internal.keys.SchemeLegacyWrapper;
040: import org.eclipse.ui.internal.util.Util;
041: import org.eclipse.ui.keys.KeySequence;
042:
043: /**
044: * Provides support for the old <code>ICommandManager</code> interface.
045: *
046: * @since 3.1
047: */
048: public final class CommandManagerLegacyWrapper implements
049: ICommandManager,
050: org.eclipse.core.commands.ICommandManagerListener,
051: IBindingManagerListener, IContextManagerListener {
052:
053: /**
054: * Whether commands should print out information about which handlers are
055: * being executed. Change this value if you want console output on command
056: * execution.
057: */
058: public static boolean DEBUG_COMMAND_EXECUTION = false;
059:
060: /**
061: * Whether commands should print out information about handler changes.
062: * Change this value if you want console output when commands change
063: * handlers.
064: */
065: public static boolean DEBUG_HANDLERS = false;
066:
067: /**
068: * Which command should print out debugging information. Change this value
069: * if you want to only here when a command with a particular identifier
070: * changes its handler.
071: */
072: public static String DEBUG_HANDLERS_COMMAND_ID = null;
073:
074: static boolean validateKeySequence(KeySequence keySequence) {
075: if (keySequence == null) {
076: return false;
077: }
078: List keyStrokes = keySequence.getKeyStrokes();
079: int size = keyStrokes.size();
080: if (size == 0 || size > 4 || !keySequence.isComplete()) {
081: return false;
082: }
083: return true;
084: }
085:
086: /**
087: * The JFace binding machine that provides binding support for this
088: * workbench mutable command manager. This value will never be
089: * <code>null</code>.
090: *
091: * @since 3.1
092: */
093: private final BindingManager bindingManager;
094:
095: /**
096: * The command manager that provides functionality for this workbench
097: * command manager. This value will never be <code>null</code>.
098: *
099: * @since 3.1
100: */
101: private final CommandManager commandManager;
102:
103: private List commandManagerListeners;
104:
105: /**
106: * The context manager that provides functionality for this workbench
107: * command manager. This value will never be <code>null</code>.
108: *
109: * @since 3.1
110: */
111: private final ContextManager contextManager;
112:
113: /**
114: * Constructs a new instance of <code>MutableCommandManager</code>. The
115: * binding manager and command manager providing support for this manager
116: * are constructed at this time.
117: *
118: * @param bindingManager
119: * The binding manager providing support for the command manager;
120: * must not be <code>null</code>.
121: * @param commandManager
122: * The command manager providing support for this command
123: * manager; must not be <code>null</code>.
124: * @param contextManager
125: * The context manager to provide context support to this
126: * manager. This value must not be <code>null</code>.
127: *
128: */
129: public CommandManagerLegacyWrapper(
130: final BindingManager bindingManager,
131: final CommandManager commandManager,
132: final ContextManager contextManager) {
133: if (contextManager == null) {
134: throw new NullPointerException(
135: "The context manager cannot be null."); //$NON-NLS-1$
136: }
137: this .bindingManager = bindingManager;
138: this .commandManager = commandManager;
139: this .contextManager = contextManager;
140: }
141:
142: public final void addCommandManagerListener(
143: final ICommandManagerListener commandManagerListener) {
144: if (commandManagerListener == null) {
145: throw new NullPointerException(
146: "Cannot add a null listener."); //$NON-NLS-1$
147: }
148:
149: if (commandManagerListeners == null) {
150: commandManagerListeners = new ArrayList();
151: this .commandManager.addCommandManagerListener(this );
152: this .bindingManager.addBindingManagerListener(this );
153: this .contextManager.addContextManagerListener(this );
154: }
155:
156: if (!commandManagerListeners.contains(commandManagerListener)) {
157: commandManagerListeners.add(commandManagerListener);
158: }
159: }
160:
161: /*
162: * (non-Javadoc)
163: *
164: * @see org.eclipse.jface.bindings.IBindingManagerListener#bindingManagerChanged(org.eclipse.jface.bindings.BindingManagerEvent)
165: */
166: public final void bindingManagerChanged(
167: final BindingManagerEvent event) {
168: final boolean schemeDefinitionsChanged = event.getScheme() != null;
169: final Set previousSchemes;
170: if (schemeDefinitionsChanged) {
171: previousSchemes = new HashSet();
172: final Scheme scheme = event.getScheme();
173: final Scheme[] definedSchemes = event.getManager()
174: .getDefinedSchemes();
175: final int definedSchemesCount = definedSchemes.length;
176: for (int i = 0; i < definedSchemesCount; i++) {
177: final Scheme definedScheme = definedSchemes[0];
178: if ((definedScheme == scheme)
179: && (event.isSchemeDefined())) {
180: continue; // skip this one, it was just defined.
181: }
182: previousSchemes.add(definedSchemes[0].getId());
183: }
184: if (!event.isSchemeDefined()) {
185: previousSchemes.add(scheme.getId());
186: }
187: } else {
188: previousSchemes = null;
189: }
190:
191: fireCommandManagerChanged(new CommandManagerEvent(this , false,
192: event.isActiveSchemeChanged(), event.isLocaleChanged(),
193: event.isPlatformChanged(), false, false,
194: schemeDefinitionsChanged, null, null, previousSchemes));
195: }
196:
197: /*
198: * (non-Javadoc)
199: *
200: * @see org.eclipse.commands.ICommandManagerListener#commandManagerChanged(org.eclipse.commands.CommandManagerEvent)
201: */
202: public final void commandManagerChanged(
203: final org.eclipse.core.commands.CommandManagerEvent event) {
204: // Figure out the set of previous category identifiers.
205: final boolean categoryIdsChanged = event.isCategoryChanged();
206: final Set previousCategoryIds;
207: if (categoryIdsChanged) {
208: previousCategoryIds = new HashSet(commandManager
209: .getDefinedCategoryIds());
210: final String categoryId = event.getCategoryId();
211: if (event.isCategoryDefined()) {
212: previousCategoryIds.remove(categoryId);
213: } else {
214: previousCategoryIds.add(categoryId);
215: }
216: } else {
217: previousCategoryIds = null;
218: }
219:
220: // Figure out the set of previous command identifiers.
221: final boolean commandIdsChanged = event.isCommandChanged();
222: final Set previousCommandIds;
223: if (commandIdsChanged) {
224: previousCommandIds = new HashSet(commandManager
225: .getDefinedCommandIds());
226: final String commandId = event.getCommandId();
227: if (event.isCommandDefined()) {
228: previousCommandIds.remove(commandId);
229: } else {
230: previousCommandIds.add(commandId);
231: }
232: } else {
233: previousCommandIds = null;
234: }
235:
236: fireCommandManagerChanged(new CommandManagerEvent(this , false,
237: false, false, false, categoryIdsChanged,
238: commandIdsChanged, false, previousCategoryIds,
239: previousCommandIds, null));
240: }
241:
242: public final void contextManagerChanged(
243: final ContextManagerEvent event) {
244: fireCommandManagerChanged(new CommandManagerEvent(this , event
245: .isActiveContextsChanged(), false, false, false, false,
246: false, false, null, null, null));
247: }
248:
249: private void fireCommandManagerChanged(
250: CommandManagerEvent commandManagerEvent) {
251: if (commandManagerEvent == null) {
252: throw new NullPointerException();
253: }
254: if (commandManagerListeners != null) {
255: for (int i = 0; i < commandManagerListeners.size(); i++) {
256: ((ICommandManagerListener) commandManagerListeners
257: .get(i))
258: .commandManagerChanged(commandManagerEvent);
259: }
260: }
261: }
262:
263: public Set getActiveContextIds() {
264: return contextManager.getActiveContextIds();
265: }
266:
267: public String getActiveKeyConfigurationId() {
268: final Scheme scheme = bindingManager.getActiveScheme();
269: if (scheme != null) {
270: return scheme.getId();
271: }
272:
273: /*
274: * TODO This is possibly a breaking change. The id should be non-null,
275: * and presumably, a real scheme id.
276: */
277: return Util.ZERO_LENGTH_STRING;
278: }
279:
280: public String getActiveLocale() {
281: return bindingManager.getLocale();
282: }
283:
284: public String getActivePlatform() {
285: return bindingManager.getPlatform();
286: }
287:
288: public ICategory getCategory(String categoryId) {
289: // TODO Provide access to the categories.
290: // return new CategoryWrapper(commandManager.getCategory(categoryId));
291: return null;
292: }
293:
294: public ICommand getCommand(String commandId) {
295: final Command command = commandManager.getCommand(commandId);
296: return new CommandLegacyWrapper(command, bindingManager);
297: }
298:
299: /*
300: * (non-Javadoc)
301: *
302: * @see org.eclipse.ui.commands.ICommandManager#getDefinedCategoryIds()
303: */
304: public Set getDefinedCategoryIds() {
305: return commandManager.getDefinedCategoryIds();
306: }
307:
308: public Set getDefinedCommandIds() {
309: return commandManager.getDefinedCommandIds();
310: }
311:
312: public Set getDefinedKeyConfigurationIds() {
313: final Set definedIds = new HashSet();
314: final Scheme[] schemes = bindingManager.getDefinedSchemes();
315: for (int i = 0; i < schemes.length; i++) {
316: definedIds.add(schemes[i].getId());
317: }
318: return definedIds;
319: }
320:
321: public IKeyConfiguration getKeyConfiguration(
322: String keyConfigurationId) {
323: final Scheme scheme = bindingManager
324: .getScheme(keyConfigurationId);
325: return new SchemeLegacyWrapper(scheme, bindingManager);
326: }
327:
328: public Map getPartialMatches(KeySequence keySequence) {
329: try {
330: final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence
331: .getInstance(keySequence.toString());
332: final Map partialMatches = bindingManager
333: .getPartialMatches(sequence);
334: final Map returnValue = new HashMap();
335: final Iterator matchItr = partialMatches.entrySet()
336: .iterator();
337: while (matchItr.hasNext()) {
338: final Map.Entry entry = (Map.Entry) matchItr.next();
339: final TriggerSequence trigger = (TriggerSequence) entry
340: .getKey();
341: if (trigger instanceof org.eclipse.jface.bindings.keys.KeySequence) {
342: final org.eclipse.jface.bindings.keys.KeySequence triggerKey = (org.eclipse.jface.bindings.keys.KeySequence) trigger;
343: returnValue.put(KeySequence.getInstance(triggerKey
344: .toString()), entry.getValue());
345: }
346: }
347: return returnValue;
348: } catch (final ParseException e) {
349: return new HashMap();
350: } catch (final org.eclipse.ui.keys.ParseException e) {
351: return new HashMap();
352: }
353: }
354:
355: public String getPerfectMatch(KeySequence keySequence) {
356: try {
357: final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence
358: .getInstance(keySequence.toString());
359: final Binding binding = bindingManager
360: .getPerfectMatch(sequence);
361: if (binding == null) {
362: return null;
363: }
364:
365: return binding.getParameterizedCommand().getId();
366:
367: } catch (final ParseException e) {
368: return null;
369: }
370: }
371:
372: public boolean isPartialMatch(KeySequence keySequence) {
373: try {
374: final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence
375: .getInstance(keySequence.toString());
376: return bindingManager.isPartialMatch(sequence);
377: } catch (final ParseException e) {
378: return false;
379: }
380: }
381:
382: public boolean isPerfectMatch(KeySequence keySequence) {
383: try {
384: final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence
385: .getInstance(keySequence.toString());
386: return bindingManager.isPerfectMatch(sequence);
387: } catch (final ParseException e) {
388: return false;
389: }
390: }
391:
392: public void removeCommandManagerListener(
393: ICommandManagerListener commandManagerListener) {
394: if (commandManagerListener == null) {
395: throw new NullPointerException(
396: "Cannot remove a null listener"); //$NON-NLS-1$
397: }
398:
399: if (commandManagerListeners != null) {
400: commandManagerListeners.remove(commandManagerListener);
401: if (commandManagerListeners.isEmpty()) {
402: commandManagerListeners = null;
403: this .commandManager.removeCommandManagerListener(this );
404: this .bindingManager.removeBindingManagerListener(this );
405: this .contextManager.removeContextManagerListener(this );
406: }
407: }
408: }
409:
410: /**
411: * Updates the handlers for a block of commands all at once.
412: *
413: * @param handlersByCommandId
414: * The map of command identifier (<code>String</code>) to
415: * handler (<code>IHandler</code>).
416: */
417: public final void setHandlersByCommandId(
418: final Map handlersByCommandId) {
419: // Wrap legacy handlers so they can be passed to the new API.
420: final Iterator entryItr = handlersByCommandId.entrySet()
421: .iterator();
422: while (entryItr.hasNext()) {
423: final Map.Entry entry = (Map.Entry) entryItr.next();
424: final Object handler = entry.getValue();
425: if (handler instanceof org.eclipse.ui.commands.IHandler) {
426: final String commandId = (String) entry.getKey();
427: handlersByCommandId
428: .put(
429: commandId,
430: new LegacyHandlerWrapper(
431: (org.eclipse.ui.commands.IHandler) handler));
432: }
433: }
434:
435: commandManager.setHandlersByCommandId(handlersByCommandId);
436: }
437: }
|