mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[platform] amending file filters in platform file choosers with extension filters, instead of replacing (IJPL-150176)
GitOrigin-RevId: bc5d9ab58303a65b186cb36dc8099975f7b6b8ba
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6547c67d6d
commit
16ad6dea8a
@@ -220,6 +220,7 @@ public class BackgroundImageDialog extends DialogWrapper {
|
||||
((CardLayout)myPreviewPanel.getLayout()).show(myPreviewPanel, EDITOR);
|
||||
myPathField.getComboBox().setEditable(true);
|
||||
var descriptor = new FileChooserDescriptor(true, false, false, false, true, false)
|
||||
.withFileFilter(file -> ImageFileTypeManager.getInstance().isImage(file))
|
||||
.withExtensionFilter(ImageFileTypeManager.getInstance().getImageFileType());
|
||||
myPathField.addBrowseFolderListener(null, descriptor, TextComponentAccessor.STRING_COMBOBOX_WHOLE_TEXT);
|
||||
JTextComponent textComponent = getComboEditor();
|
||||
|
||||
@@ -212,6 +212,7 @@ class PasswordSafeConfigurableUi(private val settings: PasswordSafeSettings) : C
|
||||
row(CredentialStoreBundle.message("settings.password.database")) {
|
||||
val fileChooserDescriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor()
|
||||
.withTitle(CredentialStoreBundle.message("passwordSafeConfigurable.keepass.database.file"))
|
||||
.withFileFilter { it.extension.equals("kdbx", ignoreCase = true) }
|
||||
.withExtensionFilter("kdbx")
|
||||
keePassDbFile = textFieldWithBrowseButton(fileChooserDescriptor, fileChosen = {
|
||||
val path = if (it.isDirectory) "${it.path}${File.separator}${DB_FILE_NAME}" else it.path
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Allows customizing {@link FileChooser} dialog options.
|
||||
@@ -46,7 +47,7 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
private boolean myTreeRootVisible = false;
|
||||
private boolean myShowHiddenFiles = false;
|
||||
private @Nullable Pair<@Nls String, List<String>> myExtensionFilter = null;
|
||||
private Condition<? super VirtualFile> myFileFilter = null;
|
||||
private Predicate<? super VirtualFile> myFileFilter = null;
|
||||
private boolean myForcedToUseIdeaFileChooser = false;
|
||||
|
||||
private final Map<String, Object> myUserData = new HashMap<>();
|
||||
@@ -87,7 +88,7 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
myTreeRootVisible = d.isTreeRootVisible();
|
||||
myShowHiddenFiles = d.isShowHiddenFiles();
|
||||
myExtensionFilter = d.myExtensionFilter;
|
||||
myFileFilter = null;
|
||||
myFileFilter = d.myFileFilter;
|
||||
myForcedToUseIdeaFileChooser = false;
|
||||
myUserData.putAll(d.myUserData);
|
||||
}
|
||||
@@ -209,11 +210,13 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @deprecated incompatible with native file choosers; please use {@link #withExtensionFilter} instead */
|
||||
@Deprecated
|
||||
/**
|
||||
* Sets simple boolean condition for use in {@link #isFileVisible(VirtualFile, boolean)} and {@link #isFileSelectable(VirtualFile)}.
|
||||
* <p/>
|
||||
* In native choosers, has no effect on visibility (use {@link #withExtensionFilter} for that), only on a final eligibility check.
|
||||
*/
|
||||
public FileChooserDescriptor withFileFilter(@Nullable Condition<? super VirtualFile> filter) {
|
||||
myFileFilter = filter;
|
||||
putUserData(FILTER_TYPE, filter != null ? "other" : null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -245,14 +248,13 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
if (extensions.length == 0) throw new IllegalArgumentException("The list must not be empty");
|
||||
if (ContainerUtil.find(extensions, String::isBlank) != null) throw new IllegalArgumentException("The list must not contain empty strings");
|
||||
myExtensionFilter = new Pair<>(label, List.of(extensions));
|
||||
putUserData(FILTER_TYPE, "file-ext");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether a file is visible in the tree.
|
||||
*
|
||||
* @deprecated ignored by native file choosers; do not use.
|
||||
* @deprecated ignored by native file choosers; use {@link #withFileFilter} and {@link #withExtensionFilter} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
|
||||
@@ -272,7 +274,7 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
if (myExtensionFilter != null && !matchesExtFilter(file, myExtensionFilter.second)) {
|
||||
return false;
|
||||
}
|
||||
if (myFileFilter != null && !myFileFilter.value(file)) {
|
||||
if (myFileFilter != null && !myFileFilter.test(file)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -306,7 +308,7 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
return matchesExtFilter(file, myExtensionFilter.second);
|
||||
}
|
||||
if (myFileFilter != null) {
|
||||
return myFileFilter.value(file);
|
||||
return myFileFilter.test(file);
|
||||
}
|
||||
}
|
||||
return acceptAsJarFile(file) || acceptAsGeneralFile(file);
|
||||
@@ -395,8 +397,17 @@ public class FileChooserDescriptor implements Cloneable {
|
||||
}
|
||||
|
||||
public @Nullable <T> T getUserData(@NotNull DataKey<T> key) {
|
||||
@SuppressWarnings("unchecked") T t = (T)myUserData.get(key.getName());
|
||||
return t;
|
||||
if (key == FILTER_TYPE) {
|
||||
var result = "";
|
||||
if (myExtensionFilter != null) result += 'e';
|
||||
if (myFileFilter != null) result += 'f';
|
||||
@SuppressWarnings("unchecked") T t = (T)result;
|
||||
return t;
|
||||
}
|
||||
else {
|
||||
@SuppressWarnings("unchecked") T t = (T)myUserData.get(key.getName());
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean matchesExtFilter(VirtualFile file, List<String> extensions) {
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
package com.intellij.openapi.fileChooser;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.Strings;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -47,15 +49,21 @@ public final class FileChooserDescriptorFactory {
|
||||
}
|
||||
|
||||
public static FileChooserDescriptor createSingleFileDescriptor(@NotNull FileType fileType) {
|
||||
return createSingleFileNoJarsDescriptor().withExtensionFilter(fileType);
|
||||
return createSingleFileNoJarsDescriptor()
|
||||
.withFileFilter(file -> FileTypeRegistry.getInstance().isFileOfType(file, fileType))
|
||||
.withExtensionFilter(fileType);
|
||||
}
|
||||
|
||||
public static FileChooserDescriptor createSingleFileOrFolderDescriptor(@NotNull FileType fileType) {
|
||||
return createSingleFileOrFolderDescriptor().withExtensionFilter(fileType);
|
||||
return createSingleFileOrFolderDescriptor()
|
||||
.withFileFilter(file -> file.isDirectory() || FileTypeRegistry.getInstance().isFileOfType(file, fileType))
|
||||
.withExtensionFilter(fileType);
|
||||
}
|
||||
|
||||
public static FileChooserDescriptor createSingleFileDescriptor(@NotNull String extension) {
|
||||
return createSingleFileNoJarsDescriptor().withExtensionFilter(extension);
|
||||
return createSingleFileNoJarsDescriptor()
|
||||
.withFileFilter(file -> Strings.endsWithIgnoreCase(file.getName(), '.' + extension))
|
||||
.withExtensionFilter(extension);
|
||||
}
|
||||
|
||||
public static FileChooserDescriptor createSingleFolderDescriptor() {
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -63,8 +64,8 @@ public final class ViewOfflineResultsAction extends AnAction {
|
||||
|
||||
LOG.assertTrue(project != null);
|
||||
|
||||
var descriptor = FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor()
|
||||
.withExtensionFilter("xml")
|
||||
var xmlFileType = FileTypeManager.getInstance().getStdFileType("XML");
|
||||
var descriptor = FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor(xmlFileType)
|
||||
.withTitle(InspectionsBundle.message("view.offline.inspections.select.path.title"))
|
||||
.withDescription(InspectionsBundle.message("view.offline.inspections.select.path.description"));
|
||||
final VirtualFile virtualFile = FileChooser.chooseFile(descriptor, project, null);
|
||||
|
||||
@@ -54,20 +54,16 @@ public final class PlaybackDebugger implements UiDebuggerExtension, PlaybackRunn
|
||||
private static final Color CODE_COLOR = PlatformColors.BLUE;
|
||||
private static final Color TEST_COLOR = JBColor.GREEN.darker();
|
||||
|
||||
private static final FileChooserDescriptor FILE_DESCRIPTOR = new ScriptFileChooserDescriptor();
|
||||
|
||||
private JPanel myComponent;
|
||||
|
||||
private PlaybackRunner runner;
|
||||
|
||||
private JEditorPane myLog;
|
||||
|
||||
private final JTextField myCurrentScript = new JTextField();
|
||||
|
||||
private VirtualFileListener myVfsListener;
|
||||
|
||||
private boolean myChanged;
|
||||
|
||||
private PlaybackDebuggerState myState;
|
||||
private static final FileChooserDescriptor FILE_DESCRIPTOR = new ScriptFileChooserDescriptor();
|
||||
private JTextArea myCodeEditor;
|
||||
|
||||
private void initUi() {
|
||||
@@ -155,6 +151,7 @@ public final class PlaybackDebugger implements UiDebuggerExtension, PlaybackRunn
|
||||
super(true, false, false, false, false, false);
|
||||
putUserData(FileChooserKeys.NEW_FILE_TYPE, UiScriptFileType.getInstance());
|
||||
putUserData(FileChooserKeys.NEW_FILE_TEMPLATE_TEXT, "");
|
||||
withFileFilter(file -> UiScriptFileType.myExtension.equalsIgnoreCase(file.getExtension()));
|
||||
withExtensionFilter(UiScriptFileType.myExtension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ internal class BrowseIconsComboBox(private val customActionsSchema: CustomAction
|
||||
|
||||
private fun browseIconAndSelect() {
|
||||
val descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
|
||||
.withFileFilter { "svg".equals(it.extension, ignoreCase = true) || "png".equals(it.extension, ignoreCase = true) }
|
||||
.withExtensionFilter(IdeBundle.message("icon.file.filter.label"), "svg", "png")
|
||||
descriptor.title = IdeBundle.message("title.browse.icon")
|
||||
descriptor.description = IdeBundle.message("prompt.browse.icon.for.selected.action")
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.diagnostic.VMOptions;
|
||||
import com.intellij.ide.BootstrapBundle;
|
||||
import com.intellij.ide.GeneralSettings;
|
||||
import com.intellij.ide.actions.ImportSettingsFilenameFilter;
|
||||
import com.intellij.ide.highlighter.ArchiveFileType;
|
||||
import com.intellij.ide.plugins.*;
|
||||
import com.intellij.ide.plugins.marketplace.MarketplacePluginDownloadService;
|
||||
import com.intellij.ide.startup.StartupActionScriptManager;
|
||||
@@ -19,6 +20,7 @@ import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.keymap.impl.KeymapManagerImpl;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
@@ -479,7 +481,9 @@ public final class ConfigImportHelper {
|
||||
}
|
||||
|
||||
public static void setSettingsFilter(@NotNull FileChooserDescriptor descriptor) {
|
||||
descriptor.withExtensionFilter(BootstrapBundle.message("import.settings.filter"), "zip", "jar");
|
||||
descriptor
|
||||
.withFileFilter(file -> FileTypeRegistry.getInstance().isFileOfType(file, ArchiveFileType.INSTANCE))
|
||||
.withExtensionFilter(BootstrapBundle.message("import.settings.filter"), "zip", "jar");
|
||||
}
|
||||
|
||||
public static void setConfigImportedInThisSession() {
|
||||
|
||||
@@ -13,39 +13,39 @@ import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static java.util.Objects.requireNonNullElse;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class FileChooserUsageCollector extends CounterUsagesCollector {
|
||||
private static final EventLogGroup GROUP = new EventLogGroup("ui.file.chooser", 3);
|
||||
private static final EventLogGroup GROUP = new EventLogGroup("ui.file.chooser", 4);
|
||||
|
||||
private static final EnumEventField<Type> TYPE = EventFields.Enum("type", Type.class);
|
||||
private static final BooleanEventField FORCED = EventFields.Boolean("forced");
|
||||
private static final BooleanEventField JAR_CONTENTS = EventFields.Boolean("jar_contents");
|
||||
private static final BooleanEventField NON_LOCAL_ROOTS = EventFields.Boolean("non_local_roots");
|
||||
private static final EnumEventField<Filter> FILTER = EventFields.Enum("filter", Filter.class);
|
||||
private static final BooleanEventField EXT_FILTER = EventFields.Boolean("ext_filter");
|
||||
private static final BooleanEventField FILE_FILTER = EventFields.Boolean("file_filter");
|
||||
private static final BooleanEventField NON_LOCAL_FILES = EventFields.Boolean("non_local_files");
|
||||
private static final VarargEventId CHOOSER_SHOWN = GROUP.registerVarargEvent(
|
||||
"chooser_shown", TYPE, FORCED, JAR_CONTENTS, NON_LOCAL_ROOTS, FILTER, NON_LOCAL_FILES);
|
||||
"chooser_shown", TYPE, FORCED, JAR_CONTENTS, NON_LOCAL_ROOTS, EXT_FILTER, FILE_FILTER, NON_LOCAL_FILES);
|
||||
|
||||
private enum Type {NATIVE, CLASSIC, NEW, OTHER}
|
||||
|
||||
private static Filter filterType(@Nullable String filterType) {
|
||||
return filterType == null ? Filter.NONE : filterType.equals("file-ext") ? Filter.EXT : Filter.OTHER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventLogGroup getGroup() {
|
||||
return GROUP;
|
||||
}
|
||||
|
||||
public static void log(FileChooserDialog chooser, FileChooserDescriptor descriptor, VirtualFile[] files) {
|
||||
var filter = requireNonNullElse(descriptor.getUserData(FileChooserDescriptor.FILTER_TYPE), "");
|
||||
CHOOSER_SHOWN.log(
|
||||
TYPE.with(chooserType(chooser)),
|
||||
FORCED.with(descriptor.isForcedToUseIdeaFileChooser()),
|
||||
JAR_CONTENTS.with(descriptor.isChooseJarContents()),
|
||||
NON_LOCAL_ROOTS.with(ContainerUtil.exists(descriptor.getRoots(), root -> !root.isInLocalFileSystem())),
|
||||
FILTER.with(filterType(descriptor.getUserData(FileChooserDescriptor.FILTER_TYPE))),
|
||||
EXT_FILTER.with(filter.indexOf('e') != 0),
|
||||
FILE_FILTER.with(filter.indexOf('f') != 0),
|
||||
NON_LOCAL_FILES.with(ContainerUtil.exists(files, file -> !file.isInLocalFileSystem()))
|
||||
);
|
||||
}
|
||||
@@ -56,6 +56,4 @@ public class FileChooserUsageCollector extends CounterUsagesCollector {
|
||||
chooser instanceof FileChooserDialogImpl ? Type.CLASSIC :
|
||||
Type.OTHER;
|
||||
}
|
||||
|
||||
private enum Filter {NONE, EXT, OTHER}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public final class SchemeImportUtil {
|
||||
if (sourceExtensions.length == 1) {
|
||||
descriptor.withExtensionFilter(sourceExtensions[0]);
|
||||
}
|
||||
else {
|
||||
else if (sourceExtensions.length > 1) {
|
||||
descriptor.withExtensionFilter(IdeCoreBundle.message("file.chooser.files.label", sourceExtensions[0].toUpperCase(Locale.ROOT)), sourceExtensions);
|
||||
}
|
||||
if (description != null) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.fileChooser.FileChooser
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry
|
||||
import com.intellij.openapi.ide.CopyPasteManager
|
||||
import com.intellij.openapi.progress.runBackgroundableTask
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
@@ -75,8 +76,10 @@ internal open class DumpInvalidTipsAction : AnAction() {
|
||||
internal class SelectAndDumpInvalidTipsAction : DumpInvalidTipsAction() {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = e.getData(CommonDataKeys.PROJECT)
|
||||
val htmlFileType = FileTypeManager.getInstance().getStdFileType("HTML")
|
||||
val descriptor = FileChooserDescriptor(true, true, false, false, false, true)
|
||||
.withExtensionFilter(FileTypeManager.getInstance().getStdFileType("HTML"))
|
||||
.withFileFilter { FileTypeRegistry.getInstance().isFileOfType(it, htmlFileType) }
|
||||
.withExtensionFilter(htmlFileType)
|
||||
.withDescription("Choose HTML files or folders with tips.")
|
||||
val chosenFiles = FileChooser.chooseFiles(descriptor, project, null)
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ package com.intellij.ide.util;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.TipsOfTheDayUsagesCollector;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.fileChooser.FileChooserFactory;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
@@ -137,8 +137,10 @@ final class TipDialog extends DialogWrapper {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
PropertiesComponent propertiesComponent = PropertiesComponent.getInstance();
|
||||
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createMultipleFilesNoJarsDescriptor()
|
||||
.withExtensionFilter(FileTypeManager.getInstance().getStdFileType("HTML"));
|
||||
var htmlFileType = FileTypeManager.getInstance().getStdFileType("HTML");
|
||||
var descriptor = FileChooserDescriptorFactory.createMultipleFilesNoJarsDescriptor()
|
||||
.withFileFilter(file -> FileTypeRegistry.getInstance().isFileOfType(file, htmlFileType))
|
||||
.withExtensionFilter(htmlFileType);
|
||||
String value = propertiesComponent.getValue(LAST_OPENED_TIP_PATH);
|
||||
VirtualFile lastOpenedTip = value != null ? LocalFileSystem.getInstance().findFileByPath(value) : null;
|
||||
VirtualFile[] pathToSelect = lastOpenedTip != null ? new VirtualFile[]{lastOpenedTip} : VirtualFile.EMPTY_ARRAY;
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.intellij.openapi.fileChooser.FileChooserFactory;
|
||||
import com.intellij.openapi.fileChooser.FileSaverDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
@@ -704,8 +705,10 @@ public final class InjectionsSettingsUI extends SearchableConfigurable.Parent.Ab
|
||||
}
|
||||
|
||||
private void doImportAction(final DataContext dataContext) {
|
||||
var xmlFileType = FileTypeManager.getInstance().getStdFileType("XML");
|
||||
var descriptor = new FileChooserDescriptor(true, false, false, false, true, false)
|
||||
.withExtensionFilter(FileTypeManager.getInstance().getStdFileType("XML"))
|
||||
.withFileFilter(file -> FileTypeRegistry.getInstance().isFileOfType(file, xmlFileType))
|
||||
.withExtensionFilter(xmlFileType)
|
||||
.withTitle(IntelliLangBundle.message("dialog.file.chooser.title.import.configuration"))
|
||||
.withDescription(IntelliLangBundle.message("dialog.file.chooser.description.please.select.the.configuration.file"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user