/******************************************************************************* * Copyright (C) 2006, 2013 Shawn O. Pearce <spearce@spearce.org> 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 *******************************************************************************/ package org.eclipse.egit.ui.internal.actions; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.NotEnabledException; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.commands.common.NotDefinedException; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.internal.CommonUtils; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.services.IServiceLocator; /** * A helper class for Team Actions on Git controlled projects. * <p> * This implements {@link IObjectActionDelegate} so that it can be used on the * Team menu and {@link IWorkbenchWindowActionDelegate} so that it works in the * command group. */ public abstract class RepositoryAction extends AbstractHandler implements IObjectActionDelegate, IWorkbenchWindowActionDelegate { private ISelection mySelection; /** * The command id */ protected final String commandId; /** * The part as set in {@link #setActivePart(IAction, IWorkbenchPart)} */ protected IServiceLocator serviceLocator; private final RepositoryActionHandler handler; /** * @param commandId * @param handler */ protected RepositoryAction(String commandId, RepositoryActionHandler handler) { this.commandId = commandId; this.handler = handler; } @Override public void setActivePart(IAction action, IWorkbenchPart targetPart) { serviceLocator = targetPart.getSite(); } @Override public void run(IAction action) { if (!shouldRunAction()) return; ExecutionEvent event = createExecutionEvent(); try { this.handler.execute(event); } catch (ExecutionException e) { Activator.handleError(e.getMessage(), e, true); } } /** * Creates {@link ExecutionEvent} based on current selection * * @return {@link ExecutionEvent} with current selection */ protected ExecutionEvent createExecutionEvent() { IServiceLocator locator = getServiceLocator(); ICommandService srv = CommonUtils.getService(locator, ICommandService.class); IHandlerService hsrv = CommonUtils.getService(locator, IHandlerService.class); Command command = srv.getCommand(commandId); ExecutionEvent event = hsrv.createExecutionEvent(command, null); if (event.getApplicationContext() instanceof IEvaluationContext) ((IEvaluationContext) event.getApplicationContext()).addVariable( ISources.ACTIVE_CURRENT_SELECTION_NAME, mySelection); return event; } /** * @return the service locator to use in the action */ protected IServiceLocator getServiceLocator() { if (serviceLocator == null) serviceLocator = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); return serviceLocator; } @Override public final void selectionChanged(IAction action, ISelection selection) { mySelection = selection; if (handler.alwaysCheckEnabled()) { handler.setSelection(mySelection); if (action != null) { action.setEnabled(isEnabled()); } } else { // Compare selection of handler, as it converts it to a suitable // selection. E.g. an ITextSelection is converted to a selection of // the file. We are only interested in the selection change if a // different file was selected, not if the offset of the text // selection changed. IStructuredSelection selectionBefore = handler.getSelection(); handler.setSelection(mySelection); if (action != null) { IStructuredSelection selectionAfter = handler.getSelection(); boolean equalSelection = (selectionBefore == null) ? selectionAfter == null : selectionBefore.equals(selectionAfter); if (!equalSelection) { action.setEnabled(isEnabled()); } } } } @Override public final Object execute(ExecutionEvent event) throws ExecutionException { if (!shouldRunAction()) return null; ICommandService srv = CommonUtils.getService(getServiceLocator(), ICommandService.class); Command command = srv.getCommand(commandId); try { return command.executeWithChecks(event); } catch (ExecutionException e) { Activator.handleError(e.getMessage(), e, true); } catch (NotDefinedException e) { Activator.handleError(e.getMessage(), e, true); } catch (NotEnabledException e) { Activator.handleError(e.getMessage(), e, true); } catch (NotHandledException e) { Activator.handleError(e.getMessage(), e, true); } return null; } @Override public final boolean isEnabled() { return handler.isEnabled(); } @Override public void init(IWorkbenchWindow window) { this.serviceLocator = window; } /** * By default always return true. Allow implementers to decide whether * the action should be run or not * * @return {@code true} when action should be executed, {@code false} * otherwise */ protected boolean shouldRunAction() { return true; } }