1
/*******************************************************************************
2
* Copyright (c) 2000, 2010 IBM Corporation and others.
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
9
* IBM Corporation - initial API and implementation
10
* Anton Leherbauer (Wind River Systems) - bug 183291
11
* Ericsson - Updated to the latest platform version of this file
12
*******************************************************************************/
13
package org.eclipse.cdt.debug.internal.ui.actions;
15
import org.eclipse.core.resources.IResource;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.IAdaptable;
18
import org.eclipse.core.runtime.IAdapterManager;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.core.runtime.Status;
22
import org.eclipse.debug.internal.ui.DebugUIPlugin;
23
import org.eclipse.jface.action.IAction;
24
import org.eclipse.jface.dialogs.ErrorDialog;
25
import org.eclipse.jface.viewers.ISelection;
26
import org.eclipse.jface.viewers.ISelectionProvider;
27
import org.eclipse.jface.viewers.IStructuredSelection;
28
import org.eclipse.swt.widgets.Event;
29
import org.eclipse.ui.IActionDelegate2;
30
import org.eclipse.ui.IEditorPart;
31
import org.eclipse.ui.IPartListener;
32
import org.eclipse.ui.IPartService;
33
import org.eclipse.ui.IWorkbenchPart;
34
import org.eclipse.ui.IWorkbenchWindow;
35
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
38
* Global retargettable debug action.
40
public abstract class RetargetAction implements IWorkbenchWindowActionDelegate, IPartListener, IActionDelegate2 {
42
protected IWorkbenchWindow fWindow = null;
43
private IWorkbenchPart fActivePart = null;
44
private Object fTargetAdapter = null;
45
private IAction fAction = null;
46
private static final ISelection EMPTY_SELECTION = new EmptySelection();
48
static class EmptySelection implements ISelection {
51
* @see org.eclipse.jface.viewers.ISelection#isEmpty()
53
public boolean isEmpty() {
60
* Returns the current selection in the active part, possibly
61
* and empty selection, but never <code>null</code>.
63
* @return the selection in the active part, possibly empty
65
protected ISelection getTargetSelection() {
66
if (fActivePart != null) {
67
ISelectionProvider selectionProvider = fActivePart.getSite().getSelectionProvider();
68
if (selectionProvider != null) {
69
return selectionProvider.getSelection();
72
return EMPTY_SELECTION;
75
protected IWorkbenchPart getActivePart() {
80
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
82
public void dispose() {
83
fWindow.getPartService().removePartListener(this);
85
fTargetAdapter = null;
89
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
91
public void init(IWorkbenchWindow window) {
92
this.fWindow = window;
93
IPartService partService = window.getPartService();
94
partService.addPartListener(this);
95
IWorkbenchPart part = partService.getActivePart();
101
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
103
public void run(IAction action) {
104
if (fTargetAdapter != null) {
106
if (isTargetEnabled()) {
107
performAction(fTargetAdapter, getTargetSelection(), fActivePart);
109
String message = getOperationUnavailableMessage();
110
IStatus status = new Status(IStatus.INFO, DebugUIPlugin.getUniqueIdentifier(), message);
111
DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), DebugUIPlugin.removeAccelerators(action.getText()), message, status);
113
} catch (CoreException e) {
114
ErrorDialog.openError(fWindow.getShell(), ActionMessages.getString("RetargetAction.0"), ActionMessages.getString("RetargetAction.1"), e.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$
120
* Returns a message to display when we find that the operation is not enabled
121
* when invoked in an editor (we check enabled state before running in this case,
122
* rather than updating on each selection change - see bug 180441).
124
* @return information message when unavailable
126
protected abstract String getOperationUnavailableMessage();
129
* Performs the specific breakpoint toggling.
131
* @param selection selection in the active part
132
* @param part active part
133
* @throws CoreException if an exception occurs
135
protected abstract void performAction(Object target, ISelection selection, IWorkbenchPart part) throws CoreException;
138
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
140
public void selectionChanged(IAction action, ISelection selection) {
141
// if the active part did not provide an adapter, see if the selection does
142
if (fTargetAdapter == null && selection instanceof IStructuredSelection) {
143
IStructuredSelection ss = (IStructuredSelection) selection;
145
Object object = ss.getFirstElement();
146
if (object instanceof IAdaptable) {
147
fTargetAdapter = getAdapter((IAdaptable) object);
151
boolean enabled = fTargetAdapter != null;
152
if (selection instanceof IStructuredSelection) {
153
enabled = isTargetEnabled();
155
action.setEnabled(enabled);
159
* @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
161
public void partActivated(IWorkbenchPart part) {
163
IResource resource = (IResource) part.getAdapter(IResource.class);
164
if (resource == null && part instanceof IEditorPart) {
165
resource = (IResource) ((IEditorPart)part).getEditorInput().getAdapter(IResource.class);
167
if (resource != null) {
168
fTargetAdapter = getAdapter(resource);
170
if (fTargetAdapter == null) {
171
fTargetAdapter = getAdapter(part);
173
if (fAction != null) {
174
fAction.setEnabled(fTargetAdapter != null);
178
protected Object getAdapter(IAdaptable adaptable) {
179
Object adapter = adaptable.getAdapter(getAdapterClass());
180
if (adapter == null) {
181
IAdapterManager adapterManager = Platform.getAdapterManager();
182
if (adapterManager.hasAdapter(adaptable, getAdapterClass().getName())) {
183
adapter = adapterManager.loadAdapter(adaptable, getAdapterClass().getName());
190
* Returns the type of adapter (target) this action works on.
192
* @return the type of adapter this action works on
194
protected abstract Class getAdapterClass();
197
* @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
199
public void partBroughtToTop(IWorkbenchPart part) {
202
* @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
204
public void partClosed(IWorkbenchPart part) {
209
* Clears reference to active part and adapter when a relevant part
210
* is closed or no longer active.
212
* @param part workbench part that has been closed or no longer active
214
protected void clearPart(IWorkbenchPart part) {
215
if (part.equals(fActivePart)) {
217
fTargetAdapter = null;
221
* @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
223
public void partDeactivated(IWorkbenchPart part) {
227
* @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
229
public void partOpened(IWorkbenchPart part) {
233
* Returns whether the target adapter is enabled
235
* @return whether target adapter is enabled
237
protected boolean isTargetEnabled() {
238
if (fTargetAdapter != null) {
239
if (fActivePart != null) {
240
return canPerformAction(fTargetAdapter, getTargetSelection(), fActivePart);
247
* Returns whether the specific operation is supported.
249
* @param target the target adapter
250
* @param selection the selection to verify the operation on
251
* @param part the part the operation has been requested on
252
* @return whether the operation can be performed
254
protected abstract boolean canPerformAction(Object target, ISelection selection, IWorkbenchPart part);
257
* @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction)
259
public void init(IAction action) {
264
* @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
266
public void runWithEvent(IAction action, Event event) {
271
* Returns the proxy to this action delegate or <code>null</code>
273
* @return action proxy or <code>null</code>
275
protected IAction getAction() {
280
* Returns whether there is currently a target adapter for this action.
282
* @return whether the action has a target adapter.
284
protected boolean hasTargetAdapter() {
285
return fTargetAdapter != null;