8017487: filechooser in Windows-Libraries folder: columns are mixed up
Reviewed-by: serb, ant
This commit is contained in:
parent
259cdd9d8f
commit
032cef6ff8
@ -29,6 +29,7 @@ import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
@ -233,6 +234,7 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
private Image smallIcon = null;
|
||||
private Image largeIcon = null;
|
||||
private Boolean isDir = null;
|
||||
private final boolean isLib;
|
||||
|
||||
/*
|
||||
* The following is to identify the My Documents folder as being special
|
||||
@ -254,6 +256,7 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
// Desktop is parent of DRIVES and NETWORK, not necessarily
|
||||
// other special shell folders.
|
||||
super(null, composePathForCsidl(csidl));
|
||||
isLib = false;
|
||||
|
||||
invoke(new Callable<Void>() {
|
||||
public Void call() throws InterruptedException {
|
||||
@ -279,7 +282,7 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
// Now we know that parent isn't immediate to 'this' because it
|
||||
// has a continued ID list. Create a shell folder for this child
|
||||
// pidl and make it the new 'parent'.
|
||||
parent = new Win32ShellFolder2((Win32ShellFolder2) parent, childPIDL);
|
||||
parent = createShellFolder((Win32ShellFolder2) parent, childPIDL);
|
||||
} else {
|
||||
// No grandchildren means we have arrived at the parent of 'this',
|
||||
// and childPIDL is directly relative to parent.
|
||||
@ -301,8 +304,9 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
/**
|
||||
* Create a system shell folder
|
||||
*/
|
||||
Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder, long relativePIDL, String path) {
|
||||
Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder, long relativePIDL, String path, boolean isLib) {
|
||||
super(parent, (path != null) ? path : "ShellFolder: ");
|
||||
this.isLib = isLib;
|
||||
this.disposer.pIShellFolder = pIShellFolder;
|
||||
this.disposer.relativePIDL = relativePIDL;
|
||||
sun.java2d.Disposer.addRecord(this, disposer);
|
||||
@ -312,16 +316,19 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
/**
|
||||
* Creates a shell folder with a parent and relative PIDL
|
||||
*/
|
||||
Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException {
|
||||
super(parent,
|
||||
invoke(new Callable<String>() {
|
||||
public String call() {
|
||||
return getFileSystemPath(parent.getIShellFolder(), relativePIDL);
|
||||
}
|
||||
}, RuntimeException.class)
|
||||
);
|
||||
this.disposer.relativePIDL = relativePIDL;
|
||||
sun.java2d.Disposer.addRecord(this, disposer);
|
||||
static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, long pIDL)
|
||||
throws InterruptedException {
|
||||
String path = invoke(new Callable<String>() {
|
||||
public String call() {
|
||||
return getFileSystemPath(parent.getIShellFolder(), pIDL);
|
||||
}
|
||||
}, RuntimeException.class);
|
||||
String libPath = resolveLibrary(path);
|
||||
if (libPath == null) {
|
||||
return new Win32ShellFolder2(parent, 0, pIDL, path, false);
|
||||
} else {
|
||||
return new Win32ShellFolder2(parent, 0, pIDL, libPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes the desktop shell folder
|
||||
@ -601,20 +608,24 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
}
|
||||
String path = getDisplayNameOf(parentIShellFolder, relativePIDL,
|
||||
SHGDN_FORPARSING);
|
||||
return path;
|
||||
}
|
||||
|
||||
private static String resolveLibrary(String path) {
|
||||
// if this is a library its default save location is taken as a path
|
||||
// this is a temp fix until java.io starts support Libraries
|
||||
if( path != null && path.startsWith("::{") &&
|
||||
path.toLowerCase().endsWith(".library-ms")) {
|
||||
for (KnownFolderDefinition kf : KnownFolderDefinition.libraries) {
|
||||
if( path.toLowerCase().endsWith(
|
||||
kf.relativePath.toLowerCase()) &&
|
||||
path.toUpperCase().startsWith(
|
||||
kf.parsingName.substring(0, 40).toUpperCase()) ) {
|
||||
if (path.toLowerCase().endsWith(
|
||||
"\\" + kf.relativePath.toLowerCase()) &&
|
||||
path.toUpperCase().startsWith(
|
||||
kf.parsingName.substring(0, 40).toUpperCase())) {
|
||||
return kf.saveLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Needs to be accessible to Win32ShellFolderManager2
|
||||
@ -750,7 +761,7 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
&& pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
|
||||
childFolder = personal;
|
||||
} else {
|
||||
childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
|
||||
childFolder = createShellFolder(Win32ShellFolder2.this, childPIDL);
|
||||
releasePIDL = false;
|
||||
}
|
||||
list.add(childFolder);
|
||||
@ -790,10 +801,11 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
|
||||
if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
|
||||
String path = getFileSystemPath(pIShellFolder, childPIDL);
|
||||
if(isLib) path = resolveLibrary( path );
|
||||
if (path != null && path.equalsIgnoreCase(filePath)) {
|
||||
long childIShellFolder = bindToObject(pIShellFolder, childPIDL);
|
||||
child = new Win32ShellFolder2(Win32ShellFolder2.this,
|
||||
childIShellFolder, childPIDL, path);
|
||||
childIShellFolder, childPIDL, path, isLib);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1129,6 +1141,8 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
private static final int LVCFMT_CENTER = 2;
|
||||
|
||||
public ShellFolderColumnInfo[] getFolderColumns() {
|
||||
ShellFolder library = resolveLibrary();
|
||||
if (library != null) return library.getFolderColumns();
|
||||
return invoke(new Callable<ShellFolderColumnInfo[]>() {
|
||||
public ShellFolderColumnInfo[] call() {
|
||||
ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
|
||||
@ -1159,6 +1173,10 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
}
|
||||
|
||||
public Object getFolderColumnValue(final int column) {
|
||||
if(!isLibrary()) {
|
||||
ShellFolder library = resolveLibrary();
|
||||
if (library != null) return library.getFolderColumnValue(column);
|
||||
}
|
||||
return invoke(new Callable<Object>() {
|
||||
public Object call() {
|
||||
return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
|
||||
@ -1166,6 +1184,26 @@ final class Win32ShellFolder2 extends ShellFolder {
|
||||
});
|
||||
}
|
||||
|
||||
boolean isLibrary() {
|
||||
return isLib;
|
||||
}
|
||||
|
||||
private ShellFolder resolveLibrary() {
|
||||
for (ShellFolder f = this; f != null; f = f.parent) {
|
||||
if (!f.isFileSystem()) {
|
||||
if (f instanceof Win32ShellFolder2 &&
|
||||
((Win32ShellFolder2)f).isLibrary()) {
|
||||
try {
|
||||
return getShellFolder(new File(getPath()));
|
||||
} catch (FileNotFoundException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
|
||||
private native ShellFolderColumnInfo[] doGetColumnInfo(long iShellFolder2);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -94,7 +94,7 @@ final class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
while (pIDL != 0) {
|
||||
long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL);
|
||||
if (curPIDL != 0) {
|
||||
parent = new Win32ShellFolder2(parent, curPIDL);
|
||||
parent = Win32ShellFolder2.createShellFolder(parent, curPIDL);
|
||||
pIDL = Win32ShellFolder2.getNextPIDLEntry(pIDL);
|
||||
} else {
|
||||
// The list is empty if the parent is Desktop and pIDL is a shortcut to Desktop
|
||||
|
82
jdk/test/java/awt/FileDialog/8017487/bug8017487.java
Normal file
82
jdk/test/java/awt/FileDialog/8017487/bug8017487.java
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 8017487
|
||||
@summary filechooser in Windows-Libraries folder: columns are mixed up
|
||||
@author Semyon Sadetsky
|
||||
@library /lib/testlibrary
|
||||
@build jdk.testlibrary.OSInfo
|
||||
@run main bug8017487
|
||||
*/
|
||||
|
||||
|
||||
import jdk.testlibrary.OSInfo;
|
||||
|
||||
import sun.awt.shell.ShellFolder;
|
||||
import sun.awt.shell.ShellFolderColumnInfo;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
import java.io.File;
|
||||
|
||||
public class bug8017487
|
||||
{
|
||||
public static void main(String[] p_args) throws Exception {
|
||||
if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS &&
|
||||
OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_VISTA) > 0 ) {
|
||||
test();
|
||||
System.out.println("ok");
|
||||
}
|
||||
}
|
||||
|
||||
private static void test() throws Exception {
|
||||
FileSystemView fsv = FileSystemView.getFileSystemView();
|
||||
File def = new File(fsv.getDefaultDirectory().getAbsolutePath());
|
||||
ShellFolderColumnInfo[] defColumns =
|
||||
ShellFolder.getShellFolder(def).getFolderColumns();
|
||||
|
||||
File[] files = fsv.getHomeDirectory().listFiles();
|
||||
for (File file : files) {
|
||||
if( "Libraries".equals(ShellFolder.getShellFolder( file ).getDisplayName())) {
|
||||
File[] libs = file.listFiles();
|
||||
for (File lib : libs) {
|
||||
ShellFolder libFolder =
|
||||
ShellFolder.getShellFolder(lib);
|
||||
if( "Library".equals(libFolder.getFolderType() ) ) {
|
||||
ShellFolderColumnInfo[] folderColumns =
|
||||
libFolder.getFolderColumns();
|
||||
|
||||
for (int i = 0; i < defColumns.length; i++) {
|
||||
if (!defColumns[i].getTitle()
|
||||
.equals(folderColumns[i].getTitle()))
|
||||
throw new RuntimeException("Columnn " +
|
||||
folderColumns[i].getTitle() +
|
||||
" doesn't match " +
|
||||
defColumns[i].getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user