提交 7eb16067 编写于 作者: D dcherepanov

7124337: [macosx] FileDialog fails to select multiple files

Reviewed-by: anthony, swingler
上级 ed0f5569
...@@ -34,6 +34,7 @@ import java.util.List; ...@@ -34,6 +34,7 @@ import java.util.List;
import java.io.*; import java.io.*;
import sun.awt.CausedFocusEvent.Cause; import sun.awt.CausedFocusEvent.Cause;
import sun.awt.AWTAccessor;
import sun.java2d.pipe.Region; import sun.java2d.pipe.Region;
class CFileDialog implements FileDialogPeer { class CFileDialog implements FileDialogPeer {
...@@ -53,33 +54,40 @@ class CFileDialog implements FileDialogPeer { ...@@ -53,33 +54,40 @@ class CFileDialog implements FileDialogPeer {
title = " "; title = " ";
} }
String userFileName = nativeRunFileDialog(title, String[] userFileNames = nativeRunFileDialog(title,
dialogMode, navigateApps, dialogMode,
target.isMultipleMode(),
navigateApps,
target.getFilenameFilter() != null, target.getFilenameFilter() != null,
target.getDirectory(), target.getDirectory(),
target.getFile()); target.getFile());
File file = null; String directory = null;
if (userFileName != null) { String file = null;
File[] files = null;
if (userFileNames != null) {
// the dialog wasn't cancelled // the dialog wasn't cancelled
file = new File(userFileName); int filesNumber = userFileNames.length;
} files = new File[filesNumber];
for (int i = 0; i < filesNumber; i++) {
files[i] = new File(userFileNames[i]);
}
if (file != null) { directory = files[0].getParent();
// make sure directory always ends in '/' // make sure directory always ends in '/'
String parent = file.getParent(); if (!directory.endsWith(File.separator)) {
if (!parent.endsWith(File.separator)) { directory = directory + File.separator;
parent = parent + File.separator;
} }
// store results back in component file = files[0].getName(); // pick any file
target.setDirectory(parent);
target.setFile(file.getName());
} else {
// setting file name to null is how we tell
// java client that user hit the cancel button
target.setFile(null);
} }
// store results back in component
AWTAccessor.FileDialogAccessor accessor = AWTAccessor.getFileDialogAccessor();
accessor.setDirectory(target, directory);
accessor.setFile(target, file);
accessor.setFiles(target, files);
} finally { } finally {
// Java2 Dialog waits for hide to let show() return // Java2 Dialog waits for hide to let show() return
target.dispose(); target.dispose();
...@@ -133,8 +141,8 @@ class CFileDialog implements FileDialogPeer { ...@@ -133,8 +141,8 @@ class CFileDialog implements FileDialogPeer {
return ret; return ret;
} }
private native String nativeRunFileDialog(String title, int mode, private native String[] nativeRunFileDialog(String title, int mode,
boolean shouldNavigateApps, boolean hasFilenameFilter, boolean multipleMode, boolean shouldNavigateApps, boolean hasFilenameFilter,
String directory, String file); String directory, String file);
@Override @Override
......
...@@ -46,11 +46,14 @@ ...@@ -46,11 +46,14 @@
// File dialog's mode // File dialog's mode
jint fMode; jint fMode;
// Indicates whether the user can select multiple files
BOOL fMultipleMode;
// Should we navigate into apps? // Should we navigate into apps?
BOOL fNavigateApps; BOOL fNavigateApps;
// panel's filename // Contains the absolute paths of the selected files as URLs
NSString *fReturnedFilename; NSArray *fURLs;
} }
// Allocator // Allocator
...@@ -60,6 +63,7 @@ ...@@ -60,6 +63,7 @@
directory:(NSString *)inPath directory:(NSString *)inPath
file:(NSString *)inFile file:(NSString *)inFile
mode:(jint)inMode mode:(jint)inMode
multipleMode:(BOOL)inMultipleMode
shouldNavigate:(BOOL)inNavigateApps shouldNavigate:(BOOL)inNavigateApps
withEnv:(JNIEnv*)env; withEnv:(JNIEnv*)env;
...@@ -69,7 +73,7 @@ ...@@ -69,7 +73,7 @@
// Get dialog return value // Get dialog return value
- (BOOL) userClickedOK; - (BOOL) userClickedOK;
// Filename user chose // Returns the absolute paths of the selected files as URLs
- (NSString *) filename; - (NSArray *) URLs;
@end @end
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
directory:(NSString *)inPath directory:(NSString *)inPath
file:(NSString *)inFile file:(NSString *)inFile
mode:(jint)inMode mode:(jint)inMode
multipleMode:(BOOL)inMultipleMode
shouldNavigate:(BOOL)inNavigateApps shouldNavigate:(BOOL)inNavigateApps
withEnv:(JNIEnv*)env; withEnv:(JNIEnv*)env;
{ {
...@@ -54,6 +55,7 @@ ...@@ -54,6 +55,7 @@
fTitle = inTitle; fTitle = inTitle;
[fTitle retain]; [fTitle retain];
fMode = inMode; fMode = inMode;
fMultipleMode = inMultipleMode;
fNavigateApps = inNavigateApps; fNavigateApps = inNavigateApps;
fPanelResult = NSCancelButton; fPanelResult = NSCancelButton;
} }
...@@ -79,8 +81,8 @@ ...@@ -79,8 +81,8 @@
[fTitle release]; [fTitle release];
fTitle = nil; fTitle = nil;
[fReturnedFilename release]; [fURLs release];
fReturnedFilename = nil; fURLs = nil;
[super dealloc]; [super dealloc];
} }
...@@ -105,7 +107,7 @@ ...@@ -105,7 +107,7 @@
if (fMode == java_awt_FileDialog_LOAD) { if (fMode == java_awt_FileDialog_LOAD) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel; NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
[openPanel setAllowsMultipleSelection:NO]; [openPanel setAllowsMultipleSelection:fMultipleMode];
[openPanel setCanChooseFiles:YES]; [openPanel setCanChooseFiles:YES];
[openPanel setCanChooseDirectories:NO]; [openPanel setCanChooseDirectories:NO];
[openPanel setCanCreateDirectories:YES]; [openPanel setCanCreateDirectories:YES];
...@@ -114,8 +116,16 @@ ...@@ -114,8 +116,16 @@
[thePanel setDelegate:self]; [thePanel setDelegate:self];
fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile]; fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile];
[thePanel setDelegate:nil]; [thePanel setDelegate:nil];
fReturnedFilename = [thePanel filename];
[fReturnedFilename retain]; if ([self userClickedOK]) {
if (fMode == java_awt_FileDialog_LOAD) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = [openPanel URLs];
} else {
fURLs = [NSArray arrayWithObject:[thePanel URL]];
}
[fURLs retain];
}
} }
[self disposer]; [self disposer];
...@@ -158,8 +168,8 @@ ...@@ -158,8 +168,8 @@
return fPanelResult == NSOKButton; return fPanelResult == NSOKButton;
} }
- (NSString *)filename { - (NSArray *)URLs {
return [[fReturnedFilename retain] autorelease]; return [[fURLs retain] autorelease];
} }
@end @end
...@@ -167,13 +177,14 @@ ...@@ -167,13 +177,14 @@
* Class: sun_lwawt_macosx_CFileDialog * Class: sun_lwawt_macosx_CFileDialog
* Method: nativeRunFileDialog * Method: nativeRunFileDialog
* Signature: (Ljava/lang/String;ILjava/io/FilenameFilter; * Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;
* Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; * Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
*/ */
JNIEXPORT jstring JNICALL JNIEXPORT jobjectArray JNICALL
Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog
(JNIEnv *env, jobject peer, jstring title, jint mode, jboolean navigateApps, jboolean hasFilter, jstring directory, jstring file) (JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,
jboolean navigateApps, jboolean hasFilter, jstring directory, jstring file)
{ {
jstring returnValue = NULL; jobjectArray returnValue = NULL;
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
NSString *dialogTitle = JNFJavaToNSString(env, title); NSString *dialogTitle = JNFJavaToNSString(env, title);
...@@ -187,6 +198,7 @@ JNF_COCOA_ENTER(env); ...@@ -187,6 +198,7 @@ JNF_COCOA_ENTER(env);
directory:JNFJavaToNSString(env, directory) directory:JNFJavaToNSString(env, directory)
file:JNFJavaToNSString(env, file) file:JNFJavaToNSString(env, file)
mode:mode mode:mode
multipleMode:multipleMode
shouldNavigate:navigateApps shouldNavigate:navigateApps
withEnv:env]; withEnv:env];
...@@ -196,8 +208,18 @@ JNF_COCOA_ENTER(env); ...@@ -196,8 +208,18 @@ JNF_COCOA_ENTER(env);
waitUntilDone:YES]; waitUntilDone:YES];
if ([dialogDelegate userClickedOK]) { if ([dialogDelegate userClickedOK]) {
NSString *filename = [dialogDelegate filename]; NSArray *urls = [dialogDelegate URLs];
returnValue = JNFNSToJavaString(env, filename); jsize count = [urls count];
jclass stringClass = (*env)->FindClass(env, "java/lang/String");
returnValue = (*env)->NewObjectArray(env, count, stringClass, NULL);
(*env)->DeleteLocalRef(env, stringClass);
[urls enumerateObjectsUsingBlock:^(id url, NSUInteger index, BOOL *stop) {
jstring filename = JNFNormalizedJavaStringForPath(env, [url path]);
(*env)->SetObjectArrayElement(env, returnValue, index, filename);
(*env)->DeleteLocalRef(env, filename);
}];
} }
[dialogDelegate release]; [dialogDelegate release];
......
...@@ -147,8 +147,8 @@ public class FileDialog extends Dialog { ...@@ -147,8 +147,8 @@ public class FileDialog extends Dialog {
static { static {
AWTAccessor.setFileDialogAccessor( AWTAccessor.setFileDialogAccessor(
new AWTAccessor.FileDialogAccessor() { new AWTAccessor.FileDialogAccessor() {
public void setFiles(FileDialog fileDialog, String directory, String files[]) { public void setFiles(FileDialog fileDialog, File files[]) {
fileDialog.setFiles(directory, files); fileDialog.setFiles(files);
} }
public void setFile(FileDialog fileDialog, String file) { public void setFile(FileDialog fileDialog, String file) {
fileDialog.file = ("".equals(file)) ? null : file; fileDialog.file = ("".equals(file)) ? null : file;
...@@ -446,13 +446,9 @@ public class FileDialog extends Dialog { ...@@ -446,13 +446,9 @@ public class FileDialog extends Dialog {
* @see #getFiles * @see #getFiles
* @since 1.7 * @since 1.7
*/ */
private void setFiles(String directory, String files[]) { private void setFiles(File files[]) {
synchronized (getObjectLock()) { synchronized (getObjectLock()) {
int filesNumber = (files != null) ? files.length : 0; this.files = files;
this.files = new File[filesNumber];
for (int i = 0; i < filesNumber; i++) {
this.files[i] = new File(directory, files[i]);
}
} }
} }
......
...@@ -34,6 +34,8 @@ import java.awt.geom.Point2D; ...@@ -34,6 +34,8 @@ import java.awt.geom.Point2D;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.io.File;
/** /**
* The AWTAccessor utility class. * The AWTAccessor utility class.
* The main purpose of this class is to enable accessing * The main purpose of this class is to enable accessing
...@@ -455,7 +457,7 @@ public final class AWTAccessor { ...@@ -455,7 +457,7 @@ public final class AWTAccessor {
/* /*
* Sets the files the user selects * Sets the files the user selects
*/ */
void setFiles(FileDialog fileDialog, String directory, String files[]); void setFiles(FileDialog fileDialog, File files[]);
/* /*
* Sets the file the user selects * Sets the file the user selects
......
...@@ -73,7 +73,7 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { ...@@ -73,7 +73,7 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer {
if (filenames == null) { if (filenames == null) {
accessor.setDirectory(fd, null); accessor.setDirectory(fd, null);
accessor.setFile(fd, null); accessor.setFile(fd, null);
accessor.setFiles(fd, null, null); accessor.setFiles(fd, null);
} else { } else {
// Fix 6987233: add the trailing slash if it's absent // Fix 6987233: add the trailing slash if it's absent
String with_separator = directory; String with_separator = directory;
...@@ -83,7 +83,13 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { ...@@ -83,7 +83,13 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer {
} }
accessor.setDirectory(fd, with_separator); accessor.setDirectory(fd, with_separator);
accessor.setFile(fd, filenames[0]); accessor.setFile(fd, filenames[0]);
accessor.setFiles(fd, directory, filenames);
int filesNumber = (filenames != null) ? filenames.length : 0;
File[] files = new File[filesNumber];
for (int i = 0; i < filesNumber; i++) {
files[i] = new File(directory, filenames[i]);
}
accessor.setFiles(fd, files);
} }
} }
......
...@@ -396,11 +396,18 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe ...@@ -396,11 +396,18 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
savedFile = file.substring(index+1); savedFile = file.substring(index+1);
} }
String[] fileNames = fileList.getSelectedItems();
int filesNumber = (fileNames != null) ? fileNames.length : 0;
File[] files = new File[filesNumber];
for (int i = 0; i < filesNumber; i++) {
files[i] = new File(savedDir, fileNames[i]);
}
AWTAccessor.FileDialogAccessor fileDialogAccessor = AWTAccessor.getFileDialogAccessor(); AWTAccessor.FileDialogAccessor fileDialogAccessor = AWTAccessor.getFileDialogAccessor();
fileDialogAccessor.setDirectory(target, savedDir); fileDialogAccessor.setDirectory(target, savedDir);
fileDialogAccessor.setFile(target, savedFile); fileDialogAccessor.setFile(target, savedFile);
fileDialogAccessor.setFiles(target, savedDir, fileList.getSelectedItems()); fileDialogAccessor.setFiles(target, files);
} }
/** /**
...@@ -419,7 +426,7 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe ...@@ -419,7 +426,7 @@ class XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListe
fileDialogAccessor.setDirectory(target, null); fileDialogAccessor.setDirectory(target, null);
fileDialogAccessor.setFile(target, null); fileDialogAccessor.setFile(target, null);
fileDialogAccessor.setFiles(target, null, null); fileDialogAccessor.setFiles(target, null);
handleQuitButton(); handleQuitButton();
} }
......
...@@ -139,13 +139,16 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { ...@@ -139,13 +139,16 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
String jDirectory = null; String jDirectory = null;
String jFile = null; String jFile = null;
String jFiles[] = null; File[] jFiles = null;
if (multiple) { if (multiple) {
jDirectory = wFiles[0]; jDirectory = wFiles[0];
jFiles = new String[wFiles.length - 1]; int filesNumber = wFiles.length - 1;
System.arraycopy(wFiles, 1, jFiles, 0, jFiles.length); jFiles = new File[filesNumber];
jFile = jFiles[1]; // choose any file for (int i = 0; i < filesNumber; i++) {
jFiles[i] = new File(jDirectory, wFiles[i + 1]);
}
jFile = wFiles[1]; // choose any file
} else { } else {
int index = wFiles[0].lastIndexOf(java.io.File.separatorChar); int index = wFiles[0].lastIndexOf(java.io.File.separatorChar);
if (index == -1) { if (index == -1) {
...@@ -155,7 +158,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { ...@@ -155,7 +158,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
jDirectory = wFiles[0].substring(0, index + 1); jDirectory = wFiles[0].substring(0, index + 1);
jFile = wFiles[0].substring(index + 1); jFile = wFiles[0].substring(index + 1);
} }
jFiles = new String[] { jFile }; jFiles = new File[] { new File(jDirectory, jFile) };
} }
final FileDialog fileDialog = (FileDialog)target; final FileDialog fileDialog = (FileDialog)target;
...@@ -163,7 +166,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { ...@@ -163,7 +166,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
fileDialogAccessor.setDirectory(fileDialog, jDirectory); fileDialogAccessor.setDirectory(fileDialog, jDirectory);
fileDialogAccessor.setFile(fileDialog, jFile); fileDialogAccessor.setFile(fileDialog, jFile);
fileDialogAccessor.setFiles(fileDialog, jDirectory, jFiles); fileDialogAccessor.setFiles(fileDialog, jFiles);
WToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() { WToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() {
public void run() { public void run() {
...@@ -178,7 +181,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { ...@@ -178,7 +181,7 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
final FileDialog fileDialog = (FileDialog)target; final FileDialog fileDialog = (FileDialog)target;
AWTAccessor.getFileDialogAccessor().setFile(fileDialog, null); AWTAccessor.getFileDialogAccessor().setFile(fileDialog, null);
AWTAccessor.getFileDialogAccessor().setFiles(fileDialog, null, null); AWTAccessor.getFileDialogAccessor().setFiles(fileDialog, null);
WToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() { WToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() {
public void run() { public void run() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册