/* * Copyright 2011 The authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.struts2.facet.ui; import com.intellij.facet.ui.FacetEditorContext; import com.intellij.facet.ui.FacetEditorTab; import com.intellij.ide.projectView.PresentationData; import com.intellij.openapi.Disposable; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.struts2.StrutsBundle; import com.intellij.struts2.StrutsIcons; import com.intellij.struts2.dom.struts.model.StrutsManager; import com.intellij.struts2.facet.StrutsFacetConfiguration; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.treeStructure.*; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeModel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; /** * Struts2 facet tab "File Sets". * * @author Yann Cébron */ public class FileSetConfigurationTab extends FacetEditorTab implements Disposable { // GUI components ----------------------- private JPanel myPanel; private SimpleTree myTree; private JButton myAddSetButton; private JButton myRemoveButton; private JButton myEditButton; // GUI helpers private final SimpleTreeBuilder myBuilder; private final SimpleNode myRootNode = new SimpleNode() { public SimpleNode[] getChildren() { final List<SimpleNode> nodes = new ArrayList<SimpleNode>(myBuffer.size()); for (final StrutsFileSet entry : myBuffer) { if (!entry.isRemoved()) { final FileSetNode setNode = new FileSetNode(entry); nodes.add(setNode); } } return ArrayUtil.toObjectArray(nodes, SimpleNode.class); } public boolean isAutoExpandNode() { return true; } }; private final StrutsConfigsSearcher myConfigsSearcher; // original config private final StrutsFacetConfiguration originalConfiguration; private final Module module; // local config private final Set<StrutsFileSet> myBuffer = new LinkedHashSet<StrutsFileSet>(); private boolean myModified; public FileSetConfigurationTab(@NotNull final StrutsFacetConfiguration strutsFacetConfiguration, @NotNull final FacetEditorContext facetEditorContext) { originalConfiguration = strutsFacetConfiguration; module = facetEditorContext.getModule(); myConfigsSearcher = new StrutsConfigsSearcher(module); // init tree final SimpleTreeStructure structure = new SimpleTreeStructure() { public Object getRootElement() { return myRootNode; } }; myTree.setRootVisible(false); myTree.setShowsRootHandles(true); // show expand/collapse handles myBuilder = new SimpleTreeBuilder(myTree, (DefaultTreeModel) myTree.getModel(), structure, null); myBuilder.initRoot(); final DumbService dumbService = DumbService.getInstance(facetEditorContext.getProject()); myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(final TreeSelectionEvent e) { final StrutsFileSet fileSet = getCurrentFileSet(); myEditButton.setEnabled(fileSet != null && !dumbService.isDumb()); myRemoveButton.setEnabled(fileSet != null); } }); myAddSetButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final StrutsFileSet fileSet = new StrutsFileSet(StrutsFileSet.getUniqueId(myBuffer), StrutsFileSet.getUniqueName(StrutsBundle.message("facet.fileset.myfileset"), myBuffer), originalConfiguration) { public boolean isNew() { return true; } }; final FileSetEditor editor = new FileSetEditor(myPanel, fileSet, facetEditorContext, myConfigsSearcher); editor.show(); if (editor.getExitCode() == DialogWrapper.OK_EXIT_CODE) { final StrutsFileSet editedFileSet = editor.getEditedFileSet(); Disposer.register(strutsFacetConfiguration, editedFileSet); myBuffer.add(editedFileSet); myModified = true; myBuilder.updateFromRoot(); selectFileSet(fileSet); } myTree.requestFocus(); } }); myEditButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final StrutsFileSet fileSet = getCurrentFileSet(); if (fileSet != null) { final FileSetEditor editor = new FileSetEditor(myPanel, fileSet, facetEditorContext, myConfigsSearcher); editor.show(); if (editor.getExitCode() == DialogWrapper.OK_EXIT_CODE) { myModified = true; myBuffer.remove(fileSet); final StrutsFileSet edited = editor.getEditedFileSet(); Disposer.register(strutsFacetConfiguration, edited); myBuffer.add(edited); edited.setAutodetected(false); myBuilder.updateFromRoot(); selectFileSet(edited); } myTree.requestFocus(); } } }); myRemoveButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { remove(); myModified = true; myBuilder.updateFromRoot(); myTree.requestFocus(); } }); dumbService.makeDumbAware(myAddSetButton, this); dumbService.makeDumbAware(myEditButton, this); } @Nullable private StrutsFileSet getCurrentFileSet() { final FileSetNode currentFileSetNode = getCurrentFileSetNode(); return currentFileSetNode == null ? null : currentFileSetNode.mySet; } @Nullable private FileSetNode getCurrentFileSetNode() { final SimpleNode selectedNode = myTree.getSelectedNode(); if (selectedNode == null) { return null; } if (selectedNode instanceof FileSetNode) { return (FileSetNode) selectedNode; } else if (selectedNode.getParent() instanceof FileSetNode) { return (FileSetNode) selectedNode.getParent(); } else { final SimpleNode parent = selectedNode.getParent(); if (parent != null && parent.getParent() instanceof FileSetNode) { return (FileSetNode) selectedNode.getParent().getParent(); } } return null; } private void selectFileSet(final StrutsFileSet fileSet) { myTree.select(myBuilder, new SimpleNodeVisitor() { public boolean accept(final SimpleNode simpleNode) { if (simpleNode instanceof FileSetNode) { if (((FileSetNode) simpleNode).mySet.equals(fileSet)) { return true; } } return false; } }, false); } private void remove() { final SimpleNode[] nodes = myTree.getSelectedNodesIfUniform(); for (final SimpleNode node : nodes) { if (node instanceof FileSetNode) { final StrutsFileSet fileSet = ((FileSetNode) node).mySet; if (fileSet.getFiles().isEmpty()) { myBuffer.remove(fileSet); return; } final int result = Messages.showYesNoDialog(myPanel, StrutsBundle.message("facet.fileset.removefileset.question", fileSet.getName()), StrutsBundle.message("facet.fileset.removefileset.title"), Messages.getQuestionIcon()); if (result == DialogWrapper.OK_EXIT_CODE) { if (fileSet.isAutodetected()) { fileSet.setRemoved(true); myBuffer.add(fileSet); } else { myBuffer.remove(fileSet); } } } else if (node instanceof ConfigFileNode) { final VirtualFilePointer filePointer = ((ConfigFileNode) node).myFilePointer; final StrutsFileSet fileSet = ((FileSetNode) node.getParent()).mySet; fileSet.removeFile(filePointer); } } } @Nullable public Icon getIcon() { return StrutsIcons.STRUTS_CONFIG_FILE; } @Nls public String getDisplayName() { return StrutsBundle.message("facet.fileset.title"); } public JComponent createComponent() { return myPanel; } public boolean isModified() { return myModified; } public void apply() { final Set<StrutsFileSet> fileSets = originalConfiguration.getFileSets(); fileSets.clear(); for (final StrutsFileSet fileSet : myBuffer) { if (!fileSet.isAutodetected() || fileSet.isRemoved()) { fileSets.add(fileSet); } } originalConfiguration.setModified(); } public void reset() { myBuffer.clear(); final Set<StrutsFileSet> sets = StrutsManager.getInstance(module.getProject()).getAllConfigFileSets(module); for (final StrutsFileSet fileSet : sets) { myBuffer.add(/*new StrutsFileSet(fileSet)*/fileSet); } myBuilder.updateFromRoot(); myTree.setSelectionRow(0); } public void disposeUIResources() { Disposer.dispose(myBuilder); Disposer.dispose(this); } public void dispose() { } private static class FileSetNode extends SimpleNode { protected final StrutsFileSet mySet; FileSetNode(final StrutsFileSet fileSet) { mySet = fileSet; final PresentationData presentationData = getPresentation(); final String name = mySet.getName(); if (fileSet.getFiles().isEmpty()) { presentationData.addText(name, getErrorAttributes()); presentationData.setTooltip(StrutsBundle.message("facet.fileset.nofiles.attached")); } else { presentationData.addText(name, getPlainAttributes()); presentationData.setLocationString("" + fileSet.getFiles().size()); } } public SimpleNode[] getChildren() { final List<SimpleNode> nodes = new ArrayList<SimpleNode>(); for (final VirtualFilePointer file : mySet.getFiles()) { nodes.add(new ConfigFileNode(file, this)); } return ArrayUtil.toObjectArray(nodes, SimpleNode.class); } public boolean isAutoExpandNode() { return true; } public Object[] getEqualityObjects() { return new Object[]{mySet, mySet.getName(), mySet.getFiles()}; } } private static final class ConfigFileNode extends SimpleNode { private final VirtualFilePointer myFilePointer; ConfigFileNode(final VirtualFilePointer name, final SimpleNode parent) { super(parent); myFilePointer = name; setIcons(StrutsIcons.STRUTS_CONFIG_FILE, StrutsIcons.STRUTS_CONFIG_FILE); } @Override public boolean isAlwaysLeaf() { return true; } protected void doUpdate() { final VirtualFile file = myFilePointer.getFile(); if (file != null) { renderFile(file, getPlainAttributes(), null); } else { renderFile(file, getErrorAttributes(), StrutsBundle.message("facet.fileset.filenotfound")); } } private void renderFile(final VirtualFile file, final SimpleTextAttributes textAttributes, @Nullable final String toolTip) { final PresentationData presentation = getPresentation(); presentation.setTooltip(toolTip); presentation.addText(myFilePointer.getFileName(), textAttributes); if (file != null) { presentation.setLocationString(file.getPath()); } } public SimpleNode[] getChildren() { return NO_CHILDREN; } } @Override public String getHelpTopic() { return "reference.settings.project.structure.facets.struts2.facet"; } }