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 
  26 package sun.lwawt.macosx;
  27 
  28 import java.awt.*;
  29 import java.awt.event.FocusEvent.Cause;
  30 import java.awt.peer.*;
  31 import java.awt.BufferCapabilities.FlipContents;
  32 import java.awt.event.*;
  33 import java.awt.image.*;
  34 import java.security.AccessController;
  35 import java.util.List;
  36 import java.io.*;
  37 
  38 import sun.awt.AWTAccessor;
  39 import sun.java2d.pipe.Region;
  40 import sun.security.action.GetBooleanAction;
  41 
  42 class 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 }