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