Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/awt/CFileDialog.m
38829 views
/*1* Copyright (c) 2011, 2016, 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>27#import <JavaNativeFoundation/JavaNativeFoundation.h>2829#import "CFileDialog.h"30#import "ThreadUtilities.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 = JNFNewGlobalRef(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];70JNFDeleteGlobalRef(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 = JNFNormalizedJavaStringForPath(env, filename);145146static JNF_CLASS_CACHE(jc_CFileDialog, "sun/lwawt/macosx/CFileDialog");147static JNF_MEMBER_CACHE(jm_queryFF, jc_CFileDialog, "queryFilenameFilter", "(Ljava/lang/String;)Z");148BOOL returnValue = JNFCallBooleanMethod(env, fFileDialog, jm_queryFF, jString); // AWT_THREADING Safe (AWTRunLoopMode)149(*env)->DeleteLocalRef(env, jString);150151return returnValue;152}153154- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {155if (!fHasFileFilter) return YES; // no filter, no problem!156157// check if it's not a normal file158NSNumber *isFile = nil;159if ([url getResourceValue:&isFile forKey:NSURLIsRegularFileKey error:nil]) {160if (![isFile boolValue]) return YES; // always show directories and non-file entities (browsing servers/mounts, etc)161}162163// if in directory-browsing mode, don't offer files164if ((fMode != java_awt_FileDialog_LOAD) && (fMode != java_awt_FileDialog_SAVE)) {165return NO;166}167168// ask the file filter up in Java169NSString* filePath = (NSString*)CFURLCopyFileSystemPath((CFURLRef)url, kCFURLPOSIXPathStyle);170BOOL shouldEnableFile = [self askFilenameFilter:filePath];171[filePath release];172return shouldEnableFile;173}174175- (BOOL) userClickedOK {176return fPanelResult == NSOKButton;177}178179- (NSArray *)URLs {180return [[fURLs retain] autorelease];181}182@end183184/*185* Class: sun_lwawt_macosx_CFileDialog186* Method: nativeRunFileDialog187* Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;188* Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;189*/190JNIEXPORT jobjectArray JNICALL191Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog192(JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,193jboolean navigateApps, jboolean chooseDirectories, jboolean hasFilter,194jstring directory, jstring file)195{196jobjectArray returnValue = NULL;197198JNF_COCOA_ENTER(env);199NSString *dialogTitle = JNFJavaToNSString(env, title);200if ([dialogTitle length] == 0) {201dialogTitle = @" ";202}203204CFileDialog *dialogDelegate = [[CFileDialog alloc] initWithFilter:hasFilter205fileDialog:peer206title:dialogTitle207directory:JNFJavaToNSString(env, directory)208file:JNFJavaToNSString(env, file)209mode:mode210multipleMode:multipleMode211shouldNavigate:navigateApps212canChooseDirectories:chooseDirectories213withEnv:env];214215[JNFRunLoop performOnMainThread:@selector(safeSaveOrLoad)216on:dialogDelegate217withObject:nil218waitUntilDone:YES];219220if ([dialogDelegate userClickedOK]) {221NSArray *urls = [dialogDelegate URLs];222jsize count = [urls count];223224static JNF_CLASS_CACHE(jc_String, "java/lang/String");225returnValue = JNFNewObjectArray(env, &jc_String, count);226227[urls enumerateObjectsUsingBlock:^(id url, NSUInteger index, BOOL *stop) {228jstring filename = JNFNormalizedJavaStringForPath(env, [url path]);229(*env)->SetObjectArrayElement(env, returnValue, index, filename);230(*env)->DeleteLocalRef(env, filename);231}];232}233234[dialogDelegate release];235JNF_COCOA_EXIT(env);236return returnValue;237}238239240