File chooser: return logical paths along with chosen files

This commit is contained in:
Roman Shevchenko
2012-02-15 18:14:24 +01:00
parent e9dca91401
commit 9a26bf5df2
4 changed files with 124 additions and 50 deletions
@@ -0,0 +1,53 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.fileChooser;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Temporary class, do not use.
* Will be removed after migration from file choosing to path choosing (approx. in IDEA 13).
*
* @author Roman Shevchenko
*/
public final class FileChooserUtil {
private static final Key<String> PATH_KEY = Key.create("FileChooser.Path");
@NotNull
public static String getSelectionPath(@NotNull final VirtualFile file) {
final String path = file.getUserData(PATH_KEY);
return path != null ? path : file.getPath();
}
public static void setSelectionPath(@NotNull final VirtualFile file, @Nullable final String path) {
file.putUserData(PATH_KEY, path);
}
@NotNull
public static String[] getPaths(@NotNull final VirtualFile[] files) {
if (files.length == 0) return ArrayUtil.EMPTY_STRING_ARRAY;
final String[] paths = new String[files.length];
for (int i = 0; i < files.length; i++) {
paths[i] = getSelectionPath(files[i]);
}
return paths;
}
}
@@ -17,8 +17,8 @@ package com.intellij.openapi.fileChooser;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -26,7 +26,6 @@ import java.util.List;
public interface FileSystemTree extends Disposable {
DataKey<FileSystemTree> DATA_KEY = DataKey.create("FileSystemTree");
Key<String> PATH_KEY = Key.create("FileSystemTree.Path");
JTree getTree();
@@ -35,11 +34,13 @@ public interface FileSystemTree extends Disposable {
@Nullable
VirtualFile getSelectedFile();
@NotNull
VirtualFile[] getSelectedFiles();
@Nullable
VirtualFile getNewFileParent();
void select(VirtualFile file, @Nullable Runnable onDone);
void select(VirtualFile[] files, @Nullable Runnable onDone);
void expand(VirtualFile file, @Nullable Runnable onDone);
@@ -50,8 +51,6 @@ public interface FileSystemTree extends Disposable {
boolean selectionExists();
VirtualFile[] getSelectedFiles();
boolean areHiddensShown();
void showHiddens(boolean showHidden);
@@ -24,10 +24,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileChooser.FileElement;
import com.intellij.openapi.fileChooser.FileSystemTree;
import com.intellij.openapi.fileChooser.*;
import com.intellij.openapi.fileChooser.impl.FileChooserFactoryImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -269,8 +266,12 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
}
}
final VirtualFile[] selectedFiles = getSelectedFiles();
if (selectedFiles.length == 0) {
close(CANCEL_EXIT_CODE);
return;
}
try {
myChooserDescriptor.validateSelectedFiles(selectedFiles);
}
@@ -280,16 +281,15 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
}
myChosenFiles = selectedFiles;
if (selectedFiles.length == 0) {
close(CANCEL_EXIT_CODE);
return;
}
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourLastFile = selectedFiles[selectedFiles.length - 1];
setLastSelectedFile(selectedFiles[selectedFiles.length - 1]);
super.doOKAction();
}
private static void setLastSelectedFile(final VirtualFile selectedFile) {
ourLastFile = selectedFile;
}
public final void doCancelAction() {
myChosenFiles = VirtualFile.EMPTY_ARRAY;
super.doCancelAction();
@@ -502,13 +502,9 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
});
}
// todo[r.sh] correct path if archive is picked via symlink
private static String getFilePath(final VirtualFile file) {
final String path = file.getUserData(FileSystemTree.PATH_KEY);
if (path != null) {
return path;
}
return file.isInLocalFileSystem() ? file.getPresentableUrl() : file.getUrl();
return file.isInLocalFileSystem() ? FileChooserUtil.getSelectionPath(file) : file.getUrl();
}
private void updateTreeFromPath(final String text) {
@@ -545,6 +541,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
}
}
// todo[r.sh] fix symlink selection
private void selectInTree(final VirtualFile[] vFile, final boolean requestFocus) {
myTreeIsUpdating = true;
if (!Arrays.asList(myFileSystemTree.getSelectedFiles()).contains(vFile)) {
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.fileChooser.ex;
import com.google.common.collect.Lists;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
@@ -26,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserUtil;
import com.intellij.openapi.fileChooser.FileElement;
import com.intellij.openapi.fileChooser.FileSystemTree;
import com.intellij.openapi.fileChooser.impl.FileComparator;
@@ -46,9 +48,11 @@ import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.UIBundle;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.ConvertingIterator;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -332,12 +336,15 @@ public class FileSystemTreeImpl implements FileSystemTree {
public VirtualFile getSelectedFile() {
final TreePath path = myTree.getSelectionPath();
if (path == null) return null;
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
if (!(node.getUserObject() instanceof FileNodeDescriptor)) return null;
FileNodeDescriptor descriptor = (FileNodeDescriptor)node.getUserObject();
return descriptor.getElement().getFile();
final FileElement element = ((FileNodeDescriptor)node.getUserObject()).getElement();
final VirtualFile file = element.getFile();
FileChooserUtil.setSelectionPath(file, element.getPath());
return file;
}
@Nullable
public VirtualFile getNewFileParent() {
if (getSelectedFile() != null) return getSelectedFile();
@@ -345,35 +352,53 @@ public class FileSystemTreeImpl implements FileSystemTree {
return roots.size() > 0 ? roots.get(0) : null;
}
@NotNull
public VirtualFile[] getSelectedFiles() {
return collectSelectedFiles(new ConvertingIterator.IdConvertor<VirtualFile>());
}
public VirtualFile[] getChosenFiles() {
return collectSelectedFiles(new Convertor<VirtualFile, VirtualFile>() {
@Nullable
public VirtualFile convert(VirtualFile file) {
final List<VirtualFile> files = collectSelectedElements(new NullableFunction<FileElement, VirtualFile>() {
@Override
public VirtualFile fun(final FileElement element) {
final VirtualFile file = element.getFile();
if (file == null || !file.isValid()) return null;
return myTreeStructure.getChooserDescriptor().getFileToSelect(file);
FileChooserUtil.setSelectionPath(file, element.getPath());
return file;
}
});
return VfsUtil.toVirtualFileArray(files);
}
private VirtualFile[] collectSelectedFiles(Convertor<VirtualFile, VirtualFile> fileConverter) {
TreePath[] paths = myTree.getSelectionPaths();
if (paths == null) return VirtualFile.EMPTY_ARRAY;
ArrayList<VirtualFile> files = new ArrayList<VirtualFile>(paths.length);
for (TreePath path : paths) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
if (!(node.getUserObject() instanceof FileNodeDescriptor)) return VirtualFile.EMPTY_ARRAY;
FileNodeDescriptor descriptor = (FileNodeDescriptor)node.getUserObject();
VirtualFile file = fileConverter.convert(descriptor.getElement().getFile());
if (file != null && file.isValid()) files.add(file);
}
@NotNull
public VirtualFile[] getChosenFiles() {
final List<VirtualFile> files = collectSelectedElements(new NullableFunction<FileElement, VirtualFile>() {
@Override
public VirtualFile fun(final FileElement element) {
VirtualFile file = element.getFile();
if (file == null || !file.isValid()) return null;
file = myTreeStructure.getChooserDescriptor().getFileToSelect(file);
FileChooserUtil.setSelectionPath(file, element.getPath());
return file;
}
});
return VfsUtil.toVirtualFileArray(files);
}
private <T> List<T> collectSelectedElements(final Function<FileElement, T> converter) {
final TreePath[] paths = myTree.getSelectionPaths();
if (paths == null) return Collections.emptyList();
final List<T> elements = Lists.newArrayList();
for (TreePath path : paths) {
final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
final Object userObject = node.getUserObject();
if (userObject instanceof FileNodeDescriptor) {
final T element = converter.fun(((FileNodeDescriptor)userObject).getElement());
if (element != null) {
elements.add(element);
}
}
}
return elements;
}
public boolean selectionExists() {
TreePath[] selectedPaths = myTree.getSelectionPaths();
return selectedPaths != null && selectedPaths.length != 0;
@@ -422,7 +447,7 @@ public class FileSystemTreeImpl implements FileSystemTree {
final FileElement element = ((FileNodeDescriptor)object).getElement();
final VirtualFile file = element.getFile();
if (file != null) {
file.putUserData(PATH_KEY, element.getPath());
FileChooserUtil.setSelectionPath(file, element.getPath());
selection.add(file);
}
}
@@ -452,7 +477,8 @@ public class FileSystemTreeImpl implements FileSystemTree {
}
boolean async = myTreeBuilder.getTreeStructure().isToBuildChildrenInBackground(virtualFile);
AbstractTreeStructure treeStructure = myTreeBuilder.getTreeStructure();
boolean async = treeStructure != null && treeStructure.isToBuildChildrenInBackground(virtualFile);
if (virtualFile instanceof NewVirtualFile) {
RefreshQueue.getInstance().refresh(async, false, null, ModalityState.stateForComponent(myTree), virtualFile);
}
@@ -463,7 +489,6 @@ public class FileSystemTreeImpl implements FileSystemTree {
}
}
public void treeCollapsed(TreeExpansionEvent event) {
}
public void treeCollapsed(TreeExpansionEvent event) { }
}
}