/******************************************************************************* * Copyright (c) 2004, 2010 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.client.ui.rcp.controllers; import org.apache.commons.lang.Validate; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.IContentProposalListener2; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jubula.client.ui.rcp.utils.ContentAssistUtil; import org.eclipse.jubula.client.ui.rcp.widgets.CheckedText; import org.eclipse.jubula.client.ui.rcp.widgets.CheckedText.IValidator; import org.eclipse.swt.widgets.Composite; /** * Cell editor with content assist and validation (both optional). * * Based on JFace Snippet: * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jface.snippets/Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/Snippet060TextCellEditorWithContentProposal.java?view=markup * * @author BREDEX GmbH * @created Apr 6, 2010 */ public class ContentAssistCellEditor extends TextCellEditor { /** whether the content proposal popup is currently open */ private boolean m_popupOpen = false; /** * Constructor * * @param parent The parent control. * @param contentProposalProvider The proposal provider for content assist. * May be <code>null</code>, in which case the * editor will not support content assist. * @param validator The validator to use. May be <code>null</code>, in which * case the editor will not support validation. * @param proposalAcceptanceStyle * The integer style that indicates how an accepted proposal * affects the control's content. See * {@link ContentProposalAdapter#setProposalAcceptanceStyle(int)}. */ public ContentAssistCellEditor(Composite parent, IContentProposalProvider contentProposalProvider, IValidator validator, int proposalAcceptanceStyle) { super(parent); Validate.notNull(text); enableValidation(validator); enableContentProposal(contentProposalProvider, proposalAcceptanceStyle); } /** * Activates validation (if it is supported). * * @param validator The validator. */ private void enableValidation(final IValidator validator) { if (validator != null) { text.addVerifyListener( new CheckedText.ValidationListener(validator)); } } /** * Activates content assist (if it is supported). * * @param contentProposalProvider * The proposal provider to use for content assist. * @param proposalAcceptanceStyle * The integer style that indicates how an accepted proposal * affects the control's content. See * {@link ContentProposalAdapter#setProposalAcceptanceStyle(int)}. * */ private void enableContentProposal( IContentProposalProvider contentProposalProvider, int proposalAcceptanceStyle) { if (contentProposalProvider != null) { ContentProposalAdapter contentProposalAdapter = new ContentProposalAdapter(text, new TextContentAdapter(), contentProposalProvider, ContentAssistUtil.getTriggerKeyStroke(), ContentAssistUtil.getTriggerChars()); contentProposalAdapter.setFilterStyle( ContentProposalAdapter.FILTER_NONE); contentProposalAdapter.setProposalAcceptanceStyle( proposalAcceptanceStyle); // Listen for popup open/close events to be able to handle focus events // correctly contentProposalAdapter.addContentProposalListener( new IContentProposalListener2() { @SuppressWarnings("synthetic-access") public void proposalPopupClosed( ContentProposalAdapter adapter) { m_popupOpen = false; } @SuppressWarnings("synthetic-access") public void proposalPopupOpened( ContentProposalAdapter adapter) { m_popupOpen = true; } }); } } /** * * {@inheritDoc} */ protected void focusLost() { if (!m_popupOpen) { // Focus lost deactivates the cell editor. // This must not happen if focus lost was caused by activating // the completion proposal popup. super.focusLost(); } } /** * * {@inheritDoc} */ protected boolean dependsOnExternalFocusListener() { // Always return false; // Otherwise, the ColumnViewerEditor will install an additional focus // listener // that cancels cell editing on focus lost, even if focus gets lost due // to // activation of the completion proposal popup. See also bug http://eclip.se/58777. return false; } }