diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index b0f06fd..e7bb4c2 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -74,6 +74,11 @@ + + + + + diff --git a/src/com/dd/DirectoryNode.java b/src/com/dd/DirectoryNode.java index 65b1175..ba71a41 100644 --- a/src/com/dd/DirectoryNode.java +++ b/src/com/dd/DirectoryNode.java @@ -4,9 +4,12 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.ProjectViewNode; import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PsiFileNode; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -34,12 +37,36 @@ public boolean contains(@NotNull VirtualFile file) { return false; } + public void addChildren(AbstractTreeNode treeNode) { + mChildNodeList.add(treeNode); + } + + public void addAllChildren(List treeNodeList) { + mChildNodeList.addAll(treeNodeList); + } + @NotNull @Override public List getChildren() { - return mChildNodeList; + if (PropertiesComponent.getInstance().getBoolean(SettingConfigurable.PREFIX_HIDE, false)) { + final ArrayList abstractTreeNodes = new ArrayList<>(); + for (AbstractTreeNode fileNode : mChildNodeList) { + PsiFile psiFile = (PsiFile) fileNode.getValue(); + final ViewSettings settings = ((PsiFileNode) fileNode).getSettings(); + String shortName = psiFile.getName().substring(mName.length()); + final int beginIndex = shortName.indexOf(ProjectStructureProvider.COMPOSE_BY_CHAR); + if (beginIndex != -1) { + shortName = shortName.substring(beginIndex + 1); + } + abstractTreeNodes.add(new FoldingNode(fileNode.getProject(), psiFile, settings, shortName)); + } + return abstractTreeNodes; + } else { + return mChildNodeList; + } } + @Override protected void update(PresentationData presentation) { presentation.setPresentableText(mName); diff --git a/src/com/dd/FoldingNode.java b/src/com/dd/FoldingNode.java new file mode 100644 index 0000000..f72c52c --- /dev/null +++ b/src/com/dd/FoldingNode.java @@ -0,0 +1,23 @@ +package com.dd; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.nodes.PsiFileNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +class FoldingNode extends PsiFileNode { + private String mName; + + public FoldingNode(Project project, PsiFile value, ViewSettings viewSettings, String shortName) { + super(project, value, viewSettings); + mName = shortName; + } + + @Override + protected void updateImpl(PresentationData presentationData) { + super.updateImpl(presentationData); + + presentationData.setPresentableText(mName); + } +} diff --git a/src/com/dd/ProjectStructureProvider.java b/src/com/dd/ProjectStructureProvider.java index 0c6319d..7a3ce39 100644 --- a/src/com/dd/ProjectStructureProvider.java +++ b/src/com/dd/ProjectStructureProvider.java @@ -1,6 +1,7 @@ package com.dd; import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDirectory; @@ -12,10 +13,12 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ProjectStructureProvider implements com.intellij.ide.projectView.TreeStructureProvider { - private static final char COMPOSE_BY_CHAR = '_'; + public static final char COMPOSE_BY_CHAR = '_'; private static final String OTHER_NODE = "other"; @Nullable @@ -27,7 +30,7 @@ public Object getData(Collection collection, String s) { @NotNull @Override public Collection modify(@NotNull AbstractTreeNode parent, @NotNull Collection children, ViewSettings viewSettings) { - List resultList = new ArrayList(); + List resultList = new ArrayList<>(); if (parent.getValue() instanceof PsiDirectory) { PsiDirectory directory = (PsiDirectory) parent.getValue(); String path = directory.getVirtualFile().getPath(); @@ -45,22 +48,36 @@ public Collection modify(@NotNull AbstractTreeNode parent, @No @NotNull private List createComposedFiles(@NotNull Collection fileNodes, ViewSettings viewSettings) { - List resultList = new ArrayList(); + List resultList = new ArrayList<>(); Project project = Utils.getCurrentProject(); if (project != null) { - HashSet composedDirNameSet = new HashSet(); - List notComposedFileNodes = new ArrayList(); + HashSet composedDirNameSet = new HashSet<>(); + List notComposedFileNodes = new ArrayList<>(); + + final boolean customPrefix = PropertiesComponent.getInstance().getBoolean(SettingConfigurable.PREFIX_CUSTOM_USE, false); + + Pattern pattern = customPrefix ? Pattern.compile(PropertiesComponent.getInstance().getValue(SettingConfigurable.PREFIX_PATTERN, SettingConfigurable.DEFAULT_PATTERN)) : null; for (AbstractTreeNode fileNode : fileNodes) { if (fileNode.getValue() instanceof PsiFile) { PsiFile psiFile = (PsiFile) fileNode.getValue(); String fileName = psiFile.getName(); - int endIndex = fileName.indexOf(COMPOSE_BY_CHAR); - if (endIndex != -1) { - String composedDirName = fileName.substring(0, endIndex); - composedDirNameSet.add(composedDirName); + if (customPrefix) { + Matcher m = pattern.matcher(fileName); + if (m.find()) { + String composedDirName = m.group(0); + composedDirNameSet.add(composedDirName); + } else { + notComposedFileNodes.add(fileNode); + } } else { - notComposedFileNodes.add(fileNode); + int endIndex = fileName.indexOf(COMPOSE_BY_CHAR); + if (endIndex != -1) { + String composedDirName = fileName.substring(0, endIndex); + composedDirNameSet.add(composedDirName); + } else { + notComposedFileNodes.add(fileNode); + } } } } @@ -68,13 +85,13 @@ private List createComposedFiles(@NotNull Collection composedFileNodes = filterByDirName(fileNodes, composedDirName); - composedDirNode.getChildren().addAll(composedFileNodes); + composedDirNode.addAllChildren(composedFileNodes); resultList.add(composedDirNode); } - if(!notComposedFileNodes.isEmpty()) { + if (!notComposedFileNodes.isEmpty()) { DirectoryNode composedDirNode = new DirectoryNode(project, viewSettings, OTHER_NODE); - composedDirNode.getChildren().addAll(notComposedFileNodes); + composedDirNode.addAllChildren(notComposedFileNodes); resultList.add(composedDirNode); } } @@ -83,16 +100,34 @@ private List createComposedFiles(@NotNull Collection filterByDirName(Collection fileNodes, String token) { - List resultList = new ArrayList(); + List resultList = new ArrayList<>(); + + final boolean customPrefix = PropertiesComponent.getInstance().getBoolean(SettingConfigurable.PREFIX_CUSTOM_USE, false); + + Pattern pattern = customPrefix ? Pattern.compile(PropertiesComponent.getInstance().getValue(SettingConfigurable.PREFIX_PATTERN, SettingConfigurable.DEFAULT_PATTERN)) : null; + for (AbstractTreeNode fileNode : fileNodes) { if (fileNode.getValue() instanceof PsiFile) { PsiFile psiFile = (PsiFile) fileNode.getValue(); String fileName = psiFile.getName(); - int endIndex = fileName.indexOf(COMPOSE_BY_CHAR); - if (endIndex != -1) { - String composedDirName = fileName.substring(0, endIndex); - if(composedDirName.equals(token)) { - resultList.add(fileNode); + + if (customPrefix) { + Matcher m = pattern.matcher(fileName); + if (m.find()) { + + String composedDirName = m.group(0); + if (composedDirName.equals(token)) { + resultList.add(fileNode); + } + } + } else { + + int endIndex = fileName.indexOf(COMPOSE_BY_CHAR); + if (endIndex != -1) { + String composedDirName = fileName.substring(0, endIndex); + if (composedDirName.equals(token)) { + resultList.add(fileNode); + } } } } diff --git a/src/com/dd/SettingConfigurable.form b/src/com/dd/SettingConfigurable.form new file mode 100644 index 0000000..acf9585 --- /dev/null +++ b/src/com/dd/SettingConfigurable.form @@ -0,0 +1,48 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/dd/SettingConfigurable.java b/src/com/dd/SettingConfigurable.java new file mode 100644 index 0000000..ea300d2 --- /dev/null +++ b/src/com/dd/SettingConfigurable.java @@ -0,0 +1,118 @@ +package com.dd; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Created by skyrylyuk on 10/15/15. + */ +public class SettingConfigurable implements Configurable { + public static final String PREFIX_PATTERN = "folding_plugin_prefix_pattern"; + public static final String PREFIX_CUSTOM_USE = "folding_plugin_prefix_custom_use"; + public static final String PREFIX_HIDE = "folding_plugin_prefix_hide"; + + public static final String DEFAULT_PATTERN = "[^_]{1,}(?=_)"; + public static final String DEFAULT_PATTERN_DOUBLE = "[^_]{1,}_[^_]{1,}(?=_)"; + + private JPanel mPanel; + private JCheckBox useCustomPatternCheckBox; + private JTextField customPattern; + private JCheckBox hideFoldingPrefix; + private boolean isModified = false; + + @Nls + @Override + public String getDisplayName() { + return "Android Folding"; + } + + @Nullable + @Override + public String getHelpTopic() { + return "null:"; + } + + @Nullable + @Override + public JComponent createComponent() { + + useCustomPatternCheckBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionEvent) { + boolean selected = getCheckBoxStatus(actionEvent); + + customPattern.setEnabled(selected); + isModified = true; + } + }); + + customPattern.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + isModified = true; + } + + @Override + public void removeUpdate(DocumentEvent e) { + isModified = true; + } + + @Override + public void changedUpdate(DocumentEvent e) { + isModified = true; + } + }); + + hideFoldingPrefix.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent actionEvent) { + isModified = true; + } + }); + + reset(); + + return mPanel; + } + + private boolean getCheckBoxStatus(ActionEvent actionEvent) { + AbstractButton abstractButton = (AbstractButton) actionEvent.getSource(); + return abstractButton.getModel().isSelected(); + } + + + @Override + public boolean isModified() { + + return isModified; + } + + @Override + public void apply() throws ConfigurationException { + PropertiesComponent.getInstance().setValue(PREFIX_CUSTOM_USE, Boolean.valueOf(useCustomPatternCheckBox.isSelected()).toString()); + PropertiesComponent.getInstance().setValue(PREFIX_PATTERN, customPattern.getText()); + PropertiesComponent.getInstance().setValue(PREFIX_HIDE, Boolean.valueOf(hideFoldingPrefix.isSelected()).toString()); + + isModified = false; + } + + @Override + public void reset() { + final boolean customPrefix = PropertiesComponent.getInstance().getBoolean(PREFIX_CUSTOM_USE, false); + useCustomPatternCheckBox.setSelected(customPrefix); + customPattern.setEnabled(customPrefix); + customPattern.setText(PropertiesComponent.getInstance().getValue(PREFIX_PATTERN, DEFAULT_PATTERN_DOUBLE)); + hideFoldingPrefix.getModel().setSelected(PropertiesComponent.getInstance().getBoolean(PREFIX_HIDE, false)); + } + + @Override + public void disposeUIResources() { + } +}