Skip to content

Commit 69f6e45

Browse files
committed
Find/replace overlay: allow pasting in multi-page editors #2509
While actions of the target editor are properly deactivated when the target is an ordinary, single-page editor, the same does not happen when the target is a multi-page editor. In consequence, for example, you cannot paste clipboard content into the overlay via the according keyboard shortcut (CTRL+V), but it will paste into the target editor instead. With this change, the functionality to deactivate target editor actions is extended to also deactivate the relevant global actions (cut, copy, paste, etc.) that editors like multi-page editors fall back to. Fixes to #2509
1 parent 64af72a commit 69f6e45

File tree

1 file changed

+42
-2
lines changed
  • bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay

1 file changed

+42
-2
lines changed

bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
*******************************************************************************/
1414
package org.eclipse.ui.internal.findandreplace.overlay;
1515

16-
import java.lang.reflect.InvocationTargetException;
1716
import java.lang.reflect.Method;
17+
import java.util.HashMap;
1818
import java.util.List;
19+
import java.util.Map;
1920
import java.util.concurrent.atomic.AtomicReference;
2021

2122
import org.osgi.framework.FrameworkUtil;
@@ -46,6 +47,7 @@
4647

4748
import org.eclipse.core.runtime.Status;
4849

50+
import org.eclipse.jface.action.IAction;
4951
import org.eclipse.jface.bindings.keys.KeyStroke;
5052
import org.eclipse.jface.dialogs.Dialog;
5153
import org.eclipse.jface.dialogs.IDialogSettings;
@@ -60,6 +62,7 @@
6062
import org.eclipse.jface.text.IFindReplaceTarget;
6163
import org.eclipse.jface.text.ITextViewer;
6264

65+
import org.eclipse.ui.IActionBars;
6366
import org.eclipse.ui.IWorkbenchPart;
6467
import org.eclipse.ui.PlatformUI;
6568
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
@@ -70,10 +73,12 @@
7073
import org.eclipse.ui.internal.findandreplace.SearchOptions;
7174
import org.eclipse.ui.internal.findandreplace.status.IFindReplaceStatus;
7275
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
76+
import org.eclipse.ui.part.MultiPageEditorSite;
7377

7478
import org.eclipse.ui.texteditor.AbstractTextEditor;
7579
import org.eclipse.ui.texteditor.FindReplaceAction;
7680
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
81+
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
7782
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
7883
import org.eclipse.ui.texteditor.StatusTextEditor;
7984

@@ -148,6 +153,8 @@ private final class KeyboardShortcuts {
148153
private ContentAssistCommandAdapter contentAssistSearchField, contentAssistReplaceField;
149154

150155
private FocusListener targetActionActivationHandling = new FocusListener() {
156+
private DeactivateGlobalActionHandlers globalActionHandlerDeaction;
157+
151158
@Override
152159
public void focusGained(FocusEvent e) {
153160
setTextEditorActionsActivated(false);
@@ -167,15 +174,48 @@ private void setTextEditorActionsActivated(boolean state) {
167174
if (!(targetPart instanceof AbstractTextEditor)) {
168175
return;
169176
}
177+
if (targetPart.getSite() instanceof MultiPageEditorSite multiEditorSite) {
178+
if (!state && globalActionHandlerDeaction == null) {
179+
globalActionHandlerDeaction = new DeactivateGlobalActionHandlers(multiEditorSite.getActionBars());
180+
} else if (state && globalActionHandlerDeaction != null) {
181+
globalActionHandlerDeaction.reactivate();
182+
globalActionHandlerDeaction = null;
183+
}
184+
}
170185
try {
171186
Method method = AbstractTextEditor.class.getDeclaredMethod("setActionActivation", boolean.class); //$NON-NLS-1$
172187
method.setAccessible(true);
173188
method.invoke(targetPart, Boolean.valueOf(state));
174-
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException | SecurityException | NoSuchMethodException ex) {
189+
} catch (IllegalArgumentException | ReflectiveOperationException ex) {
175190
TextEditorPlugin.getDefault().getLog()
176191
.log(Status.error("cannot (de-)activate actions for text editor", ex)); //$NON-NLS-1$
177192
}
178193
}
194+
195+
static final class DeactivateGlobalActionHandlers {
196+
private final static List<String> ACTIONS = List.of(ITextEditorActionConstants.CUT,
197+
ITextEditorActionConstants.COPY, ITextEditorActionConstants.PASTE,
198+
ITextEditorActionConstants.DELETE, ITextEditorActionConstants.SELECT_ALL,
199+
ITextEditorActionConstants.FIND);
200+
201+
private final Map<String, IAction> deactivatedActions = new HashMap<>();
202+
private final IActionBars actionBars;
203+
204+
public DeactivateGlobalActionHandlers(IActionBars actionBars) {
205+
this.actionBars = actionBars;
206+
for (String actionID : ACTIONS) {
207+
deactivatedActions.putIfAbsent(actionID, actionBars.getGlobalActionHandler(actionID));
208+
actionBars.setGlobalActionHandler(actionID, null);
209+
}
210+
}
211+
212+
public void reactivate() {
213+
for (String actionID : deactivatedActions.keySet()) {
214+
actionBars.setGlobalActionHandler(actionID, deactivatedActions.get(actionID));
215+
}
216+
}
217+
}
218+
179219
};
180220

181221
public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget target) {

0 commit comments

Comments
 (0)