diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java index 3ecc45e358d..e9e08c92718 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/overlay/FindReplaceOverlay.java @@ -16,7 +16,6 @@ import static org.eclipse.ui.internal.findandreplace.overlay.FindReplaceShortcutUtil.registerActionShortcutsAtControl; import java.util.List; -import java.util.function.Consumer; import org.osgi.framework.FrameworkUtil; @@ -25,23 +24,22 @@ import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.ShellAdapter; -import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGBA; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Shell; @@ -52,22 +50,17 @@ import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.IPageChangedListener; -import org.eclipse.jface.dialogs.PageChangedEvent; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.JFaceColors; -import org.eclipse.jface.window.Window; import org.eclipse.jface.text.FindReplaceDocumentAdapter; import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider; import org.eclipse.jface.text.IFindReplaceTarget; import org.eclipse.jface.text.ITextViewer; -import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter; import org.eclipse.ui.internal.findandreplace.FindReplaceLogic; @@ -75,13 +68,12 @@ import org.eclipse.ui.internal.findandreplace.HistoryStore; import org.eclipse.ui.internal.findandreplace.SearchOptions; import org.eclipse.ui.internal.findandreplace.status.IFindReplaceStatus; -import org.eclipse.ui.part.MultiPageEditorSite; import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import org.eclipse.ui.texteditor.StatusTextEditor; -public class FindReplaceOverlay extends Dialog { +public class FindReplaceOverlay { private final class KeyboardShortcuts { private static final List SEARCH_FORWARD = List.of( // KeyStroke.getInstance(SWT.CR), KeyStroke.getInstance(SWT.KEYPAD_CR)); @@ -113,10 +105,10 @@ private final class KeyboardShortcuts { private FindReplaceLogic findReplaceLogic; private final IWorkbenchPart targetPart; - private boolean overlayOpen; private boolean replaceBarOpen; - private Composite container; + private final Composite targetControl; + private Composite overlayControl; private Button replaceToggle; private FindReplaceOverlayAction replaceToggleShortcut; @@ -143,26 +135,40 @@ private final class KeyboardShortcuts { private ToolItem replaceButton; private ToolItem replaceAllButton; - private Color backgroundToUse; + private final Color generalBackgroundColor; + private Color widgetBackgroundColor; private Color normalTextForegroundColor; private boolean positionAtTop = true; - private final TargetPartVisibilityHandler targetPartVisibilityHandler; private ContentAssistCommandAdapter contentAssistSearchField, contentAssistReplaceField; - public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget target) { - super(parent); - createFindReplaceLogic(target); + private class FixColorComposite extends Composite { + public FixColorComposite(Composite parent, int style) { + super(parent, style); + } + + @Override + public void setBackground(Color color) { + super.setBackground(generalBackgroundColor); + } + } - setShellStyle(SWT.MODELESS); - setBlockOnOpen(false); + public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget target) { targetPart = part; - targetPartVisibilityHandler = new TargetPartVisibilityHandler(targetPart, this::asyncExecIfOpen, this::close, - this::updatePlacementAndVisibility); + targetControl = getTargetControl(parent, part); + generalBackgroundColor = targetControl.getShell().getBackground(); + createFindReplaceLogic(target); + createDialog(targetControl); + overlayControl.setVisible(false); + PlatformUI.getWorkbench().getHelpSystem().setHelp(overlayControl, + IAbstractTextEditorHelpContextIds.FIND_REPLACE_OVERLAY); } - @Override - protected boolean isResizable() { - return false; + private static Composite getTargetControl(Shell targetShell, IWorkbenchPart targetPart) { + if (targetPart instanceof StatusTextEditor textEditor) { + return textEditor.getAdapter(ITextViewer.class).getTextWidget(); + } else { + return targetShell; + } } private void createFindReplaceLogic(IFindReplaceTarget target) { @@ -179,7 +185,7 @@ private void createFindReplaceLogic(IFindReplaceTarget target) { } private void performReplaceAll() { - BusyIndicator.showWhile(getShell() != null ? getShell().getDisplay() : Display.getCurrent(), + BusyIndicator.showWhile(overlayControl.getShell() != null ? overlayControl.getShell().getDisplay() : Display.getCurrent(), findReplaceLogic::performReplaceAll); evaluateFindReplaceStatus(); replaceBar.storeHistory(); @@ -187,7 +193,7 @@ private void performReplaceAll() { } private void performSelectAll() { - BusyIndicator.showWhile(getShell() != null ? getShell().getDisplay() : Display.getCurrent(), + BusyIndicator.showWhile(overlayControl.getShell() != null ? overlayControl.getShell().getDisplay() : Display.getCurrent(), findReplaceLogic::performSelectAll); searchBar.storeHistory(); } @@ -204,125 +210,27 @@ public void controlResized(ControlEvent e) { } }; - private PaintListener widgetMovementListener = __ -> asyncExecIfOpen( + private Listener targetRelocationListener = __ -> asyncExecIfOpen( FindReplaceOverlay.this::updatePlacementAndVisibility); private void asyncExecIfOpen(Runnable operation) { - Shell shell = getShell(); + Shell shell = overlayControl.getShell(); if (shell != null) { shell.getDisplay().asyncExec(() -> { - if (getShell() != null) { + if (overlayControl != null || overlayControl.isDisposed() && overlayControl.getShell() != null) { operation.run(); } }); } } - private ShellAdapter overlayDeactivationListener = new ShellAdapter() { - @Override - public void shellActivated(ShellEvent e) { - // Do nothing - } - + private FocusAdapter targetFocusListener = new FocusAdapter() { @Override - public void shellDeactivated(ShellEvent e) { + public void focusGained(FocusEvent e) { removeSearchScope(); } }; - private static class TargetPartVisibilityHandler implements IPartListener2, IPageChangedListener { - private final IWorkbenchPart targetPart; - private final IWorkbenchPart topLevelPart; - private final Consumer asyncExecIfOpen; - private final Runnable closeCallback; - private final Runnable placementUpdateCallback; - - private boolean isTopLevelVisible = true; - private boolean isNestedLevelVisible = true; - - TargetPartVisibilityHandler(IWorkbenchPart targetPart, Consumer asyncExecIfOpen, - Runnable closeCallback, - Runnable placementUpdateCallback) { - this.targetPart = targetPart; - this.asyncExecIfOpen = asyncExecIfOpen; - this.closeCallback = closeCallback; - this.placementUpdateCallback = placementUpdateCallback; - if (targetPart != null && targetPart.getSite() instanceof MultiPageEditorSite multiEditorSite) { - topLevelPart = multiEditorSite.getMultiPageEditor(); - } else { - topLevelPart = targetPart; - } - } - - @Override - public void partBroughtToTop(IWorkbenchPartReference partRef) { - if (partRef.getPart(false) == topLevelPart && !isTopLevelVisible) { - this.isTopLevelVisible = true; - asyncExecIfOpen.accept(this::adaptToPartActivationChange); - } - } - - @Override - public void partVisible(IWorkbenchPartReference partRef) { - if (partRef.getPart(false) == topLevelPart && !isTopLevelVisible) { - this.isTopLevelVisible = true; - asyncExecIfOpen.accept(this::adaptToPartActivationChange); - } - } - - @Override - public void partHidden(IWorkbenchPartReference partRef) { - if (partRef.getPart(false) == topLevelPart && isTopLevelVisible) { - this.isTopLevelVisible = false; - asyncExecIfOpen.accept(this::adaptToPartActivationChange); - } - } - - @Override - public void partClosed(IWorkbenchPartReference partRef) { - if (partRef.getPart(false) == topLevelPart) { - closeCallback.run(); - } - } - - @Override - public void pageChanged(PageChangedEvent event) { - if (event.getSource() == topLevelPart) { - boolean isPageVisible = event.getSelectedPage() == targetPart; - if (isNestedLevelVisible != isPageVisible) { - this.isNestedLevelVisible = isPageVisible; - asyncExecIfOpen.accept(this::adaptToPartActivationChange); - } - } - } - - private void adaptToPartActivationChange() { - if (targetPart.getSite().getPart() == null) { - return; - } - placementUpdateCallback.run(); - - if (!isTargetVisible()) { - targetPart.getSite().getShell().setActive(); - targetPart.setFocus(); - asyncExecIfOpen.accept(this::focusTargetWidget); - } - } - - private void focusTargetWidget() { - if (targetPart.getSite().getPart() == null) { - return; - } - if (targetPart instanceof StatusTextEditor textEditor) { - textEditor.getAdapter(ITextViewer.class).getTextWidget().forceFocus(); - } - } - - public boolean isTargetVisible() { - return isTopLevelVisible && isNestedLevelVisible; - } - } - private KeyListener closeOnTargetEscapeListener = KeyListener.keyPressedAdapter(c -> { if (c.keyCode == SWT.ESC) { this.close(); @@ -341,10 +249,9 @@ private static IDialogSettings getDialogSettings() { return settings; } - @Override - public boolean close() { - if (!overlayOpen) { - return true; + public void close() { + if (!overlayControl.isVisible()) { + return; } if (targetPart != null) { targetPart.setFocus(); @@ -352,31 +259,23 @@ public boolean close() { storeOverlaySettings(); findReplaceLogic.activate(SearchOptions.GLOBAL); - overlayOpen = false; - replaceBarOpen = false; unbindListeners(); - container.dispose(); - return super.close(); + overlayControl.setVisible(false); } - @Override - public int open() { - int returnCode = Window.OK; - if (!overlayOpen) { - returnCode = super.open(); + public void open() { + if (!overlayControl.isVisible()) { + overlayControl.setVisible(true); bindListeners(); restoreOverlaySettings(); } - overlayOpen = true; - applyOverlayColors(backgroundToUse, true); - updateFromTargetSelection(); - searchBar.forceFocus(); - - getShell().layout(); + overlayControl.layout(); + overlayControl.moveAbove(null); updatePlacementAndVisibility(); updateContentAssistAvailability(); - return returnCode; + updateFromTargetSelection(); + searchBar.forceFocus(); } private void storeOverlaySettings() { @@ -390,70 +289,57 @@ private void restoreOverlaySettings() { } } - private void applyOverlayColors(Color color, boolean tryToColorReplaceBar) { - closeTools.setBackground(color); - closeButton.setBackground(color); + private void applyOverlayColors(boolean tryToColorReplaceBar) { + overlayControl.setBackground(generalBackgroundColor); + replaceToggle.setBackground(generalBackgroundColor); + + closeTools.setBackground(widgetBackgroundColor); + closeButton.setBackground(widgetBackgroundColor); - searchTools.setBackground(color); - searchInSelectionButton.setBackground(color); - wholeWordSearchButton.setBackground(color); - regexSearchButton.setBackground(color); - caseSensitiveSearchButton.setBackground(color); - searchAllButton.setBackground(color); - searchUpButton.setBackground(color); - searchDownButton.setBackground(color); + searchTools.setBackground(widgetBackgroundColor); + searchInSelectionButton.setBackground(widgetBackgroundColor); + wholeWordSearchButton.setBackground(widgetBackgroundColor); + regexSearchButton.setBackground(widgetBackgroundColor); + caseSensitiveSearchButton.setBackground(widgetBackgroundColor); + searchAllButton.setBackground(widgetBackgroundColor); + searchUpButton.setBackground(widgetBackgroundColor); + searchDownButton.setBackground(widgetBackgroundColor); - searchBarContainer.setBackground(color); - searchBar.setBackground(color); - searchContainer.setBackground(color); + searchBarContainer.setBackground(widgetBackgroundColor); + searchBar.setBackground(widgetBackgroundColor); + searchContainer.setBackground(widgetBackgroundColor); if (replaceBarOpen && tryToColorReplaceBar) { - replaceContainer.setBackground(color); - replaceBar.setBackground(color); - replaceBarContainer.setBackground(color); - replaceTools.setBackground(color); - replaceAllButton.setBackground(color); - replaceButton.setBackground(color); + replaceContainer.setBackground(widgetBackgroundColor); + replaceBar.setBackground(widgetBackgroundColor); + replaceBarContainer.setBackground(widgetBackgroundColor); + replaceTools.setBackground(widgetBackgroundColor); + replaceAllButton.setBackground(widgetBackgroundColor); + replaceButton.setBackground(widgetBackgroundColor); } } private void unbindListeners() { - getShell().removeShellListener(overlayDeactivationListener); - if (targetPart != null && targetPart instanceof StatusTextEditor textEditor) { - Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget(); - if (targetWidget != null) { - targetWidget.getShell().removeControlListener(shellMovementListener); - targetWidget.removePaintListener(widgetMovementListener); - targetWidget.removeKeyListener(closeOnTargetEscapeListener); - targetPart.getSite().getPage().removePartListener(targetPartVisibilityHandler); - } - } + targetControl.removeFocusListener(targetFocusListener); + targetControl.removeControlListener(shellMovementListener); + targetControl.removeListener(SWT.Resize, targetRelocationListener); + targetControl.removeListener(SWT.Move, targetRelocationListener); + targetControl.removeKeyListener(closeOnTargetEscapeListener); } private void bindListeners() { - getShell().addShellListener(overlayDeactivationListener); - if (targetPart instanceof StatusTextEditor textEditor) { - Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget(); - - targetWidget.getShell().addControlListener(shellMovementListener); - targetWidget.addPaintListener(widgetMovementListener); - targetWidget.addKeyListener(closeOnTargetEscapeListener); - targetPart.getSite().getPage().addPartListener(targetPartVisibilityHandler); - } + targetControl.addFocusListener(targetFocusListener); + targetControl.addControlListener(shellMovementListener); + targetControl.addListener(SWT.Resize, targetRelocationListener); + targetControl.addListener(SWT.Move, targetRelocationListener); + targetControl.addKeyListener(closeOnTargetEscapeListener); } - @Override - public Control createContents(Composite parent) { - PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), - IAbstractTextEditorHelpContextIds.FIND_REPLACE_OVERLAY); - - backgroundToUse = new Color(getShell().getDisplay(), new RGBA(0, 0, 0, 0)); - return createDialog(parent); - } - - private Control createDialog(final Composite parent) { + private void createDialog(Composite parent) { + if (parent instanceof Scrollable scrollable) { + parent = scrollable.getParent(); + } createMainContainer(parent); - retrieveBackgroundColor(); createFindContainer(); @@ -462,10 +348,8 @@ private Control createDialog(final Composite parent) { createCloseTools(); initializeSearchShortcutHandlers(); - container.layout(); - - applyDialogFont(container); - return container; + overlayControl.layout(); + Dialog.applyDialogFont(overlayControl); } private void initializeSearchShortcutHandlers() { @@ -483,12 +367,12 @@ private void initializeSearchShortcutHandlers() { private void retrieveBackgroundColor() { if (targetPart instanceof StatusTextEditor textEditor) { Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget(); - backgroundToUse = targetWidget.getBackground(); + widgetBackgroundColor = targetWidget.getBackground(); normalTextForegroundColor = targetWidget.getForeground(); } else { - Text textBarForRetrievingTheRightColor = new Text(container, SWT.SINGLE | SWT.SEARCH); - container.layout(); - backgroundToUse = textBarForRetrievingTheRightColor.getBackground(); + Text textBarForRetrievingTheRightColor = new Text(overlayControl, SWT.SINGLE | SWT.SEARCH); + overlayControl.layout(); + widgetBackgroundColor = textBarForRetrievingTheRightColor.getBackground(); normalTextForegroundColor = textBarForRetrievingTheRightColor.getForeground(); textBarForRetrievingTheRightColor.dispose(); } @@ -586,7 +470,7 @@ private void createWholeWordsButton() { } private void createReplaceTools() { - Color warningColor = JFaceColors.getErrorText(getShell().getDisplay()); + Color warningColor = JFaceColors.getErrorText(overlayControl.getShell().getDisplay()); replaceTools = new AccessibleToolBar(replaceContainer); @@ -679,7 +563,6 @@ private void createFindContainer() { GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.FILL).applyTo(searchContainer); GridLayoutFactory.fillDefaults().numColumns(3).extendedMargins(4, 4, 3, 5).equalWidth(false) .applyTo(searchContainer); - searchContainer.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); searchBarContainer = new Composite(searchContainer, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.FILL).applyTo(searchBarContainer); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(searchBarContainer); @@ -690,20 +573,19 @@ private void createReplaceContainer() { GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.FILL).applyTo(replaceContainer); GridLayoutFactory.fillDefaults().margins(0, 1).numColumns(2).extendedMargins(4, 4, 3, 5).equalWidth(false) .applyTo(replaceContainer); - replaceContainer.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); replaceBarContainer = new Composite(replaceContainer, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.END).applyTo(replaceBarContainer); GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(false).applyTo(replaceBarContainer); } private void createMainContainer(final Composite parent) { - container = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).margins(2, 2).spacing(2, 0).applyTo(container); - GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.FILL).applyTo(container); + overlayControl = new FixColorComposite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).margins(2, 2).spacing(2, 0).applyTo(overlayControl); + GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.FILL).applyTo(overlayControl); createReplaceToggle(); - contentGroup = new Composite(container, SWT.NULL); + contentGroup = new FixColorComposite(overlayControl, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(false).spacing(2, 3).applyTo(contentGroup); GridDataFactory.fillDefaults().grab(true, true).align(GridData.FILL, GridData.FILL).applyTo(contentGroup); } @@ -711,7 +593,7 @@ private void createMainContainer(final Composite parent) { private void createReplaceToggle() { replaceToggleShortcut = new FindReplaceOverlayAction(this::toggleReplace); replaceToggleShortcut.addShortcuts(KeyboardShortcuts.TOGGLE_REPLACE); - replaceToggle = new Button(container, SWT.FLAT | SWT.PUSH); + replaceToggle = new Button(overlayControl, SWT.FLAT | SWT.PUSH); GridDataFactory.fillDefaults().grab(false, true).align(GridData.BEGINNING, GridData.FILL) .applyTo(replaceToggle); replaceToggle.setToolTipText(replaceToggleShortcut @@ -755,7 +637,7 @@ private void createReplaceDialog() { initializeReplaceShortcutHandlers(); updatePlacementAndVisibility(); - applyOverlayColors(backgroundToUse, true); + applyOverlayColors(true); replaceBar.forceFocus(); } @@ -849,56 +731,32 @@ private void repositionTextSelection() { } private void updatePlacementAndVisibility() { - if (!targetPartVisibilityHandler.isTargetVisible()) { - getShell().setVisible(false); - return; - } - if (isInvalidTargetShell()) { - asyncExecIfOpen(() -> { - if (isInvalidTargetShell()) { - close(); - setParentShell(targetPart.getSite().getShell()); - open(); - targetPart.setFocus(); - } - }); - return; - } - getShell().requestLayout(); - if (!(targetPart instanceof StatusTextEditor textEditor)) { - return; - } - - Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget(); - if (!okayToUse(targetWidget)) { + if (!okayToUse(targetControl)) { this.close(); return; } - Rectangle targetControlBounds = calculateAbsoluteControlBounds(targetWidget); + overlayControl.requestLayout(); + Rectangle targetControlBounds = calculateControlBounds(targetControl); Rectangle overlayBounds = calculateDesiredOverlayBounds(targetControlBounds); updatePosition(overlayBounds); configureDisplayedWidgetsForWidth(overlayBounds.width); updateVisibility(targetControlBounds, overlayBounds); + applyOverlayColors(replaceBarOpen); repositionTextSelection(); } - private boolean isInvalidTargetPart() { - return targetPart == null || targetPart.getSite() == null || targetPart.getSite().getShell() == null; - } - - private boolean isInvalidTargetShell() { - if (isInvalidTargetPart()) { - return false; + private Rectangle calculateControlBounds(Control control) { + Rectangle controlBounds = control.getBounds(); + int width = controlBounds.width; + int height = controlBounds.height; + int x = 0; + int y = 0; + if (control instanceof Scrollable) { + x = controlBounds.x; + y = controlBounds.y; } - return !targetPart.getSite().getShell().equals(getShell().getParent()); - } - - private Rectangle calculateAbsoluteControlBounds(Control control) { - Rectangle localControlBounds = control.getBounds(); - int width = localControlBounds.width; - int height = localControlBounds.height; if (control instanceof Scrollable scrollable) { ScrollBar verticalBar = scrollable.getVerticalBar(); ScrollBar horizontalBar = scrollable.getHorizontalBar(); @@ -912,13 +770,12 @@ private Rectangle calculateAbsoluteControlBounds(Control control) { if (control instanceof StyledText styledText) { width -= styledText.getRightMargin(); } - Point absoluteControlPosition = control.toDisplay(0, 0); - return new Rectangle(absoluteControlPosition.x, absoluteControlPosition.y, width, height); + return new Rectangle(x, y, width, height); } private Rectangle calculateDesiredOverlayBounds(Rectangle targetControlBounds) { int width = getIdealOverlayWidth(targetControlBounds); - int height = container.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; + int height = overlayControl.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; int x = targetControlBounds.x + targetControlBounds.width - width; int y = targetControlBounds.y; @@ -930,9 +787,9 @@ private Rectangle calculateDesiredOverlayBounds(Rectangle targetControlBounds) { } private void updatePosition(Rectangle overlayBounds) { - getShell().setSize(new Point(overlayBounds.width, overlayBounds.height)); - getShell().setLocation(new Point(overlayBounds.x, overlayBounds.y)); - getShell().layout(true); + overlayControl.setSize(new Point(overlayBounds.width, overlayBounds.height)); + overlayControl.setLocation(new Point(overlayBounds.x, overlayBounds.y)); + overlayControl.layout(true); } private void updateVisibility(Rectangle targetControlBounds, Rectangle overlayBounds) { @@ -943,9 +800,8 @@ private void updateVisibility(Rectangle targetControlBounds, Rectangle overlayBo } else { shallBeVisible = overlayBounds.y >= targetControlBounds.y; } - Shell shell = getShell(); - if (shallBeVisible != shell.isVisible()) { - shell.setVisible(shallBeVisible); + if (shallBeVisible != overlayControl.isVisible()) { + overlayControl.setVisible(shallBeVisible); } } @@ -985,7 +841,7 @@ private void updateFromTargetSelection() { } private void evaluateFindReplaceStatus() { - Color warningColor = JFaceColors.getErrorText(getShell().getDisplay()); + Color warningColor = JFaceColors.getErrorText(overlayControl.getShell().getDisplay()); IFindReplaceStatus status = findReplaceLogic.getStatus(); if (!status.wasSuccessful()) { @@ -1017,7 +873,7 @@ private static boolean okayToUse(Widget widget) { public void setPositionToTop(boolean shouldPositionOverlayOnTop) { positionAtTop = shouldPositionOverlayOnTop; - if (overlayOpen) { + if (overlayControl != null && overlayControl.isVisible()) { updatePlacementAndVisibility(); } } @@ -1037,4 +893,8 @@ private void setContentAssistsEnablement(boolean enable) { private void updateContentAssistAvailability() { setContentAssistsEnablement(findReplaceLogic.isAvailableAndActive(SearchOptions.REGEX)); } + + public void addDisposeListener(DisposeListener listener) { + overlayControl.addDisposeListener(listener); + } } \ No newline at end of file diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceAction.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceAction.java index e6ba4778444..55dbf526c93 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceAction.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceAction.java @@ -429,7 +429,7 @@ private void showOverlayInEditor() { overlay.setPositionToTop(shouldPositionOverlayOnTop()); hookDialogPreferenceListener(); - overlay.getShell().addDisposeListener(__ -> removeDialogPreferenceListener()); + overlay.addDisposeListener(__ -> removeDialogPreferenceListener()); } @Override diff --git a/tests/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/internal/findandreplace/overlay/OverlayAccess.java b/tests/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/internal/findandreplace/overlay/OverlayAccess.java index 2d4896e9317..2add7025bc5 100644 --- a/tests/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/internal/findandreplace/overlay/OverlayAccess.java +++ b/tests/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/internal/findandreplace/overlay/OverlayAccess.java @@ -21,14 +21,13 @@ import java.util.Objects; import java.util.Set; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Collectors; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.text.tests.Accessor; @@ -44,6 +43,8 @@ class OverlayAccess implements IFindReplaceUIAccess { FindReplaceLogic findReplaceLogic; + Composite overlayControl; + HistoryTextWrapper find; HistoryTextWrapper replace; @@ -70,11 +71,10 @@ class OverlayAccess implements IFindReplaceUIAccess { Accessor dialogAccessor; - private Supplier shellRetriever; - OverlayAccess(Accessor findReplaceOverlayAccessor) { dialogAccessor= findReplaceOverlayAccessor; findReplaceLogic= (FindReplaceLogic) findReplaceOverlayAccessor.get("findReplaceLogic"); + overlayControl= (Composite) findReplaceOverlayAccessor.get("overlayControl"); find= (HistoryTextWrapper) findReplaceOverlayAccessor.get("searchBar"); replace= (HistoryTextWrapper) findReplaceOverlayAccessor.get("replaceBar"); caseSensitive= (ToolItem) findReplaceOverlayAccessor.get("caseSensitiveSearchButton"); @@ -87,7 +87,6 @@ class OverlayAccess implements IFindReplaceUIAccess { replaceButton= (ToolItem) findReplaceOverlayAccessor.get("replaceButton"); replaceAllButton= (ToolItem) findReplaceOverlayAccessor.get("replaceAllButton"); inSelection= (ToolItem) findReplaceOverlayAccessor.get("searchInSelectionButton"); - shellRetriever= () -> ((Shell) findReplaceOverlayAccessor.invoke("getShell", null)); } @Override @@ -323,15 +322,19 @@ public void assertEnabled(SearchOptions option) { @Override public boolean isShown() { - return shellRetriever.get() != null && shellRetriever.get().isVisible(); + return overlayControl.isVisible(); } @Override public boolean hasFocus() { - Shell overlayShell= shellRetriever.get(); - Control focusControl= overlayShell.getDisplay().getFocusControl(); - Shell focusControlShell= focusControl != null ? focusControl.getShell() : null; - return focusControlShell == overlayShell; + Control focusControl= overlayControl.getDisplay().getFocusControl(); + while (focusControl != null) { + if (overlayControl == focusControl) { + return true; + } + focusControl= focusControl.getParent(); + } + return false; } }