1/*
2 * Copyright (c) 2011, 2016, 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
26package sun.lwawt.macosx;
27
28import java.awt.*;
29import java.awt.event.FocusEvent.Cause;
30import java.awt.peer.*;
31import java.awt.BufferCapabilities.FlipContents;
32import java.awt.event.*;
33import java.awt.image.*;
34import java.security.AccessController;
35import java.util.List;
36import java.io.*;
37
38import sun.awt.AWTAccessor;
39import sun.java2d.pipe.Region;
40import sun.security.action.GetBooleanAction;
41
42class CFileDialog implements FileDialogPeer {
43
44    private class Task implements Runnable {
45
46        @Override
47        public void run() {
48            try {
49                boolean navigateApps = !AccessController.doPrivileged(
50                        new GetBooleanAction("apple.awt.use-file-dialog-packages"));
51                boolean chooseDirectories = AccessController.doPrivileged(
52                        new GetBooleanAction("apple.awt.fileDialogForDirectories"));
53
54                int dialogMode = target.getMode();
55                String title = target.getTitle();
56                if (title == null) {
57                    title = " ";
58                }
59
60                String[] userFileNames = nativeRunFileDialog(title,
61                        dialogMode,
62                        target.isMultipleMode(),
63                        navigateApps,
64                        chooseDirectories,
65                        target.getFilenameFilter() != null,
66                        target.getDirectory(),
67                        target.getFile());
68
69                String directory = null;
70                String file = null;
71                File[] files = null;
72
73                if (userFileNames != null) {
74                    // the dialog wasn't cancelled
75                    int filesNumber = userFileNames.length;
76                    files = new File[filesNumber];
77                    for (int i = 0; i < filesNumber; i++) {
78                        files[i] = new File(userFileNames[i]);
79                    }
80
81                    directory = files[0].getParent();
82                    // make sure directory always ends in '/'
83                    if (!directory.endsWith(File.separator)) {
84                        directory = directory + File.separator;
85                    }
86
87                    file = files[0].getName(); // pick any file
88                }
89
90                // store results back in component
91                AWTAccessor.FileDialogAccessor accessor = AWTAccessor.getFileDialogAccessor();
92                accessor.setDirectory(target, directory);
93                accessor.setFile(target, file);
94                accessor.setFiles(target, files);
95            } finally {
96                // Java2 Dialog waits for hide to let show() return
97                target.dispose();
98            }
99        }
100    }
101
102    // The target FileDialog
103    private final FileDialog target;
104
105    CFileDialog(FileDialog target) {
106        this.target = target;
107    }
108
109    @Override
110    public void dispose() {
111        LWCToolkit.targetDisposedPeer(target, this);
112        // Unlike other peers, we do not have a native model pointer to
113        // dispose of because the save and open panels are never released by
114        // an application.
115    }
116
117    @Override
118    public void setVisible(boolean visible) {
119        if (visible) {
120            // Java2 Dialog class requires peer to run code in a separate thread
121            // and handles keeping the call modal
122            new Thread(null, new Task(), "FileDialog", 0, false).start();
123        }
124        // We hide ourself before "show" returns - setVisible(false)
125        // doesn't apply
126    }
127
128    /**
129     * A callback method.
130     * If the file dialog has a file filter, ask it if inFilename is acceptable.
131     * If the dialog doesn't have a file filter return true.
132     */
133    private boolean queryFilenameFilter(final String inFilename) {
134        boolean ret = false;
135
136        final FilenameFilter ff = target.getFilenameFilter();
137        File fileObj = new File(inFilename);
138
139        // Directories are never filtered by the FileDialog.
140        if (!fileObj.isDirectory()) {
141            File directoryObj = new File(fileObj.getParent());
142            String nameOnly = fileObj.getName();
143            ret = ff.accept(directoryObj, nameOnly);
144        }
145        return ret;
146    }
147
148    private native String[] nativeRunFileDialog(String title, int mode,
149            boolean multipleMode, boolean shouldNavigateApps,
150            boolean canChooseDirectories, boolean hasFilenameFilter,
151            String directory, String file);
152
153    @Override
154    public void setDirectory(String dir) {
155    }
156
157    @Override
158    public void setFile(String file) {
159    }
160
161    @Override
162    public void setFilenameFilter(FilenameFilter filter) {
163    }
164
165    @Override
166    public void blockWindows(List<Window> windows) {
167    }
168
169    @Override
170    public void setResizable(boolean resizeable) {
171    }
172
173    @Override
174    public void setTitle(String title) {
175    }
176
177    @Override
178    public void repositionSecurityWarning() {
179    }
180
181    @Override
182    public void updateAlwaysOnTopState() {
183    }
184
185    @Override
186    public void setModalBlocked(Dialog blocker, boolean blocked) {
187    }
188
189    @Override
190    public void setOpacity(float opacity) {
191    }
192
193    @Override
194    public void setOpaque(boolean isOpaque) {
195    }
196
197    @Override
198    public void toBack() {
199    }
200
201    @Override
202    public void toFront() {
203    }
204
205    @Override
206    public void updateFocusableWindowState() {
207    }
208
209    @Override
210    public void updateIconImages() {
211    }
212
213    @Override
214    public void updateMinimumSize() {
215    }
216
217    @Override
218    public void updateWindow() {
219    }
220
221    @Override
222    public void beginLayout() {
223    }
224
225    @Override
226    public void beginValidate() {
227    }
228
229    @Override
230    public void endLayout() {
231    }
232
233    @Override
234    public void endValidate() {
235    }
236
237    @Override
238    public Insets getInsets() {
239        return new Insets(0, 0, 0, 0);
240    }
241
242    @Override
243    public void applyShape(Region shape) {
244    }
245
246    @Override
247    public boolean canDetermineObscurity() {
248        return false;
249    }
250
251    @Override
252    public int checkImage(Image img, int w, int h, ImageObserver o) {
253        return 0;
254    }
255
256    @Override
257    public void coalescePaintEvent(PaintEvent e) {
258    }
259
260    @Override
261    public void createBuffers(int numBuffers, BufferCapabilities caps)
262            throws AWTException {
263    }
264
265    @Override
266    public Image createImage(ImageProducer producer) {
267        return null;
268    }
269
270    @Override
271    public Image createImage(int width, int height) {
272        return null;
273    }
274
275    @Override
276    public VolatileImage createVolatileImage(int width, int height) {
277        return null;
278    }
279
280    @Override
281    public void destroyBuffers() {
282    }
283
284    @Override
285    public void flip(int x1, int y1, int x2, int y2, FlipContents flipAction) {
286    }
287
288    @Override
289    public Image getBackBuffer() {
290        return null;
291    }
292
293    @Override
294    public ColorModel getColorModel() {
295        return null;
296    }
297
298    @Override
299    public FontMetrics getFontMetrics(Font font) {
300        return null;
301    }
302
303    @Override
304    public Graphics getGraphics() {
305        return null;
306    }
307
308    @Override
309    public GraphicsConfiguration getGraphicsConfiguration() {
310        return null;
311    }
312
313    @Override
314    public Point getLocationOnScreen() {
315        return null;
316    }
317
318    @Override
319    public Dimension getMinimumSize() {
320        return target.getSize();
321    }
322
323    @Override
324    public Dimension getPreferredSize() {
325        return getMinimumSize();
326    }
327
328    @Override
329    public void handleEvent(AWTEvent e) {
330    }
331
332    @Override
333    public boolean handlesWheelScrolling() {
334        return false;
335    }
336
337    @Override
338    public boolean isFocusable() {
339        return false;
340    }
341
342    @Override
343    public boolean isObscured() {
344        return false;
345    }
346
347    @Override
348    public boolean isReparentSupported() {
349        return false;
350    }
351
352    @Override
353    public void layout() {
354    }
355
356    @Override
357    public void paint(Graphics g) {
358    }
359
360    @Override
361    public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
362        return false;
363    }
364
365    @Override
366    public void print(Graphics g) {
367    }
368
369    @Override
370    public void reparent(ContainerPeer newContainer) {
371    }
372
373    @Override
374    public boolean requestFocus(Component lightweightChild, boolean temporary,
375            boolean focusedWindowChangeAllowed, long time, Cause cause) {
376        return false;
377    }
378
379    @Override
380    public void setBackground(Color c) {
381    }
382
383    @Override
384    public void setForeground(Color c) {
385    }
386
387    @Override
388    public void setBounds(int x, int y, int width, int height, int op) {
389    }
390
391    @Override
392    public void setEnabled(boolean e) {
393    }
394
395    @Override
396    public void setFont(Font f) {
397    }
398
399    @Override
400    public void setZOrder(ComponentPeer above) {
401    }
402
403    @Override
404    public void updateCursorImmediately() {
405    }
406
407    @Override
408    public boolean updateGraphicsData(GraphicsConfiguration gc) {
409        return false;
410    }
411}
412