VAqua.src.org.violetlib.aqua.fc.BasicOSXFileSystemView Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaqua Show documentation
Show all versions of vaqua Show documentation
An improved native Swing look and feel for macOS
The newest version!
/*
* Copyright (c) 2009-2010 Werner Randelshofer, Switzerland.
* Copyright (c) 2014-2019 Alan Snyder
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
package org.violetlib.aqua.fc;
import java.io.File;
import java.io.IOException;
import java.util.*;
import javax.swing.*;
import org.jetbrains.annotations.NotNull;
/**
* BasicOSXFileSystemView.
*
* A common base class for OS X file system views. The key feature of an OS X file system view is that the Unix root
* directory is mapped to the system volume. Also, there is no OS X file that corresponds exactly to the Computer node
* in the file chooser tree model, but the Volumes folder is the closest, so we use that.
*
* This class also supports custom lists of hidden files.
*/
public abstract class BasicOSXFileSystemView extends AquaFileSystemView {
protected final File volumesFolder = new File("/Volumes");
protected final File networkFolder = new File("/Network");
protected final File unixRoot = new File("/");
private final File computer = volumesFolder;
protected File systemVolume;
/**
* This is a list of file names that are treated as invisible by the AWT
* FileDialog when they are at the top directory level of a volume.
* The file names are wrongly treated as visible by
* Apple's implementation FileSystemView, so we use this HashSet here, to
* hide them 'manually'.
*/
protected final static Set hiddenTopLevelNames = new HashSet<>();
protected final static Set hiddenDirectoryNames = new HashSet<>();
protected final static Set hiddenFiles = new HashSet<>();
protected BasicOSXFileSystemView() {
}
public final File getSystemVolume() {
if (systemVolume == null) {
systemVolume = determineSystemVolume();
}
return systemVolume;
}
protected File determineSystemVolume() {
File[] volumes = volumesFolder.listFiles();
File sys = null;
if (volumes != null) {
for (File volume : volumes) {
try {
if (volume.getCanonicalFile().equals(unixRoot)) {
sys = volume;
break;
}
} catch (IOException e) {
// We get here because we can't determine the canonical path for the volume. We suppress this
// exception, in the hope that it did not happen for the system volume. If it happened for the
// system volume, there is fallback code in method getSystemVolume() that handles this problem.
// AquaUtils.logError("Unable to canonicalize volume " + volumes[i]);
// e.printStackTrace();
} catch (SecurityException e) {
// We get here because we are not allowed to read the file. We suppress this exception, in the hope
// that it did not happen for the system volume. If it happened for the system volume, there is
// fallback code in method getSystemVolume() that handles this problem.
}
}
}
// If we couldn't determine the system volume, we use the root folder instead.
return (sys == null) ? unixRoot : sys;
}
@Override
public File getComputer() {
return computer;
}
/**
* Convert a file (path) to canonical form. A reference to the Unix root directory is mapped to the system volume.
*/
@Override
public File canonicalize(File f) {
if (f.equals(unixRoot)) {
return getSystemVolume();
}
return f;
}
/**
* Returns the parent directory of dir.
* This method returns the system volume instead of the root folder ("/").
*/
@Override
public File getParentDirectory(File dir) {
File parent = (isRoot(dir)) ? null : super.getParentDirectory(dir);
if (parent != null && parent.equals(unixRoot)) {
parent = getSystemVolume();
}
return parent;
}
/**
* Returns all root partitions on this system.
* This method returns the contents of the volumes folder.
* The root folder ("/") is considered as hidden and not
* returned by this method.
*/
protected List getRootList() {
List result = new ArrayList();
File[] fs = volumesFolder.listFiles();
if (fs != null) {
result.addAll(Arrays.asList(fs));
}
/*
Even if /Network is hidden when viewing /, it may be visible in the sidebar or under the Computer node.
*/
result.add(networkFolder);
return result;
}
/**
* Returns all root partitions on this system.
* This method returns the contents of the volumes folder.
* The root folder ("/") is considered as hidden and not
* returned by this method.
*/
@Override
public final File[] getRoots() {
List roots = getRootList();
return roots.toArray(new File[roots.size()]);
}
@Override
public boolean isHiddenFile(@NotNull File f) {
if (OSXFile.isInvisible(f)) {
return true;
} else {
String name = f.getName();
if (name.length() == 0) {
return false;
} else if (name.charAt(name.length() - 1) == (char) 0x0d) {
// File names ending with 0x0d are considered as hidden
return true;
} else if (name.charAt(0) == '.') {
// File names starting with '.' are considered as hidden
return true;
} else if (hiddenTopLevelNames.contains(name) && (f.getParent() == null || isRoot(f.getParentFile()))) {
return true;
} else if (hiddenDirectoryNames.contains(name)) {
return true;
} else if (hiddenFiles.contains(f)) {
return true;
} else {
return false;
}
}
}
@Override
public boolean isRoot(File aFile) {
return aFile.equals(unixRoot) || aFile.equals(networkFolder) || aFile.getParentFile() != null && aFile.getParentFile().equals(volumesFolder);
}
@Override
public boolean isParent(File folder, File file) {
if (folder == null || file == null) {
return false;
} else {
return folder.equals(file.getParentFile());
}
}
@Override
public File getChild(File parent, String fileName) {
return new File(parent, fileName);
}
@Override
public boolean isFileSystemRoot(File dir) {
File parentFile = dir.getParentFile();
return parentFile == null || parentFile.equals(volumesFolder);
}
@Override
public File getHomeDirectory() {
return createFileObject(System.getProperty("user.home"));
}
@Override
public File getDefaultDirectory() {
return getHomeDirectory();
}
@Override
public Icon getSystemIcon(File f) {
if (f.equals(networkFolder)) {
Icon icon = UIManager.getIcon("FileView.networkIcon");
if (icon != null) {
return icon;
}
}
if (f.equals(getComputer())) {
Icon icon = UIManager.getIcon("FileView.computerIcon");
if (icon != null) {
return icon;
}
}
return AquaFileIcons.getThumbnail(f);
}
@Override
public String getSystemTypeDescription(File f) {
if (OSXFile.isAvailable()) {
return OSXFile.getKindString(f);
} else {
return super.getSystemTypeDescription(f);
}
}
@Override
public Boolean isTraversable(File f) {
if (OSXFile.isAvailable()) {
return OSXFile.isTraversable(f);
} else {
return super.isTraversable(f);
}
}
@Override
public @NotNull Boolean isTraversable(File f, boolean isPackageTraversable, boolean isApplicationTraversable) {
if (OSXFile.isAvailable()) {
return OSXFile.isTraversable(f, isPackageTraversable, isApplicationTraversable);
} else {
return super.isTraversable(f);
}
}
@Override
public String getSystemDisplayName(File f) {
if (f.equals(getComputer())) {
String name = OSXFile.getComputerName();
return name != null ? name : getSystemVolume().getName();
} else {
if (OSXFile.isAvailable()) {
return OSXFile.getDisplayName(f);
} else {
return super.getSystemDisplayName(f);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy