/*
* Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC
* All rights reserved.
*
* The source code of this document is proprietary work, and is not licensed for
* distribution. For information about licensing, contact Sam Harwell at:
* sam@tunnelvisionlabs.com
*/
package org.tvl.goworks.editor.go.navigation;
import com.tvl.spi.editor.completion.CompletionProvider;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JEditorPane;
import javax.swing.SwingUtilities;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import org.antlr.v4.runtime.Token;
import org.netbeans.api.editor.mimelookup.MimeLookup;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.editor.mimelookup.MimeRegistration;
import org.netbeans.api.editor.settings.EditorStyleConstants;
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProviderExt;
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkType;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.openide.cookies.EditorCookie;
import org.openide.loaders.DataObject;
import org.openide.util.Lookup;
import org.tvl.goworks.editor.GoEditorKit;
import org.tvl.goworks.editor.go.completion.GoCompletionProvider;
import org.tvl.goworks.editor.go.highlighter.GoHighlighter.TooltipResolver;
import org.tvl.goworks.editor.go.parser.GoParser;
/**
*
* @author Sam Harwell
*/
@MimeRegistration(mimeType=GoEditorKit.GO_MIME_TYPE, service=HyperlinkProviderExt.class)
public class GoHyperlinkProvider implements HyperlinkProviderExt {
// -J-Dorg.tvl.goworks.editor.go.navigation.GoHyperlinkProvider.level=FINE
private static final Logger LOGGER = Logger.getLogger(GoHyperlinkProvider.class.getName());
@Override
public Set<HyperlinkType> getSupportedHyperlinkTypes() {
return EnumSet.of(HyperlinkType.GO_TO_DECLARATION, HyperlinkType.ALT_HYPERLINK);
}
@Override
public boolean isHyperlinkPoint(Document doc, int offset, HyperlinkType type) {
return getHyperlinkSpan(doc, offset, type) != null;
}
@Override
public int[] getHyperlinkSpan(Document doc, int offset, HyperlinkType type) {
final Lookup lookup = MimeLookup.getLookup(MimePath.get(GoEditorKit.GO_MIME_TYPE));
Collection<? extends CompletionProvider> providers = lookup.lookupAll(CompletionProvider.class);
GoCompletionProvider provider = null;
for (CompletionProvider current : providers) {
if (!(current instanceof GoCompletionProvider)) {
continue;
}
provider = (GoCompletionProvider)current;
}
if (provider == null) {
return null;
}
Token token = provider.getContext(doc, offset);
if (token == null) {
return null;
}
switch (token.getType()) {
case GoParser.IDENTIFIER:
break;
default:
return null;
}
return new int[] { token.getStartIndex(), token.getStopIndex() + 1 };
}
@Override
public void performClickAction(Document doc, int offset, HyperlinkType type) {
JTextComponent component = getComponent(doc);
if (component == null) {
return;
}
switch (type) {
case GO_TO_DECLARATION:
GoToSupport.goTo(component, offset, false);
break;
// case ALT_HYPERLINK:
// JTextComponent focused = EditorRegistry.focusedComponent();
// if (focused != null && focused.getDocument() == doc) {
// focused.setCaretPosition(offset);
// GoToImplementation.goToImplementation(focused);
// }
// break;
}
}
@Override
public String getTooltipText(Document doc, int offset, HyperlinkType type) {
JTextComponent component = getComponent(doc);
if (component == null) {
return "";
}
TooltipResolver tooltipResolver = new TooltipResolver();
return tooltipResolver.getValue(component, doc, EditorStyleConstants.Tooltip, offset, offset);
}
private static JTextComponent getComponent(Document doc) {
DataObject dataObject = NbEditorUtilities.getDataObject(doc);
if (dataObject == null) {
return null;
}
final EditorCookie editorCookie = dataObject.getLookup().lookup(EditorCookie.class);
if (editorCookie == null) {
return null;
}
JEditorPane[] panes;
if (SwingUtilities.isEventDispatchThread()) {
panes = editorCookie.getOpenedPanes();
} else {
final JEditorPane[][] panesArray = new JEditorPane[1][];
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
panesArray[0] = editorCookie.getOpenedPanes();
}
});
} catch (InterruptedException | InvocationTargetException ex) {
LOGGER.log(Level.WARNING, "An exception occurred while locating a document.", ex);
return null;
}
panes = panesArray[0];
}
if (panes == null || panes.length == 0) {
return null;
}
return panes[0];
}
}