CR-IC-3901 mac file chooser must respect FileChooserDescriptor.isFileSelectable

This commit is contained in:
Vladimir Krivosheev
2014-01-29 09:51:10 +01:00
parent e9fdcd9e38
commit f04c8a690d
2 changed files with 51 additions and 19 deletions
@@ -58,20 +58,50 @@ public class MacFileChooserDialogImpl implements PathChooserDialog {
private final Project myProject;
private Consumer<List<VirtualFile>> myCallback;
private static final Callback SHOULD_ENABLE_URL = new Callback() {
@SuppressWarnings("UnusedDeclaration")
public boolean callback(ID self, String selector, ID panel, ID url) {
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;
final ID filename = Foundation.invoke(url, "path");
final String fileName = Foundation.toStringViaUTF8(filename);
if (fileName == null) return false;
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(fileName);
return virtualFile == null || virtualFile.isDirectory() || dialog.myChooserDescriptor.isFileSelectable(virtualFile);
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);
}
};
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;
}
/*
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"
}
*/
return false;
}
};
@@ -242,19 +272,20 @@ public class MacFileChooserDialogImpl implements PathChooserDialog {
};
static {
final ID delegate = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSObject"), "NSOpenPanelDelegate_");
if (!Foundation.addMethod(delegate, Foundation.createSelector("showOpenPanel:"), MAIN_THREAD_RUNNABLE, "v*")) {
throw new RuntimeException("Unable to add method to objective-c delegate class!");
}
if (!Foundation.addMethod(delegate, Foundation.createSelector("openPanelDidEnd:returnCode:contextInfo:"), OPEN_PANEL_DID_END, "v*i")) {
throw new RuntimeException("Unable to add method to objective-c delegate class!");
}
if (!Foundation.addMethod(delegate, Foundation.createSelector("panel:shouldEnableURL:"), SHOULD_ENABLE_URL, "B@@")) {
throw new RuntimeException("Unable to add method to objective-c delegate class!");
}
ID delegate = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSObject"), "NSOpenPanelDelegate_");
addFoundationMethod(delegate, "showOpenPanel:", MAIN_THREAD_RUNNABLE, "v*");
addFoundationMethod(delegate, "openPanelDidEnd:returnCode:contextInfo:", OPEN_PANEL_DID_END, "v*i");
addFoundationMethod(delegate, "panel:shouldEnableURL:", SHOULD_ENABLE_CALLBACK, "B@@");
addFoundationMethod(delegate, "panel:validateURL:error:", VALIDATE_URL_CALLBACK, "B@@o");
Foundation.registerObjcClassPair(delegate);
}
private static void addFoundationMethod(@NotNull ID delegate, @NotNull String selector, @NotNull Callback callback, @NotNull String types) {
if (!Foundation.addMethod(delegate, Foundation.createSelector(selector), callback, types)) {
throw new RuntimeException("Unable to add method " + selector + " to objective-c delegate class!");
}
}
public MacFileChooserDialogImpl(@NotNull final FileChooserDescriptor chooserDescriptor, final Project project) {
myChooserDescriptor = chooserDescriptor;
myProject = project;
@@ -27,6 +27,7 @@ import java.util.Map;
/**
* @author spleaner
* @@see http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html
*/
public class Foundation {
private static final FoundationLibrary myFoundationLibrary;