// Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
// Licensed under the Apache License, Version 2.0 (see LICENSE).
package com.twitter.intellij.pants.projectview;
import com.intellij.icons.AllIcons;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.AbstractProjectViewPSIPane;
import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase;
import com.intellij.ide.projectView.impl.ProjectTreeStructure;
import com.intellij.ide.projectView.impl.ProjectViewTree;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.AbstractTreeUpdater;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizerUtil;
import com.intellij.openapi.util.WriteExternalException;
import com.twitter.intellij.pants.PantsBundle;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class ProjectFilesViewPane extends AbstractProjectViewPSIPane {
@NonNls public static final String ID = "ProjectFilesPane";
public static final String SHOW_EXCLUDED_FILES_OPTION = "show-excluded-files";
public static final String SHOW_ONLY_LOADED_FILES_OPTION = "show-only-loaded-files";
private boolean myShowExcludedFiles = true;
private boolean myShowOnlyLoadedFiles = false;
public ProjectFilesViewPane(Project project) {
super(project);
}
@Override
public String getTitle() {
return PantsBundle.message("pants.title.project.files");
}
@Override
public Icon getIcon() {
return AllIcons.General.ProjectTab;
}
@Override
@NotNull
public String getId() {
return ID;
}
@Override
public int getWeight() {
// There are 5 project view panels with ids from 1 to 5.
// There is an assertion that id should be unique. See ProjectViewImpl.java:441
// Picked an id that I like. :-)
return 239;
}
@Override
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
final String showExcludedOption = JDOMExternalizerUtil.readField(element, SHOW_EXCLUDED_FILES_OPTION);
myShowExcludedFiles = showExcludedOption == null || Boolean.parseBoolean(showExcludedOption);
final String showOnlyLoadedOption = JDOMExternalizerUtil.readField(element, SHOW_ONLY_LOADED_FILES_OPTION);
myShowOnlyLoadedFiles = showOnlyLoadedOption == null || Boolean.parseBoolean(showOnlyLoadedOption);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
JDOMExternalizerUtil.writeField(element, SHOW_EXCLUDED_FILES_OPTION, String.valueOf(myShowExcludedFiles));
JDOMExternalizerUtil.writeField(element, SHOW_ONLY_LOADED_FILES_OPTION, String.valueOf(myShowOnlyLoadedFiles));
}
@Override
public void addToolbarActions(DefaultActionGroup actionGroup) {
actionGroup.addAction(new ShowExcludedFilesAction()).setAsSecondary(true);
actionGroup.addAction(new ShowOnlyLoadedFilesAction()).setAsSecondary(true);
}
@Override
protected ProjectAbstractTreeStructureBase createStructure() {
return new ProjectViewPaneTreeStructure();
}
@Override
protected ProjectViewTree createTree(DefaultTreeModel treeModel) {
return new ProjectViewTree(myProject, treeModel) {
@Override
public DefaultMutableTreeNode getSelectedNode() {
return ProjectFilesViewPane.this.getSelectedNode();
}
};
}
@Override
protected AbstractTreeUpdater createTreeUpdater(AbstractTreeBuilder treeBuilder) {
return new AbstractTreeUpdater(treeBuilder);
}
@Override
public SelectInTarget createSelectInTarget() {
return new PantsProjectPaneSelectInTarget(myProject);
}
private class ProjectViewPaneTreeStructure extends ProjectTreeStructure implements PantsViewSettings {
public ProjectViewPaneTreeStructure() {
super(ProjectFilesViewPane.this.myProject, ID);
}
@Override
protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) {
return new ProjectFilesViewProjectNode(project, settings);
}
@Override
public boolean isShowExcludedFiles() {
return myShowExcludedFiles;
}
@Override
public boolean isShowOnlyLoadedFiles() {
return myShowOnlyLoadedFiles;
}
}
private final class ShowExcludedFilesAction extends ToggleAction {
private ShowExcludedFilesAction() {
super(
PantsBundle.message("pants.action.show.excluded.files"),
PantsBundle.message("pants.action.show.hide.excluded.files"),
null
);
}
@Override
public boolean isSelected(AnActionEvent event) {
return myShowExcludedFiles;
}
@Override
public void setSelected(AnActionEvent event, boolean flag) {
if (myShowExcludedFiles != flag) {
myShowExcludedFiles = flag;
updateFromRoot(true);
}
}
@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
final Presentation presentation = e.getPresentation();
final ProjectView projectView = ProjectView.getInstance(myProject);
presentation.setEnabledAndVisible(projectView.getCurrentProjectViewPane() == ProjectFilesViewPane.this);
}
}
private final class ShowOnlyLoadedFilesAction extends ToggleAction implements DumbAware {
private ShowOnlyLoadedFilesAction() {
super(
PantsBundle.message("pants.action.show.only.loaded.files"),
PantsBundle.message("pants.action.show.hide.only.loaded.files"),
null
);
}
@Override
public boolean isSelected(AnActionEvent event) {
return myShowOnlyLoadedFiles;
}
@Override
public void setSelected(AnActionEvent event, boolean flag) {
if (myShowOnlyLoadedFiles != flag) {
myShowOnlyLoadedFiles = flag;
updateFromRoot(true);
}
}
@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
final Presentation presentation = e.getPresentation();
final ProjectView projectView = ProjectView.getInstance(myProject);
presentation.setEnabledAndVisible(projectView.getCurrentProjectViewPane() == ProjectFilesViewPane.this);
}
}
}