| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.internal.commands; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.SortedMap; |
| import java.util.SortedSet; |
| import java.util.TreeMap; |
| import java.util.TreeSet; |
| |
| import org.eclipse.jface.action.ContextResolver; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IContextResolver; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.ShellAdapter; |
| import org.eclipse.swt.events.ShellEvent; |
| import org.eclipse.swt.events.ShellListener; |
| import org.eclipse.swt.events.VerifyEvent; |
| import org.eclipse.swt.events.VerifyListener; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.MenuItem; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IPageListener; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartSite; |
| import org.eclipse.ui.commands.HandlerServiceEvent; |
| import org.eclipse.ui.commands.IHandler; |
| import org.eclipse.ui.commands.IHandlerService; |
| import org.eclipse.ui.commands.IHandlerServiceListener; |
| import org.eclipse.ui.contexts.IContextActivationService; |
| import org.eclipse.ui.contexts.IContextManager; |
| import org.eclipse.ui.contexts.IContextManagerEvent; |
| import org.eclipse.ui.contexts.IContextManagerListener; |
| import org.eclipse.ui.internal.AcceleratorMenu; |
| import org.eclipse.ui.internal.IWorkbenchConstants; |
| import org.eclipse.ui.internal.PartSite; |
| import org.eclipse.ui.internal.Workbench; |
| import org.eclipse.ui.internal.WorkbenchWindow; |
| import org.eclipse.ui.internal.commands.registry.ContextBinding; |
| import org.eclipse.ui.internal.commands.registry.CoreRegistry; |
| import org.eclipse.ui.internal.commands.registry.IMutableRegistry; |
| import org.eclipse.ui.internal.commands.registry.IRegistry; |
| import org.eclipse.ui.internal.commands.registry.LocalRegistry; |
| import org.eclipse.ui.internal.commands.registry.PreferenceRegistry; |
| import org.eclipse.ui.internal.commands.util.KeySupport; |
| import org.eclipse.ui.internal.commands.util.Sequence; |
| import org.eclipse.ui.internal.commands.util.Stroke; |
| |
| public class ContextAndHandlerManager implements IContextResolver { |
| |
| private final StatusLineContributionItem modeContributionItem = new StatusLineContributionItem("ModeContributionItem"); //$NON-NLS-1$ |
| |
| private final IContextManagerListener contextManagerListener = new IContextManagerListener() { |
| public void contextManagerChanged(IContextManagerEvent contextManagerEvent) { |
| update(); |
| } |
| }; |
| |
| private final IHandlerServiceListener handlerServiceListener = new IHandlerServiceListener() { |
| public void handlerServiceChanged(HandlerServiceEvent handlerServiceEvent) { |
| update(); |
| } |
| }; |
| |
| private final IPartListener partListener = new IPartListener() { |
| public void partActivated(IWorkbenchPart workbenchPart) { |
| partEvent(); |
| } |
| |
| public void partBroughtToTop(IWorkbenchPart workbenchPart) { |
| } |
| |
| public void partClosed(IWorkbenchPart workbenchPart) { |
| partEvent(); |
| } |
| |
| public void partDeactivated(IWorkbenchPart workbenchPart) { |
| partEvent(); |
| } |
| |
| public void partOpened(IWorkbenchPart workbenchPart) { |
| partEvent(); |
| } |
| }; |
| |
| private final ShellListener shellListener = new ShellAdapter() { |
| public void shellActivated(ShellEvent shellEvent) { |
| shellEvent(); |
| } |
| |
| public void shellDeactivated(ShellEvent shellEvent) { |
| shellEvent(); |
| } |
| }; |
| |
| private final VerifyListener verifyListener = new VerifyListener() { |
| public void verifyText(VerifyEvent verifyEvent) { |
| verifyEvent.doit = false; |
| clear(); |
| } |
| }; |
| |
| private AcceleratorMenu acceleratorMenu; |
| private IContextActivationService activeWorkbenchPartContextService; |
| private IHandlerService activeWorkbenchPartHandlerService; |
| private WorkbenchWindow workbenchWindow; |
| private IContextActivationService workbenchWindowContextService; |
| private IHandlerService workbenchWindowHandlerService; |
| private Map contextsByCommand; |
| private IContextManager contextManager; |
| private boolean start = false; |
| |
| public ContextAndHandlerManager(WorkbenchWindow workbenchWindow) { |
| super(); |
| this.workbenchWindow = workbenchWindow; |
| IWorkbench workbench = workbenchWindow.getWorkbench(); |
| contextManager = ((Workbench) workbench).getContextManager(); // TODO temporary cast |
| contextManager.addContextManagerListener(contextManagerListener); |
| workbenchWindowHandlerService = ((WorkbenchWindow) workbenchWindow).getHandlerService(); |
| workbenchWindowHandlerService.addHandlerServiceListener(handlerServiceListener); |
| workbenchWindow.getStatusLineManager().add(modeContributionItem); |
| reset(); |
| |
| this.workbenchWindow.addPageListener(new IPageListener() { |
| public void pageActivated(IWorkbenchPage workbenchPage) { |
| workbenchPage.addPartListener(partListener); |
| } |
| |
| public void pageClosed(IWorkbenchPage workbenchPage) { |
| workbenchPage.removePartListener(partListener); |
| } |
| |
| public void pageOpened(IWorkbenchPage workbenchPage) { |
| workbenchPage.addPartListener(partListener); |
| } |
| }); |
| |
| workbenchWindow.getPartService().addPartListener(partListener); |
| |
| Shell shell = workbenchWindow.getShell(); |
| |
| if (shell != null) |
| shell.addShellListener(shellListener); |
| |
| partEvent(); |
| } |
| |
| private void partEvent() { |
| IContextActivationService activeWorkbenchPartContextService = null; |
| IHandlerService activeWorkbenchPartHandlerService = null; |
| IWorkbenchPage activeWorkbenchPage = workbenchWindow.getActivePage(); |
| |
| if (activeWorkbenchPage != null) { |
| IWorkbenchPart activeWorkbenchPart = activeWorkbenchPage.getActivePart(); |
| |
| if (activeWorkbenchPart != null) { |
| IWorkbenchPartSite activeWorkbenchPartSite = activeWorkbenchPart.getSite(); |
| |
| if (activeWorkbenchPartSite != null) { |
| activeWorkbenchPartContextService = ((PartSite) activeWorkbenchPartSite).getContextActivationService(); |
| activeWorkbenchPartHandlerService = ((PartSite) activeWorkbenchPartSite).getHandlerService(); |
| } |
| } |
| } |
| |
| if (this.activeWorkbenchPartHandlerService != activeWorkbenchPartHandlerService) { |
| if (this.activeWorkbenchPartHandlerService != null) |
| this.activeWorkbenchPartHandlerService.removeHandlerServiceListener(handlerServiceListener); |
| |
| this.activeWorkbenchPartHandlerService = activeWorkbenchPartHandlerService; |
| |
| if (this.activeWorkbenchPartHandlerService != null) |
| this.activeWorkbenchPartHandlerService.addHandlerServiceListener(handlerServiceListener); |
| |
| start = true; |
| update(); |
| } |
| } |
| |
| private void shellEvent() { |
| start = true; |
| update(); |
| } |
| |
| private void clear() { |
| Manager.getInstance().getKeyMachine().setMode(Sequence.create()); |
| modeContributionItem.setText(""); //$NON-NLS-1$ |
| update(); |
| } |
| |
| private void pressed(Stroke stroke, Event event) { |
| SequenceMachine keyMachine = Manager.getInstance().getKeyMachine(); |
| List strokes = new ArrayList(keyMachine.getMode().getStrokes()); |
| strokes.add(stroke); |
| Sequence childMode = Sequence.create(strokes); |
| Map sequenceMapForMode = keyMachine.getSequenceMapForMode(); |
| keyMachine.setMode(childMode); |
| Map childSequenceMapForMode = keyMachine.getSequenceMapForMode(); |
| |
| if (childSequenceMapForMode.isEmpty()) { |
| clear(); |
| IHandler handler = getHandler((String) sequenceMapForMode.get(childMode)); |
| |
| if (handler != null && handler.isEnabled()) |
| try { |
| handler.execute(event); |
| } catch (Exception e) { |
| // TODO |
| } |
| } |
| else { |
| modeContributionItem.setText(KeySupport.formatSequence(childMode, true)); |
| update(); |
| } |
| } |
| |
| private IHandler getHandler(String command) { |
| if (command != null) { |
| if (activeWorkbenchPartHandlerService != null) { |
| SortedMap handlerMap = activeWorkbenchPartHandlerService.getHandlerMap(); |
| |
| if (handlerMap != null) { |
| Object object = handlerMap.get(command); |
| |
| if (object instanceof IHandler) |
| return (IHandler) object; |
| } |
| } |
| |
| if (workbenchWindowHandlerService != null) { |
| SortedMap handlerMap = workbenchWindowHandlerService.getHandlerMap(); |
| |
| if (handlerMap != null) { |
| Object object = handlerMap.get(command); |
| |
| if (object instanceof IHandler) |
| return (IHandler) object; |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public void update() { |
| SortedSet activeContextIds = contextManager.getActiveContextIds(); |
| List contexts = new ArrayList(activeContextIds); |
| // TODO: these should be sorted somehow |
| SequenceMachine keyMachine = Manager.getInstance().getKeyMachine(); |
| |
| try { |
| // TODO: get rid of this |
| if (contexts.size() == 0) |
| contexts.add(IWorkbenchConstants.DEFAULT_ACCELERATOR_SCOPE_ID); |
| |
| keyMachine.setContexts((String[]) contexts.toArray(new String[contexts.size()])); |
| } catch (IllegalArgumentException eIllegalArgument) { |
| System.err.println(eIllegalArgument); |
| } |
| |
| Sequence mode = keyMachine.getMode(); |
| List strokes = mode.getStrokes(); |
| int size = strokes.size(); |
| Map sequenceMapForMode = keyMachine.getSequenceMapForMode(); |
| SortedSet strokeSetForMode = new TreeSet(); |
| Iterator iterator = sequenceMapForMode.entrySet().iterator(); |
| |
| while (iterator.hasNext()) { |
| Map.Entry entry = (Map.Entry) iterator.next(); |
| Sequence sequence = (Sequence) entry.getKey(); |
| String command = (String) entry.getValue(); |
| |
| if (sequence.isChildOf(mode, false)) { |
| IHandler handler = getHandler(command); |
| |
| if (handler != null) |
| strokeSetForMode.add(sequence.getStrokes().get(size)); |
| } |
| } |
| |
| iterator = strokeSetForMode.iterator(); |
| int[] accelerators = new int[strokeSetForMode.size()]; |
| int i = 0; |
| |
| while (iterator.hasNext()) |
| accelerators[i++] = ((Stroke) iterator.next()).getValue(); |
| |
| if (!start) |
| return; |
| |
| if (acceleratorMenu == null || acceleratorMenu.isDisposed()) { |
| Shell shell = workbenchWindow.getShell(); |
| |
| if (shell == null || shell.isDisposed()) |
| return; |
| |
| Menu parent = shell.getMenuBar(); |
| |
| if (parent == null || parent.isDisposed() || parent.getItemCount() < 1) |
| return; |
| |
| MenuItem parentItem = parent.getItem(parent.getItemCount() - 1); |
| |
| if (parentItem == null || parentItem.isDisposed()) |
| return; |
| |
| parent = parentItem.getMenu(); |
| |
| if (parent == null || parent.isDisposed()) |
| return; |
| |
| if (acceleratorMenu != null) |
| acceleratorMenu.dispose(); |
| |
| acceleratorMenu = new AcceleratorMenu(parent); |
| acceleratorMenu.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent selectionEvent) { |
| Event event = new Event(); |
| event.item = selectionEvent.item; |
| event.detail = selectionEvent.detail; |
| event.x = selectionEvent.x; |
| event.y = selectionEvent.y; |
| event.width = selectionEvent.width; |
| event.height = selectionEvent.height; |
| event.stateMask = selectionEvent.stateMask; |
| event.doit = selectionEvent.doit; |
| event.data = selectionEvent.data; |
| event.display = selectionEvent.display; |
| event.time = selectionEvent.time; |
| event.widget = selectionEvent.widget; |
| pressed(Stroke.create(selectionEvent.detail), event); |
| //pressed(Stroke.create(selectionEvent.detail)); |
| } |
| }); |
| } |
| |
| acceleratorMenu.setAccelerators(accelerators); |
| |
| if (size == 0) |
| acceleratorMenu.removeVerifyListener(verifyListener); |
| else |
| acceleratorMenu.addVerifyListener(verifyListener); |
| |
| ContextResolver.getInstance().setContextResolver(this); |
| MenuManager menuManager = ((WorkbenchWindow) workbenchWindow).getMenuManager(); |
| menuManager.update(IAction.TEXT); |
| |
| /* TODO make this work like it does for menus |
| CoolBarManager coolBarManager = ((WorkbenchWindow) workbenchWindow).getCoolBarManager(); |
| |
| if (coolBarManager != null) |
| coolBarManager.update(true); |
| */ |
| } |
| |
| public boolean inContext(String commandId) { |
| if (commandId != null) { |
| Set set = (Set) contextsByCommand.get(commandId); |
| |
| if (set != null) { |
| /* |
| if (activeWorkbenchPartContextService != null) { |
| List contexts = Arrays.asList(activeWorkbenchPartContextService.getActiveContextIds()); |
| |
| if (contexts != null) { |
| // TODO: get rid of this |
| contexts = new ArrayList(contexts); |
| if (contexts.size() == 0) |
| contexts.add(IWorkbenchConstants.DEFAULT_ACCELERATOR_SCOPE_ID); |
| |
| Iterator iterator = contexts.iterator(); |
| |
| while (iterator.hasNext()) { |
| String context = (String) iterator.next(); |
| |
| if (set.contains(context)) |
| return true; |
| } |
| } |
| } |
| |
| if (workbenchWindowContextService != null) { |
| List contexts = Arrays.asList(workbenchWindowContextService.getActiveContextIds()); |
| |
| if (contexts != null) { |
| // TODO: get rid of this |
| contexts = new ArrayList(contexts); |
| if (contexts.size() == 0) |
| contexts.add(IWorkbenchConstants.DEFAULT_ACCELERATOR_SCOPE_ID); |
| |
| Iterator iterator = contexts.iterator(); |
| |
| while (iterator.hasNext()) { |
| String context = (String) iterator.next(); |
| |
| if (set.contains(context)) |
| return true; |
| } |
| } |
| } |
| */ |
| |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| void reset() { |
| IRegistry coreRegistry = CoreRegistry.getInstance(); |
| IMutableRegistry localRegistry = LocalRegistry.getInstance(); |
| IMutableRegistry preferenceRegistry = PreferenceRegistry.getInstance(); |
| |
| try { |
| coreRegistry.load(); |
| } catch (IOException eIO) { |
| } |
| |
| try { |
| localRegistry.load(); |
| } catch (IOException eIO) { |
| } |
| |
| try { |
| preferenceRegistry.load(); |
| } catch (IOException eIO) { |
| } |
| |
| List contextBindings = new ArrayList(); |
| contextBindings.addAll(coreRegistry.getContextBindings()); |
| contextBindings.addAll(localRegistry.getContextBindings()); |
| contextBindings.addAll(preferenceRegistry.getContextBindings()); |
| contextsByCommand = new TreeMap(); |
| Iterator iterator = contextBindings.iterator(); |
| |
| while (iterator.hasNext()) { |
| ContextBinding contextBinding = (ContextBinding) iterator.next(); |
| String command = contextBinding.getCommand(); |
| String context = contextBinding.getContext(); |
| Set set = (Set) contextsByCommand.get(command); |
| |
| if (set == null) { |
| set = new TreeSet(); |
| contextsByCommand.put(command, set); |
| } |
| |
| set.add(context); |
| } |
| } |
| } |