package cn.ygc.plugin.fileexportplugin.dialog;
import cn.ygc.plugin.fileexportplugin.util.FileUtil;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CheckboxTree;
import com.intellij.ui.CheckedTreeNode;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.SimpleTextAttributes;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FileTreeDialog extends DialogWrapper {
private final Project project;
private final CheckboxTree tree;
private final DefaultTreeModel treeModel;
private final List<VirtualFile> selectedFiles = new ArrayList<>();
public FileTreeDialog(Project project, VirtualFile[] initialFiles) {
super(project);
this.project = project;
setTitle("Select Files to Export");
// 初始化树模型
CheckedTreeNode root = new CheckedTreeNode("Root");
for (VirtualFile file : initialFiles) {
buildTree(root, file);
}
treeModel = new DefaultTreeModel(root);
// 创建带复选框的树
tree = new CheckboxTree(new CheckboxTree.CheckboxTreeCellRenderer() {
@Override
public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
if (value instanceof DefaultMutableTreeNode node) {
Object userObj = node.getUserObject();
if (userObj instanceof VirtualFile file) {
Icon icon = file.getFileType().getIcon();
if (icon != null) {
getTextRenderer().setIcon(icon);
} else {
// 使用默认图标
getTextRenderer().setIcon(UIManager.getIcon("FileView.fileIcon"));
}
getTextRenderer().append(file.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
}
}, root);
// 配置树属性
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
init();
}
private void buildTree(DefaultMutableTreeNode parent, VirtualFile file) {
CheckedTreeNode node = new CheckedTreeNode(file);
parent.add(node);
if (file.isDirectory()) {
for (VirtualFile child : file.getChildren()) {
buildTree(node, child);
}
}
}
@Override
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JBScrollPane(tree), BorderLayout.CENTER);
return panel;
}
@Override
protected void doOKAction() {
// 清空之前选择的文件
selectedFiles.clear();
// 获取树的根节点并确保它是 CheckedTreeNode 类型
CheckedTreeNode rootNode = (CheckedTreeNode) treeModel.getRoot();
// 遍历树以找到选中的节点
traverseTree(rootNode);
// 选择导出目录
FileChooser.chooseFile(
FileChooserDescriptorFactory.createSingleFolderDescriptor(),
project,
null,
virtualFile -> {
if (virtualFile != null) {
exportFiles(virtualFile.toNioPath());
}
}
);
super.doOKAction();
}
private void traverseTree(CheckedTreeNode node) {
if (node.isChecked() && node.getUserObject() instanceof VirtualFile file) {
selectedFiles.add(file);
}
for (int i = 0; i < node.getChildCount(); i++) {
traverseTree((CheckedTreeNode) node.getChildAt(i));
}
}
private void exportFiles(Path exportPath) {
try {
String source = project.getBasePath().toString();
//提取到项目文件根目录
source = source.substring(0, source.lastIndexOf('/'));
String copy = "";
String targetPath = exportPath.toAbsolutePath().toString();
List<String> selectedFilesPath = new ArrayList<>();
for (VirtualFile file : selectedFiles) {
selectedFilesPath.add(file.getPath());
}
for (String path : selectedFilesPath) {
boolean isSubdirectory = false;
for (String otherPath : selectedFilesPath) {
if (!path.equals(otherPath) && path.startsWith(otherPath + "/")) {
isSubdirectory = true;
break;
}
}
if (!isSubdirectory) {
copy += path + ";";
}
}
FileUtil.fastCopyFileToTarget(source,copy,targetPath);
Messages.showInfoMessage("Export completed!", "Success");
} catch (Exception ex) {
Messages.showErrorDialog("Export failed: " + ex.getMessage(), "Error");
}
}
}