diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java index dbc4330202a8..4ee28ed0cbe3 100644 --- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java +++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java @@ -241,8 +241,11 @@ public class JavaSdkImpl extends JavaSdk { final FileChooserDescriptor descriptor = new FileChooserDescriptor(baseDescriptor) { @Override public void validateSelectedFiles(VirtualFile[] files) throws Exception { - if (files.length > 0 && JrtFileSystem.isModularJdk(files[0].getPath()) && !JrtFileSystem.isSupported()) { - throw new Exception(LangBundle.message("jrt.not.available.message")); + if (files.length > 0 && !JrtFileSystem.isSupported()) { + String path = files[0].getPath(); + if (JrtFileSystem.isModularJdk(path) || JrtFileSystem.isModularJdk(adjustSelectedSdkHome(path))) { + throw new Exception(LangBundle.message("jrt.not.available.message")); + } } baseDescriptor.validateSelectedFiles(files); } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java index a333565f3607..766dc8c64cdb 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacFileChooserDialogImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -15,6 +15,7 @@ */ package com.intellij.ui.mac; +import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; @@ -37,6 +38,7 @@ import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.sun.jna.Callback; +import com.sun.jna.Pointer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,53 +61,69 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { private final Project myProject; private Consumer> myCallback; - private static boolean checkFile(@NotNull ID self, ID url, boolean checkDirectories) { - MacFileChooserDialogImpl dialog = ourImplMap.get(self); - if (dialog == null) { - // Since it has already been removed from the map, the file is likely to be valid if the user was able to select it - return true; - } - - if (url == null || url.intValue() == 0) { - return false; - } - - ID filename = Foundation.invoke(url, "path"); - String fileName = Foundation.toStringViaUTF8(filename); - if (fileName == null) { - return false; - } - - VirtualFile file = LocalFileSystem.getInstance().findFileByPath(fileName); - return file == null || (!checkDirectories && file.isDirectory()) || dialog.myChooserDescriptor.isFileSelectable(file); - } - private static final Callback SHOULD_ENABLE_CALLBACK = new Callback() { @SuppressWarnings("UnusedDeclaration") public boolean callback(ID self, String selector, ID panel, ID url) { - // allow any directory - ability to select nested directories - return checkFile(self, url, false); + try { + return checkFile(self, url, true); // allow any directory - ability to select nested directories + } + catch (Exception e) { + return false; + } } }; private static final Callback VALIDATE_URL_CALLBACK = new Callback() { @SuppressWarnings("UnusedDeclaration") public boolean callback(ID self, String selector, ID panel, ID url, ID outError) { - if (checkFile(self, url, true)) { - return true; + try { + return checkFile(self, url, false); } - - /* - if (!outError.equals(ID.NIL)) { - ID error = Foundation.invoke("NSError", "errorWithDomain:code:userInfo:", Foundation.nsString("org.jetbrains"), - Foundation.createDict(new String[]{"NSLocalizedDescriptionKey"}, new Object[]{"Not allowed"})); - // todo "*outError = error" + catch (Exception e) { + if (!ID.NIL.equals(outError)) { + ID domain = Foundation.nsString(ApplicationNamesInfo.getInstance().getProductName()); + ID dict = Foundation.createDict(new String[]{"NSLocalizedDescription"}, new Object[]{e.getMessage()}); + ID error = Foundation.invoke("NSError", "errorWithDomain:code:userInfo:", domain, 100, dict); + new Pointer(outError.longValue()).setLong(0, error.longValue()); + } + return false; } - */ - return false; } }; + private static boolean checkFile(@NotNull ID self, ID url, boolean quickCheck) throws Exception { + MacFileChooserDialogImpl impl = ourImplMap.get(self); + if (impl == null) { + return true; // already removed from the map: the file is likely to be valid since the user was able to select it + } + + if (url == null || url.intValue() == 0) { + return false; + } + + ID filename = Foundation.invoke(url, "path"); + String path = Foundation.toStringViaUTF8(filename); + if (path == null) { + return false; + } + + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); + if (file == null || quickCheck && file.isDirectory()) { + return true; + } + + if (!impl.myChooserDescriptor.isFileSelectable(file)) { + return false; + } + + if (!quickCheck) { + VirtualFile[] files = {file}; + impl.myChooserDescriptor.validateSelectedFiles(files); + } + + return true; + } + private static final Callback OPEN_PANEL_DID_END = new Callback() { @SuppressWarnings("UnusedDeclaration") public void callback(ID self, String selector, ID openPanelDidEnd, ID returnCode, ID contextInfo) { @@ -300,7 +318,6 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { @Override public void choose(@Nullable final VirtualFile toSelect, @NotNull final Consumer> callback) { - ExtensionsInitializer.initialize(); myCallback = callback; @@ -356,12 +373,11 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { return Foundation.invoke(id, Foundation.createSelector(selector), args); } - /** This class is intended to force extensions initialization on EDT thread (IDEA-107271) - */ + /** This class is intended to force extensions initialization on EDT thread (IDEA-107271) */ private static class ExtensionsInitializer { private ExtensionsInitializer() {} private static boolean initialized; - private static void initialize () { + private static void initialize() { if (initialized) return; UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override @@ -372,5 +388,4 @@ public class MacFileChooserDialogImpl implements PathChooserDialog { initialized = true; } } - } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/growl/Growl.java b/platform/platform-impl/src/com/intellij/ui/mac/growl/Growl.java index 3316a0d44b33..b4ab66adb438 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/growl/Growl.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/growl/Growl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -47,10 +47,9 @@ public class Growl { final ID applicationIcon = getApplicationIcon(); final ID defaultNotifications = Foundation.fillArray(myDefaultNotification); final ID allNotifications = Foundation.fillArray(myAllNotifications); - - final ID userDict = Foundation.createDict(new String[]{GROWL_APP_NAME, GROWL_APP_ICON, GROWL_DEFAULT_NOTIFICATIONS, GROWL_ALL_NOTIFICATIONS}, - new Object[]{myProductName, applicationIcon, defaultNotifications, allNotifications}); - + final ID userDict = Foundation.createDict( + new String[]{GROWL_APP_NAME, GROWL_APP_ICON, GROWL_DEFAULT_NOTIFICATIONS, GROWL_ALL_NOTIFICATIONS}, + new Object[]{myProductName, applicationIcon, defaultNotifications, allNotifications}); final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter"); final Object notificationName = Foundation.nsString(GROWL_APPLICATION_REGISTRATION_NOTIFICATION); invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, userDict, true); @@ -59,12 +58,11 @@ public class Growl { public void notifyGrowlOf(final String notification, final String title, final String description) { final ID autoReleasePool = createAutoReleasePool(); - final ID dict = Foundation.createDict(new String[]{ - GROWL_NOTIFICATION_NAME, GROWL_NOTIFICATION_TITLE, GROWL_NOTIFICATION_DESCRIPTION, GROWL_APP_NAME}, - new Object[]{notification, title, description, myProductName}); + final ID dict = Foundation.createDict( + new String[]{GROWL_NOTIFICATION_NAME, GROWL_NOTIFICATION_TITLE, GROWL_NOTIFICATION_DESCRIPTION, GROWL_APP_NAME}, + new Object[]{notification, title, description, myProductName}); final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter"); final Object notificationName = Foundation.nsString(GROWL_NOTIFICATION); - invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, dict, true); invoke(autoReleasePool, "release"); }