Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: c74b170f9d3134e11563c042e3ab19e832832ca5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*******************************************************************************
 * Copyright (c) 2015 QNX Software Systems and others.
 * 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
 *******************************************************************************/
package org.eclipse.cdt.internal.qt.ui.editor;

import java.io.File;
import java.util.List;

import javax.script.Bindings;
import javax.script.ScriptException;

import org.eclipse.cdt.internal.qt.core.Activator;
import org.eclipse.cdt.qt.core.IQMLAnalyzer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
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.hyperlink.IHyperlink;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.texteditor.ITextEditor;

public class QMLHyperlink implements IHyperlink {

	private final IRegion region;
	private final ITextViewer viewer;
	private final ITextEditor editor;

	public QMLHyperlink(IRegion region, ITextViewer viewer, ITextEditor editor) {
		this.region = region;
		this.viewer = viewer;
		this.editor = editor;
	}

	@Override
	public IRegion getHyperlinkRegion() {
		return region;
	}

	@Override
	public String getTypeLabel() {
		return null;
	}

	@Override
	public String getHyperlinkText() {
		return "Open Declaration";
	}

	@Override
	public void open() {
		IQMLAnalyzer analyzer = Activator.getService(IQMLAnalyzer.class);
		try {
			IDocument document = viewer.getDocument();
			String selected = document.get(region.getOffset(), region.getLength());
			IFileEditorInput fileInput = (IFileEditorInput) editor.getEditorInput();
			String fileName = new File(fileInput.getFile().getLocationURI()).getAbsolutePath().substring(1);
			List<Bindings> definitions = analyzer.getDefinition(selected, fileName, document.get(),
					region.getOffset() + region.getLength());
			if (!definitions.isEmpty()) {
				Bindings definition = definitions.iterator().next();
				Bindings start = (Bindings) definition.get("start"); //$NON-NLS-1$
				if (start == null) {
					return;
				}
				int startLine = (int) (double) start.get("line"); //$NON-NLS-1$
				int startChar = (int) (double) start.get("ch"); //$NON-NLS-1$
				int startOffset = document.getLineOffset(startLine) + startChar;
				Bindings end = (Bindings) definition.get("end"); //$NON-NLS-1$
				int endLine = (int) (double) end.get("line"); //$NON-NLS-1$
				int endChar = (int) (double) end.get("ch"); //$NON-NLS-1$
				int endOffset = document.getLineOffset(endLine) + endChar;
				String target = (String) definition.get("file"); //$NON-NLS-1$
				if (fileName.equals(target)) {
					editor.selectAndReveal(startOffset, endOffset - startOffset);
				} else {
					IFile[] targetFiles = ResourcesPlugin.getWorkspace().getRoot()
							.findFilesForLocationURI(new File("/" + target).toURI()); //$NON-NLS-1$
					if (targetFiles.length > 0) {
						IEditorPart part = IDE.openEditor(editor.getEditorSite().getPage(), targetFiles[0]);
						if (part instanceof ITextEditor) {
							((ITextEditor) part).selectAndReveal(startOffset, endOffset - startOffset);
						}
					}
				}
			}
		} catch (BadLocationException | NoSuchMethodException | ScriptException | PartInitException e) {
			Activator.log(e);
		}
	}

}

Back to the top