In progress: [ Issue 44 ] Add ability to hyperlink to imported files
https://code.google.com/p/protobuf-dt/issues/detail?id=44
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ImportHyperlink.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ImportHyperlink.java
index 78f284e..ea8f08f 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ImportHyperlink.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ImportHyperlink.java
@@ -9,9 +9,17 @@
package com.google.eclipse.protobuf.ui.editor;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IFile;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.*;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+
+import com.google.eclipse.protobuf.ui.util.Resources;
/**
* A hyperlink for imported .proto files.
@@ -21,25 +29,13 @@
class ImportHyperlink implements IHyperlink {
private final URI importUri;
- private final String uriText;
private final IRegion region;
+ private final Resources resources;
- ImportHyperlink(URI importUri, String uriText, IRegion region) {
+ ImportHyperlink(URI importUri, IRegion region, Resources resources) {
this.importUri = importUri;
- this.uriText = uriText;
this.region = region;
- }
-
- public IRegion getHyperlinkRegion() {
- return region;
- }
-
- public String getTypeLabel() {
- return "type";
- }
-
- public String getHyperlinkText() {
- return "text";
+ this.resources = resources;
}
public void open() {
@@ -49,10 +45,35 @@
}
private void openFromWorkspace() {
- System.out.println("open from Workspace");
+ IFile file = resources.file(importUri);
+ IEditorInput editorInput = new FileEditorInput(file);
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ page.openEditor(editorInput, "com.google.eclipse.protobuf.Protobuf");
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ }
}
private void openFromFileSystem() {
- System.out.println("open from file system");
+ IFileStore fileStore = EFS.getLocalFileSystem().getStore(resources.pathOf(importUri));
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ IDE.openEditorOnFileStore(page, fileStore);
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getTypeLabel() {
+ return null;
+ }
+
+ public IRegion getHyperlinkRegion() {
+ return region;
+ }
+
+ public String getHyperlinkText() {
+ return null;
}
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufHyperlinkDetector.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufHyperlinkDetector.java
index 2d29674..729c483 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufHyperlinkDetector.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufHyperlinkDetector.java
@@ -22,6 +22,7 @@
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.ui.util.Resources;
import com.google.inject.Inject;
/**
@@ -32,13 +33,18 @@
*/
public class ProtobufHyperlinkDetector extends DefaultHyperlinkDetector {
+ private static final IHyperlink[] NO_HYPERLINKS = null;
+
+ private static final char QUOTE = '\"';
+
@Inject private EObjectAtOffsetHelper eObjectAtOffsetHelper;
+ @Inject private Resources resources;
@Override public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region,
final boolean canShowMultipleHyperlinks) {
IXtextDocument document = (IXtextDocument)textViewer.getDocument();
IHyperlink[] importHyperlinks = importHyperlinks(document, region);
- if (importHyperlinks != null) return importHyperlinks;
+ if (importHyperlinks != NO_HYPERLINKS) return importHyperlinks;
return document.readOnly(new IUnitOfWork<IHyperlink[], XtextResource>() {
public IHyperlink[] exec(XtextResource resource) {
return getHelper().createHyperlinksByOffset(resource, region.getOffset(), canShowMultipleHyperlinks);
@@ -50,18 +56,28 @@
return document.readOnly(new IUnitOfWork<IHyperlink[], XtextResource>() {
public IHyperlink[] exec(XtextResource resource) {
EObject resolved = eObjectAtOffsetHelper.resolveElementAt(resource, region.getOffset());
- if (!(resolved instanceof Import)) return null;
- Import anImport = (Import) resolved;
+ if (!(resolved instanceof Import)) return NO_HYPERLINKS;
+ IRegion importUriRegion;
try {
- int lineNumber = document.getLineOfOffset(region.getOffset());
- int lineLength = document.getLineLength(lineNumber);
- document.get(region.getOffset(), lineLength - region.getOffset());
+ importUriRegion = importUriRegion(document, region.getOffset());
} catch (BadLocationException e) {
+ return NO_HYPERLINKS;
}
- String importUri = anImport.getImportURI();
- IHyperlink hyperlink = new ImportHyperlink(createURI(importUri), importUri, region);
+ String importUri = ((Import) resolved).getImportURI();
+ IHyperlink hyperlink = new ImportHyperlink(createURI(importUri), importUriRegion, resources);
return new IHyperlink[] { hyperlink };
}
});
}
+
+ private IRegion importUriRegion(final IXtextDocument document, final int offset) throws BadLocationException {
+ int lineNumber = document.getLineOfOffset(offset);
+ int lineLength = document.getLineLength(lineNumber);
+ int lineOffset = document.getLineOffset(lineNumber);
+ String line = document.get(lineOffset, lineLength);
+ int openingQuoteIndex = line.indexOf(QUOTE);
+ int closingQuoteIndex = line.indexOf(QUOTE, ++openingQuoteIndex);
+ String importUri = line.substring(openingQuoteIndex, closingQuoteIndex);
+ return new Region(lineOffset + openingQuoteIndex, importUri.length());
+ }
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategies.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategies.java
index 831688c..7a84aef 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategies.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileResolverStrategies.java
@@ -14,6 +14,7 @@
import java.util.Map;
import com.google.eclipse.protobuf.ui.preferences.paths.PathResolutionType;
+import com.google.eclipse.protobuf.ui.util.Resources;
import com.google.inject.Inject;
import com.google.inject.Singleton;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
index 22dc6c6..83ac24a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
@@ -16,6 +16,7 @@
import com.google.eclipse.protobuf.scoping.IFileUriResolver;
import com.google.eclipse.protobuf.ui.preferences.paths.*;
+import com.google.eclipse.protobuf.ui.util.Resources;
import com.google.inject.Inject;
/**
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolver.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolver.java
index 6379c7d..f07108f 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolver.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolver.java
@@ -15,6 +15,7 @@
import com.google.eclipse.protobuf.ui.preferences.paths.DirectoryPath;
import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
+import com.google.eclipse.protobuf.ui.util.Resources;
/**
* @author alruiz@google.com (Alex Ruiz)
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver.java
index b220689..04ccf86 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver.java
@@ -17,6 +17,7 @@
import org.eclipse.xtext.util.Pair;
import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
+import com.google.eclipse.protobuf.ui.util.Resources;
/**
* @author alruiz@google.com (Alex Ruiz)
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/Resources.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
similarity index 69%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/Resources.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
index dbda15e..abe9f2d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/Resources.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
@@ -6,10 +6,11 @@
*
* http://www.eclipse.org/legal/epl-v10.html
*/
-package com.google.eclipse.protobuf.ui.scoping;
+package com.google.eclipse.protobuf.ui.util;
import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import com.google.inject.Singleton;
@@ -40,9 +41,23 @@
return file(fileUri).exists();
}
- private IFile file(URI uri) {
- IPath resourcePath = new Path(uri.toPlatformString(true));
+ /**
+ * Returns a handle to file identified by the given URI.
+ * @param uri the given URI.
+ * @return a handle to file identified by the given URI.
+ */
+ public IFile file(URI uri) {
+ IPath resourcePath = pathOf(uri);
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
return root.getFile(resourcePath);
}
+
+ /**
+ * Constructs a new path from the given URI.
+ * @param uri the given URI.
+ * @return the constructed path.
+ */
+ public IPath pathOf(URI uri) {
+ return new Path(uri.toPlatformString(true));
+ }
}