jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
author xdono
Wed, 02 Jul 2008 12:55:45 -0700
changeset 715 f16baef3a20e
parent 678 7d331a53a753
child 2489 5052722686e2
permissions -rw-r--r--
6719955: Update copyright year Summary: Update copyright year for files that have been modified in 2008 Reviewed-by: ohair, tbell
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 678
diff changeset
     2
 * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.shell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Toolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.FileNotFoundException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.swing.SwingConstants;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
// NOTE: This class supersedes Win32ShellFolder, which was removed from
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
//       distribution after version 1.4.2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * Win32 Shell Folders
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * There are two fundamental types of shell folders : file system folders
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * and non-file system folders.  File system folders are relatively easy
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * to deal with.  Non-file system folders are items such as My Computer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * Network Neighborhood, and the desktop.  Some of these non-file system
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * folders have special values and properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * Win32 keeps two basic data structures for shell folders.  The first
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * of these is called an ITEMIDLIST.  Usually a pointer, called an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * LPITEMIDLIST, or more frequently just "PIDL".  This structure holds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * a series of identifiers and can be either relative to the desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * (an absolute PIDL), or relative to the shell folder that contains them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * Some Win32 functions can take absolute or relative PIDL values, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * others can only accept relative values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * The second data structure is an IShellFolder COM interface.  Using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * this interface, one can enumerate the relative PIDLs in a shell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * folder, get attributes, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * All Win32ShellFolder2 objects which are folder types (even non-file
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * system folders) contain an IShellFolder object. Files are named in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * directories via relative PIDLs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * @author Michael Martak
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * @author Leif Samuelsson
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * @author Kenneth Russell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * @since 1.4 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
final class Win32ShellFolder2 extends ShellFolder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private static native void initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    private static final boolean is98;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        String osName = System.getProperty("os.name");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        is98 = (osName != null && osName.startsWith("Windows 98"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    // Win32 Shell Folder Constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    public static final int DESKTOP = 0x0000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    public static final int INTERNET = 0x0001;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    public static final int PROGRAMS = 0x0002;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    public static final int CONTROLS = 0x0003;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    public static final int PRINTERS = 0x0004;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    public static final int PERSONAL = 0x0005;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    public static final int FAVORITES = 0x0006;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    public static final int STARTUP = 0x0007;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    public static final int RECENT = 0x0008;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    public static final int SENDTO = 0x0009;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    public static final int BITBUCKET = 0x000a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    public static final int STARTMENU = 0x000b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    public static final int DESKTOPDIRECTORY = 0x0010;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    public static final int DRIVES = 0x0011;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    public static final int NETWORK = 0x0012;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    public static final int NETHOOD = 0x0013;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    public static final int FONTS = 0x0014;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    public static final int TEMPLATES = 0x0015;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    public static final int COMMON_STARTMENU = 0x0016;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    public static final int COMMON_PROGRAMS = 0X0017;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    public static final int COMMON_STARTUP = 0x0018;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    public static final int COMMON_DESKTOPDIRECTORY = 0x0019;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    public static final int APPDATA = 0x001a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    public static final int PRINTHOOD = 0x001b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public static final int ALTSTARTUP = 0x001d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    public static final int COMMON_ALTSTARTUP = 0x001e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    public static final int COMMON_FAVORITES = 0x001f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    public static final int INTERNET_CACHE = 0x0020;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    public static final int COOKIES = 0x0021;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    public static final int HISTORY = 0x0022;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    // Win32 shell folder attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    public static final int ATTRIB_CANCOPY          = 0x00000001;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    public static final int ATTRIB_CANMOVE          = 0x00000002;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    public static final int ATTRIB_CANLINK          = 0x00000004;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    public static final int ATTRIB_CANRENAME        = 0x00000010;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    public static final int ATTRIB_CANDELETE        = 0x00000020;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    public static final int ATTRIB_HASPROPSHEET     = 0x00000040;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    public static final int ATTRIB_DROPTARGET       = 0x00000100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    public static final int ATTRIB_LINK             = 0x00010000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    public static final int ATTRIB_SHARE            = 0x00020000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    public static final int ATTRIB_READONLY         = 0x00040000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    public static final int ATTRIB_GHOSTED          = 0x00080000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    public static final int ATTRIB_HIDDEN           = 0x00080000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    public static final int ATTRIB_FILESYSANCESTOR  = 0x10000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    public static final int ATTRIB_FOLDER           = 0x20000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    public static final int ATTRIB_FILESYSTEM       = 0x40000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    public static final int ATTRIB_HASSUBFOLDER     = 0x80000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    public static final int ATTRIB_VALIDATE         = 0x01000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    public static final int ATTRIB_REMOVABLE        = 0x02000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    public static final int ATTRIB_COMPRESSED       = 0x04000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public static final int ATTRIB_BROWSABLE        = 0x08000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    public static final int ATTRIB_NONENUMERATED    = 0x00100000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    public static final int ATTRIB_NEWCONTENT       = 0x00200000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    // IShellFolder::GetDisplayNameOf constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    public static final int SHGDN_NORMAL            = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    public static final int SHGDN_INFOLDER          = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    public static final int SHGDN_INCLUDE_NONFILESYS= 0x2000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    public static final int SHGDN_FORADDRESSBAR     = 0x4000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    public static final int SHGDN_FORPARSING        = 0x8000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    // Values for system call LoadIcon()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    public enum SystemIcon {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        IDI_APPLICATION(32512),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        IDI_HAND(32513),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        IDI_ERROR(32513),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        IDI_QUESTION(32514),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        IDI_EXCLAMATION(32515),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        IDI_WARNING(32515),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        IDI_ASTERISK(32516),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        IDI_INFORMATION(32516),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        IDI_WINLOGO(32517);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        private final int iconID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        SystemIcon(int iconID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            this.iconID = iconID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        public int getIconID() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            return iconID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    static class FolderDisposer implements sun.java2d.DisposerRecord {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         * This is cached as a concession to getFolderType(), which needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         * an absolute PIDL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        long absolutePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
         * We keep track of shell folders through the IShellFolder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
         * interface of their parents plus their relative PIDL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        long pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        long relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        boolean disposed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        public void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            if (disposed) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            if (relativePIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                releasePIDL(relativePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            if (absolutePIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                releasePIDL(absolutePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            if (pIShellFolder != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                releaseIShellFolder(pIShellFolder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            disposed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    FolderDisposer disposer = new FolderDisposer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    private void setIShellFolder(long pIShellFolder) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        disposer.pIShellFolder = pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    private void setRelativePIDL(long relativePIDL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        disposer.relativePIDL = relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * The following are for caching various shell folder properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    private long pIShellIcon = -1L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    private String folderType = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    private String displayName = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    private Image smallIcon = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    private Image largeIcon = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    private Boolean isDir = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * The following is to identify the My Documents folder as being special
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    private boolean isPersonal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * Create a system special shell folder, such as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * desktop or Network Neighborhood.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    Win32ShellFolder2(int csidl) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        // Desktop is parent of DRIVES and NETWORK, not necessarily
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        // other special shell folders.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        super(null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
              (getFileSystemPath(csidl) == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                ? ("ShellFolder: 0x"+Integer.toHexString(csidl)) : getFileSystemPath(csidl));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        if (csidl == DESKTOP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            initDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            initSpecial(getDesktop().getIShellFolder(), csidl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            // At this point, the native method initSpecial() has set our relativePIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            // relative to the Desktop, which may not be our immediate parent. We need
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            // to traverse this ID list and break it into a chain of shell folders from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            // the top, with each one having an immediate parent and a relativePIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            // relative to that parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            long pIDL = disposer.relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            parent = getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            while (pIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                // Get a child pidl relative to 'parent'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                long childPIDL = copyFirstPIDLEntry(pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                if (childPIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                    // Get a handle to the the rest of the ID list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                    // i,e, parent's grandchilren and down
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                    pIDL = getNextPIDLEntry(pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                    if (pIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                        // Now we know that parent isn't immediate to 'this' because it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                        // has a continued ID list. Create a shell folder for this child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                        // pidl and make it the new 'parent'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                        parent = new Win32ShellFolder2((Win32ShellFolder2)parent, childPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                        // No grandchildren means we have arrived at the parent of 'this',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                        // and childPIDL is directly relative to parent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                        disposer.relativePIDL = childPIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        sun.java2d.Disposer.addRecord(this, disposer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * Create a system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder, long relativePIDL, String path) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        super(parent, (path != null) ? path : "ShellFolder: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        this.disposer.pIShellFolder = pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        this.disposer.relativePIDL = relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        sun.java2d.Disposer.addRecord(this, disposer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * Creates a shell folder with a parent and relative PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    Win32ShellFolder2(Win32ShellFolder2 parent, long relativePIDL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        super(parent, getFileSystemPath(parent.getIShellFolder(), relativePIDL));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        this.disposer.relativePIDL = relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        getAbsolutePath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        sun.java2d.Disposer.addRecord(this, disposer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    // Initializes the desktop shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    private native void initDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    // Initializes a special, non-file system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    // from one of the above constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    private native void initSpecial(long desktopIShellFolder, int csidl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    /** Marks this folder as being the My Documents (Personal) folder */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    public void setIsPersonal() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        isPersonal = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * This method is implemented to make sure that no instances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * of <code>ShellFolder</code> are ever serialized. If <code>isFileSystem()</code> returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * <code>true</code>, then the object is representable with an instance of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * <code>java.io.File</code> instead. If not, then the object depends
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * on native PIDL state and should not be serialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     *
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   309
     * @return a <code>java.io.File</code> replacement object. If the folder
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * is a not a normal directory, then returns the first non-removable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * drive (normally "C:\").
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    protected Object writeReplace() throws java.io.ObjectStreamException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        if (isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            return new File(getPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            Win32ShellFolder2 drives = Win32ShellFolderManager2.getDrives();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            if (drives != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                File[] driveRoots = drives.listFiles();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                if (driveRoots != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                    for (int i = 0; i < driveRoots.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                        if (driveRoots[i] instanceof Win32ShellFolder2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                            Win32ShellFolder2 sf = (Win32ShellFolder2)driveRoots[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                            if (sf.isFileSystem() && !sf.hasAttribute(ATTRIB_REMOVABLE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                                return new File(sf.getPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            // Ouch, we have no hard drives. Return something "valid" anyway.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            return new File("C:\\");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * Finalizer to clean up any COM objects or PIDLs used by this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    protected void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        disposer.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    // Given a (possibly multi-level) relative PIDL (with respect to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    // the desktop, at least in all of the usage cases in this code),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    // return a pointer to the next entry. Does not mutate the PIDL in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    // any way. Returns 0 if the null terminator is reached.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    static native long getNextPIDLEntry(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    // Given a (possibly multi-level) relative PIDL (with respect to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    // the desktop, at least in all of the usage cases in this code),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    // copy the first entry into a newly-allocated PIDL. Returns 0 if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    // the PIDL is at the end of the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    static native long copyFirstPIDLEntry(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    // Given a parent's absolute PIDL and our relative PIDL, build an absolute PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    private static native long combinePIDLs(long ppIDL, long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    // Release a PIDL object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    static native void releasePIDL(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    // Release an IShellFolder object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    private static native void releaseIShellFolder(long pIShellFolder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * Accessor for IShellFolder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    public long getIShellFolder() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (disposer.pIShellFolder == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            assert(isDirectory());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            assert(parent != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            long parentIShellFolder = getParentIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            if (parentIShellFolder == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                throw new InternalError("Parent IShellFolder was null for " + getAbsolutePath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            // We are a directory with a parent and a relative PIDL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            // We want to bind to the parent so we get an IShellFolder instance associated with us.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            disposer.pIShellFolder = bindToObject(parentIShellFolder, disposer.relativePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            if (disposer.pIShellFolder == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                throw new InternalError("Unable to bind " + getAbsolutePath() + " to parent");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        return disposer.pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * Get the parent ShellFolder's IShellFolder interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    public long getParentIShellFolder() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        Win32ShellFolder2 parent = (Win32ShellFolder2)getParentFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        if (parent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            // Parent should only be null if this is the desktop, whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            // relativePIDL is relative to its own IShellFolder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            return getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        return parent.getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * Accessor for relative PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    public long getRelativePIDL() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        if (disposer.relativePIDL == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            throw new InternalError("Should always have a relative PIDL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        return disposer.relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    private long getAbsolutePIDL() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        if (parent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            // This is the desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            return getRelativePIDL();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            if (disposer.absolutePIDL == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                disposer.absolutePIDL = combinePIDLs(((Win32ShellFolder2)parent).getAbsolutePIDL(), getRelativePIDL());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            return disposer.absolutePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * Helper function to return the desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    public Win32ShellFolder2 getDesktop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        return Win32ShellFolderManager2.getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * Helper function to return the desktop IShellFolder interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    public long getDesktopIShellFolder() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        return getDesktop().getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    private static boolean pathsEqual(String path1, String path2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        // Same effective implementation as Win32FileSystem
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        return path1.equalsIgnoreCase(path2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     * Check to see if two ShellFolder objects are the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    public boolean equals(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        if (o == null || !(o instanceof Win32ShellFolder2)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            // Short-circuit circuitous delegation path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            if (!(o instanceof File)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                return super.equals(o);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            return pathsEqual(getPath(), ((File) o).getPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        Win32ShellFolder2 rhs = (Win32ShellFolder2) o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        if ((parent == null && rhs.parent != null) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            (parent != null && rhs.parent == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        if (isFileSystem() && rhs.isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            // Only folders with identical parents can be equal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            return (pathsEqual(getPath(), rhs.getPath()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                    (parent == rhs.parent || parent.equals(rhs.parent)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        if (parent == rhs.parent || parent.equals(rhs.parent)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    private static boolean pidlsEqual(long pIShellFolder, long pidl1, long pidl2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        return (compareIDs(pIShellFolder, pidl1, pidl2) == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    private static native int compareIDs(long pParentIShellFolder, long pidl1, long pidl2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * @return Whether this is a file system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    public boolean isFileSystem() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        return hasAttribute(ATTRIB_FILESYSTEM);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * Return whether the given attribute flag is set for this object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    public boolean hasAttribute(int attribute) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        // Caching at this point doesn't seem to be cost efficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        return (getAttributes0(getParentIShellFolder(), getRelativePIDL(), attribute) & attribute) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * Returns the queried attributes specified in attrsMask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * Could plausibly be used for attribute caching but have to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     * very careful not to touch network drives and file system roots
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * with a full attrsMask
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    private static native int getAttributes0(long pParentIShellFolder, long pIDL, int attrsMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    // Return the path to the underlying file system object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    private static String getFileSystemPath(long parentIShellFolder, long relativePIDL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            String s =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                                  getLinkLocation(parentIShellFolder, relativePIDL, false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            if (s != null && s.startsWith("\\\\")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_NORMAL | SHGDN_FORPARSING);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    static native String getFileSystemPath(int csidl) throws IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    // Return whether the path is a network root.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    // Path is assumed to be non-null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    private static boolean isNetworkRoot(String path) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        return (path.equals("\\\\") || path.equals("\\") || path.equals("//") || path.equals("/"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     * @return The parent shell folder of this shell folder, null if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     * there is no parent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    public File getParentFile() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        return parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    public boolean isDirectory() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        if (isDir == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            // Folders with SFGAO_BROWSABLE have "shell extension" handlers and are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            // not traversable in JFileChooser. An exception is "My Documents" on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            // Windows 98.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            if (hasAttribute(ATTRIB_FOLDER)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                && (!hasAttribute(ATTRIB_BROWSABLE) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                    (is98 && equals(Win32ShellFolderManager2.getPersonal())))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                isDir = Boolean.TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            } else if (isLink()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                ShellFolder linkLocation = getLinkLocation(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                isDir = Boolean.valueOf(linkLocation != null && linkLocation.isDirectory());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                isDir = Boolean.FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        return isDir.booleanValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * Functions for enumerating an IShellFolder's children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    // Returns an IEnumIDList interface for an IShellFolder.  The value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    // returned must be released using releaseEnumObjects().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    private long getEnumObjects(long pIShellFolder, boolean includeHiddenFiles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    // Returns an IEnumIDList interface for an IShellFolder.  The value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    // returned must be released using releaseEnumObjects().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    private native long getEnumObjects(long pIShellFolder, boolean isDesktop,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                                       boolean includeHiddenFiles);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    // Returns the next sequential child as a relative PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    // from an IEnumIDList interface.  The value returned must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    // be released using releasePIDL().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    private native long getNextChild(long pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
    // Releases the IEnumIDList interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    private native void releaseEnumObjects(long pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    // Returns the IShellFolder of a child from a parent IShellFolder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    // and a relative PIDL.  The value returned must be released
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    // using releaseIShellFolder().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    private static native long bindToObject(long parentIShellFolder, long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     * @return An array of shell folders that are children of this shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
     *         object. The array will be empty if the folder is empty.  Returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
     *         <code>null</code> if this shellfolder does not denote a directory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    public File[] listFiles(boolean includeHiddenFiles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        SecurityManager security = System.getSecurityManager();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        if (security != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            security.checkRead(getPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        if (!isDirectory()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        // Links to directories are not directories and cannot be parents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        // This does not apply to folders in My Network Places (NetHood)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        // because they are both links and real directories!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            return new File[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        // If we are a directory, we have a parent and (at least) a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        // relative PIDL. We must first ensure we are bound to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        // parent so we have an IShellFolder to query.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        long pIShellFolder = getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        // Now we can enumerate the objects in this folder.
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   608
        ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        if (pEnumObjects != 0) {
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   611
            long childPIDL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                if (Thread.currentThread().isInterrupted()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                    return new File[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                childPIDL = getNextChild(pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                boolean releasePIDL = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                if (childPIDL != 0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                    (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                    Win32ShellFolder2 childFolder = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                    if (this.equals(desktop)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                        && personal != null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                        && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                        childFolder = personal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                        childFolder = new Win32ShellFolder2(this, childPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                        releasePIDL = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                    list.add(childFolder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                if (releasePIDL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                    releasePIDL(childPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            } while (childPIDL != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            releaseEnumObjects(pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        }
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   638
        return list.toArray(new ShellFolder[list.size()]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     * Look for (possibly special) child folder by it's path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * @return The child shellfolder, or null if not found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    Win32ShellFolder2 getChildByPath(String filePath) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        long pIShellFolder = getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        long pEnumObjects =  getEnumObjects(pIShellFolder, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        Win32ShellFolder2 child = null;
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   651
        long childPIDL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                String path = getFileSystemPath(pIShellFolder, childPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                if (path != null && path.equalsIgnoreCase(filePath)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                    long childIShellFolder = bindToObject(pIShellFolder, childPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                    child = new Win32ShellFolder2(this, childIShellFolder, childPIDL, path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
            releasePIDL(childPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        releaseEnumObjects(pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        return child;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * @return Whether this shell folder is a link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    public boolean isLink() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        return hasAttribute(ATTRIB_LINK);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     * @return Whether this shell folder is marked as hidden
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    public boolean isHidden() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        return hasAttribute(ATTRIB_HIDDEN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    // Return the link location of a shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
    private static native long getLinkLocation(long parentIShellFolder,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                                        long relativePIDL, boolean resolve);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * @return The shell folder linked to by this shell folder, or null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * if this shell folder is not a link or is a broken or invalid link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    public ShellFolder getLinkLocation()  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        return getLinkLocation(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    private ShellFolder getLinkLocation(boolean resolve)  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        if (!isLink()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        ShellFolder location = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        long linkLocationPIDL = getLinkLocation(getParentIShellFolder(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                                                getRelativePIDL(), resolve);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        if (linkLocationPIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                location =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                    Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                                                                               linkLocationPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            } catch (InternalError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                // Could be a link to a non-bindable object, such as a network connection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                // TODO: getIShellFolder() should throw FileNotFoundException instead
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        return location;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
    // Parse a display name into a PIDL relative to the current IShellFolder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    long parseDisplayName(String name) throws FileNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
            return parseDisplayName0(getIShellFolder(), name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            throw new FileNotFoundException("Could not find file " + name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    private static native long parseDisplayName0(long pIShellFolder, String name) throws IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    // Return the display name of a shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    private static native String getDisplayNameOf(long parentIShellFolder,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                                                  long relativePIDL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                                                  int attrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
     * @return The name used to display this shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    public String getDisplayName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        if (displayName == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            displayName = getDisplayNameOf(getParentIShellFolder(), getRelativePIDL(), SHGDN_NORMAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        return displayName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    // Return the folder type of a shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    private static native String getFolderType(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
     * @return The type of shell folder as a string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    public String getFolderType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        if (folderType == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            folderType = getFolderType(getAbsolutePIDL());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        return folderType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    // Return the executable type of a file system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    private native String getExecutableType(String path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * @return The executable type as a string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    public String getExecutableType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        if (!isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        return getExecutableType(getAbsolutePath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    // Icons
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    private static Map smallSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    private static Map largeSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    private static Map smallLinkedSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
    private static Map largeLinkedSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    private static native long getIShellIcon(long pIShellFolder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    // Return the icon of a file system shell folder in the form of an HICON
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    private static native long getIcon(String absolutePath, boolean getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
    private static native long extractIcon(long parentIShellFolder, long relativePIDL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                                           boolean getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    // Returns an icon from the Windows system icon list in the form of an HICON
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    private static native long getSystemIcon(int iconID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    private static native long getIconResource(String libName, int iconID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                                               int cxDesired, int cyDesired,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                                               boolean useVGAColors);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                                               // Note: useVGAColors is ignored on XP and later
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    // Return the bits from an HICON.  This has a side effect of setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    // the imageHash variable for efficient caching / comparing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    private static native int[] getIconBits(long hIcon, int iconSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
    // Dispose the HICON
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
    private static native void disposeIcon(long hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    public static native int[] getFileChooserBitmapBits();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    private long getIShellIcon() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        if (pIShellIcon == -1L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            pIShellIcon = getIShellIcon(getIShellFolder());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        return pIShellIcon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    static int[] fileChooserBitmapBits = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    static Image[] fileChooserIcons = new Image[47];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    static Image getFileChooserIcon(int i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        if (fileChooserIcons[i] != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            return fileChooserIcons[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            if (fileChooserBitmapBits == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                fileChooserBitmapBits = getFileChooserBitmapBits();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            if (fileChooserBitmapBits != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                int nImages = fileChooserBitmapBits.length / (16*16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                int[] bitmapBits = new int[16 * 16];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                for (int y = 0; y < 16; y++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                    for (int x = 0; x < 16; x++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                        bitmapBits[y * 16 + x] = fileChooserBitmapBits[y * (nImages * 16) + (i * 16) + x];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                img.setRGB(0, 0, 16, 16, bitmapBits, 0, 16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                fileChooserIcons[i] = img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        return fileChooserIcons[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    private static Image makeIcon(long hIcon, boolean getLargeIcon) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        if (hIcon != 0L && hIcon != -1L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            // Get the bits.  This has the side effect of setting the imageHash value for this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
            int size = getLargeIcon ? 32 : 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            int[] iconBits = getIconBits(hIcon, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
            if (iconBits != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                img.setRGB(0, 0, size, size, iconBits, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                return img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
     * @return The icon image used to display this shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
    public Image getIcon(boolean getLargeIcon) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        Image icon = getLargeIcon ? largeIcon : smallIcon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        if (icon == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            long parentIShellIcon = (parent != null) ? ((Win32ShellFolder2)parent).getIShellIcon() : 0L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            long relativePIDL = getRelativePIDL();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
            if (isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                // These are cached per type (using the index in the system image list)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                int index = getIconIndex(parentIShellIcon, relativePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                if (index > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    Map imageCache;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                    if (isLink()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                        imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                        imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                    icon = (Image)imageCache.get(Integer.valueOf(index));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                    if (icon == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                        long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                        icon = makeIcon(hIcon, getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                        disposeIcon(hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                        if (icon != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                            imageCache.put(Integer.valueOf(index), icon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
            if (icon == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                // These are only cached per object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                long hIcon = extractIcon(getParentIShellFolder(), getRelativePIDL(), getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                icon = makeIcon(hIcon, getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                disposeIcon(hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
            if (getLargeIcon) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                largeIcon = icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                smallIcon = icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        if (icon == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
            icon = super.getIcon(getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        return icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
     * Gets an icon from the Windows system icon list as an <code>Image</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    static Image getSystemIcon(SystemIcon iconType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        long hIcon = getSystemIcon(iconType.getIconID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        Image icon = makeIcon(hIcon, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        disposeIcon(hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        return icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
     * Gets an icon from the Windows system icon list as an <code>Image</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
     */
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   913
    static Image getShell32Icon(int iconID, boolean getLargeIcon) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        boolean useVGAColors = true; // Will be ignored on XP and later
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   916
        int size = getLargeIcon ? 32 : 16;
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   917
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
        Toolkit toolkit = Toolkit.getDefaultToolkit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
        String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
        if (shellIconBPP != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
            useVGAColors = shellIconBPP.equals("4");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   924
        long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        if (hIcon != 0) {
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   926
            Image icon = makeIcon(hIcon, getLargeIcon);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
            disposeIcon(hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
            return icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
     * Returns the canonical form of this abstract pathname.  Equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
     * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
     * @see java.io.File#getCanonicalFile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
    public File getCanonicalFile() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
     * Indicates whether this is a special folder (includes My Documents)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    public boolean isSpecial() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
        return isPersonal || !isFileSystem() || (this == getDesktop());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
     * Compares this object with the specified object for order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     * @see sun.awt.shell.ShellFolder#compareTo(File)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
    public int compareTo(File file2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        if (!(file2 instanceof Win32ShellFolder2)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
            if (isFileSystem() && !isSpecial()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
                return super.compareTo(file2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
                return -1; // Non-file shellfolders sort before files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        return Win32ShellFolderManager2.compareShellFolders(this, (Win32ShellFolder2) file2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    // native constants from commctrl.h
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
    private static final int LVCFMT_LEFT = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
    private static final int LVCFMT_RIGHT = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    private static final int LVCFMT_CENTER = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    public ShellFolderColumnInfo[] getFolderColumns() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
        ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        if (columns != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
            List<ShellFolderColumnInfo> notNullColumns =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
                    new ArrayList<ShellFolderColumnInfo>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            for (int i = 0; i < columns.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
                ShellFolderColumnInfo column = columns[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
                if (column != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                    column.setAlignment(column.getAlignment() == LVCFMT_RIGHT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                            ? SwingConstants.RIGHT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
                                : column.getAlignment() == LVCFMT_CENTER
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                            ? SwingConstants.CENTER
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
                                : SwingConstants.LEADING);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   986
                    column.setComparator(new ColumnComparator(getIShellFolder(), i));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                    notNullColumns.add(column);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            columns = new ShellFolderColumnInfo[notNullColumns.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
            notNullColumns.toArray(columns);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
        return columns;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    public Object getFolderColumnValue(int column) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    private native ShellFolderColumnInfo[] doGetColumnInfo(long iShellFolder2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
    private native Object doGetColumnValue(long parentIShellFolder2, long childPIDL, int columnIdx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1005
    private static native int compareIDsByColumn(long pParentIShellFolder, long pidl1, long pidl2, int columnIdx);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1008
    public void sortChildren(List<? extends File> files) {
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1009
        Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1010
    }
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1011
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1012
    private static class ColumnComparator implements Comparator<File> {
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1013
        private final long parentIShellFolder;
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1014
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
        private final int columnIdx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1017
        public ColumnComparator(long parentIShellFolder, int columnIdx) {
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1018
            this.parentIShellFolder = parentIShellFolder;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
            this.columnIdx = columnIdx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
        // compares 2 objects within this folder by the specified column
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1023
        public int compare(File o, File o1) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
            if (o instanceof Win32ShellFolder2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
                    && o1 instanceof Win32ShellFolder2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                // delegates comparison to native method
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1027
                return compareIDsByColumn(parentIShellFolder,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
                        ((Win32ShellFolder2) o).getRelativePIDL(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
                        ((Win32ShellFolder2) o1).getRelativePIDL(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                        columnIdx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
}