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