Skip to content

Commit

Permalink
Ref #926: Allow to select only camel-jbang supported files (#928)
Browse files Browse the repository at this point in the history
## 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
  • Loading branch information
essobedo authored Oct 7, 2023
1 parent f7aaa74 commit 0cd74fc
Showing 1 changed file with 65 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,65 +19,99 @@
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;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;

public class CamelJBangRunnerConfPanel implements PanelWithAnchor {
private static final Set<String> SUPPORTED_EXTENSIONS = Set.of("java", "groovy", "kts", "js", "jsh", "xml", "yaml");
protected JPanel panel;
protected LabeledComponent<TextFieldWithBrowseButton> filesComponent;
protected LabeledComponent<EditorTextField> commandOptionsComponent;
protected LabeledComponent<EditorTextField> dependenciesComponent;
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<JTextField> 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<VirtualFile> 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<VirtualFile> 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
Expand Down

0 comments on commit 0cd74fc

Please sign in to comment.