/** * 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( ContentProposalAdapter adapter, String infoText, ContentProposalList proposalList, int maxDisplay) { // 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( adapter.getControl().getShell(), SWT.RESIZE | SWT.ON_TOP, false, false, false, false, false, null, infoText); this.adapter = adapter; this.control = adapter.getControl(); this.labelProvider = adapter.getLabelProvider(); this.proposalList = proposalList; }
/* * In an async block, request the proposals. This is used when clients are * in the middle of processing an event that affects the widget content. By * using an async, we ensure that the widget content is up to date with the * event. */ private void asyncRecomputeProposals() { footer.setText("Searching..."); if (isValid()) { control .getDisplay() .asyncExec( new Runnable() { public void run() { adapter.recordCursorPosition(); adapter.getProposals( new IContentProposalSearchHandler() { @Override public void handleResult(ContentProposalList proposalList) { recomputeProposals(proposalList); } }); } }); } else { adapter.getProposals( new IContentProposalSearchHandler() { @Override public void handleResult(ContentProposalList proposalList) { recomputeProposals(proposalList); } }); } }
/* * (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 (adapter.getProposalAcceptanceStyle() == ContentProposalAdapter.PROPOSAL_INSERT) { Rectangle insertionBounds = adapter.getControlContentAdapter().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(); } // Constrain to the display Rectangle constrainedBounds = getConstrainedShellBounds(new Rectangle(initialX, initialY, popupSize.x, popupSize.y)); // If there has been an adjustment causing the popup to overlap // with the control, then put the popup above the control. if (constrainedBounds.y < initialY) getShell().setBounds(initialX, location.y - popupSize.y, popupSize.x, popupSize.y); else 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(); } } }); }
/** * 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(); } boolean ret = super.close(); adapter.notifyPopupClosed(); return ret; }
/* * Accept the current proposal. */ private void acceptCurrentProposal() { // Close before accepting the proposal. This is important // so that the cursor position can be properly restored at // acceptance, which does not work without focus on some controls. // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=127108 IContentProposal proposal = getSelectedProposal(); close(); if (proposal != null) { adapter.proposalAccepted(proposal); } }