1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package sun.awt.X11; 26 27 import java.awt.FileDialog; 28 import java.awt.peer.FileDialogPeer; 29 import java.io.File; 30 import java.io.FilenameFilter; 31 import sun.awt.AWTAccessor; 32 33 /** 34 * FileDialogPeer for the GtkFileChooser. 35 * 36 * @author Costantino Cerbo (c.cerbo@gmail.com) 37 */ 38 final class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { 39 40 private final FileDialog fd; 41 42 // A pointer to the native GTK FileChooser widget 43 private volatile long widget = 0L; 44 GtkFileDialogPeer(FileDialog fd)45 GtkFileDialogPeer(FileDialog fd) { 46 super(fd); 47 this.fd = fd; 48 } 49 initIDs()50 private static native void initIDs(); 51 static { initIDs()52 initIDs(); 53 } 54 run(String title, int mode, String dir, String file, FilenameFilter filter, boolean isMultipleMode, int x, int y)55 private native void run(String title, int mode, String dir, String file, 56 FilenameFilter filter, boolean isMultipleMode, int x, int y); quit()57 private native void quit(); 58 59 @Override toFront()60 public native void toFront(); 61 62 @Override setBounds(int x, int y, int width, int height, int op)63 public native void setBounds(int x, int y, int width, int height, int op); 64 65 /** 66 * Called exclusively by the native C code. 67 */ setFileInternal(String directory, String[] filenames)68 private void setFileInternal(String directory, String[] filenames) { 69 AWTAccessor.FileDialogAccessor accessor = AWTAccessor 70 .getFileDialogAccessor(); 71 72 if (filenames == null) { 73 accessor.setDirectory(fd, null); 74 accessor.setFile(fd, null); 75 accessor.setFiles(fd, null); 76 } else { 77 // Fix 6987233: add the trailing slash if it's absent 78 String with_separator = directory; 79 if (directory != null) { 80 with_separator = directory.endsWith(File.separator) ? 81 directory : (directory + File.separator); 82 } 83 accessor.setDirectory(fd, with_separator); 84 accessor.setFile(fd, filenames[0]); 85 86 int filesNumber = (filenames != null) ? filenames.length : 0; 87 File[] files = new File[filesNumber]; 88 for (int i = 0; i < filesNumber; i++) { 89 files[i] = new File(directory, filenames[i]); 90 } 91 accessor.setFiles(fd, files); 92 } 93 } 94 95 /** 96 * Called exclusively by the native C code. 97 */ filenameFilterCallback(String fullname)98 private boolean filenameFilterCallback(String fullname) { 99 if (fd.getFilenameFilter() == null) { 100 // no filter, accept all. 101 return true; 102 } 103 104 File filen = new File(fullname); 105 return fd.getFilenameFilter().accept(new File(filen.getParent()), 106 filen.getName()); 107 } 108 109 @Override setVisible(boolean b)110 public void setVisible(boolean b) { 111 XToolkit.awtLock(); 112 try { 113 if (b) { 114 Thread t = new Thread() { 115 public void run() { 116 showNativeDialog(); 117 fd.setVisible(false); 118 } 119 }; 120 t.start(); 121 } else { 122 quit(); 123 fd.setVisible(false); 124 } 125 } finally { 126 XToolkit.awtUnlock(); 127 } 128 } 129 130 @Override dispose()131 public void dispose() { 132 quit(); 133 super.dispose(); 134 } 135 136 @Override setDirectory(String dir)137 public void setDirectory(String dir) { 138 // We do not implement this method because we 139 // have delegated to FileDialog#setDirectory 140 } 141 142 @Override setFile(String file)143 public void setFile(String file) { 144 // We do not implement this method because we 145 // have delegated to FileDialog#setFile 146 } 147 148 @Override setFilenameFilter(FilenameFilter filter)149 public void setFilenameFilter(FilenameFilter filter) { 150 // We do not implement this method because we 151 // have delegated to FileDialog#setFilenameFilter 152 } 153 showNativeDialog()154 private void showNativeDialog() { 155 String dirname = fd.getDirectory(); 156 // File path has a priority against directory path. 157 String filename = fd.getFile(); 158 if (filename != null) { 159 final File file = new File(filename); 160 if (fd.getMode() == FileDialog.LOAD 161 && dirname != null 162 && file.getParent() == null) { 163 // File path for gtk_file_chooser_set_filename. 164 filename = dirname + (dirname.endsWith(File.separator) ? "" : 165 File.separator) + filename; 166 } 167 if (fd.getMode() == FileDialog.SAVE && file.getParent() != null) { 168 // Filename for gtk_file_chooser_set_current_name. 169 filename = file.getName(); 170 // Directory path for gtk_file_chooser_set_current_folder. 171 dirname = file.getParent(); 172 } 173 } 174 run(fd.getTitle(), fd.getMode(), dirname, filename, 175 fd.getFilenameFilter(), fd.isMultipleMode(), fd.getX(), fd.getY()); 176 } 177 } 178