/*******************************************************************************
* Copyright (c) 2009, 2015 Ericsson 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:
* Ericsson - initial implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.commands;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.actions.MessagesForVMActions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* Base class for actions which delegate functionality to an adapter retrieved
* from the current debug context.
*
* @since 2.0
*/
abstract public class RetargetDebugContextCommand extends AbstractHandler implements IDebugContextListener {
private ISelection fDebugContext;
private Object fTargetAdapter = null;
private IDebugContextService fContextService = null;
private String fCommandId = null;
protected Object getTargetAdapter() { return fTargetAdapter; }
protected ISelection getDebugContext() { return fDebugContext; }
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
*/
public RetargetDebugContextCommand() {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
fContextService = DebugUITools.getDebugContextManager().getContextService(window);
fContextService.addPostDebugContextListener(this);
fDebugContext = fContextService.getActiveContext();
update();
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
fCommandId = event.getCommand().getId();
if (fTargetAdapter != null) {
try {
performCommand(fTargetAdapter, fDebugContext);
} catch (ExecutionException e) {
Shell shell = HandlerUtil.getActiveWorkbenchWindowChecked(event).getShell();
ErrorDialog.openError(shell, MessagesForVMActions.RetargetDebugContextAction_ErrorDialog_title, MessagesForVMActions.RetargetDebugContextAction_ErrorDialog_message, null);
}
}
update();
return null;
}
/**
* Returns whether the specific operation is supported.
*
* @param target the target adapter
* @param debugContext the selection to verify the operation on
* @return whether the operation can be performed
*/
protected abstract boolean canPerformCommand(Object target, ISelection debugContext);
/**
* Performs the specific operation.
*
* @param target the target adapter
* @param debugContext the selection to verify the operation on
* @throws CoreException if an exception occurs
*/
protected abstract void performCommand(Object target, ISelection debugContext) throws ExecutionException;
/**
* Returns the type of adapter (target) this command works on.
*
* @return the type of adapter this command works on
*/
protected abstract Class<?> getAdapterClass();
public void update() {
boolean enabled = false;
fTargetAdapter = null;
if (fDebugContext instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) fDebugContext;
if (!ss.isEmpty()) {
Object object = ss.getFirstElement();
if (object instanceof IAdaptable) {
fTargetAdapter = getAdapter((IAdaptable) object);
if (fTargetAdapter != null) {
enabled = canPerformCommand(fTargetAdapter, fDebugContext);
}
}
}
}
setBaseEnabled(enabled);
if (fCommandId != null) {
ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class);
if (commandService != null) {
commandService.refreshElements(fCommandId, null);
}
}
}
@Override
public void dispose() {
// Must use the stored service. If we try to fetch the service
// again with the workbenchWindow, it may fail if the window is
// already closed.
fContextService.removePostDebugContextListener(this);
fTargetAdapter = null;
}
@Override
public void debugContextChanged(DebugContextEvent event) {
fDebugContext = event.getContext();
update();
}
protected Object getAdapter(IAdaptable adaptable) {
Object adapter = adaptable.getAdapter(getAdapterClass());
if (adapter == null) {
IAdapterManager adapterManager = Platform.getAdapterManager();
if (adapterManager.hasAdapter(adaptable, getAdapterClass().getName())) {
adapter = adapterManager.loadAdapter(adaptable, getAdapterClass().getName());
}
}
return adapter;
}
}