[ui] NIO-based file chooser: preserving selection on reloads; focusing created files

GitOrigin-RevId: 2313d93dcea1449c35b70cef9bc1cdbe1dc0f3bb
This commit is contained in:
Roman Shevchenko
2022-02-11 09:27:52 +00:00
committed by intellij-monorepo-bot
parent a74af24011
commit 1ca29cf435
7 changed files with 30 additions and 23 deletions
@@ -23,7 +23,8 @@ public interface FileChooserPanel {
@NotNull JComponent getComponent();
void load(@Nullable Path path);
void reload();
void reload(@Nullable Path focusOn);
boolean showPathBar();
void showPathBar(boolean show);
@@ -57,7 +57,7 @@ public class FileDeleteAction extends FileChooserAction {
return null;
}
});
panel.reload();
panel.reload(null);
}
catch (IOException ex) {
Messages.showErrorDialog(panel.getComponent(), IoErrorText.message(ex), CommonBundle.getErrorTitle());
@@ -55,14 +55,14 @@ public class NewFileAction extends FileChooserAction implements LightEditCompati
while (true) {
var input = MessagesService.getInstance().showInputDialog(null, panel.getComponent(), prompt, title, null, initial, validator, selection, null);
if (input == null) return;
if (input == null) break;
var name = input.trim();
initial = name;
selection = null;
var progress = UIBundle.message("file.chooser.creating.progress", name);
try {
ProgressManager.getInstance().run(new Task.WithResult<Path, IOException>(e.getProject(), panel.getComponent(), progress, true) {
var newFile = ProgressManager.getInstance().run(new Task.WithResult<Path, IOException>(e.getProject(), panel.getComponent(), progress, true) {
@Override
protected Path compute(@NotNull ProgressIndicator indicator) throws IOException {
indicator.setIndeterminate(true);
@@ -73,7 +73,7 @@ public class NewFileAction extends FileChooserAction implements LightEditCompati
return newFile;
}
});
panel.reload();
panel.reload(newFile);
break;
}
catch (IOException | InvalidPathException ex) {
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.fileChooser.actions;
import com.intellij.CommonBundle;
@@ -68,7 +68,7 @@ public class NewFolderAction extends FileChooserAction implements LightEditCompa
try {
var progress = UIBundle.message("file.chooser.creating.progress", name);
ProgressManager.getInstance().run(new Task.WithResult<Path, IOException>(e.getProject(), panel.getComponent(), progress, true) {
var newDir = ProgressManager.getInstance().run(new Task.WithResult<Path, IOException>(e.getProject(), panel.getComponent(), progress, true) {
@Override
protected Path compute(@NotNull ProgressIndicator indicator) throws IOException {
indicator.setIndeterminate(true);
@@ -78,7 +78,7 @@ public class NewFolderAction extends FileChooserAction implements LightEditCompa
return newDirectory;
}
});
panel.reload();
panel.reload(newDir);
break;
}
catch (IOException | InvalidPathException ex) {
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.fileChooser.actions;
import com.intellij.ide.lightEdit.LightEditCompatible;
@@ -16,7 +16,7 @@ public class RefreshFileChooserAction extends FileChooserAction implements Light
@Override
protected void actionPerformed(@NotNull FileChooserPanel panel, @NotNull AnActionEvent e) {
panel.reload();
panel.reload(null);
}
@Override
@@ -174,7 +174,7 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
UIUtil.invokeLaterIfNeeded(() -> {
synchronized (myLock) {
if (key == myWatchKey && myCurrentDirectory != null) {
doLoad(myCurrentDirectory);
reload(null);
}
}
});
@@ -197,10 +197,10 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
private void openItemAtIndex(int idx, InputEvent e) {
FsItem item = myModel.get(idx);
if (item.directory) {
doLoad(item.path, item.name == FsItem.UPLINK ? UPPER_LEVEL : 0);
load(item.path, null, item.name == FsItem.UPLINK ? UPPER_LEVEL : 0);
}
else if (myDescriptor.isChooseJarContents() && myRegistry.getFileTypeByFileName(item.name) == ArchiveFileType.INSTANCE) {
doLoad(item.path, INTO_ARCHIVE);
load(item.path, null, INTO_ARCHIVE);
}
else {
myCallback.run();
@@ -246,7 +246,7 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
@Override
public void load(@Nullable Path path) {
if (path == null || path.isAbsolute()) {
doLoad(path);
load(path, null, 0);
}
else {
throw new IllegalArgumentException("Not absolute: " + path);
@@ -254,9 +254,15 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
}
@Override
public void reload() {
public void reload(@Nullable Path focusOn) {
if (focusOn == null) {
FsItem value = myList.getSelectedValue();
if (value != null) {
focusOn = value.path;
}
}
synchronized (myLock) {
doLoad(myCurrentDirectory);
load(myCurrentDirectory, focusOn, 0);
}
}
@@ -283,11 +289,13 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
myShowHiddenFiles = show;
synchronized (myLock) {
if (myCurrentDirectory != null) {
var selection = myList.getSelectedValue();
myModel.clear();
for (int i = 1; i < myCurrentContent.size(); i++) { // excluding `.`
FsItem item = myCurrentContent.get(i);
if (show || item.visible) myModel.add(item);
}
myList.setSelectedValue(selection, true);
}
}
}
@@ -330,14 +338,10 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
});
}
private void doLoad(@Nullable Path path) {
doLoad(path, 0);
}
private static final int UPPER_LEVEL = 1;
private static final int INTO_ARCHIVE = 2;
private void doLoad(@Nullable Path path, int direction) {
private void load(@Nullable Path path, @Nullable Path focusOn, int direction) {
synchronized (myLock) {
myPath.setItem(path != null ? new PathWrapper(path) : null);
myModel.clear();
@@ -354,7 +358,9 @@ final class FileChooserPanelImpl extends JBPanel<FileChooserPanelImpl> implement
myCurrentTask = pair(id, ProcessIOExecutorService.INSTANCE.submit(() -> {
var directory = directoryToLoad(path, direction == INTO_ARCHIVE);
if (directory != null) {
var pathToSelect = childDir != null && childDir.getParent() == null && isJar(childDir.toUri()) ? parent(childDir) : childDir;
var pathToSelect = focusOn != null ? focusOn :
childDir != null && childDir.getParent() == null && isJar(childDir.toUri()) ? parent(childDir) :
childDir;
loadDirectory(directory, pathToSelect, id);
}
else {
@@ -134,7 +134,7 @@ final class NewFileChooserDialogImpl extends DialogWrapper implements FileChoose
var urls = misses.stream().map(s -> "&nbsp;&nbsp;&nbsp;" + s).collect(Collectors.joining("<br>"));
var message = UIBundle.message("file.chooser.vfs.lookup", urls);
Messages.showErrorDialog(myPanel, message, getTitle());
myPanel.reload();
myPanel.reload(null);
return;
}