Bug 78847 - Support evaluations for ctrl+s in the details pane
diff --git a/org.eclipse.debug.ui/schema/variableValueEditors.exsd b/org.eclipse.debug.ui/schema/variableValueEditors.exsd
index e00051c..cc10141 100644
--- a/org.eclipse.debug.ui/schema/variableValueEditors.exsd
+++ b/org.eclipse.debug.ui/schema/variableValueEditors.exsd
@@ -1,77 +1,77 @@
-<?xml version='1.0' encoding='UTF-8'?>

-<!-- Schema file written by PDE -->

-<schema targetNamespace="org.eclipse.debug.ui">

-<annotation>

-      <appInfo>

-         <meta.schema plugin="org.eclipse.debug.ui" id="variableValueEditors" name="Variable Value Editors"/>

-      </appInfo>

-      <documentation>

-         This extension point provides a mechanism for contributing variable value editors for a particular debug model. When the user invokes the &quot;Change Value...&quot; action on a variable in the Variables view, the contributed &lt;code&gt;org.eclipse.debug.ui.actions.IVariableValueEditor&lt;/code&gt; will be invoked to change the value.

-      </documentation>

-   </annotation>

-

-   <element name="extension">

-      <complexType>

-         <sequence>

-            <element ref="variableValueEditor"/>

-         </sequence>

-         <attribute name="point" type="string" use="required">

-            <annotation>

-               <documentation>

-                  

-               </documentation>

-            </annotation>

-         </attribute>

-         <attribute name="id" type="string">

-            <annotation>

-               <documentation>

-                  

-               </documentation>

-            </annotation>

-         </attribute>

-         <attribute name="name" type="string">

-            <annotation>

-               <documentation>

-                  

-               </documentation>

-            </annotation>

-         </attribute>

-      </complexType>

-   </element>

-

-   <element name="variableValueEditor">

-      <complexType>

-         <attribute name="class" type="string" use="required">

-            <annotation>

-               <documentation>

-                  Implementation of &lt;code&gt;org.eclipse.debug.ui.actions.IVariableValueEditor&lt;/code&gt;

-               </documentation>

-            </annotation>

-         </attribute>

-         <attribute name="modelId" type="string" use="required">

-            <annotation>

-               <documentation>

-                  The debug model identifier for which the given variable value editor is applicable.

-               </documentation>

-            </annotation>

-         </attribute>

-      </complexType>

-   </element>

-

-   <annotation>

-      <appInfo>

-         <meta.section type="since"/>

-      </appInfo>

-      <documentation>

-         3.1

-      </documentation>

-   </annotation>

-

-   <annotation>

-      <appInfo>

-         <meta.section type="examples"/>

-      </appInfo>

-      <documentation>

+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.debug.ui">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.debug.ui" id="variableValueEditors" name="Variable Value Editors"/>
+      </appInfo>
+      <documentation>
+         This extension point provides a mechanism for contributing variable value editors for a particular debug model. Variable value editors are used to edit/save variable values. When the user invokes the &quot;Change Value...&quot; or &quot;Assign Value&quot; (details pane) actions on a variable in the Variables view, the contributed &lt;code&gt;org.eclipse.debug.ui.actions.IVariableValueEditor&lt;/code&gt; will be invoked to change the value.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="variableValueEditor"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="variableValueEditor">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Implementation of &lt;code&gt;org.eclipse.debug.ui.actions.IVariableValueEditor&lt;/code&gt;
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="modelId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The debug model identifier for which the given variable value editor is applicable.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         3.1
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
          &lt;pre&gt;
    &lt;extension
          point=&quot;org.eclipse.debug.ui.variableValueEditors&quot;&gt;
@@ -79,39 +79,39 @@
          modelId=&quot;com.examples.myDebugModel&quot;
          class=&quot;com.examples.variables.MyVariableValueEditor&quot;/&gt;
    &lt;/extension&gt;
-&lt;/pre&gt;

-      </documentation>

-   </annotation>

-

-   <annotation>

-      <appInfo>

-         <meta.section type="apiInfo"/>

-      </appInfo>

-      <documentation>

-         Value of the attribute &lt;b&gt;class&lt;/b&gt; must be a fully qualified name of a Java class that implements the interface &lt;b&gt;org.eclipse.debug.ui.actions.IVariableValueEditor&lt;/b&gt;.

-      </documentation>

-   </annotation>

-

-   <annotation>

-      <appInfo>

-         <meta.section type="implementation"/>

-      </appInfo>

-      <documentation>

-         

-      </documentation>

-   </annotation>

-

-   <annotation>

-      <appInfo>

-         <meta.section type="copyright"/>

-      </appInfo>

-      <documentation>

+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         Value of the attribute &lt;b&gt;class&lt;/b&gt; must be a fully qualified name of a Java class that implements the interface &lt;b&gt;org.eclipse.debug.ui.actions.IVariableValueEditor&lt;/b&gt;.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
          Copyright (c) 2004 IBM Corporation and others.&lt;br&gt;
 All rights reserved. This program and the accompanying materials are made 
 available under the terms of the Common Public License v1.0 which 
 accompanies this distribution, and is available at 
-&lt;a href=&quot;http://www.eclipse.org/legal/cpl-v10.html&quot;&gt;http://www.eclipse.org/legal/cpl-v10.html&lt;/a&gt;

-      </documentation>

-   </annotation>

-

-</schema>

+&lt;a href=&quot;http://www.eclipse.org/legal/cpl-v10.html&quot;&gt;http://www.eclipse.org/legal/cpl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AssignValueAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AssignValueAction.java
index 68fbb2f..e99ca4f 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AssignValueAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AssignValueAction.java
@@ -18,6 +18,8 @@
 import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.views.variables.VariablesView;
+import org.eclipse.debug.ui.actions.IVariableValueEditor;
+import org.eclipse.debug.ui.actions.VariableValueEditorManager;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -26,7 +28,10 @@
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.actions.SelectionProviderAction;
 
-
+/**
+ * Action which assigns a value to a variable from the detail pane
+ * of the variables view.
+ */
 public class AssignValueAction extends SelectionProviderAction {
 	private VariablesView variablesView;
 	private ISourceViewer detailsViewer;
@@ -70,18 +75,30 @@
 			} catch (BadLocationException e1) {
 			}
 		}
+		IWorkbenchWindow window= DebugUIPlugin.getActiveWorkbenchWindow();
+		Shell activeShell= null;
+		if (window != null) {
+			activeShell= window.getShell();
+		}
+		
+		String modelIdentifier = variable.getModelIdentifier();
+		IVariableValueEditor editor = VariableValueEditorManager.getDefault().getVariableValueEditor(modelIdentifier);
+		if (editor != null) {
+		    if (editor.saveVariable(variable, value, activeShell)) {
+		        // If we successfully delegate to an editor which performs the save,
+		        // don't do any more work.
+		        return;
+		    }
+		}
 		
 		try {
+		    // If we failed to delegate to anyone, perform the default assignment.
 			if (variable.verifyValue(value)) {
 				variable.setValue(value);
 			} else {
-				IWorkbenchWindow window= DebugUIPlugin.getActiveWorkbenchWindow();
-				if (window == null) {
-					return;
-				}
-				Shell activeShell= window.getShell();
-				
-				DebugUIPlugin.errorDialog(activeShell, ActionMessages.getString("AssignValueAction.2"), MessageFormat.format(ActionMessages.getString("AssignValueAction.3"), new String[] {value, variable.getName()}), new StatusInfo(IStatus.ERROR, ActionMessages.getString("AssignValueAction.4")));  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			    if (activeShell != null) {
+			        DebugUIPlugin.errorDialog(activeShell, ActionMessages.getString("AssignValueAction.2"), MessageFormat.format(ActionMessages.getString("AssignValueAction.3"), new String[] {value, variable.getName()}), new StatusInfo(IStatus.ERROR, ActionMessages.getString("AssignValueAction.4")));  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			    }
 			}
 		} catch (DebugException e) {
 			DebugUIPlugin.log(e);
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ChangeVariableValueAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ChangeVariableValueAction.java
index c01acb4..29f73bb 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ChangeVariableValueAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ChangeVariableValueAction.java
@@ -12,14 +12,8 @@
 
  
 import java.text.MessageFormat;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Map;
 
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IValueModification;
 import org.eclipse.debug.core.model.IVariable;
@@ -30,6 +24,7 @@
 import org.eclipse.debug.internal.ui.views.variables.VariablesView;
 import org.eclipse.debug.ui.IDebugUIConstants;
 import org.eclipse.debug.ui.actions.IVariableValueEditor;
+import org.eclipse.debug.ui.actions.VariableValueEditorManager;
 import org.eclipse.jface.dialogs.IInputValidator;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
@@ -41,22 +36,18 @@
  * Action for changing the value of primitives and <code>String</code> variables.
  * This action will attempt to delegate the editing operation to a registered
  * variable value editor, if any is provided for the variable's debug model.
- * @see org.eclipse.debug.ui.actions.IVariableValueEditor
+ * @see org.eclipse.debug.ui.actions.VariableValueEditorManager
  */
 public class ChangeVariableValueAction extends SelectionProviderAction {
     
 	protected IVariable fVariable;
     private VariablesView fView;
     private boolean fEditing= false;
-    /**
-     * Mapping of debug model identifiers to variable value editors.
-     * The keys in this map are always Strings (model ids).
-     * The values in the map are IConfigurationElements at startup,
-     * which are replaced by IVariableValueEditors as the editors
-     * are instantiated (editors are loaded lazily, then cached).
-     */
-    private Map fEditorMap= new HashMap();
 	
+    /**
+     * Creates a new ChangeVariableValueAction for the given variables view
+     * @param view the varibles view in which this action will appear
+     */
 	public ChangeVariableValueAction(VariablesView view) {
 		super(view.getViewer(), ActionMessages.getString("ChangeVariableValue.title")); //$NON-NLS-1$
 		setDescription(ActionMessages.getString("ChangeVariableValue.toolTipText")); //$NON-NLS-1$
@@ -67,23 +58,6 @@
 			this,
 			IDebugHelpContextIds.CHANGE_VALUE_ACTION);
 		fView= view;
-		loadVariableEditors();
-	}
-	
-	/**
-	 * Loads contributors to the org.eclipse.debug.ui.variableValueEditors extension point,
-	 * for use when the user runs this action.
-	 */
-	private void loadVariableEditors() {
-		IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_VARIABLE_VALUE_EDITORS);
-		IConfigurationElement[] elements = ep.getConfigurationElements();
-		for (int i = 0; i < elements.length; i++) {
-            IConfigurationElement element = elements[i];
-            String modelId = element.getAttribute("modelId"); //$NON-NLS-1$
-            if (modelId != null) {
-                fEditorMap.put(modelId, element);
-            }
-        }
 	}
 	
 	/**
@@ -91,7 +65,6 @@
 	 */
 	protected void doActionPerformed(final IVariable variable) {
 	    Shell shell = fView.getViewSite().getShell();
-	    
 		// If a previous edit is still in progress, don't start another		
 	    if (fEditing) {
 	        return;
@@ -115,20 +88,7 @@
      */
     private boolean delegateEdit(Shell shell) {
         String modelIdentifier = fVariable.getModelIdentifier();
-        Object object = fEditorMap.get(modelIdentifier);
-        IVariableValueEditor editor= null;
-        if (object instanceof IVariableValueEditor) {
-            editor= (IVariableValueEditor) object;
-        } else if (object instanceof IConfigurationElement) {
-            try {
-                editor = (IVariableValueEditor) ((IConfigurationElement) object).createExecutableExtension("class"); //$NON-NLS-1$
-                fEditorMap.put(modelIdentifier, editor);
-            } catch (CoreException e) {
-                // If an exception occurs, loading the extension, just log it and
-                // return false to use the default editor.
-                DebugUIPlugin.log(e);
-            }
-        }
+        IVariableValueEditor editor= VariableValueEditorManager.getDefault().getVariableValueEditor(modelIdentifier);
         if (editor != null) {
             return editor.editVariable(fVariable, shell);
         }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/IVariableValueEditor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/IVariableValueEditor.java
index f4db8ec..5099c92 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/IVariableValueEditor.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/IVariableValueEditor.java
@@ -33,7 +33,23 @@
      * @return whether this editor has completed the edit operation for the given variable.
      *  <code>true</code> if no more work should be done, <code>false</code> if the debug
      *  platform should prompt the user to edit the given variable using the default
-     *  variable editor.
+     *  variable editor
      */
     public boolean editVariable(IVariable variable, Shell shell);
+    
+    /**
+     * Saves the given expression to the given variable, if appropriate. If this
+     * editor does not set the given variable's value from the given expression, this
+     * method returns false. Returning false indicates that the Debug Platform should
+     * perform the default operation to set a variable's value based on a String.
+     * 
+     * @param variable the variable to edit
+     * @param expression the expression to assign to the given variable
+     * @param shell the currently active shell, which can be used to report errors to the
+     *  user. May be <code>null</code> if no active shell could be found.
+     * @return whether this editor has completed the save operation for the given variable.
+     *  <code>true</code> if no more work should be done, <code>false</code> if the debug
+     *  platform should perform the default save operation
+     */
+    public boolean saveVariable(IVariable variable, String expression, Shell shell);
 }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/VariableValueEditorManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/VariableValueEditorManager.java
new file mode 100644
index 0000000..b12d506
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/VariableValueEditorManager.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *******************************************************************************/
+package org.eclipse.debug.ui.actions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.ui.IDebugUIConstants;
+
+/**
+ * Manager which provides the variable value editors contributed
+ * via the org.eclipse.debug.ui.variableValueEditors extension
+ * point.
+ * 
+ * @see org.eclipse.debug.ui.actions.IVariableValueEditor
+ * @since 3.1
+ */
+public class VariableValueEditorManager {
+    
+    /**
+     * Mapping of debug model identifiers to variable value editors.
+     * The keys in this map are always Strings (model ids).
+     * The values in the map are IConfigurationElements at startup,
+     * which are replaced by IVariableValueEditors as the editors
+     * are instantiated (editors are loaded lazily, then cached).
+     */
+    private Map fEditorMap= new HashMap();
+    
+    /**
+     * The singleton instance of this manager.
+     */
+    private static VariableValueEditorManager fgManager;
+
+    /**
+     * Creates a new variable value editor manager. Clients
+     * should access the singleton instance of this manager
+     * by calling getDefault()
+     */
+    private VariableValueEditorManager() {
+        loadVariableEditors();
+    }
+
+    /**
+     * Returns the singleton instance of this manager.
+     * @return the singleton instance of this manager
+     */
+    public static VariableValueEditorManager getDefault() {
+        if (fgManager == null) {
+            fgManager= new VariableValueEditorManager();
+        }
+        return fgManager;
+    }
+    
+    /**
+     * Returns the variable value editor associated with the given debug
+     * model identifier or <code>null</code> if no editor has been supplied
+     * for the given debug model.
+     * @param modelIdentifier the debug model identifier
+     * @return the variable value editor associated with the given debug model
+     *  identifier or <code>null</code>
+     */
+    public IVariableValueEditor getVariableValueEditor(String modelIdentifier) {
+        Object object = fEditorMap.get(modelIdentifier);
+        IVariableValueEditor editor= null;
+        if (object instanceof IVariableValueEditor) {
+            editor= (IVariableValueEditor) object;
+        } else if (object instanceof IConfigurationElement) {
+            try {
+                editor = (IVariableValueEditor) ((IConfigurationElement) object).createExecutableExtension("class"); //$NON-NLS-1$
+                fEditorMap.put(modelIdentifier, editor);
+            } catch (CoreException e) {
+                // If an exception occurs, loading the extension, just log it and
+                // return null.
+                DebugUIPlugin.log(e);
+            }
+        }
+        return editor;
+    }
+	
+	/**
+	 * Loads contributors to the org.eclipse.debug.ui.variableValueEditors extension point,
+	 * for use when the user runs this action.
+	 */
+	private void loadVariableEditors() {
+		IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_VARIABLE_VALUE_EDITORS);
+		IConfigurationElement[] elements = ep.getConfigurationElements();
+		for (int i = 0; i < elements.length; i++) {
+            IConfigurationElement element = elements[i];
+            String modelId = element.getAttribute("modelId"); //$NON-NLS-1$
+            if (modelId != null) {
+                fEditorMap.put(modelId, element);
+            }
+        }
+	}
+}