All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jface.text.contentassist.ContextInformationPopup Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.text.contentassist;

import java.util.Iterator;
import java.util.Stack;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

import org.eclipse.jface.contentassist.IContentAssistSubjectControl;

import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.TextPresentation;


/**
 * This class is used to present context information to the user.
 * If multiple contexts are valid at the current cursor location,
 * a list is presented from which the user may choose one context.
 * Once the user makes their choice, or if there was only a single
 * possible context, the context information is shown in a tool tip like popup. 

* If the tool tip is visible and the user wants to see context information of * a context embedded into the one for which context information is displayed, * context information for the embedded context is shown. As soon as the * cursor leaves the embedded context area, the context information for * the embedding context is shown again. * * @see IContextInformation * @see IContextInformationValidator */ class ContextInformationPopup implements IContentAssistListener { /** * Represents the state necessary for embedding contexts. * * @since 2.0 */ static class ContextFrame { final int fBeginOffset; final int fOffset; final int fVisibleOffset; final IContextInformation fInformation; final IContextInformationValidator fValidator; final IContextInformationPresenter fPresenter; /* * @since 3.1 */ public ContextFrame(IContextInformation information, int beginOffset, int offset, int visibleOffset, IContextInformationValidator validator, IContextInformationPresenter presenter) { fInformation = information; fBeginOffset = beginOffset; fOffset = offset; fVisibleOffset = visibleOffset; fValidator = validator; fPresenter = presenter; } /* * @see java.lang.Object#equals(java.lang.Object) * @since 3.0 */ public boolean equals(Object obj) { if (obj instanceof ContextFrame) { ContextFrame frame= (ContextFrame) obj; return fInformation.equals(frame.fInformation) && fBeginOffset == frame.fBeginOffset; } return super.equals(obj); } /* * @see java.lang.Object#hashCode() * @since 3.1 */ public int hashCode() { return (fInformation.hashCode() << 16) | fBeginOffset; } } private ITextViewer fViewer; private ContentAssistant fContentAssistant; private PopupCloser fPopupCloser= new PopupCloser(); private Shell fContextSelectorShell; private Point fContextSelectorPopupSize; private Table fContextSelectorTable; private IContextInformation[] fContextSelectorInput; private String fLineDelimiter= null; private Shell fContextInfoPopup; private StyledText fContextInfoText; private TextPresentation fTextPresentation; private Stack fContextFrameStack= new Stack(); /** * The content assist subject control. * * @since 3.0 */ private IContentAssistSubjectControl fContentAssistSubjectControl; /** * The content assist subject control adapter. * * @since 3.0 */ private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter; /** * Selection listener on the text widget which is active * while a context information pop up is shown. * * @since 3.0 */ private SelectionListener fTextWidgetSelectionListener; /** * The last removed context frame is remembered in order to not re-query the * user about which context should be used. * * @since 3.0 */ private ContextFrame fLastContext= null; /** * Creates a new context information popup. * * @param contentAssistant the content assist for computing the context information * @param viewer the viewer on top of which the context information is shown */ public ContextInformationPopup(ContentAssistant contentAssistant, ITextViewer viewer) { fContentAssistant= contentAssistant; fViewer= viewer; fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer); } /** * Creates a new context information popup. * * @param contentAssistant the content assist for computing the context information * @param contentAssistSubjectControl the content assist subject control on top of which the context information is shown * @since 3.0 */ public ContextInformationPopup(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl) { fContentAssistant= contentAssistant; fContentAssistSubjectControl= contentAssistSubjectControl; fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl); } /** * Shows all possible contexts for the given cursor position of the viewer. * * @param autoActivated true if auto activated * @return a potential error message or null in case of no error */ public String showContextProposals(final boolean autoActivated) { final Control control= fContentAssistSubjectControlAdapter.getControl(); BusyIndicator.showWhile(control.getDisplay(), new Runnable() { public void run() { int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; IContextInformation[] contexts= computeContextInformation(offset); int count = (contexts == null ? 0 : contexts.length); if (count == 1) { ContextFrame frame= createContextFrame(contexts[0], offset); if (isDuplicate(frame)) validateContextInformation(); else // Show context information directly internalShowContextInfo(frame); } else if (count > 0) { // if any of the proposed context matches any of the contexts on the stack, // assume that one (so, if context info is invoked repeatedly, the current // info is kept) int index= 0; for (int i= 0; i < contexts.length; i++) { IContextInformation info= contexts[i]; ContextFrame frame= createContextFrame(info, offset); // check top of stack and stored context if (isDuplicate(frame)) { validateContextInformation(); return; } if (isLastFrame(frame)) { index= i; } // also check all other contexts for (Iterator it= fContextFrameStack.iterator(); it.hasNext(); ) { ContextFrame stackFrame= (ContextFrame) it.next(); if (stackFrame.equals(frame)) { validateContextInformation(); return; } } } // otherwise: // Precise context must be selected if (fLineDelimiter == null) fLineDelimiter= fContentAssistSubjectControlAdapter.getLineDelimiter(); createContextSelector(); setContexts(contexts, index); displayContextSelector(); } } }); return getErrorMessage(); } /** * Displays the given context information for the given offset. * * @param info the context information * @param offset the offset * @since 2.0 */ public void showContextInformation(final IContextInformation info, final int offset) { Control control= fContentAssistSubjectControlAdapter.getControl(); BusyIndicator.showWhile(control.getDisplay(), new Runnable() { public void run() { if (info == null) validateContextInformation(); else { ContextFrame frame= createContextFrame(info, offset); if (isDuplicate(frame)) validateContextInformation(); else internalShowContextInfo(frame); hideContextSelector(); } } }); } /** * Displays the given context information for the given offset. * * @param frame the context frame to display, or null * @since 3.0 */ private void internalShowContextInfo(ContextFrame frame) { if (frame != null) { fContextFrameStack.push(frame); if (fContextFrameStack.size() == 1) fLastContext= null; internalShowContextFrame(frame, fContextFrameStack.size() == 1); validateContextInformation(); } } /** * Creates a context frame for the given offset. * * @param information the context information * @param offset the offset * @return the created context frame * @since 3.0 */ private ContextFrame createContextFrame(IContextInformation information, int offset) { IContextInformationValidator validator= fContentAssistSubjectControlAdapter.getContextInformationValidator(fContentAssistant, offset); if (validator != null) { int beginOffset= (information instanceof IContextInformationExtension) ? ((IContextInformationExtension) information).getContextInformationPosition() : offset; if (beginOffset == -1) beginOffset= offset; int visibleOffset= fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x - (offset - beginOffset); IContextInformationPresenter presenter = fContentAssistSubjectControlAdapter.getContextInformationPresenter(fContentAssistant, offset); return new ContextFrame(information, beginOffset, offset, visibleOffset, validator, presenter); } return null; } /** * Compares frame with the top of the stack, returns true * if the frames are the same. * * @param frame the frame to check * @return true if frame matches the top of the stack * @since 3.0 */ private boolean isDuplicate(ContextFrame frame) { if (frame == null) return false; if (fContextFrameStack.isEmpty()) return false; // stack not empty ContextFrame top= (ContextFrame) fContextFrameStack.peek(); return frame.equals(top); } /** * Compares frame with most recently removed context frame, returns true * if the frames are the same. * * @param frame the frame to check * @return true if frame matches the most recently removed * @since 3.0 */ private boolean isLastFrame(ContextFrame frame) { return frame != null && frame.equals(fLastContext); } /** * Shows the given context frame. * * @param frame the frame to display * @param initial true if this is the first frame to be displayed * @since 2.0 */ private void internalShowContextFrame(ContextFrame frame, boolean initial) { fContentAssistSubjectControlAdapter.installValidator(frame); if (frame.fPresenter != null) { if (fTextPresentation == null) fTextPresentation= new TextPresentation(); fContentAssistSubjectControlAdapter.installContextInformationPresenter(frame); frame.fPresenter.updatePresentation(frame.fOffset, fTextPresentation); } createContextInfoPopup(); fContextInfoText.setText(frame.fInformation.getInformationDisplayString()); if (fTextPresentation != null) TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText); resize(frame.fVisibleOffset); if (initial) { if (fContentAssistant.addContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP)) { if (fContentAssistSubjectControlAdapter.getControl() != null) { fTextWidgetSelectionListener= new SelectionAdapter() { /* * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { validateContextInformation(); }}; fContentAssistSubjectControlAdapter.addSelectionListener(fTextWidgetSelectionListener); } fContentAssistant.addToLayout(this, fContextInfoPopup, ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset); fContextInfoPopup.setVisible(true); } } else { fContentAssistant.layout(ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset); } } /** * Computes all possible context information for the given offset. * * @param offset the offset * @return all possible context information for the given offset * @since 2.0 */ private IContextInformation[] computeContextInformation(int offset) { return fContentAssistSubjectControlAdapter.computeContextInformation(fContentAssistant, offset); } /** *Returns the error message generated while computing context information. * * @return the error message */ private String getErrorMessage() { return fContentAssistant.getErrorMessage(); } /** * Creates the context information popup. This is the tool tip like overlay window. */ private void createContextInfoPopup() { if (Helper.okToUse(fContextInfoPopup)) return; Control control= fContentAssistSubjectControlAdapter.getControl(); Display display= control.getDisplay(); fContextInfoPopup= new Shell(control.getShell(), SWT.NO_TRIM | SWT.ON_TOP); fContextInfoPopup.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); fContextInfoText= new StyledText(fContextInfoPopup, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP); Color c= fContentAssistant.getContextInformationPopupBackground(); if (c == null) c= display.getSystemColor(SWT.COLOR_INFO_BACKGROUND); fContextInfoText.setBackground(c); c= fContentAssistant.getContextInformationPopupForeground(); if (c == null) c= display.getSystemColor(SWT.COLOR_INFO_FOREGROUND); fContextInfoText.setForeground(c); } /** * Resizes the context information popup. * * @param offset the caret offset in widget coordinates * @since 2.0 */ private void resize(int offset) { Point size= fContextInfoText.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); final int TEXT_PAD= 0; final int BORDER_PAD= 2; final int PAD= TEXT_PAD + BORDER_PAD; size.x += PAD; Rectangle bounds= fContentAssistant.getLayoutManager().computeBoundsAboveBelow(fContextInfoPopup, size, offset); if (bounds.width < size.x) // we don't fit on the screen - try again and wrap size= fContextInfoText.computeSize(bounds.width - PAD, SWT.DEFAULT, true); size.x += TEXT_PAD; fContextInfoText.setSize(size); fContextInfoText.setLocation(1,1); size.x += BORDER_PAD; size.y += BORDER_PAD; fContextInfoPopup.setSize(size); } /** * Hides the context information popup. */ private void hideContextInfoPopup() { if (Helper.okToUse(fContextInfoPopup)) { int size= fContextFrameStack.size(); if (size > 0) { fLastContext= (ContextFrame) fContextFrameStack.pop(); -- size; } if (size > 0) { ContextFrame current= (ContextFrame) fContextFrameStack.peek(); internalShowContextFrame(current, false); } else { fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP); if (fContentAssistSubjectControlAdapter.getControl() != null) fContentAssistSubjectControlAdapter.removeSelectionListener(fTextWidgetSelectionListener); fTextWidgetSelectionListener= null; fContextInfoPopup.setVisible(false); fContextInfoPopup.dispose(); fContextInfoPopup= null; if (fTextPresentation != null) { fTextPresentation.clear(); fTextPresentation= null; } } } if (fContextInfoPopup == null) fContentAssistant.contextInformationClosed(); } /** * Creates the context selector in case the user has the choice between multiple valid contexts * at a given offset. */ private void createContextSelector() { if (Helper.okToUse(fContextSelectorShell)) return; Control control= fContentAssistSubjectControlAdapter.getControl(); fContextSelectorShell= new Shell(control.getShell(), SWT.ON_TOP | SWT.RESIZE); GridLayout layout= new GridLayout(); layout.marginWidth= 0; layout.marginHeight= 0; fContextSelectorShell.setLayout(layout); fContextSelectorShell.setBackground(control.getDisplay().getSystemColor(SWT.COLOR_BLACK)); fContextSelectorShell.addControlListener(new ControlListener() { public void controlMoved(ControlEvent e) { } public void controlResized(ControlEvent e) { fContextSelectorPopupSize= fContextSelectorShell.getSize(); } }); if (fViewer instanceof ITextViewerExtension) { final ITextViewerExtension textViewerExtension= (ITextViewerExtension)fViewer; final StyledText textWidget= fViewer.getTextWidget(); final VerifyKeyListener verifyListener= new VerifyKeyListener() { public void verifyKey(VerifyEvent event) { if (isActive() && event.keyCode == 13 && event.character == '\r' && event.widget == textWidget) { event.doit= false; insertSelectedContext(); hideContextSelector(); } } }; textViewerExtension.prependVerifyKeyListener(verifyListener); fContextSelectorShell.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { textViewerExtension.removeVerifyKeyListener(verifyListener); } }); } fContextSelectorTable= new Table(fContextSelectorShell, SWT.H_SCROLL | SWT.V_SCROLL); fContextSelectorTable.setLocation(1, 1); GridData gd= new GridData(GridData.FILL_BOTH); gd.heightHint= fContextSelectorTable.getItemHeight() * 10; gd.widthHint= 300; fContextSelectorTable.setLayoutData(gd); Point size= fContentAssistant.restoreContextSelectorPopupSize(); if (size != null) fContextSelectorShell.setSize(size); else fContextSelectorShell.pack(true); Color c= fContentAssistant.getContextSelectorBackground(); if (c == null) c= control.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND); fContextSelectorTable.setBackground(c); c= fContentAssistant.getContextSelectorForeground(); if (c == null) c= control.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND); fContextSelectorTable.setForeground(c); fContextSelectorTable.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { } public void widgetDefaultSelected(SelectionEvent e) { insertSelectedContext(); hideContextSelector(); } }); fPopupCloser.install(fContentAssistant, fContextSelectorTable); fContextSelectorTable.setHeaderVisible(false); fContentAssistant.addToLayout(this, fContextSelectorShell, ContentAssistant.LayoutManager.LAYOUT_CONTEXT_SELECTOR, fContentAssistant.getSelectionOffset()); } /** * Returns the minimal required height for the popup, may return 0 if the popup has not been * created yet. * * @return the minimal height * @since 3.3 */ int getMinimalHeight() { int height= 0; if (Helper.okToUse(fContextSelectorTable)) { int items= fContextSelectorTable.getItemHeight() * 10; Rectangle trim= fContextSelectorTable.computeTrim(0, 0, SWT.DEFAULT, items); height= trim.height; } return height; } /** * Returns the size of the context selector pop-up. * * @return a Point containing the size * @since 3.9 */ Point getContextSelectorPopupSize() { return fContextSelectorPopupSize; } /** * Causes the context information of the context selected in the context selector * to be displayed in the context information popup. */ private void insertSelectedContext() { int i= fContextSelectorTable.getSelectionIndex(); if (i < 0 || i >= fContextSelectorInput.length) return; int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; internalShowContextInfo(createContextFrame(fContextSelectorInput[i], offset)); } /** * Sets the contexts in the context selector to the given set. * * @param contexts the possible contexts * @param selectionIndex the index of the proposal to select */ private void setContexts(IContextInformation[] contexts, int selectionIndex) { if (Helper.okToUse(fContextSelectorTable)) { fContextSelectorInput= contexts; fContextSelectorTable.setRedraw(false); fContextSelectorTable.removeAll(); TableItem item; IContextInformation t; for (int i= 0; i < contexts.length; i++) { t= contexts[i]; item= new TableItem(fContextSelectorTable, SWT.NULL); if (t.getImage() != null) item.setImage(t.getImage()); item.setText(t.getContextDisplayString()); } fContextSelectorTable.select(selectionIndex); fContextSelectorTable.setRedraw(true); } } /** * Displays the context selector. */ private void displayContextSelector() { if (fContentAssistant.addContentAssistListener(this, ContentAssistant.CONTEXT_SELECTOR)) fContextSelectorShell.setVisible(true); } /** * Hides the context selector. */ private void hideContextSelector() { if (Helper.okToUse(fContextSelectorShell)) { fContentAssistant.storeContextSelectorPopupSize(); fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_SELECTOR); fPopupCloser.uninstall(); fContextSelectorShell.setVisible(false); fContextSelectorShell.dispose(); fContextSelectorShell= null; } if (!Helper.okToUse(fContextInfoPopup)) fContentAssistant.contextInformationClosed(); } /** *Returns whether the context selector has the focus. * * @return true if the context selector has the focus */ public boolean hasFocus() { if (Helper.okToUse(fContextSelectorShell)) return (fContextSelectorShell.isFocusControl() || fContextSelectorTable.isFocusControl()); return false; } /** * Hides context selector and context information popup. */ public void hide() { hideContextSelector(); hideContextInfoPopup(); } /** * Returns whether this context information popup is active. I.e., either * a context selector or context information is displayed. * * @return true if the context selector is active */ public boolean isActive() { return (Helper.okToUse(fContextInfoPopup) || Helper.okToUse(fContextSelectorShell)); } /* * @see IContentAssistListener#verifyKey(VerifyEvent) */ public boolean verifyKey(VerifyEvent e) { if (Helper.okToUse(fContextSelectorShell)) return contextSelectorKeyPressed(e); if (Helper.okToUse(fContextInfoPopup)) return contextInfoPopupKeyPressed(e); return true; } /** * Processes a key stroke in the context selector. * * @param e the verify event describing the key stroke * @return true if processing can be stopped */ private boolean contextSelectorKeyPressed(VerifyEvent e) { char key= e.character; if (key == 0) { int newSelection= fContextSelectorTable.getSelectionIndex(); int visibleRows= (fContextSelectorTable.getSize().y / fContextSelectorTable.getItemHeight()) - 1; int itemCount= fContextSelectorTable.getItemCount(); switch (e.keyCode) { case SWT.ARROW_UP : newSelection -= 1; if (newSelection < 0) newSelection= itemCount - 1; break; case SWT.ARROW_DOWN : newSelection += 1; if (newSelection > itemCount - 1) newSelection= 0; break; case SWT.PAGE_DOWN : newSelection += visibleRows; if (newSelection >= itemCount) newSelection= itemCount - 1; break; case SWT.PAGE_UP : newSelection -= visibleRows; if (newSelection < 0) newSelection= 0; break; case SWT.HOME : newSelection= 0; break; case SWT.END : newSelection= itemCount - 1; break; default : if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1 && e.keyCode != SWT.MOD2 && e.keyCode != SWT.MOD3 && e.keyCode != SWT.MOD4) hideContextSelector(); return true; } fContextSelectorTable.setSelection(newSelection); fContextSelectorTable.showSelection(); e.doit= false; return false; } else if ('\t' == key) { // switch focus to selector shell e.doit= false; fContextSelectorShell.setFocus(); return false; } else if (key == SWT.ESC) { e.doit= false; hideContextSelector(); } return true; } /** * Processes a key stroke while the info popup is up. * * @param e the verify event describing the key stroke * @return true if processing can be stopped */ private boolean contextInfoPopupKeyPressed(KeyEvent e) { char key= e.character; if (key == 0) { switch (e.keyCode) { case SWT.ARROW_LEFT: case SWT.ARROW_RIGHT: case SWT.ARROW_UP: case SWT.ARROW_DOWN: validateContextInformation(); 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(); break; } } else if (key == SWT.ESC) { e.doit= false; hideContextInfoPopup(); } else { validateContextInformation(); } return true; } /* * @see IEventConsumer#processEvent(VerifyEvent) */ public void processEvent(VerifyEvent event) { if (Helper.okToUse(fContextSelectorShell)) contextSelectorProcessEvent(event); if (Helper.okToUse(fContextInfoPopup)) contextInfoPopupProcessEvent(event); } /** * Processes a key stroke in the context selector. * * @param e the verify event describing the key stroke */ private void contextSelectorProcessEvent(VerifyEvent e) { if (e.start == e.end && e.text != null && e.text.equals(fLineDelimiter)) { e.doit= false; insertSelectedContext(); } hideContextSelector(); } /** * Processes a key stroke while the info popup is up. * * @param e the verify event describing the key stroke */ private void contextInfoPopupProcessEvent(VerifyEvent e) { if (e.start != e.end && (e.text == null || e.text.length() == 0)) validateContextInformation(); } /** * Validates the context information for the viewer's actual cursor position. */ private void validateContextInformation() { /* * Post the code in the event queue in order to ensure that the * action described by this verify key event has already been executed. * Otherwise, we'd validate the context information based on the * pre-key-stroke state. */ if (!Helper.okToUse(fContextInfoPopup)) return; fContextInfoPopup.getDisplay().asyncExec(new Runnable() { private ContextFrame fFrame= (ContextFrame) fContextFrameStack.peek(); public void run() { // only do this if no other frames have been added in between if (!fContextFrameStack.isEmpty() && fFrame == fContextFrameStack.peek()) { int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; // iterate all contexts on the stack while (Helper.okToUse(fContextInfoPopup) && !fContextFrameStack.isEmpty()) { ContextFrame top= (ContextFrame) fContextFrameStack.peek(); if (top.fValidator == null || !top.fValidator.isContextInformationValid(offset)) { hideContextInfoPopup(); // 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); resize(widgetOffset); break; } else break; } } } }); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy