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 @@ +