1 /******************************************************************************* 2 * Copyright (c) 2011 Google, Inc. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Google, Inc. - initial API and implementation 10 *******************************************************************************/ 11 package org.eclipse.wb.internal.core.utils.binding.editors.controls; 12 13 import com.google.common.collect.Lists; 14 15 import org.eclipse.core.commands.AbstractHandler; 16 import org.eclipse.core.commands.ExecutionEvent; 17 import org.eclipse.core.commands.ExecutionException; 18 import org.eclipse.core.commands.IHandler; 19 import org.eclipse.core.expressions.EvaluationResult; 20 import org.eclipse.core.expressions.Expression; 21 import org.eclipse.core.expressions.ExpressionInfo; 22 import org.eclipse.core.expressions.IEvaluationContext; 23 import org.eclipse.core.runtime.CoreException; 24 import org.eclipse.swt.events.DisposeEvent; 25 import org.eclipse.swt.events.DisposeListener; 26 import org.eclipse.swt.events.FocusEvent; 27 import org.eclipse.swt.events.FocusListener; 28 import org.eclipse.swt.widgets.Control; 29 import org.eclipse.ui.ISources; 30 import org.eclipse.ui.PlatformUI; 31 import org.eclipse.ui.handlers.IHandlerActivation; 32 import org.eclipse.ui.handlers.IHandlerService; 33 import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; 34 35 import java.util.List; 36 37 /** 38 * Manager for installing/unistalling global handlers for {@link Control} actions commands. 39 * 40 * @author sablin_aa 41 * @author mitin_aa 42 */ 43 public abstract class AbstractControlActionsManager { 44 @SuppressWarnings("deprecation") 45 protected final Object[] COMMAND_HANDLER_IDS = new Object[]{ 46 IWorkbenchActionDefinitionIds.COPY, 47 IWorkbenchActionDefinitionIds.CUT, 48 IWorkbenchActionDefinitionIds.PASTE, 49 IWorkbenchActionDefinitionIds.DELETE, 50 IWorkbenchActionDefinitionIds.SELECT_ALL, 51 IWorkbenchActionDefinitionIds.UNDO, 52 IWorkbenchActionDefinitionIds.REDO}; 53 //////////////////////////////////////////////////////////////////////////// 54 // 55 // Constructor 56 // 57 //////////////////////////////////////////////////////////////////////////// 58 protected final Control m_control; 59 private boolean m_active = false; 60 61 public AbstractControlActionsManager(final Control control) { 62 m_control = control; 63 m_control.addFocusListener(new FocusListener() { 64 @Override 65 public void focusGained(FocusEvent e) { 66 activateHandlers(); 67 m_active = true; 68 } 69 70 @Override 71 public void focusLost(FocusEvent e) { 72 deactivateHandlers(); 73 m_active = false; 74 } 75 }); 76 m_control.addDisposeListener(new DisposeListener() { 77 @Override 78 public void widgetDisposed(DisposeEvent e) { 79 if (m_active) { 80 // deactivate on dispose 81 deactivateHandlers(); 82 } 83 } 84 }); 85 } 86 87 //////////////////////////////////////////////////////////////////////////// 88 // 89 // Handlers 90 // 91 //////////////////////////////////////////////////////////////////////////// 92 protected static final IHandler EMPTY_HANDLER = new AbstractHandler() { 93 @Override 94 public Object execute(ExecutionEvent event) throws ExecutionException { 95 // do nothing 96 return null; 97 } 98 99 @Override 100 public boolean isEnabled() { 101 // of course, it is enabled ;) 102 return true; 103 } 104 105 @Override 106 public boolean isHandled() { 107 // we do not handle the actions; since action not handled, its' underlying SWT event 108 // would not be filtered by workbench, so it get a chance to be handled by SWT code 109 // or to be passed to the OS; see WorkbenchKeyboard.press() method. 110 return false; 111 } 112 }; 113 114 /** 115 * @returns the global handler service. 116 */ 117 public static IHandlerService getHandlerService() { 118 return (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class); 119 } 120 121 /** 122 * Activates the handlers for list of commands (see COMMAND_HANDLERS) with:<br> 123 * 1. The empty handler (except 'selectAll'), so underlying SWT event wouldn't be filtered by the 124 * workbench;<br> 125 * 2. Highest priority {@link Expression}, so this handler has a chance to be set. 126 */ 127 protected void activateHandlers() { 128 IHandlerService service = getHandlerService(); 129 for (int i = 0; i < COMMAND_HANDLER_IDS.length; ++i) { 130 String actionName = (String) COMMAND_HANDLER_IDS[i]; 131 IHandler handler = getHandlerFor(actionName); 132 activateHandler(actionName, service, handler, new Expression() { 133 @Override 134 public EvaluationResult evaluate(IEvaluationContext context) throws CoreException { 135 return EvaluationResult.TRUE; 136 } 137 138 @Override 139 public void collectExpressionInfo(ExpressionInfo info) { 140 // get the highest priority 141 // note, if someone else has such priority, there will be key-binding conflicts logged. 142 info.markSystemPropertyAccessed(); 143 info.markDefaultVariableAccessed(); 144 info.addVariableNameAccess(ISources.ACTIVE_MENU_NAME); 145 } 146 }); 147 } 148 } 149 150 protected IHandler getHandlerFor(String actionName) { 151 return EMPTY_HANDLER; 152 } 153 154 /** 155 * Activates handler and stores it into a collection for further deactivation. 156 */ 157 private final List<IHandlerActivation> m_activations = Lists.newLinkedList(); 158 159 private void activateHandler(String actionName, 160 IHandlerService service, 161 IHandler handler, 162 Expression highPriorityExpression) { 163 // activate handler and store it into a collection for further deactivation 164 m_activations.add(service.activateHandler(actionName, handler, highPriorityExpression)); 165 } 166 167 /** 168 * Deactivates all handlers and clears handlers collection. 169 */ 170 protected void deactivateHandlers() { 171 getHandlerService().deactivateHandlers(m_activations); 172 m_activations.clear(); 173 } 174 } 175