/******************************************************************************* * Copyright (c) 2000, 2005 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.gef; import java.util.HashMap; import java.util.Map; import org.eclipse.swt.events.KeyEvent; import org.eclipse.jface.action.IAction; /** * The KeyHandler should handle all normal keystrokes on an <code>EditPartViewer</code>. * <I>Normal</i> is simply defined as keystrokes which are not associated with an * Accelerator on the Menu. The KeyHandler will be forwarded KeyEvents by the active Tool, * which is usually the SelectionTool. The Tool may be in a state where keystrokes should * not be processed, in which case it will not forward the keystrokes. For this reason, * it is important to always handle KeyEvents by using a KeyHandler. * <P> * KeyHandlers can be chained by calling {@link #setParent(KeyHandler)}. If this * KeyHandler does not handle the keystroke, it will pass the keystroke to its * <i>parent</i> KeyHandler. * <P> * KeyHandlers can be implemented using two stragegies. One is to map {@link KeyStroke * KeyStrokes} to {@link org.eclipse.jface.action.IAction Actions} using the {@link * #put(KeyStroke, IAction)} and {@link #remove(KeyStroke)} API. The other is to subclass * KeyHandler, and override various methods. A combination of the two is also useful. * @since 2.0 */ public class KeyHandler { private Map actions; private KeyHandler parent; /** * Processes a <i>key pressed</i> event. This method is called by the Tool whenever a key * is pressed, and the Tool is in the proper state. * @param event the KeyEvent * @return <code>true</code> if KeyEvent was handled in some way */ public boolean keyPressed(KeyEvent event) { if (performStroke(new KeyStroke(event, true))) { event.doit = false; return true; } return parent != null && parent.keyPressed(event); } /** * Processes a <i>key released</i> event. This method is called by the Tool whenever a key * is released, and the Tool is in the proper state. * @param event the KeyEvent * @return <code>true</code> if KeyEvent was handled in some way */ public boolean keyReleased(KeyEvent event) { if (performStroke(new KeyStroke(event, false))) return true; return parent != null && parent.keyReleased(event); } private boolean performStroke(KeyStroke key) { if (actions == null) return false; IAction action = (IAction)actions.get(key); if (action == null) return false; if (action.isEnabled()) action.run(); return true; } /** * Maps a specified <code>KeyStroke</code> to an <code>IAction</code>. When a KeyEvent * occurs matching the given KeyStroke, the Action will be <code>run()</code> iff it is * enabled. * @param keystroke the KeyStroke * @param action the Action to run */ public void put(KeyStroke keystroke, IAction action) { if (actions == null) actions = new HashMap(); actions.put(keystroke, action); } /** * Removed a mapped <code>IAction</code> for the specified <code>KeyStroke</code>. * @param keystroke the KeyStroke to be unmapped */ public void remove(KeyStroke keystroke) { if (actions != null) actions.remove(keystroke); } /** * Sets a <i>parent</i> <code>KeyHandler</code> to which this KeyHandler will forward * un-consumed KeyEvents. This KeyHandler will first attempt to handle KeyEvents. If it * does not recognize a given KeyEvent, that event is passed to its <i>parent</i> * @param parent the <i>parent</i> KeyHandler * @return <code>this</code> for convenience */ public KeyHandler setParent(KeyHandler parent) { this.parent = parent; return this; } }