/*******************************************************************************
* Copyright (c) 2007, 2010 Nokia 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:
* Nokia - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.actions;
import org.eclipse.cdt.debug.internal.core.CRequest;
import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.progress.WorkbenchJob;
/**
* Invoked when user right clicks on an element in the Variables or Expressions
* view and selects 'Add Watchpoint (C/C++)'
*/
public class AddWatchpointOnVariableActionDelegate extends AddWatchpointActionDelegate implements IObjectActionDelegate {
/** The target variable/expression */
private ICWatchpointTarget fVar;
/** The view where fVar was selected */
private IWorkbenchPart fActivePart;
/**
* Constructor
*/
public AddWatchpointOnVariableActionDelegate() {
super();
}
/* (non-Javadoc)
* @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
*/
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
fActivePart = targetPart;
}
private static class GetSizeRequest extends CRequest implements ICWatchpointTarget.GetSizeRequest {
int fSize = -1;
public int getSize() {
return fSize;
}
public void setSize(int size) {
fSize = size;
}
};
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointActionDelegate#run(org.eclipse.jface.action.IAction)
*/
public void run(IAction action) {
if (fVar == null) {
return;
}
final String expr = fVar.getExpression();
if (expr == null) {
assert false : "how are we getting an empty expression?"; //$NON-NLS-1$
return;
}
// Getting the size of the variable/expression is an asynchronous
// operation...or at least the API is (the CDI implementation reacts
// synchronously)
final ICWatchpointTarget.GetSizeRequest request = new GetSizeRequest() {
public void done() {
if (isSuccess()) {
// Now that we have the size, put up a dialog to create the watchpoint
final int size = getSize();
assert size > 0 : "unexpected variale/expression size"; //$NON-NLS-1$
WorkbenchJob job = new WorkbenchJob("open watchpoint dialog") { //$NON-NLS-1$
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
AddWatchpointDialog dlg = new AddWatchpointDialog(CDebugUIPlugin.getActiveWorkbenchShell(),
getMemorySpaceManagement());
dlg.setExpression(expr);
dlg.initializeRange(false, Integer.toString(size));
if (dlg.open() == Window.OK) {
addWatchpoint(dlg.getWriteAccess(), dlg.getReadAccess(), dlg.getExpression(), dlg.getMemorySpace(), dlg.getRange());
}
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule();
}
else {
WorkbenchJob job = new WorkbenchJob("watchpoint error") { //$NON-NLS-1$
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (fActivePart != null) {
ErrorDialog.openError( fActivePart.getSite().getWorkbenchWindow().getShell(), ActionMessages.getString( "AddWatchpointOnVariableActionDelegate.Error_Dlg_Title" ), ActionMessages.getString( "AddWatchpointOnVariableActionDelegate.No_Element_Size" ), getStatus() ); //$NON-NLS-1$ //$NON-NLS-2$
}
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule();
}
}
};
fVar.getSize(request);
}
private class CanCreateWatchpointRequest extends CRequest implements ICWatchpointTarget.CanCreateWatchpointRequest {
boolean fCanCreate;
public boolean getCanCreate() {
return fCanCreate;
}
public void setCanCreate(boolean value) {
fCanCreate = value;
}
};
/**
* Record the target variable/expression
*
* @see org.eclipse.ui.actions.ActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
* org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(final IAction action, ISelection selection) {
fVar = null;
if (selection == null || selection.isEmpty()) {
action.setEnabled(false);
return;
}
if (selection instanceof TreeSelection) {
Object obj = ((TreeSelection)selection).getFirstElement();
fVar = (ICWatchpointTarget)DebugPlugin.getAdapter(obj, ICWatchpointTarget.class);
if (fVar != null) {
final ICWatchpointTarget.CanCreateWatchpointRequest request = new CanCreateWatchpointRequest() {
public void done() {
action.setEnabled(getCanCreate());
}
};
fVar.canSetWatchpoint(request);
return;
}
assert false : "action should not have been available for object " + obj; //$NON-NLS-1$
}
else if (selection instanceof StructuredSelection) {
// Not sure why, but sometimes we get an extraneous empty StructuredSelection. Seems harmless enough
assert ((StructuredSelection)selection).getFirstElement() == null : "action installed in unexpected type of view/part"; //$NON-NLS-1$
}
else {
assert false : "action installed in unexpected type of view/part"; //$NON-NLS-1$
}
action.setEnabled(false);
}
}