/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.editor.quickfix; import elemental.dom.Element; import elemental.dom.Node; import elemental.events.CustomEvent; import elemental.events.Event; import elemental.events.EventListener; import elemental.html.SpanElement; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; import org.eclipse.che.ide.api.editor.codeassist.Completion; import org.eclipse.che.ide.api.editor.codeassist.CompletionProposal; import org.eclipse.che.ide.api.editor.text.LinearRange; import org.eclipse.che.ide.api.editor.texteditor.HandlesUndoRedo; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; import org.eclipse.che.ide.api.editor.texteditor.UndoableEditor; import org.eclipse.che.ide.ui.popup.PopupResources; import org.eclipse.che.ide.ui.popup.PopupWidget; import org.eclipse.che.ide.util.dom.Elements; import org.eclipse.che.ide.util.loging.Log; /** * Widget for quick assist display. */ public class QuickAssistWidget extends PopupWidget<CompletionProposal> { /** * Custom event type. */ private static final String CUSTOM_EVT_TYPE_VALIDATE = "itemvalidate"; /** The related editor. */ private final TextEditor textEditor; @AssistedInject public QuickAssistWidget(final PopupResources popupResources, @Assisted final TextEditor textEditor) { super(popupResources, "Proposals:"); this.textEditor = textEditor; } public Element createItem(final CompletionProposal proposal) { final Element element = Elements.createLiElement(popupResources.popupStyle().item()); final Element icon = Elements.createDivElement(popupResources.popupStyle().icon()); if (proposal.getIcon() != null && proposal.getIcon().getSVGImage() != null) { icon.appendChild((Node)proposal.getIcon().getSVGImage().getElement()); } else if (proposal.getIcon() != null && proposal.getIcon().getImage() != null) { icon.appendChild((Node)proposal.getIcon().getImage().getElement()); } element.appendChild(icon); final SpanElement label = Elements.createSpanElement(popupResources.popupStyle().label()); label.setInnerHTML(proposal.getDisplayString()); element.appendChild(label); final EventListener validateListener = new EventListener() { @Override public void handleEvent(final Event evt) { proposal.getCompletion(new CompletionProposal.CompletionCallback() { @Override public void onCompletion(final Completion completion) { HandlesUndoRedo undoRedo = null; if(textEditor instanceof UndoableEditor){ UndoableEditor undoableEditor = (UndoableEditor)QuickAssistWidget.this.textEditor; undoRedo = undoableEditor.getUndoRedo(); } try { if(undoRedo != null){ undoRedo.beginCompoundChange(); } completion.apply(textEditor.getDocument()); final LinearRange selection = completion.getSelection(textEditor.getDocument()); if (selection != null) { textEditor.getDocument().setSelectedRange(selection, true); } } catch (final Exception e) { Log.error(getClass(), e); } finally { if(undoRedo != null){ undoRedo.endCompoundChange(); } } } }); hide(); } }; element.addEventListener(Event.DBLCLICK, validateListener, false); element.addEventListener(CUSTOM_EVT_TYPE_VALIDATE, validateListener, false); return element; } @Override public String getEmptyMessage() { return "No proposals"; } @Override public void validateItem(final Element validatedItem) { validatedItem.dispatchEvent(createValidateEvent(CUSTOM_EVT_TYPE_VALIDATE)); super.validateItem(validatedItem); } /* Overriden to give the popup the focus for keyboard control */ @Override public boolean needsFocus() { return true; } private native CustomEvent createValidateEvent(String eventType) /*-{ return new CustomEvent(eventType); }-*/; }