### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.workbench Index: Eclipse UI/org/eclipse/ui/internal/services/SourcePriorityNameMapping.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/services/SourcePriorityNameMapping.java,v retrieving revision 1.11 diff -u -r1.11 SourcePriorityNameMapping.java --- Eclipse UI/org/eclipse/ui/internal/services/SourcePriorityNameMapping.java 16 Mar 2007 18:00:35 -0000 1.11 +++ Eclipse UI/org/eclipse/ui/internal/services/SourcePriorityNameMapping.java 17 Mar 2007 13:14:25 -0000 @@ -72,6 +72,8 @@ addMapping(ACTIVE_MENU_NAME, ACTIVE_MENU); addMapping(ACTIVE_MENU_SELECTION_NAME, ACTIVE_MENU); addMapping(ACTIVE_MENU_EDITOR_INPUT_NAME, ACTIVE_MENU); + addMapping(ACTIVE_FOCUS_CONTROL_ID_NAME, ACTIVE_MENU); + addMapping(ACTIVE_FOCUS_CONTROL_NAME, ACTIVE_MENU); addMapping(ACTIVE_PART_NAME, ACTIVE_PART); addMapping(ACTIVE_PART_ID_NAME, ACTIVE_PART_ID); addMapping(ACTIVE_SHELL_NAME, ACTIVE_SHELL); Index: Eclipse UI/org/eclipse/ui/internal/Workbench.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java,v retrieving revision 1.432 diff -u -r1.432 Workbench.java --- Eclipse UI/org/eclipse/ui/internal/Workbench.java 16 Mar 2007 18:00:32 -0000 1.432 +++ Eclipse UI/org/eclipse/ui/internal/Workbench.java 17 Mar 2007 13:14:25 -0000 @@ -140,6 +140,7 @@ import org.eclipse.ui.internal.intro.IIntroRegistry; import org.eclipse.ui.internal.intro.IntroDescriptor; import org.eclipse.ui.internal.keys.BindingService; +import org.eclipse.ui.internal.menus.FocusControlSourceProvider; import org.eclipse.ui.internal.menus.WorkbenchMenuService; import org.eclipse.ui.internal.misc.Policy; import org.eclipse.ui.internal.misc.StatusUtil; @@ -169,6 +170,7 @@ import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.intro.IIntroManager; import org.eclipse.ui.keys.IBindingService; +import org.eclipse.ui.menus.IFocusService; import org.eclipse.ui.menus.IMenuService; import org.eclipse.ui.operations.IWorkbenchOperationSupport; import org.eclipse.ui.progress.IProgressService; @@ -1625,12 +1627,23 @@ contextService.addSourceProvider(currentSelectionSourceProvider); menuService.addSourceProvider(currentSelectionSourceProvider); sourceProviderService.registerProvider(currentSelectionSourceProvider); + actionSetSourceProvider = new ActionSetSourceProvider(); evaluationService.addSourceProvider(actionSetSourceProvider); handlerService[0].addSourceProvider(actionSetSourceProvider); contextService.addSourceProvider(actionSetSourceProvider); menuService.addSourceProvider(actionSetSourceProvider); sourceProviderService.registerProvider(actionSetSourceProvider); + + FocusControlSourceProvider focusControl = new FocusControlSourceProvider(); + serviceLocator.registerService(IFocusService.class, focusControl); + evaluationService.addSourceProvider(focusControl); + handlerService[0].addSourceProvider(focusControl); + contextService.addSourceProvider(focusControl); + menuService.addSourceProvider(focusControl); + sourceProviderService.registerProvider(focusControl); + + menuSourceProvider = new MenuSourceProvider(); evaluationService.addSourceProvider(menuSourceProvider); handlerService[0].addSourceProvider(menuSourceProvider); Index: Eclipse UI/org/eclipse/ui/ISources.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/ISources.java,v retrieving revision 1.11 diff -u -r1.11 ISources.java --- Eclipse UI/org/eclipse/ui/ISources.java 15 Mar 2007 13:09:39 -0000 1.11 +++ Eclipse UI/org/eclipse/ui/ISources.java 17 Mar 2007 13:14:23 -0000 @@ -281,4 +281,20 @@ * @since 3.3 */ public static final String ACTIVE_MENU_EDITOR_INPUT_NAME = "activeMenuEditorInput"; //$NON-NLS-1$ + + /** + * The variable name for the active focus Control, when provided by the + * IFocusService. + * + * @since 3.3 + */ + public static final String ACTIVE_FOCUS_CONTROL_NAME = "activeFocusControl"; //$NON-NLS-1$ + + /** + * The variable name for the active focus Control id, when provided by the + * IFocusService. + * + * @since 3.3 + */ + public static final String ACTIVE_FOCUS_CONTROL_ID_NAME = "activeFocusControlId"; //$NON-NLS-1$ } Index: Eclipse UI/org/eclipse/ui/menus/IFocusService.java =================================================================== RCS file: Eclipse UI/org/eclipse/ui/menus/IFocusService.java diff -N Eclipse UI/org/eclipse/ui/menus/IFocusService.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse UI/org/eclipse/ui/menus/IFocusService.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 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.ui.menus; + +import org.eclipse.swt.widgets.Control; + +/** + * Tracks focusGained and focusLost events for a Control registered with this + * service, and provides them as variables to the application evaluation context + * for evaluation be the various services. + *

+ * This service provides 2 variables, activeFocusControl (a Control) and + * activeFocusControlId (the ID registered with the service). + *

+ *

+ * You can use this service to provide default cut/copy/paste/selectAll for + * specific text controls outside of the normal workbench part lifecycle, like a + * control contributed to the trim. For example: + *

+ *

+ * + *

+ * <handler
+ *      class="org.eclipse.ui.internal.handlers.WidgetMethodHandler:paste"
+ *      commandId="org.eclipse.ui.edit.paste">
+ *   <activeWhen>
+ *      <with variable="activeFocusControlId">
+ *         <equals value="org.eclipse.ui.tests.focusText"/>
+ *      </with>
+ *   </activeWhen>
+ * </handler>
+ * 
+ * + *

+ * + * @see org.eclipse.ui.ISources + * @since 3.3 + */ +public interface IFocusService { + /** + * Use the value to provide default copy behaviour in a handler element + * class attribute. + */ + public static final String COPY_HANDLER = "org.eclipse.ui.internal.handlers.WidgetMethodHandler:copy"; //$NON-NLS-1$ + + /** + * Use the value to provide default paste behaviour in a handler element + * class attribute. + */ + public static final String PASTE_HANDLER = "org.eclipse.ui.internal.handlers.WidgetMethodHandler:paste"; //$NON-NLS-1$ + + /** + * Use the value to provide default cut behaviour in a handler element class + * attribute. + */ + public static final String CUT_HANDLER = "org.eclipse.ui.internal.handlers.WidgetMethodHandler:cut"; //$NON-NLS-1$ + + /** + * Use the value to provide default select all behaviour in a handler + * element class attribute. + */ + public static final String SELECT_ALL_HANDLER = "org.eclipse.ui.internal.handlers.SelectAllHandler"; //$NON-NLS-1$ + + /** + * A Control for the service to track. We will remove ourselves as a + * listener on a dispose. + * + * @param control + * the control. Must not be null. + * @param id + * the unique ID for this control. Must not be null. + */ + public void addFocusTracker(Control control, String id); + + /** + * No longer track focus events for this control. Use this method when the + * control should no longer be tracked, but is not disposed. + * + * @param control + * the control registered with the service. Must not be + * null. + */ + public void removeFocusTracker(Control control); +} Index: Eclipse UI/org/eclipse/ui/internal/menus/FocusControlSourceProvider.java =================================================================== RCS file: Eclipse UI/org/eclipse/ui/internal/menus/FocusControlSourceProvider.java diff -N Eclipse UI/org/eclipse/ui/internal/menus/FocusControlSourceProvider.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse UI/org/eclipse/ui/internal/menus/FocusControlSourceProvider.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 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.ui.internal.menus; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.AbstractSourceProvider; +import org.eclipse.ui.ISources; +import org.eclipse.ui.menus.IFocusService; + +/** + * @since 3.3 + * + */ +public class FocusControlSourceProvider extends AbstractSourceProvider + implements IFocusService { + + /** + * The names of the sources supported by this source provider. + */ + private static final String[] PROVIDED_SOURCE_NAMES = new String[] { + ISources.ACTIVE_FOCUS_CONTROL_ID_NAME, + ISources.ACTIVE_FOCUS_CONTROL_NAME }; + + Map controlToId = new HashMap(); + private FocusListener focusListener; + + private String currentId; + + private Control currentControl; + + private DisposeListener disposeListener; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.menus.IFocusService#addTrackerFor(org.eclipse.swt.widgets.Control, + * java.lang.String) + */ + public void addFocusTracker(Control control, String id) { + if (control.isDisposed()) { + return; + } + controlToId.put(control, id); + control.addFocusListener(getFocusListener()); + control.addDisposeListener(getDisposeListener()); + } + + /** + * @return + */ + private DisposeListener getDisposeListener() { + if (disposeListener == null) { + disposeListener = new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + controlToId.remove(e.widget); + } + }; + } + return disposeListener; + } + + /** + * @return + */ + private FocusListener getFocusListener() { + if (focusListener == null) { + focusListener = new FocusListener() { + public void focusGained(FocusEvent e) { + focusIn(e.widget); + } + + public void focusLost(FocusEvent e) { + focusIn(null); + } + }; + } + return focusListener; + } + + /** + * @param widget + */ + private void focusIn(Widget widget) { + String id = (String) controlToId.get(widget); + if (currentId != id) { + if (id == null) { + currentId = null; + currentControl = null; + } else { + currentId = id; + currentControl = (Control) widget; + } + Map m = new HashMap(); + m.put(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME, currentId); + m.put(ISources.ACTIVE_FOCUS_CONTROL_NAME, currentControl); + fireSourceChanged(ISources.ACTIVE_MENU, m); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.menus.IFocusService#removeTrackerFor(org.eclipse.swt.widgets.Control) + */ + public void removeFocusTracker(Control control) { + controlToId.remove(control); + if (control.isDisposed()) { + return; + } + control.removeFocusListener(getFocusListener()); + control.removeDisposeListener(getDisposeListener()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.ISourceProvider#dispose() + */ + public void dispose() { + Iterator i = controlToId.keySet().iterator(); + while (i.hasNext()) { + Control c = (Control) i.next(); + if (!c.isDisposed()) { + c.removeFocusListener(getFocusListener()); + c.removeDisposeListener(getDisposeListener()); + } + } + controlToId.clear(); + controlToId = null; + focusListener = null; + disposeListener = null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.ISourceProvider#getCurrentState() + */ + public Map getCurrentState() { + Map m = new HashMap(); + m.put(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME, currentId); + m.put(ISources.ACTIVE_FOCUS_CONTROL_NAME, currentControl); + return m; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.ISourceProvider#getProvidedSourceNames() + */ + public String[] getProvidedSourceNames() { + return PROVIDED_SOURCE_NAMES; + } +}