blob: 7bdf3583014da4a5414d6310d8f23fcacb94a645 [file] [log] [blame]
package org.eclipse.debug.internal.ui.actions;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.util.Iterator;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValueModification;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.SelectionProviderAction;
import org.eclipse.ui.help.WorkbenchHelp;
/**
* Action for changing the value of primitives and <code>String</code> variables.
*/
public class ChangeVariableValueAction extends SelectionProviderAction {
// Fields for inline editing
protected Composite fComposite;
protected Tree fTree;
protected Label fEditorLabel;
protected Text fEditorText;
protected TreeEditor fTreeEditor;
protected IVariable fVariable;
protected boolean fKeyReleased= false;
public ChangeVariableValueAction(Viewer viewer) {
super(viewer, ActionMessages.getString("ChangeVariableValue.title")); //$NON-NLS-1$
setDescription(ActionMessages.getString("ChangeVariableValue.toolTipText")); //$NON-NLS-1$
setImageDescriptor(DebugPluginImages.getImageDescriptor(IInternalDebugUIConstants.IMG_ELCL_CHANGE_VARIABLE_VALUE));
setHoverImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_LCL_CHANGE_VARIABLE_VALUE));
setDisabledImageDescriptor(DebugPluginImages.getImageDescriptor(IInternalDebugUIConstants.IMG_DLCL_CHANGE_VARIABLE_VALUE));
fTree= ((TreeViewer)viewer).getTree();
fTreeEditor= new TreeEditor(fTree);
WorkbenchHelp.setHelp(
this,
IDebugHelpContextIds.CHANGE_VALUE_ACTION);
}
/**
* Edit the variable value with an inline text editor.
*/
protected void doActionPerformed(final IVariable variable) {
IWorkbenchWindow window= DebugUIPlugin.getActiveWorkbenchWindow();
if (window == null) {
return;
}
final Shell activeShell= window.getShell();
// If a previous edit is still in progress, finish it
if (fEditorText != null) {
saveChangesAndCleanup(fVariable, activeShell);
}
fVariable = variable;
// Use a Composite containing a Label and a Text. This allows us to edit just
// the value, while still showing the variable name.
fComposite = new Composite(fTree, SWT.NONE);
fComposite.setBackground(fTree.getBackground());
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 0;
layout.marginWidth = 0;
fComposite.setLayout(layout);
fEditorLabel = new Label(fComposite, SWT.LEFT);
fEditorLabel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
// Fix for bug 1766. Border behavior on Windows & Linux for text
// fields is different. On Linux, you always get a border, on Windows,
// you don't. Specifying a border on Linux results in the characters
// getting pushed down so that only there very tops are visible. Thus,
// we have to specify different style constants for the different platforms.
int textStyles = SWT.SINGLE | SWT.LEFT;
if (SWT.getPlatform().equals("win32")) { //$NON-NLS-1$
textStyles |= SWT.BORDER;
}
fEditorText = new Text(fComposite, textStyles);
fEditorText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL));
String valueString= ""; //$NON-NLS-1$
try {
valueString= fVariable.getValue().getValueString();
} catch (DebugException de) {
DebugUIPlugin.errorDialog(activeShell,ActionMessages.getString("ChangeVariableValue.errorDialogTitle"),ActionMessages.getString("ChangeVariableValue.errorDialogMessage"), de); //$NON-NLS-1$ //$NON-NLS-2$
}
TreeItem[] selectedItems = fTree.getSelection();
fTreeEditor.horizontalAlignment = SWT.LEFT;
fTreeEditor.grabHorizontal = true;
fTreeEditor.setEditor(fComposite, selectedItems[0]);
// There is no API on the model presentation to get just the variable name,
// so we have to make do with just calling IVariable.getName()
String varName = ""; //$NON-NLS-1$
try {
varName = fVariable.getName();
} catch (DebugException de) {
DebugUIPlugin.errorDialog(activeShell,ActionMessages.getString("ChangeVariableValue.errorDialogTitle"),ActionMessages.getString("ChangeVariableValue.errorDialogMessage"), de.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$
}
fEditorLabel.setText(varName + "="); //$NON-NLS-1$
fEditorText.setText(valueString);
fEditorText.selectAll();
fComposite.layout(true);
fComposite.setVisible(true);
fEditorText.setFocus();
// CR means commit the changes, ESC means abort changing the value
fEditorText.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent event) {
if (event.character == SWT.CR) {
if (fKeyReleased) {
saveChangesAndCleanup(fVariable, activeShell);
} else {
cleanup();
return;
}
}
if (event.character == SWT.ESC) {
cleanup();
return;
}
fKeyReleased= true;
}
});
// If the focus is lost, then act as if user hit CR and commit changes
fEditorText.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent fe) {
if (fKeyReleased) {
saveChangesAndCleanup(fVariable, activeShell);
} else {
cleanup();
}
}
});
}
/**
* If the new value validates, save it, and dispose the text widget,
* otherwise sound the system bell and leave the user in the editor.
*/
protected void saveChangesAndCleanup(IVariable variable, Shell shell) {
String newValue= fEditorText.getText();
try {
if (!variable.verifyValue(newValue)) {
shell.getDisplay().beep();
return;
}
variable.setValue(newValue);
} catch (DebugException de) {
DebugUIPlugin.errorDialog(shell, ActionMessages.getString("ChangeVariableValue.errorDialogTitle"),ActionMessages.getString("ChangeVariableValue.errorDialogMessage"), de); //$NON-NLS-2$ //$NON-NLS-1$
}
cleanup();
}
/**
* Tidy up the widgets that were used
*/
private void cleanup() {
fKeyReleased= false;
if (fEditorText != null) {
fEditorText.dispose();
fEditorText = null;
fVariable = null;
fTreeEditor.setEditor(null, null);
fComposite.setVisible(false);
}
}
/**
* Updates the enabled state of this action based
* on the selection
*/
protected void update(IStructuredSelection sel) {
Iterator iter= sel.iterator();
if (iter.hasNext()) {
Object object= iter.next();
if (object instanceof IValueModification) {
IValueModification varMod= (IValueModification)object;
if (!varMod.supportsValueModification()) {
setEnabled(false);
return;
}
setEnabled(!iter.hasNext());
return;
}
}
setEnabled(false);
}
/**
* @see Action
*/
public void run() {
Iterator iterator= getStructuredSelection().iterator();
doActionPerformed((IVariable)iterator.next());
}
/**
* @see SelectionProviderAction
*/
public void selectionChanged(IStructuredSelection sel) {
update(sel);
}
}