From 0cd74fcec70a5136e4ec8eaa0b4bd5f4f27c44b3 Mon Sep 17 00:00:00 2001 From: Nicolas Filotto Date: Sat, 7 Oct 2023 11:02:35 +0200 Subject: [PATCH] Ref #926: Allow to select only camel-jbang supported files (#928) ## Motivation The file selector of the Camel JBang Application Run Configuration doesn't filter out idea files, it should be improved to avoid selecting random files and to ease the selection of a file when there is only one file in the project ## Modifications: * Only allow to select files with allowed extensions * Auto-select the first allowed file * Replace the old file chooser to support multi-selection --- .../runner/ui/CamelJBangRunnerConfPanel.java | 96 +++++++++++++------ 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/ui/CamelJBangRunnerConfPanel.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/ui/CamelJBangRunnerConfPanel.java index 72b5c12c..259a9cae 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/ui/CamelJBangRunnerConfPanel.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/ui/CamelJBangRunnerConfPanel.java @@ -19,20 +19,19 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Set; import javax.swing.JComponent; import javax.swing.JPanel; -import javax.swing.JTextField; import com.github.cameltooling.idea.runner.CamelJBangRunConfiguration; import com.github.cameltooling.idea.runner.CamelJBangRunConfigurationOptions; +import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.ComponentWithBrowseButton; import com.intellij.openapi.ui.LabeledComponent; -import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; -import com.intellij.openapi.util.NlsSafe; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorTextField; import com.intellij.ui.PanelWithAnchor; @@ -40,6 +39,7 @@ import org.jetbrains.annotations.NotNull; public class CamelJBangRunnerConfPanel implements PanelWithAnchor { + private static final Set SUPPORTED_EXTENSIONS = Set.of("java", "groovy", "kts", "js", "jsh", "xml", "yaml"); protected JPanel panel; protected LabeledComponent filesComponent; protected LabeledComponent commandOptionsComponent; @@ -47,37 +47,71 @@ public class CamelJBangRunnerConfPanel implements PanelWithAnchor { protected JComponent anchor; public CamelJBangRunnerConfPanel(@NotNull Project project) { + filesComponent.getComponent().addActionListener(e -> openFilesChooser(project)); + this.anchor = UIUtil.mergeComponentsWithAnchor(filesComponent, commandOptionsComponent, dependenciesComponent); + } + + private void openFilesChooser(@NotNull Project project) { VirtualFile root = project.getBaseDir(); - TextComponentAccessor textComponentAccessor = new TextComponentAccessor<>() { - @Override - public @NlsSafe String getText(JTextField component) { - return component.getText(); + FileChooserDescriptor desc = createFileChooserDescriptor(root); + FileChooser.chooseFiles( + desc, project, getInitialFileToSelect(root, desc), + files -> updateFilesComponentContent(root, files) + ); + } + + @NotNull + private static VirtualFile getInitialFileToSelect(VirtualFile root, FileChooserDescriptor desc) { + for (VirtualFile file : root.getChildren()) { + if (desc.isFileSelectable(file)) { + return file; } + } + return root; + } + + private static FileChooserDescriptor createFileChooserDescriptor(VirtualFile root) { + FileChooserDescriptor desc = new FileChooserDescriptor(true, false, false, false, false, true) + .withDescription("The list of Camel JBang files to Run/Debug.") + .withTitle("Select Files to Run/Debug") + .withShowFileSystemRoots(false) + .withShowHiddenFiles(false) + .withHideIgnored(true) + .withRoots(root) + .withTreeRootVisible(false) + .withFileFilter(file -> SUPPORTED_EXTENSIONS.contains(FileUtilRt.getExtension(file.getName()))); + desc.setForcedToUseIdeaFileChooser(true); + return desc; + } - @Override - public void setText(JTextField component, @NlsSafe @NotNull String text) { - if (root != null && root.getCanonicalPath() != null && text.startsWith(root.getCanonicalPath())) { - text = text.substring(root.getCanonicalPath().length() + 1); - } - if (component.getText() == null || component.getText().isBlank()) { - component.setText(text); - } else { - component.setText(String.format("%s %s", component.getText(), text)); - } + private void updateFilesComponentContent(VirtualFile root, List files) { + String contentToAppend = extractContentToAppend(root, files); + if (contentToAppend.isEmpty()) { + return; + } + TextFieldWithBrowseButton component = filesComponent.getComponent(); + String existingContent = component.getText(); + if (existingContent.isBlank()) { + component.setText(contentToAppend); + } else { + component.setText(String.format("%s %s", existingContent, contentToAppend)); + } + } + + @NotNull + private static String extractContentToAppend(VirtualFile root, List files) { + StringBuilder contentToAppend = new StringBuilder(); + for (VirtualFile file : files) { + String path = file.getPath(); + if (root != null && root.getCanonicalPath() != null && path.startsWith(root.getCanonicalPath())) { + path = path.substring(root.getCanonicalPath().length() + 1); } - }; - filesComponent.getComponent().addActionListener( - new ComponentWithBrowseButton.BrowseFolderActionListener<>( - "Select Files to Run/Debug", "The list of Camel JBang files to run/debug", filesComponent.getComponent(), - project, new FileChooserDescriptor(true, false, false, false, false, true), textComponentAccessor) { - protected VirtualFile getInitialFile() { - if (root == null) { - return super.getInitialFile(); - } - return root; - } - }); - this.anchor = UIUtil.mergeComponentsWithAnchor(filesComponent, commandOptionsComponent, dependenciesComponent); + if (!contentToAppend.isEmpty()) { + contentToAppend.append(' '); + } + contentToAppend.append(path); + } + return contentToAppend.toString(); } @Override