jdk/src/solaris/classes/sun/awt/motif/MFileDialogPeer.java
changeset 1211 b659a7cee935
parent 1210 7798f9e88bf9
parent 1203 3e5496df0d2b
child 1212 d718a4419361
equal deleted inserted replaced
1210:7798f9e88bf9 1211:b659a7cee935
     1 /*
       
     2  * Copyright 1995-2003 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 package sun.awt.motif;
       
    26 
       
    27 import java.awt.*;
       
    28 import java.awt.peer.*;
       
    29 import java.io.*;
       
    30 import java.awt.datatransfer.*;
       
    31 import java.util.ArrayList;
       
    32 import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
       
    33 
       
    34 public class MFileDialogPeer extends MDialogPeer implements FileDialogPeer {
       
    35     private FilenameFilter filter;
       
    36     private String[] NativeFilteredFiles;
       
    37     native void create(MComponentPeer parent);
       
    38     void create(MComponentPeer parent, Object arg) {
       
    39         create(parent);
       
    40     }
       
    41     public MFileDialogPeer(FileDialog target) {
       
    42         super(target);
       
    43         FileDialog      fdialog = (FileDialog)target;
       
    44         String          dir = fdialog.getDirectory();
       
    45         String          file = fdialog.getFile();
       
    46         FilenameFilter  filter = fdialog.getFilenameFilter();
       
    47 
       
    48         insets = new Insets(0, 0, 0, 0);
       
    49         setDirectory(dir);
       
    50         if (file != null) {
       
    51             setFile(file);
       
    52         }
       
    53             setFilenameFilter(filter);
       
    54     }
       
    55     native void         pReshape(int x, int y, int width, int height);
       
    56     native void         pDispose();
       
    57     native void         pShow();
       
    58     native void         pHide();
       
    59     native void         setFileEntry(String dir, String file, String[] ffiles);
       
    60     native void insertReplaceFileDialogText(String l);
       
    61     public native void  setFont(Font f);
       
    62 
       
    63     String getFilteredFile(String file) {
       
    64         if (file == null) {
       
    65             file = ((FileDialog)target).getFile();
       
    66         }
       
    67         String dir = ((FileDialog)target).getDirectory();
       
    68         if (dir == null) {
       
    69             dir = "./";
       
    70         }
       
    71         if (file == null) {
       
    72             file = "";
       
    73         }
       
    74         if (filter != null && !filter.accept(new File(dir), file)) {
       
    75             file = "";
       
    76         }
       
    77         return file;
       
    78     }
       
    79     // NOTE: This method is called by privileged threads.
       
    80     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
       
    81     public void         handleSelected(final String file) {
       
    82         final FileDialog fileDialog = (FileDialog)target;
       
    83         MToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() {
       
    84             public void run() {
       
    85                 int index = file.lastIndexOf(java.io.File.separatorChar);/*2509*//*ibm*/
       
    86                 String dir;
       
    87 
       
    88                 if (index == -1) {
       
    89                     dir = "."+java.io.File.separator;
       
    90                     fileDialog.setFile(file);
       
    91                 } else {
       
    92                     dir = file.substring(0, index + 1);
       
    93                     fileDialog.setFile(file.substring(index + 1));
       
    94                 }
       
    95                 fileDialog.setDirectory(dir);
       
    96                 fileDialog.hide();
       
    97             }
       
    98         });
       
    99     } // handleSelected()
       
   100 
       
   101     // NOTE: This method is called by privileged threads.
       
   102     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
       
   103     public void         handleCancel() {
       
   104         final FileDialog fileDialog = (FileDialog)target;
       
   105         MToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() {
       
   106             public void run() {
       
   107                 fileDialog.setFile(null);
       
   108                 fileDialog.hide();
       
   109             }
       
   110         });
       
   111     } // handleCancel()
       
   112 
       
   113     // NOTE: This method is called by privileged threads.
       
   114     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
       
   115     public void         handleQuit() {
       
   116         final FileDialog fileDialog = (FileDialog)target;
       
   117         MToolkit.executeOnEventHandlerThread(fileDialog, new Runnable() {
       
   118             public void run() {
       
   119                 fileDialog.hide();
       
   120             }
       
   121         });
       
   122     } // handleQuit()
       
   123 
       
   124     public  void setDirectory(String dir) {
       
   125         String file = ((FileDialog)target).getFile();
       
   126         setFileEntry((dir != null) ? dir : "./", (file != null) ? file
       
   127                      : "", null);
       
   128     }
       
   129 
       
   130 
       
   131     public  void setFile(String file) {
       
   132         String dir = ((FileDialog)target).getDirectory();
       
   133         if (dir == null) {
       
   134             dir = "./";
       
   135         }
       
   136         setFileEntry((dir != null) ? dir : "./", getFilteredFile(null), null);
       
   137     }
       
   138     class DirectoryFilter implements FilenameFilter {
       
   139         FilenameFilter userFilter;
       
   140         DirectoryFilter(FilenameFilter userFilter) {
       
   141             this.userFilter = userFilter;
       
   142         }
       
   143         public boolean accept(File parent, String name) {
       
   144             File toTest = new File(parent, name);
       
   145             if (toTest.isDirectory()) {
       
   146                 return false;
       
   147             } else if (userFilter != null) {
       
   148                 return userFilter.accept(parent, name);
       
   149             } else {
       
   150                 return true;
       
   151             }
       
   152         }
       
   153     }
       
   154     public void doFilter(FilenameFilter filter, String dir) {
       
   155         String d = (dir == null) ? (((FileDialog)target).getDirectory()):(dir);
       
   156         String f = getFilteredFile(null);
       
   157         File df = new File((d != null) ? d : ".");
       
   158         String[] files = df.list(new DirectoryFilter(filter));
       
   159         String[] nffiles = NativeFilteredFiles;
       
   160 
       
   161         // At this point we have two file lists.
       
   162         // The first one is a filtered list of files that we retrieve
       
   163         // by using Java code and Java filter.
       
   164         // The second one is a filtered list of files that we retrieve
       
   165         // by using the native code and native pattern.
       
   166         // We should find an intersection of these two lists. The result
       
   167         // will be exactly what we expect to see in setFileEntry.
       
   168         // For more details please see 4784704.
       
   169         if ( files != null ) {
       
   170             ArrayList filearr = new ArrayList();
       
   171             if (nffiles != null) {
       
   172                 for (int j = 0; j < files.length; j++) {
       
   173                     for (int n = 0; n < nffiles.length; n++) {
       
   174                         if (files[j].equals(nffiles[n])) {
       
   175                             filearr.add(files[j]);
       
   176                             break;
       
   177                         }
       
   178                     }
       
   179                 }
       
   180             }
       
   181             files = new String[filearr.size()];
       
   182             for (int i = 0; i < files.length; i++) {
       
   183                 files[i] = (String)filearr.get(i);
       
   184             }
       
   185         }
       
   186         if (files == null || files.length == 0) {
       
   187             files = new String[1];
       
   188             files[0] = "";
       
   189         }
       
   190         setFileEntry((d != null) ? d : ".", (f != null) ? f : "", files);
       
   191     }
       
   192     private boolean proceedFiltering(final String dir, String[] nffiles,
       
   193                                      boolean isPrivileged)
       
   194     {
       
   195         // Transfer the native filtered file list to the doFilter method.
       
   196         NativeFilteredFiles = nffiles;
       
   197         // If we are not on the Toolkit thread we can call doFilter() directly.
       
   198         // If the filter is null no user code will be invoked
       
   199         if (!isPrivileged || filter == null) {
       
   200             try {
       
   201                 doFilter(filter, dir);
       
   202                 return true;
       
   203             } catch(Exception e) {
       
   204                 e.printStackTrace();
       
   205                 return false;
       
   206             }
       
   207         }
       
   208         // Otherwise we have to call user code on EvenDispatchThread
       
   209         final ToolkitThreadBlockedHandler priveleged_lock =
       
   210             MToolkitThreadBlockedHandler.getToolkitThreadBlockedHandler();
       
   211         final boolean[] finished = new boolean[1];
       
   212         final boolean[] result = new boolean[1];
       
   213         finished[0] = false;
       
   214         result[0] = false;
       
   215 
       
   216 
       
   217         // Use the same Toolkit blocking mechanism as in DnD.
       
   218         priveleged_lock.lock();
       
   219 
       
   220         MToolkit.executeOnEventHandlerThread((FileDialog)target, new Runnable() {
       
   221             public void run() {
       
   222                 priveleged_lock.lock();
       
   223                 try {
       
   224                     doFilter(filter, dir);
       
   225                     result[0] = true;
       
   226                 } catch (Exception e) {
       
   227                     e.printStackTrace();
       
   228                     result[0] = false;
       
   229                 } finally {
       
   230                     finished[0] = true;
       
   231                     priveleged_lock.exit();
       
   232                     priveleged_lock.unlock();
       
   233                 }
       
   234             }
       
   235         });
       
   236 
       
   237         while (!finished[0]) {
       
   238             priveleged_lock.enter();
       
   239         }
       
   240 
       
   241         priveleged_lock.unlock();
       
   242 
       
   243         return result[0];
       
   244     }
       
   245 
       
   246     public void setFilenameFilter(FilenameFilter filter) {
       
   247         this.filter = filter;
       
   248         FileDialog      fdialog = (FileDialog)target;
       
   249         String          dir = fdialog.getDirectory();
       
   250         String          file = fdialog.getFile();
       
   251         setFile(file);
       
   252         doFilter(filter, null);
       
   253     }
       
   254 
       
   255     // Called from native widget when paste key is pressed and we
       
   256     // already own the selection (prevents Motif from hanging while
       
   257     // waiting for the selection)
       
   258     //
       
   259     public void pasteFromClipboard() {
       
   260         Clipboard clipboard = target.getToolkit().getSystemClipboard();
       
   261 
       
   262         Transferable content = clipboard.getContents(this);
       
   263         if (content != null) {
       
   264             try {
       
   265                 String data = (String)(content.getTransferData(DataFlavor.stringFlavor));
       
   266                 insertReplaceFileDialogText(data);
       
   267             } catch (Exception e) {
       
   268             }
       
   269         }
       
   270     }
       
   271 
       
   272 // CAVEAT:
       
   273 // Peer coalescing code turned over the fact that the following functions
       
   274 // were being inherited from Dialog and were not implemented in awt_FileDialog.c
       
   275 // Five methods decribed by the peer interface are at fault (setResizable, setTitle,
       
   276 // toFront, toBack and handleFocusTraversalEvent).  Additionally show has to be overridden
       
   277 // as it was necessary to add a show function in MDialogPeer for modality flag passing.
       
   278 // As a result we were winding up in  awt_Dialog.c (now coalesced into awt_TopLevel).
       
   279 // As Filedialogs are modal and its unclear to me that any of these functions
       
   280 // can be called while the FD is on-screen let it go.  RJM.
       
   281     public void show() {
       
   282         // must have our own show or we wind up in pShow for Window. Bad. Very bad.
       
   283         setVisible(true);
       
   284         setFilenameFilter(filter);
       
   285     }
       
   286 
       
   287     /**
       
   288      * MFileDialogPeer doesn't have native pData so we don't do restack on it
       
   289      * @see java.awt.peer.ContainerPeer#restack
       
   290      */
       
   291     public void restack() {
       
   292     }
       
   293 
       
   294     /**
       
   295      * @see java.awt.peer.ContainerPeer#isRestackSupported
       
   296      */
       
   297     public boolean isRestackSupported() {
       
   298         return false;
       
   299     }
       
   300 }