📄 contentproposaladapter.java
字号:
rightProposedBounds = getConstrainedShellBounds(rightProposedBounds); // If it won't fit on the right, try the left if (rightProposedBounds.intersects(parentBounds)) { Rectangle leftProposedBounds = new Rectangle(parentBounds.x - parentBounds.width - POPUP_HORIZONTALSPACING - 1, parentBounds.y, parentBounds.width, parentBounds.height); leftProposedBounds = getConstrainedShellBounds(leftProposedBounds); // If it won't fit on the left, choose the proposed bounds // that fits the best if (leftProposedBounds.intersects(parentBounds)) { if (rightProposedBounds.x - parentBounds.x >= parentBounds.x - leftProposedBounds.x) { rightProposedBounds.x = parentBounds.x + parentBounds.width + PopupDialog.POPUP_HORIZONTALSPACING; proposedBounds = rightProposedBounds; } else { leftProposedBounds.width = parentBounds.x - POPUP_HORIZONTALSPACING - leftProposedBounds.x; proposedBounds = leftProposedBounds; } } else { // use the proposed bounds on the left proposedBounds = leftProposedBounds; } } else { // use the proposed bounds on the right proposedBounds = rightProposedBounds; } getShell().setBounds(proposedBounds); } /* * Set the text contents of the popup. */ void setContents(String newContents) { if (newContents == null) { newContents = EMPTY; } this.contents = newContents; if (text != null && !text.isDisposed()) { text.setText(contents); } } /* * Return whether the popup has focus. */ boolean hasFocus() { if (text == null || text.isDisposed()) { return false; } return text.getShell().isFocusControl() || text.isFocusControl(); } } /* * The listener installed on the target control. */ private Listener targetControlListener; /* * The listener installed in order to close the popup. */ private PopupCloserListener popupCloser; /* * The table used to show the list of proposals. */ private Table proposalTable; /* * The proposals to be shown (cached to avoid repeated requests). */ private IContentProposal[] proposals; /* * Secondary popup used to show detailed information about the selected * proposal.. */ private InfoPopupDialog infoPopup; /* * Flag indicating whether there is a pending secondary popup update. */ private boolean pendingDescriptionUpdate = false; /* * Filter text - tracked while popup is open, only if we are told to * filter */ private String filterText = EMPTY; /** * Constructs a new instance of this popup, specifying the control for * which this popup is showing content, and how the proposals should be * obtained and displayed. * * @param infoText * Text to be shown in a lower info area, or * <code>null</code> if there is no info area. */ ContentProposalPopup(String infoText) { // IMPORTANT: Use of SWT.ON_TOP is critical here for ensuring // that the target control retains focus on Mac and Linux. Without // it, the focus will disappear, keystrokes will not go to the // popup, and the popup closer will wrongly close the popup. // On platforms where SWT.ON_TOP overrides SWT.RESIZE, we will live // with this. // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=126138 super(control.getShell(), SWT.RESIZE | SWT.ON_TOP, false, false, false, false, null, infoText); this.proposals = getProposals(filterText); } /* * Overridden to force change of colors. * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=136244 * (non-Javadoc) * @see org.eclipse.jface.dialogs.PopupDialog#createContents(org.eclipse.swt.widgets.Composite) */ protected Control createContents(Composite parent) { Control contents = super.createContents(parent); changeDefaultColors(parent); return contents; } /* * Set the colors of the popup. The contents have already been created. */ private void changeDefaultColors(Control control) { applyForegroundColor(getShell().getDisplay().getSystemColor( SWT.COLOR_LIST_FOREGROUND), control); applyBackgroundColor(getShell().getDisplay().getSystemColor( SWT.COLOR_LIST_BACKGROUND), control); } /* * Creates the content area for the proposal popup. This creates a table * and places it inside the composite. The table will contain a list of * all the proposals. * * @param parent The parent composite to contain the dialog area; must * not be <code>null</code>. */ protected final Control createDialogArea(final Composite parent) { // Use virtual where appropriate (see flag definition). if (USE_VIRTUAL) { proposalTable = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL); Listener listener = new Listener() { public void handleEvent(Event event) { handleSetData(event); } }; proposalTable.addListener(SWT.SetData, listener); } else { proposalTable = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL); } // compute the proposals to force population of the table. recomputeProposals(filterText); proposalTable.setHeaderVisible(false); proposalTable.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { // If a proposal has been selected, show it in the popup. // Otherwise close the popup. if (e.item == null) { if (infoPopup != null) { infoPopup.close(); } } else { TableItem item = (TableItem) e.item; IContentProposal proposal = (IContentProposal) item .getData(); showProposalDescription(proposal.getDescription()); } } // Default selection was made. Accept the current proposal. public void widgetDefaultSelected(SelectionEvent e) { acceptCurrentProposal(); } }); return proposalTable; } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.PopupDialog.adjustBounds() */ protected void adjustBounds() { // Get our control's location in display coordinates. Point location = control.getDisplay().map(control.getParent(), null, control.getLocation()); int initialX = location.x + POPUP_OFFSET; int initialY = location.y + control.getSize().y + POPUP_OFFSET; // If we are inserting content, use the cursor position to // position the control. if (getProposalAcceptanceStyle() == PROPOSAL_INSERT) { Rectangle insertionBounds = controlContentAdapter .getInsertionBounds(control); initialX = initialX + insertionBounds.x; initialY = location.y + insertionBounds.y + insertionBounds.height; } // If there is no specified size, force it by setting // up a layout on the table. if (popupSize == null) { GridData data = new GridData(GridData.FILL_BOTH); data.heightHint = proposalTable.getItemHeight() * POPUP_CHAR_HEIGHT; data.widthHint = Math.max(control.getSize().x, POPUP_MINIMUM_WIDTH); proposalTable.setLayoutData(data); getShell().pack(); popupSize = getShell().getSize(); } getShell().setBounds(initialX, initialY, popupSize.x, popupSize.y); // Now set up a listener to monitor any changes in size. getShell().addListener(SWT.Resize, new Listener() { public void handleEvent(Event e) { popupSize = getShell().getSize(); if (infoPopup != null) { infoPopup.adjustBounds(); } } }); } /* * Handle the set data event. Set the item data of the requested item to * the corresponding proposal in the proposal cache. */ private void handleSetData(Event event) { TableItem item = (TableItem) event.item; int index = proposalTable.indexOf(item); if (0 <= index && index < proposals.length) { IContentProposal current = proposals[index]; item.setText(getString(current)); item.setImage(getImage(current)); item.setData(current); } else { // this should not happen, but does on win32 } } /* * Caches the specified proposals and repopulates the table if it has * been created. */ private void setProposals(IContentProposal[] newProposals) { if (newProposals == null || newProposals.length == 0) { newProposals = getEmptyProposalArray(); } this.proposals = newProposals; // If there is a table if (isValid()) { final int newSize = newProposals.length; if (USE_VIRTUAL) { // Set and clear the virtual table. Data will be // provided in the SWT.SetData event handler. proposalTable.setItemCount(newSize); proposalTable.clearAll(); } else { // Populate the table manually proposalTable.setRedraw(false); proposalTable.setItemCount(newSize); TableItem[] items = proposalTable.getItems(); for (int i = 0; i < items.length; i++) { TableItem item = items[i]; IContentProposal proposal = newProposals[i]; item.setText(getString(proposal)); item.setImage(getImage(proposal)); item.setData(proposal); } proposalTable.setRedraw(true); } // Default to the first selection if there is content. if (newProposals.length > 0) { selectProposal(0); } else { // No selection, close the secondary popup if it was open if (infoPopup != null) { infoPopup.close(); } } } } /* * Get the string for the specified proposal. Always return a String of * some kind. */ private String getString(IContentProposal proposal) { if (proposal == null) { return EMPTY; } if (labelProvider == null) { return proposal.getLabel() == null ? proposal.getContent() : proposal.getLabel(); } return labelProvider.getText(proposal); } /* * Get the image for the specified proposal. If there is no image * available, return null. */ private Image getImage(IContentProposal proposal) { if (proposal == null || labelProvider == null) { return null; } return labelProvider.getImage(proposal); } /* * Return an empty array. Used so that something always shows in the * proposal popup, even if no proposal provider was specified. */ private IContentProposal[] getEmptyProposalArray() { return new IContentProposal[0]; } /* * Answer true if the popup is valid, which means the table has been * created and not disposed. */ private boolean isValid() { return proposalTable != null && !proposalTable.isDisposed(); } /* * Return whether the receiver has focus. */ private boolean hasFocus() { if (!isValid()) { return false; } return getShell().isFocusControl() || proposalTable.isFocusControl(); } /* * Return the current selected proposal. */ private IContentProposal getSelectedProposal() { if (isValid()) { int i = proposalTable.getSelectionIndex(); if (proposals == null || i < 0 || i >= proposals.length) { return null; } return proposals[i]; } return null; } /* * Select the proposal at the given index. */ private void selectProposal(int index) { Assert .isTrue(index >= 0, "Proposal index should never be negative"); //$NON-NLS-1$ if (!isValid() || proposals == null || index >= proposals.length) { return; } proposalTable.setSelection(index); proposalTable.showSelection(); showProposalDescription(proposals[index].getDescription()); } /** * Opens this ContentProposalPopup. This method is extended in order to * add the control listener when the popup is opened and to invoke the * secondary popup if applicable. * * @return the return code * * @see org.eclipse.jface.window.Window#open() */ public int open() { int value = super.open(); if (popupCloser == null) { popupCloser = new PopupCloserListener(); } popupCloser.installListeners(); IContentProposal p = getSelectedProposal(); if (p != null) { showProposalDescription(p.getDescription()); } return value; } /** * Closes this popup. This method is extended to remove the control * listener. * * @return <code>true</code> if the window is (or was already) closed, * and <code>false</code> if it is still open */ public boolean close() { popupCloser.removeListeners(); if (infoPopup != null) { infoPopup.close(); } return super.close(); } /* * Get the proposals from the proposal provider. The provider may or may * not filter the proposals based on the specified filter text. */ private IContentProposal[] getProposals(String filterString) { if (proposalProvider == null || !isValid()) { return null; } int position = insertionPos; if (position == -1) { position = getControlContentAdapter().getCursorPosition( getControl()); } String contents = getControlContentAdapter().getControlContents( getControl()); IContentProposal[] proposals = proposalProvider.getProposals( contents, position); if (filterStyle != FILTER_NONE) { return filterProposals(proposals, filterString); } return proposals; } /* * Show the proposal description in a secondary popup. */ private void showProposalDescription(String description) { // If we do not already have a pending update, then // create a thread now that will show the proposal description if (!pendingDescriptionUpdate && description != null) { // Create a thread that will sleep for the specified delay // before creating the popup. We do not use Jobs since this // code must be able to run independently of the Eclipse // runtime. Runnable runnable = new Runnable() { public void run() { pendingDescriptionUpdate = true; try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -