Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/awt/CFileDialog.m
41152 views
/*1* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#import <sys/stat.h>26#import <Cocoa/Cocoa.h>2728#import "ThreadUtilities.h"29#import "JNIUtilities.h"30#import "CFileDialog.h"3132#import "java_awt_FileDialog.h"33#import "sun_lwawt_macosx_CFileDialog.h"3435@implementation CFileDialog3637- (id)initWithFilter:(jboolean)inHasFilter38fileDialog:(jobject)inDialog39title:(NSString *)inTitle40directory:(NSString *)inPath41file:(NSString *)inFile42mode:(jint)inMode43multipleMode:(BOOL)inMultipleMode44shouldNavigate:(BOOL)inNavigateApps45canChooseDirectories:(BOOL)inChooseDirectories46withEnv:(JNIEnv*)env;47{48if (self = [super init]) {49fHasFileFilter = inHasFilter;50fFileDialog = (*env)->NewGlobalRef(env, inDialog);51fDirectory = inPath;52[fDirectory retain];53fFile = inFile;54[fFile retain];55fTitle = inTitle;56[fTitle retain];57fMode = inMode;58fMultipleMode = inMultipleMode;59fNavigateApps = inNavigateApps;60fChooseDirectories = inChooseDirectories;61fPanelResult = NSCancelButton;62}6364return self;65}6667-(void) disposer {68if (fFileDialog != NULL) {69JNIEnv *env = [ThreadUtilities getJNIEnvUncached];70(*env)->DeleteGlobalRef(env, fFileDialog);71fFileDialog = NULL;72}73}7475-(void) dealloc {76[fDirectory release];77fDirectory = nil;7879[fFile release];80fFile = nil;8182[fTitle release];83fTitle = nil;8485[fURLs release];86fURLs = nil;8788[super dealloc];89}9091- (void)safeSaveOrLoad {92NSSavePanel *thePanel = nil;9394/*95* 8013553: turns off extension hiding for the native file dialog.96* This way is used because setExtensionHidden(NO) doesn't work97* as expected.98*/99NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];100[defaults setBool:NO forKey:@"NSNavLastUserSetHideExtensionButtonState"];101102if (fMode == java_awt_FileDialog_SAVE) {103thePanel = [NSSavePanel savePanel];104[thePanel setAllowsOtherFileTypes:YES];105} else {106thePanel = [NSOpenPanel openPanel];107}108109if (thePanel != nil) {110[thePanel setTitle:fTitle];111112if (fNavigateApps) {113[thePanel setTreatsFilePackagesAsDirectories:YES];114}115116if (fMode == java_awt_FileDialog_LOAD) {117NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;118[openPanel setAllowsMultipleSelection:fMultipleMode];119[openPanel setCanChooseFiles:!fChooseDirectories];120[openPanel setCanChooseDirectories:fChooseDirectories];121[openPanel setCanCreateDirectories:YES];122}123124[thePanel setDelegate:self];125fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile];126[thePanel setDelegate:nil];127128if ([self userClickedOK]) {129if (fMode == java_awt_FileDialog_LOAD) {130NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;131fURLs = [openPanel URLs];132} else {133fURLs = [NSArray arrayWithObject:[thePanel URL]];134}135[fURLs retain];136}137}138139[self disposer];140}141142- (BOOL) askFilenameFilter:(NSString *)filename {143JNIEnv *env = [ThreadUtilities getJNIEnv];144jstring jString = NormalizedPathJavaStringFromNSString(env, filename);145146DECLARE_CLASS_RETURN(jc_CFileDialog, "sun/lwawt/macosx/CFileDialog", NO);147DECLARE_METHOD_RETURN(jm_queryFF, jc_CFileDialog, "queryFilenameFilter", "(Ljava/lang/String;)Z", NO);148BOOL returnValue = (*env)->CallBooleanMethod(env, fFileDialog, jm_queryFF, jString);149CHECK_EXCEPTION();150(*env)->DeleteLocalRef(env, jString);151152return returnValue;153}154155- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {156if (!fHasFileFilter) return YES; // no filter, no problem!157158// check if it's not a normal file159NSNumber *isFile = nil;160if ([url getResourceValue:&isFile forKey:NSURLIsRegularFileKey error:nil]) {161if (![isFile boolValue]) return YES; // always show directories and non-file entities (browsing servers/mounts, etc)162}163164// if in directory-browsing mode, don't offer files165if ((fMode != java_awt_FileDialog_LOAD) && (fMode != java_awt_FileDialog_SAVE)) {166return NO;167}168169// ask the file filter up in Java170NSString* filePath = (NSString*)CFURLCopyFileSystemPath((CFURLRef)url, kCFURLPOSIXPathStyle);171BOOL shouldEnableFile = [self askFilenameFilter:filePath];172[filePath release];173return shouldEnableFile;174}175176- (BOOL) userClickedOK {177return fPanelResult == NSOKButton;178}179180- (NSArray *)URLs {181return [[fURLs retain] autorelease];182}183@end184185/*186* Class: sun_lwawt_macosx_CFileDialog187* Method: nativeRunFileDialog188* Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;189* Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;190*/191JNIEXPORT jobjectArray JNICALL192Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog193(JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,194jboolean navigateApps, jboolean chooseDirectories, jboolean hasFilter,195jstring directory, jstring file)196{197jobjectArray returnValue = NULL;198199JNI_COCOA_ENTER(env);200NSString *dialogTitle = JavaStringToNSString(env, title);201if ([dialogTitle length] == 0) {202dialogTitle = @" ";203}204205CFileDialog *dialogDelegate = [[CFileDialog alloc] initWithFilter:hasFilter206fileDialog:peer207title:dialogTitle208directory:JavaStringToNSString(env, directory)209file:JavaStringToNSString(env, file)210mode:mode211multipleMode:multipleMode212shouldNavigate:navigateApps213canChooseDirectories:chooseDirectories214withEnv:env];215216[ThreadUtilities performOnMainThread:@selector(safeSaveOrLoad)217on:dialogDelegate218withObject:nil219waitUntilDone:YES];220221if ([dialogDelegate userClickedOK]) {222NSArray *urls = [dialogDelegate URLs];223jsize count = [urls count];224225DECLARE_CLASS_RETURN(jc_String, "java/lang/String", NULL);226returnValue = (*env)->NewObjectArray(env, count, jc_String, NULL);227228[urls enumerateObjectsUsingBlock:^(id url, NSUInteger index, BOOL *stop) {229jstring filename = NormalizedPathJavaStringFromNSString(env, [url path]);230(*env)->SetObjectArrayElement(env, returnValue, index, filename);231(*env)->DeleteLocalRef(env, filename);232}];233}234235[dialogDelegate release];236JNI_COCOA_EXIT(env);237return returnValue;238}239240241