Commit d3b473ac authored by Johannes Roith's avatar Johannes Roith
Browse files

Implement Hyperlinks. There is a major bug with positioning, which still has to be fixed.

parent 6eb200a0
......@@ -13,7 +13,15 @@ import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.swt.custom.StyleRange;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.Visitor;
import de.in.tum.www2.cup.analysis.WildcardVisitor;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.IHasDeclarationReference;
import de.in.tum.www2.cup.ast.IHasDefinitionReference;
import de.in.tum.www2.cup.ast.IWithName;
import de.in.tum.www2.cup.ast.Name;
import de.in.tum.www2.cup.ast.ParserResult;
public class CupHyperlinkDetector implements IHyperlinkDetector {
......@@ -23,12 +31,73 @@ public class CupHyperlinkDetector implements IHyperlinkDetector {
this.editor = editor;
}
static public class HyperlinkingVisitor extends Visitor<Object> {
static public class HyperlinkingVisitor extends WildcardVisitor<Object> {
// TODO: we should assume that references have been resolved,
// which means, we can easily look up the declaration
// and definition locations.
IRegion inputRegion;
CupTextEditor editor;
ITextViewer textViewer;
List<IHyperlink> links;
private int offset;
public List<IHyperlink> getLinks() {
return links;
}
public HyperlinkingVisitor(IRegion region,
CupTextEditor editor, ITextViewer textViewer)
{
this.links = new ArrayList<IHyperlink>();
this.inputRegion = inputRegion;
this.editor = editor;
this.textViewer = textViewer;
IDocument document = textViewer.getDocument();
offset = region.getOffset();
/*
IRegion lineRegion = null;
String candidate = null;
try {
lineRegion = document.getLineInformationOfOffset(offset);
candidate = document.get(lineRegion.getOffset(), lineRegion.getLength());
} catch (org.eclipse.jface.text.BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
}
@Override
public void postVisitWildcard(AbstractNode node, Object data) {
if (node instanceof IHasDefinitionReference && node instanceof IWithName) {
AbstractNode def = ((IHasDefinitionReference) node).getDefinition();
Name name = ((IWithName) node).getName();
if (def != null && name != null && name.name != null) {
if (name.getBegin().getOffsetFromStart() < offset)
return;
Region outputRegion = new Region(
name.getBegin().getOffsetFromStart(),
name.name.length());
links.add(new CupHyperlink(outputRegion, editor, textViewer,
def.getBegin().getOffsetFromStart(), 1));
}
}
}
@Override
public Object preVisitWildcard(AbstractNode node, Object data) {
return data;
}
}
static public class CupHyperlink implements IHyperlink {
......@@ -72,126 +141,19 @@ public class CupHyperlinkDetector implements IHyperlinkDetector {
}
/*
// https://eclipse.googlesource.com/egit/egit/+/0906cde57ce4ae4117151d96a2af82e0dc076593%5E!/
@Override
public static StyleRange[] getHyperlinkDetectorStyleRanges(
ITextViewer textViewer, IHyperlinkDetector[] hyperlinkDetectors) {
List<StyleRange> styleRangeList = new ArrayList<StyleRange>();
if (hyperlinkDetectors != null && hyperlinkDetectors.length > 0) {
for (int i = 0; i < textViewer.getTextWidget().getText().length(); i++) {
IRegion region = new Region(i, 0);
for (IHyperlinkDetector hyperLinkDetector : hyperlinkDetectors) {
IHyperlink[] hyperlinks = hyperLinkDetector
.detectHyperlinks(textViewer, region, true);
if (hyperlinks != null) {
for (IHyperlink hyperlink : hyperlinks) {
StyleRange hyperlinkStyleRange = new StyleRange(
hyperlink.getHyperlinkRegion().getOffset(),
hyperlink.getHyperlinkRegion().getLength(),
Display.getDefault().getSystemColor(
SWT.COLOR_BLUE), Display
.getDefault().getSystemColor(
SWT.COLOR_WHITE));
hyperlinkStyleRange.underline = true;
styleRangeList.add(hyperlinkStyleRange);
}
}
}
}
}
StyleRange[] styleRangeArray = new StyleRange[styleRangeList.size()];
styleRangeList.toArray(styleRangeArray);
return styleRangeArray;
}
+ // set the cursor when hovering over a link
+ textWidget.addListener(SWT.MouseMove, new Listener() {
+ public void handleEvent(final Event e) {
+ StyleRange styleRange = getStyleRange(e.x, e.y);
+ if (styleRange != null && styleRange.underline)
+ textWidget.setCursor(SYS_LINK_CURSOR);
+ else
+ textWidget.setCursor(sys_normalCursor);
+ }
+ });
+ private StyleRange getStyleRange(final int x, final int y) {
+ final StyledText t = sourceViewer.getTextWidget();
+ final int offset;
+ try {
+ offset = t.getOffsetAtLocation(new Point(x, y));
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ if (offset < t.getCharCount())
+ return t.getStyleRangeAtOffset(offset);
+ else
+ return null;
+ }
+
sourceViewer.addTextListener(new ITextListener() {
public void textChanged(TextEvent event) {
+ textWidget.setStyleRanges(
+ new StyleRange[0]);
+ for (StyleRange styleRange : UIUtils
+ .getHyperlinkDetectorStyleRanges(
+ sourceViewer,
+ configuration
+ .getHyperlinkDetectors(sourceViewer)))
+ textWidget.setStyleRange(styleRange);
if (undoAction != null)
undoAction.update();
if (redoAction != null)
@@ -641,6 +695,17 @@
}
});
*/
@Override
public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
IRegion region, boolean canShowMultipleHyperlinks) {
List<IHyperlink> links = new ArrayList<IHyperlink>();
IDocument document = textViewer.getDocument();
int offset = region.getOffset();
ParserResult result = editor.getModel().getAstModel();
if (result != null) {
result.resolveReferences();
HyperlinkingVisitor hv = new HyperlinkingVisitor(region, editor, textViewer);
result.accept(hv, null);
return hv.getLinks().toArray(new IHyperlink[0]);
IRegion lineRegion = null;
String candidate = null;
try {
lineRegion = document.getLineInformationOfOffset(offset);
candidate = document.get(lineRegion.getOffset(),lineRegion.getLength());
} catch (org.eclipse.jface.text.BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
// TODO: extract actual information using visitor pattern!
// -> we should have run this in advance, maybe?
int index = candidate.indexOf("terminal");
if (index != -1) {
IRegion targetRegion = new Region(lineRegion.getOffset() + index, 7);
if ((targetRegion.getOffset() <= offset)
&& ((targetRegion.getOffset() + targetRegion.getLength()) > offset)) {
links.add(new CupHyperlink(region, editor, textViewer, 100, 5));
}
}
if (links.size() == 0)
return null;
return links.toArray(new IHyperlink[0]);
return new IHyperlink[0];
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment