Skip to main content
summaryrefslogtreecommitdiffstats
blob: 8ec163dc262726a58e63265c37f1c8ce5230ddb8 (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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*******************************************************************************
 * Copyright (c) 2005 - 2007 committers of openArchitectureWare 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
 * 
 * Contributors: committers of openArchitectureWare - initial API and
 * implementation
 ******************************************************************************/
package org.eclipse.xtend.shared.ui.editor.navigation;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.xtend.shared.ui.Activator;
import org.eclipse.xtend.shared.ui.core.IXtendXpandProject;
import org.eclipse.xtend.shared.ui.core.search.SearchMatch;
import org.eclipse.xtend.shared.ui.core.search.XtendXpandSearchEngine;

/**
 * GenericHyperlinkDetector is used to detect hyperlinkable words inside oAW
 * editors.
 * 
 * @author Peter Friese
 */
public class GenericHyperlinkDetector implements IHyperlinkDetector {

	private final IEditorPart editor;

	public GenericHyperlinkDetector(IEditorPart editor) {
		this.editor = editor;
	}

	/**
	 * {@inheritDoc}
	 */
	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
		if (region == null || textViewer == null) {
			return null;
		}

		// get hyperlinked region
		IRegion hyperlinkRegion = getHyperlinkRegion(textViewer, region.getOffset());
		if (hyperlinkRegion == null) {
			return null;
		}

		// get the word that is hyperlinked
		String hyperlinkedWord = textViewer.getDocument().get().substring(hyperlinkRegion.getOffset(),
				hyperlinkRegion.getOffset() + hyperlinkRegion.getLength());

		IXtendXpandProject project = getOawProject();
		if (project != null) {
			List<SearchMatch> matches = XtendXpandSearchEngine.findDeclarations(project, hyperlinkedWord);
			List<GenericHyperlink> links = new ArrayList<GenericHyperlink>();
			for (SearchMatch searchMatch : matches) {
				GenericHyperlink genericHyperlink = new GenericHyperlink(getWorkbenchPage(), searchMatch,
						hyperlinkRegion, hyperlinkedWord);
				links.add(genericHyperlink);
			}
			if (canShowMultipleHyperlinks) {
				return links.toArray(new IHyperlink[links.size()]);
			} else if (!links.isEmpty()) {
				return new IHyperlink[] { links.get(0) };
			}
		}
		return null;
	}

	private IWorkbenchPage getWorkbenchPage() {
		return editor.getSite().getWorkbenchWindow().getActivePage();
	}

	private IXtendXpandProject getOawProject() {
		IFile file = getFile();
		if (file == null) {
			return null;
		}
		return Activator.getExtXptModelManager().findProject(file);
	}

	private IFile getFile() {
		return (IFile) editor.getEditorInput().getAdapter(IFile.class);
	}

	/**
	 * Given a text viewer and an offset (i.e. the current cursor position),
	 * analyses the region around this location in order to find the word under
	 * the cursor.
	 * 
	 * @param textViewer
	 *            The underlying text viewer.
	 * @param offset
	 *            The cursor location.
	 * @return The document region defining the hyperlinked word.
	 */
	private IRegion getHyperlinkRegion(ITextViewer textViewer, int offset) {
		String currDoc = textViewer.getDocument().get();

		// special handling if cursor is located at end of document
		if (offset == currDoc.length()) {
			return null;
		}

		// find word start
		int start = offset;
		while (start > -1 && WordDetector.isWordPart(currDoc.charAt(start))) {
			start--;
		}

		// find word end
		start++;
		int end = offset;
		while (end < currDoc.length() && WordDetector.isWordPart(currDoc.charAt(end))) {
			end++;
		}

		if (start < 0) {
			start = 0;
		}

		if (end < start) {
			end = start;
		}

		return new Region(start, end - start);
	}

}

Back to the top