diff --git a/build/conf/mac/Contents/Info.plist b/build/conf/mac/Contents/Info.plist
index 77df63ba5fb6..0603a2567e3e 100644
--- a/build/conf/mac/Contents/Info.plist
+++ b/build/conf/mac/Contents/Info.plist
@@ -61,7 +61,7 @@
LSRequiresNativeExecution
YES
-
+ @@url_schemes@@
Java
ClassPath
diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
index cc8bb295e2de..46c91bc1cb70 100644
--- a/build/scripts/utils.gant
+++ b/build/scripts/utils.gant
@@ -340,6 +340,7 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
replacefilter(token: "@@idea_properties@@", value: coreProperties)
replacefilter(token: "@@class_path@@", value: classPath)
replacefilter(token: "@@help_id@@", value: helpId)
+ replacefilter(token: "@@url_schemes@@", value: ifNull(args.urlSchemes, ""))
}
if (executable != "idea") {
diff --git a/platform/platform-impl/src/com/intellij/ui/CustomProtocolHandler.java b/platform/platform-impl/src/com/intellij/ui/CustomProtocolHandler.java
new file mode 100644
index 000000000000..cfeb9cb404a5
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/CustomProtocolHandler.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import com.intellij.ide.CommandLineProcessor;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Dennis.Ushakov
+ */
+public abstract class CustomProtocolHandler {
+ public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.customProtocolHandler");
+ private final String myScheme;
+
+ protected CustomProtocolHandler(String scheme) {
+ myScheme = scheme;
+ }
+
+ public boolean openLink(@NotNull URI uri) {
+ final List args = getOpenArgs(uri);
+ return !args.isEmpty() && CommandLineProcessor.processExternalCommandLine(args) != null;
+ }
+
+ @NotNull
+ public List getOpenArgs(URI uri) {
+ final List args = new ArrayList();
+ if (myScheme.equals(uri.getScheme())) {
+ final String query = uri.getQuery();
+ String file = null;
+ String line = null;
+ if (query != null) {
+ for (String param : query.split("&")) {
+ String[] pair = param.split("=");
+ String key = decode(pair[0]);
+ if (pair.length > 1) {
+ if ("file".equals(key)) {
+ file = decode(pair[1]);
+ } else if ("line".equals(key)) {
+ line = decode(pair[1]);
+ }
+ }
+ }
+ }
+ if (file != null) {
+
+ if (line != null) {
+ args.add("--line");
+ args.add(line);
+ }
+ args.add(file);
+ }
+ }
+ return args;
+ }
+
+ private static String decode(String s) {
+ try {
+ return URLDecoder.decode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java
index 195f385ab45a..ae8e9bde3c05 100644
--- a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java
+++ b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java
@@ -15,9 +15,7 @@
*/
package com.intellij.ui.mac;
-import com.apple.eawt.AppEvent;
-import com.apple.eawt.FullScreenAdapter;
-import com.apple.eawt.FullScreenUtilities;
+import com.apple.eawt.*;
import com.intellij.Patches;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
@@ -26,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
+import com.intellij.ui.CustomProtocolHandler;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.mac.foundation.MacUtil;
@@ -206,6 +205,24 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable {
finally {
invoke(pool, "release");
}
+
+ // install uri handler
+ final ID mainBundle = invoke("NSBundle", "mainBundle");
+ final ID urlTypes = invoke(mainBundle, "objectForInfoDictionaryKey:", Foundation.nsString("CFBundleURLTypes"));
+ if (urlTypes.equals(ID.NIL)) {
+ LOG.warn("no url bundle present");
+ return;
+ }
+ Application.getApplication().setOpenURIHandler(new OpenURIHandler() {
+ @Override
+ public void openURI(AppEvent.OpenURIEvent event) {
+ for (CustomProtocolHandler handler : CustomProtocolHandler.EP_NAME.getExtensions()) {
+ if (handler.openLink(event.getURI())) {
+ return;
+ }
+ }
+ }
+ });
}
public void remove() {
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index d23e7fe23f10..e9e81089324b 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -167,6 +167,7 @@
+