Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-02-17 01:39:50 +03:00
3 changed files with 66 additions and 50 deletions
@@ -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);
}
@@ -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<List<VirtualFile>> 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<List<VirtualFile>> 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;
}
}
}
@@ -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");
}