package org.rubypeople.rdt.internal.ui.text.hyperlinks;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.PartInitException;
import org.jruby.ast.Node;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.util.Util;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.internal.ui.actions.OpenActionUtil;
import org.rubypeople.rdt.internal.ui.actions.SelectionConverter;
import org.rubypeople.rdt.internal.ui.text.IRubyPartitions;
import org.rubypeople.rdt.internal.ui.text.RubyWordFinder;
import org.rubypeople.rdt.internal.ui.text.TextMessages;
import org.rubypeople.rdt.ui.IWorkingCopyManager;
import org.rubypeople.rdt.ui.text.hyperlinks.IHyperlinkProvider;
public class RubyElementsHyperlinkProvider implements IHyperlinkProvider {
public RubyElementsHyperlinkProvider() {}
class LazyRubyHyperlink implements IHyperlink {
private IRegion fRegion;
private IRubyScript script;
public LazyRubyHyperlink(IRubyScript script, IRegion region) {
fRegion = region;
this.script = script;
}
public IRegion getHyperlinkRegion() {
return fRegion;
}
public String getHyperlinkText() {
// TODO Auto-generated method stub
return null;
}
public String getTypeLabel() {
return "ruby";
}
public void open() {
try {
IRubyElement[] elements = SelectionConverter.codeResolve(script, fRegion.getOffset(), fRegion.getLength());
if (elements != null && elements.length > 0) {
if (elements.length > 1) {
IRubyElement selected = OpenActionUtil.selectRubyElement(elements, Display.getDefault().getActiveShell(), TextMessages.RubyElementsHyperlinkProvider_SelectInstance, TextMessages.RubyElementsHyperlinkProvider_SelectDefinition_msg);
if (selected != null)
OpenActionUtil.open(selected, true);
} else {
OpenActionUtil.open(elements[0], true);
}
}
} catch (PartInitException e) {
RubyPlugin.log(e);
} catch (RubyModelException e) {
RubyPlugin.log(e);
}
}
}
public IHyperlink getHyperlink(IEditorInput input, ITextViewer textViewer, Node node, IRegion region, boolean canShowMultipleHyperlinks) {
if (!inCode(textViewer, region)) return null;
IRegion newRegion = RubyWordFinder.findWord(textViewer.getDocument(), region.getOffset());
try {
IWorkingCopyManager manager = RubyPlugin.getDefault().getWorkingCopyManager();
IRubyScript script = manager.getWorkingCopy(input);
if (script != null) {
// Check the "word" and if it's a keyword or operator then don't offer a link
String contents = textViewer.getDocument().get(newRegion.getOffset(), newRegion.getLength());
if (Util.isOperator(contents) || Util.isKeyword(contents)) {
return null;
}
return new LazyRubyHyperlink(script, newRegion);
}
} catch (Exception e) {
RubyPlugin.log(e);
}
return null;
}
private boolean inCode(ITextViewer textViewer, IRegion region) {
try {
ITypedRegion[] regions= TextUtilities.computePartitioning(textViewer.getDocument(), IRubyPartitions.RUBY_PARTITIONING, region.getOffset(), region.getLength(), false);
if (regions == null) return false;
for (int i = 0; i < regions.length; i++) {
String type = regions[i].getType();
if (type.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
return true;
}
}
} catch (BadLocationException e1) {
// ignore
}
return false;
}
}