diff options
author | Stephan Wahlbrink | 2017-02-16 06:58:35 +0000 |
---|---|---|
committer | Mickael Istria | 2020-01-06 10:02:50 +0000 |
commit | 1a10cc33a7e3625d0a5170461e6763c86e4e239e (patch) | |
tree | bc1b48bf93c64cf640fdb51e3e3df0b62a73871c | |
parent | 9fae9caf849cc3428e20a680145072eb0372c891 (diff) | |
download | eclipse.platform.text-1a10cc33a7e3625d0a5170461e6763c86e4e239e.tar.gz eclipse.platform.text-1a10cc33a7e3625d0a5170461e6763c86e4e239e.tar.xz eclipse.platform.text-1a10cc33a7e3625d0a5170461e6763c86e4e239e.zip |
Bug 94106: Fix hide/cleanup of content information popup stackY20200108-0435S4_15_0_M1I20200110-0905I20200110-0200I20200109-2350I20200108-2240I20200108-0600I20200108-0025I20200107-1800I20200107-0600I20200106-1805I20200106-0600
Change-Id: Ia35c3c860918d2713e29b11b409d7cacfe726fe7
Signed-off-by: Stephan Wahlbrink <sw@wahlbrink.eu>
4 files changed, 150 insertions, 13 deletions
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AbstractContentAssistTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AbstractContentAssistTest.java index c6692817b12..dbdc2703459 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AbstractContentAssistTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AbstractContentAssistTest.java @@ -26,8 +26,11 @@ import org.junit.After; import org.junit.Assert; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ST; import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; @@ -48,6 +51,8 @@ public class AbstractContentAssistTest { private SourceViewer viewer; private ContentAssistant assistant; private Document document; + + private Button button; public AbstractContentAssistTest() { @@ -64,10 +69,11 @@ public class AbstractContentAssistTest { protected void setupSourceViewer(ContentAssistant contentAssistant, String initialText) { shell= new Shell(); - shell.setSize(500, 240); - shell.setLayout(new FillLayout()); + shell.setSize(500, 280); + shell.setLayout(new GridLayout()); viewer= new SourceViewer(shell, null, SWT.NONE); + viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); assistant= contentAssistant; viewer.configure(createSourceViewerConfiguration()); @@ -77,6 +83,9 @@ public class AbstractContentAssistTest { } viewer.setDocument(document); + button= new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + shell.open(); Assert.assertTrue(new DisplayHelper() { @Override @@ -130,6 +139,41 @@ public class AbstractContentAssistTest { processEvents(); } + protected void postSourceViewerKeyEvent(char character, int stateMask, int type) { + processEvents(); + Event event= new Event(); + event.type= type; + event.widget= viewer.getTextWidget(); + event.display= viewer.getTextWidget().getDisplay(); + event.character= character; + event.stateMask= stateMask; + event.doit= true; + viewer.getTextWidget().notifyListeners(type, event); + processEvents(); + } + + protected void emulatePressArrowKey(int keyCode) { + switch (keyCode) { + case SWT.ARROW_LEFT: + viewer.getTextWidget().invokeAction(ST.COLUMN_PREVIOUS); + break; + case SWT.ARROW_RIGHT: + viewer.getTextWidget().invokeAction(ST.COLUMN_NEXT); + break; + case SWT.ARROW_UP: + viewer.getTextWidget().invokeAction(ST.LINE_UP); + break; + case SWT.ARROW_DOWN: + viewer.getTextWidget().invokeAction(ST.LINE_DOWN); + break; + } + postSourceViewerKeyEvent(keyCode, 0, ST.VerifyKey); + } + + protected void emulatePressEscKey() { + postSourceViewerKeyEvent(SWT.ESC, 0, ST.VerifyKey); + } + protected void runTextOperation(int operation) { ITextOperationTarget textOperationTarget= viewer.getTextOperationTarget(); @@ -142,6 +186,11 @@ public class AbstractContentAssistTest { } + public Button getButton() { + return button; + } + + protected void processEvents() { DisplayHelper.driveEventQueue(shell.getDisplay()); } diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationPresenterTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationPresenterTest.java index 80b8cefc0d1..31fa47066ab 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationPresenterTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationPresenterTest.java @@ -102,7 +102,7 @@ public class ContextInformationPresenterTest extends AbstractContentAssistTest { new StyleRange(0, 3, null, null, SWT.BOLD) }, getInfoStyleRanges(this.infoShell)); - postSourceViewerKeyEvent(SWT.ARROW_RIGHT, 0, SWT.KeyDown); + emulatePressArrowKey(SWT.ARROW_RIGHT); assertEquals("idx= 0", getInfoText(this.infoShell)); assertArrayEquals(new StyleRange[] { diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationTest.java index 1d5d6afa85e..27a1f96c79d 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/ContextInformationTest.java @@ -20,6 +20,7 @@ import java.util.List; import org.junit.Test; +import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; @@ -88,6 +89,92 @@ public class ContextInformationTest extends AbstractContentAssistTest { new Accessor(getContentAssistant(), ContentAssistant.class).invoke("hide", new Object[0]); } + @Test + public void testContextInfo_hide_focusOut() throws Exception { + setupSourceViewer(createBarContentAssist(), BarContentAssistProcessor.PROPOSAL); + + final List<Shell> beforeShells = getCurrentShells(); + + selectAndReveal(4, 0); + processEvents(); + + triggerContextInformation(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 0", getInfoText(this.infoShell)); + + selectAndReveal(8, 0); + processEvents(); + + triggerContextInformation(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 1", getInfoText(this.infoShell)); + + // Hide all + getButton().setFocus(); + processEvents(); + assertTrue(this.infoShell.isDisposed() || !this.infoShell.isVisible()); + } + + @Test + public void testContextInfo_hide_keyEsc() throws Exception { + setupSourceViewer(createBarContentAssist(), BarContentAssistProcessor.PROPOSAL); + + final List<Shell> beforeShells = getCurrentShells(); + + selectAndReveal(4, 0); + processEvents(); + + triggerContextInformation(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 0", getInfoText(this.infoShell)); + + selectAndReveal(8, 0); + processEvents(); + + triggerContextInformation(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 1", getInfoText(this.infoShell)); + + emulatePressEscKey(); + processEvents(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 0", getInfoText(this.infoShell)); + + emulatePressEscKey(); + processEvents(); + assertTrue(this.infoShell.isDisposed() || !this.infoShell.isVisible()); + } + + @Test + public void testContextInfo_hide_validRange() throws Exception { + setupSourceViewer(createBarContentAssist(), BarContentAssistProcessor.PROPOSAL + '\n'); + + final List<Shell> beforeShells = getCurrentShells(); + + selectAndReveal(4, 0); + processEvents(); + + triggerContextInformation(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 0", getInfoText(this.infoShell)); + + selectAndReveal(8, 0); + processEvents(); + + triggerContextInformation(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 1", getInfoText(this.infoShell)); + + emulatePressArrowKey(SWT.ARROW_LEFT); + processEvents(); + this.infoShell= findNewShell(beforeShells); + assertEquals("idx= 0", getInfoText(this.infoShell)); + + emulatePressArrowKey(SWT.ARROW_DOWN); + processEvents(); + assertTrue(this.infoShell.isDisposed() || !this.infoShell.isVisible()); + } + static String getInfoText(final Shell shell) { assertTrue(shell.isVisible()); diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContextInformationPopup.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContextInformationPopup.java index 742d8699942..7bf6d32af33 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContextInformationPopup.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContextInformationPopup.java @@ -11,6 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Stephan Wahlbrink <sw@wahlbrink.eu> - Bug 512251 - Fix IllegalArgumentException in ContextInformationPopup + * Stephan Wahlbrink <sw@wahlbrink.eu> - Bug 94106 - Fix hide/cleanup of content information popup stack *******************************************************************************/ package org.eclipse.jface.text.contentassist; @@ -460,8 +461,11 @@ class ContextInformationPopup implements IContentAssistListener { /** * Hides the context information popup. + * + * @param all <code>true</code> to hide popups at all, + * <code>false</code> to restore previous context frame if possible */ - private void hideContextInfoPopup() { + private void hideContextInfoPopup(boolean all) { if (Helper.okToUse(fContextInfoPopup)) { @@ -470,7 +474,7 @@ class ContextInformationPopup implements IContentAssistListener { fLastContext= fContextFrameStack.pop(); -- size; - if (size > 0) { + if (size > 0 && !all) { ContextFrame current= fContextFrameStack.peek(); if (canShowFrame(current)) { internalShowContextFrame(current, false); @@ -478,9 +482,6 @@ class ContextInformationPopup implements IContentAssistListener { } // continue - try next } - else { - break; - } } fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP); @@ -702,7 +703,7 @@ class ContextInformationPopup implements IContentAssistListener { */ public void hide() { hideContextSelector(); - hideContextInfoPopup(); + hideContextInfoPopup(true); } /** @@ -815,13 +816,13 @@ class ContextInformationPopup implements IContentAssistListener { break; default: if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1 && e.keyCode != SWT.MOD2 && e.keyCode != SWT.MOD3 && e.keyCode != SWT.MOD4) - hideContextInfoPopup(); + hideContextInfoPopup(true); break; } } else if (key == SWT.ESC) { e.doit= false; - hideContextInfoPopup(); + hideContextInfoPopup(false); } else { validateContextInformation(); } @@ -888,7 +889,7 @@ class ContextInformationPopup implements IContentAssistListener { while (Helper.okToUse(fContextInfoPopup) && !fContextFrameStack.isEmpty()) { ContextFrame top= fContextFrameStack.peek(); if (top.fValidator == null || !top.fValidator.isContextInformationValid(offset)) { - hideContextInfoPopup(); // loop variant: reduces the number of contexts on the stack + hideContextInfoPopup(false); // loop variant: reduces the number of contexts on the stack } else if (top.fPresenter != null && top.fPresenter.updatePresentation(offset, fTextPresentation)) { int widgetOffset= fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x; TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText); |