package com.intellij.lang.javascript.flex.build;
import com.intellij.icons.AllIcons;
import com.intellij.lang.javascript.flex.FlexBundle;
import com.intellij.lang.javascript.flex.projectStructure.FlexBuildConfigurationsExtension;
import com.intellij.lang.javascript.flex.projectStructure.model.FlexBuildConfiguration;
import com.intellij.lang.javascript.flex.projectStructure.options.BCUtils;
import com.intellij.lang.javascript.flex.projectStructure.ui.CompositeConfigurable;
import com.intellij.lang.javascript.flex.projectStructure.ui.FlexBCConfigurable;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.MasterDetailsComponent;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Trinity;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.navigation.Place;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Enumeration;
public class FlashProjectStructureErrorsDialog extends DialogWrapper {
private JPanel myMainPanel;
private Tree myTree;
private final Project myProject;
public FlashProjectStructureErrorsDialog(final Project project,
final Collection<Trinity<Module, FlexBuildConfiguration, FlashProjectStructureProblem>> problems) {
super(project);
myProject = project;
myTree.setRootVisible(false);
myTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
for (Trinity<Module, FlexBuildConfiguration, FlashProjectStructureProblem> problem : problems) {
addProblem(problem.first, problem.second, problem.third);
}
myTree.setCellRenderer(new ColoredTreeCellRenderer() {
public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)value;
final Object userObject = treeNode.getUserObject();
if (userObject instanceof Module) {
setIcon(ModuleType.get((Module)userObject).getIcon());
append(((Module)userObject).getName());
}
else if (userObject instanceof FlexBuildConfiguration) {
setIcon(((FlexBuildConfiguration)userObject).getIcon());
BCUtils.renderBuildConfiguration((FlexBuildConfiguration)userObject, null).appendToComponent(this);
}
else if (userObject instanceof FlashProjectStructureProblem) {
setIcon(AllIcons.General.Error);
append(((FlashProjectStructureProblem)userObject).errorMessage);
}
}
});
myTree.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
openProjectStructure();
}
}
});
new DoubleClickListener() {
@Override
protected boolean onDoubleClick(MouseEvent e) {
openProjectStructure();
return true;
}
}.installOn(myTree);
setTitle(FlexBundle.message("project.setup.problem.title"));
setOKButtonText(FlexBundle.message("open.project.structure"));
init();
}
protected JComponent createCenterPanel() {
return myMainPanel;
}
public JComponent getPreferredFocusedComponent() {
TreeUtil.expandAll(myTree);
return myTree;
}
private void addProblem(final Module module, final FlexBuildConfiguration bc, final FlashProjectStructureProblem problem) {
final DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)myTree.getModel().getRoot();
final DefaultMutableTreeNode moduleNode = getOrCreateChildNode(rootNode, module);
final DefaultMutableTreeNode bcNode = getOrCreateChildNode(moduleNode, bc);
bcNode.add(new DefaultMutableTreeNode(problem));
}
@NotNull
private static DefaultMutableTreeNode getOrCreateChildNode(final DefaultMutableTreeNode parentNode, final Object userObject) {
final Enumeration children = parentNode.children();
while (children.hasMoreElements()) {
final DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)children.nextElement();
if (userObject.equals(childNode.getUserObject())) {
return childNode;
}
}
final DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(userObject);
parentNode.add(childNode);
return childNode;
}
private void openProjectStructure() {
final TreePath selectionPath = myTree.getSelectionPath();
DefaultMutableTreeNode node = selectionPath == null ? null : (DefaultMutableTreeNode)selectionPath.getLastPathComponent();
Object userObject = node == null ? null : node.getUserObject();
if (userObject == null) return;
final Ref<Module> moduleRef = new Ref<>();
final Ref<FlexBuildConfiguration> bcRef = new Ref<>();
final Ref<FlashProjectStructureProblem> problemRef = new Ref<>();
if (userObject instanceof FlashProjectStructureProblem) {
problemRef.set((FlashProjectStructureProblem)userObject);
node = (DefaultMutableTreeNode)node.getParent();
userObject = node.getUserObject();
}
if (userObject instanceof FlexBuildConfiguration) {
bcRef.set((FlexBuildConfiguration)userObject);
node = (DefaultMutableTreeNode)node.getParent();
userObject = node.getUserObject();
}
if (userObject instanceof Module) {
moduleRef.set((Module)userObject);
}
close(CANCEL_EXIT_CODE);
final ProjectStructureConfigurable configurable = ProjectStructureConfigurable.getInstance(myProject);
ShowSettingsUtil.getInstance().editConfigurable(myProject, configurable, () -> {
final Place place;
if (problemRef.get() instanceof FlashProjectStructureProblem.FlexUnitOutputFolderProblem) {
place = new Place()
.putPath(ProjectStructureConfigurable.CATEGORY, configurable.getProjectConfig());
}
else if (moduleRef.isNull()) {
place = new Place()
.putPath(ProjectStructureConfigurable.CATEGORY, configurable.getModulesConfig());
}
else if (bcRef.isNull()) {
place = new Place()
.putPath(ProjectStructureConfigurable.CATEGORY, configurable.getModulesConfig())
.putPath(MasterDetailsComponent.TREE_OBJECT, moduleRef.get());
}
else {
place = FlexBuildConfigurationsExtension.getInstance().getConfigurator().getPlaceFor(moduleRef.get(), bcRef.get().getName());
if (!problemRef.isNull()) {
place.putPath(CompositeConfigurable.TAB_NAME, problemRef.get().tabName);
place.putPath(FlexBCConfigurable.LOCATION_ON_TAB, problemRef.get().locationOnTab);
}
}
configurable.navigateTo(place, true);
});
}
}