Skip to main content
summaryrefslogtreecommitdiffstats
blob: 868d459eab65c5aa56d0f8f5377d235448488002 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package org.eclipse.debug.internal.ui;

/*
 * (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.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
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;

	private static final String PREFIX= "change_variable_value_action.";
	private static final String ERROR= PREFIX + "error.";
	private static final String DIALOG_TITLE= PREFIX + "dialog.title";
	private static final String DIALOG_MESSAGE= PREFIX + "dialog.message";
	private static final String DIALOG_INVALID= PREFIX + "dialog.invalid";
	
	public ChangeVariableValueAction(Viewer viewer) {
		super(viewer, DebugUIUtils.getResourceString(PREFIX + TEXT));
		setDescription(DebugUIUtils.getResourceString(PREFIX + DESCRIPTION));
		fTree= ((TreeViewer)viewer).getTree();
		fTreeEditor= new TreeEditor(fTree);
		WorkbenchHelp.setHelp(
			this,
			new Object[] { IDebugHelpContextIds.CHANGE_VALUE_ACTION });
	}
	
	/**
	 * Edit the variable value with an inline text editor.  
	 */
	protected void doActionPerformed(final IVariable variable) {
		final Shell activeShell= DebugUIPlugin.getActiveWorkbenchWindow().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));
		fEditorText = new Text(fComposite, SWT.BORDER | SWT.SINGLE | SWT.LEFT);
		fEditorText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL));
		String valueString= "";
		try {
			valueString= fVariable.getValue().getValueString();
		} catch (DebugException de) {
			DebugUIUtils.errorDialog(activeShell, ERROR, de.getStatus());			
		}
		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 = "";
		try {
			varName = fVariable.getName();
		} catch (DebugException de) {
		}
		fEditorLabel.setText(varName + "=");

		fEditorText.setText(valueString);
		fEditorText.selectAll();
		
		fComposite.layout(true);
		fComposite.setVisible(true);
		fEditorText.setFocus();
	
		// CR means commit the change, ESC means abort changing the value
		fEditorText.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent event) {
				if (event.character == SWT.CR) {
					saveChangesAndCleanup(fVariable, activeShell);
				}
				if (event.character == SWT.ESC) {
					cleanup();
				}
			}
		});
	
		// If the focus is lost, then act as if user hit CR and commit change
		fEditorText.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent fe) {
				saveChangesAndCleanup(fVariable, activeShell);
			}
		});				
	}
	
	/** 
	 * 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) {
			DebugUIUtils.errorDialog(shell, ERROR, de.getStatus());			
		}
		cleanup();		
	}

	/**
	 * Tidy up the widgets that were used
	 */
	private void cleanup() {
		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);
	}
}

Back to the top