diff --git a/debug/org.eclipse.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.debug.ui/META-INF/MANIFEST.MF index 860867d420f..db518583668 100644 --- a/debug/org.eclipse.debug.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.debug.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.debug.ui; singleton:=true -Bundle-Version: 3.19.100.qualifier +Bundle-Version: 3.19.200.qualifier Bundle-Activator: org.eclipse.debug.internal.ui.DebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.debug.ui/plugin.xml b/debug/org.eclipse.debug.ui/plugin.xml index d0d3ddbace7..6c5874db097 100644 --- a/debug/org.eclipse.debug.ui/plugin.xml +++ b/debug/org.eclipse.debug.ui/plugin.xml @@ -1584,7 +1584,7 @@ icon="$nl$/icons/full/elcl16/rem_all_co.svg" helpContextId="remove_all_expressions_action_context" class="org.eclipse.debug.internal.ui.actions.expressions.RemoveAllExpressionsAction" - menubarPath="expressionGroup" + menubarPath="expressionRemoveGroup" id="org.eclipse.debug.ui.debugview.popupMenu.removeAllExpressionsAction"> diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPreferenceInitializer.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPreferenceInitializer.java index 5969fe81a2c..108e4fab77d 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPreferenceInitializer.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPreferenceInitializer.java @@ -58,6 +58,8 @@ public void initializeDefaultPreferences() { prefs.setDefault(IDebugPreferenceConstants.PREF_PROMPT_DISABLE_ALL_BREAKPOINTS, true); prefs.setDefault(IDebugPreferenceConstants.PREF_PROMPT_ENABLE_ALL_BREAKPOINTS, true); prefs.setDefault(IInternalDebugUIConstants.PREF_SKIP_ALL_BREAKPOINTS_PROMPT, true); + prefs.setDefault(IDebugPreferenceConstants.PREF_PROMPT_PASTE_MULTILINE_EXPRESSIONS, + IInternalDebugUIConstants.EXPRESSION_PASTE_PROMPT); /** * Context launching preferences. Appear on the the Launching preference page diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IInternalDebugUIConstants.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IInternalDebugUIConstants.java index 93eb1e99458..28e2e44e015 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IInternalDebugUIConstants.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IInternalDebugUIConstants.java @@ -465,4 +465,22 @@ public interface IInternalDebugUIConstants { */ String PREF_SKIP_ALL_BREAKPOINTS_PROMPT = IDebugUIConstants.PLUGIN_ID + ".DisableSkipAllBreakpointsOnLaunch"; //$NON-NLS-1$ + /** + * String indicating always prompt on pasting multi-line expression + * + */ + String EXPRESSION_PASTE_PROMPT = "org.eclipse.debug.ui.expression.paste.prompt"; //$NON-NLS-1$ + + /** + * String indicating always paste as combined single expression + * + */ + String EXPRESSION_PASTE_AS_SINGLE = "org.eclipse.debug.ui.expression.paste.single"; //$NON-NLS-1$ + + /** + * String indicating always paste as multiple expressions + * + */ + String EXPRESSION_PASTE_AS_MUTLY = "org.eclipse.debug.ui.expression.paste.multi"; //$NON-NLS-1$ + } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java index cba82e7430f..19581a0839b 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java @@ -254,5 +254,11 @@ public class ActionMessages extends NLS { public static String EnableAllBreakpointsAction_3; public static String BreakpointLabelDialog; public static String RemoveFromFavoritesAction; + public static String PasteWatchExpressionsActionLabel; + public static String ExpressionPasteTitle; + public static String ExpressionPasteMultiButton; + public static String ExpressionPasteSingleButton; + public static String ExpressionPasteDialog; + public static String ExpressionPasteRemember; } \ No newline at end of file diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties index 2e1defe031d..d6dac94cb0e 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties @@ -7,7 +7,7 @@ # https://www.eclipse.org/legal/epl-2.0/ # # SPDX-License-Identifier: EPL-2.0 -# +# # Contributors: # IBM Corporation - initial API and implementation # Mike Morearty - Bug 271411 @@ -99,7 +99,7 @@ RelaunchLastAction_Error_encountered_attempting_to_relaunch_4=Error encountered # @see Bug 105733 TVT 3.1 - TCT 531 - Poor grammar in "Run Eclipse Application" and "Profile Eclipse Application" # - the following string is used to display the tooltip for run/debug/profile buttons and is # the concatenation of "{mode} {configuration name}", for example "Run HelloWorld". In some languages -# this may need to be reversed to be translated properly. +# this may need to be reversed to be translated properly. ## AbstractLaunchHistoryAction_0={0} {1} AbstractLaunchHistoryAction_1=Run @@ -164,8 +164,8 @@ ModifyWatchpointAction_0=Error ModifyWatchpointAction_1=Failed to modify watchpoint LaunchShortcutsAction_1=(none applicable) ## -# The following string is used to display launch histories using an integer mnemonic - i.e. -# "{number} {configuration name}". For example "1 HelloWorld". +# The following string is used to display launch histories using an integer mnemonic - i.e. +# "{number} {configuration name}". For example "1 HelloWorld". ## LaunchConfigurationAction_0=&{0} {1} FindDialog_1=&Specify an element to select (? = any character, * = any String): @@ -227,8 +227,9 @@ RunLastAction_0=&Run Last Launched RunLastAction_1=&Run RunLastAction_2=Run the selected resource or active editor RunLastAction_3=Run the previously launched application +PasteWatchExpressionsActionLabel=Paste Expressions ## -# The following string is used to display actions to open the launch dialog for +# The following string is used to display actions to open the launch dialog for # a specific mode - for example "Debug Configurations..." ## OpenLaunchDialogAction_1={0} Configurations... @@ -237,4 +238,10 @@ VirtualFindAction_1=Unable to locate {0} in viewer ToggleBreakpointsTargetManager_defaultToggleTarget_name = Default ToggleBreakpointsTargetManager_defaultToggleTarget_description = Default -BreakpointLabelDialog=Provide a custom label, or blank for the default label \ No newline at end of file +BreakpointLabelDialog=Provide a custom label, or blank for the default label + +ExpressionPasteMultiButton=Multiple Expressions +ExpressionPasteSingleButton=Single Expression +ExpressionPasteTitle=Paste Multiline Expression +ExpressionPasteDialog=You are pasting a multiline expression. Choose whether to paste it as a single combined expression or as separate multiple expressions. +ExpressionPasteRemember=Remember my preference next time \ No newline at end of file diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/PasteWatchExpressionsAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/PasteWatchExpressionsAction.java index 53204c5314d..32c54ec76ca 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/PasteWatchExpressionsAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/PasteWatchExpressionsAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Adobe Systems, Inc. and others. + * Copyright (c) 2009, 2025 Adobe Systems, Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * Adobe Systems, Inc. - initial API and implementation + * IBM Corporation - Improve paste expressions *******************************************************************************/ package org.eclipse.debug.internal.ui.actions.expressions; @@ -27,8 +28,6 @@ public class PasteWatchExpressionsAction extends SelectionListenerAction { public PasteWatchExpressionsAction(ExpressionView expressionView) { super(ActionMessages.PasteWatchExpressionsAction_0); fExpressionView = expressionView; -// setToolTipText(BreakpointGroupMessages.PasteWatchExpressionsAction_1); -// PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugHelpContextIds.PASTE_WATCH_EXPRESSIONS_ACTION); } @Override @@ -43,6 +42,10 @@ public boolean isEnabled() { return fExpressionView.canPaste(); } + @Override + public String getText() { + return ActionMessages.PasteWatchExpressionsActionLabel; + } } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java index 5a77da46dd6..dbfb7fa4ea5 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -17,11 +17,14 @@ import org.eclipse.debug.internal.ui.IDebugHelpContextIds; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.SWTFactory; +import org.eclipse.debug.internal.ui.actions.ActionMessages; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.RadioGroupFieldEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IWorkbench; @@ -70,6 +73,18 @@ protected void createFieldEditors() { addField(new BooleanFieldEditor(IInternalDebugUIConstants.PREF_SKIP_ALL_BREAKPOINTS_PROMPT, DebugPreferencesMessages.DebugPreferencePage_PromptSkipBreakpoints, SWT.NONE, getFieldEditorParent())); + FieldEditor edit = new RadioGroupFieldEditor(IDebugPreferenceConstants.PREF_PROMPT_PASTE_MULTILINE_EXPRESSIONS, + DebugPreferencesMessages.DebugPreferencePage_PromptMultiExpressions, 3, + new String[][] { + { ActionMessages.ExpressionPasteMultiButton, + IInternalDebugUIConstants.EXPRESSION_PASTE_AS_MUTLY }, + { ActionMessages.ExpressionPasteSingleButton, + IInternalDebugUIConstants.EXPRESSION_PASTE_AS_SINGLE }, + { DebugPreferencesMessages.LaunchingPreferencePage_5, + IInternalDebugUIConstants.EXPRESSION_PASTE_PROMPT } }, + getFieldEditorParent(), true); + addField(edit); + SWTFactory.createHorizontalSpacer(getFieldEditorParent(), 2); ColorFieldEditor mem= new ColorFieldEditor(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR, DebugPreferencesMessages.DebugPreferencePage_4, getFieldEditorParent()); addField(mem); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java index cf401c4152e..405efd58d37 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java @@ -230,4 +230,6 @@ public class DebugPreferencesMessages extends NLS { public static Object ConsoleDisableElapsedTime; + public static String DebugPreferencePage_PromptMultiExpressions; + } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties index e29da0fd839..2e9edd3b4fb 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties @@ -30,7 +30,7 @@ ConsolePreferencePage_12=Displayed &tab width: ConsolePreferencePage_13=Tab width must be between 1 and 100 inclusive. ConsolePreferencePage_11=Back&ground color: ConsolePreferencePage_Interpret_control_characters=Interpret ASCII &control characters -ConsolePreferencePage_Interpret_cr_as_control_character=Interpret Carriage &Return (\\r) as control character +ConsolePreferencePage_Interpret_cr_as_control_character=Interpret Carriage &Return (\\r) as control character ConsolePreferencePage_Enable_Word_Wrap_text=E&nable word wrap ConsoleElapsedTimeLabel=Elapsed Time Format (Choose 'None' to disable) ConsoleDefaultElapsedTimeFormat=%d:%02d:%02d @@ -59,6 +59,7 @@ DebugPreferencePage_32=&Prompt for confirmation when disabling all breakpoints DebugPreferencePage_5=Prompt for confirmation when deleting all e&xpressions DebugPreferencePage_showValuesInline=Show debug values &inline on text editors (Experimental) DebugPreferencePage_PromptSkipBreakpoints=Prompt when launching application in debug mode with 'Skip Breakpoints' enabled +DebugPreferencePage_PromptMultiExpressions=Select how multi-line expressions should be pasted in the 'Expressions View' LaunchingPreferencePage_1=&Build (if required) before launching LaunchingPreferencePage_2=Save required dirty editors before launching diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/IDebugPreferenceConstants.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/IDebugPreferenceConstants.java index 6d357225a54..c6c712340d5 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/IDebugPreferenceConstants.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/IDebugPreferenceConstants.java @@ -336,6 +336,12 @@ public interface IDebugPreferenceConstants { */ String DEBUG_VIEW_TOOLBAR_HIDDEN_PERSPECTIVES = "org.eclipse.debug.ui.Debug_view.debug_toolbar_hidden_perspectives"; //$NON-NLS-1$ String CONSOLE_ELAPSED_FORMAT = "org.eclipse.console.elapsedTimeFormat"; //$NON-NLS-1$ + + /** + * Stores the boolean preference of whether to prompt when pasting multi-line + * expressions + */ + String PREF_PROMPT_PASTE_MULTILINE_EXPRESSIONS = IDebugUIConstants.PLUGIN_ID + ".paste_multiline_exp_prompt"; //$NON-NLS-1$ } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java index 70cadd9ad59..801c99b8bf7 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -16,6 +16,8 @@ package org.eclipse.debug.internal.ui.views.expression; +import java.util.LinkedHashMap; + import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.core.DebugPlugin; @@ -23,7 +25,10 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IWatchExpression; +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.internal.ui.actions.ActionMessages; import org.eclipse.debug.internal.ui.actions.expressions.EditWatchExpressinInPlaceAction; import org.eclipse.debug.internal.ui.actions.expressions.PasteWatchExpressionsAction; import org.eclipse.debug.internal.ui.actions.variables.ChangeVariableValueAction; @@ -41,6 +46,10 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; @@ -80,6 +89,9 @@ protected void configureToolBar(IToolBarManager tbm) { protected void fillContextMenu(IMenuManager menu) { menu.add(new Separator(IDebugUIConstants.EMPTY_EXPRESSION_GROUP)); menu.add(new Separator(IDebugUIConstants.EXPRESSION_GROUP)); + if (!getClipboardText().isEmpty()) { + menu.appendToGroup(IDebugUIConstants.EXPRESSION_GROUP, fPasteAction); + } menu.add(getAction(FIND_ACTION)); ChangeVariableValueAction changeValueAction = (ChangeVariableValueAction)getAction("ChangeVariableValue"); //$NON-NLS-1$ if (changeValueAction.isApplicable()) { @@ -201,17 +213,63 @@ public boolean canPaste() { */ public boolean performPaste() { String clipboardText = getClipboardText(); + if (clipboardText != null && clipboardText.length() > 0) { - IExpressionManager expressionManager = DebugPlugin.getDefault().getExpressionManager(); - IWatchExpression watchExpression = expressionManager - .newWatchExpression(clipboardText); - expressionManager.addExpression(watchExpression); - watchExpression.setExpressionContext(getContext()); + if (clipboardText.matches("(?s).*\\R.*")) { //$NON-NLS-1$ + IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); + String pref = store.getString(IDebugPreferenceConstants.PREF_PROMPT_PASTE_MULTILINE_EXPRESSIONS); + if (pref.equals(IInternalDebugUIConstants.EXPRESSION_PASTE_PROMPT)) { + LinkedHashMap buttons = new LinkedHashMap<>(); + buttons.put(ActionMessages.ExpressionPasteMultiButton, IDialogConstants.YES_ID); + buttons.put(ActionMessages.ExpressionPasteSingleButton, IDialogConstants.NO_ID); + MessageDialogWithToggle dialog = new MessageDialogWithToggle(DebugUIPlugin.getShell(), + ActionMessages.ExpressionPasteTitle, null, + ActionMessages.ExpressionPasteDialog, + MessageDialog.QUESTION, buttons, 0, ActionMessages.ExpressionPasteRemember, false); + dialog.open(); + if (dialog.getReturnCode() == IDialogConstants.YES_ID) { + for (String expression : clipboardText.split("\n")) { //$NON-NLS-1$ + createExpression(expression); + } + store.setValue(IDebugPreferenceConstants.PREF_PROMPT_PASTE_MULTILINE_EXPRESSIONS, + dialog.getToggleState() ? IInternalDebugUIConstants.EXPRESSION_PASTE_AS_MUTLY + : IInternalDebugUIConstants.EXPRESSION_PASTE_PROMPT); + } else { + createExpression(clipboardText); + store.setValue(IDebugPreferenceConstants.PREF_PROMPT_PASTE_MULTILINE_EXPRESSIONS, + dialog.getToggleState() ? IInternalDebugUIConstants.EXPRESSION_PASTE_AS_SINGLE + : IInternalDebugUIConstants.EXPRESSION_PASTE_PROMPT); + } + } else if (pref.equals(IInternalDebugUIConstants.EXPRESSION_PASTE_AS_SINGLE)) { + createExpression(clipboardText); + } else { + for (String expression : clipboardText.split("\n")) { //$NON-NLS-1$ + createExpression(expression); + } + } + return true; + } + createExpression(clipboardText); return true; } return false; } + /** + * Creates an expression in Expression's View for the given snippet + * + * @param expression snippet to be converted as expression + */ + private void createExpression(String expression) { + if (expression.isEmpty() || expression.matches("[\\t\\n\\r]+")) { //$NON-NLS-1$ + return; + } + IExpressionManager expressionManager = DebugPlugin.getDefault().getExpressionManager(); + IWatchExpression watchExpression = expressionManager.newWatchExpression(expression); + expressionManager.addExpression(watchExpression); + watchExpression.setExpressionContext(getContext()); + } + // TODO: duplicate code from WatchExpressionAction protected IDebugElement getContext() { IAdaptable object = DebugUITools.getPartDebugContext(getSite());